gsd-pi 2.76.0 → 2.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -25
- package/dist/claude-cli-check.js +32 -3
- package/dist/mcp-server.d.ts +7 -0
- package/dist/mcp-server.js +35 -1
- package/dist/onboarding.js +45 -0
- package/dist/resource-loader.d.ts +1 -1
- package/dist/resource-loader.js +2 -8
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +31 -8
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +77 -17
- package/dist/resources/extensions/gsd/auto/loop.js +9 -0
- package/dist/resources/extensions/gsd/auto/phases.js +104 -11
- package/dist/resources/extensions/gsd/auto/run-unit.js +38 -2
- package/dist/resources/extensions/gsd/auto/session.js +22 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -3
- package/dist/resources/extensions/gsd/auto-model-selection.js +53 -16
- package/dist/resources/extensions/gsd/auto-post-unit.js +25 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +32 -1
- package/dist/resources/extensions/gsd/auto-start.js +58 -57
- package/dist/resources/extensions/gsd/auto-verification.js +33 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
- package/dist/resources/extensions/gsd/auto.js +70 -28
- package/dist/resources/extensions/gsd/blocked-models.js +68 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +93 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +12 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +52 -6
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +84 -23
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +54 -89
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
- package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
- package/dist/resources/extensions/gsd/complexity-classifier.js +5 -3
- package/dist/resources/extensions/gsd/db-writer.js +88 -16
- package/dist/resources/extensions/gsd/doctor-git-checks.js +23 -29
- package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
- package/dist/resources/extensions/gsd/error-classifier.js +31 -3
- package/dist/resources/extensions/gsd/exec-history.js +120 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +168 -23
- package/dist/resources/extensions/gsd/guided-flow.js +190 -1
- package/dist/resources/extensions/gsd/health-widget.js +4 -1
- package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
- package/dist/resources/extensions/gsd/init-wizard.js +15 -1
- package/dist/resources/extensions/gsd/key-manager.js +28 -0
- package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
- package/dist/resources/extensions/gsd/memory-store.js +19 -0
- package/dist/resources/extensions/gsd/model-router.js +36 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +44 -9
- package/dist/resources/extensions/gsd/preferences-types.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
- package/dist/resources/extensions/gsd/preferences.js +17 -17
- package/dist/resources/extensions/gsd/prompt-loader.js +22 -7
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
- package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
- package/dist/resources/extensions/gsd/state.js +43 -4
- package/dist/resources/extensions/gsd/token-counter.js +22 -5
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
- package/dist/resources/extensions/gsd/tools/memory-tools.js +26 -1
- package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
- package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
- package/dist/resources/extensions/search-the-web/command-search-provider.js +5 -4
- package/dist/resources/extensions/search-the-web/native-search.js +45 -13
- package/dist/resources/skills/api-design/SKILL.md +190 -0
- package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
- package/dist/resources/skills/forensics/SKILL.md +153 -0
- package/dist/resources/skills/grill-me/SKILL.md +93 -0
- package/dist/resources/skills/handoff/SKILL.md +121 -0
- package/dist/resources/skills/observability/SKILL.md +174 -0
- package/dist/resources/skills/security-review/SKILL.md +181 -0
- package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/dist/resources/skills/tdd/SKILL.md +112 -0
- package/dist/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/dist/resources/skills/write-docs/SKILL.md +82 -0
- package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.js +6 -1
- package/dist/wizard.js +2 -0
- package/package.json +1 -1
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
- package/packages/mcp-server/dist/remote-questions.js +732 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +7 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +70 -8
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts +14 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +49 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +163 -25
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -3
- package/packages/mcp-server/src/mcp-server.test.ts +67 -0
- package/packages/mcp-server/src/remote-questions.test.ts +294 -0
- package/packages/mcp-server/src/remote-questions.ts +916 -0
- package/packages/mcp-server/src/server.ts +89 -14
- package/packages/mcp-server/src/session-manager.ts +43 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
- package/packages/mcp-server/src/workflow-tools.ts +215 -43
- package/packages/mcp-server/tsconfig.test.json +19 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +12 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +30 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +14 -0
- package/packages/pi-agent-core/src/types.ts +34 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/custom.d.ts +38 -0
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/custom.js +41 -0
- package/packages/pi-ai/dist/models/custom.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +13 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +60 -15
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +16 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts +17 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js +75 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js +41 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/models/custom.ts +42 -0
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
- package/packages/pi-ai/src/providers/anthropic.ts +15 -4
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
- package/packages/pi-ai/src/providers/openai-completions.ts +57 -16
- package/packages/pi-ai/src/providers/simple-options.ts +17 -1
- package/packages/pi-ai/src/providers/think-tag-parser.test.ts +44 -0
- package/packages/pi-ai/src/providers/think-tag-parser.ts +94 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +32 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +35 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +205 -2
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.js +92 -12
- package/packages/pi-coding-agent/dist/core/model-discovery.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js +16 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js +61 -1
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +90 -10
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +10 -6
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +45 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +13 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -2
- package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +351 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +258 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
- package/packages/pi-coding-agent/src/core/index.ts +10 -0
- package/packages/pi-coding-agent/src/core/model-discovery.test.ts +19 -0
- package/packages/pi-coding-agent/src/core/model-discovery.ts +99 -12
- package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
- package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
- package/packages/pi-coding-agent/src/core/model-registry-discovery.test.ts +75 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +102 -10
- package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
- package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -1
- package/packages/pi-coding-agent/src/core/session-manager.ts +10 -6
- package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
- package/packages/pi-coding-agent/src/index.ts +16 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/pkg/package.json +1 -1
- package/scripts/link-workspace-packages.cjs +1 -0
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +32 -8
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +78 -17
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +149 -5
- package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -0
- package/src/resources/extensions/gsd/auto/loop.ts +9 -0
- package/src/resources/extensions/gsd/auto/phases.ts +131 -10
- package/src/resources/extensions/gsd/auto/run-unit.ts +40 -2
- package/src/resources/extensions/gsd/auto/session.ts +35 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +16 -3
- package/src/resources/extensions/gsd/auto-model-selection.ts +71 -15
- package/src/resources/extensions/gsd/auto-post-unit.ts +29 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +26 -1
- package/src/resources/extensions/gsd/auto-start.ts +60 -68
- package/src/resources/extensions/gsd/auto-verification.ts +33 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
- package/src/resources/extensions/gsd/auto.ts +73 -28
- package/src/resources/extensions/gsd/blocked-models.ts +98 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +54 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +89 -26
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +55 -90
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
- package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
- package/src/resources/extensions/gsd/complexity-classifier.ts +5 -3
- package/src/resources/extensions/gsd/db-writer.ts +88 -17
- package/src/resources/extensions/gsd/doctor-git-checks.ts +23 -27
- package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
- package/src/resources/extensions/gsd/error-classifier.ts +36 -3
- package/src/resources/extensions/gsd/exec-history.ts +153 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
- package/src/resources/extensions/gsd/gitignore.ts +1 -1
- package/src/resources/extensions/gsd/gsd-db.ts +186 -23
- package/src/resources/extensions/gsd/guided-flow.ts +222 -1
- package/src/resources/extensions/gsd/health-widget.ts +3 -1
- package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
- package/src/resources/extensions/gsd/init-wizard.ts +15 -1
- package/src/resources/extensions/gsd/journal.ts +2 -1
- package/src/resources/extensions/gsd/key-manager.ts +28 -0
- package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
- package/src/resources/extensions/gsd/memory-store.ts +26 -0
- package/src/resources/extensions/gsd/model-router.ts +42 -1
- package/src/resources/extensions/gsd/pre-execution-checks.ts +46 -10
- package/src/resources/extensions/gsd/preferences-types.ts +46 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
- package/src/resources/extensions/gsd/preferences.ts +17 -17
- package/src/resources/extensions/gsd/prompt-loader.ts +30 -7
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
- package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
- package/src/resources/extensions/gsd/state.ts +45 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +188 -2
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +33 -3
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +68 -66
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +148 -3
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
- package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +237 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +40 -9
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +447 -1
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +356 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
- package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
- package/src/resources/extensions/gsd/token-counter.ts +22 -5
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
- package/src/resources/extensions/gsd/tools/memory-tools.ts +31 -1
- package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
- package/src/resources/extensions/search-the-web/command-search-provider.ts +5 -4
- package/src/resources/extensions/search-the-web/native-search.ts +48 -12
- package/src/resources/skills/api-design/SKILL.md +190 -0
- package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/src/resources/skills/design-an-interface/SKILL.md +102 -0
- package/src/resources/skills/forensics/SKILL.md +153 -0
- package/src/resources/skills/grill-me/SKILL.md +93 -0
- package/src/resources/skills/handoff/SKILL.md +121 -0
- package/src/resources/skills/observability/SKILL.md +174 -0
- package/src/resources/skills/security-review/SKILL.md +181 -0
- package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/src/resources/skills/tdd/SKILL.md +112 -0
- package/src/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/src/resources/skills/write-docs/SKILL.md +82 -0
- package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
- /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: observability
|
|
3
|
+
description: Add agent-first observability to code — structured logs, health endpoints, failure-state persistence, and explicit failure modes — so the next agent hitting a problem at 3am has the signals it needs to diagnose. Use when asked to "add logging", "add observability", "add metrics", "debug later", "make this observable", or when building/refactoring a subsystem that will run unattended (auto-mode engine, background jobs, servers, watchers). Operationalizes VISION.md's "agent-first observability" principle.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<objective>
|
|
7
|
+
Instrument code so that a cold-start agent can understand what happened by reading signals, not by rerunning with extra logging. The deliverable is a set of specific instrumentation additions: structured logs at decision points, health/status surfaces for long-running processes, persisted failure state, and explicit failure modes that don't get swallowed.
|
|
8
|
+
</objective>
|
|
9
|
+
|
|
10
|
+
<context>
|
|
11
|
+
GSD-2's `VISION.md` lists "agent-first observability" as a principle, and the system prompt calls it out: "A future version of you will land in this codebase with no memory… you add observability because you're the one who'll need it at 3am." GSD-2 already exemplifies this — `activity/*.jsonl`, `journal/*.jsonl`, `metrics.json`, `doctor-history.jsonl` — but new code doesn't get that treatment automatically.
|
|
12
|
+
|
|
13
|
+
This skill is the thinking process for adding it. Not "add logs everywhere" — add the *right* signals at the *right* decision points.
|
|
14
|
+
|
|
15
|
+
Invocation points:
|
|
16
|
+
- Building auto-mode-style code (loops, dispatch, guards, retries)
|
|
17
|
+
- Adding a background job, watcher, or scheduled task
|
|
18
|
+
- Writing a server or long-running process
|
|
19
|
+
- Refactoring a subsystem that has been hard to debug
|
|
20
|
+
- Addressing a production bug where "we had no visibility" surfaced
|
|
21
|
+
</context>
|
|
22
|
+
|
|
23
|
+
<core_principle>
|
|
24
|
+
**LOG DECISIONS, NOT ACTIVITY.** "Entering function X" is noise. "Dispatched unit `slice/S02` after guard check passed because `status=pending`" is signal. Every log line should answer a question a future debugger will ask.
|
|
25
|
+
|
|
26
|
+
**FAIL LOUDLY AND PERSIST THE REASON.** Silent `try/catch` that returns `undefined` is an anti-pattern. If something fails, the failure state needs to be somewhere a fresh agent can find it — a JSONL, a status file, a health endpoint.
|
|
27
|
+
|
|
28
|
+
**OBSERVABILITY IS NOT FREE.** Every log allocation, every metric, every health check costs CPU and disk. Add only what you would actually read.
|
|
29
|
+
</core_principle>
|
|
30
|
+
|
|
31
|
+
<process>
|
|
32
|
+
|
|
33
|
+
## Step 1: Map the failure modes
|
|
34
|
+
|
|
35
|
+
Before instrumenting, list what can go wrong:
|
|
36
|
+
|
|
37
|
+
1. **What inputs could be invalid?** External API responses, user-submitted data, filesystem state, env vars.
|
|
38
|
+
2. **What external dependencies could fail?** Network, DB, child processes, filesystem permissions.
|
|
39
|
+
3. **What internal invariants could break?** State transitions, lock acquisition, concurrency assumptions.
|
|
40
|
+
4. **What silent corruption is possible?** Truncated writes, partial transactions, stale caches.
|
|
41
|
+
|
|
42
|
+
This map tells you where to instrument. Don't instrument uniformly — instrument at the decision points where these failures would manifest.
|
|
43
|
+
|
|
44
|
+
## Step 2: Structured logs at decision points
|
|
45
|
+
|
|
46
|
+
For each decision the code makes that could plausibly go wrong later:
|
|
47
|
+
|
|
48
|
+
- **What decision?** ("Dispatching unit X", "Retrying with backoff", "Skipping validation because flag set")
|
|
49
|
+
- **Why?** ("status=pending", "previous attempt exit=1", "--dev flag set")
|
|
50
|
+
- **What would a future debugger want to know?** (The values that drove the choice.)
|
|
51
|
+
|
|
52
|
+
Format:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
log.info({
|
|
56
|
+
event: "unit-dispatched",
|
|
57
|
+
unitType: "slice",
|
|
58
|
+
unitId: "S02",
|
|
59
|
+
reason: "pending",
|
|
60
|
+
attempt: 1,
|
|
61
|
+
flowId,
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use the project's existing logger if one exists. In gsd-2, follow the patterns in `src/resources/extensions/gsd/activity-log.ts` and `src/resources/extensions/gsd/journal.ts` — structured JSONL, one event per line, with `ts`, `event`, and domain-specific fields.
|
|
66
|
+
|
|
67
|
+
Avoid:
|
|
68
|
+
- `console.log("here")` — what does "here" mean in six months?
|
|
69
|
+
- Logging secrets, tokens, or PII — ever.
|
|
70
|
+
- Formatting structured data into a prose string — it can't be grepped or filtered.
|
|
71
|
+
|
|
72
|
+
## Step 3: Persist failure state
|
|
73
|
+
|
|
74
|
+
When something fails in a way the caller can't immediately handle, write the failure state to disk:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
await writeAtomically(
|
|
78
|
+
resolve(".gsd/runtime/last-error.json"),
|
|
79
|
+
JSON.stringify({
|
|
80
|
+
ts: new Date().toISOString(),
|
|
81
|
+
phase: "execute",
|
|
82
|
+
unitId,
|
|
83
|
+
error: { message, stack, code },
|
|
84
|
+
retryCount,
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
A fresh agent reading `.gsd/runtime/` sees what happened last, what was retried, and where the process stopped. Pattern exists already in gsd-2 — reuse the `atomic-write.ts` helpers and the `.gsd/runtime/` and `.gsd/forensics/` directories.
|
|
90
|
+
|
|
91
|
+
## Step 4: Health and status surfaces
|
|
92
|
+
|
|
93
|
+
For long-running processes:
|
|
94
|
+
|
|
95
|
+
- **Health endpoint** (HTTP server) or **status file** (CLI tool). Cheap to call, no side effects. Returns current state: `{status: "healthy" | "degraded" | "down", ...diagnostics}`.
|
|
96
|
+
- **Digest view** — a small representation of recent work. In gsd-2, this is `STATE.md` and the health widget. In a server, it's `/internal/status` with last 10 request summaries.
|
|
97
|
+
- **Minimal metrics** — counters for the 3–5 things that matter (requests, errors, active jobs). Not everything — just what drives alerts.
|
|
98
|
+
|
|
99
|
+
Don't build a metrics empire. Build exactly what you'd check at 3am.
|
|
100
|
+
|
|
101
|
+
## Step 5: Explicit failure modes
|
|
102
|
+
|
|
103
|
+
Replace silent handling with explicit:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// Bad
|
|
107
|
+
try {
|
|
108
|
+
return await db.getUser(id);
|
|
109
|
+
} catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Good
|
|
114
|
+
try {
|
|
115
|
+
return await db.getUser(id);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
log.error({ event: "db-getuser-failed", userId: id, err: serializeError(err) });
|
|
118
|
+
throw new DatabaseError("Failed to load user", { cause: err, userId: id });
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The caller now knows the failure happened, gets an error type it can branch on, and a log line exists for forensics.
|
|
123
|
+
|
|
124
|
+
## Step 6: Remove the scaffolding
|
|
125
|
+
|
|
126
|
+
Before shipping, cull the ad-hoc instrumentation you used while debugging. Keep only:
|
|
127
|
+
- Decision-point logs that a future agent would use
|
|
128
|
+
- Persistent failure state
|
|
129
|
+
- Health/status surfaces
|
|
130
|
+
- Explicit failure modes
|
|
131
|
+
|
|
132
|
+
Drop:
|
|
133
|
+
- Temporary `console.log` debug lines
|
|
134
|
+
- Spammy per-iteration logs that no one will read
|
|
135
|
+
- Metrics that were "might be useful someday"
|
|
136
|
+
|
|
137
|
+
The system prompt says it plainly: "Remove noisy one-off instrumentation before finishing unless it provides durable diagnostic value."
|
|
138
|
+
|
|
139
|
+
## Step 7: Verify the signals work
|
|
140
|
+
|
|
141
|
+
Pick one plausible failure mode from Step 1 and simulate it (inject an error, point at a missing file, break a dependency). Confirm:
|
|
142
|
+
|
|
143
|
+
1. The failure produced a log line a cold-start agent could understand.
|
|
144
|
+
2. The failure state persisted somewhere durable.
|
|
145
|
+
3. The health surface reflects the degraded state.
|
|
146
|
+
4. Nothing was swallowed silently.
|
|
147
|
+
|
|
148
|
+
If any signal is missing, add it — that's the gap this skill exists to catch.
|
|
149
|
+
|
|
150
|
+
</process>
|
|
151
|
+
|
|
152
|
+
<anti_patterns>
|
|
153
|
+
|
|
154
|
+
- **Uniform logging.** Logging every function entry/exit buries signal in noise.
|
|
155
|
+
- **Prose logs.** `"Processing user 42 now"` vs `{event: "user-process-start", userId: 42}` — the latter is queryable, the former is not.
|
|
156
|
+
- **Silent swallowing.** `catch {}` or `catch (err) { /* ignore */ }` without a log is a deferred production incident.
|
|
157
|
+
- **Metrics empire.** 200 Prometheus metrics nobody reads. Ship 5 that drive alerts.
|
|
158
|
+
- **Logging secrets.** API keys, tokens, passwords, full request bodies with PII — never.
|
|
159
|
+
- **"I'll add logging when it breaks."** By then you don't have the signal. Instrument now.
|
|
160
|
+
- **Over-instrumenting hot paths.** Logging inside a tight loop kills performance. Sample or aggregate.
|
|
161
|
+
|
|
162
|
+
</anti_patterns>
|
|
163
|
+
|
|
164
|
+
<success_criteria>
|
|
165
|
+
|
|
166
|
+
- [ ] Failure modes were listed before instrumenting.
|
|
167
|
+
- [ ] Logs are at decision points, structured, and contain the driving values.
|
|
168
|
+
- [ ] Failure state is persisted to a known location (`.gsd/runtime/`, `/var/log/`, a status file).
|
|
169
|
+
- [ ] Long-running processes expose a health or status surface.
|
|
170
|
+
- [ ] No silent `try/catch` swallowing errors.
|
|
171
|
+
- [ ] Ad-hoc debug instrumentation was removed.
|
|
172
|
+
- [ ] One plausible failure was simulated and the signals were confirmed to reach a fresh reader.
|
|
173
|
+
|
|
174
|
+
</success_criteria>
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-review
|
|
3
|
+
description: Threat-model-driven security review of a change, feature, or subsystem. Runs a STRIDE-style pass (Spoofing, Tampering, Repudiation, Info disclosure, Denial of service, Elevation of privilege), examines the actual code, and produces a filing-ready report with severity, exploit scenario, and concrete remediation. Use when asked to "security review", "threat model", "check for vulnerabilities", "audit this for security", "secure this", or before shipping any change that touches auth, input handling, data access, or external surfaces.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<objective>
|
|
7
|
+
Produce a security review that names specific exploit paths through the actual code — not a generic checklist. The deliverable is a prioritized list of findings, each with: where the issue lives, the threat category, a concrete exploit scenario, severity, and a remediation the caller can implement. Read-only: does not modify code.
|
|
8
|
+
</objective>
|
|
9
|
+
|
|
10
|
+
<context>
|
|
11
|
+
GSD-2's general `review` skill covers security as one of several categories. This skill is the deeper pass — triggered deliberately when security is the primary concern. It complements v1's `/gsd-secure-phase` concept, adapted to the gsd-2 artifact model.
|
|
12
|
+
|
|
13
|
+
Invocation points:
|
|
14
|
+
- Any change touching authentication, authorization, session handling
|
|
15
|
+
- Any change touching user input → database, filesystem, or shell
|
|
16
|
+
- Any change exposing a new external surface (HTTP endpoint, webhook, IPC boundary)
|
|
17
|
+
- Secrets handling, environment variable changes, crypto code
|
|
18
|
+
- Pre-release audit of a feature or milestone
|
|
19
|
+
- Response to a suspected vulnerability
|
|
20
|
+
|
|
21
|
+
Do NOT use for:
|
|
22
|
+
- General code review (use `review`)
|
|
23
|
+
- Performance audits (use `code-optimizer`)
|
|
24
|
+
</context>
|
|
25
|
+
|
|
26
|
+
<core_principle>
|
|
27
|
+
**CODE BEFORE CHECKLISTS.** A threat model that doesn't read the code is theater. Find the actual input source, the actual validation (or absence), the actual sink. Cite file:line for every finding.
|
|
28
|
+
|
|
29
|
+
**THREAT, NOT HYPOTHETICAL.** "SQL injection is possible in theory" is useless. "If an attacker passes `' OR 1=1--` to `getUser(name)` at `src/db/users.ts:42`, the query becomes `SELECT … WHERE name='' OR 1=1--'`, returning every row" is actionable.
|
|
30
|
+
|
|
31
|
+
**READ-ONLY.** Don't patch while reviewing — you conflate reviewer and author and lose the audit trail. Report, let the user act.
|
|
32
|
+
</core_principle>
|
|
33
|
+
|
|
34
|
+
<process>
|
|
35
|
+
|
|
36
|
+
## Step 1: Scope the review
|
|
37
|
+
|
|
38
|
+
Identify what to review:
|
|
39
|
+
- Recent diff (staged / branch / specific commit)
|
|
40
|
+
- A named subsystem (`src/auth/`, the webhook handler, etc.)
|
|
41
|
+
- A user-provided concern ("I'm worried about our JWT handling")
|
|
42
|
+
|
|
43
|
+
If the scope is vague, ask one round of clarifying questions (1–3 questions). Otherwise proceed.
|
|
44
|
+
|
|
45
|
+
## Step 2: Map the attack surface
|
|
46
|
+
|
|
47
|
+
Before STRIDE: identify every untrusted entry point in the scope:
|
|
48
|
+
|
|
49
|
+
- HTTP routes / GraphQL resolvers / RPC endpoints
|
|
50
|
+
- CLI flag parsing and argv consumption
|
|
51
|
+
- Webhook handlers, event subscribers
|
|
52
|
+
- Environment variables read at runtime
|
|
53
|
+
- Files read from untrusted locations
|
|
54
|
+
- Third-party library deserialization (YAML, XML, pickle, etc.)
|
|
55
|
+
- IPC boundaries, child processes
|
|
56
|
+
|
|
57
|
+
For each, note: who can reach this surface? (public internet, authenticated user, same-host process, admin-only).
|
|
58
|
+
|
|
59
|
+
## Step 3: STRIDE pass
|
|
60
|
+
|
|
61
|
+
For each attack surface, walk STRIDE:
|
|
62
|
+
|
|
63
|
+
### Spoofing (identity)
|
|
64
|
+
- Can an attacker pretend to be another user?
|
|
65
|
+
- Are identity tokens verified before they're trusted?
|
|
66
|
+
- Session cookies: HttpOnly, Secure, SameSite set?
|
|
67
|
+
|
|
68
|
+
### Tampering (integrity)
|
|
69
|
+
- Can an attacker modify data in transit or at rest?
|
|
70
|
+
- Are webhooks signed and signatures verified?
|
|
71
|
+
- Are incoming payloads rehydrated without integrity checks?
|
|
72
|
+
|
|
73
|
+
### Repudiation (audit trail)
|
|
74
|
+
- Is there a log of who did what?
|
|
75
|
+
- Can an attacker erase their trail?
|
|
76
|
+
- Are logs tamper-evident where it matters?
|
|
77
|
+
|
|
78
|
+
### Information disclosure
|
|
79
|
+
- Does an error message leak internal state, stack traces, file paths, DB queries?
|
|
80
|
+
- Are secrets logged anywhere?
|
|
81
|
+
- Are authorization checks upstream of data loading, or does the query run first?
|
|
82
|
+
|
|
83
|
+
### Denial of service
|
|
84
|
+
- Are there unbounded loops, unpaginated queries, or user-controlled recursion?
|
|
85
|
+
- Rate limits on expensive endpoints?
|
|
86
|
+
- Regex-on-user-input vulnerable to ReDoS?
|
|
87
|
+
|
|
88
|
+
### Elevation of privilege
|
|
89
|
+
- Are admin-only routes actually gated?
|
|
90
|
+
- Can a low-privilege user trigger a high-privilege operation through an unauthenticated webhook?
|
|
91
|
+
- Are role checks enforced at the handler, the service, and the data layer — or just one?
|
|
92
|
+
|
|
93
|
+
Use `Agent(subagent_type=Explore)` in parallel if the scope is large — one sub-agent per STRIDE category over the same surface list.
|
|
94
|
+
|
|
95
|
+
## Step 4: OWASP cross-check (web scope)
|
|
96
|
+
|
|
97
|
+
If the scope includes web surfaces, confirm against the top OWASP patterns that STRIDE doesn't cleanly cover:
|
|
98
|
+
|
|
99
|
+
- Injection (SQL, NoSQL, command, template, LDAP)
|
|
100
|
+
- XSS (stored, reflected, DOM)
|
|
101
|
+
- SSRF (server makes requests to attacker-controlled URLs)
|
|
102
|
+
- Insecure deserialization
|
|
103
|
+
- Path traversal
|
|
104
|
+
- Open redirects
|
|
105
|
+
- Broken access control at object level (IDOR)
|
|
106
|
+
- CSRF where cookies are used for auth
|
|
107
|
+
|
|
108
|
+
For each present, find the code path. Same standard: cite file:line.
|
|
109
|
+
|
|
110
|
+
## Step 5: Triage
|
|
111
|
+
|
|
112
|
+
For each finding, assign:
|
|
113
|
+
|
|
114
|
+
- **Severity:** Critical / High / Medium / Low / Informational
|
|
115
|
+
- **Exploitability:** Remote unauthenticated / authenticated user / adjacent user / admin-only / local-only
|
|
116
|
+
- **Business impact:** Data breach / account takeover / service disruption / audit failure / minor
|
|
117
|
+
|
|
118
|
+
Severity × Exploitability = priority. Sort findings by priority.
|
|
119
|
+
|
|
120
|
+
## Step 6: Write the report
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
## Security Review — <scope>
|
|
124
|
+
|
|
125
|
+
### Summary
|
|
126
|
+
|
|
127
|
+
<1–3 sentences — biggest finding and overall posture>
|
|
128
|
+
|
|
129
|
+
### Findings
|
|
130
|
+
|
|
131
|
+
#### CRITICAL-1: SQL injection in `getUser`
|
|
132
|
+
|
|
133
|
+
**Location:** `src/db/users.ts:42`
|
|
134
|
+
**Category:** Tampering / Info disclosure (STRIDE) + OWASP A03 Injection
|
|
135
|
+
**Exploit:** Passing `' OR 1=1--` to the `name` parameter produces the query `SELECT * FROM users WHERE name='' OR 1=1--'`, returning every row. `name` arrives from `POST /api/search` without validation.
|
|
136
|
+
**Reachability:** Remote unauthenticated (endpoint has no auth).
|
|
137
|
+
**Remediation:** Use a parameterized query. The codebase's `db.prepare` helper at `src/db/util.ts:17` handles this — switch `getUser` to it.
|
|
138
|
+
|
|
139
|
+
#### HIGH-2: ...
|
|
140
|
+
|
|
141
|
+
### Non-findings considered
|
|
142
|
+
|
|
143
|
+
<brief: what you checked and ruled out — prevents repeat reviews>
|
|
144
|
+
|
|
145
|
+
### Out of scope
|
|
146
|
+
|
|
147
|
+
<what wasn't reviewed>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Offer to file as a GitHub issue — requires explicit confirmation per the outward-action rule. Sensitive findings should stay in `.gsd/security-reviews/` and not be pushed to a public tracker; check the repository's security policy first.
|
|
151
|
+
|
|
152
|
+
## Step 7: Follow-ups
|
|
153
|
+
|
|
154
|
+
If the review found CRITICAL or HIGH issues:
|
|
155
|
+
- Recommend filing a private security advisory (not a public issue) if the repo is public.
|
|
156
|
+
- Flag the finding for `/gsd start hotfix` if it's in the scope of active work.
|
|
157
|
+
- Append one line to `.gsd/DECISIONS.md` if the remediation involves an architectural change.
|
|
158
|
+
|
|
159
|
+
</process>
|
|
160
|
+
|
|
161
|
+
<anti_patterns>
|
|
162
|
+
|
|
163
|
+
- **Generic checklists.** "Does it validate input?" yes/no without pointing at the code is not a review.
|
|
164
|
+
- **Hypothetical exploits without code.** If you can't name the path, the finding isn't real yet.
|
|
165
|
+
- **Modifying code during review.** Reviewer and author must stay separate.
|
|
166
|
+
- **Treating every theoretical issue as CRITICAL.** Severity requires exploitability.
|
|
167
|
+
- **Skipping reachability.** A "critical" behind admin-only auth is usually not critical.
|
|
168
|
+
- **Filing sensitive findings publicly.** Check the repo's security policy first.
|
|
169
|
+
|
|
170
|
+
</anti_patterns>
|
|
171
|
+
|
|
172
|
+
<success_criteria>
|
|
173
|
+
|
|
174
|
+
- [ ] Every finding cites a file:line.
|
|
175
|
+
- [ ] Every finding has a concrete exploit scenario, not just a category.
|
|
176
|
+
- [ ] Severity, exploitability, and business impact are stated.
|
|
177
|
+
- [ ] At least one non-finding is listed (shows what was ruled out).
|
|
178
|
+
- [ ] No code was modified during the review.
|
|
179
|
+
- [ ] Critical findings are routed through an appropriate disclosure channel, not auto-filed publicly.
|
|
180
|
+
|
|
181
|
+
</success_criteria>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spike-wrap-up
|
|
3
|
+
description: Package findings from a completed spike into a durable, project-local skill that auto-loads on future similar work. Reads the most recent `.gsd/workflows/spikes/` directory, interviews the user briefly on what's reusable, then writes `.claude/skills/<name>/SKILL.md`. Use when asked to "wrap up the spike", "package this as a skill", "make this reusable", "turn findings into a skill", or at the end of the synthesize phase of `/gsd start spike`. Closes the parity gap with GSD v1's `/gsd-spike-wrap-up`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<objective>
|
|
7
|
+
Convert the output of a research spike (`SCOPE.md`, `research/*.md`, `RECOMMENDATION.md`) into a project-local skill under `.claude/skills/` so that the next time a similar task comes up, the agent loads the skill automatically. This is how throwaway spikes become durable capital.
|
|
8
|
+
</objective>
|
|
9
|
+
|
|
10
|
+
<context>
|
|
11
|
+
GSD's spike workflow (`src/resources/extensions/gsd/workflow-templates/spike.md`) produces documents in `.gsd/workflows/spikes/<slug>/`. Those documents are useful once and then forgotten unless something packages them for reuse.
|
|
12
|
+
|
|
13
|
+
GSD already watches `.claude/skills/` (and `.agents/skills/`) at both user and project levels — see `src/resources/extensions/gsd/skill-discovery.ts`. Any skill written there is picked up on the next session without further wiring. This skill is the bridge from "spike done" to "skill available."
|
|
14
|
+
|
|
15
|
+
Invocation points:
|
|
16
|
+
- End of Phase 3 (synthesize) in `/gsd start spike` — prompt suggests running this skill
|
|
17
|
+
- User has a spike directory and wants to harvest it
|
|
18
|
+
- Pre-existing `RECOMMENDATION.md` that deserves a permanent home
|
|
19
|
+
</context>
|
|
20
|
+
|
|
21
|
+
<core_principle>
|
|
22
|
+
**NOT EVERY SPIKE DESERVES A SKILL.** If the recommendation was "don't do X," there may be no reusable guidance. Ask the user first; exit without writing if the answer is no.
|
|
23
|
+
|
|
24
|
+
**PROJECT-LOCAL, NOT USER-GLOBAL.** Write to `.claude/skills/` in the repo, not `~/.claude/skills/`. The skill encodes project-specific choices that should not leak into unrelated projects.
|
|
25
|
+
|
|
26
|
+
**DESCRIPTION IS THE DISCOVERABILITY SIGNAL.** The `description` field in frontmatter is the primary signal the agent uses to judge relevance and decide whether to load the skill — it is a heuristic, not a deterministic trigger. Write it as keywords the future agent will plausibly encounter, not a summary.
|
|
27
|
+
</core_principle>
|
|
28
|
+
|
|
29
|
+
<process>
|
|
30
|
+
|
|
31
|
+
## Step 1: Find the spike
|
|
32
|
+
|
|
33
|
+
1. List directories under `.gsd/workflows/spikes/` — sort by mtime, newest first.
|
|
34
|
+
2. If multiple exist, ask the user which to wrap up. Default: the most recent.
|
|
35
|
+
3. If none exist, tell the user and stop. This skill requires a completed spike.
|
|
36
|
+
|
|
37
|
+
Read the core files:
|
|
38
|
+
- `<spike>/SCOPE.md` — the question that was asked
|
|
39
|
+
- `<spike>/research/*.md` — the angles investigated
|
|
40
|
+
- `<spike>/RECOMMENDATION.md` — the conclusion
|
|
41
|
+
|
|
42
|
+
## Step 2: Decide if it deserves a skill
|
|
43
|
+
|
|
44
|
+
Ask the user — one round:
|
|
45
|
+
|
|
46
|
+
1. **Is the conclusion reusable on future work, or was it specific to one decision?**
|
|
47
|
+
Recommendation: packaging is worth it if the findings include repeatable guidance (how to evaluate X, a pattern to follow, a library's gotchas). If the spike ended in "we chose library Y, end of story," it probably belongs in `.gsd/DECISIONS.md` instead.
|
|
48
|
+
|
|
49
|
+
2. **What is the trigger?** When should a future agent load this skill? Give concrete keywords — "adding a new webhook handler", "writing a SQL migration", etc.
|
|
50
|
+
|
|
51
|
+
If the user says it's not worth packaging, offer instead to append a summary to `.gsd/DECISIONS.md` and stop.
|
|
52
|
+
|
|
53
|
+
## Step 3: Design the skill
|
|
54
|
+
|
|
55
|
+
Before writing, sketch in the conversation:
|
|
56
|
+
|
|
57
|
+
- **Name:** kebab-case, short, unambiguous. Prefix with the project's domain when helpful (`auth-webhook-setup`, not `webhook`).
|
|
58
|
+
- **Description (frontmatter):** one sentence, 120–1024 chars, keyword-rich. Must state when the agent should load it. Rewrite at least twice before settling.
|
|
59
|
+
- **Objective:** one paragraph — what the skill does and what artifact it produces.
|
|
60
|
+
- **Process:** numbered steps. Reference the spike's findings as the source, but the skill itself should be executable without reading the spike.
|
|
61
|
+
- **Anti-patterns:** gotchas the spike surfaced — things that looked right but didn't work.
|
|
62
|
+
- **Success criteria:** checklist the skill's user can confirm against.
|
|
63
|
+
|
|
64
|
+
Show this sketch to the user. One round of feedback. Iterate.
|
|
65
|
+
|
|
66
|
+
## Step 4: Write the skill
|
|
67
|
+
|
|
68
|
+
Write to `.claude/skills/<name>/SKILL.md` (create the directory). Match the frontmatter + XML-tag structure used by other bundled skills — see `src/resources/skills/review/SKILL.md` for the canonical shape.
|
|
69
|
+
|
|
70
|
+
Minimum structure:
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
---
|
|
74
|
+
name: <skill-name>
|
|
75
|
+
description: <one sentence with trigger keywords>
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
<objective>
|
|
79
|
+
<one paragraph — what this skill does>
|
|
80
|
+
</objective>
|
|
81
|
+
|
|
82
|
+
<context>
|
|
83
|
+
<when to invoke, what produced it (cite the spike), assumptions>
|
|
84
|
+
</context>
|
|
85
|
+
|
|
86
|
+
<process>
|
|
87
|
+
## Step 1: <action>
|
|
88
|
+
<instructions>
|
|
89
|
+
|
|
90
|
+
## Step 2: <action>
|
|
91
|
+
<instructions>
|
|
92
|
+
</process>
|
|
93
|
+
|
|
94
|
+
<anti_patterns>
|
|
95
|
+
- <gotcha from the spike>
|
|
96
|
+
- <another gotcha>
|
|
97
|
+
</anti_patterns>
|
|
98
|
+
|
|
99
|
+
<success_criteria>
|
|
100
|
+
- [ ] <observable confirmation>
|
|
101
|
+
- [ ] <observable confirmation>
|
|
102
|
+
</success_criteria>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If the spike produced a reusable template (a config file, a starter script), copy it into `.claude/skills/<name>/templates/` or `.claude/skills/<name>/references/` and reference it from the skill body.
|
|
106
|
+
|
|
107
|
+
## Step 5: Archive the spike, link from the skill
|
|
108
|
+
|
|
109
|
+
1. In the new SKILL.md, reference the originating spike: "Derived from `.gsd/workflows/spikes/<slug>/RECOMMENDATION.md` (dated YYYY-MM-DD)."
|
|
110
|
+
2. Do NOT delete the spike directory — spikes are research artifacts and retain value for forensics.
|
|
111
|
+
3. Append one line to `.gsd/DECISIONS.md`: `- YYYY-MM-DD [spike]: packaged "<slug>" findings as skill <name>`.
|
|
112
|
+
|
|
113
|
+
## Step 6: Confirm pickup
|
|
114
|
+
|
|
115
|
+
Tell the user the skill will be surfaced on the next session via `skill-discovery.ts`. If they want to use it immediately, they can `Read .claude/skills/<name>/SKILL.md` now.
|
|
116
|
+
|
|
117
|
+
</process>
|
|
118
|
+
|
|
119
|
+
<anti_patterns>
|
|
120
|
+
|
|
121
|
+
- **Writing to `~/.claude/skills/`.** That's user-global. Project spikes produce project skills — keep them scoped.
|
|
122
|
+
- **Verbose frontmatter description.** The description is an index entry, not a tutorial. Keywords over prose.
|
|
123
|
+
- **Packaging every spike.** If the outcome was "we decided X once," append to DECISIONS.md and move on.
|
|
124
|
+
- **Copy-pasting the spike verbatim into the skill.** The spike is research; the skill is executable guidance. Re-author.
|
|
125
|
+
- **Deleting the source spike.** Research artifacts should persist.
|
|
126
|
+
|
|
127
|
+
</anti_patterns>
|
|
128
|
+
|
|
129
|
+
<success_criteria>
|
|
130
|
+
|
|
131
|
+
- [ ] A new `.claude/skills/<name>/SKILL.md` exists with well-formed frontmatter.
|
|
132
|
+
- [ ] The `description` field uses keywords that will plausibly match future agent work.
|
|
133
|
+
- [ ] The skill body is executable on its own without re-reading the originating spike.
|
|
134
|
+
- [ ] The originating spike is referenced from the skill.
|
|
135
|
+
- [ ] `.gsd/DECISIONS.md` has a one-line entry recording the packaging.
|
|
136
|
+
- [ ] The spike directory itself is untouched.
|
|
137
|
+
|
|
138
|
+
</success_criteria>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: Test-driven development with red-green-refactor loops built around vertical slices (tracer bullets), not horizontal layers. Use when asked to "use TDD", "write test-first", "red-green-refactor", "build this with tests", or whenever a feature has a clear observable contract and would benefit from tests that outlive refactors. Complements the bundled test and add-tests skills — use this for the discipline, use those for the mechanics.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<objective>
|
|
7
|
+
Drive feature implementation through one red-green-refactor cycle per vertical slice. Each cycle produces a single failing test that pins one observable behavior, then the minimal code that makes it pass, then refactoring while GREEN. Never refactor while RED. Never write all tests up front.
|
|
8
|
+
</objective>
|
|
9
|
+
|
|
10
|
+
<context>
|
|
11
|
+
GSD already organizes work into slices (S##) and tasks (T##). This skill operates at the task level — inside a single T##-PLAN.md, it structures the execution as a sequence of tiny red-green-refactor cycles rather than write-all-then-test or write-all-without-tests.
|
|
12
|
+
|
|
13
|
+
Invocation points:
|
|
14
|
+
- Task plan calls out behavior with a clear external contract (pure function, API endpoint, module boundary)
|
|
15
|
+
- Bug fix — write the failing repro test first, then fix
|
|
16
|
+
- Refactor into a new module — write the tests against the new interface first
|
|
17
|
+
|
|
18
|
+
Do not use this skill for:
|
|
19
|
+
- Exploratory spikes (use `/gsd start spike` — no production code ships)
|
|
20
|
+
- Pure UI polish where visual verification beats unit tests
|
|
21
|
+
- Scripts that run once and are deleted
|
|
22
|
+
</context>
|
|
23
|
+
|
|
24
|
+
<core_principle>
|
|
25
|
+
**TESTS VERIFY BEHAVIOR THROUGH PUBLIC INTERFACES, NOT IMPLEMENTATION DETAILS.** A good test reads like a specification and survives refactors. A test that mocks internals or asserts private state fails every time you clean up the code — that is a bad test pretending to be a good one.
|
|
26
|
+
|
|
27
|
+
**VERTICAL SLICES, NOT HORIZONTAL LAYERS.** Writing all tests upfront ("horizontal slicing") produces tests for behavior you imagined, not behavior the code actually exhibits. One tracer bullet at a time: write one test, make it pass, learn, write the next.
|
|
28
|
+
|
|
29
|
+
**NEVER REFACTOR WHILE RED.** Refactoring without a passing test means you are guessing whether you broke something. Get to green first. Then clean up. Then go red again for the next slice.
|
|
30
|
+
</core_principle>
|
|
31
|
+
|
|
32
|
+
<process>
|
|
33
|
+
|
|
34
|
+
## Step 1: Confirm the interface
|
|
35
|
+
|
|
36
|
+
Before writing anything:
|
|
37
|
+
|
|
38
|
+
1. What is the public interface? (function signature, HTTP route, module exports)
|
|
39
|
+
2. Which behaviors matter most? List them in order of how badly you'd want to know if they broke.
|
|
40
|
+
3. What does a "caller" look like? Write one example call in prose.
|
|
41
|
+
|
|
42
|
+
If the user has not supplied these, ask — one round, 1–3 questions.
|
|
43
|
+
|
|
44
|
+
## Step 2: Tracer bullet
|
|
45
|
+
|
|
46
|
+
Pick the first behavior — usually the happy path for the most common input. Write one test that exercises it end-to-end through the public interface. Run it. It must fail (RED). If it passes, the test is not testing what you think it is — fix the test before writing any code.
|
|
47
|
+
|
|
48
|
+
Then write the minimum code to make it pass. "Minimum" means: if hard-coding `return 42` makes the test pass, hard-code `return 42`. You will generalize on the next cycle. Run the test. It must pass (GREEN).
|
|
49
|
+
|
|
50
|
+
This proves the end-to-end path works — test harness, imports, wiring, build. Everything from Step 3 onward is incremental.
|
|
51
|
+
|
|
52
|
+
## Step 3: Red-green loop
|
|
53
|
+
|
|
54
|
+
Pick the next behavior. Write one test that pins it. Run — RED. Write the minimum code that makes it pass without breaking prior tests. Run — GREEN.
|
|
55
|
+
|
|
56
|
+
Guidelines for picking the next behavior:
|
|
57
|
+
|
|
58
|
+
- Alternate happy-path-variant and edge-case tests — don't do all happy paths then all edges.
|
|
59
|
+
- Stop adding happy paths when they stop revealing new code. Move to errors.
|
|
60
|
+
- If the next test would require no new code, you have hit the end of this slice — skip to Step 4.
|
|
61
|
+
|
|
62
|
+
Guidelines for writing the test:
|
|
63
|
+
|
|
64
|
+
- One assertion per concept (multiple `expect` calls that describe one behavior are fine).
|
|
65
|
+
- No mocking of internals. Mock external I/O (network, filesystem, clock) only when necessary.
|
|
66
|
+
- The test name reads as a sentence: "rejects requests missing an auth header".
|
|
67
|
+
|
|
68
|
+
Guidelines for writing the code:
|
|
69
|
+
|
|
70
|
+
- Minimum to pass. If there are three cases and two are untested, write only the one that's under test.
|
|
71
|
+
- Copy-paste is fine on the first and second occurrence. Extract on the third.
|
|
72
|
+
|
|
73
|
+
## Step 4: Refactor while GREEN
|
|
74
|
+
|
|
75
|
+
Now that the behavior is pinned, clean up. Extract duplicated logic. Rename unclear variables. Deepen the module — move responsibilities behind the interface until the internals stop leaking into the test.
|
|
76
|
+
|
|
77
|
+
Rules:
|
|
78
|
+
|
|
79
|
+
- Every refactor keeps every test GREEN. Run tests after each small change.
|
|
80
|
+
- If a refactor would require changing a test, the test was coupled to implementation — either the test is wrong, or the interface you thought you were pinning is actually different. Fix the test first, then refactor.
|
|
81
|
+
- Don't refactor speculatively. Extract around real duplication and real seams, not imagined ones.
|
|
82
|
+
|
|
83
|
+
## Step 5: Close the slice
|
|
84
|
+
|
|
85
|
+
When the behavior the task plan specified is fully under test and the code is clean:
|
|
86
|
+
|
|
87
|
+
1. Run the full test suite — not just the tests you wrote. Verify no regressions.
|
|
88
|
+
2. Append a one-line summary of what is now pinned to `.gsd/KNOWLEDGE.md` if the behavior is non-obvious or the test surfaced a trap future agents should know about.
|
|
89
|
+
3. Use `gsd_*` tools to mark the task complete — do not edit checkboxes by hand.
|
|
90
|
+
|
|
91
|
+
</process>
|
|
92
|
+
|
|
93
|
+
<anti_patterns>
|
|
94
|
+
|
|
95
|
+
- **Writing all tests first.** Horizontal slicing. Produces imagined-behavior tests that decouple from reality.
|
|
96
|
+
- **Mocking internals.** `jest.mock("./internal-helper")` tells you the wiring matches your mental model, not that the behavior is correct.
|
|
97
|
+
- **Refactoring while RED.** You have no signal. Any change could be right or wrong.
|
|
98
|
+
- **"Just one more test" after GREEN without refactoring.** You accumulate duplication and the code rots in place.
|
|
99
|
+
- **Testing implementation detail.** "It calls `fetchUser` three times." Who cares? Test the observable result.
|
|
100
|
+
- **Skipping the failing run.** If you never saw RED, you don't know the test would have caught the bug.
|
|
101
|
+
|
|
102
|
+
</anti_patterns>
|
|
103
|
+
|
|
104
|
+
<success_criteria>
|
|
105
|
+
|
|
106
|
+
- [ ] Every behavior the task plan called out has a test that pins it through the public interface.
|
|
107
|
+
- [ ] Every test went RED before it went GREEN. No test was born passing.
|
|
108
|
+
- [ ] All refactoring happened on GREEN. The final code is not the first draft.
|
|
109
|
+
- [ ] Full test suite runs clean — no regressions.
|
|
110
|
+
- [ ] No test mocks an internal helper or asserts a private field.
|
|
111
|
+
|
|
112
|
+
</success_criteria>
|