@entelligentsia/forgecli 1.1.0 → 1.1.3
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 +26 -0
- package/README.md +4 -0
- package/dist/CHANGELOG-forge-plugin.md +114 -0
- package/dist/CHANGELOG-pi.md +56 -0
- package/dist/extensions/forgecli/forge-subagent.js +58 -0
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/mcp-bridge/grove.d.ts +38 -0
- package/dist/extensions/forgecli/mcp-bridge/grove.js +88 -2
- package/dist/extensions/forgecli/mcp-bridge/grove.js.map +1 -1
- package/dist/extensions/forgecli/mcp-bridge/json-rpc-stdio.d.ts +26 -2
- package/dist/extensions/forgecli/mcp-bridge/json-rpc-stdio.js +68 -13
- package/dist/extensions/forgecli/mcp-bridge/json-rpc-stdio.js.map +1 -1
- package/dist/extensions/forgecli/mcp-bridge/mcp-bridge.js +13 -2
- package/dist/extensions/forgecli/mcp-bridge/mcp-bridge.js.map +1 -1
- package/dist/extensions/forgecli/mcp-bridge/mcp-session.d.ts +3 -3
- package/dist/extensions/forgecli/mcp-bridge/mcp-session.js +3 -6
- package/dist/extensions/forgecli/mcp-bridge/mcp-session.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/init/init-phase-dispatch.d.ts +49 -40
- package/dist/extensions/forgecli/orchestrators/init/init-phase-dispatch.js +59 -188
- package/dist/extensions/forgecli/orchestrators/init/init-phase-dispatch.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/init/init-phases.d.ts +0 -43
- package/dist/extensions/forgecli/orchestrators/init/init-phases.js +11 -59
- package/dist/extensions/forgecli/orchestrators/init/init-phases.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/init/init-steps.d.ts +115 -0
- package/dist/extensions/forgecli/orchestrators/init/init-steps.js +125 -0
- package/dist/extensions/forgecli/orchestrators/init/init-steps.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/init/run-init-pipeline.js +400 -211
- package/dist/extensions/forgecli/orchestrators/init/run-init-pipeline.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/init/run-init-types.d.ts +8 -2
- package/dist/extensions/forgecli/orchestrators/init/run-init-types.js +15 -5
- package/dist/extensions/forgecli/orchestrators/init/run-init-types.js.map +1 -1
- package/dist/forge-payload/.base-pack/workflows-js/wfl-init.js +99 -38
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.init/generation/generate-kb-doc.md +24 -0
- package/dist/forge-payload/.schemas/migrations.json +77 -0
- package/dist/forge-payload/init/generation/generate-kb-doc.md +24 -0
- package/dist/forge-payload/init/phases/phase-2/context.md +23 -0
- package/dist/forge-payload/init/phases/phase-2/database.md +26 -0
- package/dist/forge-payload/init/phases/phase-2/deployment.md +26 -0
- package/dist/forge-payload/init/phases/phase-2/domain-concepts.md +26 -0
- package/dist/forge-payload/init/phases/phase-2/domain-model.md +26 -0
- package/dist/forge-payload/init/phases/phase-2/entity-model.md +26 -0
- package/dist/forge-payload/init/phases/phase-2/index.md +25 -0
- package/dist/forge-payload/init/phases/phase-2/processes.md +26 -0
- package/dist/forge-payload/init/phases/phase-2/routing.md +25 -0
- package/dist/forge-payload/init/phases/phase-2/stack-checklist.md +25 -0
- package/dist/forge-payload/init/phases/phase-2/stack.md +27 -0
- package/dist/forge-payload/init/phases/phase-2/testing.md +26 -0
- package/dist/forge-payload/init/phases/phase-2-discover.md +15 -9
- package/dist/forge-payload/payload-manifest.json +2 -2
- package/dist/forge-payload/tools/seed-store.cjs +14 -0
- package/dist/forge-payload/tools/verify-phase.cjs +61 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +3 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +10 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.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 +4 -6
- 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/env/nodejs.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js +20 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +2 -14
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +16 -5
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +61 -41
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +8 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +2 -14
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +15 -45
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +15 -45
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +461 -22
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +140 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +141 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts +20 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.d.ts +21 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts +21 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts +10 -5
- package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js +4 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts +82 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +57 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.js +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.js +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js +5 -5
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts +88 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js +75 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +33 -15
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +101 -84
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/together.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/together.models.js +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/together.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +44 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +41 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js +12 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js +12 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js +12 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.js +15 -15
- package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.d.ts +25 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.js +109 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts +2 -0
- 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 +15 -2
- 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 +3 -2
- 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/overflow.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +56 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +6 -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 +39 -15
- 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/auth-storage.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js +13 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.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 +5 -8
- 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/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js +6 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -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 +33 -1
- 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 +16 -2
- 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/http-dispatcher.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/http-dispatcher.js +28 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/http-dispatcher.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.d.ts +10 -0
- 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 +14 -17
- 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/provider-attribution.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.js +0 -10
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts +20 -1
- 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 +87 -68
- 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 +3 -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 +8 -0
- 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/tools/bash.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js +20 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.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 +2 -2
- 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/index.d.ts +3 -2
- 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 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +15 -7
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-entry.d.ts +19 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-entry.js +52 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-entry.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +13 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/status-indicator.d.ts +28 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/status-indicator.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/status-indicator.js +60 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/status-indicator.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +6 -2
- 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 +18 -5
- 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 +10 -10
- 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 +143 -130
- 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/rpc/rpc-client.d.ts +15 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.js +14 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.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 +16 -0
- 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 +26 -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/package-manager-cli.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md +55 -8
- package/node_modules/@earendil-works/pi-coding-agent/docs/rpc.md +58 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/sdk.md +28 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/session-format.md +18 -8
- package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +1 -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/package.json +1 -1
- 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/entry-renderer.ts +41 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/gondolin/package-lock.json +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/gondolin/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/question.ts +1 -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 +12 -12
- package/node_modules/@earendil-works/pi-coding-agent/package.json +4 -4
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
// run-init-pipeline.ts — top-level FSM for the /forge:init orchestrated pipeline.
|
|
2
2
|
// FORGE-S33-T03.
|
|
3
3
|
//
|
|
4
|
-
// Provides `runInitPipeline(opts)` which drives the
|
|
5
|
-
// -
|
|
6
|
-
// -
|
|
7
|
-
// -
|
|
4
|
+
// Provides `runInitPipeline(opts)` which drives the step machine (Slice 1):
|
|
5
|
+
// - builds the flat INIT_STEPS table, topo-sorts it into waves
|
|
6
|
+
// - startPhase routing (resume from any coarse phase 1–4 via PHASE_TO_WAVE)
|
|
7
|
+
// - runs each wave concurrently (runWave/Promise.all); per step:
|
|
8
|
+
// check precondition → run (deterministic thunk OR subagent) → check
|
|
9
|
+
// requiredOutput → advance / rerun (retryPolicy) / halt
|
|
10
|
+
// - deterministic Phase 3/4 execution via existing helpers (now steps)
|
|
8
11
|
// - checkpoint writes via writeInitProgress
|
|
9
12
|
// - orchestrator transcript + OrchestratorTree nodes
|
|
10
13
|
// - IL10-compliant phase event emission (orchestrator-only; subagents never emit)
|
|
@@ -13,7 +16,7 @@
|
|
|
13
16
|
// Iron Laws:
|
|
14
17
|
// IL6 — no shell-string interpolation; all external calls via spawnSync argv arrays
|
|
15
18
|
// IL7 — every failure path emits ctx.ui.notify and returns; no silent continuation
|
|
16
|
-
// IL10 — ALL LLM dispatch goes through
|
|
19
|
+
// IL10 — ALL LLM dispatch goes through dispatchSingleAgent → runForgeSubagent (NO sendKickoff)
|
|
17
20
|
// Orchestrator is the sole emitter of phase events; subagents NEVER call store-cli emit.
|
|
18
21
|
//
|
|
19
22
|
// Layering: may import from orchestrators/init/ siblings, orchestrators/common/,
|
|
@@ -31,8 +34,10 @@ import { createOrchestratorNotifier } from "../common/orchestrator-notify.js";
|
|
|
31
34
|
import { runPipelinePreflight } from "../common/orchestrator-entry.js";
|
|
32
35
|
import { withOrchestratorTranscript, } from "../common/orchestrator-transcript-session.js";
|
|
33
36
|
import { emitEvent } from "../task/task-events.js";
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
37
|
+
import { INIT_SESSION_ID } from "./init-phases.js";
|
|
38
|
+
import { dispatchSingleAgent, readInitPhasePrompt, readInitSharedProcedure, readInitPhase2Fragment, } from "./init-phase-dispatch.js";
|
|
39
|
+
import { runStep, runWave, topoSortWaves, } from "./init-steps.js";
|
|
40
|
+
import { DISCOVERY_SCHEMA, DOMAINS, KB_DOC_IDS, KB_DOC_SCHEMA } from "./run-init-types.js";
|
|
36
41
|
import { getSessionRegistry } from "../../session-registry.js";
|
|
37
42
|
import { getOrchestratorTree } from "../../orchestrator-tree.js";
|
|
38
43
|
// ── Status / message keys ─────────────────────────────────────────────────────
|
|
@@ -41,14 +46,23 @@ const MESSAGE_KEY = "forge:init:message";
|
|
|
41
46
|
// ── buildInitPhaseEvent ───────────────────────────────────────────────────────
|
|
42
47
|
/**
|
|
43
48
|
* Build an init-specific phase event object for IL10 emission.
|
|
44
|
-
* The orchestrator calls this after each
|
|
49
|
+
* The orchestrator calls this after each successful subagent STEP completes.
|
|
50
|
+
*
|
|
51
|
+
* `stepId` is folded into `eventId` (and per-step start/end timestamps are used)
|
|
52
|
+
* so every step in a concurrent fan-out wave produces a DISTINCT event file.
|
|
53
|
+
* Deriving the id from phaseName + waveStartMs alone collided every step in a
|
|
54
|
+
* wave onto one <eventId>.json (store.writeEvent is a plain overwrite), silently
|
|
55
|
+
* discarding all but the last step's token accounting.
|
|
45
56
|
*/
|
|
46
|
-
function buildInitPhaseEvent(phaseName, sprintId, startMs, endMs, model, provider, usage) {
|
|
57
|
+
function buildInitPhaseEvent(phaseName, stepId, sprintId, startMs, endMs, model, provider, usage) {
|
|
47
58
|
const durationMs = Math.max(0, endMs - startMs);
|
|
48
59
|
const startIso = new Date(startMs).toISOString();
|
|
49
60
|
const compactTs = startIso.replace(/[-:.Z]/g, "");
|
|
61
|
+
// Sanitize the step id for use inside a filesystem-safe eventId (step ids
|
|
62
|
+
// carry ':' e.g. "discovery:routing", "kb-doc:stack").
|
|
63
|
+
const safeStepId = stepId.replace(/[^A-Za-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
50
64
|
return {
|
|
51
|
-
eventId: `forge-init_${phaseName}_${compactTs}`,
|
|
65
|
+
eventId: `forge-init_${phaseName}_${safeStepId}_${compactTs}`,
|
|
52
66
|
sprintId,
|
|
53
67
|
role: `init-${phaseName}`,
|
|
54
68
|
action: `forge:init:${phaseName}`,
|
|
@@ -179,8 +193,6 @@ async function runInitPipelineInner(opts, modelRoutingConfig, session) {
|
|
|
179
193
|
}
|
|
180
194
|
// Resolve kbFolder from opts or configCache (default: "engineering").
|
|
181
195
|
const kbFolder = opts.kbFolder ?? "engineering";
|
|
182
|
-
// kbPathFinal is resolved by Phase 4 or from configCache after Phase 1.
|
|
183
|
-
let kbPathFinal;
|
|
184
196
|
// Build initial configCache from .forge/config.json (fallback: {}).
|
|
185
197
|
let configCache = {};
|
|
186
198
|
try {
|
|
@@ -189,237 +201,414 @@ async function runInitPipelineInner(opts, modelRoutingConfig, session) {
|
|
|
189
201
|
catch {
|
|
190
202
|
// File not yet present — Phase 1 will create it
|
|
191
203
|
}
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
204
|
+
// ── Coarse-phase ↔ wave bridge ────────────────────────────────────────────
|
|
205
|
+
// The step machine groups steps into topo waves, but the on-disk
|
|
206
|
+
// `.forge/cache/init-progress` checkpoint + resume tests speak the coarse
|
|
207
|
+
// phase number (1–4). These tables bridge the two with NO checkpoint-format
|
|
208
|
+
// change (PLAN design #8). Wave layout (from topoSortWaves on INIT_STEPS):
|
|
209
|
+
// 0 discovery×5 · 1 config-writer · 2 enforce-config → phase 1 (collect)
|
|
210
|
+
// 3 kb-doc×10 · 4 index · 5 context · 6 verify-discover → phase 2 (discover)
|
|
211
|
+
// 7 materialize → phase 3
|
|
212
|
+
// 8 register → phase 4
|
|
213
|
+
const WAVE_PHASE_NUM = [1, 1, 1, 2, 2, 2, 2, 3, 4];
|
|
214
|
+
const WAVE_PHASE_NAME = [
|
|
215
|
+
"collect", "collect", "collect",
|
|
216
|
+
"discover", "discover", "discover", "discover",
|
|
217
|
+
"materialize", "register",
|
|
218
|
+
];
|
|
219
|
+
// Resume: coarse startPhase (1–4) → first wave of that phase.
|
|
220
|
+
const PHASE_TO_WAVE = { 1: 0, 2: 3, 3: 7, 4: 8 };
|
|
221
|
+
const startWave = PHASE_TO_WAVE[opts.startPhase ?? 1] ?? 0;
|
|
222
|
+
const state = {
|
|
223
|
+
configCache,
|
|
224
|
+
verifyOk: true,
|
|
225
|
+
phase3Ok: true,
|
|
226
|
+
phase4Ok: true,
|
|
227
|
+
};
|
|
228
|
+
// Pre-read the bundled phase prompts needed for the resume range. A prompt
|
|
229
|
+
// read failure is a graceful pipeline failure (IL7), not a thrown crash.
|
|
230
|
+
//
|
|
231
|
+
// Slice 2 (FORGE-S35-T03): the Phase-2 base prompt is NO LONGER the whole
|
|
232
|
+
// phase-2-discover.md rulebook. It is the shared procedure (generate-kb-doc.md);
|
|
233
|
+
// each Phase-2 step appends its OWN substance fragment + AGENT PARAMS in its
|
|
234
|
+
// buildPrompt, so a subagent sees only its own docId's work. Fragments are
|
|
235
|
+
// keyed by KB_DOC_ID basename plus "index" / "context".
|
|
236
|
+
const promptCache = {};
|
|
237
|
+
const phase2Fragments = {};
|
|
238
|
+
try {
|
|
239
|
+
if (startWave <= 1)
|
|
240
|
+
promptCache[1] = readInitPhasePrompt(bundleRoot, 1);
|
|
241
|
+
if (startWave <= 5) {
|
|
242
|
+
promptCache[2] = readInitSharedProcedure(bundleRoot);
|
|
243
|
+
const fragmentNames = [
|
|
244
|
+
...KB_DOC_IDS.map((id) => id.slice(id.lastIndexOf("/") + 1)),
|
|
245
|
+
"index",
|
|
246
|
+
"context",
|
|
247
|
+
];
|
|
248
|
+
for (const name of fragmentNames) {
|
|
249
|
+
phase2Fragments[name] = readInitPhase2Fragment(bundleRoot, name);
|
|
250
|
+
}
|
|
201
251
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
const e = err;
|
|
255
|
+
const failure = `phase prompt read failed: ${e.message ?? "unknown"}`;
|
|
256
|
+
ctx.ui.notify(`× forge:init — ${failure}`, "error");
|
|
257
|
+
return makeFailResult({ ok: false, lastPhase: WAVE_PHASE_NUM[startWave], failure });
|
|
258
|
+
}
|
|
259
|
+
// ── Subagent step runner (IL10: dispatch via dispatchSingleAgent) ─────────
|
|
260
|
+
const dispatchCounts = {};
|
|
261
|
+
let currentWaveIndex = startWave;
|
|
262
|
+
const dispatchSubagent = async (run) => {
|
|
263
|
+
const base = promptCache[run.promptPhase];
|
|
264
|
+
if (base === undefined) {
|
|
265
|
+
throw new Error(`init: phase-${run.promptPhase} prompt not loaded for step ${run.subLabel}`);
|
|
266
|
+
}
|
|
267
|
+
const prompt = run.buildPrompt(base, state);
|
|
268
|
+
const dispatchParams = {
|
|
218
269
|
opts,
|
|
219
|
-
phase,
|
|
220
|
-
phaseIndex: currentPhaseIndex,
|
|
221
270
|
cwd,
|
|
222
271
|
ctx,
|
|
223
272
|
bundleRoot,
|
|
224
|
-
kbFolder,
|
|
225
|
-
isoTimestamp: opts.isoTimestamp,
|
|
226
273
|
modelRoutingConfig,
|
|
227
274
|
forgeToolDefs: opts.forgeToolDefs,
|
|
228
|
-
dispatchCounts
|
|
275
|
+
dispatchCounts,
|
|
276
|
+
orderHint: currentWaveIndex,
|
|
277
|
+
};
|
|
278
|
+
return dispatchSingleAgent(run.subLabel, run.subRole, run.modelRole, prompt, run.schema, run.persona, dispatchParams);
|
|
279
|
+
};
|
|
280
|
+
// ── INIT_STEPS: the flat step table that supersedes coarse INIT_PHASES ─────
|
|
281
|
+
function buildInitSteps() {
|
|
282
|
+
const iso = opts.isoTimestamp;
|
|
283
|
+
// Deterministic postcondition for a subagent step: its own dispatch exited 0.
|
|
284
|
+
const exitOk = async (_c, lastResult) => ({
|
|
285
|
+
ok: lastResult?.exitCode === 0,
|
|
286
|
+
reason: lastResult && lastResult.exitCode !== 0 ? `subagent exited ${lastResult.exitCode}` : undefined,
|
|
229
287
|
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
288
|
+
// Deterministic precondition replacing the DELETED Phase-2 gate subagent:
|
|
289
|
+
// verify phase-1 config is ready before kb-doc generation fans out.
|
|
290
|
+
const kbReady = async (c) => {
|
|
291
|
+
const cc = c.configCache;
|
|
292
|
+
const ok = !!cc && typeof cc === "object";
|
|
293
|
+
return { ok, reason: ok ? undefined : "phase-1 config not ready (gate)" };
|
|
294
|
+
};
|
|
295
|
+
const steps = [];
|
|
296
|
+
// Wave 0 — 5 domain discovery agents (independent fan-out).
|
|
297
|
+
for (const domain of DOMAINS) {
|
|
298
|
+
steps.push({
|
|
299
|
+
id: `discovery:${domain}`,
|
|
300
|
+
dependsOn: [],
|
|
301
|
+
retryPolicy: { maxReruns: 0 },
|
|
302
|
+
requiredOutput: exitOk,
|
|
303
|
+
run: {
|
|
304
|
+
kind: "subagent",
|
|
305
|
+
promptPhase: 1,
|
|
306
|
+
subLabel: `discovery:${domain}`,
|
|
307
|
+
subRole: "plan",
|
|
308
|
+
modelRole: "discovery",
|
|
309
|
+
persona: "engineer",
|
|
310
|
+
phaseGroup: "collect",
|
|
311
|
+
schema: DISCOVERY_SCHEMA,
|
|
312
|
+
buildPrompt: (b) => `${b}\n\n<!-- AGENT PARAMS -->\ndomain: ${domain}\nkbFolder: ${kbFolder}\nisoTimestamp: ${iso}\n`,
|
|
313
|
+
},
|
|
242
314
|
});
|
|
243
|
-
return makeFailResult({ ok: false, lastPhase: phaseNum, failure });
|
|
244
315
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
316
|
+
// Wave 1 — config-writer (depends on all domains; retries once).
|
|
317
|
+
steps.push({
|
|
318
|
+
id: "config-writer",
|
|
319
|
+
dependsOn: DOMAINS.map((d) => `discovery:${d}`),
|
|
320
|
+
retryPolicy: { maxReruns: 1 },
|
|
321
|
+
requiredOutput: exitOk,
|
|
322
|
+
run: {
|
|
323
|
+
kind: "subagent",
|
|
324
|
+
promptPhase: 1,
|
|
325
|
+
subLabel: "config-writer",
|
|
326
|
+
subRole: "plan",
|
|
327
|
+
modelRole: "config",
|
|
328
|
+
persona: "engineer",
|
|
329
|
+
phaseGroup: "collect",
|
|
330
|
+
buildPrompt: (b) => `${b}\n\n<!-- AGENT PARAMS -->\nrole: config-writer\nkbFolder: ${kbFolder}\nisoTimestamp: ${iso}\n`,
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
// Wave 2 — deterministic: orchestrator-owned KB-folder + prefix enforcement,
|
|
334
|
+
// configCache refresh, coarse phase-1 checkpoint. (Migrated verbatim from the
|
|
335
|
+
// old inlined post-collect hook — the KB folder + prefix are NOT LLM-routed.)
|
|
336
|
+
steps.push({
|
|
337
|
+
id: "enforce-config",
|
|
338
|
+
dependsOn: ["config-writer"],
|
|
339
|
+
retryPolicy: { maxReruns: 0 },
|
|
340
|
+
run: {
|
|
341
|
+
kind: "deterministic",
|
|
342
|
+
thunk: async () => {
|
|
343
|
+
const manageConfigTool = path.join(toolsRoot, "manage-config.cjs");
|
|
344
|
+
if (fs.existsSync(manageConfigTool)) {
|
|
345
|
+
await runToolAdvisory(manageConfigTool, ["set", "paths.engineering", kbFolder], cwd, ctx, "manage-config paths.engineering");
|
|
346
|
+
const projectPrefix = opts.projectPrefix ?? deriveProjectPrefix(projectName);
|
|
347
|
+
await runToolAdvisory(manageConfigTool, ["set", "project.prefix", projectPrefix], cwd, ctx, "manage-config project.prefix");
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
state.configCache = JSON.parse(fs.readFileSync(path.join(cwd, ".forge", "config.json"), "utf8"));
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// keep existing cache
|
|
354
|
+
}
|
|
355
|
+
writeInitProgress(cwd, 1);
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
// Wave 3 — 10 kb-doc agents (independent fan-out; gate is now a precondition).
|
|
360
|
+
for (const docId of KB_DOC_IDS) {
|
|
361
|
+
steps.push({
|
|
362
|
+
id: `kb-doc:${docId}`,
|
|
363
|
+
dependsOn: ["enforce-config"],
|
|
364
|
+
precondition: kbReady,
|
|
365
|
+
retryPolicy: { maxReruns: 1 },
|
|
366
|
+
requiredOutput: exitOk,
|
|
367
|
+
run: {
|
|
368
|
+
kind: "subagent",
|
|
369
|
+
promptPhase: 2,
|
|
370
|
+
subLabel: `kb-doc:${docId}`,
|
|
371
|
+
subRole: "plan",
|
|
372
|
+
modelRole: "kb-doc",
|
|
373
|
+
persona: "engineer",
|
|
374
|
+
phaseGroup: "discover",
|
|
375
|
+
schema: KB_DOC_SCHEMA,
|
|
376
|
+
buildPrompt: (b) => {
|
|
377
|
+
const fragment = phase2Fragments[docId.slice(docId.lastIndexOf("/") + 1)] ?? "";
|
|
378
|
+
return `${b}\n\n${fragment}\n\n<!-- AGENT PARAMS -->\nrole: kb-doc\ndocId: ${docId}\nkbFolder: ${kbFolder}\nisoTimestamp: ${iso}\n`;
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
});
|
|
300
382
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
383
|
+
// Wave 4 — index (depends on all kb-docs).
|
|
384
|
+
steps.push({
|
|
385
|
+
id: "index",
|
|
386
|
+
dependsOn: KB_DOC_IDS.map((d) => `kb-doc:${d}`),
|
|
387
|
+
retryPolicy: { maxReruns: 0 },
|
|
388
|
+
requiredOutput: exitOk,
|
|
389
|
+
run: {
|
|
390
|
+
kind: "subagent",
|
|
391
|
+
promptPhase: 2,
|
|
392
|
+
subLabel: "index",
|
|
393
|
+
subRole: "plan",
|
|
394
|
+
modelRole: "index",
|
|
395
|
+
persona: "engineer",
|
|
396
|
+
phaseGroup: "discover",
|
|
397
|
+
buildPrompt: (b) => `${b}\n\n${phase2Fragments["index"] ?? ""}\n\n<!-- AGENT PARAMS -->\nrole: index\nkbFolder: ${kbFolder}\nisoTimestamp: ${iso}\n`,
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
// Wave 5 — context (depends on index; retries once).
|
|
401
|
+
steps.push({
|
|
402
|
+
id: "context",
|
|
403
|
+
dependsOn: ["index"],
|
|
404
|
+
retryPolicy: { maxReruns: 1 },
|
|
405
|
+
requiredOutput: exitOk,
|
|
406
|
+
run: {
|
|
407
|
+
kind: "subagent",
|
|
408
|
+
promptPhase: 2,
|
|
409
|
+
subLabel: "context",
|
|
410
|
+
subRole: "plan",
|
|
411
|
+
modelRole: "context",
|
|
412
|
+
persona: "engineer",
|
|
413
|
+
phaseGroup: "discover",
|
|
414
|
+
buildPrompt: (b) => `${b}\n\n${phase2Fragments["context"] ?? ""}\n\n<!-- AGENT PARAMS -->\nrole: context\nkbFolder: ${kbFolder}\nisoTimestamp: ${iso}\n`,
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
// Wave 6 — deterministic: verifyPhase2 + post-verify hooks + coarse phase-2
|
|
418
|
+
// checkpoint. requiredOutput gates on the verify result.
|
|
419
|
+
steps.push({
|
|
420
|
+
id: "verify-discover",
|
|
421
|
+
dependsOn: ["context"],
|
|
422
|
+
retryPolicy: { maxReruns: 0 },
|
|
423
|
+
requiredOutput: async (c) => {
|
|
424
|
+
const s = c;
|
|
425
|
+
return { ok: s.verifyOk, reason: s.verifyReason };
|
|
426
|
+
},
|
|
427
|
+
run: {
|
|
428
|
+
kind: "deterministic",
|
|
429
|
+
thunk: async () => {
|
|
430
|
+
let kbPath = kbFolder;
|
|
431
|
+
try {
|
|
432
|
+
const cachePaths = state.configCache.paths;
|
|
433
|
+
if (cachePaths && typeof cachePaths.engineering === "string") {
|
|
434
|
+
kbPath = cachePaths.engineering;
|
|
435
|
+
}
|
|
339
436
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
437
|
+
catch {
|
|
438
|
+
// use kbFolder default
|
|
439
|
+
}
|
|
440
|
+
const verifyResult = await verifyPhase2(cwd, kbPath);
|
|
441
|
+
if (!verifyResult.ok) {
|
|
442
|
+
state.verifyOk = false;
|
|
443
|
+
state.verifyReason = `Phase 2 verify failed: ${verifyResult.missing.join(", ")}`;
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
state.verifyOk = true;
|
|
447
|
+
await runPhase2PostVerifyHooks(cwd, bundleRoot, toolsRoot, projectName, state.configCache, ctx);
|
|
448
|
+
writeInitProgress(cwd, 2);
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
// Wave 7 — deterministic: Phase 3 materialize (scaffold + verify) + checkpoint.
|
|
453
|
+
steps.push({
|
|
454
|
+
id: "materialize",
|
|
455
|
+
dependsOn: ["verify-discover"],
|
|
456
|
+
retryPolicy: { maxReruns: 0 },
|
|
457
|
+
requiredOutput: async (c) => {
|
|
458
|
+
const s = c;
|
|
459
|
+
return {
|
|
460
|
+
ok: s.phase3Ok,
|
|
461
|
+
reason: s.phase3Ok ? undefined : "Phase 3 abort (verify failed or tools missing)",
|
|
462
|
+
};
|
|
463
|
+
},
|
|
464
|
+
run: {
|
|
465
|
+
kind: "deterministic",
|
|
466
|
+
thunk: async () => {
|
|
467
|
+
const phase3Result = await runPhase3(cwd, bundleRoot, toolsRoot, ctx);
|
|
468
|
+
if (phase3Result === "abort") {
|
|
469
|
+
state.phase3Ok = false;
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
state.phase3Ok = true;
|
|
473
|
+
writeInitProgress(cwd, 3);
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
// Wave 8 — deterministic: Phase 4 register (internally deletes init-progress).
|
|
478
|
+
steps.push({
|
|
479
|
+
id: "register",
|
|
480
|
+
dependsOn: ["materialize"],
|
|
481
|
+
retryPolicy: { maxReruns: 0 },
|
|
482
|
+
requiredOutput: async (c) => {
|
|
483
|
+
const s = c;
|
|
484
|
+
return { ok: s.phase4Ok, reason: s.phase4Ok ? undefined : "Phase 4 abort" };
|
|
485
|
+
},
|
|
486
|
+
run: {
|
|
487
|
+
kind: "deterministic",
|
|
488
|
+
thunk: async () => {
|
|
489
|
+
const isPiRuntime = opts.isPiRuntime ?? (() => false);
|
|
490
|
+
const getBundledToolsRoot = opts.getBundledToolsRoot ?? (() => toolsRoot);
|
|
491
|
+
const phase4Ctx = {
|
|
492
|
+
cwd,
|
|
493
|
+
bundleRoot,
|
|
494
|
+
toolsRoot,
|
|
495
|
+
projectName,
|
|
496
|
+
configCache: state.configCache,
|
|
497
|
+
ctx,
|
|
498
|
+
isPiRuntime,
|
|
499
|
+
getBundledToolsRoot,
|
|
500
|
+
};
|
|
501
|
+
const phase4Result = await runPhase4(phase4Ctx);
|
|
502
|
+
if (phase4Result === "abort") {
|
|
503
|
+
state.phase4Ok = false;
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
state.phase4Ok = true;
|
|
507
|
+
state.kbPathFinal = phase4Result.kbPathFinal;
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
return steps;
|
|
512
|
+
}
|
|
513
|
+
// ── Drive the waves ────────────────────────────────────────────────────────
|
|
514
|
+
const steps = buildInitSteps();
|
|
515
|
+
const waves = topoSortWaves(steps);
|
|
516
|
+
let lastPhase = startWave === 0 ? 0 : WAVE_PHASE_NUM[startWave - 1] ?? 0;
|
|
517
|
+
const pipelineStartMs = Date.now();
|
|
518
|
+
for (let w = startWave; w < waves.length; w++) {
|
|
519
|
+
currentWaveIndex = w;
|
|
520
|
+
const wave = waves[w];
|
|
521
|
+
const phaseName = WAVE_PHASE_NAME[w];
|
|
522
|
+
const phaseNum = WAVE_PHASE_NUM[w];
|
|
523
|
+
ctx.ui.setStatus?.(STATUS_KEY, `forge:init: wave ${w + 1}/${waves.length} (${phaseName})`);
|
|
524
|
+
ctx.ui.notify(`→ init: ${phaseName} · wave ${w + 1}/${waves.length} [${wave.map((s) => s.id).join(", ")}]`, "info");
|
|
525
|
+
orchTranscript.record({
|
|
526
|
+
kind: "phase-start",
|
|
527
|
+
ts: new Date().toISOString(),
|
|
528
|
+
phase: phaseName,
|
|
529
|
+
phaseIndex: w,
|
|
530
|
+
phaseCount: waves.length,
|
|
531
|
+
attempt: 1,
|
|
532
|
+
workflowFile: `init-${phaseName}`,
|
|
533
|
+
persona: "engineer",
|
|
534
|
+
});
|
|
535
|
+
const waveStartMs = Date.now();
|
|
536
|
+
const outcomes = await runWave(wave, (step) => runStep(step, { ctx: state, dispatchSubagent }));
|
|
537
|
+
// IL10: orchestrator emits ONE phase event per successful subagent step,
|
|
538
|
+
// composed from captured result.{model,provider,usage} + the step's OWN
|
|
539
|
+
// start/end bracket (outcome.startMs/endMs) so each event is distinct and
|
|
540
|
+
// duration is attributed per step, not per wave. Deterministic steps emit
|
|
541
|
+
// nothing (no subagent telemetry to attribute). Subagents never emit.
|
|
542
|
+
const { sprintId } = opts;
|
|
543
|
+
for (let i = 0; i < wave.length; i++) {
|
|
544
|
+
const step = wave[i];
|
|
545
|
+
const outcome = outcomes[i];
|
|
546
|
+
if (step.run.kind !== "subagent" || !outcome.ok || !outcome.result)
|
|
547
|
+
continue;
|
|
368
548
|
if (!sprintId) {
|
|
369
|
-
ctx.ui.notify(`⚠ forge:init — sprintId not provided; skipping phase event emit for ${
|
|
549
|
+
ctx.ui.notify(`⚠ forge:init — sprintId not provided; skipping phase event emit for ${step.id}`, "warning");
|
|
550
|
+
continue;
|
|
370
551
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
// Write checkpoint after LLM phase (phases 1 and 2).
|
|
384
|
-
if (phase.name === "collect") {
|
|
385
|
-
writeInitProgress(cwd, 1);
|
|
386
|
-
}
|
|
387
|
-
else if (phase.name === "discover") {
|
|
388
|
-
writeInitProgress(cwd, 2);
|
|
552
|
+
const r = outcome.result;
|
|
553
|
+
const phaseEvent = buildInitPhaseEvent(step.run.phaseGroup, step.id, sprintId, outcome.startMs, outcome.endMs, r.model ?? "unknown", r.provider ?? "unknown", {
|
|
554
|
+
input: r.usage.input,
|
|
555
|
+
output: r.usage.output,
|
|
556
|
+
cacheRead: r.usage.cacheRead,
|
|
557
|
+
cacheWrite: r.usage.cacheWrite,
|
|
558
|
+
});
|
|
559
|
+
const emitResult = emitEvent(storeCli, cwd, sprintId, phaseEvent);
|
|
560
|
+
if (!emitResult.ok) {
|
|
561
|
+
ctx.ui.notify(`⚠ forge:init — phase event emit failed for ${step.id}: ${emitResult.stderr.trim()}`, "warning");
|
|
389
562
|
}
|
|
390
563
|
}
|
|
391
|
-
//
|
|
564
|
+
// Halt on the first failed step in this wave (declaration order).
|
|
565
|
+
const failedIdx = outcomes.findIndex((o) => !o.ok);
|
|
566
|
+
if (failedIdx >= 0) {
|
|
567
|
+
const failedStep = wave[failedIdx];
|
|
568
|
+
const failure = outcomes[failedIdx].reason ?? `step "${failedStep.id}" failed`;
|
|
569
|
+
ctx.ui.notify(`× forge:init — ${phaseName} step "${failedStep.id}" failed: ${failure}`, "error");
|
|
570
|
+
orchTranscript.record({
|
|
571
|
+
kind: "phase-end",
|
|
572
|
+
ts: new Date().toISOString(),
|
|
573
|
+
phase: phaseName,
|
|
574
|
+
phaseIndex: w,
|
|
575
|
+
attempt: 1,
|
|
576
|
+
verdict: "error",
|
|
577
|
+
elapsedMs: Date.now() - waveStartMs,
|
|
578
|
+
});
|
|
579
|
+
return makeFailResult({ ok: false, lastPhase: phaseNum, failure });
|
|
580
|
+
}
|
|
392
581
|
orchTranscript.record({
|
|
393
582
|
kind: "phase-end",
|
|
394
583
|
ts: new Date().toISOString(),
|
|
395
|
-
phase:
|
|
396
|
-
phaseIndex:
|
|
584
|
+
phase: phaseName,
|
|
585
|
+
phaseIndex: w,
|
|
397
586
|
attempt: 1,
|
|
398
587
|
verdict: "n/a",
|
|
399
|
-
elapsedMs: Date.now() -
|
|
588
|
+
elapsedMs: Date.now() - waveStartMs,
|
|
400
589
|
});
|
|
401
|
-
const elapsed = Math.floor((Date.now() -
|
|
402
|
-
ctx.ui.notify(`✓ init: ${
|
|
590
|
+
const elapsed = Math.floor((Date.now() - waveStartMs) / 1000);
|
|
591
|
+
ctx.ui.notify(`✓ init: ${phaseName} wave ${w + 1}/${waves.length} complete (${elapsed}s)`, "info");
|
|
403
592
|
lastPhase = phaseNum;
|
|
404
|
-
currentPhaseIndex++;
|
|
405
593
|
}
|
|
406
|
-
// ── All
|
|
407
|
-
const pipelineEndMs = Date.now();
|
|
594
|
+
// ── All waves complete — assemble InitReport ───────────────────────────────
|
|
408
595
|
orchTranscript.record({
|
|
409
596
|
kind: "pipeline-end",
|
|
410
597
|
ts: new Date().toISOString(),
|
|
411
598
|
outcome: "complete",
|
|
412
|
-
elapsedMs:
|
|
599
|
+
elapsedMs: Date.now() - pipelineStartMs,
|
|
413
600
|
});
|
|
414
|
-
const
|
|
415
|
-
|
|
601
|
+
const finalCache = state.configCache;
|
|
602
|
+
const stack = typeof finalCache.project?.stack === "string"
|
|
603
|
+
? finalCache.project.stack
|
|
416
604
|
: undefined;
|
|
417
|
-
const skillMatches = Array.isArray(
|
|
418
|
-
?
|
|
605
|
+
const skillMatches = Array.isArray(finalCache.installedSkills)
|
|
606
|
+
? finalCache.installedSkills
|
|
419
607
|
: undefined;
|
|
420
|
-
// If Phase 4 didn't run (resume at
|
|
608
|
+
// If Phase 4 didn't run (resume at phase 1–3), derive kbPathFinal from configCache.
|
|
609
|
+
let kbPathFinal = state.kbPathFinal;
|
|
421
610
|
if (!kbPathFinal) {
|
|
422
|
-
const p =
|
|
611
|
+
const p = finalCache.paths;
|
|
423
612
|
if (p && typeof p.engineering === "string" && p.engineering) {
|
|
424
613
|
kbPathFinal = p.engineering;
|
|
425
614
|
}
|