@entelligentsia/forgecli 1.0.3 → 1.0.14
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/CHANGELOG.md +93 -0
- package/README.md +2 -1
- package/dist/CHANGELOG-forge-plugin.md +250 -0
- package/dist/CHANGELOG-pi.md +94 -0
- package/dist/bin/forge.js +0 -0
- package/dist/extensions/forgecli/config-layer.d.ts +16 -0
- package/dist/extensions/forgecli/config-layer.js +5 -0
- package/dist/extensions/forgecli/config-layer.js.map +1 -1
- package/dist/extensions/forgecli/dashboard/component.d.ts +102 -0
- package/dist/extensions/forgecli/dashboard/component.js +882 -0
- package/dist/extensions/forgecli/dashboard/component.js.map +1 -0
- package/dist/extensions/forgecli/dashboard/register.d.ts +2 -0
- package/dist/extensions/forgecli/dashboard/register.js +45 -0
- package/dist/extensions/forgecli/dashboard/register.js.map +1 -0
- package/dist/extensions/forgecli/dashboard/view-model.d.ts +35 -0
- package/dist/extensions/forgecli/dashboard/view-model.js +54 -0
- package/dist/extensions/forgecli/dashboard/view-model.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.js +72 -7
- package/dist/extensions/forgecli/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/forge-artifact-tool.js +27 -4
- package/dist/extensions/forgecli/forge-artifact-tool.js.map +1 -1
- package/dist/extensions/forgecli/forge-cli-schema.json +4 -0
- package/dist/extensions/forgecli/forge-commands.js +1 -0
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-init/phase4-register.js +53 -0
- package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.js +6 -4
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/forge-tools.js +2 -2
- package/dist/extensions/forgecli/forge-tools.js.map +1 -1
- package/dist/extensions/forgecli/index.js +5 -0
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/lib/halt-advisor.d.ts +54 -0
- package/dist/extensions/forgecli/lib/halt-advisor.js +90 -0
- package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -0
- package/dist/extensions/forgecli/migration-engine.js +25 -12
- package/dist/extensions/forgecli/migration-engine.js.map +1 -1
- package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +25 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.js +183 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -0
- package/dist/extensions/forgecli/orchestrator-tree.d.ts +96 -0
- package/dist/extensions/forgecli/orchestrator-tree.js +390 -0
- package/dist/extensions/forgecli/orchestrator-tree.js.map +1 -0
- package/dist/extensions/forgecli/project-orientation.js +12 -8
- package/dist/extensions/forgecli/project-orientation.js.map +1 -1
- package/dist/extensions/forgecli/regenerate.d.ts +16 -0
- package/dist/extensions/forgecli/regenerate.js +110 -0
- package/dist/extensions/forgecli/regenerate.js.map +1 -1
- package/dist/extensions/forgecli/run-sprint.js +33 -3
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.d.ts +32 -0
- package/dist/extensions/forgecli/run-task.js +185 -12
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/subagent/phase-guard.js +15 -5
- package/dist/extensions/forgecli/subagent/phase-guard.js.map +1 -1
- package/dist/extensions/forgecli/subagent/phase-summary-map.d.ts +1 -0
- package/dist/extensions/forgecli/subagent/phase-summary-map.js +17 -0
- package/dist/extensions/forgecli/subagent/phase-summary-map.js.map +1 -1
- package/dist/extensions/forgecli/thread-switcher.js +105 -764
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
- package/dist/extensions/forgecli/viewport-events.js +32 -0
- package/dist/extensions/forgecli/viewport-events.js.map +1 -1
- package/dist/forge-payload/.base-pack/commands/fix-bug.md +1 -1
- package/dist/forge-payload/.base-pack/commands/run-sprint.md +1 -1
- package/dist/forge-payload/.base-pack/commands/run-task.md +1 -1
- package/dist/forge-payload/.base-pack/personas/architect.md +1 -1
- package/dist/forge-payload/.base-pack/personas/bug-fixer.md +1 -1
- package/dist/forge-payload/.base-pack/personas/collator.md +3 -3
- package/dist/forge-payload/.base-pack/personas/engineer.md +1 -1
- package/dist/forge-payload/.base-pack/personas/librarian.md +1 -1
- package/dist/forge-payload/.base-pack/personas/orchestrator.md +1 -1
- package/dist/forge-payload/.base-pack/personas/product-manager.md +1 -1
- package/dist/forge-payload/.base-pack/personas/qa-engineer.md +1 -1
- package/dist/forge-payload/.base-pack/personas/supervisor.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/event-emission-schema.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/friction-emit.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/progress-reporting.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/_fragments/store-cli-verbs.md +29 -5
- package/dist/forge-payload/.base-pack/workflows/architect_approve.md +8 -10
- package/dist/forge-payload/.base-pack/workflows/architect_review_sprint_completion.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/architect_sprint_intake.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/architect_sprint_plan.md +5 -5
- package/dist/forge-payload/.base-pack/workflows/collator_agent.md +5 -7
- package/dist/forge-payload/.base-pack/workflows/commit_task.md +7 -9
- package/dist/forge-payload/.base-pack/workflows/enhance.md +5 -5
- package/dist/forge-payload/.base-pack/workflows/implement_plan.md +9 -9
- package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +12 -13
- package/dist/forge-payload/.base-pack/workflows/plan_task.md +5 -6
- package/dist/forge-payload/.base-pack/workflows/review_code.md +8 -8
- package/dist/forge-payload/.base-pack/workflows/review_plan.md +8 -8
- package/dist/forge-payload/.base-pack/workflows/sprint_retrospective.md +3 -3
- package/dist/forge-payload/.base-pack/workflows/triage.md +13 -10
- package/dist/forge-payload/.base-pack/workflows/update_implementation.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/update_plan.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/validate_task.md +6 -8
- package/dist/forge-payload/.base-pack/workflows-js/wfl-fix-bug.js +490 -0
- package/dist/forge-payload/.base-pack/workflows-js/wfl-run-sprint.js +416 -0
- package/dist/forge-payload/.base-pack/workflows-js/wfl-run-task.js +608 -0
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/_defs/locator.schema.json +13 -0
- package/dist/forge-payload/.schemas/bug.schema.json +1 -0
- package/dist/forge-payload/.schemas/config.schema.json +2 -3
- package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/.schemas/event.schema.json +16 -0
- package/dist/forge-payload/.schemas/migrations.json +299 -0
- package/dist/forge-payload/.schemas/sprint.schema.json +1 -0
- package/dist/forge-payload/.schemas/task.schema.json +1 -0
- package/dist/forge-payload/commands/health.md +29 -0
- package/dist/forge-payload/commands/rebuild.md +143 -15
- package/dist/forge-payload/commands/update.md +28 -27
- package/dist/forge-payload/hooks/preflight-session.cjs +99 -0
- package/dist/forge-payload/init/phases/phase-3-materialize.md +18 -5
- package/dist/forge-payload/integrity.json +7 -6
- package/dist/forge-payload/meta/fragments/tool-discipline.md +1 -1
- package/dist/forge-payload/meta/personas/meta-architect.md +1 -1
- package/dist/forge-payload/meta/personas/meta-bug-fixer.md +1 -1
- package/dist/forge-payload/meta/personas/meta-collator.md +7 -7
- package/dist/forge-payload/meta/personas/meta-engineer.md +1 -1
- package/dist/forge-payload/meta/personas/meta-orchestrator.md +1 -1
- package/dist/forge-payload/meta/personas/meta-supervisor.md +1 -1
- package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +1 -1
- package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +2 -2
- package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +29 -5
- package/dist/forge-payload/meta/workflows/meta-approve.md +8 -10
- package/dist/forge-payload/meta/workflows/meta-bug-triage.md +13 -10
- package/dist/forge-payload/meta/workflows/meta-collate.md +6 -8
- package/dist/forge-payload/meta/workflows/meta-commit.md +7 -9
- package/dist/forge-payload/meta/workflows/meta-enhance.md +5 -5
- package/dist/forge-payload/meta/workflows/meta-fix-bug.md +35 -11
- package/dist/forge-payload/meta/workflows/meta-implement.md +18 -9
- package/dist/forge-payload/meta/workflows/meta-migrate.md +13 -14
- package/dist/forge-payload/meta/workflows/meta-new-sprint.md +3 -3
- package/dist/forge-payload/meta/workflows/meta-orchestrate.md +175 -82
- package/dist/forge-payload/meta/workflows/meta-plan-sprint.md +6 -6
- package/dist/forge-payload/meta/workflows/meta-plan-task.md +12 -6
- package/dist/forge-payload/meta/workflows/meta-retro.md +4 -4
- package/dist/forge-payload/meta/workflows/meta-retrospective.md +4 -4
- package/dist/forge-payload/meta/workflows/meta-review-implementation.md +8 -8
- package/dist/forge-payload/meta/workflows/meta-review-plan.md +8 -8
- package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +3 -3
- package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +3 -3
- package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +6 -6
- package/dist/forge-payload/meta/workflows/meta-update-implementation.md +2 -2
- package/dist/forge-payload/meta/workflows/meta-update-plan.md +2 -2
- package/dist/forge-payload/meta/workflows/meta-validate.md +6 -8
- package/dist/forge-payload/schemas/_defs/locator.schema.json +13 -0
- package/dist/forge-payload/schemas/bug.schema.json +1 -0
- package/dist/forge-payload/schemas/config.schema.json +2 -3
- package/dist/forge-payload/schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/schemas/event.schema.json +16 -0
- package/dist/forge-payload/schemas/sprint.schema.json +1 -0
- package/dist/forge-payload/schemas/structure-manifest.json +76 -73
- package/dist/forge-payload/schemas/task.schema.json +1 -0
- package/dist/forge-payload/skills/refresh-kb-links/SKILL.md +14 -7
- package/dist/forge-payload/tools/artifact-store.cjs +242 -0
- package/dist/forge-payload/tools/artifact.cjs +60 -120
- package/dist/forge-payload/tools/banners.cjs +29 -10
- package/dist/forge-payload/tools/check-structure.cjs +88 -7
- package/dist/forge-payload/tools/collate.cjs +16 -2
- package/dist/forge-payload/tools/lib/artifact-kinds.cjs +95 -0
- package/dist/forge-payload/tools/lib/store-nlp.cjs +6 -0
- package/dist/forge-payload/tools/lib/store-query-exec.cjs +39 -5
- package/dist/forge-payload/tools/lib/suggest.cjs +2 -1
- package/dist/forge-payload/tools/manage-config.cjs +5 -7
- package/dist/forge-payload/tools/parse-gates.cjs +73 -1
- package/dist/forge-payload/tools/postflight-gate.cjs +252 -0
- package/dist/forge-payload/tools/preflight-gate.cjs +102 -5
- package/dist/forge-payload/tools/store-cli.cjs +50 -15
- package/dist/forge-payload/tools/substitute-placeholders.cjs +5 -4
- package/dist/forge-payload/tools/verify-phase.cjs +17 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts +5 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js +81 -18
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +19 -24
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js +14 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +22 -8
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/README.md +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +374 -122
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +424 -232
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +38 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +21 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +6 -10
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google.js +5 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/google.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js +3 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.js +2 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +159 -78
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +16 -11
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +4 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +6 -10
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/stream.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/stream.js +14 -2
- package/node_modules/@earendil-works/pi-ai/dist/stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +14 -4
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.js +34 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts +9 -7
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js +8 -7
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts +10 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +179 -79
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +94 -0
- package/node_modules/@earendil-works/pi-coding-agent/README.md +9 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts +3 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +27 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +15 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +5 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +28 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js +18 -24
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js +8 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts +7 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +65 -13
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.d.ts +9 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js +134 -11
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js +10 -6
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts +6 -7
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +75 -28
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +14 -9
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +0 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js +7 -10
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js +5 -7
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js +6 -7
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.d.ts +5 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.js +17 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js +5 -6
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +69 -16
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js +118 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +1 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +2 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +59 -6
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js +10 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js +3 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.d.ts +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.js +13 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/deprecation.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.d.ts +3 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/json.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/custom-provider.md +13 -10
- package/node_modules/@earendil-works/pi-coding-agent/docs/development.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md +12 -6
- package/node_modules/@earendil-works/pi-coding-agent/docs/models.md +25 -12
- package/node_modules/@earendil-works/pi-coding-agent/docs/providers.md +13 -5
- package/node_modules/@earendil-works/pi-coding-agent/docs/quickstart.md +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/rpc.md +2 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/sdk.md +6 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/session-format.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/sessions.md +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +7 -3
- package/node_modules/@earendil-works/pi-coding-agent/docs/terminal-setup.md +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/tui.md +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/usage.md +9 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/README.md +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/index.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/git-merge-and-resolve.ts +115 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/input-transform-streaming.ts +39 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +443 -61
- package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -6
- package/node_modules/@earendil-works/pi-tui/README.md +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +24 -83
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js +7 -55
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +7 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +12 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +34 -7
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +33 -10
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +172 -37
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +6 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +27 -15
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +25 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +96 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/package.json +2 -2
- package/node_modules/@entelligentsia/forge-compress/LICENSE +21 -0
- package/node_modules/@entelligentsia/forge-compress/README.md +85 -0
- package/node_modules/@mariozechner/clipboard/Cargo.toml +3 -3
- package/node_modules/@mariozechner/clipboard/index.d.ts +34 -20
- package/node_modules/@mariozechner/clipboard/index.js +546 -257
- package/node_modules/@mariozechner/clipboard/package.json +5 -6
- package/node_modules/@mariozechner/clipboard/package.json.prepack-backup +14 -14
- package/node_modules/@mariozechner/clipboard/src/lib.rs +4 -9
- package/node_modules/@mariozechner/clipboard-linux-x64-gnu/clipboard.linux-x64-gnu.node +0 -0
- package/node_modules/@mariozechner/clipboard-linux-x64-gnu/package.json +2 -2
- package/package.json +7 -7
- package/dist/bin/forgecli.d.ts +0 -2
- package/dist/bin/forgecli.js +0 -6
- package/dist/bin/forgecli.js.map +0 -1
- package/dist/extensions/forgecli/config-tui/index.d.ts +0 -5
- package/dist/extensions/forgecli/config-tui/index.js +0 -5
- package/dist/extensions/forgecli/config-tui/index.js.map +0 -1
- package/dist/extensions/forgecli/loaders/persona-skill-loader.d.ts +0 -45
- package/dist/extensions/forgecli/loaders/persona-skill-loader.js +0 -227
- package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +0 -1
- package/dist/extensions/forgecli/loaders/template-render.d.ts +0 -20
- package/dist/extensions/forgecli/loaders/template-render.js +0 -85
- package/dist/extensions/forgecli/loaders/template-render.js.map +0 -1
- package/dist/extensions/forgecli/loaders/workflow-loader.d.ts +0 -41
- package/dist/extensions/forgecli/loaders/workflow-loader.js +0 -164
- package/dist/extensions/forgecli/loaders/workflow-loader.js.map +0 -1
- package/dist/forge-payload/.base-pack/commands/quiz-agent.md +0 -6
- package/dist/forge-payload/.base-pack/commands/retrospective.md +0 -6
- package/dist/forge-payload/.base-pack/commands/sprint-intake.md +0 -6
- package/dist/forge-payload/.base-pack/commands/sprint-plan.md +0 -6
- package/dist/forge-payload/.base-pack/workflows/fix_bug.md +0 -446
- package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +0 -934
- package/dist/forge-payload/.base-pack/workflows/run_sprint.md +0 -225
- package/dist/forge-payload/commands/calibrate.md +0 -10
- package/dist/forge-payload/commands/materialize.md +0 -119
- package/dist/forge-payload/commands/migrate.md +0 -12
- package/dist/forge-payload/commands/quiz-agent.md +0 -6
- package/dist/forge-payload/commands/regenerate.md +0 -6
- package/dist/forge-payload/commands/store-query.md +0 -6
- package/dist/forge-payload/commands/store-repair.md +0 -6
- package/dist/forge-payload/commands/update-tools.md +0 -10
- package/dist/forge-payload/meta/templates/meta-retrospective.md +0 -28
- package/dist/forge-payload/tools/prompts/sprint-plan-prompt.md +0 -70
- package/dist/forge-payload/tools/schemas/task-list.schema.json +0 -53
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts +0 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js +0 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts +0 -20
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js +0 -92
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts +0 -18
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js +0 -42
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts +0 -10
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js +0 -31
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts +0 -30
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js +0 -170
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts +0 -26
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js +0 -90
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js.map +0 -1
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/README.md +0 -3
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/clipboard.linux-x64-musl.node +0 -0
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/package.json +0 -25
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// postflight-gate.cjs — evaluates a phase's declared outputs block against
|
|
4
|
+
// the filesystem / task state, post-subagent-return. Returns structured failure
|
|
5
|
+
// data so the orchestrator (run-task.ts) can halt before FSM advance when outputs
|
|
6
|
+
// are not satisfied.
|
|
7
|
+
//
|
|
8
|
+
// Pure function: only fs.existsSync / fs.statSync / fs.readFileSync. No writes,
|
|
9
|
+
// no network, no LLM, no process spawns.
|
|
10
|
+
//
|
|
11
|
+
// CLI shim: node postflight-gate.cjs --phase <name> --task <taskId>
|
|
12
|
+
// Exit codes: 0 (ok), 1 (guard failed), 2 (invalid args / parse error)
|
|
13
|
+
// Stdout on exit 1: single JSON line { phase, reasonCode, detail, remediation }
|
|
14
|
+
//
|
|
15
|
+
// New reasonCodes (FORGE-S26-T19):
|
|
16
|
+
// output-missing — artifact path does not exist
|
|
17
|
+
// output-stub — artifact exists but size < min= bytes
|
|
18
|
+
// require-failed — require predicate over state field failed
|
|
19
|
+
// tool-error — internal parse or store-read failure
|
|
20
|
+
|
|
21
|
+
const fs = require('node:fs');
|
|
22
|
+
const path = require('node:path');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* postflight({ phase, outputs, state, substitutions })
|
|
26
|
+
*
|
|
27
|
+
* @param {string} phase - Phase name (e.g. 'implement')
|
|
28
|
+
* @param {object} outputs - Parsed outputs spec from parseOutputs() — { [phase]: { artifacts, require } }
|
|
29
|
+
* @param {object} [state] - Task/bug state for require predicates (e.g. { task: {...} })
|
|
30
|
+
* @param {object} [substitutions] - Template variable substitutions (e.g. { engineering, sprint, task })
|
|
31
|
+
* @returns {{ ok: boolean, missing: string[], reasonCode: string, detail: string, remediation: string }}
|
|
32
|
+
*/
|
|
33
|
+
function postflight({ phase, outputs, state = {}, substitutions = {} }) {
|
|
34
|
+
const spec = outputs && outputs[phase];
|
|
35
|
+
if (!spec) {
|
|
36
|
+
// No outputs block for this phase — pass through (no-op)
|
|
37
|
+
return { ok: true, missing: [], reasonCode: null, detail: '', remediation: '' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const missing = [];
|
|
41
|
+
|
|
42
|
+
for (const art of spec.artifacts || []) {
|
|
43
|
+
const resolved = applySubstitutions(art.path, substitutions);
|
|
44
|
+
let exists = false;
|
|
45
|
+
let size = 0;
|
|
46
|
+
try {
|
|
47
|
+
const st = fs.statSync(resolved);
|
|
48
|
+
exists = st.isFile();
|
|
49
|
+
size = st.size;
|
|
50
|
+
} catch (_) {
|
|
51
|
+
exists = false;
|
|
52
|
+
}
|
|
53
|
+
if (!exists) {
|
|
54
|
+
missing.push(`output-missing: artifact absent: ${resolved}`);
|
|
55
|
+
} else if (size < (art.minBytes || 0)) {
|
|
56
|
+
missing.push(
|
|
57
|
+
`output-stub: artifact too small: ${resolved} (${size} bytes, need >= ${art.minBytes})`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const pred of spec.require || []) {
|
|
63
|
+
if (!evalPredicate(pred, state)) {
|
|
64
|
+
missing.push(
|
|
65
|
+
`require-failed: ${describePredicate(pred)} (got ${JSON.stringify(readField(pred.field, state))})`,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (missing.length === 0) {
|
|
71
|
+
return { ok: true, missing: [], reasonCode: null, detail: '', remediation: '' };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const { reasonCode, detail, remediation } = buildStructuredFailure(phase, missing);
|
|
75
|
+
return { ok: false, missing, reasonCode, detail, remediation };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function applySubstitutions(template, subs) {
|
|
79
|
+
return template.replace(/\{(\w+)\}/g, (full, key) => {
|
|
80
|
+
if (Object.prototype.hasOwnProperty.call(subs, key)) return String(subs[key]);
|
|
81
|
+
return full;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function readField(dottedPath, state) {
|
|
86
|
+
const parts = dottedPath.split('.');
|
|
87
|
+
let cur = state;
|
|
88
|
+
for (const p of parts) {
|
|
89
|
+
if (cur === null || cur === undefined) return undefined;
|
|
90
|
+
cur = cur[p];
|
|
91
|
+
}
|
|
92
|
+
return cur;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function evalPredicate(pred, state) {
|
|
96
|
+
const actual = readField(pred.field, state);
|
|
97
|
+
switch (pred.op) {
|
|
98
|
+
case '==':
|
|
99
|
+
return String(actual) === String(pred.value);
|
|
100
|
+
case '!=':
|
|
101
|
+
return String(actual) !== String(pred.value);
|
|
102
|
+
case 'in':
|
|
103
|
+
return (pred.value || []).map(String).includes(String(actual));
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`postflight-gate: unknown predicate op "${pred.op}"`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function describePredicate(pred) {
|
|
110
|
+
if (pred.op === 'in') return `${pred.field} in [${(pred.value || []).join(', ')}]`;
|
|
111
|
+
return `${pred.field} ${pred.op} ${pred.value}`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function buildStructuredFailure(phase, missing) {
|
|
115
|
+
let reasonCode = 'tool-error';
|
|
116
|
+
const detailParts = [];
|
|
117
|
+
|
|
118
|
+
for (const m of missing) {
|
|
119
|
+
detailParts.push(m);
|
|
120
|
+
if (reasonCode === 'tool-error') {
|
|
121
|
+
if (/^output-missing/i.test(m)) {
|
|
122
|
+
reasonCode = 'output-missing';
|
|
123
|
+
} else if (/^output-stub/i.test(m)) {
|
|
124
|
+
reasonCode = 'output-stub';
|
|
125
|
+
} else if (/^require-failed/i.test(m)) {
|
|
126
|
+
reasonCode = 'require-failed';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const detail = detailParts.join('; ');
|
|
132
|
+
|
|
133
|
+
const remediationMap = {
|
|
134
|
+
'output-missing': 'Re-run the phase that produces this artifact (e.g. /forge:implement), then retry.',
|
|
135
|
+
'output-stub': 'The artifact was produced but appears incomplete (stub). Ensure the phase wrote a complete file.',
|
|
136
|
+
'require-failed': 'Correct the task/bug state so it satisfies the postflight require predicate, then retry.',
|
|
137
|
+
'tool-error': 'Check the outputs block configuration and store records; run node .forge/tools/postflight-gate.cjs manually for diagnostics.',
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
reasonCode,
|
|
142
|
+
detail,
|
|
143
|
+
remediation: remediationMap[reasonCode],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = { postflight };
|
|
148
|
+
|
|
149
|
+
// CLI shim — only runs when invoked directly
|
|
150
|
+
if (require.main === module) {
|
|
151
|
+
const args = parseArgs(process.argv.slice(2));
|
|
152
|
+
if (!args.phase || !args.task) {
|
|
153
|
+
process.stderr.write('Usage: postflight-gate.cjs --phase <phaseName> --task <taskId>\n');
|
|
154
|
+
process.exit(2);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const { parseOutputs } = require('./parse-gates.cjs');
|
|
158
|
+
|
|
159
|
+
// Resolve config
|
|
160
|
+
let engineeringRoot = 'engineering';
|
|
161
|
+
try {
|
|
162
|
+
const cfg = JSON.parse(fs.readFileSync(path.resolve(process.cwd(), '.forge/config.json'), 'utf8'));
|
|
163
|
+
if (cfg.paths && cfg.paths.engineering) engineeringRoot = cfg.paths.engineering;
|
|
164
|
+
} catch (_) { /* fall back to default */ }
|
|
165
|
+
|
|
166
|
+
// Load task record
|
|
167
|
+
let taskRecord = null;
|
|
168
|
+
try {
|
|
169
|
+
const store = require('./store.cjs');
|
|
170
|
+
taskRecord = store.getTask(args.task);
|
|
171
|
+
} catch (_) {
|
|
172
|
+
// store.cjs not available or task not found — continue with substitutions from args
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Build substitutions
|
|
176
|
+
const sprintId = taskRecord ? taskRecord.sprintId : undefined;
|
|
177
|
+
const substitutions = {
|
|
178
|
+
engineering: engineeringRoot,
|
|
179
|
+
sprint: sprintId,
|
|
180
|
+
task: args.task,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Load workflow markdown (scan .forge/workflows/ for phase)
|
|
184
|
+
const workflowMd = loadWorkflowMarkdown(args.phase);
|
|
185
|
+
if (!workflowMd) {
|
|
186
|
+
process.stderr.write(`postflight-gate: no outputs block defined for phase "${args.phase}" — skipping\n`);
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let outputs;
|
|
191
|
+
try {
|
|
192
|
+
outputs = parseOutputs(workflowMd);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
process.stderr.write(`postflight-gate: ${err.message}\n`);
|
|
195
|
+
process.exit(2);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (!outputs[args.phase]) {
|
|
199
|
+
process.stderr.write(`postflight-gate: no outputs block for phase "${args.phase}" — skipping\n`);
|
|
200
|
+
process.exit(0);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Build state from task record
|
|
204
|
+
const state = {};
|
|
205
|
+
if (taskRecord) state.task = taskRecord;
|
|
206
|
+
|
|
207
|
+
const result = postflight({ phase: args.phase, outputs, state, substitutions });
|
|
208
|
+
|
|
209
|
+
if (result.ok) process.exit(0);
|
|
210
|
+
|
|
211
|
+
process.stderr.write(`Postflight guard failed for phase "${args.phase}":\n`);
|
|
212
|
+
for (const m of result.missing) process.stderr.write(` - ${m}\n`);
|
|
213
|
+
|
|
214
|
+
// Emit structured JSON on stdout for orchestrators
|
|
215
|
+
process.stdout.write(JSON.stringify({
|
|
216
|
+
phase: args.phase,
|
|
217
|
+
reasonCode: result.reasonCode,
|
|
218
|
+
detail: result.detail,
|
|
219
|
+
remediation: result.remediation,
|
|
220
|
+
}) + '\n');
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function parseArgs(argv) {
|
|
225
|
+
const out = {};
|
|
226
|
+
for (let i = 0; i < argv.length; i++) {
|
|
227
|
+
const a = argv[i];
|
|
228
|
+
if (a === '--phase') out.phase = argv[++i];
|
|
229
|
+
else if (a === '--task') out.task = argv[++i];
|
|
230
|
+
}
|
|
231
|
+
return out;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function loadWorkflowMarkdown(phaseName) {
|
|
235
|
+
const workflowsDir = path.resolve(process.cwd(), '.forge/workflows');
|
|
236
|
+
let entries;
|
|
237
|
+
try {
|
|
238
|
+
entries = fs.readdirSync(workflowsDir).filter((f) => f.endsWith('.md'));
|
|
239
|
+
} catch (_) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
const fencePattern = new RegExp('^```outputs\\s+phase=' + escapeRegex(phaseName) + '\\s*$', 'm');
|
|
243
|
+
for (const entry of entries) {
|
|
244
|
+
const md = fs.readFileSync(path.join(workflowsDir, entry), 'utf8');
|
|
245
|
+
if (fencePattern.test(md)) return md;
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function escapeRegex(s) {
|
|
251
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
252
|
+
}
|
|
@@ -113,7 +113,49 @@ function describePredicate(pred) {
|
|
|
113
113
|
return `${pred.field} ${pred.op} ${pred.value}`;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
module.exports = { preflight, resolveTaskArtifactDir, resolveSprintArtifactDir };
|
|
116
|
+
module.exports = { preflight, resolveTaskArtifactDir, resolveSprintArtifactDir, deriveSprintTaskFromArtifactPath };
|
|
117
|
+
|
|
118
|
+
// Derive {sprint} and {task} substitutions directly from a task's artifact path
|
|
119
|
+
// (task.path) when that path is a directory under `<engineeringRoot>/sprints/`.
|
|
120
|
+
//
|
|
121
|
+
// task.path is the authoritative artifact location — it is where the plan /
|
|
122
|
+
// implement phases actually write PLAN.md, REVIEW.md, etc. Splitting it tolerates
|
|
123
|
+
// ANY nesting depth and ANY on-disk naming, so a single rule covers both the
|
|
124
|
+
// modern 2-level layout (`sprints/<sprint>/<task>/`) and legacy 3-level layouts
|
|
125
|
+
// (`sprints/<sprint>/tasks/<task>/`) whose on-disk sprint dir name need not equal
|
|
126
|
+
// sprintId (e.g. sprintId "S19" → dir "sprint_19_platform_ux_improvements"). The
|
|
127
|
+
// directory-scan resolution (resolveSprintArtifactDir + resolveTaskArtifactDir)
|
|
128
|
+
// cannot express the `tasks/` nesting, which is what broke review-plan preflight
|
|
129
|
+
// for heterogeneous-layout projects (walkinto.in S19/S32/S33).
|
|
130
|
+
//
|
|
131
|
+
// {task} = the last path segment (the artifact directory name)
|
|
132
|
+
// {sprint} = everything between `sprints/` and that last segment, joined by "/"
|
|
133
|
+
//
|
|
134
|
+
// File-vs-dir guard: if task.path ends in a filename (has an extension), the
|
|
135
|
+
// artifact directory is its PARENT — strip the filename first. This prevents the
|
|
136
|
+
// bogus `.../TASK_PROMPT.md/PLAN.md` (ENOTDIR) seen when a project stores
|
|
137
|
+
// task.path as a file inside the artifact dir.
|
|
138
|
+
//
|
|
139
|
+
// Returns null when the path is absent, or not under `<engineeringRoot>/sprints/`
|
|
140
|
+
// (e.g. a forge/ source-file path — see regression S12-T06), or resolves to
|
|
141
|
+
// fewer than 2 directory segments. In every null case the caller falls back to
|
|
142
|
+
// the directory-scan resolution, preserving prior behaviour.
|
|
143
|
+
function deriveSprintTaskFromArtifactPath(taskPath, engineeringRoot) {
|
|
144
|
+
if (!taskPath) return null;
|
|
145
|
+
let norm = String(taskPath).replace(/\\/g, '/').replace(/\/+$/, '');
|
|
146
|
+
// File-vs-dir guard — drop a trailing filename so we split on the dir.
|
|
147
|
+
if (/\.[a-zA-Z0-9]+$/.test(norm)) {
|
|
148
|
+
norm = norm.replace(/\/[^/]*$/, '');
|
|
149
|
+
}
|
|
150
|
+
const er = String(engineeringRoot || 'engineering').replace(/\/+$/, '');
|
|
151
|
+
const prefix = er + '/sprints/';
|
|
152
|
+
if (!norm.startsWith(prefix)) return null;
|
|
153
|
+
const segs = norm.slice(prefix.length).split('/').filter(Boolean);
|
|
154
|
+
if (segs.length < 2) return null;
|
|
155
|
+
const task = segs[segs.length - 1];
|
|
156
|
+
const sprint = segs.slice(0, -1).join('/');
|
|
157
|
+
return { sprint, task };
|
|
158
|
+
}
|
|
117
159
|
|
|
118
160
|
// CLI shim: `node preflight-gate.cjs --phase <name> --task <taskId> [--bug <bugId>] [--workflow <name>]`
|
|
119
161
|
// exit codes: 0 ok, 1 gate(s) failed, 2 invalid args / missing definitions
|
|
@@ -246,10 +288,18 @@ if (require.main === module) {
|
|
|
246
288
|
// name is used both as the {sprint} substitution and as the directory in
|
|
247
289
|
// which resolveTaskArtifactDir scans for task subdirectories.
|
|
248
290
|
const sprintId = taskRecord ? taskRecord.sprintId : undefined;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
291
|
+
// Primary resolution: derive {sprint}/{task} straight from task.path (the
|
|
292
|
+
// authoritative artifact directory). This honours arbitrary layout nesting —
|
|
293
|
+
// including legacy 3-level `sprints/<sprint>/tasks/<task>/` trees the
|
|
294
|
+
// directory-scan resolution below cannot express. Falls back to the scan when
|
|
295
|
+
// task.path is not an artifact dir under sprints/ (e.g. a forge/ source file).
|
|
296
|
+
const derived = taskRecord ? deriveSprintTaskFromArtifactPath(taskRecord.path, engineeringRoot) : null;
|
|
297
|
+
const resolvedSprintDir = derived
|
|
298
|
+
? derived.sprint
|
|
299
|
+
: (sprintId ? (resolveSprintArtifactDir(sprintId, engineeringRoot) || sprintId) : undefined);
|
|
300
|
+
const taskArtifactDir = derived
|
|
301
|
+
? derived.task
|
|
302
|
+
: resolveTaskArtifactDir(taskRecord, engineeringRoot, undefined, resolvedSprintDir);
|
|
253
303
|
// Fallback: if task.path points to a file (e.g., TASK_PROMPT.md) we want
|
|
254
304
|
// the *directory* segment, not the filename. Without this, a project that
|
|
255
305
|
// stores task.path as the prompt file would propagate "TASK_PROMPT.md" as
|
|
@@ -299,9 +349,56 @@ if (require.main === module) {
|
|
|
299
349
|
if (result.ok) process.exit(0);
|
|
300
350
|
process.stderr.write(`Gate failed for phase "${args.phase}":\n`);
|
|
301
351
|
for (const m of result.missing) process.stderr.write(` - ${m}\n`);
|
|
352
|
+
// Emit structured JSON on stdout for orchestrators to parse and render.
|
|
353
|
+
// Shape: { phase, reasonCode, detail, remediation }
|
|
354
|
+
const structured = buildStructuredFailure(args.phase, result.missing);
|
|
355
|
+
process.stdout.write(JSON.stringify(structured) + '\n');
|
|
302
356
|
process.exit(1);
|
|
303
357
|
}
|
|
304
358
|
|
|
359
|
+
// Build a structured gate-failure object for orchestrators.
|
|
360
|
+
// Maps the human-readable `missing[]` strings to a typed { phase, reasonCode, detail, remediation }.
|
|
361
|
+
// reasonCode is derived from the dominant failure pattern:
|
|
362
|
+
// artifact-missing — artifact missing / too small
|
|
363
|
+
// predecessor-verdict-missing — after-clause verdict absent or wrong
|
|
364
|
+
// illegal-status — require/forbid predicate fired
|
|
365
|
+
// tool-error — internal error / unrecognised pattern
|
|
366
|
+
// When multiple failures exist, reasonCode reflects the first recognised pattern;
|
|
367
|
+
// detail combines all messages; only a single JSON object is ever emitted.
|
|
368
|
+
function buildStructuredFailure(phase, missing) {
|
|
369
|
+
let reasonCode = 'tool-error';
|
|
370
|
+
const detailParts = [];
|
|
371
|
+
|
|
372
|
+
for (const m of missing) {
|
|
373
|
+
detailParts.push(m);
|
|
374
|
+
if (reasonCode === 'tool-error') {
|
|
375
|
+
if (/^artifact (missing|too small)/i.test(m)) {
|
|
376
|
+
reasonCode = 'artifact-missing';
|
|
377
|
+
} else if (/^predecessor verdict (missing|unreadable)/i.test(m) || /verdict is "/i.test(m)) {
|
|
378
|
+
reasonCode = 'predecessor-verdict-missing';
|
|
379
|
+
} else if (/^(require failed|forbid triggered)/i.test(m)) {
|
|
380
|
+
reasonCode = 'illegal-status';
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const detail = detailParts.join('; ');
|
|
386
|
+
|
|
387
|
+
const remediationMap = {
|
|
388
|
+
'artifact-missing': `Re-run the phase that produces this artifact (e.g. /forge:plan or /forge:implement), then retry.`,
|
|
389
|
+
'predecessor-verdict-missing': `Ensure the predecessor review phase completed and recorded a verdict via set-summary, then retry.`,
|
|
390
|
+
'illegal-status': `Correct the task/bug status (use store-cli update-status) so it satisfies the gate predicate, then retry.`,
|
|
391
|
+
'tool-error': `Check the gate configuration and store records for this task; run node .forge/tools/preflight-gate.cjs manually for diagnostics.`,
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
phase,
|
|
396
|
+
reasonCode,
|
|
397
|
+
detail,
|
|
398
|
+
remediation: remediationMap[reasonCode],
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
|
|
305
402
|
function parseArgs(argv) {
|
|
306
403
|
const out = {};
|
|
307
404
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -55,6 +55,7 @@ const { validateRecord, NULLABLE_FIELDS } = require('./lib/validate.js');
|
|
|
55
55
|
|
|
56
56
|
// FORGE-S22-T03: suggestion engine for "Did you mean?" on validation/transition errors
|
|
57
57
|
const { suggest, suggestEntityType, formatSuggestion } = require('./lib/suggest.cjs');
|
|
58
|
+
const { resolveSummaryFilename, PHASE_TO_KIND } = require('./lib/artifact-kinds.cjs');
|
|
58
59
|
|
|
59
60
|
// Valid phase keys for summaries (dot-delimited → underscore in JSON key)
|
|
60
61
|
const VALID_SUMMARY_PHASES = new Set(['plan', 'review_plan', 'implementation', 'code_review', 'validation', 'triage', 'approve']);
|
|
@@ -432,8 +433,8 @@ Commands:
|
|
|
432
433
|
progress-clear <sprintOrBugId> Clear (truncate) the progress log
|
|
433
434
|
write-collation-state '<json>' Write COLLATION_STATE.json
|
|
434
435
|
validate <entity> '<json>' Validate against schema without writing
|
|
435
|
-
set-summary <taskId> <phase> <jsonFile> Set a phase summary on a task record
|
|
436
|
-
set-bug-summary <bugId> <phase> <jsonFile> Set a phase summary on a bug record
|
|
436
|
+
set-summary <taskId> <phase> [<jsonFile>] Set a phase summary on a task record (sidecar auto-resolved from record.path when jsonFile omitted)
|
|
437
|
+
set-bug-summary <bugId> <phase> [<jsonFile>] Set a phase summary on a bug record (sidecar auto-resolved from record.path when jsonFile omitted)
|
|
437
438
|
describe <entity> Print the JSON Schema for an entity
|
|
438
439
|
template <entity> Print a canonical sample record (required fields populated)
|
|
439
440
|
|
|
@@ -1289,9 +1290,50 @@ function _setSummaryOnEntity(entityKind, entityId, phase, summaryFilePath) {
|
|
|
1289
1290
|
process.exit(1);
|
|
1290
1291
|
}
|
|
1291
1292
|
|
|
1293
|
+
// Load entity first — its `path` is the authoritative artifact directory and
|
|
1294
|
+
// is needed both to self-resolve the sidecar (when no file arg is given) and
|
|
1295
|
+
// to merge the summary below.
|
|
1296
|
+
const record = entityKind === 'task' ? store.getTask(entityId) : store.getBug(entityId);
|
|
1297
|
+
if (!record) {
|
|
1298
|
+
console.error(`${entityKind} not found: ${entityId}`);
|
|
1299
|
+
process.exit(1);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// ADR artifact-resolution Phase 1: when the caller omits the JSON file, derive
|
|
1303
|
+
// the sidecar from record.path + the canonical phase→filename map. The agent
|
|
1304
|
+
// never hand-builds the path (kills the Class-1 failures + the arity bug).
|
|
1305
|
+
let selfResolved = false;
|
|
1306
|
+
if (!summaryFilePath) {
|
|
1307
|
+
if (typeof record.path !== 'string' || record.path.length === 0) {
|
|
1308
|
+
console.error(`Cannot self-resolve summary sidecar: ${entityKind} ${entityId} has no "path". Pass an explicit <jsonFile>.`);
|
|
1309
|
+
process.exit(1);
|
|
1310
|
+
}
|
|
1311
|
+
// record.path is the entity directory; defensively strip a trailing filename.
|
|
1312
|
+
const dir = /\.(md|json)$/i.test(record.path) ? path.dirname(record.path) : record.path;
|
|
1313
|
+
summaryFilePath = path.join(dir, resolveSummaryFilename(entityKind, phase));
|
|
1314
|
+
selfResolved = true;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1292
1317
|
// Read and validate summary JSON
|
|
1293
1318
|
if (!fs.existsSync(summaryFilePath)) {
|
|
1294
|
-
|
|
1319
|
+
// v1.0.10: self-resolve looks for the CANONICAL filename. If an agent wrote a
|
|
1320
|
+
// non-canonical sidecar (e.g. VALIDATE-SUMMARY.json via the Write tool instead
|
|
1321
|
+
// of forge_artifact's VALIDATION-SUMMARY.json), surface the near-name file so
|
|
1322
|
+
// the error is fixable in one step rather than a silent dead-end.
|
|
1323
|
+
let hint = '';
|
|
1324
|
+
if (selfResolved) {
|
|
1325
|
+
try {
|
|
1326
|
+
const dir = path.dirname(summaryFilePath);
|
|
1327
|
+
const expected = path.basename(summaryFilePath);
|
|
1328
|
+
const nearby = fs.readdirSync(dir).filter((f) => f !== expected && f.endsWith('.json') && /summary/i.test(f));
|
|
1329
|
+
if (nearby.length > 0) {
|
|
1330
|
+
const kind = PHASE_TO_KIND[phase];
|
|
1331
|
+
hint = ` (expected ${expected}; found ${nearby.join(', ')} in the same dir — write the sidecar via ` +
|
|
1332
|
+
`forge_artifact artifact:"${kind}", or rename it to ${expected})`;
|
|
1333
|
+
}
|
|
1334
|
+
} catch (_) { /* dir unreadable — fall back to the plain message */ }
|
|
1335
|
+
}
|
|
1336
|
+
console.error(`Summary file not found: ${summaryFilePath}${hint}`);
|
|
1295
1337
|
process.exit(1);
|
|
1296
1338
|
}
|
|
1297
1339
|
|
|
@@ -1309,14 +1351,7 @@ function _setSummaryOnEntity(entityKind, entityId, phase, summaryFilePath) {
|
|
|
1309
1351
|
process.exit(1);
|
|
1310
1352
|
}
|
|
1311
1353
|
|
|
1312
|
-
//
|
|
1313
|
-
const record = entityKind === 'task' ? store.getTask(entityId) : store.getBug(entityId);
|
|
1314
|
-
if (!record) {
|
|
1315
|
-
console.error(`${entityKind} not found: ${entityId}`);
|
|
1316
|
-
process.exit(1);
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
// Merge summary
|
|
1354
|
+
// Merge summary (record was loaded above for path resolution)
|
|
1320
1355
|
if (!record.summaries) record.summaries = {};
|
|
1321
1356
|
record.summaries[phase] = summary;
|
|
1322
1357
|
|
|
@@ -1394,8 +1429,8 @@ function cmdSetSummary() {
|
|
|
1394
1429
|
const phase = args[2];
|
|
1395
1430
|
const summaryFile = args[3];
|
|
1396
1431
|
|
|
1397
|
-
if (!taskId || !phase
|
|
1398
|
-
console.error('Usage: store-cli.cjs set-summary <taskId> <phase> <jsonFile>');
|
|
1432
|
+
if (!taskId || !phase) {
|
|
1433
|
+
console.error('Usage: store-cli.cjs set-summary <taskId> <phase> [<jsonFile>]');
|
|
1399
1434
|
process.exit(1);
|
|
1400
1435
|
}
|
|
1401
1436
|
|
|
@@ -1407,8 +1442,8 @@ function cmdSetBugSummary() {
|
|
|
1407
1442
|
const phase = args[2];
|
|
1408
1443
|
const summaryFile = args[3];
|
|
1409
1444
|
|
|
1410
|
-
if (!bugId || !phase
|
|
1411
|
-
console.error('Usage: store-cli.cjs set-bug-summary <bugId> <phase> <jsonFile>');
|
|
1445
|
+
if (!bugId || !phase) {
|
|
1446
|
+
console.error('Usage: store-cli.cjs set-bug-summary <bugId> <phase> [<jsonFile>]');
|
|
1412
1447
|
process.exit(1);
|
|
1413
1448
|
}
|
|
1414
1449
|
|
|
@@ -120,10 +120,11 @@ const RUNTIME_PASSTHROUGH_KEYS = new Set([
|
|
|
120
120
|
* project prefix via getCommandsSubdir() — see walkBasePack.
|
|
121
121
|
*/
|
|
122
122
|
const SUBDIR_OUTPUT_MAP = {
|
|
123
|
-
personas:
|
|
124
|
-
skills:
|
|
125
|
-
workflows:
|
|
126
|
-
templates:
|
|
123
|
+
personas: path.join('.forge', 'personas'),
|
|
124
|
+
skills: path.join('.forge', 'skills'),
|
|
125
|
+
workflows: path.join('.forge', 'workflows'),
|
|
126
|
+
templates: path.join('.forge', 'templates'),
|
|
127
|
+
'workflows-js': path.join('.claude', 'workflows'),
|
|
127
128
|
};
|
|
128
129
|
|
|
129
130
|
/**
|
|
@@ -194,6 +194,14 @@ function verifyPhase2(cwd, kbPath) {
|
|
|
194
194
|
|
|
195
195
|
const PHASE3_DIRS = ['workflows', 'personas', 'skills', 'templates'];
|
|
196
196
|
|
|
197
|
+
// JS workflow files that substitute-placeholders.cjs emits from
|
|
198
|
+
// base-pack/workflows-js/ into .claude/workflows/ (FORGE-S28-T01).
|
|
199
|
+
// These are checked in addition to the .forge/ directory checks.
|
|
200
|
+
const PHASE3_JS_FILES = [
|
|
201
|
+
path.join('.claude', 'workflows', 'wfl-run-task.js'),
|
|
202
|
+
path.join('.claude', 'workflows', 'wfl-run-sprint.js'),
|
|
203
|
+
];
|
|
204
|
+
|
|
197
205
|
function verifyPhase3(cwd) {
|
|
198
206
|
const missing = [];
|
|
199
207
|
const checked = [];
|
|
@@ -213,6 +221,15 @@ function verifyPhase3(cwd) {
|
|
|
213
221
|
}
|
|
214
222
|
}
|
|
215
223
|
|
|
224
|
+
// Assert generated JS workflow files are present (FORGE-S28-T01)
|
|
225
|
+
for (const relFile of PHASE3_JS_FILES) {
|
|
226
|
+
checked.push(relFile);
|
|
227
|
+
const absFile = path.join(cwd, relFile);
|
|
228
|
+
if (!fs.existsSync(absFile)) {
|
|
229
|
+
missing.push(relFile);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
216
233
|
return {
|
|
217
234
|
phase: 3,
|
|
218
235
|
ok: missing.length === 0,
|
|
@@ -36,6 +36,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
36
36
|
private createStreamFn;
|
|
37
37
|
private drainQueuedMessages;
|
|
38
38
|
private createLoopConfig;
|
|
39
|
+
private validateUniqueNames;
|
|
39
40
|
private validateToolNames;
|
|
40
41
|
private flushPendingSessionWrites;
|
|
41
42
|
private handleAgentEvent;
|
|
@@ -69,9 +70,12 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
69
70
|
label?: string;
|
|
70
71
|
}): Promise<NavigateTreeResult>;
|
|
71
72
|
getModel(): Model<any>;
|
|
72
|
-
getThinkingLevel(): ThinkingLevel;
|
|
73
73
|
setModel(model: Model<any>): Promise<void>;
|
|
74
|
+
getThinkingLevel(): ThinkingLevel;
|
|
74
75
|
setThinkingLevel(level: ThinkingLevel): Promise<void>;
|
|
76
|
+
getTools(): TTool[];
|
|
77
|
+
setTools(tools: TTool[], activeToolNames?: string[]): Promise<void>;
|
|
78
|
+
getActiveTools(): TTool[];
|
|
75
79
|
setActiveTools(toolNames: string[]): Promise<void>;
|
|
76
80
|
getSteeringMode(): QueueMode;
|
|
77
81
|
setSteeringMode(mode: QueueMode): Promise<void>;
|
|
@@ -81,7 +85,6 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
81
85
|
setResources(resources: AgentHarnessResources<TSkill, TPromptTemplate>): Promise<void>;
|
|
82
86
|
getStreamOptions(): AgentHarnessStreamOptions;
|
|
83
87
|
setStreamOptions(streamOptions: AgentHarnessStreamOptions): Promise<void>;
|
|
84
|
-
setTools(tools: TTool[], activeToolNames?: string[]): Promise<void>;
|
|
85
88
|
abort(): Promise<AbortResult>;
|
|
86
89
|
waitForIdle(): Promise<void>;
|
|
87
90
|
subscribe(listener: (event: AgentHarnessEvent<TSkill, TPromptTemplate>, signal?: AbortSignal) => Promise<void> | void): () => void;
|