@entelligentsia/forgecli 1.0.25 → 1.0.36
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 +258 -0
- package/README.md +2 -0
- package/dist/CHANGELOG-forge-plugin.md +163 -0
- package/dist/bin/argv.d.ts +2 -2
- package/dist/bin/argv.js +25 -0
- package/dist/bin/argv.js.map +1 -1
- package/dist/bin/forge.js +12 -0
- package/dist/bin/forge.js.map +1 -1
- package/dist/bin/init.d.ts +23 -0
- package/dist/bin/init.js +123 -0
- package/dist/bin/init.js.map +1 -0
- package/dist/bin/uninstall.d.ts +20 -0
- package/dist/bin/uninstall.js +141 -0
- package/dist/bin/uninstall.js.map +1 -0
- package/dist/extensions/forgecli/add-pipeline.d.ts +19 -0
- package/dist/extensions/forgecli/add-pipeline.js +143 -0
- package/dist/extensions/forgecli/add-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/add-task.d.ts +20 -0
- package/dist/extensions/forgecli/add-task.js +154 -0
- package/dist/extensions/forgecli/add-task.js.map +1 -0
- package/dist/extensions/forgecli/approve.d.ts +22 -0
- package/dist/extensions/forgecli/approve.js +152 -0
- package/dist/extensions/forgecli/approve.js.map +1 -0
- package/dist/extensions/forgecli/banner.d.ts +10 -0
- package/dist/extensions/forgecli/banner.js +36 -0
- package/dist/extensions/forgecli/banner.js.map +1 -0
- package/dist/extensions/forgecli/calibrate.d.ts +64 -0
- package/dist/extensions/forgecli/calibrate.js +481 -0
- package/dist/extensions/forgecli/calibrate.js.map +1 -0
- package/dist/extensions/forgecli/claude-bootstrap/bootstrap.d.ts +40 -0
- package/dist/extensions/forgecli/claude-bootstrap/bootstrap.js +593 -0
- package/dist/extensions/forgecli/claude-bootstrap/bootstrap.js.map +1 -0
- package/dist/extensions/forgecli/claude-bootstrap/settings-merge.d.ts +46 -0
- package/dist/extensions/forgecli/claude-bootstrap/settings-merge.js +245 -0
- package/dist/extensions/forgecli/claude-bootstrap/settings-merge.js.map +1 -0
- package/dist/extensions/forgecli/claude-bootstrap/uninstall.d.ts +23 -0
- package/dist/extensions/forgecli/claude-bootstrap/uninstall.js +215 -0
- package/dist/extensions/forgecli/claude-bootstrap/uninstall.js.map +1 -0
- package/dist/extensions/forgecli/collate.d.ts +22 -0
- package/dist/extensions/forgecli/collate.js +134 -0
- package/dist/extensions/forgecli/collate.js.map +1 -0
- package/dist/extensions/forgecli/commit.d.ts +22 -0
- package/dist/extensions/forgecli/commit.js +152 -0
- package/dist/extensions/forgecli/commit.js.map +1 -0
- package/dist/extensions/forgecli/config-command.d.ts +8 -0
- package/dist/extensions/forgecli/config-command.js +67 -0
- package/dist/extensions/forgecli/config-command.js.map +1 -0
- package/dist/extensions/forgecli/config-layer.d.ts +53 -0
- package/dist/extensions/forgecli/config-layer.js +72 -0
- package/dist/extensions/forgecli/config-layer.js.map +1 -0
- package/dist/extensions/forgecli/config-writer.d.ts +16 -0
- package/dist/extensions/forgecli/config-writer.js +69 -0
- package/dist/extensions/forgecli/config-writer.js.map +1 -0
- package/dist/extensions/forgecli/dashboard/component.js +10 -7
- package/dist/extensions/forgecli/dashboard/component.js.map +1 -1
- package/dist/extensions/forgecli/enhance.d.ts +27 -0
- package/dist/extensions/forgecli/enhance.js +199 -0
- package/dist/extensions/forgecli/enhance.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.d.ts +85 -0
- package/dist/extensions/forgecli/fix-bug.js +1580 -0
- package/dist/extensions/forgecli/fix-bug.js.map +1 -0
- package/dist/extensions/forgecli/forge-header.d.ts +12 -0
- package/dist/extensions/forgecli/forge-header.js +114 -0
- package/dist/extensions/forgecli/forge-header.js.map +1 -0
- package/dist/extensions/forgecli/forge-init.d.ts +26 -0
- package/dist/extensions/forgecli/forge-init.js +514 -0
- package/dist/extensions/forgecli/forge-init.js.map +1 -0
- package/dist/extensions/forgecli/forge-root.d.ts +10 -0
- package/dist/extensions/forgecli/forge-root.js +62 -0
- package/dist/extensions/forgecli/forge-root.js.map +1 -0
- package/dist/extensions/forgecli/forge-update-command.d.ts +100 -0
- package/dist/extensions/forgecli/forge-update-command.js +435 -0
- package/dist/extensions/forgecli/forge-update-command.js.map +1 -0
- package/dist/extensions/forgecli/friction-emit.d.ts +99 -0
- package/dist/extensions/forgecli/friction-emit.js +245 -0
- package/dist/extensions/forgecli/friction-emit.js.map +1 -0
- package/dist/extensions/forgecli/implement.d.ts +22 -0
- package/dist/extensions/forgecli/implement.js +170 -0
- package/dist/extensions/forgecli/implement.js.map +1 -0
- package/dist/extensions/forgecli/init-context.d.ts +99 -0
- package/dist/extensions/forgecli/init-context.js +178 -0
- package/dist/extensions/forgecli/init-context.js.map +1 -0
- package/dist/extensions/forgecli/init-progress.d.ts +39 -0
- package/dist/extensions/forgecli/init-progress.js +117 -0
- package/dist/extensions/forgecli/init-progress.js.map +1 -0
- package/dist/extensions/forgecli/input-router.d.ts +33 -0
- package/dist/extensions/forgecli/input-router.js +136 -0
- package/dist/extensions/forgecli/input-router.js.map +1 -0
- package/dist/extensions/forgecli/lib/halt-advisor.d.ts +59 -0
- package/dist/extensions/forgecli/lib/halt-advisor.js +113 -0
- package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -0
- package/dist/extensions/forgecli/lib/orchestrator-preflight.d.ts +46 -0
- package/dist/extensions/forgecli/lib/orchestrator-preflight.js +64 -0
- package/dist/extensions/forgecli/lib/orchestrator-preflight.js.map +1 -0
- package/dist/extensions/forgecli/materialize.d.ts +16 -0
- package/dist/extensions/forgecli/materialize.js +195 -0
- package/dist/extensions/forgecli/materialize.js.map +1 -0
- package/dist/extensions/forgecli/migrate.d.ts +22 -0
- package/dist/extensions/forgecli/migrate.js +260 -0
- package/dist/extensions/forgecli/migrate.js.map +1 -0
- package/dist/extensions/forgecli/migration-engine.d.ts +117 -0
- package/dist/extensions/forgecli/migration-engine.js +563 -0
- package/dist/extensions/forgecli/migration-engine.js.map +1 -0
- package/dist/extensions/forgecli/model-registry.d.ts +61 -0
- package/dist/extensions/forgecli/model-registry.js +127 -0
- package/dist/extensions/forgecli/model-registry.js.map +1 -0
- package/dist/extensions/forgecli/model-resolver.d.ts +32 -0
- package/dist/extensions/forgecli/model-resolver.js +65 -0
- package/dist/extensions/forgecli/model-resolver.js.map +1 -0
- package/dist/extensions/forgecli/model-validator.d.ts +29 -0
- package/dist/extensions/forgecli/model-validator.js +107 -0
- package/dist/extensions/forgecli/model-validator.js.map +1 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +26 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.js +213 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-body.d.ts +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-body.js +65 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-body.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-id.d.ts +23 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-id.js +140 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-id.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phase-dispatch.d.ts +54 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phase-dispatch.js +349 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phase-dispatch.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phases.d.ts +8 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phases.js +60 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phases.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-state.d.ts +14 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-state.js +100 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-state.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-triage-routing.d.ts +72 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-triage-routing.js +204 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-triage-routing.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict-loop.d.ts +38 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict-loop.js +166 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict-loop.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict.d.ts +3 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict.js +55 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-command.d.ts +7 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-command.js +293 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-command.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-pipeline.d.ts +2 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-pipeline.js +501 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-types.d.ts +41 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-types.js +5 -0
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-types.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-entry.d.ts +43 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-entry.js +85 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-entry.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-misc.d.ts +8 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-misc.js +37 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-misc.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-notify.d.ts +28 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-notify.js +45 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-notify.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-transcript-session.d.ts +26 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-transcript-session.js +75 -0
- package/dist/extensions/forgecli/orchestrators/common/orchestrator-transcript-session.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/common/summary-recovery.d.ts +24 -0
- package/dist/extensions/forgecli/orchestrators/common/summary-recovery.js +37 -0
- package/dist/extensions/forgecli/orchestrators/common/summary-recovery.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/fix-bug.d.ts +9 -93
- package/dist/extensions/forgecli/orchestrators/fix-bug.js +23 -1721
- package/dist/extensions/forgecli/orchestrators/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/run-sprint.d.ts +3 -12
- package/dist/extensions/forgecli/orchestrators/run-sprint.js +48 -270
- package/dist/extensions/forgecli/orchestrators/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/run-task.d.ts +10 -214
- package/dist/extensions/forgecli/orchestrators/run-task.js +31 -1481
- package/dist/extensions/forgecli/orchestrators/run-task.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/sprint/sprint-ceremony.d.ts +33 -0
- package/dist/extensions/forgecli/orchestrators/sprint/sprint-ceremony.js +135 -0
- package/dist/extensions/forgecli/orchestrators/sprint/sprint-ceremony.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/sprint/sprint-state.d.ts +18 -0
- package/dist/extensions/forgecli/orchestrators/sprint/sprint-state.js +55 -0
- package/dist/extensions/forgecli/orchestrators/sprint/sprint-state.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-command.d.ts +9 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-command.js +174 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-command.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-pipeline.d.ts +2 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-pipeline.js +494 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-types.d.ts +62 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-types.js +5 -0
- package/dist/extensions/forgecli/orchestrators/task/run-task-types.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-body.d.ts +4 -0
- package/dist/extensions/forgecli/orchestrators/task/task-body.js +48 -0
- package/dist/extensions/forgecli/orchestrators/task/task-body.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-events.d.ts +63 -0
- package/dist/extensions/forgecli/orchestrators/task/task-events.js +185 -0
- package/dist/extensions/forgecli/orchestrators/task/task-events.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-gates.d.ts +34 -0
- package/dist/extensions/forgecli/orchestrators/task/task-gates.js +78 -0
- package/dist/extensions/forgecli/orchestrators/task/task-gates.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phase-dispatch.d.ts +42 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phase-dispatch.js +370 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phase-dispatch.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phases.d.ts +14 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phases.js +26 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phases.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-record.d.ts +9 -0
- package/dist/extensions/forgecli/orchestrators/task/task-record.js +58 -0
- package/dist/extensions/forgecli/orchestrators/task/task-record.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-state.d.ts +14 -0
- package/dist/extensions/forgecli/orchestrators/task/task-state.js +35 -0
- package/dist/extensions/forgecli/orchestrators/task/task-state.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/task/task-verdict-loop.d.ts +36 -0
- package/dist/extensions/forgecli/orchestrators/task/task-verdict-loop.js +152 -0
- package/dist/extensions/forgecli/orchestrators/task/task-verdict-loop.js.map +1 -0
- package/dist/extensions/forgecli/plan.d.ts +22 -0
- package/dist/extensions/forgecli/plan.js +167 -0
- package/dist/extensions/forgecli/plan.js.map +1 -0
- package/dist/extensions/forgecli/quiz-agent.d.ts +17 -0
- package/dist/extensions/forgecli/quiz-agent.js +98 -0
- package/dist/extensions/forgecli/quiz-agent.js.map +1 -0
- package/dist/extensions/forgecli/read-command.d.ts +2 -0
- package/dist/extensions/forgecli/read-command.js +100 -0
- package/dist/extensions/forgecli/read-command.js.map +1 -0
- package/dist/extensions/forgecli/regenerate.d.ts +40 -0
- package/dist/extensions/forgecli/regenerate.js +438 -0
- package/dist/extensions/forgecli/regenerate.js.map +1 -0
- package/dist/extensions/forgecli/remove-command.d.ts +17 -0
- package/dist/extensions/forgecli/remove-command.js +124 -0
- package/dist/extensions/forgecli/remove-command.js.map +1 -0
- package/dist/extensions/forgecli/report-bug.d.ts +25 -0
- package/dist/extensions/forgecli/report-bug.js +159 -0
- package/dist/extensions/forgecli/report-bug.js.map +1 -0
- package/dist/extensions/forgecli/retrospective.d.ts +20 -0
- package/dist/extensions/forgecli/retrospective.js +126 -0
- package/dist/extensions/forgecli/retrospective.js.map +1 -0
- package/dist/extensions/forgecli/review-code.d.ts +35 -0
- package/dist/extensions/forgecli/review-code.js +196 -0
- package/dist/extensions/forgecli/review-code.js.map +1 -0
- package/dist/extensions/forgecli/review-plan.d.ts +35 -0
- package/dist/extensions/forgecli/review-plan.js +200 -0
- package/dist/extensions/forgecli/review-plan.js.map +1 -0
- package/dist/extensions/forgecli/run-sprint.d.ts +27 -0
- package/dist/extensions/forgecli/run-sprint.js +716 -0
- package/dist/extensions/forgecli/run-sprint.js.map +1 -0
- package/dist/extensions/forgecli/run-task.d.ts +204 -0
- package/dist/extensions/forgecli/run-task.js +1403 -0
- package/dist/extensions/forgecli/run-task.js.map +1 -0
- package/dist/extensions/forgecli/skill-curation-flag.d.ts +21 -0
- package/dist/extensions/forgecli/skill-curation-flag.js +71 -0
- package/dist/extensions/forgecli/skill-curation-flag.js.map +1 -0
- package/dist/extensions/forgecli/skill-curator-subagent.d.ts +102 -0
- package/dist/extensions/forgecli/skill-curator-subagent.js +339 -0
- package/dist/extensions/forgecli/skill-curator-subagent.js.map +1 -0
- package/dist/extensions/forgecli/skill-retriever.d.ts +84 -0
- package/dist/extensions/forgecli/skill-retriever.js +246 -0
- package/dist/extensions/forgecli/skill-retriever.js.map +1 -0
- package/dist/extensions/forgecli/skill-usage-tracker.d.ts +91 -0
- package/dist/extensions/forgecli/skill-usage-tracker.js +224 -0
- package/dist/extensions/forgecli/skill-usage-tracker.js.map +1 -0
- package/dist/extensions/forgecli/sprint-intake.d.ts +10 -0
- package/dist/extensions/forgecli/sprint-intake.js +91 -0
- package/dist/extensions/forgecli/sprint-intake.js.map +1 -0
- package/dist/extensions/forgecli/sprint-plan.d.ts +14 -0
- package/dist/extensions/forgecli/sprint-plan.js +122 -0
- package/dist/extensions/forgecli/sprint-plan.js.map +1 -0
- package/dist/extensions/forgecli/status-command.d.ts +19 -0
- package/dist/extensions/forgecli/status-command.js +140 -0
- package/dist/extensions/forgecli/status-command.js.map +1 -0
- package/dist/extensions/forgecli/store-error-remediation.d.ts +65 -0
- package/dist/extensions/forgecli/store-error-remediation.js +307 -0
- package/dist/extensions/forgecli/store-error-remediation.js.map +1 -0
- package/dist/extensions/forgecli/store-query.d.ts +22 -0
- package/dist/extensions/forgecli/store-query.js +107 -0
- package/dist/extensions/forgecli/store-query.js.map +1 -0
- package/dist/extensions/forgecli/store-repair.d.ts +17 -0
- package/dist/extensions/forgecli/store-repair.js +123 -0
- package/dist/extensions/forgecli/store-repair.js.map +1 -0
- package/dist/extensions/forgecli/store-resolver.d.ts +56 -0
- package/dist/extensions/forgecli/store-resolver.js +263 -0
- package/dist/extensions/forgecli/store-resolver.js.map +1 -0
- package/dist/extensions/forgecli/store-validator.d.ts +16 -0
- package/dist/extensions/forgecli/store-validator.js +32 -0
- package/dist/extensions/forgecli/store-validator.js.map +1 -0
- package/dist/extensions/forgecli/test-orchestrate.d.ts +2 -0
- package/dist/extensions/forgecli/test-orchestrate.js +182 -0
- package/dist/extensions/forgecli/test-orchestrate.js.map +1 -0
- package/dist/extensions/forgecli/thread-switcher.d.ts +5 -0
- package/dist/extensions/forgecli/thread-switcher.js +189 -0
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -0
- package/dist/extensions/forgecli/transition-guard.d.ts +20 -0
- package/dist/extensions/forgecli/transition-guard.js +89 -0
- package/dist/extensions/forgecli/transition-guard.js.map +1 -0
- package/dist/extensions/forgecli/update/forge-update-command.js +10 -7
- package/dist/extensions/forgecli/update/forge-update-command.js.map +1 -1
- package/dist/extensions/forgecli/update-check.d.ts +37 -0
- package/dist/extensions/forgecli/update-check.js +185 -0
- package/dist/extensions/forgecli/update-check.js.map +1 -0
- package/dist/extensions/forgecli/update-tools.d.ts +23 -0
- package/dist/extensions/forgecli/update-tools.js +135 -0
- package/dist/extensions/forgecli/update-tools.js.map +1 -0
- package/dist/extensions/forgecli/validate.d.ts +22 -0
- package/dist/extensions/forgecli/validate.js +152 -0
- package/dist/extensions/forgecli/validate.js.map +1 -0
- package/dist/extensions/forgecli/viewport-events.d.ts +78 -0
- package/dist/extensions/forgecli/viewport-events.js +243 -0
- package/dist/extensions/forgecli/viewport-events.js.map +1 -0
- package/dist/extensions/forgecli/viewport-renderer.d.ts +83 -0
- package/dist/extensions/forgecli/viewport-renderer.js +233 -0
- package/dist/extensions/forgecli/viewport-renderer.js.map +1 -0
- package/dist/extensions/forgecli/viewport-theme.d.ts +11 -0
- package/dist/extensions/forgecli/viewport-theme.js +128 -0
- package/dist/extensions/forgecli/viewport-theme.js.map +1 -0
- package/dist/extensions/forgecli/whats-new-widget.d.ts +26 -0
- package/dist/extensions/forgecli/whats-new-widget.js +376 -0
- package/dist/extensions/forgecli/whats-new-widget.js.map +1 -0
- package/dist/extensions/forgecli/whats-new.d.ts +120 -0
- package/dist/extensions/forgecli/whats-new.js +470 -0
- package/dist/extensions/forgecli/whats-new.js.map +1 -0
- package/dist/forge-payload/.base-pack/commands/approve.md +2 -2
- package/dist/forge-payload/.base-pack/commands/check-agent.md +2 -2
- package/dist/forge-payload/.base-pack/commands/collate.md +2 -2
- package/dist/forge-payload/.base-pack/commands/commit.md +2 -2
- package/dist/forge-payload/.base-pack/commands/enhance.md +2 -2
- package/dist/forge-payload/.base-pack/commands/fix-bug.md +2 -2
- package/dist/forge-payload/.base-pack/commands/implement.md +2 -2
- package/dist/forge-payload/.base-pack/commands/init.md +278 -0
- package/dist/forge-payload/.base-pack/commands/new-sprint.md +2 -2
- package/dist/forge-payload/.base-pack/commands/plan-sprint.md +2 -2
- package/dist/forge-payload/.base-pack/commands/plan.md +2 -2
- package/dist/forge-payload/.base-pack/commands/retro.md +2 -2
- package/dist/forge-payload/.base-pack/commands/review-code.md +2 -2
- package/dist/forge-payload/.base-pack/commands/review-plan.md +2 -2
- package/dist/forge-payload/.base-pack/commands/run-sprint.md +2 -2
- package/dist/forge-payload/.base-pack/commands/run-task.md +2 -2
- package/dist/forge-payload/.base-pack/commands/validate.md +2 -2
- package/dist/forge-payload/.base-pack/workflows/collator_agent.md +5 -6
- package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +1 -1
- package/dist/forge-payload/.base-pack/workflows-js/wfl-init.js +449 -0
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/.schemas/migrations.json +85 -0
- package/dist/forge-payload/commands/add-pipeline.md +1 -1
- package/dist/forge-payload/commands/add-task.md +3 -3
- package/dist/forge-payload/commands/ask.md +1 -1
- package/dist/forge-payload/commands/check-agent.md +1 -1
- package/dist/forge-payload/commands/config.md +1 -1
- package/dist/forge-payload/commands/health.md +1 -1
- package/dist/forge-payload/commands/init.md +62 -7
- package/dist/forge-payload/commands/rebuild.md +3 -3
- package/dist/forge-payload/commands/remove.md +1 -1
- package/dist/forge-payload/commands/repair.md +1 -1
- package/dist/forge-payload/commands/report-bug.md +1 -1
- package/dist/forge-payload/commands/status.md +1 -1
- package/dist/forge-payload/commands/update.md +3 -3
- package/dist/forge-payload/hooks/lib/common.cjs +228 -0
- package/dist/forge-payload/hooks/lib/plugin-detection.cjs +106 -0
- package/dist/forge-payload/hooks/lib/update-msg.cjs +23 -0
- package/dist/forge-payload/hooks/lib/update-url.cjs +46 -0
- package/dist/forge-payload/hooks/lib/write-registry.js +53 -0
- package/dist/forge-payload/init/discovery/discover-database.md +32 -0
- package/dist/forge-payload/init/discovery/discover-processes.md +31 -0
- package/dist/forge-payload/init/discovery/discover-routing.md +31 -0
- package/dist/forge-payload/init/discovery/discover-stack.md +33 -0
- package/dist/forge-payload/init/discovery/discover-testing.md +34 -0
- package/dist/forge-payload/init/generation/generate-commands.md +171 -0
- package/dist/forge-payload/init/generation/generate-kb-doc.md +60 -0
- package/dist/forge-payload/init/generation/generate-knowledge-base.md +56 -0
- package/dist/forge-payload/init/generation/generate-persona.md +73 -0
- package/dist/forge-payload/init/generation/generate-personas.md +54 -0
- package/dist/forge-payload/init/generation/generate-skill.md +66 -0
- package/dist/forge-payload/init/generation/generate-skills.md +36 -0
- package/dist/forge-payload/init/generation/generate-template.md +60 -0
- package/dist/forge-payload/init/generation/generate-templates.md +39 -0
- package/dist/forge-payload/init/generation/generate-tools.md +133 -0
- package/dist/forge-payload/init/generation/generate-workflows.md +78 -0
- package/dist/forge-payload/init/phases/phase-1-collect.md +10 -2
- package/dist/forge-payload/init/phases/phase-3-materialize.md +1 -1
- package/dist/forge-payload/init/phases/phase-4-register.md +8 -0
- package/dist/forge-payload/init/workflow-gen-plan.json +17 -0
- package/dist/forge-payload/integrity.json +16 -16
- package/dist/forge-payload/meta/workflows/meta-collate.md +5 -6
- package/dist/forge-payload/meta/workflows/meta-migrate.md +1 -1
- package/dist/forge-payload/schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/schemas/structure-manifest.json +3 -12
- package/dist/forge-payload/tools/forge-preflight.cjs +268 -0
- package/dist/forge-payload/tools/lib/paths.cjs +12 -11
- package/dist/forge-payload/tools/lib/pricing.cjs +31 -11
- package/dist/forge-payload/tools/query-logger.cjs +34 -0
- package/dist/forge-payload/tools/substitute-placeholders.cjs +5 -6
- package/node_modules/@mariozechner/clipboard/package.json +1 -2
- package/package.json +2 -2
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/README.md +0 -3
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/package.json +0 -25
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// forge:collate — native kickoff handler (FORGE-S21-T10).
|
|
2
|
+
//
|
|
3
|
+
// Replaces the auto-generated stub previously installed by
|
|
4
|
+
// registerAllForgeCommands (forge-commands.ts). Kickoff Shim archetype
|
|
5
|
+
// (Pack-04 + Pack-06): single LLM handoff in current context, no fork.
|
|
6
|
+
//
|
|
7
|
+
// The collator_agent.md workflow has no audience restriction (defaults to
|
|
8
|
+
// "any"), so standalone human invocations are allowed — useful for retro
|
|
9
|
+
// runs and manual collation triggers.
|
|
10
|
+
//
|
|
11
|
+
// Iron Laws:
|
|
12
|
+
// IL1 — code only under forge-cli/src/extensions/forgecli/.
|
|
13
|
+
// IL4 — no JSON.stringify-into-subagent dispatch.
|
|
14
|
+
// IL6 — no shell-string interpolation; no spawn calls here.
|
|
15
|
+
// IL7 — every failure path emits ctx.ui.notify and returns; no silent
|
|
16
|
+
// continuation.
|
|
17
|
+
import * as fs from "node:fs";
|
|
18
|
+
import * as path from "node:path";
|
|
19
|
+
import { assertAudience } from "./audience-gate.js";
|
|
20
|
+
import { sendKickoff } from "./kickoff.js";
|
|
21
|
+
// FORGE-S25-T16: extracted to lib modules (H-1, H-2). Re-exported here for
|
|
22
|
+
// backward compatibility with existing test and consumer imports.
|
|
23
|
+
import { extractPersonaNames } from "./lib/frontmatter-parser.js";
|
|
24
|
+
import { loadPersona, PersonaSkillLoaderError } from "./parsers/persona-skill-loader.js";
|
|
25
|
+
import { loadWorkflow, WorkflowLoaderError } from "./parsers/workflow-loader.js";
|
|
26
|
+
export { extractPersonaNames };
|
|
27
|
+
import { checkMaterialization } from "./lib/manifest-checker.js";
|
|
28
|
+
export { checkMaterialization };
|
|
29
|
+
export function parseCollateArgs(rawArgs, cwd) {
|
|
30
|
+
const trimmed = (rawArgs ?? "").trim();
|
|
31
|
+
if (trimmed === "") {
|
|
32
|
+
return { mode: "empty", taskRef: "", sourceLabel: "(no input — collator infers sprint from store/context)" };
|
|
33
|
+
}
|
|
34
|
+
if (trimmed.startsWith("@")) {
|
|
35
|
+
const ref = trimmed.slice(1).trim();
|
|
36
|
+
const filePath = path.isAbsolute(ref) ? ref : path.resolve(cwd, ref);
|
|
37
|
+
const seed = fs.readFileSync(filePath, "utf8");
|
|
38
|
+
return { mode: "file", taskRef: seed, sourceLabel: `(seed from file: ${ref})` };
|
|
39
|
+
}
|
|
40
|
+
return { mode: "text", taskRef: trimmed, sourceLabel: "(seed from inline text)" };
|
|
41
|
+
}
|
|
42
|
+
export function composeKickoff(opts) {
|
|
43
|
+
const { workflowMd, personaIdentity, parsed } = opts;
|
|
44
|
+
const sections = ["# /forge:collate", ""];
|
|
45
|
+
if (personaIdentity.trim().length > 0) {
|
|
46
|
+
sections.push(personaIdentity.trim(), "");
|
|
47
|
+
}
|
|
48
|
+
sections.push("## Dispatch", "", "Run the workflow below. Specifically:", "", "1. Identify the active sprint via `forge_store_query` — do NOT raw-read `.forge/store/`.", "2. Follow the workflow Algorithm verbatim: collate store data into MASTER_INDEX.md, sprint INDEX.md, task INDEX.md files.", "3. Write all collated markdown files using the `write` tool.", "4. Honour Pack-06 Read/Write/Ask/Store discipline: store reads go via `forge_store_query`; in-conversation clarifications use `forge_ask_user`.");
|
|
49
|
+
sections.push("", "---", "", "## Workflow", "", workflowMd.trim(), "", "---");
|
|
50
|
+
if (parsed.mode === "empty") {
|
|
51
|
+
sections.push("", "## Input", "", "(no seed — infer sprint from store context)");
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
sections.push("", `## Input — ${parsed.sourceLabel}`, "", parsed.taskRef.trim());
|
|
55
|
+
}
|
|
56
|
+
return sections.join("\n");
|
|
57
|
+
}
|
|
58
|
+
// Registration -------------------------------------------------------------
|
|
59
|
+
const WORKFLOW_REL_PATH = path.join(".forge", "workflows", "collator_agent.md");
|
|
60
|
+
export function registerCollate(pi, options = {}) {
|
|
61
|
+
pi.registerCommand("forge:collate", {
|
|
62
|
+
description: "Run the collator-agent workflow. " +
|
|
63
|
+
"Usage: /forge:collate [@<file> | <sprint-id> | <free-form text>]. " +
|
|
64
|
+
"Empty args → collator infers the active sprint from store context.",
|
|
65
|
+
async handler(args, ctx) {
|
|
66
|
+
const cwd = options.cwd ?? process.cwd();
|
|
67
|
+
const workflowPath = path.join(cwd, WORKFLOW_REL_PATH);
|
|
68
|
+
let workflowMd;
|
|
69
|
+
let workflowAudience;
|
|
70
|
+
try {
|
|
71
|
+
const loaded = loadWorkflow(workflowPath);
|
|
72
|
+
workflowMd = loaded.rawMarkdown;
|
|
73
|
+
workflowAudience = loaded.audience;
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
if (err instanceof WorkflowLoaderError) {
|
|
77
|
+
if (err.code === "missing_file") {
|
|
78
|
+
ctx.ui.notify(`× forge:collate — workflow not found at ${WORKFLOW_REL_PATH}; run /forge:init or /forge:rebuild first.`, "error");
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
ctx.ui.notify(`× forge:collate — workflow load failed (${err.code}): ${err.message}`, "error");
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const e = err;
|
|
86
|
+
ctx.ui.notify(`× forge:collate — failed to read workflow: ${e.message ?? "unknown"}`, "error");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let parsed;
|
|
90
|
+
try {
|
|
91
|
+
parsed = parseCollateArgs(args, cwd);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
const e = err;
|
|
95
|
+
ctx.ui.notify(`× forge:collate — failed to read seed: ${e.message ?? "unknown"}`, "error");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const check = checkMaterialization(workflowPath, workflowMd);
|
|
99
|
+
if (!check.ok) {
|
|
100
|
+
for (const marker of check.missing) {
|
|
101
|
+
ctx.ui.notify(`× workflow regression: ${marker} not found in ${workflowPath}`, "error");
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const personas = extractPersonaNames(workflowMd);
|
|
106
|
+
let personaIdentity = "";
|
|
107
|
+
if (personas.length > 0) {
|
|
108
|
+
try {
|
|
109
|
+
const persona = loadPersona(personas[0], { cwd });
|
|
110
|
+
personaIdentity = persona.identity;
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
if (err instanceof PersonaSkillLoaderError) {
|
|
114
|
+
ctx.ui.notify(`× forge:collate — persona '${personas[0]}' load failed (${err.code}): ${err.message}`, "error");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const e = err;
|
|
118
|
+
ctx.ui.notify(`× forge:collate — persona load error: ${e.message ?? "unknown"}`, "error");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (!assertAudience({ workflowName: "collator_agent", audience: workflowAudience }, ctx)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const kickoff = composeKickoff({
|
|
126
|
+
workflowMd,
|
|
127
|
+
personaIdentity,
|
|
128
|
+
parsed,
|
|
129
|
+
});
|
|
130
|
+
sendKickoff(pi, kickoff);
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=collate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collate.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/collate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { extractPersonaNames } from "./lib/frontmatter-parser.js";
|
|
3
|
+
export { extractPersonaNames };
|
|
4
|
+
import { checkMaterialization, type MaterializationCheck } from "./lib/manifest-checker.js";
|
|
5
|
+
export { checkMaterialization, type MaterializationCheck };
|
|
6
|
+
export type ArgMode = "empty" | "file" | "text";
|
|
7
|
+
export interface ParsedArgs {
|
|
8
|
+
mode: ArgMode;
|
|
9
|
+
taskRef: string;
|
|
10
|
+
sourceLabel: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function parseCommitArgs(rawArgs: string, cwd: string): ParsedArgs;
|
|
13
|
+
export interface ComposeKickoffOpts {
|
|
14
|
+
workflowMd: string;
|
|
15
|
+
personaIdentity: string;
|
|
16
|
+
parsed: ParsedArgs;
|
|
17
|
+
}
|
|
18
|
+
export declare function composeKickoff(opts: ComposeKickoffOpts): string;
|
|
19
|
+
export interface RegisterCommitOptions {
|
|
20
|
+
cwd?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function registerCommit(pi: ExtensionAPI, options?: RegisterCommitOptions): void;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// forge:commit — native kickoff handler (FORGE-S21-T10).
|
|
2
|
+
//
|
|
3
|
+
// Replaces the auto-generated stub previously installed by
|
|
4
|
+
// registerAllForgeCommands (forge-commands.ts). Kickoff Shim archetype
|
|
5
|
+
// (Pack-04 + Pack-06): single LLM handoff in current context, no fork.
|
|
6
|
+
//
|
|
7
|
+
// Note: The materialized workflow (commit_task.md) declares
|
|
8
|
+
// `audience: subagent` — advisory only. Users may invoke this command
|
|
9
|
+
// manually from the CLI; assertAudience never refuses subagent-audience
|
|
10
|
+
// workflows. Orchestrator chains still dispatch via runForgeSubagent
|
|
11
|
+
// directly and do NOT route through this handler.
|
|
12
|
+
//
|
|
13
|
+
// Iron Laws:
|
|
14
|
+
// IL1 — code only under forge-cli/src/extensions/forgecli/.
|
|
15
|
+
// IL4 — no JSON.stringify-into-subagent dispatch.
|
|
16
|
+
// IL6 — no shell-string interpolation; no spawn calls here.
|
|
17
|
+
// IL7 — every failure path emits ctx.ui.notify and returns; no silent
|
|
18
|
+
// continuation.
|
|
19
|
+
import * as fs from "node:fs";
|
|
20
|
+
import * as path from "node:path";
|
|
21
|
+
import { assertAudience } from "./audience-gate.js";
|
|
22
|
+
import { discoverForgeConfig } from "./forge-root.js";
|
|
23
|
+
import { sendKickoff } from "./kickoff.js";
|
|
24
|
+
// FORGE-S25-T16: extracted to lib modules (H-1, H-2). Re-exported here for
|
|
25
|
+
// backward compatibility with existing test and consumer imports.
|
|
26
|
+
import { extractPersonaNames } from "./lib/frontmatter-parser.js";
|
|
27
|
+
import { parseGuardArgs, runPipelineGuard } from "./lib/pipeline-guard.js";
|
|
28
|
+
import { loadPersona, PersonaSkillLoaderError } from "./parsers/persona-skill-loader.js";
|
|
29
|
+
import { loadWorkflow, WorkflowLoaderError } from "./parsers/workflow-loader.js";
|
|
30
|
+
export { extractPersonaNames };
|
|
31
|
+
import { checkMaterialization } from "./lib/manifest-checker.js";
|
|
32
|
+
export { checkMaterialization };
|
|
33
|
+
export function parseCommitArgs(rawArgs, cwd) {
|
|
34
|
+
const trimmed = (rawArgs ?? "").trim();
|
|
35
|
+
if (trimmed === "") {
|
|
36
|
+
return { mode: "empty", taskRef: "", sourceLabel: "(no input — engineer infers task from store/context)" };
|
|
37
|
+
}
|
|
38
|
+
if (trimmed.startsWith("@")) {
|
|
39
|
+
const ref = trimmed.slice(1).trim();
|
|
40
|
+
const filePath = path.isAbsolute(ref) ? ref : path.resolve(cwd, ref);
|
|
41
|
+
const seed = fs.readFileSync(filePath, "utf8");
|
|
42
|
+
return { mode: "file", taskRef: seed, sourceLabel: `(seed from file: ${ref})` };
|
|
43
|
+
}
|
|
44
|
+
return { mode: "text", taskRef: trimmed, sourceLabel: "(seed from inline text)" };
|
|
45
|
+
}
|
|
46
|
+
export function composeKickoff(opts) {
|
|
47
|
+
const { workflowMd, personaIdentity, parsed } = opts;
|
|
48
|
+
const sections = ["# /forge:commit", ""];
|
|
49
|
+
if (personaIdentity.trim().length > 0) {
|
|
50
|
+
sections.push(personaIdentity.trim(), "");
|
|
51
|
+
}
|
|
52
|
+
sections.push("## Dispatch", "", "Run the workflow below. Specifically:", "", "1. Read the task implementation at `engineering/sprints/<SPRINT_ID>/<TASK_ID>/PROGRESS.md` (the source of truth).", "2. Query the store for the task and its sprint/feature context via `forge_store_query` — do NOT raw-read `.forge/store/`.", "3. Follow the workflow Algorithm verbatim: stage changes, write commit message, finalize store status.", "4. Write `COMMIT-SUMMARY.json` to the task directory using the `write` tool.", "5. Update task status by calling the `forge_store` MCP tool: `{command:'update-status', args:['task','<TASK_ID>','status','committed']}`. Never raw-write `.forge/store/`. Do NOT bash-shell `forge store ...`.", "6. Honour Pack-06 Read/Write/Ask/Store discipline: writes go via the `forge_store` MCP tool; in-conversation clarifications use `forge_ask_user`.");
|
|
53
|
+
sections.push("", "---", "", "## Workflow", "", workflowMd.trim(), "", "---");
|
|
54
|
+
if (parsed.mode === "empty") {
|
|
55
|
+
sections.push("", "## Input", "", "(no seed — infer task from sprint context and store)");
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
sections.push("", `## Input — ${parsed.sourceLabel}`, "", parsed.taskRef.trim());
|
|
59
|
+
}
|
|
60
|
+
return sections.join("\n");
|
|
61
|
+
}
|
|
62
|
+
// Registration -------------------------------------------------------------
|
|
63
|
+
const WORKFLOW_REL_PATH = path.join(".forge", "workflows", "commit_task.md");
|
|
64
|
+
export function registerCommit(pi, options = {}) {
|
|
65
|
+
pi.registerCommand("forge:commit", {
|
|
66
|
+
description: "Run the commit-task workflow for a Forge task. " +
|
|
67
|
+
"Usage: /forge:commit [@<file> | <free-form text>]. " +
|
|
68
|
+
"Note: this workflow is subagent-only; standalone invocations are refused. " +
|
|
69
|
+
"Orchestrator chains dispatch directly via runForgeSubagent.",
|
|
70
|
+
async handler(args, ctx) {
|
|
71
|
+
const cwd = options.cwd ?? process.cwd();
|
|
72
|
+
const workflowPath = path.join(cwd, WORKFLOW_REL_PATH);
|
|
73
|
+
// Pipeline step guard (FORGE-S26-T11): check task state before dispatching.
|
|
74
|
+
const guardParsed = parseGuardArgs(args);
|
|
75
|
+
if (!guardParsed.force) {
|
|
76
|
+
const forgeConfig = discoverForgeConfig(cwd);
|
|
77
|
+
if (forgeConfig) {
|
|
78
|
+
const guard = runPipelineGuard("commit", guardParsed.taskIdHint, forgeConfig.forgeRoot, cwd);
|
|
79
|
+
if (guard.blocked) {
|
|
80
|
+
ctx.ui.notify(guard.message, "error");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const effectiveArgs = guardParsed.cleanArgs;
|
|
86
|
+
let workflowMd;
|
|
87
|
+
let workflowAudience;
|
|
88
|
+
try {
|
|
89
|
+
const loaded = loadWorkflow(workflowPath);
|
|
90
|
+
workflowMd = loaded.rawMarkdown;
|
|
91
|
+
workflowAudience = loaded.audience;
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
if (err instanceof WorkflowLoaderError) {
|
|
95
|
+
if (err.code === "missing_file") {
|
|
96
|
+
ctx.ui.notify(`× forge:commit — workflow not found at ${WORKFLOW_REL_PATH}; run /forge:init or /forge:rebuild first.`, "error");
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
ctx.ui.notify(`× forge:commit — workflow load failed (${err.code}): ${err.message}`, "error");
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const e = err;
|
|
104
|
+
ctx.ui.notify(`× forge:commit — failed to read workflow: ${e.message ?? "unknown"}`, "error");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
let parsed;
|
|
108
|
+
try {
|
|
109
|
+
parsed = parseCommitArgs(effectiveArgs, cwd);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
const e = err;
|
|
113
|
+
ctx.ui.notify(`× forge:commit — failed to read seed: ${e.message ?? "unknown"}`, "error");
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const check = checkMaterialization(workflowPath, workflowMd);
|
|
117
|
+
if (!check.ok) {
|
|
118
|
+
for (const marker of check.missing) {
|
|
119
|
+
ctx.ui.notify(`× workflow regression: ${marker} not found in ${workflowPath}`, "error");
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const personas = extractPersonaNames(workflowMd);
|
|
124
|
+
let personaIdentity = "";
|
|
125
|
+
if (personas.length > 0) {
|
|
126
|
+
try {
|
|
127
|
+
const persona = loadPersona(personas[0], { cwd });
|
|
128
|
+
personaIdentity = persona.identity;
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
if (err instanceof PersonaSkillLoaderError) {
|
|
132
|
+
ctx.ui.notify(`× forge:commit — persona '${personas[0]}' load failed (${err.code}): ${err.message}`, "error");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const e = err;
|
|
136
|
+
ctx.ui.notify(`× forge:commit — persona load error: ${e.message ?? "unknown"}`, "error");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!assertAudience({ workflowName: "commit_task", audience: workflowAudience }, ctx)) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const kickoff = composeKickoff({
|
|
144
|
+
workflowMd,
|
|
145
|
+
personaIdentity,
|
|
146
|
+
parsed,
|
|
147
|
+
});
|
|
148
|
+
sendKickoff(pi, kickoff);
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
export interface RegisterConfigCommandOptions {
|
|
3
|
+
/** When null, /forge:config is registered but only the routing-config bits
|
|
4
|
+
* are reachable — plugin-config display is hidden (no .forge to read).
|
|
5
|
+
*/
|
|
6
|
+
forgeRoot: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function registerConfigCommand(pi: ExtensionAPI, _opts: RegisterConfigCommandOptions): void;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Native /forge:config handler — replaces the LLM-backed delegateMarkdownCommand
|
|
2
|
+
// stub that previously lived in forge-commands.ts.
|
|
3
|
+
//
|
|
4
|
+
// Plan 16 Slice 4a + 4b. The handler delegates to runConfigTui which is the
|
|
5
|
+
// same entry point used by the `forge config` bin subcommand — single source
|
|
6
|
+
// of truth for the routing config TUI / show flow. The wrapper supplies a
|
|
7
|
+
// `mountConfigTui` callback that uses ctx.ui.custom() to overlay the TUI.
|
|
8
|
+
import { createConfigTuiComponent } from "./config-tui/component.js";
|
|
9
|
+
import { runConfigTui } from "./config-tui/handler.js";
|
|
10
|
+
import { getInputRouter } from "./input-router.js";
|
|
11
|
+
export function registerConfigCommand(pi, _opts) {
|
|
12
|
+
pi.registerCommand("forge:config", {
|
|
13
|
+
description: "Inspect or change forge-cli routing config (persona-models, pipeline overrides) and view Forge project config",
|
|
14
|
+
async handler(args, ctx) {
|
|
15
|
+
const argv = args.trim().length === 0 ? [] : args.trim().split(/\s+/);
|
|
16
|
+
const mountConfigTui = async (init) => {
|
|
17
|
+
// Mark overlay active so forge-input-router suppresses arrow-activator
|
|
18
|
+
// listeners (thread-switcher's ↓, whats-new's ↓) while the TUI owns
|
|
19
|
+
// input focus.
|
|
20
|
+
const router = getInputRouter();
|
|
21
|
+
router.pushOverlay();
|
|
22
|
+
try {
|
|
23
|
+
const exitCode = await ctx.ui.custom((tui, theme, _kb, done) => {
|
|
24
|
+
// Component drives done() on q or successful confirm-quit.
|
|
25
|
+
// Pi TUI key rule 3: call tui.requestRender() after state changes.
|
|
26
|
+
const component = createConfigTuiComponent({
|
|
27
|
+
...init,
|
|
28
|
+
onExit: (code) => done(code),
|
|
29
|
+
onSaved: (target) => ctx.ui.notify(`forge config: saved → ${target}`, "info"),
|
|
30
|
+
onError: (msg) => ctx.ui.notify(`forge config: ${msg}`, "error"),
|
|
31
|
+
requestRender: () => tui.requestRender(),
|
|
32
|
+
theme,
|
|
33
|
+
});
|
|
34
|
+
return component;
|
|
35
|
+
}, {
|
|
36
|
+
overlay: true,
|
|
37
|
+
overlayOptions: {
|
|
38
|
+
width: "100%",
|
|
39
|
+
anchor: "center",
|
|
40
|
+
margin: 0,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
return exitCode;
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
router.popOverlay();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const exitCode = await runConfigTui(argv, process.cwd(), {
|
|
50
|
+
write: () => { },
|
|
51
|
+
writeErr: (s) => ctx.ui.notify(s, "error"),
|
|
52
|
+
ctx: {
|
|
53
|
+
notify: (msg, level) => {
|
|
54
|
+
const lvl = (level === "warning" || level === "error" ? level : "info");
|
|
55
|
+
ctx.ui.notify(msg, lvl);
|
|
56
|
+
},
|
|
57
|
+
mountConfigTui,
|
|
58
|
+
modelRegistry: ctx.modelRegistry,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
if (exitCode !== 0) {
|
|
62
|
+
ctx.ui.notify(`forge:config exited with code ${exitCode}`, "warning");
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=config-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-command.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/config-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface PersonaModel {
|
|
2
|
+
provider: string;
|
|
3
|
+
model: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
export type PersonaModelsMap = Record<string, PersonaModel>;
|
|
7
|
+
export interface PhaseConfig {
|
|
8
|
+
"model-override"?: string | PersonaModel;
|
|
9
|
+
}
|
|
10
|
+
export interface PipelineConfig {
|
|
11
|
+
"persona-models"?: PersonaModelsMap;
|
|
12
|
+
/** Phase overrides keyed by role string. */
|
|
13
|
+
phases?: Record<string, PhaseConfig>;
|
|
14
|
+
}
|
|
15
|
+
export interface SkillCurationConfig {
|
|
16
|
+
/**
|
|
17
|
+
* FORGE-S24 SKILL-CURATION pipeline rollout flag. Default false.
|
|
18
|
+
* When false, the four T08–T11 modules (skill-retriever, skill-usage-tracker,
|
|
19
|
+
* skill-curator-subagent, friction-emit) no-op at entry. Wired into the
|
|
20
|
+
* orchestrator handlers (run-task / fix-bug) so a flag-off run is
|
|
21
|
+
* byte-identical to pre-FORGE-S24 behaviour.
|
|
22
|
+
*/
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface ForgeCliFeatureFlags {
|
|
26
|
+
skillCuration?: SkillCurationConfig;
|
|
27
|
+
}
|
|
28
|
+
export interface GlobalConfig {
|
|
29
|
+
"persona-models"?: PersonaModelsMap;
|
|
30
|
+
forgeCli?: ForgeCliFeatureFlags;
|
|
31
|
+
}
|
|
32
|
+
export interface ProjectConfig {
|
|
33
|
+
"persona-models"?: PersonaModelsMap;
|
|
34
|
+
forgeCli?: ForgeCliFeatureFlags;
|
|
35
|
+
pipelines?: Record<string, PipelineConfig>;
|
|
36
|
+
}
|
|
37
|
+
export interface MergedConfig {
|
|
38
|
+
/** Shallow-merged persona-models (project wins on key collision). */
|
|
39
|
+
"persona-models"?: PersonaModelsMap;
|
|
40
|
+
/** Project-only pipelines (L3/L4 config lives here). */
|
|
41
|
+
pipelines?: Record<string, PipelineConfig>;
|
|
42
|
+
/** The raw global config for L1 lookups — null if absent or invalid. */
|
|
43
|
+
_global: GlobalConfig | null;
|
|
44
|
+
/** The raw project config for L2 lookups — null if absent or invalid. */
|
|
45
|
+
_project: ProjectConfig | null;
|
|
46
|
+
}
|
|
47
|
+
export interface LayeredConfig {
|
|
48
|
+
global: GlobalConfig | null;
|
|
49
|
+
project: ProjectConfig | null;
|
|
50
|
+
merged: MergedConfig;
|
|
51
|
+
errors: string[];
|
|
52
|
+
}
|
|
53
|
+
export declare function loadLayeredConfig(cwd: string): LayeredConfig;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import AjvModule from "ajv";
|
|
3
|
+
import schema from "./forge-cli-schema.json" with { type: "json" };
|
|
4
|
+
import { getGlobalConfigPath, getProjectConfigPath } from "./paths/paths.js";
|
|
5
|
+
// Ajv v8 ESM interop: default export is a namespace holder;
|
|
6
|
+
// the actual constructor lives at .Ajv or .default.Ajv.
|
|
7
|
+
const Ajv = AjvModule.default?.Ajv ?? AjvModule.Ajv ?? AjvModule;
|
|
8
|
+
const ajv = new Ajv({ allErrors: true });
|
|
9
|
+
const validate = ajv.compile(schema);
|
|
10
|
+
function validateConfig(raw, label) {
|
|
11
|
+
const ok = validate(raw);
|
|
12
|
+
if (!ok) {
|
|
13
|
+
const messages = validate.errors
|
|
14
|
+
?.map((e) => `${e.instancePath || "/"} ${e.message}`)
|
|
15
|
+
.join("; ") ?? "unknown";
|
|
16
|
+
return { valid: false, error: `forge-cli ${label} config schema error: ${messages}` };
|
|
17
|
+
}
|
|
18
|
+
return { valid: true, data: raw };
|
|
19
|
+
}
|
|
20
|
+
function readJsonFile(filePath) {
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
23
|
+
}
|
|
24
|
+
catch (_err) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function loadLayeredConfig(cwd) {
|
|
29
|
+
const errors = [];
|
|
30
|
+
const globalPath = getGlobalConfigPath();
|
|
31
|
+
const projectPath = getProjectConfigPath(cwd);
|
|
32
|
+
let globalConfig = null;
|
|
33
|
+
let projectConfig = null;
|
|
34
|
+
const rawGlobal = readJsonFile(globalPath);
|
|
35
|
+
if (rawGlobal !== null) {
|
|
36
|
+
const result = validateConfig(rawGlobal, "global");
|
|
37
|
+
if (result.valid) {
|
|
38
|
+
globalConfig = result.data;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
errors.push(result.error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const rawProject = readJsonFile(projectPath);
|
|
45
|
+
if (rawProject !== null) {
|
|
46
|
+
const result = validateConfig(rawProject, "project");
|
|
47
|
+
if (result.valid) {
|
|
48
|
+
projectConfig = result.data;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
errors.push(result.error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Shallow-merge persona-models: global first, project overwrites per key
|
|
55
|
+
const mergedPersonaModels = {
|
|
56
|
+
...(globalConfig?.["persona-models"] ?? {}),
|
|
57
|
+
...(projectConfig?.["persona-models"] ?? {}),
|
|
58
|
+
};
|
|
59
|
+
const merged = {
|
|
60
|
+
_global: globalConfig,
|
|
61
|
+
_project: projectConfig,
|
|
62
|
+
};
|
|
63
|
+
if (Object.keys(mergedPersonaModels).length > 0) {
|
|
64
|
+
merged["persona-models"] = mergedPersonaModels;
|
|
65
|
+
}
|
|
66
|
+
// Pipelines are project-only (global config is project-agnostic)
|
|
67
|
+
if (projectConfig?.pipelines) {
|
|
68
|
+
merged.pipelines = projectConfig.pipelines;
|
|
69
|
+
}
|
|
70
|
+
return { global: globalConfig, project: projectConfig, merged, errors };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=config-layer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-layer.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/config-layer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PersonaModelsMap, PipelineConfig } from "./config-layer.js";
|
|
2
|
+
export type ConfigLayer = "global" | "project";
|
|
3
|
+
export interface RoutingConfigBuffer {
|
|
4
|
+
"persona-models"?: PersonaModelsMap;
|
|
5
|
+
pipelines?: Record<string, PipelineConfig>;
|
|
6
|
+
}
|
|
7
|
+
export interface WriteOptions {
|
|
8
|
+
layer: ConfigLayer;
|
|
9
|
+
cwd: string;
|
|
10
|
+
buffer: RoutingConfigBuffer;
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveTargetPath(opts: {
|
|
13
|
+
layer: ConfigLayer;
|
|
14
|
+
cwd: string;
|
|
15
|
+
}): string;
|
|
16
|
+
export declare function writeRoutingConfig(opts: WriteOptions): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Atomic, schema-validated writer for forge-cli routing config files.
|
|
2
|
+
//
|
|
3
|
+
// Plan 16, Slice 4a. Writes ONLY to (paths resolved via paths/paths.ts):
|
|
4
|
+
// - global layer (L1) → getGlobalConfigPath() → ~/.pi/forge-cli/config.json
|
|
5
|
+
// - project layer (L2/L3/L4) → getProjectConfigPath(cwd) →
|
|
6
|
+
// <cwd>/.pi/forge-cli/config.json
|
|
7
|
+
//
|
|
8
|
+
// Never writes to .forge/config.json — that's the plugin's pipeline catalogue,
|
|
9
|
+
// read-only from this TUI.
|
|
10
|
+
//
|
|
11
|
+
// Write protocol:
|
|
12
|
+
// 1. Validate buffer against forge-cli-schema.json. Throw on fail.
|
|
13
|
+
// 2. If buffer is empty ({}) and target file exists → unlink. Return target.
|
|
14
|
+
// 3. Otherwise: write to <target>.tmp, fsync, rename atomically to <target>.
|
|
15
|
+
import * as fs from "node:fs";
|
|
16
|
+
import * as path from "node:path";
|
|
17
|
+
import AjvModule from "ajv";
|
|
18
|
+
import schema from "./forge-cli-schema.json" with { type: "json" };
|
|
19
|
+
import { getGlobalConfigPath, getProjectConfigPath } from "./paths/paths.js";
|
|
20
|
+
// Ajv v8 ESM interop: default export is a namespace holder;
|
|
21
|
+
// the actual constructor lives at .Ajv or .default.Ajv.
|
|
22
|
+
const Ajv = AjvModule.default?.Ajv ?? AjvModule.Ajv ?? AjvModule;
|
|
23
|
+
const ajv = new Ajv({ allErrors: true });
|
|
24
|
+
const validate = ajv.compile(schema);
|
|
25
|
+
export function resolveTargetPath(opts) {
|
|
26
|
+
if (opts.layer === "global") {
|
|
27
|
+
return getGlobalConfigPath();
|
|
28
|
+
}
|
|
29
|
+
return getProjectConfigPath(opts.cwd);
|
|
30
|
+
}
|
|
31
|
+
function isEmpty(buffer) {
|
|
32
|
+
const personaCount = Object.keys(buffer["persona-models"] ?? {}).length;
|
|
33
|
+
const pipelineCount = Object.keys(buffer.pipelines ?? {}).length;
|
|
34
|
+
return personaCount === 0 && pipelineCount === 0;
|
|
35
|
+
}
|
|
36
|
+
export function writeRoutingConfig(opts) {
|
|
37
|
+
const target = resolveTargetPath(opts);
|
|
38
|
+
// Empty buffer → delete file if present.
|
|
39
|
+
if (isEmpty(opts.buffer)) {
|
|
40
|
+
if (fs.existsSync(target)) {
|
|
41
|
+
fs.unlinkSync(target);
|
|
42
|
+
}
|
|
43
|
+
return target;
|
|
44
|
+
}
|
|
45
|
+
// Validate FIRST. Any failure short-circuits before touching the filesystem.
|
|
46
|
+
const ok = validate(opts.buffer);
|
|
47
|
+
if (!ok) {
|
|
48
|
+
const messages = validate.errors
|
|
49
|
+
?.map((e) => `${e.instancePath || "/"} ${e.message}`)
|
|
50
|
+
.join("; ") ?? "unknown";
|
|
51
|
+
throw new Error(`forge-cli config schema error: ${messages}`);
|
|
52
|
+
}
|
|
53
|
+
// Ensure parent dir exists.
|
|
54
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
55
|
+
// Atomic write: temp file + rename. Pretty-print for human-readable diffs.
|
|
56
|
+
const tmpPath = `${target}.tmp`;
|
|
57
|
+
const serialized = `${JSON.stringify(opts.buffer, null, 2)}\n`;
|
|
58
|
+
const fd = fs.openSync(tmpPath, "w");
|
|
59
|
+
try {
|
|
60
|
+
fs.writeSync(fd, serialized);
|
|
61
|
+
fs.fsyncSync(fd);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
fs.closeSync(fd);
|
|
65
|
+
}
|
|
66
|
+
fs.renameSync(tmpPath, target);
|
|
67
|
+
return target;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=config-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/config-writer.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,6DAA6D;AAC7D,sCAAsC;AACtC,EAAE;AACF,+EAA+E;AAC/E,2BAA2B;AAC3B,EAAE;AACF,kBAAkB;AAClB,qEAAqE;AACrE,+EAA+E;AAC/E,+EAA+E;AAE/E,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,SAAS,MAAM,KAAK,CAAC;AAE5B,OAAO,MAAM,MAAM,yBAAyB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,4DAA4D;AAC5D,wDAAwD;AACxD,MAAM,GAAG,GAAI,SAAiB,CAAC,OAAO,EAAE,GAAG,IAAK,SAAiB,CAAC,GAAG,IAAI,SAAS,CAAC;AAenF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAErC,MAAM,UAAU,iBAAiB,CAAC,IAAyC;IAC1E,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,mBAAmB,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,OAAO,CAAC,MAA2B;IAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IACxE,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IACjE,OAAO,YAAY,KAAK,CAAC,IAAI,aAAa,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACpD,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAEvC,yCAAyC;IACzC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAED,6EAA6E;IAC7E,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,EAAE,CAAC;QACT,MAAM,QAAQ,GACb,QAAQ,CAAC,MAAM;YACd,EAAE,GAAG,CAAC,CAAC,CAA8C,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;aACjG,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,4BAA4B;IAC5B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,2EAA2E;IAC3E,MAAM,OAAO,GAAG,GAAG,MAAM,MAAM,CAAC;IAChC,MAAM,UAAU,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAE/D,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC;QACJ,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7B,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QACV,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IACD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE/B,OAAO,MAAM,CAAC;AACf,CAAC"}
|