gsd-pi 2.41.0 → 2.42.0-dev.eedc83f
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 +92 -29
- package/dist/cli-web-branch.d.ts +6 -0
- package/dist/cli-web-branch.js +17 -0
- package/dist/cli.js +15 -1
- package/dist/onboarding.js +2 -1
- package/dist/resource-loader.js +39 -6
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
- package/dist/resources/extensions/gsd/auto/loop.js +89 -1
- package/dist/resources/extensions/gsd/auto/phases.js +28 -10
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
- package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
- package/dist/resources/extensions/gsd/auto-start.js +8 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
- package/dist/resources/extensions/gsd/auto.js +64 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
- package/dist/resources/extensions/gsd/context-injector.js +74 -0
- package/dist/resources/extensions/gsd/context-store.js +4 -3
- package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
- package/dist/resources/extensions/gsd/custom-verification.js +145 -0
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
- package/dist/resources/extensions/gsd/db-writer.js +5 -2
- package/dist/resources/extensions/gsd/definition-loader.js +352 -0
- package/dist/resources/extensions/gsd/detection.js +20 -1
- package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
- package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
- package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
- package/dist/resources/extensions/gsd/doctor.js +11 -1
- package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
- package/dist/resources/extensions/gsd/engine-types.js +8 -0
- package/dist/resources/extensions/gsd/execution-policy.js +8 -0
- package/dist/resources/extensions/gsd/exit-command.js +12 -2
- package/dist/resources/extensions/gsd/export.js +9 -13
- package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
- package/dist/resources/extensions/gsd/files.js +28 -11
- package/dist/resources/extensions/gsd/forensics.js +94 -3
- package/dist/resources/extensions/gsd/git-constants.js +1 -0
- package/dist/resources/extensions/gsd/git-service.js +73 -3
- package/dist/resources/extensions/gsd/graph.js +225 -0
- package/dist/resources/extensions/gsd/gsd-db.js +25 -8
- package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +7 -3
- package/dist/resources/extensions/gsd/journal.js +85 -0
- package/dist/resources/extensions/gsd/md-importer.js +5 -0
- package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences.js +60 -8
- package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
- package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
- package/dist/resources/extensions/gsd/repo-identity.js +92 -7
- package/dist/resources/extensions/gsd/rule-registry.js +489 -0
- package/dist/resources/extensions/gsd/rule-types.js +6 -0
- package/dist/resources/extensions/gsd/run-manager.js +134 -0
- package/dist/resources/extensions/gsd/service-tier.js +147 -0
- package/dist/resources/extensions/gsd/session-lock.js +2 -2
- package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
- package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
- package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
- package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
- package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
- package/dist/resources/extensions/mcp-client/index.js +2 -1
- package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
- package/dist/resources/extensions/subagent/index.js +7 -3
- package/dist/resources/extensions/voice/index.js +4 -4
- package/dist/resources/skills/create-workflow/SKILL.md +103 -0
- package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- 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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
- package/dist/web/standalone/.next/server/chunks/229.js +3 -3
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.d.ts +4 -0
- package/dist/web-mode.js +69 -11
- package/package.json +1 -1
- package/packages/native/src/__tests__/text.test.mjs +33 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +6 -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/src/agent.test.ts +53 -0
- package/packages/pi-agent-core/src/agent.ts +3 -0
- package/packages/pi-agent-core/src/types.ts +6 -0
- package/packages/pi-agent-core/tsconfig.json +1 -1
- package/packages/pi-ai/dist/models.d.ts +5 -3
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +1135 -1588
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +1543 -0
- package/packages/pi-ai/src/models.generated.ts +1140 -1593
- package/packages/pi-ai/src/models.ts +7 -4
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.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 +18 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.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 +34 -10
- 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.ts +7 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
- package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
- package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
- package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
- package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
- package/pkg/package.json +1 -1
- package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
- package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
- package/src/resources/extensions/gsd/auto/loop.ts +101 -1
- package/src/resources/extensions/gsd/auto/phases.ts +30 -10
- package/src/resources/extensions/gsd/auto/session.ts +6 -0
- package/src/resources/extensions/gsd/auto/types.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
- package/src/resources/extensions/gsd/auto-start.ts +8 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
- package/src/resources/extensions/gsd/auto.ts +71 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
- package/src/resources/extensions/gsd/context-injector.ts +100 -0
- package/src/resources/extensions/gsd/context-store.ts +4 -3
- package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
- package/src/resources/extensions/gsd/custom-verification.ts +180 -0
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
- package/src/resources/extensions/gsd/db-writer.ts +6 -2
- package/src/resources/extensions/gsd/definition-loader.ts +462 -0
- package/src/resources/extensions/gsd/detection.ts +20 -1
- package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
- package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
- package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +12 -1
- package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
- package/src/resources/extensions/gsd/engine-types.ts +71 -0
- package/src/resources/extensions/gsd/execution-policy.ts +43 -0
- package/src/resources/extensions/gsd/exit-command.ts +14 -2
- package/src/resources/extensions/gsd/export.ts +8 -15
- package/src/resources/extensions/gsd/extension-manifest.json +2 -2
- package/src/resources/extensions/gsd/files.ts +29 -12
- package/src/resources/extensions/gsd/forensics.ts +101 -3
- package/src/resources/extensions/gsd/git-constants.ts +1 -0
- package/src/resources/extensions/gsd/git-service.ts +76 -6
- package/src/resources/extensions/gsd/graph.ts +312 -0
- package/src/resources/extensions/gsd/gsd-db.ts +37 -8
- package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +7 -3
- package/src/resources/extensions/gsd/journal.ts +134 -0
- package/src/resources/extensions/gsd/md-importer.ts +6 -0
- package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
- package/src/resources/extensions/gsd/preferences-types.ts +6 -0
- package/src/resources/extensions/gsd/preferences.ts +63 -6
- package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
- package/src/resources/extensions/gsd/prompts/queue.md +1 -1
- package/src/resources/extensions/gsd/repo-identity.ts +95 -7
- package/src/resources/extensions/gsd/rule-registry.ts +599 -0
- package/src/resources/extensions/gsd/rule-types.ts +68 -0
- package/src/resources/extensions/gsd/run-manager.ts +180 -0
- package/src/resources/extensions/gsd/service-tier.ts +184 -0
- package/src/resources/extensions/gsd/session-lock.ts +2 -2
- package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
- package/src/resources/extensions/gsd/templates/decisions.md +2 -2
- package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
- package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
- package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
- package/src/resources/extensions/gsd/types.ts +3 -0
- package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
- package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
- package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
- package/src/resources/extensions/gsd/worktree-resolver.ts +32 -11
- package/src/resources/extensions/mcp-client/index.ts +5 -1
- package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
- package/src/resources/extensions/subagent/index.ts +7 -3
- package/src/resources/extensions/voice/index.ts +4 -4
- package/src/resources/skills/create-workflow/SKILL.md +103 -0
- package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
- /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* custom-verification.ts — Step verification for custom workflows.
|
|
3
|
+
*
|
|
4
|
+
* Reads the frozen DEFINITION.yaml from a run directory, finds the step's
|
|
5
|
+
* `verify` policy, and dispatches to the appropriate handler. Four policies:
|
|
6
|
+
*
|
|
7
|
+
* - content-heuristic: file existence + optional minSize + optional pattern match
|
|
8
|
+
* - shell-command: spawnSync with 30s timeout, exit 0 → continue, else retry
|
|
9
|
+
* - prompt-verify: always "pause" (defers to agent)
|
|
10
|
+
* - human-review: always "pause" (waits for manual inspection)
|
|
11
|
+
* - (no policy): returns "continue" (passthrough)
|
|
12
|
+
*
|
|
13
|
+
* Observability:
|
|
14
|
+
* - Return value is the typed verification outcome ("continue" | "retry" | "pause").
|
|
15
|
+
* - shell-command captures stderr from spawnSync — callers can inspect on retry.
|
|
16
|
+
* - content-heuristic logs the specific failure (missing file, below minSize, pattern mismatch).
|
|
17
|
+
* - The frozen DEFINITION.yaml on disk is the single source of truth for step policies.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
21
|
+
import { join, resolve, sep } from "node:path";
|
|
22
|
+
import { spawnSync } from "node:child_process";
|
|
23
|
+
import type { StepDefinition, VerifyPolicy } from "./definition-loader.js";
|
|
24
|
+
import { readFrozenDefinition } from "./custom-workflow-engine.js";
|
|
25
|
+
|
|
26
|
+
/** Verification outcome type — matches ExecutionPolicy.verify() return type. */
|
|
27
|
+
export type VerificationOutcome = "continue" | "retry" | "pause";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Run custom verification for a specific step in a workflow run.
|
|
31
|
+
*
|
|
32
|
+
* Reads the frozen DEFINITION.yaml from `runDir`, finds the step with the
|
|
33
|
+
* given `stepId`, and dispatches to the appropriate verification handler
|
|
34
|
+
* based on the step's `verify.policy` field.
|
|
35
|
+
*
|
|
36
|
+
* @param runDir — absolute path to the workflow run directory
|
|
37
|
+
* @param stepId — the step ID to verify (e.g. "step-1")
|
|
38
|
+
* @returns "continue" if verification passes, "retry" if it should retry, "pause" if it needs review
|
|
39
|
+
* @throws Error if DEFINITION.yaml is missing or unreadable
|
|
40
|
+
*/
|
|
41
|
+
export function runCustomVerification(
|
|
42
|
+
runDir: string,
|
|
43
|
+
stepId: string,
|
|
44
|
+
): VerificationOutcome {
|
|
45
|
+
const def = readFrozenDefinition(runDir);
|
|
46
|
+
|
|
47
|
+
const step = def.steps.find((s: StepDefinition) => s.id === stepId);
|
|
48
|
+
if (!step) {
|
|
49
|
+
// Step not found in definition — nothing to verify, continue
|
|
50
|
+
return "continue";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!step.verify) {
|
|
54
|
+
// No verification policy configured — passthrough
|
|
55
|
+
return "continue";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return dispatchPolicy(runDir, step, step.verify);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Dispatch to the correct policy handler.
|
|
63
|
+
*/
|
|
64
|
+
function dispatchPolicy(
|
|
65
|
+
runDir: string,
|
|
66
|
+
step: StepDefinition,
|
|
67
|
+
verify: VerifyPolicy,
|
|
68
|
+
): VerificationOutcome {
|
|
69
|
+
switch (verify.policy) {
|
|
70
|
+
case "content-heuristic":
|
|
71
|
+
return handleContentHeuristic(runDir, step, verify);
|
|
72
|
+
case "shell-command":
|
|
73
|
+
return handleShellCommand(runDir, verify);
|
|
74
|
+
case "prompt-verify":
|
|
75
|
+
return "pause";
|
|
76
|
+
case "human-review":
|
|
77
|
+
return "pause";
|
|
78
|
+
default:
|
|
79
|
+
// Unknown policy — safe default is pause
|
|
80
|
+
return "pause";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* content-heuristic handler.
|
|
86
|
+
*
|
|
87
|
+
* For each path in the step's `produces` array:
|
|
88
|
+
* 1. Check that the file exists (resolved relative to runDir)
|
|
89
|
+
* 2. If `minSize` is set, check that file size >= minSize bytes
|
|
90
|
+
* 3. If `pattern` is set, check that file content matches the regex
|
|
91
|
+
*
|
|
92
|
+
* Returns "continue" if all checks pass, "pause" if any fail.
|
|
93
|
+
* If `produces` is empty or undefined, returns "continue" (nothing to check).
|
|
94
|
+
*/
|
|
95
|
+
function handleContentHeuristic(
|
|
96
|
+
runDir: string,
|
|
97
|
+
step: StepDefinition,
|
|
98
|
+
verify: { policy: "content-heuristic"; minSize?: number; pattern?: string },
|
|
99
|
+
): VerificationOutcome {
|
|
100
|
+
const produces = step.produces;
|
|
101
|
+
if (!produces || produces.length === 0) {
|
|
102
|
+
return "continue";
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
for (const relPath of produces) {
|
|
106
|
+
const absPath = resolve(runDir, relPath);
|
|
107
|
+
// Path traversal guard
|
|
108
|
+
if (!absPath.startsWith(resolve(runDir) + sep) && absPath !== resolve(runDir)) {
|
|
109
|
+
return "pause";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 1. File existence
|
|
113
|
+
if (!existsSync(absPath)) {
|
|
114
|
+
return "pause";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 2. Minimum size check
|
|
118
|
+
if (verify.minSize !== undefined) {
|
|
119
|
+
const stat = statSync(absPath);
|
|
120
|
+
if (stat.size < verify.minSize) {
|
|
121
|
+
return "pause";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 3. Pattern match check (with timeout guard against ReDoS)
|
|
126
|
+
if (verify.pattern !== undefined) {
|
|
127
|
+
const content = readFileSync(absPath, "utf-8");
|
|
128
|
+
try {
|
|
129
|
+
if (!new RegExp(verify.pattern).test(content)) {
|
|
130
|
+
return "pause";
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
// Invalid regex at runtime — treat as verification failure
|
|
134
|
+
return "pause";
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return "continue";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* shell-command handler.
|
|
144
|
+
*
|
|
145
|
+
* Runs the command via `sh -c` with cwd set to the run directory
|
|
146
|
+
* and a 30-second timeout. Returns "continue" if exit code 0,
|
|
147
|
+
* "retry" otherwise (including timeout/signal kills).
|
|
148
|
+
*
|
|
149
|
+
* SECURITY: The command string comes from a frozen DEFINITION.yaml written
|
|
150
|
+
* at run-creation time. The trust boundary is the workflow definition author.
|
|
151
|
+
* Commands run with the same privileges as the GSD process. Only use
|
|
152
|
+
* shell-command verification with definitions you trust.
|
|
153
|
+
*/
|
|
154
|
+
function handleShellCommand(
|
|
155
|
+
runDir: string,
|
|
156
|
+
verify: { policy: "shell-command"; command: string },
|
|
157
|
+
): VerificationOutcome {
|
|
158
|
+
// Guard: reject commands containing shell expansion patterns that suggest injection
|
|
159
|
+
const dangerousPatterns = /\$\(|`|;\s*(rm|curl|wget|nc|bash|sh|eval)\b/;
|
|
160
|
+
if (dangerousPatterns.test(verify.command)) {
|
|
161
|
+
console.warn(
|
|
162
|
+
`custom-verification: shell-command contains suspicious pattern, skipping: ${verify.command}`,
|
|
163
|
+
);
|
|
164
|
+
return "pause";
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const result = spawnSync("sh", ["-c", verify.command], {
|
|
168
|
+
cwd: runDir,
|
|
169
|
+
timeout: 30_000,
|
|
170
|
+
encoding: "utf-8",
|
|
171
|
+
stdio: "pipe",
|
|
172
|
+
env: { ...process.env, PATH: process.env.PATH },
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
if (result.status === 0) {
|
|
176
|
+
return "continue";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return "retry";
|
|
180
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* custom-workflow-engine.ts — WorkflowEngine implementation for custom workflows.
|
|
3
|
+
*
|
|
4
|
+
* Drives the auto-loop using GRAPH.yaml step state from a run directory.
|
|
5
|
+
* Each iteration: deriveState reads the graph, resolveDispatch picks the
|
|
6
|
+
* next eligible step, reconcile marks it complete and persists.
|
|
7
|
+
*
|
|
8
|
+
* Observability:
|
|
9
|
+
* - All state reads/writes go through graph.ts YAML I/O — inspectable on disk.
|
|
10
|
+
* - `resolveDispatch` returns unitType "custom-step" with unitId "<name>/<stepId>".
|
|
11
|
+
* - `getDisplayMetadata` provides step N/M progress for dashboard rendering.
|
|
12
|
+
* - Phase transitions are derivable from GRAPH.yaml step statuses.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { WorkflowEngine } from "./workflow-engine.js";
|
|
16
|
+
import type {
|
|
17
|
+
EngineState,
|
|
18
|
+
EngineDispatchAction,
|
|
19
|
+
CompletedStep,
|
|
20
|
+
ReconcileResult,
|
|
21
|
+
DisplayMetadata,
|
|
22
|
+
} from "./engine-types.js";
|
|
23
|
+
import { readFileSync } from "node:fs";
|
|
24
|
+
import { join } from "node:path";
|
|
25
|
+
import { parse } from "yaml";
|
|
26
|
+
import {
|
|
27
|
+
readGraph,
|
|
28
|
+
writeGraph,
|
|
29
|
+
getNextPendingStep,
|
|
30
|
+
markStepComplete,
|
|
31
|
+
expandIteration,
|
|
32
|
+
type WorkflowGraph,
|
|
33
|
+
} from "./graph.js";
|
|
34
|
+
import { injectContext } from "./context-injector.js";
|
|
35
|
+
import type { WorkflowDefinition, StepDefinition } from "./definition-loader.js";
|
|
36
|
+
|
|
37
|
+
/** Read and parse the frozen DEFINITION.yaml from a run directory. */
|
|
38
|
+
export function readFrozenDefinition(runDir: string): WorkflowDefinition {
|
|
39
|
+
const defPath = join(runDir, "DEFINITION.yaml");
|
|
40
|
+
const raw = readFileSync(defPath, "utf-8");
|
|
41
|
+
return parse(raw, { schema: "core" }) as WorkflowDefinition;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class CustomWorkflowEngine implements WorkflowEngine {
|
|
45
|
+
readonly engineId = "custom";
|
|
46
|
+
private readonly runDir: string;
|
|
47
|
+
|
|
48
|
+
constructor(runDir: string) {
|
|
49
|
+
this.runDir = runDir;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Derive engine state from GRAPH.yaml on disk.
|
|
54
|
+
*
|
|
55
|
+
* Phase is "complete" when all steps are complete or expanded,
|
|
56
|
+
* "running" otherwise (any pending or active steps remain).
|
|
57
|
+
*/
|
|
58
|
+
async deriveState(_basePath: string): Promise<EngineState> {
|
|
59
|
+
const graph = readGraph(this.runDir);
|
|
60
|
+
const allDone = graph.steps.every(
|
|
61
|
+
(s) => s.status === "complete" || s.status === "expanded",
|
|
62
|
+
);
|
|
63
|
+
const phase = allDone ? "complete" : "running";
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
phase,
|
|
67
|
+
currentMilestoneId: null,
|
|
68
|
+
activeSliceId: null,
|
|
69
|
+
activeTaskId: null,
|
|
70
|
+
isComplete: allDone,
|
|
71
|
+
raw: graph,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Resolve the next dispatch action from graph state.
|
|
77
|
+
*
|
|
78
|
+
* Uses getNextPendingStep to find the first step whose dependencies
|
|
79
|
+
* are all satisfied. If the step has an `iterate` config in the frozen
|
|
80
|
+
* DEFINITION.yaml, expands it into instance steps before dispatching.
|
|
81
|
+
*
|
|
82
|
+
* Returns a dispatch with unitType "custom-step" and unitId in
|
|
83
|
+
* "<workflowName>/<stepId>" format.
|
|
84
|
+
*
|
|
85
|
+
* Observability:
|
|
86
|
+
* - Iterate expansion is logged to stderr with item count and parent step ID.
|
|
87
|
+
* - Missing source artifacts throw with the full resolved path for diagnosis.
|
|
88
|
+
* - Zero-match expansions return a stop action with level "info".
|
|
89
|
+
* - Expanded GRAPH.yaml is written to disk before dispatch — inspectable on disk.
|
|
90
|
+
*/
|
|
91
|
+
async resolveDispatch(
|
|
92
|
+
state: EngineState,
|
|
93
|
+
_context: { basePath: string },
|
|
94
|
+
): Promise<EngineDispatchAction> {
|
|
95
|
+
let graph = state.raw as WorkflowGraph;
|
|
96
|
+
let next = getNextPendingStep(graph);
|
|
97
|
+
|
|
98
|
+
if (!next) {
|
|
99
|
+
return {
|
|
100
|
+
action: "stop",
|
|
101
|
+
reason: "All steps complete",
|
|
102
|
+
level: "info",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check frozen DEFINITION.yaml for iterate config on this step
|
|
107
|
+
const def = readFrozenDefinition(this.runDir);
|
|
108
|
+
const stepDef = def.steps.find((s: StepDefinition) => s.id === next!.id);
|
|
109
|
+
|
|
110
|
+
if (stepDef?.iterate) {
|
|
111
|
+
const iterate = stepDef.iterate;
|
|
112
|
+
|
|
113
|
+
// Read source artifact
|
|
114
|
+
const sourcePath = join(this.runDir, iterate.source);
|
|
115
|
+
let sourceContent: string;
|
|
116
|
+
try {
|
|
117
|
+
sourceContent = readFileSync(sourcePath, "utf-8");
|
|
118
|
+
} catch {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`Iterate source artifact not found: ${sourcePath} (step "${next.id}", source: "${iterate.source}")`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Extract items via regex with global+multiline flags.
|
|
125
|
+
// Guard against ReDoS: if matching takes too long on large inputs, bail.
|
|
126
|
+
const regex = new RegExp(iterate.pattern, "gm");
|
|
127
|
+
const items: string[] = [];
|
|
128
|
+
const matchStart = Date.now();
|
|
129
|
+
let match: RegExpExecArray | null;
|
|
130
|
+
while ((match = regex.exec(sourceContent)) !== null) {
|
|
131
|
+
if (match[1] !== undefined) items.push(match[1]);
|
|
132
|
+
if (Date.now() - matchStart > 5_000) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Iterate pattern "${iterate.pattern}" exceeded 5s timeout on step "${next.id}" — possible ReDoS`,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Expand the graph
|
|
140
|
+
const expandedGraph = expandIteration(graph, next.id, items, next.prompt);
|
|
141
|
+
writeGraph(this.runDir, expandedGraph);
|
|
142
|
+
graph = expandedGraph;
|
|
143
|
+
|
|
144
|
+
// Re-query for first instance step
|
|
145
|
+
next = getNextPendingStep(expandedGraph);
|
|
146
|
+
|
|
147
|
+
if (!next) {
|
|
148
|
+
return {
|
|
149
|
+
action: "stop",
|
|
150
|
+
reason: "Iterate expansion produced no instances",
|
|
151
|
+
level: "info",
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Enrich prompt with context from prior step artifacts
|
|
157
|
+
const enrichedPrompt = injectContext(this.runDir, next.id, next.prompt);
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
action: "dispatch",
|
|
161
|
+
step: {
|
|
162
|
+
unitType: "custom-step",
|
|
163
|
+
unitId: `${graph.metadata.name}/${next.id}`,
|
|
164
|
+
prompt: enrichedPrompt,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Reconcile state after a step completes.
|
|
171
|
+
*
|
|
172
|
+
* Extracts the stepId from the completedStep's unitId (last segment after `/`),
|
|
173
|
+
* marks it complete in the graph, and writes the updated GRAPH.yaml to disk.
|
|
174
|
+
*
|
|
175
|
+
* Returns "milestone-complete" when all steps are now done, "continue" otherwise.
|
|
176
|
+
*/
|
|
177
|
+
async reconcile(
|
|
178
|
+
state: EngineState,
|
|
179
|
+
completedStep: CompletedStep,
|
|
180
|
+
): Promise<ReconcileResult> {
|
|
181
|
+
const graph = state.raw as WorkflowGraph;
|
|
182
|
+
|
|
183
|
+
// Extract stepId from "<workflowName>/<stepId>"
|
|
184
|
+
const parts = completedStep.unitId.split("/");
|
|
185
|
+
const stepId = parts[parts.length - 1];
|
|
186
|
+
|
|
187
|
+
const updatedGraph = markStepComplete(graph, stepId);
|
|
188
|
+
writeGraph(this.runDir, updatedGraph);
|
|
189
|
+
|
|
190
|
+
const allDone = updatedGraph.steps.every(
|
|
191
|
+
(s) => s.status === "complete" || s.status === "expanded",
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
outcome: allDone ? "milestone-complete" : "continue",
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Return UI-facing metadata for progress display.
|
|
201
|
+
*
|
|
202
|
+
* Shows "Step N/M" progress where N = completed count and M = total.
|
|
203
|
+
*/
|
|
204
|
+
getDisplayMetadata(state: EngineState): DisplayMetadata {
|
|
205
|
+
const graph = state.raw as WorkflowGraph;
|
|
206
|
+
const total = graph.steps.length;
|
|
207
|
+
const completed = graph.steps.filter((s) => s.status === "complete").length;
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
engineLabel: "WORKFLOW",
|
|
211
|
+
currentPhase: state.phase,
|
|
212
|
+
progressSummary: `Step ${completed}/${total}`,
|
|
213
|
+
stepCount: { completed, total },
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -35,8 +35,8 @@ export function generateDecisionsMd(decisions: Decision[]): string {
|
|
|
35
35
|
lines.push(' To reverse a decision, add a new row that supersedes it.');
|
|
36
36
|
lines.push(' Read this file at the start of any planning or research phase. -->');
|
|
37
37
|
lines.push('');
|
|
38
|
-
lines.push('| # | When | Scope | Decision | Choice | Rationale | Revisable? |');
|
|
39
|
-
lines.push('
|
|
38
|
+
lines.push('| # | When | Scope | Decision | Choice | Rationale | Revisable? | Made By |');
|
|
39
|
+
lines.push('|---|------|-------|----------|--------|-----------|------------|---------|');
|
|
40
40
|
|
|
41
41
|
for (const d of decisions) {
|
|
42
42
|
// Escape pipe characters within cell values to preserve table structure
|
|
@@ -48,6 +48,7 @@ export function generateDecisionsMd(decisions: Decision[]): string {
|
|
|
48
48
|
d.choice,
|
|
49
49
|
d.rationale,
|
|
50
50
|
d.revisable,
|
|
51
|
+
d.made_by ?? 'agent',
|
|
51
52
|
].map(cell => (cell ?? '').replace(/\|/g, '\\|'));
|
|
52
53
|
|
|
53
54
|
lines.push(`| ${cells.join(' | ')} |`);
|
|
@@ -181,6 +182,7 @@ export interface SaveDecisionFields {
|
|
|
181
182
|
rationale: string;
|
|
182
183
|
revisable?: string;
|
|
183
184
|
when_context?: string;
|
|
185
|
+
made_by?: import('./types.js').DecisionMadeBy;
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
/**
|
|
@@ -205,6 +207,7 @@ export async function saveDecisionToDb(
|
|
|
205
207
|
choice: fields.choice,
|
|
206
208
|
rationale: fields.rationale,
|
|
207
209
|
revisable: fields.revisable ?? 'Yes',
|
|
210
|
+
made_by: fields.made_by ?? 'agent',
|
|
208
211
|
superseded_by: null,
|
|
209
212
|
});
|
|
210
213
|
|
|
@@ -222,6 +225,7 @@ export async function saveDecisionToDb(
|
|
|
222
225
|
choice: row['choice'] as string,
|
|
223
226
|
rationale: row['rationale'] as string,
|
|
224
227
|
revisable: row['revisable'] as string,
|
|
228
|
+
made_by: (row['made_by'] as string as import('./types.js').DecisionMadeBy) ?? 'agent',
|
|
225
229
|
superseded_by: (row['superseded_by'] as string) ?? null,
|
|
226
230
|
}));
|
|
227
231
|
}
|