gsd-pi 2.41.0-dev.0acbce9 → 2.41.0-dev.5a170d0
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 +1 -1
- package/dist/cli-web-branch.d.ts +6 -0
- package/dist/cli-web-branch.js +17 -0
- package/dist/onboarding.js +2 -1
- 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-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 +16 -0
- 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 +1 -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.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 +10 -3
- package/dist/resources/extensions/gsd/git-service.js +5 -1
- 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 +2 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences.js +1 -0
- 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/queue.md +1 -1
- package/dist/resources/extensions/gsd/repo-identity.js +46 -2
- 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 +138 -0
- 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 +19 -2
- 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 +16 -16
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- 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/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.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/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.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/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.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/skill-health/route.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/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +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 +16 -16
- package/dist/web/standalone/.next/server/chunks/229.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/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/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +29 -7
- package/package.json +1 -1
- package/packages/native/src/__tests__/text.test.mjs +33 -0
- 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/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 +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
- 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 +5 -0
- 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-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 +13 -0
- 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 +1 -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.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 +9 -3
- package/src/resources/extensions/gsd/git-service.ts +5 -4
- 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 +2 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
- package/src/resources/extensions/gsd/preferences-types.ts +3 -0
- package/src/resources/extensions/gsd/preferences.ts +1 -0
- 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/queue.md +1 -1
- package/src/resources/extensions/gsd/repo-identity.ts +47 -2
- 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 +171 -0
- 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/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/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 +386 -0
- 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 +98 -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/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/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 +178 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +195 -105
- 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 +30 -9
- 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/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_ssgManifest.js +0 -0
|
@@ -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
|
}
|