Add Coder workspace prompt modes and custom skills#1448
Conversation
|
The latest Agentuity deployment details.
|
📝 WalkthroughWalkthroughWorkspace APIs and CLI gain support for an optional workspace-level system prompt and a system-prompt mode. CLI create/update commands accept inline or file-based prompts with validation. Separately, a new custom-skill creation API and CLI command were added to create SKILL.md-backed custom skills. Tests added/updated for both features. ChangesWorkspace System Prompt Support
Custom Skill Creation (SKILL.md-backed)
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
📦 Canary Packages Publishedversion: PackagesInstallAdd to your {
"dependencies": {
"@agentuity/keyvalue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-keyvalue-2.0.14-4302280.tgz",
"@agentuity/task": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-task-2.0.14-4302280.tgz",
"@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-opencode-2.0.14-4302280.tgz",
"@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-evals-2.0.14-4302280.tgz",
"@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-schema-2.0.14-4302280.tgz",
"@agentuity/vector": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-vector-2.0.14-4302280.tgz",
"@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-frontend-2.0.14-4302280.tgz",
"@agentuity/claude-code": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-claude-code-2.0.14-4302280.tgz",
"@agentuity/migrate": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-migrate-2.0.14-4302280.tgz",
"@agentuity/coder-tui": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-coder-tui-2.0.14-4302280.tgz",
"@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-core-2.0.14-4302280.tgz",
"@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-workbench-2.0.14-4302280.tgz",
"@agentuity/coder": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-coder-2.0.14-4302280.tgz",
"@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-cli-2.0.14-4302280.tgz",
"@agentuity/sandbox": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-sandbox-2.0.14-4302280.tgz",
"@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-postgres-2.0.14-4302280.tgz",
"@agentuity/webhook": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-webhook-2.0.14-4302280.tgz",
"@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-auth-2.0.14-4302280.tgz",
"@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-drizzle-2.0.14-4302280.tgz",
"@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-runtime-2.0.14-4302280.tgz",
"@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-react-2.0.14-4302280.tgz",
"@agentuity/queue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-queue-2.0.14-4302280.tgz",
"@agentuity/schedule": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-schedule-2.0.14-4302280.tgz",
"@agentuity/email": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-email-2.0.14-4302280.tgz",
"@agentuity/db": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-db-2.0.14-4302280.tgz",
"@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-server-2.0.14-4302280.tgz"
}
}Or install directly: bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-keyvalue-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-task-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-opencode-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-evals-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-schema-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-vector-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-frontend-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-claude-code-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-migrate-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-coder-tui-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-core-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-workbench-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-coder-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-cli-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-sandbox-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-postgres-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-webhook-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-auth-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-drizzle-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-runtime-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-react-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-queue-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-schedule-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-email-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-db-2.0.14-4302280.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.14-4302280/agentuity-server-2.0.14-4302280.tgz |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/cli/test/cmd/coder/workspace.test.ts`:
- Around line 225-284: Replace the manual globalThis.fetch assignments in the
"create handler sends inline system prompt" and "create handler reads system
prompt from file" tests by importing and using mockFetch from
`@agentuity/test-utils`; specifically, remove the globalThis.fetch = (...) blocks
and wrap the async handler logic with mockFetch(async (url, init) => {
expect(String(url)).toBe(...); expect(init?.method).toBe('POST'); requestBody =
JSON.parse(String(init?.body)); return jsonResponse(...); }); keep the same
assertions against requestBody and result, and ensure any temp-dir cleanup
remains; reference the test cases and createWorkspaceSubcommand.handler so you
replace the manual fetch mocking with mockFetch for both tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a13bb8c0-d310-4ed7-9848-67f488733254
📒 Files selected for processing (6)
packages/cli/src/cmd/coder/workspace/common.tspackages/cli/src/cmd/coder/workspace/create.tspackages/cli/src/cmd/coder/workspace/update.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/src/services/coder/types.tspackages/core/test/coder-client.test.ts
📜 Review details
⏰ 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). (13)
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: Template Integration Tests
- GitHub Check: Queue CLI Tests
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Standalone Agent Test
- GitHub Check: Postgres SSL Integration Test
- GitHub Check: Cloud Deployment Tests
- GitHub Check: Package Installation & Usage Test
- GitHub Check: Windows WSL CLI Smoke Test
- GitHub Check: Pack & Upload
- GitHub Check: Build
- GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (6)
packages/cli/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/create.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome as code formatter with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5
Files:
packages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/create.tspackages/core/test/coder-client.test.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/src/services/coder/types.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use TypeScript Strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/create.tspackages/core/test/coder-client.test.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/src/services/coder/types.ts
**/test/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.{ts,tsx}: Place tests intest/folder, never insrc/or__tests__/directories
Import from../src/in test files
Use@agentuity/test-utilsfor mocks in tests
Files:
packages/core/test/coder-client.test.tspackages/cli/test/cmd/coder/workspace.test.ts
packages/core/**/*.test.ts
📄 CodeRabbit inference engine (packages/core/AGENTS.md)
Use Bun's built-in test runner with
bun testcommand
Files:
packages/core/test/coder-client.test.ts
packages/core/src/**/*.ts
📄 CodeRabbit inference engine (packages/core/AGENTS.md)
packages/core/src/**/*.ts: Build TypeScript withbun run buildcommand
Run TypeScript type checking withbun run typecheckcommand
Ensure runtime compatibility with both Browser and Node/Bun environments with no runtime-specific code
Build target must be ESNext with TypeScript declaration files
Prefer interfaces for public APIs
Use generics for reusable type utilities
Ensure no side effects in all exports - all exports must be pure with no global mutations
All relative imports in TypeScript files MUST include the.tsextension
Runbun run buildbefore publishing to compile TypeScript
Files:
packages/core/src/services/coder/types.ts
🧠 Learnings (3)
📚 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/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/create.tspackages/core/test/coder-client.test.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/src/services/coder/types.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/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/create.tspackages/cli/src/cmd/coder/workspace/common.ts
📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1010
File: packages/drizzle/test/proxy.test.ts:594-603
Timestamp: 2026-02-21T02:05:57.982Z
Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.
Applied to files:
packages/core/test/coder-client.test.tspackages/cli/test/cmd/coder/workspace.test.ts
| test('create handler sends inline system prompt', async () => { | ||
| let requestBody: unknown; | ||
| globalThis.fetch = (async (url: string, init?: RequestInit) => { | ||
| expect(String(url)).toBe('https://coder.example/api/hub/workspaces'); | ||
| expect(init?.method).toBe('POST'); | ||
| requestBody = JSON.parse(String(init?.body)); | ||
| return jsonResponse({ | ||
| workspace: makeWorkspace({ | ||
| systemPrompt: 'Follow the release checklist.', | ||
| selectionCount: 1, | ||
| }), | ||
| }); | ||
| }) as typeof globalThis.fetch; | ||
|
|
||
| const result = await createWorkspaceSubcommand.handler( | ||
| makeContext({ opts: { systemPrompt: 'Follow the release checklist.' }, json: true }) | ||
| ); | ||
|
|
||
| expect(requestBody).toMatchObject({ | ||
| name: 'My Workspace', | ||
| systemPrompt: 'Follow the release checklist.', | ||
| }); | ||
| expect(result).toMatchObject({ | ||
| systemPrompt: 'Follow the release checklist.', | ||
| }); | ||
| }); | ||
|
|
||
| test('create handler reads system prompt from file', async () => { | ||
| const dir = mkdtempSync(join(tmpdir(), 'agentuity-workspace-prompt-test-')); | ||
| const systemPromptFile = join(dir, 'WORKSPACE_PROMPT.md'); | ||
| writeFileSync(systemPromptFile, 'Prefer small changes.\n'); | ||
| let requestBody: unknown; | ||
| try { | ||
| globalThis.fetch = (async (url: string, init?: RequestInit) => { | ||
| expect(String(url)).toBe('https://coder.example/api/hub/workspaces'); | ||
| expect(init?.method).toBe('POST'); | ||
| requestBody = JSON.parse(String(init?.body)); | ||
| return jsonResponse({ | ||
| workspace: makeWorkspace({ | ||
| systemPrompt: 'Prefer small changes.\n', | ||
| selectionCount: 1, | ||
| }), | ||
| }); | ||
| }) as typeof globalThis.fetch; | ||
|
|
||
| const result = await createWorkspaceSubcommand.handler( | ||
| makeContext({ opts: { systemPromptFile }, json: true }) | ||
| ); | ||
|
|
||
| expect(requestBody).toMatchObject({ | ||
| name: 'My Workspace', | ||
| systemPrompt: 'Prefer small changes.\n', | ||
| }); | ||
| expect(result).toMatchObject({ | ||
| systemPrompt: 'Prefer small changes.\n', | ||
| }); | ||
| } finally { | ||
| rmSync(dir, { recursive: true, force: true }); | ||
| } | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify direct fetch monkey-patching in this test file.
rg -n -C2 'globalThis\.fetch\s*=' packages/cli/test/cmd/coder/workspace.test.tsRepository: agentuity/sdk
Length of output: 4657
🏁 Script executed:
# Check if `@agentuity/test-utils` is imported anywhere and how it's used
rg -n '@agentuity/test-utils' packages/cli/test/ --type ts --type tsxRepository: agentuity/sdk
Length of output: 85
🏁 Script executed:
# Check what's exported from `@agentuity/test-utils`
fd -e ts -e tsx -path '*/test-utils/*' | head -20Repository: agentuity/sdk
Length of output: 226
🏁 Script executed:
# Check if there are other test files and how they handle mocking
fd -e test.ts -e test.tsx packages/cli/test/ | head -10Repository: agentuity/sdk
Length of output: 435
🏁 Script executed:
# Look at package.json to understand dependencies
cat package.json | grep -A 5 -B 5 'test-utils'Repository: agentuity/sdk
Length of output: 39
🏁 Script executed:
# Search for `@agentuity/test-utils` imports in test files
rg '@agentuity/test-utils' packages/cli/test/Repository: agentuity/sdk
Length of output: 783
🏁 Script executed:
# Find all test files
fd -e test.ts packages/cli/test/Repository: agentuity/sdk
Length of output: 435
🏁 Script executed:
# Check if `@agentuity/test-utils` package exists and what it exports
find . -path '*/test-utils/*' -name '*.ts' 2>/dev/null | head -20Repository: agentuity/sdk
Length of output: 215
🏁 Script executed:
# Look at the current test file's imports
head -50 packages/cli/test/cmd/coder/workspace.test.tsRepository: agentuity/sdk
Length of output: 1704
🏁 Script executed:
# Check the mockFetch implementation
cat packages/test-utils/src/mock-fetch.tsRepository: agentuity/sdk
Length of output: 1089
🏁 Script executed:
# Check how mockFetch is used in an example test file
grep -A 20 'mockFetch' packages/cli/test/upgrade.test.ts | head -40Repository: agentuity/sdk
Length of output: 1386
🏁 Script executed:
# Check if workspace.test.ts has any imports from `@agentuity/test-utils`
grep -n 'import.*@agentuity/test-utils' packages/cli/test/cmd/coder/workspace.test.tsRepository: agentuity/sdk
Length of output: 39
Use mockFetch from @agentuity/test-utils instead of manually patching globalThis.fetch.
The new system-prompt tests at lines 225–284 and 346–420 manually assign to globalThis.fetch. Replace with mockFetch(async (url, init) => { ... }) to align with the repo's test mocking standard and match usage in other test files (e.g., upgrade.test.ts).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/cli/test/cmd/coder/workspace.test.ts` around lines 225 - 284,
Replace the manual globalThis.fetch assignments in the "create handler sends
inline system prompt" and "create handler reads system prompt from file" tests
by importing and using mockFetch from `@agentuity/test-utils`; specifically,
remove the globalThis.fetch = (...) blocks and wrap the async handler logic with
mockFetch(async (url, init) => { expect(String(url)).toBe(...);
expect(init?.method).toBe('POST'); requestBody = JSON.parse(String(init?.body));
return jsonResponse(...); }); keep the same assertions against requestBody and
result, and ensure any temp-dir cleanup remains; reference the test cases and
createWorkspaceSubcommand.handler so you replace the manual fetch mocking with
mockFetch for both tests.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/cli/src/cmd/coder/skill/create.ts (2)
112-120: 💤 Low valueAdd
returnaftertui.fatalto prevent fall-through.If
tui.fataldoesn't immediately terminate the process (e.g., in test environments where it throws), the code falls through to line 118-119 and callstui.fatalagain. Add an explicitreturnfor defensive clarity.♻️ Proposed fix
} catch (err) { if (err instanceof ValidationOutputError) { ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown'); ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2)); tui.fatal(`Failed to create custom skill: ${err.message}`, ErrorCode.VALIDATION_FAILED); + return; } const msg = err instanceof Error ? err.message : String(err); tui.fatal(`Failed to create custom skill: ${msg}`, ErrorCode.NETWORK_ERROR); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/cli/src/cmd/coder/skill/create.ts` around lines 112 - 120, The catch block handling ValidationOutputError can fall-through and call tui.fatal twice; after calling tui.fatal inside the if (err instanceof ValidationOutputError) branch add an explicit return to stop execution; update the catch in createSkill (or the surrounding function handling skill creation) so that after ctx.logger.trace(...) and tui.fatal(`Failed to create custom skill: ${err.message}`, ErrorCode.VALIDATION_FAILED) the function returns immediately, preventing the subsequent generic tui.fatal(...) for ErrorCode.NETWORK_ERROR from also running.
9-30: 💤 Low valueConsider using
StructuredErrorfor consistency with similar helpers.The
readSkillContenthelper uses plainError, while the analogousreadSystemPromptandreadSetupScriptinworkspace/common.tsuseStructuredError. For consistency across the codebase, consider usingStructuredErrorhere as well.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/cli/src/cmd/coder/skill/create.ts` around lines 9 - 30, The helper readSkillContent currently throws plain Error values; change it to throw StructuredError instances for consistency with readSystemPrompt and readSetupScript: import or reference StructuredError and replace the three Error throws (conflicting flags, missing input, and file read failure) with new StructuredError(...) preserving the same messages and the file read failure should include the original error as the cause (or StructuredError field) just like the other helpers do. Ensure the thrown StructuredError uses the same message formatting as before and includes the underlying error details when wrapping the Bun.file read failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/cli/test/cmd/coder/skill.test.ts`:
- Around line 63-71: Replace manual globalThis.fetch reassignment and
RELATED_ORIGINAL_FETCH scaffolding in the test file with the mockFetch helper
from `@agentuity/test-utils`: remove uses of ORIGINAL_FETCH and any
globalThis.fetch reset in beforeEach/afterEach and test blocks, import mockFetch
and call mockFetch(...) in each test to set up responses, and remove manual
cleanup for fetch (mockFetch handles teardown). Update tests that reference
ORIGINAL_FETCH/globalThis.fetch to use the mockFetch return semantics (e.g.,
providing response bodies/status) and ensure no direct process of reassigning
globalThis.fetch remains in functions like the beforeEach/afterEach hooks or the
individual tests that previously set fetch.
---
Nitpick comments:
In `@packages/cli/src/cmd/coder/skill/create.ts`:
- Around line 112-120: The catch block handling ValidationOutputError can
fall-through and call tui.fatal twice; after calling tui.fatal inside the if
(err instanceof ValidationOutputError) branch add an explicit return to stop
execution; update the catch in createSkill (or the surrounding function handling
skill creation) so that after ctx.logger.trace(...) and tui.fatal(`Failed to
create custom skill: ${err.message}`, ErrorCode.VALIDATION_FAILED) the function
returns immediately, preventing the subsequent generic tui.fatal(...) for
ErrorCode.NETWORK_ERROR from also running.
- Around line 9-30: The helper readSkillContent currently throws plain Error
values; change it to throw StructuredError instances for consistency with
readSystemPrompt and readSetupScript: import or reference StructuredError and
replace the three Error throws (conflicting flags, missing input, and file read
failure) with new StructuredError(...) preserving the same messages and the file
read failure should include the original error as the cause (or StructuredError
field) just like the other helpers do. Ensure the thrown StructuredError uses
the same message formatting as before and includes the underlying error details
when wrapping the Bun.file read failure.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 06390b94-cffc-405e-a180-96b5dcdf5d3a
📒 Files selected for processing (11)
packages/cli/src/cmd/coder/skill/create.tspackages/cli/src/cmd/coder/skill/index.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/src/cmd/coder/workspace/create.tspackages/cli/src/cmd/coder/workspace/update.tspackages/cli/test/cmd/coder/skill.test.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/src/services/coder/client.tspackages/core/src/services/coder/skills.tspackages/core/src/services/coder/types.tspackages/core/test/coder-client.test.ts
📜 Review details
⏰ 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). (13)
- GitHub Check: Queue CLI Tests
- GitHub Check: Windows WSL CLI Smoke Test
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: Standalone Agent Test
- GitHub Check: Cloud Deployment Tests
- GitHub Check: Package Installation & Usage Test
- GitHub Check: Postgres SSL Integration Test
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Template Integration Tests
- GitHub Check: Pack & Upload
- GitHub Check: Build
- GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (8)
packages/cli/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/src/cmd/coder/workspace/create.tspackages/cli/src/cmd/coder/skill/create.tspackages/cli/test/cmd/coder/skill.test.tspackages/cli/src/cmd/coder/skill/index.tspackages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome as code formatter with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5
Files:
packages/cli/src/cmd/coder/workspace/create.tspackages/cli/src/cmd/coder/skill/create.tspackages/cli/test/cmd/coder/skill.test.tspackages/cli/src/cmd/coder/skill/index.tspackages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/test/coder-client.test.tspackages/core/src/services/coder/client.tspackages/core/src/services/coder/skills.tspackages/core/src/services/coder/types.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use TypeScript Strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/cli/src/cmd/coder/workspace/create.tspackages/cli/src/cmd/coder/skill/create.tspackages/cli/test/cmd/coder/skill.test.tspackages/cli/src/cmd/coder/skill/index.tspackages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/test/coder-client.test.tspackages/core/src/services/coder/client.tspackages/core/src/services/coder/skills.tspackages/core/src/services/coder/types.ts
**/test/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.{ts,tsx}: Place tests intest/folder, never insrc/or__tests__/directories
Import from../src/in test files
Use@agentuity/test-utilsfor mocks in tests
Files:
packages/cli/test/cmd/coder/skill.test.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/test/coder-client.test.ts
packages/cli/src/cmd/**/index.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
packages/cli/src/cmd/**/index.ts: Each command must be structured as a directory insrc/cmd/with anindex.tsfile as the entry point
Always define interfaces or Zod schemas for command options; never useanytype for type safety
Usetui.*helpers (header, info, success, warning, error, table, progress) for formatted TUI output instead of raw console methods
Usectx.loggerfor logging instead of console methods; uselogger.fatal()for fatal errors which logs and exits with code 1
Always checkisJSONMode()before outputting data and provide machine-readable output when in JSON mode
UserequireAuth(ctx)for commands that require authentication oroptionalAuth(ctx)for commands that support optional authentication
Files:
packages/cli/src/cmd/coder/skill/index.ts
**/index.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use named exports from package
index.tsfiles
Files:
packages/cli/src/cmd/coder/skill/index.ts
packages/core/**/*.test.ts
📄 CodeRabbit inference engine (packages/core/AGENTS.md)
Use Bun's built-in test runner with
bun testcommand
Files:
packages/core/test/coder-client.test.ts
packages/core/src/**/*.ts
📄 CodeRabbit inference engine (packages/core/AGENTS.md)
packages/core/src/**/*.ts: Build TypeScript withbun run buildcommand
Run TypeScript type checking withbun run typecheckcommand
Ensure runtime compatibility with both Browser and Node/Bun environments with no runtime-specific code
Build target must be ESNext with TypeScript declaration files
Prefer interfaces for public APIs
Use generics for reusable type utilities
Ensure no side effects in all exports - all exports must be pure with no global mutations
All relative imports in TypeScript files MUST include the.tsextension
Runbun run buildbefore publishing to compile TypeScript
Files:
packages/core/src/services/coder/client.tspackages/core/src/services/coder/skills.tspackages/core/src/services/coder/types.ts
🧠 Learnings (3)
📚 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/coder/workspace/create.tspackages/cli/src/cmd/coder/skill/create.tspackages/cli/test/cmd/coder/skill.test.tspackages/cli/src/cmd/coder/skill/index.tspackages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/common.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/test/coder-client.test.tspackages/core/src/services/coder/client.tspackages/core/src/services/coder/skills.tspackages/core/src/services/coder/types.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/coder/workspace/create.tspackages/cli/src/cmd/coder/skill/create.tspackages/cli/src/cmd/coder/skill/index.tspackages/cli/src/cmd/coder/workspace/update.tspackages/cli/src/cmd/coder/workspace/common.ts
📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1010
File: packages/drizzle/test/proxy.test.ts:594-603
Timestamp: 2026-02-21T02:05:57.982Z
Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.
Applied to files:
packages/cli/test/cmd/coder/skill.test.tspackages/cli/test/cmd/coder/workspace.test.tspackages/core/test/coder-client.test.ts
🔇 Additional comments (13)
packages/cli/test/cmd/coder/workspace.test.ts (2)
226-294: UsemockFetchfrom@agentuity/test-utilsinstead of directly patchingglobalThis.fetch.The new system prompt tests manually assign to
globalThis.fetch. Per coding guidelines, tests should usemockFetchfrom@agentuity/test-utilsfor mocking. This applies to lines 226-294, 356-406, and 433-456.
70-80: LGTM!The test fixtures are correctly extended with
systemPromptandsystemPromptModefields, and the test coverage is comprehensive—covering inline prompts, file-based prompts, mutual exclusivity validation, invalid mode validation, and file read errors.packages/cli/src/cmd/coder/workspace/common.ts (1)
1-148: LGTM!The implementation follows established patterns (mirroring
readSetupScript), usesStructuredErrorcorrectly per coding guidelines, and thenormalizeSystemPromptModefunction properly validates the mode values. TheprintWorkspaceSummaryupdate correctly displays the prompt mode when a system prompt is configured.packages/cli/src/cmd/coder/workspace/create.ts (1)
139-151: LGTM!The system prompt handling follows the same pattern as the existing setup script handling, with proper error handling and validation. The CLI options are well-documented and the example demonstrates the new functionality clearly.
packages/cli/src/cmd/coder/workspace/update.ts (1)
125-137: LGTM!The update handler correctly mirrors the create handler's system prompt handling, allowing users to update the system prompt and mode independently. The error handling is consistent with the rest of the codebase.
packages/core/src/services/coder/types.ts (2)
45-48: LGTM!The
CoderWorkspaceSystemPromptModeSchemaenum is well-defined with clear semantics ('append' vs 'overwrite') and a descriptive comment explaining its purpose.
569-580: LGTM!The
CoderCreateCustomSkillRequestSchemacorrectly uses a Zod refine to enforce non-empty content, which provides a clear validation error message for the required SKILL.md content.packages/core/src/services/coder/skills.ts (1)
64-79: LGTM!The
coderCreateCustomSkillfunction follows a clean pattern: validating input with the schema, then delegating tocoderSaveSkillwith the appropriatesourceandrepovalues set to'custom'. The conditional description spread avoids sendingundefinedvalues.packages/core/src/services/coder/client.ts (1)
454-460: LGTM!The
createCustomSkillmethod follows the established pattern used by other skill methods in the class, with a clear JSDoc comment and proper delegation to the helper function.packages/cli/src/cmd/coder/skill/index.ts (1)
20-25: Nice addition of custom-skill discoverability and routing.The new example and subcommand registration are consistent and make the
coder skill createflow easy to find.Also applies to: 41-47
packages/cli/test/cmd/coder/skill.test.ts (1)
146-183: Good local-validation coverage for mutually exclusive and required content flags.The tests correctly ensure no network call is attempted on invalid CLI input paths.
packages/core/test/coder-client.test.ts (2)
458-484: System-prompt schema and payload tests look solid.These assertions cover acceptance/rejection boundaries and verify create/update request wiring for
systemPrompt+systemPromptMode.Also applies to: 672-774
951-1023: Custom-skill request and validation coverage is well targeted.Great job validating both happy-path payload shape and blank-content schema rejection.
| beforeEach(() => { | ||
| globalThis.fetch = ORIGINAL_FETCH; | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| process.exit = ORIGINAL_EXIT; | ||
| process.stderr.write = ORIGINAL_STDERR_WRITE; | ||
| globalThis.fetch = ORIGINAL_FETCH; | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use @agentuity/test-utils for fetch mocks instead of manual global reassignment.
Line [75] and related blocks manually override globalThis.fetch; this is brittle and conflicts with the test-mocking guideline for this repo. Please switch these to mockFetch(...) and drop the fetch reset scaffolding.
Proposed refactor pattern
import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
+import { mockFetch } from '@agentuity/test-utils';
...
-const ORIGINAL_FETCH = globalThis.fetch;
...
describe('coder skill commands', () => {
- beforeEach(() => {
- globalThis.fetch = ORIGINAL_FETCH;
- });
-
afterEach(() => {
process.exit = ORIGINAL_EXIT;
process.stderr.write = ORIGINAL_STDERR_WRITE;
- globalThis.fetch = ORIGINAL_FETCH;
});
...
- globalThis.fetch = (async (url: string, init?: RequestInit) => {
+ mockFetch(async (url, init) => {
expect(String(url)).toBe('https://coder.example/api/hub/skills/library');
expect(init?.method).toBe('POST');
requestBody = JSON.parse(String(init?.body));
return jsonResponse({ ... });
- }) as typeof globalThis.fetch;
+ });As per coding guidelines, "Use @agentuity/test-utils for mocks in tests".
Also applies to: 75-91, 117-133, 148-151, 172-175
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/cli/test/cmd/coder/skill.test.ts` around lines 63 - 71, Replace
manual globalThis.fetch reassignment and RELATED_ORIGINAL_FETCH scaffolding in
the test file with the mockFetch helper from `@agentuity/test-utils`: remove uses
of ORIGINAL_FETCH and any globalThis.fetch reset in beforeEach/afterEach and
test blocks, import mockFetch and call mockFetch(...) in each test to set up
responses, and remove manual cleanup for fetch (mockFetch handles teardown).
Update tests that reference ORIGINAL_FETCH/globalThis.fetch to use the mockFetch
return semantics (e.g., providing response bodies/status) and ensure no direct
process of reassigning globalThis.fetch remains in functions like the
beforeEach/afterEach hooks or the individual tests that previously set fetch.
Summary
createCustomSkillagentuity coder skill createwith--contentand--content-fileinputsTests
bun run buildfrompackages/corebun run typecheckfrompackages/corebun run typecheckfrompackages/clibun test packages/core/test/coder-client.test.ts packages/cli/test/cmd/coder/skill.test.ts packages/cli/test/cmd/coder/workspace.test.tsLinks
Summary by CodeRabbit
New Features
Tests