38d44a6ff8d439aa808e02e2c1474dbde88ea364
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
397c34142a |
Deepen SDK package seam and converge runtime skills policy (#3238)
* Deepen SDK package seam and converge runtime skills policy * fix(sdk): unified install-root resolution for workflows and agents (CR finding 1) Use the already-resolved gsdInstallDir constant instead of calling resolveLegacyInstallDir() again when computing agentsDir, ensuring workflowsDir and agentsDir share the same install root. * fix(sdk): tilde shortening requires path-boundary match (CR finding 2) Both renderGlobalSkillsBaseDisplayPath and renderGlobalSkillDisplayPath used startsWith(home) which could incorrectly shorten unrelated paths sharing the same prefix. Now checks for home === base or base.startsWith(home + sep) to ensure a real directory boundary. * fix(sdk): validate loadConfig export before invocation (CR finding 3) After requiring core.cjs, check typeof mod.loadConfig === 'function' before calling it. Throws a classified GSDError with the module path if the export is missing, rather than a generic TypeError. * fix(test): guard root lookup before .path dereference (CR finding 4) Added assert.ok() guards for claudeRoot and codexRoot after the .find() calls so that a missing root produces an explicit assertion failure rather than a TypeError on .path dereference. * fix(ci): fail-safe on transient API errors in approval dismissal (CR finding 6) resolveRole() returns 'unknown' for non-404 errors (rate limits, 5xx, network blips). shouldDismissReviewer() now treats 'unknown' as unresolvable and skips dismissal, preventing legitimate approvals from being dismissed due to a transient API failure. Only 'none' (true 404) is treated as a confirmed non-collaborator. * changeset: pr=3238 SDK package seam and runtime skills convergence * fix(sdk): harden resolveGlobalSkillDir against path traversal (CR finding 1) Use resolve+relative to validate that skillName cannot escape the global skills base directory. Values like "../../foo" or absolute paths now return null instead of joining directly. All imports (resolve, relative, isAbsolute) were already present in helpers.ts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(sdk): split skill-dir-resolution and skill-not-found warnings (CR finding 2) After resolveGlobalSkillDir's hardening can return null for traversal attempts, the old single-branch warning "Global skill not found at ..." was misleading. Split into two distinct cases: - skillDir === null → "Could not resolve global skill directory for ..." - skillMd missing → "Global skill not found at ..." Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: lock skill path-traversal rejection in resolveGlobalSkillDir Regression test verifying that traversal segments (../../foo, ../escape), empty string, and absolute paths are all rejected (return null), while a legitimate skill name resolves correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(sdk): align display-path contract + traversal coverage for resolveGlobalSkillMarkdownPath (CR nitpicks) - renderGlobalSkillsBaseDisplayPath now returns a non-null string for unsupported runtimes (e.g. cline → "(cline does not use a skills directory)") matching the existing renderGlobalSkillDisplayPath contract; callers of both helpers no longer need null-checks for unsupported runtimes. - Remove now-redundant ! non-null assertion on renderGlobalSkillsBaseDisplayPath calls in skill-manifest.ts (return type is string, not string | null). - Extend the path-traversal test block to assert resolveGlobalSkillMarkdownPath also propagates null for ../../foo, ../escape, empty, and /abs/path inputs, locking the null-propagation contract against future refactors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
377a6d2c6e |
fix(sdk): use installed agent/workflow prompts instead of stripped-down bundled copies
The SDK bundled its own agents and workflows at ~17% the size of the real ones, missing critical instructions like file naming conventions, scope reduction rules, discovery protocols, and TDD integration. This caused the planner to create a single PLAN.md instead of properly named per-plan files (01-01-PLAN.md, 01-02-PLAN.md), breaking wave-based parallel execution. - Invert load priority: installed GSD agents/workflows first, SDK bundled as last-resort fallback - Replace @-reference stripping with resolution (read + inline content) - Use full agent definitions instead of extracting only the <role> block - Delete sdk/prompts/agents/ and sdk/prompts/workflows/ (13 files) - Delete headless-prompts.test.ts (validated deleted files) - Thread projectDir through sanitizePrompt for @-reference resolution Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
8ac02084be | fix(sdk): point checkAgentsInstalled at ~/.claude/agents (#2401) | ||
|
|
89f95c43ba |
feat: auto --init flag, headless prompts, and prompt sanitizer (#1417)
* fix: Created 10 headless prompt files (5 workflows + 5 agents) in sdk/p… - "sdk/prompts/workflows/execute-plan.md" - "sdk/prompts/workflows/research-phase.md" - "sdk/prompts/workflows/plan-phase.md" - "sdk/prompts/workflows/verify-phase.md" - "sdk/prompts/workflows/discuss-phase.md" - "sdk/prompts/agents/gsd-executor.md" - "sdk/prompts/agents/gsd-phase-researcher.md" - "sdk/prompts/agents/gsd-planner.md" GSD-Task: S01/T02 * feat: Created prompt-sanitizer.ts, wired headless prompt loading into P… - "sdk/src/prompt-sanitizer.ts" - "sdk/src/phase-prompt.ts" - "sdk/src/gsd-tools.ts" - "sdk/src/gsd-tools.test.ts" - "sdk/src/phase-runner-types.test.ts" GSD-Task: S01/T01 * test: Added 111 unit tests covering sanitizePrompt(), headless prompt l… - "sdk/src/prompt-sanitizer.test.ts" - "sdk/src/headless-prompts.test.ts" - "sdk/src/phase-prompt.test.ts" GSD-Task: S01/T03 * feat: Wired sdkPromptsDir preference and sanitizePrompt into InitRunner… - "sdk/src/init-runner.ts" - "sdk/package.json" GSD-Task: S02/T01 * feat: add --init flag to auto command for single-command PRD-to-execution gsd-sdk auto --init @path/to/prd.md now bootstraps the project (init) then immediately runs the autonomous phase execution loop. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add remaining headless prompt files and templates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: Extended init-runner.test.ts with 7 sdkPromptsDir preference and… - "sdk/src/init-runner.test.ts" GSD-Task: S02/T03 --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
596ce2d252 |
feat: GSD SDK — headless CLI with init + auto commands (#1407)
* test: Bootstrapped sdk/ as TypeScript ESM package with full GSD-1 PLAN.… - "sdk/package.json" - "sdk/tsconfig.json" - "sdk/vitest.config.ts" - "sdk/src/types.ts" - "sdk/src/plan-parser.ts" - "sdk/src/plan-parser.test.ts" GSD-Task: S01/T01 * test: Implemented config reader and gsd-tools bridge with 25 unit tests… - "sdk/src/config.ts" - "sdk/src/config.test.ts" - "sdk/src/gsd-tools.ts" - "sdk/src/gsd-tools.test.ts" GSD-Task: S01/T02 * test: Built prompt-builder, session-runner, and GSD class — 85 total un… - "sdk/src/prompt-builder.ts" - "sdk/src/prompt-builder.test.ts" - "sdk/src/session-runner.ts" - "sdk/src/index.ts" - "sdk/src/types.ts" GSD-Task: S01/T03 * test: Created E2E integration test with fixtures proving full SDK pipel… - "sdk/src/e2e.integration.test.ts" - "sdk/test-fixtures/sample-plan.md" - "sdk/test-fixtures/.planning/config.json" - "sdk/test-fixtures/.planning/STATE.md" - "vitest.config.ts" - "tsconfig.json" GSD-Task: S01/T04 * test: Added PhaseType/GSDEventType enums, 16-variant GSDEvent union, GS… - "sdk/src/types.ts" - "sdk/src/event-stream.ts" - "sdk/src/logger.ts" - "sdk/src/event-stream.test.ts" - "sdk/src/logger.test.ts" GSD-Task: S02/T01 * test: Built ContextEngine for phase-aware context file resolution, getT… - "sdk/src/context-engine.ts" - "sdk/src/tool-scoping.ts" - "sdk/src/phase-prompt.ts" - "sdk/src/context-engine.test.ts" - "sdk/src/tool-scoping.test.ts" - "sdk/src/phase-prompt.test.ts" GSD-Task: S02/T02 * test: Wired event stream into session runner, added onEvent()/addTransp… - "sdk/src/session-runner.ts" - "sdk/src/index.ts" - "sdk/src/e2e.integration.test.ts" GSD-Task: S02/T03 * feat: Added PhaseStepType enum, PhaseOpInfo interface, phase lifecycle… - "sdk/src/types.ts" - "sdk/src/gsd-tools.ts" - "sdk/src/session-runner.ts" - "sdk/src/index.ts" - "sdk/src/phase-runner-types.test.ts" GSD-Task: S03/T01 * test: Implemented PhaseRunner state machine with 39 unit tests covering… - "sdk/src/phase-runner.ts" - "sdk/src/phase-runner.test.ts" GSD-Task: S03/T02 * test: Wired PhaseRunner into GSD.runPhase() public API with full re-exp… - "sdk/src/index.ts" - "sdk/src/phase-runner.integration.test.ts" - "sdk/src/phase-runner.ts" GSD-Task: S03/T03 * test: Expanded runVerifyStep with full gap closure cycle (plan → execut… - "sdk/src/types.ts" - "sdk/src/phase-runner.ts" - "sdk/src/phase-runner.test.ts" GSD-Task: S04/T02 * fix: Added 3 integration tests proving phasePlanIndex returns correct t… - "sdk/src/phase-runner.integration.test.ts" - "sdk/src/index.ts" GSD-Task: S04/T03 * test: Add milestone-level types, typed roadmapAnalyze(), GSD.run() orch… - "sdk/src/types.ts" - "sdk/src/gsd-tools.ts" - "sdk/src/index.ts" - "sdk/src/milestone-runner.test.ts" GSD-Task: S05/T01 * test: Added CLITransport (structured stdout log lines) and WSTransport… - "sdk/src/cli-transport.ts" - "sdk/src/cli-transport.test.ts" - "sdk/src/ws-transport.ts" - "sdk/src/ws-transport.test.ts" - "sdk/src/index.ts" - "sdk/package.json" GSD-Task: S05/T02 * test: Added gsd-sdk CLI entry point with argument parsing, bin field, p… - "sdk/src/cli.ts" - "sdk/src/cli.test.ts" - "sdk/package.json" GSD-Task: S05/T03 * feat: Add InitNewProjectInfo type, initNewProject()/configSet() GSDTool… - "sdk/src/types.ts" - "sdk/src/gsd-tools.ts" - "sdk/src/cli.ts" - "sdk/src/cli.test.ts" - "sdk/src/gsd-tools.test.ts" GSD-Task: S01/T01 * chore: Created InitRunner orchestrator with setup → config → PROJECT.md… - "sdk/src/init-runner.ts" - "sdk/src/types.ts" - "sdk/src/index.ts" GSD-Task: S01/T02 * test: Wired InitRunner into CLI main() for full gsd-sdk init dispatch a… - "sdk/src/cli.ts" - "sdk/src/init-runner.test.ts" - "sdk/src/cli.test.ts" GSD-Task: S01/T03 * test: Add PlanCheck step, AI self-discuss, and retryOnce wrapper to Pha… - "sdk/src/types.ts" - "sdk/src/phase-runner.ts" - "sdk/src/session-runner.ts" - "sdk/src/phase-runner.test.ts" - "sdk/src/phase-runner-types.test.ts" GSD-Task: S02/T01 * feat: Rewrite CLITransport with ANSI colors, phase banners, spawn indic… - "sdk/src/cli-transport.ts" - "sdk/src/cli-transport.test.ts" GSD-Task: S02/T02 * test: Add `gsd-sdk auto` command with autoMode config override, USAGE t… - "sdk/src/cli.ts" - "sdk/src/cli.test.ts" - "sdk/src/index.ts" - "sdk/src/types.ts" GSD-Task: S02/T03 * fix: CLI shebang + gsd-tools non-JSON output handling Three bugs found during first real gsd-sdk run: 1. cli.ts shebang was commented out — shell executed JS as bash, triggering ImageMagick's import command instead of Node 2. configSet() called exec() which JSON.parse()d the output, but gsd-tools config-set returns 'key=value' text, not JSON. Added execRaw() method for commands that return plain text. 3. Same JSON parse bug affected commit() (returns git SHA), stateLoad(), verifySummary(), initExecutePhase(), stateBeginPhase(), and phaseComplete(). All switched to execRaw(). Tests updated to match real gsd-tools output format (plain text instead of mocked JSON). 376/376 tests pass. |