Skip to content

feat(snapshot): add packages field for npm/bun dependencies in declarative YAML#994

Open
jhaynie wants to merge 2 commits intomainfrom
task/npm-dependencies-in-yaml-cli-964
Open

feat(snapshot): add packages field for npm/bun dependencies in declarative YAML#994
jhaynie wants to merge 2 commits intomainfrom
task/npm-dependencies-in-yaml-cli-964

Conversation

@jhaynie
Copy link
Member

@jhaynie jhaynie commented Feb 18, 2026

Summary

  • Adds a packages field to the snapshot YAML schema for declarative npm/bun package installation
  • Packages are validated, hashed into the content hash, displayed in output, and sent to the API
  • Enables reproducible snapshot builds that include npm/bun packages without manual shell scripts

Problem

The declarative snapshot build file (agentuity-snapshot.yaml) only supports apt packages in the dependencies field. Any snapshot that needs npm packages (e.g., opencode-ai, typescript) must be built manually via sandbox create → exec → snapshot → delete, which is not reproducible from the YAML alone.

Solution

New packages field in the YAML schema:

version: 1
runtime: agentuity:latest
name: my-snapshot

dependencies:
  - curl           # apt packages (existing)

packages:           # npm/bun packages (new)
  - opencode-ai
  - typescript

Changes

File Change
packages/server/.../snapshot-build.ts Added packages to Zod schema + validation refinement
packages/server/.../snapshot.ts Added packages to finalize API params
packages/cli/.../snapshot/build.ts Package name validation (regex), content hash, dry-run + success display, finalize call
packages/cli/.../snapshot/generate.ts Updated YAML/JSON templates with packages example

Security

Package names are validated against a strict regex that prevents shell injection (no ;, |, &, $, backticks, etc.), since package names are used in a bun install -g command at container startup.

Companion PRs

  • hadron: Generates install-packages.sh and passes to pilot via --script
  • catalyst: Needs to store and return packages in snapshot metadata (separate change)

Resolves #964

Summary by CodeRabbit

  • New Features
    • Added support for specifying npm/bun packages in sandbox snapshots, templates, creation requests, and API responses; packages are shown in CLI dry-run and final summaries.
  • Validation
    • Build config now validates package names and surfaces errors for invalid entries.

…ative YAML

Support npm/bun packages in the snapshot build file via a new 'packages'
field. Packages are validated against a regex to prevent shell injection,
included in the content hash for change detection, displayed in dry-run
and success output, and sent to the API in the finalize call.

Example usage in agentuity-snapshot.yaml:

  packages:
    - opencode-ai
    - typescript

Resolves #964
@agentuity-agent
Copy link

agentuity-agent bot commented Feb 18, 2026

The latest Agentuity deployment details. Learn more about Agentuity.

Project Deployment Preview Updated (UTC)
docs 🔴 Failed - Feb 18, 2026 3:45 AM

The build failed with the following:

@coderabbitai
Copy link

coderabbitai bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

Adds an optional packages field propagated through sandbox creation and snapshot build flows: included in schemas and APIs, validated and integrated into content hashing, surfaced in CLI output/templates, and carried in finalization payloads.

Changes

Cohort / File(s) Summary
CLI: snapshot build
packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
Accepts packages?: string[] in content hash generation, validates package names, prints Packages in dry-run and final summaries, and includes packages in the snapshotBuildFinalize payload.
CLI: template generation
packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
Added packages example to JSON template and an optional commented packages section to the YAML template for guidance.
CLI: sandbox get
packages/cli/src/cmd/cloud/sandbox/get.ts
Added optional packages: string[] to SandboxGetResponseSchema to expose globally installed packages in responses.
Server: snapshot build/finalize
packages/server/src/api/sandbox/snapshot-build.ts, packages/server/src/api/sandbox/snapshot.ts
Added optional packages: string[] to SnapshotBuildFileBaseSchema and _SnapshotBuildFinalizeParamsSchema; updated validation to require at least one of dependencies/files/env/packages and included packages in finalize request body when present.
Server: sandbox create/get APIs
packages/server/src/api/sandbox/create.ts, packages/server/src/api/sandbox/get.ts
Added packages?: string[] to SandboxCreateRequestSchema and SandboxInfoDataSchema; sandboxCreate forwards options.packages to request body, and sandboxGet maps response packages into returned SandboxInfo.
Core: sandbox service types
packages/core/src/services/sandbox.ts
Added public packages?: string[] to SandboxCreateOptions and SandboxInfo interfaces to represent globally installed npm/bun packages.
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR implements all key objectives from issue #964: adds declarative packages field to snapshot YAML schema, validates package names to prevent injection, includes packages in content hash, displays in dry-run/output, and sends to API during finalization.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the packages field feature across CLI, server, and core layers. No unrelated modifications detected beyond the stated objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Feb 18, 2026

📦 Canary Packages Published

version: 1.0.14-dffedb1

Packages
Package Version URL
@agentuity/postgres 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-postgres-1.0.14-dffedb1.tgz
@agentuity/auth 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-auth-1.0.14-dffedb1.tgz
@agentuity/server 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-server-1.0.14-dffedb1.tgz
@agentuity/frontend 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-frontend-1.0.14-dffedb1.tgz
@agentuity/drizzle 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-drizzle-1.0.14-dffedb1.tgz
@agentuity/schema 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-schema-1.0.14-dffedb1.tgz
@agentuity/claude-code 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-claude-code-1.0.14-dffedb1.tgz
@agentuity/runtime 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-runtime-1.0.14-dffedb1.tgz
@agentuity/workbench 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-workbench-1.0.14-dffedb1.tgz
@agentuity/core 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-core-1.0.14-dffedb1.tgz
@agentuity/evals 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-evals-1.0.14-dffedb1.tgz
@agentuity/opencode 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-opencode-1.0.14-dffedb1.tgz
@agentuity/cli 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-cli-1.0.14-dffedb1.tgz
@agentuity/react 1.0.14-dffedb1 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-react-1.0.14-dffedb1.tgz
Install

Add to your package.json:

{
  "dependencies": {
    "@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-postgres-1.0.14-dffedb1.tgz",
    "@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-auth-1.0.14-dffedb1.tgz",
    "@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-server-1.0.14-dffedb1.tgz",
    "@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-frontend-1.0.14-dffedb1.tgz",
    "@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-drizzle-1.0.14-dffedb1.tgz",
    "@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-schema-1.0.14-dffedb1.tgz",
    "@agentuity/claude-code": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-claude-code-1.0.14-dffedb1.tgz",
    "@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-runtime-1.0.14-dffedb1.tgz",
    "@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-workbench-1.0.14-dffedb1.tgz",
    "@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-core-1.0.14-dffedb1.tgz",
    "@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-evals-1.0.14-dffedb1.tgz",
    "@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-opencode-1.0.14-dffedb1.tgz",
    "@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-cli-1.0.14-dffedb1.tgz",
    "@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-react-1.0.14-dffedb1.tgz"
  }
}

Or install directly:

bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-postgres-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-auth-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-server-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-frontend-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-drizzle-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-schema-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-claude-code-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-runtime-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-workbench-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-core-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-evals-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-opencode-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-cli-1.0.14-dffedb1.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.14-dffedb1/agentuity-react-1.0.14-dffedb1.tgz

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts (1)

976-998: Indentation inconsistency within the if (!options.json) block.

The Dependencies, Packages (npm/bun), and Environment output sections (lines 976-998) appear to have lost a level of indentation compared to the Metadata section (lines 1000-1006) and other code within the same if (!options.json) block starting at line 956. These sections should be indented to align with the rest of the block.

♻️ Proposed fix
-		if (buildConfig.dependencies && buildConfig.dependencies.length > 0) {
-			console.log('');
-			tui.info('Dependencies:');
-			for (const dep of buildConfig.dependencies) {
-				console.log(`  ${tui.muted('•')} ${dep}`);
+			if (buildConfig.dependencies && buildConfig.dependencies.length > 0) {
+				console.log('');
+				tui.info('Dependencies:');
+				for (const dep of buildConfig.dependencies) {
+					console.log(`  ${tui.muted('•')} ${dep}`);
+				}
 			}
-		}
 
-		if (buildConfig.packages && buildConfig.packages.length > 0) {
-			console.log('');
-			tui.info('Packages (npm/bun):');
-			for (const pkg of buildConfig.packages) {
-				console.log(`  ${tui.muted('•')} ${pkg}`);
+			if (buildConfig.packages && buildConfig.packages.length > 0) {
+				console.log('');
+				tui.info('Packages (npm/bun):');
+				for (const pkg of buildConfig.packages) {
+					console.log(`  ${tui.muted('•')} ${pkg}`);
+				}
 			}
-		}
 
-		if (finalEnv && Object.keys(finalEnv).length > 0) {
-			console.log('');
-			tui.info('Environment:');
-			for (const [envKey, envValue] of Object.entries(finalEnv)) {
-				console.log(`  ${tui.muted('•')} ${envKey}=${tui.maskSecret(envValue)}`);
+			if (finalEnv && Object.keys(finalEnv).length > 0) {
+				console.log('');
+				tui.info('Environment:');
+				for (const [envKey, envValue] of Object.entries(finalEnv)) {
+					console.log(`  ${tui.muted('•')} ${envKey}=${tui.maskSecret(envValue)}`);
+				}
 			}
-		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts` around lines 976 - 998,
The console output blocks for dependencies, packages and environment are
mis-indented inside the if (!options.json) block; move the entire blocks that
reference buildConfig (buildConfig.dependencies, buildConfig.packages) and
finalEnv (Object.entries(finalEnv), using tui.info, tui.muted, tui.maskSecret)
so they align with the surrounding Metadata output code inside the same if
(!options.json) scope—i.e., increase their indentation level to match the other
statements in that block without changing logic or conditions.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d2f6d0 and be6c13f.

📒 Files selected for processing (4)
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
🧰 Additional context used
📓 Path-based instructions (7)
packages/cli/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

Use Bun.file(f).exists() instead of existsSync(f) for file existence checks

Files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with tabs (width 3), single quotes, and semicolons for code formatting

Files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with ESNext target and bundler moduleResolution

Files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use StructuredError from @agentuity/core for error handling

Files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
packages/cli/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use commander.js framework for CLI implementation in the cli package

Files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
packages/server/src/**/*.ts

📄 CodeRabbit inference engine (packages/server/AGENTS.md)

packages/server/src/**/*.ts: All code must be written in TypeScript
Use zod for runtime validation of schemas and data

Files:

  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
packages/server/src/api/**/*.ts

📄 CodeRabbit inference engine (packages/server/AGENTS.md)

Organize API clients by feature domain in src/api/ subdirectories (apikey, db, eval, org, project, queue, region, sandbox, session, thread, user)

Files:

  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
🧠 Learnings (5)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
📚 Learning: 2026-01-13T04:32:02.691Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 565
File: packages/cli/src/cmd/cloud/region-lookup.ts:14-26
Timestamp: 2026-01-13T04:32:02.691Z
Learning: Enforce sandbox identifier prefixes in new code within the CLI cloud region lookup: new sandboxes must use the sbx_ prefix. The snbx_ prefix may appear in legacy code or examples, but do not use snbx_ for new sandboxes. When reviewing changes in packages/cli/src/cmd/cloud/, ensure any created sandbox identifiers use sbx_ and remove or migrate any snbx_ usages in newly added code.

Applied to files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
📚 Learning: 2026-02-17T14:23:15.448Z
Learnt from: potofpie
Repo: agentuity/sdk PR: 974
File: packages/cli/src/cmd/git/account/list.ts:39-40
Timestamp: 2026-02-17T14:23:15.448Z
Learning: In the Agentuity CLI framework (packages/cli), when a subcommand declares requires: { auth: true }, the framework will automatically call requireAuth() before invoking the handler. Do not call requireAuth(ctx) manually inside command handlers. This applies to all TypeScript command files under packages/cli/src, including paths like packages/cli/src/cmd/git/account/list.ts.

Applied to files:

  • packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts
  • packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts
📚 Learning: 2025-12-19T14:19:33.765Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 259
File: packages/cli/src/cmd/build/vite/registry-generator.ts:306-312
Timestamp: 2025-12-19T14:19:33.765Z
Learning: Route files under src/api should use the .ts extension only (no .tsx) and regex patterns for such paths should anchor to \.ts$ (e.g., /\/.ts$/). Agent files may support both .ts and .tsx, but route files in the Agentuity SDK codebase are restricted to .ts. This guideline applies to all similar route files under src/api across the repository.

Applied to files:

  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
📚 Learning: 2025-12-30T00:13:37.849Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 355
File: packages/server/src/api/sandbox/util.ts:2-6
Timestamp: 2025-12-30T00:13:37.849Z
Learning: In the packages/server tree, treat code as runtime-agnostic between Node.js and Bun. Ensure TypeScript files (e.g., util.ts) import and use APIs in a way that works under both runtimes. It is acceptable to rely on Bun’s Node.js compatibility for built-ins accessed via the node: namespace (e.g., node:events, node:stream, node:buffer). During reviews, prefer patterns and imports that remain compatible with Bun's environment, and flag any hard dependencies on runtime-specific globals or non-portable Node APIs.

Applied to files:

  • packages/server/src/api/sandbox/snapshot-build.ts
  • packages/server/src/api/sandbox/snapshot.ts
🪛 GitHub Actions: Build Packages & Test
packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts

[error] 586-586: ESLint: Unnecessary escape character: - (no-useless-escape).

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Pack & Upload
  • GitHub Check: Queue SDK Tests
  • GitHub Check: Queue CLI Tests
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: Template Integration Tests
  • GitHub Check: Package Installation & Usage Test
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Cloud Deployment Tests
🔇 Additional comments (4)
packages/cli/src/cmd/cloud/sandbox/snapshot/generate.ts (1)

38-42: LGTM!

The new packages field is well-documented in the YAML template with clear guidance on its purpose (global npm/bun packages installed via bun install -g). The JSON template includes a practical example. Both are consistent with the broader PR changes.

Also applies to: 77-77

packages/server/src/api/sandbox/snapshot.ts (1)

597-597: LGTM!

The packages field is correctly added to the finalize params schema with appropriate Zod typing. The destructuring and conditional body assignment follow the established pattern used for dependencies, env, and metadata.

Also applies to: 675-676, 686-686

packages/server/src/api/sandbox/snapshot-build.ts (1)

25-30: LGTM!

The packages field is correctly integrated into both the base schema and the validation refinement. The "at least one of" validation now properly includes packages as a valid option alongside dependencies, files, and env.

Also applies to: 58-58, 65-66, 69-69

packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts (1)

300-300: LGTM on packages integration throughout the build flow.

The implementation correctly:

  • Adds packages to the content hash for reproducibility (with deterministic sorting)
  • Validates package names using a regex to prevent shell injection (security requirement per PR objectives)
  • Propagates packages through dry-run output, finalization, and final success output
  • Follows the same patterns established for dependencies

Also applies to: 319-322, 584-598, 638-638, 673-679, 948-948

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts`:
- Around line 586-587: The packageNameRegex contains an unnecessary escape for
the hyphen in the character class, triggering ESLint no-useless-escape; update
the regex definition (packageNameRegex) to remove the backslash before the
hyphen (or place the hyphen at the end of the class) so the character class
becomes valid without the useless escape and re-run lint/tests.

---

Nitpick comments:
In `@packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts`:
- Around line 976-998: The console output blocks for dependencies, packages and
environment are mis-indented inside the if (!options.json) block; move the
entire blocks that reference buildConfig (buildConfig.dependencies,
buildConfig.packages) and finalEnv (Object.entries(finalEnv), using tui.info,
tui.muted, tui.maskSecret) so they align with the surrounding Metadata output
code inside the same if (!options.json) scope—i.e., increase their indentation
level to match the other statements in that block without changing logic or
conditions.

Comment on lines +586 to +587
const packageNameRegex =
/^(@[a-zA-Z0-9._-]+\/)?[a-zA-Z0-9._-]+(@[a-zA-Z0-9._^~><=\-]+)?$/;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix unnecessary escape character in regex.

The pipeline is failing due to ESLint's no-useless-escape rule. The hyphen at the end of the character class doesn't need escaping.

🔧 Proposed fix
 		const packageNameRegex =
-			/^(@[a-zA-Z0-9._-]+\/)?[a-zA-Z0-9._-]+(@[a-zA-Z0-9._^~><=\-]+)?$/;
+			/^(@[a-zA-Z0-9._-]+\/)?[a-zA-Z0-9._-]+(@[a-zA-Z0-9._^~><=-]+)?$/;
🧰 Tools
🪛 GitHub Actions: Build Packages & Test

[error] 586-586: ESLint: Unnecessary escape character: - (no-useless-escape).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/cmd/cloud/sandbox/snapshot/build.ts` around lines 586 - 587,
The packageNameRegex contains an unnecessary escape for the hyphen in the
character class, triggering ESLint no-useless-escape; update the regex
definition (packageNameRegex) to remove the backslash before the hyphen (or
place the hyphen at the end of the class) so the character class becomes valid
without the useless escape and re-run lint/tests.

…faces

Add npm/bun packages support to the sandbox CRUD APIs, mirroring the
existing dependencies field:
- core: SandboxCreateOptions and SandboxInfo interfaces
- server: SandboxCreateRequestSchema, sandboxCreate function, SandboxInfoDataSchema, sandboxGet return
- cli: SandboxGetResponseSchema
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/cli/src/cmd/cloud/sandbox/get.ts (1)

139-171: ⚠️ Potential issue | 🟡 Minor

Surface packages in CLI output and JSON return.

Right now the CLI parses packages but never shows/returns them, so the new field is effectively hidden from users.

✅ Proposed fix
 			if (result.dependencies && result.dependencies.length > 0) {
 				tableData['Dependencies'] = result.dependencies.join(', ');
 			}
+			if (result.packages && result.packages.length > 0) {
+				tableData['Packages'] = result.packages.join(', ');
+			}
 			if (resourceParts.length > 0) {
 				tableData['Resources'] = resourceParts.join(', ');
 			}
@@
 			stderrStreamUrl: result.stderrStreamUrl,
 			dependencies: result.dependencies,
+			packages: result.packages,
 			metadata: result.metadata,
 			resources: result.resources,
 			url: result.url,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/cmd/cloud/sandbox/get.ts` around lines 139 - 171, The CLI
builds tableData from result but never includes result.packages nor returns
packages in the JSON response; update the display and return to surface packages
by adding a tableData['Packages'] entry when result.packages exists (e.g.,
tableData['Packages'] = result.packages.join(', ')) and include packages:
result.packages in the final returned object alongside the other fields
(sandboxId, name, description, etc.) so both the tui.table output and the
function's JSON return expose the packages field.
packages/server/src/api/sandbox/create.ts (1)

85-92: ⚠️ Potential issue | 🔴 Critical

Add server-side package-name validation to block injection attacks.

The API currently accepts arbitrary strings for npm/bun packages and forwards them to bun install -g. While dependencies (apt) are validated in the CLI, the packages field lacks validation entirely, creating a security gap. Client-side validation can be bypassed.

Suggested schema hardening
+const PackageNameSchema = z
+	.string()
+	.regex(/^[a-z0-9@][a-z0-9@/._-]*$/i, 'Invalid package name');
+
 export const SandboxCreateRequestSchema = z
 	.object({
 		dependencies: z
 			.array(z.string())
 			.optional()
 			.describe('Apt packages to install when creating the sandbox'),
-		packages: z
-			.array(z.string())
+		packages: z
+			.array(PackageNameSchema)
 			.optional()
 			.describe('npm/bun packages to install globally when creating the sandbox'),

Apply the same validation to SnapshotBuildFileBaseSchema in packages/server/src/api/sandbox/snapshot-build.ts (lines 25-30).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/server/src/api/sandbox/create.ts` around lines 85 - 92, The packages
array currently accepts arbitrary strings; add server-side package-name
validation by replacing the freeform z.array(z.string()) for the "packages"
field in create.ts with the same package-name validator used elsewhere (e.g., a
PackageNameSchema or similar validator) so only safe npm/bun package names are
allowed, and apply the identical change to SnapshotBuildFileBaseSchema in
snapshot-build.ts (the packages field in that schema) so both endpoints enforce
the same validated package-name format and block injection vectors.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be6c13f and dffedb1.

📒 Files selected for processing (4)
  • packages/cli/src/cmd/cloud/sandbox/get.ts
  • packages/core/src/services/sandbox.ts
  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
🧰 Additional context used
📓 Path-based instructions (9)
packages/cli/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

Use Bun.file(f).exists() instead of existsSync(f) for file existence checks

Files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with tabs (width 3), single quotes, and semicolons for code formatting

Files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
  • packages/core/src/services/sandbox.ts
  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with ESNext target and bundler moduleResolution

Files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
  • packages/core/src/services/sandbox.ts
  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use StructuredError from @agentuity/core for error handling

Files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
  • packages/core/src/services/sandbox.ts
  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
packages/cli/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use commander.js framework for CLI implementation in the cli package

Files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
packages/core/src/**/*.ts

📄 CodeRabbit inference engine (packages/core/AGENTS.md)

packages/core/src/**/*.ts: Use TypeScript for all code in the @agentuity/core package
Prefer interfaces for public API definitions in @agentuity/core
Use generic types for reusable type utilities in @agentuity/core
Ensure no side effects in exports - all exports must be pure functions or types with no global mutations
Ensure code is compatible with both Browser and Node/Bun runtime environments

Files:

  • packages/core/src/services/sandbox.ts
packages/core/src/services/*.ts

📄 CodeRabbit inference engine (packages/core/AGENTS.md)

Use FetchAdapter abstraction for HTTP service implementations

Files:

  • packages/core/src/services/sandbox.ts
packages/server/src/**/*.ts

📄 CodeRabbit inference engine (packages/server/AGENTS.md)

packages/server/src/**/*.ts: All code must be written in TypeScript
Use zod for runtime validation of schemas and data

Files:

  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
packages/server/src/api/**/*.ts

📄 CodeRabbit inference engine (packages/server/AGENTS.md)

Organize API clients by feature domain in src/api/ subdirectories (apikey, db, eval, org, project, queue, region, sandbox, session, thread, user)

Files:

  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
🧠 Learnings (5)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
  • packages/core/src/services/sandbox.ts
  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
📚 Learning: 2026-01-13T04:32:02.691Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 565
File: packages/cli/src/cmd/cloud/region-lookup.ts:14-26
Timestamp: 2026-01-13T04:32:02.691Z
Learning: Enforce sandbox identifier prefixes in new code within the CLI cloud region lookup: new sandboxes must use the sbx_ prefix. The snbx_ prefix may appear in legacy code or examples, but do not use snbx_ for new sandboxes. When reviewing changes in packages/cli/src/cmd/cloud/, ensure any created sandbox identifiers use sbx_ and remove or migrate any snbx_ usages in newly added code.

Applied to files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
📚 Learning: 2026-02-17T14:23:15.448Z
Learnt from: potofpie
Repo: agentuity/sdk PR: 974
File: packages/cli/src/cmd/git/account/list.ts:39-40
Timestamp: 2026-02-17T14:23:15.448Z
Learning: In the Agentuity CLI framework (packages/cli), when a subcommand declares requires: { auth: true }, the framework will automatically call requireAuth() before invoking the handler. Do not call requireAuth(ctx) manually inside command handlers. This applies to all TypeScript command files under packages/cli/src, including paths like packages/cli/src/cmd/git/account/list.ts.

Applied to files:

  • packages/cli/src/cmd/cloud/sandbox/get.ts
📚 Learning: 2025-12-19T14:19:33.765Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 259
File: packages/cli/src/cmd/build/vite/registry-generator.ts:306-312
Timestamp: 2025-12-19T14:19:33.765Z
Learning: Route files under src/api should use the .ts extension only (no .tsx) and regex patterns for such paths should anchor to \.ts$ (e.g., /\/.ts$/). Agent files may support both .ts and .tsx, but route files in the Agentuity SDK codebase are restricted to .ts. This guideline applies to all similar route files under src/api across the repository.

Applied to files:

  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
📚 Learning: 2025-12-30T00:13:37.849Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 355
File: packages/server/src/api/sandbox/util.ts:2-6
Timestamp: 2025-12-30T00:13:37.849Z
Learning: In the packages/server tree, treat code as runtime-agnostic between Node.js and Bun. Ensure TypeScript files (e.g., util.ts) import and use APIs in a way that works under both runtimes. It is acceptable to rely on Bun’s Node.js compatibility for built-ins accessed via the node: namespace (e.g., node:events, node:stream, node:buffer). During reviews, prefer patterns and imports that remain compatible with Bun's environment, and flag any hard dependencies on runtime-specific globals or non-portable Node APIs.

Applied to files:

  • packages/server/src/api/sandbox/create.ts
  • packages/server/src/api/sandbox/get.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Package Installation & Usage Test
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Cloud Deployment Tests
🔇 Additional comments (2)
packages/core/src/services/sandbox.ts (1)

463-467: Packages fields look good in core sandbox types.

Clear docs and optionality mirror the existing dependencies surface cleanly.

Also applies to: 711-714

packages/server/src/api/sandbox/get.ts (1)

122-129: Packages field is wired through schema and response mapping.

Nice and consistent with other sandbox metadata.

Also applies to: 215-216

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/cli/src/cmd/cloud/sandbox/get.ts`:
- Around line 139-171: The CLI builds tableData from result but never includes
result.packages nor returns packages in the JSON response; update the display
and return to surface packages by adding a tableData['Packages'] entry when
result.packages exists (e.g., tableData['Packages'] = result.packages.join(',
')) and include packages: result.packages in the final returned object alongside
the other fields (sandboxId, name, description, etc.) so both the tui.table
output and the function's JSON return expose the packages field.

In `@packages/server/src/api/sandbox/create.ts`:
- Around line 85-92: The packages array currently accepts arbitrary strings; add
server-side package-name validation by replacing the freeform
z.array(z.string()) for the "packages" field in create.ts with the same
package-name validator used elsewhere (e.g., a PackageNameSchema or similar
validator) so only safe npm/bun package names are allowed, and apply the
identical change to SnapshotBuildFileBaseSchema in snapshot-build.ts (the
packages field in that schema) so both endpoints enforce the same validated
package-name format and block injection vectors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Snapshot build: support npm/bun dependencies in declarative YAML

1 participant