@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
|
@@ -89,14 +89,21 @@ Personas live in `.forge/personas/`.
|
|
|
89
89
|
|
|
90
90
|
Only include rows for workflow files that actually exist on disk. Check each:
|
|
91
91
|
|
|
92
|
+
Atomic workflows (LLM-generated markdown in `.forge/workflows/`):
|
|
93
|
+
|
|
92
94
|
- `.forge/workflows/plan_task.md` β "Research codebase β implementation plan"
|
|
93
95
|
- `.forge/workflows/implement_plan.md` β "Execute approved plan β code changes"
|
|
94
|
-
- `.forge/workflows/fix_bug.md` β "Triage β fix β verify"
|
|
95
|
-
- `.forge/workflows/orchestrate_task.md` β "Full task pipeline (plan β implement β review β commit)"
|
|
96
|
-
- `.forge/workflows/run_sprint.md` β "Full sprint orchestration"
|
|
97
96
|
- `.forge/workflows/architect_sprint_plan.md` β "Sprint planning and task decomposition"
|
|
98
97
|
- `.forge/workflows/architect_sprint_intake.md` β "Sprint intake and requirements elicitation"
|
|
99
98
|
|
|
99
|
+
Orchestration is deterministic JS, not prose. The LLM orchestration workflows
|
|
100
|
+
(`orchestrate_task` / `run_sprint` / `fix_bug`) are **retired** β link the JS
|
|
101
|
+
drivers in `.claude/workflows/` instead (only include rows where the file exists):
|
|
102
|
+
|
|
103
|
+
- `.claude/workflows/wfl-run-task.js` β "Full task pipeline (plan β implement β review β approve β commit)"
|
|
104
|
+
- `.claude/workflows/wfl-run-sprint.js` β "Full sprint orchestration"
|
|
105
|
+
- `.claude/workflows/wfl-fix-bug.js` β "Triage β fix β verify"
|
|
106
|
+
|
|
100
107
|
```markdown
|
|
101
108
|
<!-- forge-workflow-links: managed by Forge β do not edit manually -->
|
|
102
109
|
## Forge Workflows
|
|
@@ -105,13 +112,13 @@ Only include rows for workflow files that actually exist on disk. Check each:
|
|
|
105
112
|
|----------|---------|
|
|
106
113
|
| [Plan](.forge/workflows/plan_task.md) | Research codebase β implementation plan |
|
|
107
114
|
| [Implement](.forge/workflows/implement_plan.md) | Execute approved plan β code changes |
|
|
108
|
-
| [
|
|
109
|
-
| [Run
|
|
110
|
-
| [
|
|
115
|
+
| [Run task](.claude/workflows/wfl-run-task.js) | Full task pipeline (plan β implement β review β approve β commit) |
|
|
116
|
+
| [Run sprint](.claude/workflows/wfl-run-sprint.js) | Full sprint orchestration |
|
|
117
|
+
| [Fix bug](.claude/workflows/wfl-fix-bug.js) | Triage β fix β verify |
|
|
111
118
|
<!-- /forge-workflow-links -->
|
|
112
119
|
```
|
|
113
120
|
|
|
114
|
-
(Only include rows where the referenced
|
|
121
|
+
(Only include rows where the referenced file exists on disk.)
|
|
115
122
|
|
|
116
123
|
## KB Integrity Check
|
|
117
124
|
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// ββ ArtifactStore β backend-agnostic artifact provider βββββββββββββββββββββββ
|
|
4
|
+
//
|
|
5
|
+
// Mirrors the store.cjs `Store`/`FSImpl` pattern (ADR
|
|
6
|
+
// `doc/decisions/artifact-resolution-abstraction.md`, issue #111 Phase 3):
|
|
7
|
+
// a backend-agnostic facade delegating to a swappable, SYNCHRONOUS impl,
|
|
8
|
+
// default-wired to the filesystem, impl exported for substitution.
|
|
9
|
+
//
|
|
10
|
+
// class ArtifactStore { read|write|exists|url|list|delete(handle) β impl }
|
|
11
|
+
// class FsArtifactImpl { engineering/ files }
|
|
12
|
+
// module.exports = new ArtifactStore(new FsArtifactImpl())
|
|
13
|
+
// module.exports.FsArtifactImpl = FsArtifactImpl // swap for S3Impl / CmsImpl / DbBlobImpl
|
|
14
|
+
//
|
|
15
|
+
// A `handle` is the logical address (entityType, entityId, artifactKind) β never
|
|
16
|
+
// a path. The fs impl resolves it from the store record's `path` (the locator)
|
|
17
|
+
// plus the canonical kind registry, so callers never construct paths.
|
|
18
|
+
//
|
|
19
|
+
// SYNC CONSTRAINT (load-bearing): in-process callers (store-cli.cjs,
|
|
20
|
+
// preflight-gate.cjs, collate.cjs) invoke this without `await`, so every method
|
|
21
|
+
// is synchronous β same constraint that blocks the store's async InstantDbImpl
|
|
22
|
+
// (see doc/decisions/instantdb-store-backend.md). A future remote impl must
|
|
23
|
+
// either stay sync or be reached only through the forge-cli subprocess surface.
|
|
24
|
+
|
|
25
|
+
const fs = require('fs');
|
|
26
|
+
const path = require('path');
|
|
27
|
+
const { execFileSync } = require('child_process');
|
|
28
|
+
const { resolveArtifactFilename } = require('./lib/artifact-kinds.cjs');
|
|
29
|
+
|
|
30
|
+
// ββ Locator helpers ({ backend, ref }) βββββββββββββββββββββββββββββββββββββββ
|
|
31
|
+
|
|
32
|
+
// Derive the backend-agnostic locator from a store record. Prefers an explicit
|
|
33
|
+
// `record.locator`; otherwise treats the legacy `record.path` as an fs locator
|
|
34
|
+
// (the back-compat alias maintained during migration).
|
|
35
|
+
function toLocator(record) {
|
|
36
|
+
if (record && record.locator && record.locator.backend) return record.locator;
|
|
37
|
+
if (record && typeof record.path === 'string' && record.path.length > 0) {
|
|
38
|
+
return { backend: 'fs', ref: record.path };
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// For an fs locator ref, return the entity *directory* (strip a trailing filename).
|
|
44
|
+
function fsRefToDir(ref) {
|
|
45
|
+
const norm = String(ref).replace(/\\/g, '/').replace(/\/+$/, '');
|
|
46
|
+
return /\.[a-zA-Z0-9]+$/.test(norm) ? norm.replace(/\/[^/]*$/, '') : norm;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ββ Default dir resolution (store record path) βββββββββββββββββββββββββββββββ
|
|
50
|
+
// Reads a record's `path` via store-cli (out-of-process) so this module has no
|
|
51
|
+
// hard dependency on store internals. Returns the entity directory or null.
|
|
52
|
+
function readStorePath(entity, entityId, toolDir, projectRoot) {
|
|
53
|
+
const cliPath = path.join(toolDir, 'store-cli.cjs');
|
|
54
|
+
try {
|
|
55
|
+
const result = execFileSync('node', [cliPath, 'read', entity, entityId, '--json'], {
|
|
56
|
+
cwd: projectRoot, encoding: 'utf8', timeout: 10_000,
|
|
57
|
+
});
|
|
58
|
+
const record = JSON.parse(result);
|
|
59
|
+
const loc = toLocator(record);
|
|
60
|
+
if (loc && loc.backend === 'fs') return fsRefToDir(loc.ref);
|
|
61
|
+
} catch (_) { /* store unavailable / record not found β fall through */ }
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Resolve entity directory from the store record's path, falling back to
|
|
66
|
+
// ID-only construction. (Moved verbatim from artifact.cjs; re-exported there.)
|
|
67
|
+
function resolveEntityDir(entity, entityId, engineeringPath, toolDir, projectRoot) {
|
|
68
|
+
switch (entity) {
|
|
69
|
+
case 'bug': {
|
|
70
|
+
const storePath = readStorePath('bug', entityId, toolDir, projectRoot);
|
|
71
|
+
if (storePath) return storePath;
|
|
72
|
+
return path.join(engineeringPath, 'bugs', entityId);
|
|
73
|
+
}
|
|
74
|
+
case 'sprint': {
|
|
75
|
+
const storePath = readStorePath('sprint', entityId, toolDir, projectRoot);
|
|
76
|
+
if (storePath) return storePath;
|
|
77
|
+
return path.join(engineeringPath, 'sprints', entityId);
|
|
78
|
+
}
|
|
79
|
+
case 'task': {
|
|
80
|
+
const storePath = readStorePath('task', entityId, toolDir, projectRoot);
|
|
81
|
+
if (storePath) return storePath;
|
|
82
|
+
const match = entityId.match(/^(.+-S\d+)-T\d+$/);
|
|
83
|
+
if (!match) return null;
|
|
84
|
+
const sprintId = match[1];
|
|
85
|
+
const sprintPath = readStorePath('sprint', sprintId, toolDir, projectRoot);
|
|
86
|
+
if (sprintPath) return path.join(sprintPath, entityId);
|
|
87
|
+
return path.join(engineeringPath, 'sprints', sprintId, entityId);
|
|
88
|
+
}
|
|
89
|
+
default:
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ββ Facade βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
95
|
+
|
|
96
|
+
class ArtifactStore {
|
|
97
|
+
// The constructor impl is the default backend (`fs`). Additional backends are
|
|
98
|
+
// added with register(name, impl) β Phase 4. Each call routes to the impl for
|
|
99
|
+
// the handle's `backend` (default 'fs'), so adding a backend requires
|
|
100
|
+
// implementing the method surface only β no call-site or prompt changes.
|
|
101
|
+
constructor(impl) {
|
|
102
|
+
this.impl = impl; // default (fs) backend
|
|
103
|
+
this._backends = new Map([['fs', impl]]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Register an additional backend impl (e.g. an S3/CMS/DB provider). Returns
|
|
107
|
+
// `this` for chaining; re-registering the same name replaces the impl.
|
|
108
|
+
register(backend, impl) {
|
|
109
|
+
this._backends.set(backend, impl);
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
_implFor(handle) {
|
|
114
|
+
const backend = (handle && handle.backend) || 'fs';
|
|
115
|
+
const impl = this._backends.get(backend);
|
|
116
|
+
if (!impl) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`No ArtifactStore backend registered for "${backend}". ` +
|
|
119
|
+
`Registered: ${[...this._backends.keys()].join(', ')}. ` +
|
|
120
|
+
`Add one with artifactStore.register("${backend}", impl).`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return impl;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
read(handle) { return this._implFor(handle).read(handle); }
|
|
127
|
+
write(handle, content) { return this._implFor(handle).write(handle, content); }
|
|
128
|
+
exists(handle) { return this._implFor(handle).exists(handle); }
|
|
129
|
+
url(handle) { return this._implFor(handle).url(handle); }
|
|
130
|
+
list(handle) { return this._implFor(handle).list(handle); }
|
|
131
|
+
delete(handle) { return this._implFor(handle).delete(handle); }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ββ Filesystem impl βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
135
|
+
|
|
136
|
+
class FsArtifactImpl {
|
|
137
|
+
// opts: { projectRoot, engineeringPath, toolDir, resolveDir }
|
|
138
|
+
// resolveDir(entity, entityId) β dir (relative to projectRoot) | null.
|
|
139
|
+
// Injectable for testing; defaults to the store-record resolver above.
|
|
140
|
+
constructor(opts = {}) {
|
|
141
|
+
this.projectRoot = opts.projectRoot || process.cwd();
|
|
142
|
+
this.engineeringPath = opts.engineeringPath || 'engineering';
|
|
143
|
+
this.toolDir = opts.toolDir || __dirname;
|
|
144
|
+
this._resolveDir = opts.resolveDir
|
|
145
|
+
|| ((entity, entityId) => resolveEntityDir(entity, entityId, this.engineeringPath, this.toolDir, this.projectRoot));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
_absDir(handle) {
|
|
149
|
+
const dir = this._resolveDir(handle.entity, handle.entityId);
|
|
150
|
+
if (!dir) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`Cannot resolve ${handle.entity} directory for "${handle.entityId}". ` +
|
|
153
|
+
`Expected ID pattern: task=PREFIX-SNN-TNN, bug=PREFIX-BNN[-slug], sprint=PREFIX-SNN.`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return path.resolve(this.projectRoot, dir);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
_absFile(handle) {
|
|
160
|
+
return path.join(this._absDir(handle), resolveArtifactFilename(handle.entity, handle.kind));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
read(handle) {
|
|
164
|
+
const file = this._absFile(handle);
|
|
165
|
+
if (!fs.existsSync(file)) {
|
|
166
|
+
const err = new Error(`Artifact not found: ${path.relative(this.projectRoot, file)}`);
|
|
167
|
+
err.code = 'ENOENT';
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
return fs.readFileSync(file, 'utf8');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
write(handle, content) {
|
|
174
|
+
const dir = this._absDir(handle);
|
|
175
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
176
|
+
const file = path.join(dir, resolveArtifactFilename(handle.entity, handle.kind));
|
|
177
|
+
fs.writeFileSync(file, content, 'utf8');
|
|
178
|
+
return { bytes: Buffer.byteLength(content, 'utf8'), ref: path.relative(this.projectRoot, file) };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
exists(handle) {
|
|
182
|
+
try { return fs.existsSync(this._absFile(handle)); }
|
|
183
|
+
catch (_) { return false; }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
url(handle) {
|
|
187
|
+
return 'file://' + this._absFile(handle);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Entity-level listing: handle without `kind`. Returns existing filenames.
|
|
191
|
+
list(handle) {
|
|
192
|
+
const dir = this._absDir(handle);
|
|
193
|
+
if (!fs.existsSync(dir)) return [];
|
|
194
|
+
return fs.readdirSync(dir).filter((f) => f.endsWith('.md') || f.endsWith('.json'));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
delete(handle) {
|
|
198
|
+
const file = this._absFile(handle);
|
|
199
|
+
if (fs.existsSync(file)) { fs.unlinkSync(file); return true; }
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ββ Reference non-fs backend (Phase 4) βββββββββββββββββββββββββββββββββββββββ
|
|
205
|
+
//
|
|
206
|
+
// A complete, synchronous, in-memory implementation of the ArtifactStore method
|
|
207
|
+
// surface. It exists as the canonical *reference* for adding a backend: a real
|
|
208
|
+
// S3/CMS/DB provider implements these same six methods and is wired with
|
|
209
|
+
// `artifactStore.register('<backend>', new XxxArtifactImpl(...))` β no prompt or
|
|
210
|
+
// call-site changes. (A networked impl is sync-bound for in-process callers per
|
|
211
|
+
// the ADR; it is reachable async-internally only through the forge-cli
|
|
212
|
+
// subprocess surface. This in-memory impl is fully functional and dependency-free.)
|
|
213
|
+
class MemArtifactImpl {
|
|
214
|
+
constructor() { this.files = new Map(); }
|
|
215
|
+
_key(h) { return `${h.entity}/${h.entityId}/${resolveArtifactFilename(h.entity, h.kind)}`; }
|
|
216
|
+
read(handle) {
|
|
217
|
+
const k = this._key(handle);
|
|
218
|
+
if (!this.files.has(k)) { const e = new Error(`Artifact not found: mem:${k}`); e.code = 'ENOENT'; throw e; }
|
|
219
|
+
return this.files.get(k);
|
|
220
|
+
}
|
|
221
|
+
write(handle, content) {
|
|
222
|
+
const k = this._key(handle);
|
|
223
|
+
this.files.set(k, content);
|
|
224
|
+
return { bytes: Buffer.byteLength(content, 'utf8'), ref: `mem:${k}` };
|
|
225
|
+
}
|
|
226
|
+
exists(handle) { return this.files.has(this._key(handle)); }
|
|
227
|
+
url(handle) { return `mem://${this._key(handle)}`; }
|
|
228
|
+
list(handle) {
|
|
229
|
+
const prefix = `${handle.entity}/${handle.entityId}/`;
|
|
230
|
+
return [...this.files.keys()].filter((k) => k.startsWith(prefix)).map((k) => k.slice(prefix.length));
|
|
231
|
+
}
|
|
232
|
+
delete(handle) { return this.files.delete(this._key(handle)); }
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
module.exports = new ArtifactStore(new FsArtifactImpl());
|
|
236
|
+
module.exports.ArtifactStore = ArtifactStore;
|
|
237
|
+
module.exports.FsArtifactImpl = FsArtifactImpl;
|
|
238
|
+
module.exports.MemArtifactImpl = MemArtifactImpl;
|
|
239
|
+
module.exports.toLocator = toLocator;
|
|
240
|
+
module.exports.fsRefToDir = fsRefToDir;
|
|
241
|
+
module.exports.resolveEntityDir = resolveEntityDir;
|
|
242
|
+
module.exports.readStorePath = readStorePath;
|
|
@@ -14,59 +14,26 @@
|
|
|
14
14
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const path = require('path');
|
|
17
|
-
const { execFileSync } = require('child_process');
|
|
18
17
|
const { findProjectRoot } = require('./lib/project-root.cjs');
|
|
19
18
|
|
|
20
19
|
// ββ Artifact catalog βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
'review-plan-summary': { filename: 'REVIEW-PLAN-SUMMARY.json', type: 'json' },
|
|
39
|
-
'implementation-summary': { filename: 'IMPLEMENTATION-SUMMARY.json', type: 'json' },
|
|
40
|
-
'review-code-summary': { filename: 'REVIEW-CODE-SUMMARY.json', type: 'json' },
|
|
41
|
-
'review-impl-summary': { filename: 'REVIEW-IMPL-SUMMARY.json', type: 'json' },
|
|
42
|
-
'validation-summary': { filename: 'VALIDATION-SUMMARY.json', type: 'json' },
|
|
43
|
-
'approve-summary': { filename: 'APPROVE-SUMMARY.json', type: 'json' },
|
|
44
|
-
'commit-summary': { filename: 'COMMIT-SUMMARY.json', type: 'json' },
|
|
45
|
-
'triage-summary': { filename: 'TRIAGE-SUMMARY.json', type: 'json' },
|
|
46
|
-
'writeback-summary': { filename: 'WRITEBACK-SUMMARY.json', type: 'json' },
|
|
47
|
-
'collation-summary': { filename: 'COLLATION-SUMMARY.json', type: 'json' },
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// Per-entity filename overrides. Bug-mode plans and plan-summaries use the
|
|
51
|
-
// BUG_FIX_PLAN prefix to match the long-standing forge convention and the
|
|
52
|
-
// preflight-gate.cjs expectations for review-plan in bug mode. Without this
|
|
53
|
-
// override, plan-fix (routed via plan_task.md post FORGE-BUG-040) writes
|
|
54
|
-
// PLAN.md and review-plan preflight then fails "artifact missing:
|
|
55
|
-
// BUG_FIX_PLAN.md" β see FORGE-BUG-041.
|
|
56
|
-
const ARTIFACT_FILENAME_OVERRIDES = {
|
|
57
|
-
bug: {
|
|
58
|
-
'plan': 'BUG_FIX_PLAN.md',
|
|
59
|
-
'plan-summary': 'BUG-FIX-PLAN-SUMMARY.json',
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
function resolveArtifactFilename(entity, artifactName) {
|
|
64
|
-
const override = ARTIFACT_FILENAME_OVERRIDES[entity];
|
|
65
|
-
if (override && override[artifactName]) return override[artifactName];
|
|
66
|
-
return ARTIFACT_CATALOG[artifactName].filename;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const ARTIFACT_NAMES = Object.keys(ARTIFACT_CATALOG).sort();
|
|
20
|
+
//
|
|
21
|
+
// The catalog, bug-mode overrides, and filename resolution now live in the
|
|
22
|
+
// canonical registry at lib/artifact-kinds.cjs (ADR artifact-resolution Phase 1),
|
|
23
|
+
// consumed here and by store-cli.cjs so there is ONE source of truth.
|
|
24
|
+
const {
|
|
25
|
+
ARTIFACT_CATALOG,
|
|
26
|
+
ARTIFACT_FILENAME_OVERRIDES,
|
|
27
|
+
ARTIFACT_NAMES,
|
|
28
|
+
resolveArtifactFilename,
|
|
29
|
+
} = require('./lib/artifact-kinds.cjs');
|
|
30
|
+
|
|
31
|
+
// The provider seam (ArtifactStore/FsArtifactImpl) and entity-dir resolution
|
|
32
|
+
// live in artifact-store.cjs (ADR Phase 3). This CLI is a thin layer over the
|
|
33
|
+
// facade: it owns arg parsing, @-file expansion, JSON validation, and display;
|
|
34
|
+
// all filesystem access goes through the provider.
|
|
35
|
+
const artifactStore = require('./artifact-store.cjs');
|
|
36
|
+
const { ArtifactStore, FsArtifactImpl, resolveEntityDir } = artifactStore;
|
|
70
37
|
|
|
71
38
|
// ββ Summary JSON validation ββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
72
39
|
|
|
@@ -88,66 +55,6 @@ function validateSummaryJson(content) {
|
|
|
88
55
|
return null;
|
|
89
56
|
}
|
|
90
57
|
|
|
91
|
-
// ββ Entity path resolution βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
92
|
-
|
|
93
|
-
/** Read a store record via store-cli and return its `path` field, or null on failure. */
|
|
94
|
-
function readStorePath(entity, entityId, toolDir, projectRoot) {
|
|
95
|
-
const cliPath = path.join(toolDir, 'store-cli.cjs');
|
|
96
|
-
try {
|
|
97
|
-
const result = execFileSync('node', [cliPath, 'read', entity, entityId, '--json'], {
|
|
98
|
-
cwd: projectRoot,
|
|
99
|
-
encoding: 'utf8',
|
|
100
|
-
timeout: 10_000,
|
|
101
|
-
});
|
|
102
|
-
const record = JSON.parse(result);
|
|
103
|
-
if (typeof record.path === 'string' && record.path.length > 0) {
|
|
104
|
-
// Defensive: if the path ends with a file extension, the store record
|
|
105
|
-
// was written with a filename (e.g. "β¦/PROGRESS.md") instead of the
|
|
106
|
-
// directory. Strip the trailing filename to get the entity directory.
|
|
107
|
-
const p = record.path;
|
|
108
|
-
if (/\.(md|json)$/i.test(p)) return path.dirname(p);
|
|
109
|
-
return p;
|
|
110
|
-
}
|
|
111
|
-
} catch (_) {
|
|
112
|
-
// Store unavailable or record not found β fall through.
|
|
113
|
-
}
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Resolve entity directory using the store record's `path` field when available,
|
|
119
|
-
* falling back to ID-only construction.
|
|
120
|
-
*/
|
|
121
|
-
function resolveEntityDir(entity, entityId, engineeringPath, toolDir, projectRoot) {
|
|
122
|
-
switch (entity) {
|
|
123
|
-
case 'bug': {
|
|
124
|
-
const storePath = readStorePath('bug', entityId, toolDir, projectRoot);
|
|
125
|
-
if (storePath) return storePath;
|
|
126
|
-
return path.join(engineeringPath, 'bugs', entityId);
|
|
127
|
-
}
|
|
128
|
-
case 'sprint': {
|
|
129
|
-
const storePath = readStorePath('sprint', entityId, toolDir, projectRoot);
|
|
130
|
-
if (storePath) return storePath;
|
|
131
|
-
return path.join(engineeringPath, 'sprints', entityId);
|
|
132
|
-
}
|
|
133
|
-
case 'task': {
|
|
134
|
-
const storePath = readStorePath('task', entityId, toolDir, projectRoot);
|
|
135
|
-
if (storePath) return storePath;
|
|
136
|
-
// Fallback: derive from sprint prefix + sprint record path.
|
|
137
|
-
const match = entityId.match(/^(.+-S\d+)-T\d+$/);
|
|
138
|
-
if (!match) return null;
|
|
139
|
-
const sprintId = match[1];
|
|
140
|
-
const sprintPath = readStorePath('sprint', sprintId, toolDir, projectRoot);
|
|
141
|
-
if (sprintPath) {
|
|
142
|
-
return path.join(sprintPath, entityId);
|
|
143
|
-
}
|
|
144
|
-
return path.join(engineeringPath, 'sprints', sprintId, entityId);
|
|
145
|
-
}
|
|
146
|
-
default:
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
58
|
// ββ CLI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
152
59
|
|
|
153
60
|
if (require.main === module) {
|
|
@@ -163,6 +70,9 @@ if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h') {
|
|
|
163
70
|
' read <entity> <entityId> <artifact> Read artifact content',
|
|
164
71
|
' write <entity> <entityId> <artifact> <content|@file>',
|
|
165
72
|
' Write artifact (content or @/path/to/file)',
|
|
73
|
+
' exists <entity> <entityId> <artifact> Exit 0 if present, 2 if absent',
|
|
74
|
+
' url <entity> <entityId> <artifact> Print the backend URL (file:// for fs)',
|
|
75
|
+
' delete <entity> <entityId> <artifact> Delete an artifact',
|
|
166
76
|
'',
|
|
167
77
|
'Entities: task, bug, sprint',
|
|
168
78
|
`Known artifacts: ${ARTIFACT_NAMES.join(', ')}`,
|
|
@@ -211,6 +121,14 @@ if (!entityDir) {
|
|
|
211
121
|
|
|
212
122
|
const absDir = path.resolve(projectRoot, entityDir);
|
|
213
123
|
|
|
124
|
+
// Provider instance β all filesystem access for read/write/exists/url/delete
|
|
125
|
+
// goes through the facade (ADR Phase 3). Wired with the already-resolved dir so
|
|
126
|
+
// the CLI and the provider agree on location without a second store read.
|
|
127
|
+
const store = new ArtifactStore(new FsArtifactImpl({
|
|
128
|
+
projectRoot, engineeringPath, toolDir,
|
|
129
|
+
resolveDir: () => entityDir,
|
|
130
|
+
}));
|
|
131
|
+
|
|
214
132
|
// ββ list ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
215
133
|
|
|
216
134
|
if (subcmd === 'list') {
|
|
@@ -262,16 +180,41 @@ if (!catalogEntry) {
|
|
|
262
180
|
}
|
|
263
181
|
|
|
264
182
|
const resolvedFilename = resolveArtifactFilename(entity, artifactName);
|
|
265
|
-
const
|
|
183
|
+
const displayPath = path.join(entityDir, resolvedFilename);
|
|
184
|
+
const handle = { entity, entityId, kind: artifactName };
|
|
266
185
|
|
|
267
186
|
// ββ read βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
268
187
|
|
|
269
188
|
if (subcmd === 'read') {
|
|
270
|
-
if (!
|
|
271
|
-
process.stderr.write(`Artifact not found: ${
|
|
189
|
+
if (!store.exists(handle)) {
|
|
190
|
+
process.stderr.write(`Artifact not found: ${displayPath}\n`);
|
|
272
191
|
process.exit(2);
|
|
273
192
|
}
|
|
274
|
-
process.stdout.write(
|
|
193
|
+
process.stdout.write(store.read(handle));
|
|
194
|
+
process.exit(0);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ββ exists βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
198
|
+
|
|
199
|
+
if (subcmd === 'exists') {
|
|
200
|
+
// Boolean check: always exit 0 with a "true"/"false" token so callers
|
|
201
|
+
// (including the forge-cli subprocess surface) never treat absence as an error.
|
|
202
|
+
process.stdout.write(store.exists(handle) ? 'true\n' : 'false\n');
|
|
203
|
+
process.exit(0);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ββ url ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
207
|
+
|
|
208
|
+
if (subcmd === 'url') {
|
|
209
|
+
process.stdout.write(store.url(handle) + '\n');
|
|
210
|
+
process.exit(0);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ββ delete βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
214
|
+
|
|
215
|
+
if (subcmd === 'delete') {
|
|
216
|
+
const removed = store.delete(handle);
|
|
217
|
+
process.stdout.write(removed ? `Deleted ${displayPath}\n` : `Nothing to delete: ${displayPath}\n`);
|
|
275
218
|
process.exit(0);
|
|
276
219
|
}
|
|
277
220
|
|
|
@@ -308,15 +251,12 @@ if (subcmd === 'write') {
|
|
|
308
251
|
}
|
|
309
252
|
}
|
|
310
253
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
process.stdout.write(
|
|
314
|
-
`Wrote ${Buffer.byteLength(content, 'utf8')} bytes to ${path.join(entityDir, resolvedFilename)}\n`
|
|
315
|
-
);
|
|
254
|
+
const res = store.write(handle, content);
|
|
255
|
+
process.stdout.write(`Wrote ${res.bytes} bytes to ${displayPath}\n`);
|
|
316
256
|
process.exit(0);
|
|
317
257
|
}
|
|
318
258
|
|
|
319
|
-
process.stderr.write(`Unknown subcommand: ${subcmd}. Valid: list, read, write\n`);
|
|
259
|
+
process.stderr.write(`Unknown subcommand: ${subcmd}. Valid: list, read, write, exists, url, delete\n`);
|
|
320
260
|
process.exit(1);
|
|
321
261
|
|
|
322
262
|
} // end if (require.main === module)
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
// node banners.cjs --subtitle "Forging your SDLC"
|
|
33
33
|
// node banners.cjs --progress 5 12 "Templates"
|
|
34
34
|
// node banners.cjs --phase 7 12 "Workflows" ember
|
|
35
|
+
// node banners.cjs --badge forge --quiet (automated/orchestrator use: zero stdout)
|
|
35
36
|
|
|
36
37
|
// βββ Plain-mode detection βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
37
38
|
// Resolved at call-time so tests can flip env vars dynamically.
|
|
@@ -51,6 +52,12 @@ function stripAnsi(s) {
|
|
|
51
52
|
// Soft override β set by `--plain` CLI flag to force plain mode for one run.
|
|
52
53
|
let FORCE_PLAIN = false;
|
|
53
54
|
|
|
55
|
+
// Quiet mode β set by `--quiet` CLI flag to suppress all stdout output.
|
|
56
|
+
// Used by the orchestrator loop so banner output does not enter the LLM context
|
|
57
|
+
// window (output remains visible on a real TTY via the human's terminal but is
|
|
58
|
+
// not fed back as tool-call response text).
|
|
59
|
+
let QUIET_MODE = false;
|
|
60
|
+
|
|
54
61
|
// βββ ANSI helpers βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
55
62
|
const R = '\x1b[0m';
|
|
56
63
|
const B = '\x1b[1m';
|
|
@@ -376,6 +383,7 @@ function _maybePlain(s) {
|
|
|
376
383
|
|
|
377
384
|
// βββ CLI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
378
385
|
// node banners.cjs [<name>] [--gallery] [--badge <name>] [--mark <name>] [--list]
|
|
386
|
+
// node banners.cjs --badge <name> --quiet (suppress all stdout; orchestrator use)
|
|
379
387
|
|
|
380
388
|
if (require.main === module) {
|
|
381
389
|
let args = process.argv.slice(2);
|
|
@@ -387,38 +395,49 @@ if (require.main === module) {
|
|
|
387
395
|
args = args.slice(0, plainIdx).concat(args.slice(plainIdx + 1));
|
|
388
396
|
}
|
|
389
397
|
|
|
398
|
+
// --quiet may appear anywhere; consume it before dispatch.
|
|
399
|
+
// When set, all stdout is suppressed (exit 0 still guaranteed on success).
|
|
400
|
+
const quietIdx = args.indexOf('--quiet');
|
|
401
|
+
if (quietIdx !== -1) {
|
|
402
|
+
QUIET_MODE = true;
|
|
403
|
+
args = args.slice(0, quietIdx).concat(args.slice(quietIdx + 1));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Helper: write to stdout only when not in quiet mode.
|
|
407
|
+
const emit = (s) => { if (!QUIET_MODE) process.stdout.write(s); };
|
|
408
|
+
|
|
390
409
|
try {
|
|
391
410
|
if (!args.length || args[0] === '--gallery') {
|
|
392
|
-
|
|
411
|
+
emit(gallery() + '\n');
|
|
393
412
|
} else if (args[0] === '--list') {
|
|
394
|
-
|
|
413
|
+
emit(list().map(n => {
|
|
395
414
|
const b = BANNERS[n];
|
|
396
415
|
return `${b.emoji} ${n.padEnd(8)} β ${b.tagline}`;
|
|
397
|
-
}).join('\n'));
|
|
416
|
+
}).join('\n') + '\n');
|
|
398
417
|
} else if (args[0] === '--badge') {
|
|
399
|
-
|
|
418
|
+
emit(badge(args[1] || '') + '\n');
|
|
400
419
|
} else if (args[0] === '--mark') {
|
|
401
|
-
|
|
420
|
+
emit(mark(args[1] || '') + '\n');
|
|
402
421
|
} else if (args[0] === '--subtitle') {
|
|
403
|
-
|
|
422
|
+
emit(subtitle(args.slice(1).join(' ')) + '\n');
|
|
404
423
|
} else if (args[0] === '--progress') {
|
|
405
424
|
const n = Number(args[1]);
|
|
406
425
|
const total = Number(args[2]);
|
|
407
426
|
const label = args.slice(3).join(' ') || undefined;
|
|
408
|
-
|
|
427
|
+
emit(progressBar(n, total, { label }) + '\n');
|
|
409
428
|
} else if (args[0] === '--phase') {
|
|
410
429
|
const n = Number(args[1]);
|
|
411
430
|
const total = Number(args[2]);
|
|
412
431
|
const name = args[3] || '';
|
|
413
432
|
const bannerKey = args[4] || 'forge';
|
|
414
433
|
const mode = args[5]; // optional 'fast' | 'full'
|
|
415
|
-
|
|
434
|
+
emit(phaseHeader(n, total, name, bannerKey, mode ? { mode } : undefined) + '\n');
|
|
416
435
|
} else if (args[0] === '--rule') {
|
|
417
436
|
// --rule [text] Zen-blue em-dash horizontal rule (with optional label)
|
|
418
437
|
const text = args.slice(1).join(' ') || undefined;
|
|
419
|
-
|
|
438
|
+
emit(ruleLine(text) + '\n');
|
|
420
439
|
} else {
|
|
421
|
-
|
|
440
|
+
emit(render(args[0]) + '\n');
|
|
422
441
|
}
|
|
423
442
|
} catch (e) {
|
|
424
443
|
console.error(e.message);
|