@entelligentsia/forgecli 1.0.14 → 1.0.21
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 +185 -0
- package/README.md +7 -1
- package/dist/CHANGELOG-forge-plugin.md +61 -0
- package/dist/bin/config.js +4 -4
- package/dist/bin/config.js.map +1 -1
- package/dist/bin/update-cli.d.ts +1 -1
- package/dist/bin/update-cli.js +1 -1
- package/dist/bin/update-cli.js.map +1 -1
- package/dist/extensions/forgecli/ask-user-tool.js +1 -1
- package/dist/extensions/forgecli/ask-user-tool.js.map +1 -1
- package/dist/extensions/forgecli/commands/add-pipeline.d.ts +19 -0
- package/dist/extensions/forgecli/commands/add-pipeline.js +143 -0
- package/dist/extensions/forgecli/commands/add-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/commands/add-task.d.ts +20 -0
- package/dist/extensions/forgecli/commands/add-task.js +154 -0
- package/dist/extensions/forgecli/commands/add-task.js.map +1 -0
- package/dist/extensions/forgecli/commands/approve.d.ts +22 -0
- package/dist/extensions/forgecli/commands/approve.js +152 -0
- package/dist/extensions/forgecli/commands/approve.js.map +1 -0
- package/dist/extensions/forgecli/commands/collate.d.ts +22 -0
- package/dist/extensions/forgecli/commands/collate.js +134 -0
- package/dist/extensions/forgecli/commands/collate.js.map +1 -0
- package/dist/extensions/forgecli/commands/commit.d.ts +22 -0
- package/dist/extensions/forgecli/commands/commit.js +152 -0
- package/dist/extensions/forgecli/commands/commit.js.map +1 -0
- package/dist/extensions/forgecli/commands/config-command.d.ts +8 -0
- package/dist/extensions/forgecli/commands/config-command.js +67 -0
- package/dist/extensions/forgecli/commands/config-command.js.map +1 -0
- package/dist/extensions/forgecli/commands/enhance.d.ts +45 -0
- package/dist/extensions/forgecli/commands/enhance.js +219 -0
- package/dist/extensions/forgecli/commands/enhance.js.map +1 -0
- package/dist/extensions/forgecli/commands/implement.d.ts +22 -0
- package/dist/extensions/forgecli/commands/implement.js +170 -0
- package/dist/extensions/forgecli/commands/implement.js.map +1 -0
- package/dist/extensions/forgecli/commands/plan.d.ts +22 -0
- package/dist/extensions/forgecli/commands/plan.js +167 -0
- package/dist/extensions/forgecli/commands/plan.js.map +1 -0
- package/dist/extensions/forgecli/commands/quiz-agent.d.ts +17 -0
- package/dist/extensions/forgecli/commands/quiz-agent.js +98 -0
- package/dist/extensions/forgecli/commands/quiz-agent.js.map +1 -0
- package/dist/extensions/forgecli/commands/read-command.d.ts +2 -0
- package/dist/extensions/forgecli/commands/read-command.js +100 -0
- package/dist/extensions/forgecli/commands/read-command.js.map +1 -0
- package/dist/extensions/forgecli/commands/regenerate.d.ts +40 -0
- package/dist/extensions/forgecli/commands/regenerate.js +426 -0
- package/dist/extensions/forgecli/commands/regenerate.js.map +1 -0
- package/dist/extensions/forgecli/commands/remove-command.d.ts +17 -0
- package/dist/extensions/forgecli/commands/remove-command.js +124 -0
- package/dist/extensions/forgecli/commands/remove-command.js.map +1 -0
- package/dist/extensions/forgecli/commands/report-bug.d.ts +25 -0
- package/dist/extensions/forgecli/commands/report-bug.js +159 -0
- package/dist/extensions/forgecli/commands/report-bug.js.map +1 -0
- package/dist/extensions/forgecli/commands/retrospective.d.ts +20 -0
- package/dist/extensions/forgecli/commands/retrospective.js +126 -0
- package/dist/extensions/forgecli/commands/retrospective.js.map +1 -0
- package/dist/extensions/forgecli/commands/review-code.d.ts +35 -0
- package/dist/extensions/forgecli/commands/review-code.js +196 -0
- package/dist/extensions/forgecli/commands/review-code.js.map +1 -0
- package/dist/extensions/forgecli/commands/review-plan.d.ts +35 -0
- package/dist/extensions/forgecli/commands/review-plan.js +200 -0
- package/dist/extensions/forgecli/commands/review-plan.js.map +1 -0
- package/dist/extensions/forgecli/commands/sprint-intake.d.ts +10 -0
- package/dist/extensions/forgecli/commands/sprint-intake.js +91 -0
- package/dist/extensions/forgecli/commands/sprint-intake.js.map +1 -0
- package/dist/extensions/forgecli/commands/sprint-plan.d.ts +14 -0
- package/dist/extensions/forgecli/commands/sprint-plan.js +122 -0
- package/dist/extensions/forgecli/commands/sprint-plan.js.map +1 -0
- package/dist/extensions/forgecli/commands/status-command.d.ts +19 -0
- package/dist/extensions/forgecli/commands/status-command.js +140 -0
- package/dist/extensions/forgecli/commands/status-command.js.map +1 -0
- package/dist/extensions/forgecli/commands/store-query.d.ts +22 -0
- package/dist/extensions/forgecli/commands/store-query.js +107 -0
- package/dist/extensions/forgecli/commands/store-query.js.map +1 -0
- package/dist/extensions/forgecli/commands/store-repair.d.ts +17 -0
- package/dist/extensions/forgecli/commands/store-repair.js +123 -0
- package/dist/extensions/forgecli/commands/store-repair.js.map +1 -0
- package/dist/extensions/forgecli/commands/test-orchestrate.d.ts +2 -0
- package/dist/extensions/forgecli/commands/test-orchestrate.js +182 -0
- package/dist/extensions/forgecli/commands/test-orchestrate.js.map +1 -0
- package/dist/extensions/forgecli/commands/transcripts-command.d.ts +87 -0
- package/dist/extensions/forgecli/commands/transcripts-command.js +418 -0
- package/dist/extensions/forgecli/commands/transcripts-command.js.map +1 -0
- package/dist/extensions/forgecli/commands/validate.d.ts +22 -0
- package/dist/extensions/forgecli/commands/validate.js +152 -0
- package/dist/extensions/forgecli/commands/validate.js.map +1 -0
- package/dist/extensions/forgecli/config/config-layer.d.ts +53 -0
- package/dist/extensions/forgecli/config/config-layer.js +72 -0
- package/dist/extensions/forgecli/config/config-layer.js.map +1 -0
- package/dist/extensions/forgecli/config/config-writer.d.ts +16 -0
- package/dist/extensions/forgecli/config/config-writer.js +69 -0
- package/dist/extensions/forgecli/config/config-writer.js.map +1 -0
- package/dist/extensions/forgecli/config/model-registry.d.ts +61 -0
- package/dist/extensions/forgecli/config/model-registry.js +127 -0
- package/dist/extensions/forgecli/config/model-registry.js.map +1 -0
- package/dist/extensions/forgecli/config/model-resolver.d.ts +32 -0
- package/dist/extensions/forgecli/config/model-resolver.js +65 -0
- package/dist/extensions/forgecli/config/model-resolver.js.map +1 -0
- package/dist/extensions/forgecli/config/model-validator.d.ts +29 -0
- package/dist/extensions/forgecli/config/model-validator.js +107 -0
- package/dist/extensions/forgecli/config/model-validator.js.map +1 -0
- package/dist/extensions/forgecli/config-layer.d.ts +0 -16
- package/dist/extensions/forgecli/config-layer.js +0 -5
- package/dist/extensions/forgecli/config-layer.js.map +1 -1
- package/dist/extensions/forgecli/config-tui/component.js +1 -1
- package/dist/extensions/forgecli/config-tui/component.js.map +1 -1
- package/dist/extensions/forgecli/config-tui/handler.js +1 -1
- package/dist/extensions/forgecli/config-tui/handler.js.map +1 -1
- package/dist/extensions/forgecli/config-tui/screens/override-editor.js +1 -1
- package/dist/extensions/forgecli/config-tui/screens/override-editor.js.map +1 -1
- package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js +1 -1
- package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js.map +1 -1
- package/dist/extensions/forgecli/config-tui/screens/show-resolved.js +1 -1
- package/dist/extensions/forgecli/config-tui/screens/show-resolved.js.map +1 -1
- package/dist/extensions/forgecli/config-tui/state/buffer.d.ts +2 -2
- package/dist/extensions/forgecli/config-tui/state/model.d.ts +1 -1
- package/dist/extensions/forgecli/config-tui/state/reducer.js.map +1 -1
- package/dist/extensions/forgecli/config-tui/state/selectors.d.ts +2 -2
- package/dist/extensions/forgecli/config-tui/state/selectors.js +1 -1
- package/dist/extensions/forgecli/config-tui/state/selectors.js.map +1 -1
- package/dist/extensions/forgecli/context-governor-compaction.d.ts +94 -0
- package/dist/extensions/forgecli/context-governor-compaction.js +327 -0
- package/dist/extensions/forgecli/context-governor-compaction.js.map +1 -0
- package/dist/extensions/forgecli/context-governor.d.ts +169 -0
- package/dist/extensions/forgecli/context-governor.js +592 -0
- package/dist/extensions/forgecli/context-governor.js.map +1 -0
- package/dist/extensions/forgecli/dashboard/component.d.ts +17 -5
- package/dist/extensions/forgecli/dashboard/component.js +160 -115
- package/dist/extensions/forgecli/dashboard/component.js.map +1 -1
- package/dist/extensions/forgecli/dashboard/register.js +7 -21
- package/dist/extensions/forgecli/dashboard/register.js.map +1 -1
- package/dist/extensions/forgecli/dashboard/theme.d.ts +27 -0
- package/dist/extensions/forgecli/dashboard/theme.js +91 -0
- package/dist/extensions/forgecli/dashboard/theme.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.js +59 -5
- package/dist/extensions/forgecli/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/forge-artifact-tool.js +3 -2
- package/dist/extensions/forgecli/forge-artifact-tool.js.map +1 -1
- package/dist/extensions/forgecli/forge-cli-schema.json +0 -4
- package/dist/extensions/forgecli/forge-commands.js +1 -1
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-init/forge-init.d.ts +26 -0
- package/dist/extensions/forgecli/forge-init/forge-init.js +514 -0
- package/dist/extensions/forgecli/forge-init/forge-init.js.map +1 -0
- package/dist/extensions/forgecli/forge-init/init-context.d.ts +99 -0
- package/dist/extensions/forgecli/forge-init/init-context.js +178 -0
- package/dist/extensions/forgecli/forge-init/init-context.js.map +1 -0
- package/dist/extensions/forgecli/forge-init/init-progress.d.ts +39 -0
- package/dist/extensions/forgecli/forge-init/init-progress.js +117 -0
- package/dist/extensions/forgecli/forge-init/init-progress.js.map +1 -0
- package/dist/extensions/forgecli/forge-init/phase4-register.js +1 -1
- package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -1
- package/dist/extensions/forgecli/forge-init/run-phases.js +2 -2
- package/dist/extensions/forgecli/forge-init/run-phases.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.d.ts +42 -1
- package/dist/extensions/forgecli/forge-subagent.js +59 -18
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/forge-tools.d.ts +0 -25
- package/dist/extensions/forgecli/forge-tools.js +8 -37
- package/dist/extensions/forgecli/forge-tools.js.map +1 -1
- package/dist/extensions/forgecli/governor-config.d.ts +19 -0
- package/dist/extensions/forgecli/governor-config.js +58 -0
- package/dist/extensions/forgecli/governor-config.js.map +1 -0
- package/dist/extensions/forgecli/health-check.js +1 -1
- package/dist/extensions/forgecli/health-check.js.map +1 -1
- package/dist/extensions/forgecli/hook-dispatcher.d.ts +3 -1
- package/dist/extensions/forgecli/hook-dispatcher.js +39 -5
- package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
- package/dist/extensions/forgecli/hooks/post-init-hook.js +11 -6
- package/dist/extensions/forgecli/hooks/post-init-hook.js.map +1 -1
- package/dist/extensions/forgecli/hooks/post-sprint-hook.js +11 -6
- package/dist/extensions/forgecli/hooks/post-sprint-hook.js.map +1 -1
- package/dist/extensions/forgecli/hooks/write-guard.js +1 -1
- package/dist/extensions/forgecli/hooks/write-guard.js.map +1 -1
- package/dist/extensions/forgecli/index.js +70 -36
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/kickoff.d.ts +9 -0
- package/dist/extensions/forgecli/kickoff.js +15 -0
- package/dist/extensions/forgecli/kickoff.js.map +1 -1
- package/dist/extensions/forgecli/lib/forge-config.d.ts +1 -1
- package/dist/extensions/forgecli/lib/forge-config.js +1 -1
- package/dist/extensions/forgecli/lib/forge-config.js.map +1 -1
- package/dist/extensions/forgecli/lib/forge-root.d.ts +10 -0
- package/dist/extensions/forgecli/lib/forge-root.js +62 -0
- package/dist/extensions/forgecli/lib/forge-root.js.map +1 -0
- package/dist/extensions/forgecli/lib/halt-advisor.d.ts +19 -14
- package/dist/extensions/forgecli/lib/halt-advisor.js +36 -13
- package/dist/extensions/forgecli/lib/halt-advisor.js.map +1 -1
- package/dist/extensions/forgecli/lib/run-cjs.d.ts +26 -0
- package/dist/extensions/forgecli/lib/run-cjs.js +42 -0
- package/dist/extensions/forgecli/lib/run-cjs.js.map +1 -0
- package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +3 -2
- package/dist/extensions/forgecli/orchestrator-status-bar.js +90 -60
- package/dist/extensions/forgecli/orchestrator-status-bar.js.map +1 -1
- package/dist/extensions/forgecli/orchestrator-tree.d.ts +4 -0
- package/dist/extensions/forgecli/orchestrator-tree.js +21 -3
- package/dist/extensions/forgecli/orchestrator-tree.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/calibrate.d.ts +64 -0
- package/dist/extensions/forgecli/orchestrators/calibrate.js +481 -0
- package/dist/extensions/forgecli/orchestrators/calibrate.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/fix-bug.d.ts +93 -0
- package/dist/extensions/forgecli/orchestrators/fix-bug.js +1705 -0
- package/dist/extensions/forgecli/orchestrators/fix-bug.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/halt-advisor.d.ts +59 -0
- package/dist/extensions/forgecli/orchestrators/halt-advisor.js +113 -0
- package/dist/extensions/forgecli/orchestrators/halt-advisor.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/materialize.d.ts +16 -0
- package/dist/extensions/forgecli/orchestrators/materialize.js +195 -0
- package/dist/extensions/forgecli/orchestrators/materialize.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/migrate.d.ts +22 -0
- package/dist/extensions/forgecli/orchestrators/migrate.js +260 -0
- package/dist/extensions/forgecli/orchestrators/migrate.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/orchestrator-preflight.d.ts +46 -0
- package/dist/extensions/forgecli/orchestrators/orchestrator-preflight.js +64 -0
- package/dist/extensions/forgecli/orchestrators/orchestrator-preflight.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/run-sprint.d.ts +27 -0
- package/dist/extensions/forgecli/orchestrators/run-sprint.js +734 -0
- package/dist/extensions/forgecli/orchestrators/run-sprint.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/run-task.d.ts +215 -0
- package/dist/extensions/forgecli/orchestrators/run-task.js +1491 -0
- package/dist/extensions/forgecli/orchestrators/run-task.js.map +1 -0
- package/dist/extensions/forgecli/paths/paths.d.ts +8 -0
- package/dist/extensions/forgecli/paths/paths.js +17 -0
- package/dist/extensions/forgecli/paths/paths.js.map +1 -1
- package/dist/extensions/forgecli/phase-vocab.d.ts +31 -0
- package/dist/extensions/forgecli/phase-vocab.js +82 -0
- package/dist/extensions/forgecli/phase-vocab.js.map +1 -0
- package/dist/extensions/forgecli/run-sprint.d.ts +3 -1
- package/dist/extensions/forgecli/run-sprint.js +1 -0
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.d.ts +34 -1
- package/dist/extensions/forgecli/run-task.js +144 -6
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/session-registry.d.ts +2 -2
- package/dist/extensions/forgecli/session-registry.js +6 -2
- package/dist/extensions/forgecli/session-registry.js.map +1 -1
- package/dist/extensions/forgecli/skill-curation/friction-emit.d.ts +99 -0
- package/dist/extensions/forgecli/skill-curation/friction-emit.js +245 -0
- package/dist/extensions/forgecli/skill-curation/friction-emit.js.map +1 -0
- package/dist/extensions/forgecli/skill-curation/skill-curation-flag.d.ts +21 -0
- package/dist/extensions/forgecli/skill-curation/skill-curation-flag.js +71 -0
- package/dist/extensions/forgecli/skill-curation/skill-curation-flag.js.map +1 -0
- package/dist/extensions/forgecli/skill-curation/skill-curator-subagent.d.ts +102 -0
- package/dist/extensions/forgecli/skill-curation/skill-curator-subagent.js +339 -0
- package/dist/extensions/forgecli/skill-curation/skill-curator-subagent.js.map +1 -0
- package/dist/extensions/forgecli/skill-curation/skill-retriever.d.ts +84 -0
- package/dist/extensions/forgecli/skill-curation/skill-retriever.js +246 -0
- package/dist/extensions/forgecli/skill-curation/skill-retriever.js.map +1 -0
- package/dist/extensions/forgecli/skill-curation/skill-usage-tracker.d.ts +91 -0
- package/dist/extensions/forgecli/skill-curation/skill-usage-tracker.js +224 -0
- package/dist/extensions/forgecli/skill-curation/skill-usage-tracker.js.map +1 -0
- package/dist/extensions/forgecli/store/store-error-remediation.d.ts +65 -0
- package/dist/extensions/forgecli/store/store-error-remediation.js +307 -0
- package/dist/extensions/forgecli/store/store-error-remediation.js.map +1 -0
- package/dist/extensions/forgecli/store/store-resolver.d.ts +56 -0
- package/dist/extensions/forgecli/store/store-resolver.js +263 -0
- package/dist/extensions/forgecli/store/store-resolver.js.map +1 -0
- package/dist/extensions/forgecli/store/store-validator.d.ts +16 -0
- package/dist/extensions/forgecli/store/store-validator.js +32 -0
- package/dist/extensions/forgecli/store/store-validator.js.map +1 -0
- package/dist/extensions/forgecli/store/transition-guard.d.ts +20 -0
- package/dist/extensions/forgecli/store/transition-guard.js +89 -0
- package/dist/extensions/forgecli/store/transition-guard.js.map +1 -0
- package/dist/extensions/forgecli/subagent/orchestrator-transcript.js +5 -0
- package/dist/extensions/forgecli/subagent/orchestrator-transcript.js.map +1 -1
- package/dist/extensions/forgecli/thread-switcher.d.ts +4 -1
- package/dist/extensions/forgecli/thread-switcher.js +36 -21
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
- package/dist/extensions/forgecli/transcript-archive-types.d.ts +171 -0
- package/dist/extensions/forgecli/transcript-archive-types.js +130 -0
- package/dist/extensions/forgecli/transcript-archive-types.js.map +1 -0
- package/dist/extensions/forgecli/transcript-archive.d.ts +127 -0
- package/dist/extensions/forgecli/transcript-archive.js +656 -0
- package/dist/extensions/forgecli/transcript-archive.js.map +1 -0
- package/dist/extensions/forgecli/transcript-replay.d.ts +28 -0
- package/dist/extensions/forgecli/transcript-replay.js +153 -0
- package/dist/extensions/forgecli/transcript-replay.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/component.d.ts +36 -0
- package/dist/extensions/forgecli/transcripts-tui/component.js +112 -0
- package/dist/extensions/forgecli/transcripts-tui/component.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/index.d.ts +4 -0
- package/dist/extensions/forgecli/transcripts-tui/index.js +5 -0
- package/dist/extensions/forgecli/transcripts-tui/index.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/screens/browse.d.ts +21 -0
- package/dist/extensions/forgecli/transcripts-tui/screens/browse.js +172 -0
- package/dist/extensions/forgecli/transcripts-tui/screens/browse.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/screens/types.d.ts +22 -0
- package/dist/extensions/forgecli/transcripts-tui/screens/types.js +4 -0
- package/dist/extensions/forgecli/transcripts-tui/screens/types.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/state/index.d.ts +4 -0
- package/dist/extensions/forgecli/transcripts-tui/state/index.js +5 -0
- package/dist/extensions/forgecli/transcripts-tui/state/index.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/state/init.d.ts +8 -0
- package/dist/extensions/forgecli/transcripts-tui/state/init.js +18 -0
- package/dist/extensions/forgecli/transcripts-tui/state/init.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/state/model.d.ts +56 -0
- package/dist/extensions/forgecli/transcripts-tui/state/model.js +6 -0
- package/dist/extensions/forgecli/transcripts-tui/state/model.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/state/reducer.d.ts +2 -0
- package/dist/extensions/forgecli/transcripts-tui/state/reducer.js +51 -0
- package/dist/extensions/forgecli/transcripts-tui/state/reducer.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/state/selectors.d.ts +10 -0
- package/dist/extensions/forgecli/transcripts-tui/state/selectors.js +62 -0
- package/dist/extensions/forgecli/transcripts-tui/state/selectors.js.map +1 -0
- package/dist/extensions/forgecli/transcripts-tui/theme.d.ts +20 -0
- package/dist/extensions/forgecli/transcripts-tui/theme.js +47 -0
- package/dist/extensions/forgecli/transcripts-tui/theme.js.map +1 -0
- package/dist/extensions/forgecli/tui/banner.d.ts +10 -0
- package/dist/extensions/forgecli/tui/banner.js +36 -0
- package/dist/extensions/forgecli/tui/banner.js.map +1 -0
- package/dist/extensions/forgecli/tui/forge-header.d.ts +12 -0
- package/dist/extensions/forgecli/tui/forge-header.js +114 -0
- package/dist/extensions/forgecli/tui/forge-header.js.map +1 -0
- package/dist/extensions/forgecli/tui/input-router.d.ts +33 -0
- package/dist/extensions/forgecli/tui/input-router.js +136 -0
- package/dist/extensions/forgecli/tui/input-router.js.map +1 -0
- package/dist/extensions/forgecli/tui/orchestrator-status-bar.d.ts +26 -0
- package/dist/extensions/forgecli/tui/orchestrator-status-bar.js +213 -0
- package/dist/extensions/forgecli/tui/orchestrator-status-bar.js.map +1 -0
- package/dist/extensions/forgecli/tui/thread-switcher.d.ts +18 -0
- package/dist/extensions/forgecli/tui/thread-switcher.js +194 -0
- package/dist/extensions/forgecli/tui/thread-switcher.js.map +1 -0
- package/dist/extensions/forgecli/update/forge-update-command.d.ts +100 -0
- package/dist/extensions/forgecli/update/forge-update-command.js +435 -0
- package/dist/extensions/forgecli/update/forge-update-command.js.map +1 -0
- package/dist/extensions/forgecli/update/migration-engine.d.ts +117 -0
- package/dist/extensions/forgecli/update/migration-engine.js +563 -0
- package/dist/extensions/forgecli/update/migration-engine.js.map +1 -0
- package/dist/extensions/forgecli/update/update-check.d.ts +37 -0
- package/dist/extensions/forgecli/update/update-check.js +185 -0
- package/dist/extensions/forgecli/update/update-check.js.map +1 -0
- package/dist/extensions/forgecli/update/update-tools.d.ts +23 -0
- package/dist/extensions/forgecli/update/update-tools.js +135 -0
- package/dist/extensions/forgecli/update/update-tools.js.map +1 -0
- package/dist/extensions/forgecli/update/whats-new-widget.d.ts +26 -0
- package/dist/extensions/forgecli/update/whats-new-widget.js +376 -0
- package/dist/extensions/forgecli/update/whats-new-widget.js.map +1 -0
- package/dist/extensions/forgecli/update/whats-new.d.ts +120 -0
- package/dist/extensions/forgecli/update/whats-new.js +470 -0
- package/dist/extensions/forgecli/update/whats-new.js.map +1 -0
- package/dist/extensions/forgecli/viewport/events.d.ts +113 -0
- package/dist/extensions/forgecli/viewport/events.js +290 -0
- package/dist/extensions/forgecli/viewport/events.js.map +1 -0
- package/dist/extensions/forgecli/viewport/renderer.d.ts +102 -0
- package/dist/extensions/forgecli/viewport/renderer.js +277 -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 +131 -0
- package/dist/extensions/forgecli/viewport/theme.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/engine.js +1 -1
- package/dist/extensions/forgecli/wf-engine/engine.js.map +1 -1
- package/dist/forge-payload/.base-pack/workflows/implement_plan.md +9 -0
- package/dist/forge-payload/.base-pack/workflows/plan_task.md +7 -0
- package/dist/forge-payload/.base-pack/workflows/review_code.md +4 -3
- package/dist/forge-payload/.base-pack/workflows/review_plan.md +4 -3
- package/dist/forge-payload/.base-pack/workflows/validate_task.md +4 -3
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/migrations.json +132 -27
- package/dist/forge-payload/meta/workflows/meta-review-implementation.md +4 -3
- package/dist/forge-payload/meta/workflows/meta-review-plan.md +4 -3
- package/dist/forge-payload/meta/workflows/meta-validate.md +4 -3
- package/dist/forge-payload/tools/collate.cjs +32 -0
- package/dist/forge-payload/tools/postflight-gate.cjs +56 -10
- package/package.json +5 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type { Component, TUI } from "@earendil-works/pi-tui";
|
|
2
|
+
import type { Component, Focusable, TUI } from "@earendil-works/pi-tui";
|
|
3
3
|
import type { OrchestratorTree } from "../orchestrator-tree.js";
|
|
4
4
|
import type { NodeViewModel } from "./view-model.js";
|
|
5
5
|
export interface DashboardState {
|
|
@@ -11,6 +11,10 @@ export interface DashboardState {
|
|
|
11
11
|
focusPanel: "tree" | "detail";
|
|
12
12
|
/** Whether the detail panel's prompt section is expanded. */
|
|
13
13
|
promptExpanded: boolean;
|
|
14
|
+
/** Activity-log expansion (ctrl+o): false = clamp long entries to a small
|
|
15
|
+
* row budget, true = render full content. Display policy lives entirely in
|
|
16
|
+
* the view — the model stores log entries verbatim. */
|
|
17
|
+
logExpanded: boolean;
|
|
14
18
|
/** Node ID targeted for cancellation confirmation, if active. */
|
|
15
19
|
cancelTargetId: string | null;
|
|
16
20
|
/** Scroll offset for the detail panel (0 = top). */
|
|
@@ -22,8 +26,12 @@ export declare class DashboardController {
|
|
|
22
26
|
private state;
|
|
23
27
|
private onInvalidate?;
|
|
24
28
|
private refreshTimer?;
|
|
29
|
+
private disposed;
|
|
30
|
+
private readonly readOnly;
|
|
25
31
|
private _handlers;
|
|
26
|
-
constructor(tree: OrchestratorTree, initialCursorId?: string
|
|
32
|
+
constructor(tree: OrchestratorTree, initialCursorId?: string, opts?: {
|
|
33
|
+
readOnly?: boolean;
|
|
34
|
+
});
|
|
27
35
|
setOnInvalidate(cb: () => void): void;
|
|
28
36
|
/** Rebuild the ViewModel from the live model. Called on every model event. */
|
|
29
37
|
private rebuildViewModel;
|
|
@@ -67,6 +75,8 @@ export declare class DashboardController {
|
|
|
67
75
|
private activateCursor;
|
|
68
76
|
private toggleExpand;
|
|
69
77
|
private collapseCursor;
|
|
78
|
+
/** Replay mode: read-only dashboards (archived trees) never cancel. */
|
|
79
|
+
isReadOnly(): boolean;
|
|
70
80
|
private startCancel;
|
|
71
81
|
private ensureAncestorsExpanded;
|
|
72
82
|
autoExpandNewNode(id: string): void;
|
|
@@ -75,7 +85,11 @@ export declare class DashboardController {
|
|
|
75
85
|
dispose(): void;
|
|
76
86
|
getState(): DashboardState;
|
|
77
87
|
}
|
|
78
|
-
export declare class DashboardComponent implements Component {
|
|
88
|
+
export declare class DashboardComponent implements Component, Focusable {
|
|
89
|
+
/** IL3: Focusable — pi sets this to true when the overlay has
|
|
90
|
+
* keyboard focus. Without this, arrow-key and Escape events are
|
|
91
|
+
* swallowed at the overlay layer. (Lesson from config-TUI commit 07e886f.) */
|
|
92
|
+
focused: boolean;
|
|
79
93
|
private controller;
|
|
80
94
|
private theme;
|
|
81
95
|
private tui;
|
|
@@ -86,7 +100,6 @@ export declare class DashboardComponent implements Component {
|
|
|
86
100
|
invalidate(): void;
|
|
87
101
|
dispose(): void;
|
|
88
102
|
private renderTreePanel;
|
|
89
|
-
private nodeGlyph;
|
|
90
103
|
private renderDetailPanel;
|
|
91
104
|
/** Render a cancel-confirmation dialog overlaid on the dashboard.
|
|
92
105
|
* The dashboard content stays visible above and below the dialog.
|
|
@@ -97,6 +110,5 @@ export declare class DashboardComponent implements Component {
|
|
|
97
110
|
* dismisses the cancel prompt, not the dashboard.
|
|
98
111
|
*/
|
|
99
112
|
private overlayCancelConfirm;
|
|
100
|
-
private statusLabel;
|
|
101
113
|
private formatMetrics;
|
|
102
114
|
}
|
|
@@ -20,11 +20,20 @@
|
|
|
20
20
|
// manages the refresh timer, and handles input. DashboardComponent reads
|
|
21
21
|
// only from the controller — never directly from the OrchestratorTree model.
|
|
22
22
|
// This eliminates the boundary violations catalogued in the audit.
|
|
23
|
+
//
|
|
24
|
+
// Iron Laws conformance:
|
|
25
|
+
// IL1 — All visible strings route through dashboard/theme.ts helpers or
|
|
26
|
+
// theme.fg()/bg()/bold(). No raw glyphs.
|
|
27
|
+
// IL2 — Dual-layer width safety: screen renderers call truncateLines(),
|
|
28
|
+
// orchestrator applies truncateToWidth per line.
|
|
29
|
+
// IL3 — DashboardComponent implements Focusable (focused: boolean = false).
|
|
30
|
+
// IL7 — Timer unmount-safety: disposed flag guards interval callbacks.
|
|
23
31
|
import { matchesKey, Key, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
24
32
|
import { getSessionRegistry } from "../session-registry.js";
|
|
25
33
|
import { buildViewModel } from "./view-model.js";
|
|
26
|
-
import { fmtTokenMeter } from "../viewport
|
|
27
|
-
import { paintTailLine } from "../viewport
|
|
34
|
+
import { fmtTokenMeter, toDisplayLines } from "../viewport/renderer.js";
|
|
35
|
+
import { paintTailLine } from "../viewport/theme.js";
|
|
36
|
+
import { cursor, nodeGlyph, statusLabel, dim, accentBold, warn, bold, border, collapseIndicator, promptExpandIcon, truncateLines, } from "./theme.js";
|
|
28
37
|
// ── Word-wrap helper ───────────────────────────────────────────────────────────
|
|
29
38
|
//
|
|
30
39
|
// Splits a line (which may contain ANSI escape sequences) into multiple
|
|
@@ -32,6 +41,15 @@ import { paintTailLine } from "../viewport-theme.js";
|
|
|
32
41
|
// Preserves ANSI styling across wrapped lines. Falls back to character-level
|
|
33
42
|
// truncation for individual tokens wider than maxWidth.
|
|
34
43
|
function wrapLine(line, maxWidth) {
|
|
44
|
+
// Row-integrity guard (layer 2 of the single-line invariant; layer 1 is
|
|
45
|
+
// toDisplayLines at the appendTail model boundary): a raw \n inside a
|
|
46
|
+
// composed pane row resets the terminal cursor to column 0 and the
|
|
47
|
+
// remainder renders under the LEFT pane. visibleWidth() counts \n as an
|
|
48
|
+
// ordinary character, so the short-line early-return below would pass a
|
|
49
|
+
// multi-line string through intact — split first, wrap each part.
|
|
50
|
+
if (/[\r\n]/.test(line)) {
|
|
51
|
+
return line.split(/\r\n|\r|\n/).flatMap((part) => wrapLine(part, maxWidth));
|
|
52
|
+
}
|
|
35
53
|
if (maxWidth <= 0)
|
|
36
54
|
return [line];
|
|
37
55
|
const visW = visibleWidth(line);
|
|
@@ -99,8 +117,20 @@ function wrapLine(line, maxWidth) {
|
|
|
99
117
|
lines.push(curLine);
|
|
100
118
|
}
|
|
101
119
|
return lines.length > 0 ? lines : [line];
|
|
102
|
-
}
|
|
120
|
+
}
|
|
121
|
+
/** Last-resort flatten for the pane compose loop: replace any surviving line
|
|
122
|
+
* break with a visible ⏎ so a single corrupted string can't shift the whole
|
|
123
|
+
* row grid. Upstream layers (toDisplayLines at appendTail, wrapLine split)
|
|
124
|
+
* should make this a no-op. */
|
|
125
|
+
function flattenRow(line) {
|
|
126
|
+
return /[\r\n]/.test(line) ? line.replace(/\r\n|\r|\n/g, " ⏎ ") : line;
|
|
127
|
+
}
|
|
128
|
+
// ── Refresh timer ───────────────────────────────────────────────────────────
|
|
103
129
|
const REFRESH_INTERVAL_MS = 1000;
|
|
130
|
+
/** Max rendered rows per log entry when the activity log is clamped. */
|
|
131
|
+
const LOG_CLAMP_ROWS = 2;
|
|
132
|
+
/** Max prompt lines shown when expanded but not in full mode (ctrl+o). */
|
|
133
|
+
const PROMPT_CLAMP_LINES = 20;
|
|
104
134
|
// ── Controller ──────────────────────────────────────────────────────────────
|
|
105
135
|
export class DashboardController {
|
|
106
136
|
tree;
|
|
@@ -108,8 +138,11 @@ export class DashboardController {
|
|
|
108
138
|
state;
|
|
109
139
|
onInvalidate;
|
|
110
140
|
refreshTimer;
|
|
141
|
+
disposed = false; // IL7: guards interval callbacks after dispose
|
|
142
|
+
readOnly;
|
|
111
143
|
_handlers;
|
|
112
|
-
constructor(tree, initialCursorId) {
|
|
144
|
+
constructor(tree, initialCursorId, opts) {
|
|
145
|
+
this.readOnly = opts?.readOnly ?? false;
|
|
113
146
|
this.tree = tree;
|
|
114
147
|
this.vm = buildViewModel(tree);
|
|
115
148
|
// Default cursor to the first active root, or empty string if tree is empty.
|
|
@@ -119,6 +152,7 @@ export class DashboardController {
|
|
|
119
152
|
expanded: new Set(),
|
|
120
153
|
focusPanel: "tree",
|
|
121
154
|
promptExpanded: false,
|
|
155
|
+
logExpanded: false,
|
|
122
156
|
cancelTargetId: null,
|
|
123
157
|
detailScroll: 0,
|
|
124
158
|
};
|
|
@@ -127,12 +161,14 @@ export class DashboardController {
|
|
|
127
161
|
// On every model event, rebuild VM then invalidate the view.
|
|
128
162
|
const onModelChange = () => {
|
|
129
163
|
this.rebuildViewModel();
|
|
130
|
-
this.
|
|
164
|
+
if (!this.disposed)
|
|
165
|
+
this.onInvalidate?.();
|
|
131
166
|
};
|
|
132
167
|
const onTreeChange = (id) => {
|
|
133
168
|
this.rebuildViewModel();
|
|
134
169
|
this.autoExpandNewNode(id);
|
|
135
|
-
this.
|
|
170
|
+
if (!this.disposed)
|
|
171
|
+
this.onInvalidate?.();
|
|
136
172
|
};
|
|
137
173
|
this.tree.on("change", onModelChange);
|
|
138
174
|
this.tree.on("tail", onModelChange);
|
|
@@ -268,7 +304,15 @@ export class DashboardController {
|
|
|
268
304
|
// Cancel confirmation mode takes priority.
|
|
269
305
|
if (this.state.cancelTargetId) {
|
|
270
306
|
this.handleCancelConfirm(data);
|
|
271
|
-
this.
|
|
307
|
+
if (!this.disposed)
|
|
308
|
+
this.onInvalidate?.();
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
// ctrl+o: toggle activity-log expansion (global — works in both panels).
|
|
312
|
+
if (matchesKey(data, Key.ctrl("o"))) {
|
|
313
|
+
this.state.logExpanded = !this.state.logExpanded;
|
|
314
|
+
if (!this.disposed)
|
|
315
|
+
this.onInvalidate?.();
|
|
272
316
|
return;
|
|
273
317
|
}
|
|
274
318
|
switch (this.state.focusPanel) {
|
|
@@ -279,7 +323,8 @@ export class DashboardController {
|
|
|
279
323
|
this.handleDetailInput(data);
|
|
280
324
|
break;
|
|
281
325
|
}
|
|
282
|
-
this.
|
|
326
|
+
if (!this.disposed)
|
|
327
|
+
this.onInvalidate?.();
|
|
283
328
|
}
|
|
284
329
|
handleTreeInput(data) {
|
|
285
330
|
if (matchesKey(data, Key.up)) {
|
|
@@ -409,7 +454,16 @@ export class DashboardController {
|
|
|
409
454
|
this.state.cursorId = node.parentId;
|
|
410
455
|
}
|
|
411
456
|
}
|
|
457
|
+
/** Replay mode: read-only dashboards (archived trees) never cancel. */
|
|
458
|
+
isReadOnly() {
|
|
459
|
+
return this.readOnly;
|
|
460
|
+
}
|
|
412
461
|
startCancel() {
|
|
462
|
+
// Read-only replay: cancel is meaningless on an archived tree, and
|
|
463
|
+
// cancelNodeAndSessions would touch the LIVE SessionRegistry
|
|
464
|
+
// singleton. Single guard here covers both `x` entry points.
|
|
465
|
+
if (this.readOnly)
|
|
466
|
+
return;
|
|
413
467
|
const node = this.vm.nodes.get(this.state.cursorId);
|
|
414
468
|
if (!node)
|
|
415
469
|
return;
|
|
@@ -478,6 +532,11 @@ export class DashboardController {
|
|
|
478
532
|
if (this.refreshTimer)
|
|
479
533
|
return;
|
|
480
534
|
this.refreshTimer = setInterval(() => {
|
|
535
|
+
// IL7: guard against firing after dispose.
|
|
536
|
+
if (this.disposed) {
|
|
537
|
+
this.stopRefreshTimer();
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
481
540
|
if (!this.hasRunningNodes()) {
|
|
482
541
|
// One last render to settle final frame, then stop timer.
|
|
483
542
|
this.onInvalidate?.();
|
|
@@ -495,6 +554,7 @@ export class DashboardController {
|
|
|
495
554
|
}
|
|
496
555
|
// ── Cleanup ────────────────────────────────────────────────────────────
|
|
497
556
|
dispose() {
|
|
557
|
+
this.disposed = true; // IL7: set before clearing timer so callback sees it
|
|
498
558
|
this.stopRefreshTimer();
|
|
499
559
|
for (const { event, handler } of this._handlers) {
|
|
500
560
|
this.tree.off(event, handler);
|
|
@@ -507,6 +567,10 @@ export class DashboardController {
|
|
|
507
567
|
}
|
|
508
568
|
// ── View ────────────────────────────────────────────────────────────────────
|
|
509
569
|
export class DashboardComponent {
|
|
570
|
+
/** IL3: Focusable — pi sets this to true when the overlay has
|
|
571
|
+
* keyboard focus. Without this, arrow-key and Escape events are
|
|
572
|
+
* swallowed at the overlay layer. (Lesson from config-TUI commit 07e886f.) */
|
|
573
|
+
focused = false;
|
|
510
574
|
controller;
|
|
511
575
|
theme;
|
|
512
576
|
tui;
|
|
@@ -535,7 +599,7 @@ export class DashboardComponent {
|
|
|
535
599
|
// ── Right panel: detail ─────────────────────────────────────────
|
|
536
600
|
const rightLines = selectedNode
|
|
537
601
|
? this.renderDetailPanel(selectedNode, rightWidth)
|
|
538
|
-
: [
|
|
602
|
+
: [dim("Select a node in the tree", this.theme)];
|
|
539
603
|
// ── Compose ─────────────────────────────────────────────────────
|
|
540
604
|
const termHeight = this.tui.terminal.rows;
|
|
541
605
|
// Deduct 3 lines for top border, bottom border, and hints footer
|
|
@@ -563,35 +627,37 @@ export class DashboardComponent {
|
|
|
563
627
|
paddedRightLines.push(rightLines[i + activeScroll] ?? "");
|
|
564
628
|
}
|
|
565
629
|
const lines = [];
|
|
566
|
-
const border = (s) => this.theme.fg("border", s);
|
|
567
|
-
const accent = (s) => this.theme.fg("accent", s);
|
|
568
630
|
// ── Header ──────────────────────────────────────────────────────
|
|
569
631
|
const headerText = ` Orchestrator Dashboard `;
|
|
570
|
-
const headerPad = contentWidth - visibleWidth(border("")) - visibleWidth(
|
|
571
|
-
lines.push(border("╭") +
|
|
572
|
-
|
|
573
|
-
border("─".repeat(Math.max(0, headerPad))) +
|
|
574
|
-
border("╮"));
|
|
632
|
+
const headerPad = contentWidth - visibleWidth(border("", this.theme)) - visibleWidth(accentBold(headerText, this.theme));
|
|
633
|
+
lines.push(border("╭", this.theme) +
|
|
634
|
+
accentBold(headerText, this.theme) +
|
|
635
|
+
border("─".repeat(Math.max(0, headerPad)), this.theme) +
|
|
636
|
+
border("╮", this.theme));
|
|
575
637
|
for (let i = 0; i < contentHeight; i++) {
|
|
576
|
-
|
|
577
|
-
|
|
638
|
+
// Final row-integrity guard: by this point every line has passed
|
|
639
|
+
// wrapLine/truncate, but a stray line break would corrupt the whole
|
|
640
|
+
// row grid — flatten defensively (should never fire).
|
|
641
|
+
const left = truncateToWidth(flattenRow(paddedLeftLines[i]), leftWidth);
|
|
642
|
+
const right = truncateToWidth(flattenRow(paddedRightLines[i]), rightWidth);
|
|
578
643
|
const lPad = leftWidth - visibleWidth(left);
|
|
579
644
|
const rPad = rightWidth - visibleWidth(right);
|
|
580
|
-
lines.push(border("│") +
|
|
645
|
+
lines.push(border("│", this.theme) +
|
|
581
646
|
left +
|
|
582
647
|
" ".repeat(Math.max(0, lPad)) +
|
|
583
|
-
border("│") +
|
|
648
|
+
border("│", this.theme) +
|
|
584
649
|
" " +
|
|
585
650
|
right +
|
|
586
651
|
" ".repeat(Math.max(0, rPad)) +
|
|
587
|
-
border("│"));
|
|
652
|
+
border("│", this.theme));
|
|
588
653
|
}
|
|
589
654
|
// ── Footer: bottom border + key hints + model/token meter ────────
|
|
590
|
-
const dim = (s) => this.theme.fg("dim", s);
|
|
591
655
|
const hintsBase = state.cancelTargetId
|
|
592
656
|
? " y confirm · n dismiss · esc close"
|
|
593
|
-
:
|
|
594
|
-
|
|
657
|
+
: this.controller.isReadOnly()
|
|
658
|
+
? " ↑↓ nav · → expand · ← back · ⏎ focus · ^o log · esc close · replay (read-only)"
|
|
659
|
+
: " ↑↓ nav · → expand · ← back · ⏎ focus · ^o log · x cancel · esc close";
|
|
660
|
+
lines.push(border("╰", this.theme) + border("─".repeat(contentWidth), this.theme) + border("╯", this.theme));
|
|
595
661
|
// Aggregate model + token footer (mirrors ViewportFooterComponent).
|
|
596
662
|
const aggUsage = this.controller.getAggregateUsage();
|
|
597
663
|
const aggCompression = this.controller.getAggregateCompression();
|
|
@@ -603,18 +669,18 @@ export class DashboardComponent {
|
|
|
603
669
|
: (activeModel?.provider ?? activeModel?.model ?? "");
|
|
604
670
|
let footerLine = "";
|
|
605
671
|
if (modelLabel && meter) {
|
|
606
|
-
footerLine = `${hintsBase} ${dim(modelLabel)} Σ ${meter}${compSuffix}`;
|
|
672
|
+
footerLine = `${hintsBase} ${dim(modelLabel, this.theme)} Σ ${meter}${compSuffix}`;
|
|
607
673
|
}
|
|
608
674
|
else if (meter) {
|
|
609
675
|
footerLine = `${hintsBase} Σ ${meter}${compSuffix}`;
|
|
610
676
|
}
|
|
611
677
|
else if (modelLabel) {
|
|
612
|
-
footerLine = `${hintsBase} ${dim(modelLabel)}`;
|
|
678
|
+
footerLine = `${hintsBase} ${dim(modelLabel, this.theme)}`;
|
|
613
679
|
}
|
|
614
680
|
else {
|
|
615
681
|
footerLine = hintsBase;
|
|
616
682
|
}
|
|
617
|
-
lines.push(dim(truncateToWidth(footerLine, width)));
|
|
683
|
+
lines.push(dim(truncateToWidth(footerLine, width), this.theme));
|
|
618
684
|
// ── Overlay cancel confirmation on top of dashboard content ────
|
|
619
685
|
if (state.cancelTargetId) {
|
|
620
686
|
return this.overlayCancelConfirm(lines, width, state.cancelTargetId);
|
|
@@ -641,11 +707,11 @@ export class DashboardComponent {
|
|
|
641
707
|
// ── Tree panel renderer ─────────────────────────────────────────────────
|
|
642
708
|
renderTreePanel(visibleIds, state, width) {
|
|
643
709
|
if (visibleIds.length === 0) {
|
|
644
|
-
return [
|
|
710
|
+
return [dim("No session running", this.theme)];
|
|
645
711
|
}
|
|
646
712
|
const lines = [];
|
|
647
713
|
// Header
|
|
648
|
-
lines.push(
|
|
714
|
+
lines.push(accentBold(" Phases", this.theme));
|
|
649
715
|
for (const id of visibleIds) {
|
|
650
716
|
const node = this.controller.getNode(id);
|
|
651
717
|
if (!node)
|
|
@@ -653,110 +719,110 @@ export class DashboardComponent {
|
|
|
653
719
|
const isCursor = id === state.cursorId;
|
|
654
720
|
const depth = node.depth;
|
|
655
721
|
const indent = " ".repeat(depth * 2);
|
|
722
|
+
// IL1: themed cursor and glyphs — no raw characters.
|
|
723
|
+
const cursorChar = cursor(isCursor, this.theme);
|
|
656
724
|
// Status glyph
|
|
657
|
-
const glyph =
|
|
725
|
+
const glyph = nodeGlyph(node.status, this.theme);
|
|
658
726
|
// Progress label for orchestrators
|
|
659
727
|
let label = node.label;
|
|
660
728
|
if (node.kind === "orchestrator") {
|
|
661
729
|
const prog = this.controller.getSubtreeProgress(id);
|
|
662
730
|
label += ` ${prog.completed}/${prog.total}`;
|
|
663
731
|
}
|
|
664
|
-
// Expand indicator
|
|
732
|
+
// Expand/collapse indicator — themed
|
|
665
733
|
const expandIndicator = node.kind === "orchestrator"
|
|
666
734
|
? state.expanded.has(id)
|
|
667
735
|
? " "
|
|
668
|
-
:
|
|
736
|
+
: collapseIndicator(this.theme)
|
|
669
737
|
: " ";
|
|
670
738
|
// Combine
|
|
671
|
-
const prefix = `${indent}${
|
|
739
|
+
const prefix = `${indent}${cursorChar} ${glyph} ${expandIndicator} `;
|
|
672
740
|
const styled = isCursor
|
|
673
741
|
? this.theme.bold(this.theme.fg("accent", `${prefix}${label}`))
|
|
674
742
|
: `${prefix}${label}`;
|
|
675
743
|
lines.push(truncateToWidth(styled, width));
|
|
676
744
|
}
|
|
677
|
-
|
|
745
|
+
// IL2: dual-layer width safety — first guard in screen renderer.
|
|
746
|
+
return truncateLines(lines, width);
|
|
678
747
|
}
|
|
679
|
-
nodeGlyph(node) {
|
|
680
|
-
switch (node.status) {
|
|
681
|
-
case "completed":
|
|
682
|
-
return this.theme.fg("success", "✔");
|
|
683
|
-
case "running":
|
|
684
|
-
return this.theme.fg("accent", "●");
|
|
685
|
-
case "cancelling":
|
|
686
|
-
return this.theme.fg("warning", "⏳");
|
|
687
|
-
case "cancelled":
|
|
688
|
-
return this.theme.fg("muted", "⊘");
|
|
689
|
-
case "failed":
|
|
690
|
-
return this.theme.fg("error", "✗");
|
|
691
|
-
case "escalated":
|
|
692
|
-
return this.theme.fg("error", "▲");
|
|
693
|
-
case "pending":
|
|
694
|
-
default:
|
|
695
|
-
return this.theme.fg("dim", "○");
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
// ── Detail panel renderer ────────────────────────────────────────────────
|
|
699
748
|
renderDetailPanel(node, width) {
|
|
700
749
|
const lines = [];
|
|
701
|
-
const dim = (s) => this.theme.fg("dim", s);
|
|
702
|
-
const accent = (s) => this.theme.fg("accent", s);
|
|
703
|
-
const bold = (s) => this.theme.bold(s);
|
|
704
|
-
const success = (s) => this.theme.fg("success", s);
|
|
705
|
-
const warn = (s) => this.theme.fg("warning", s);
|
|
706
750
|
// ── Header: label + status (wrap long model strings) ──────────────────
|
|
707
|
-
const
|
|
751
|
+
const statusLabelStr = statusLabel(node.status);
|
|
708
752
|
const modelPart = node.model ? ` · ${node.provider ?? ""} ${node.model}` : "";
|
|
709
|
-
lines.push(...wrapLine(`${
|
|
753
|
+
lines.push(...wrapLine(`${nodeGlyph(node.status, this.theme)} ${bold(statusLabelStr, this.theme)}${dim(modelPart, this.theme)}`, width));
|
|
710
754
|
// ── Metrics line ────────────────────────────────────────────────
|
|
711
755
|
const metrics = this.formatMetrics(node);
|
|
712
756
|
if (metrics)
|
|
713
|
-
lines.push(...wrapLine(dim(metrics), width));
|
|
757
|
+
lines.push(...wrapLine(dim(metrics, this.theme), width));
|
|
714
758
|
lines.push("");
|
|
715
759
|
// ── Orchestrator node: list children ─────────────────────────────
|
|
716
760
|
if (node.kind === "orchestrator" && node.children.length > 0) {
|
|
717
761
|
const children = this.controller.getChildren(node.id);
|
|
718
|
-
lines.push(...wrapLine(dim(bold(`Agents · ${children.length}
|
|
762
|
+
lines.push(...wrapLine(dim(bold(`Agents · ${children.length}`, this.theme), this.theme), width));
|
|
719
763
|
for (const child of children) {
|
|
720
|
-
const cglyph =
|
|
764
|
+
const cglyph = nodeGlyph(child.status, this.theme);
|
|
721
765
|
const cmodel = child.model ? ` ${child.provider ?? ""} ${child.model}` : "";
|
|
722
766
|
const cmetrics = this.formatMetrics(child);
|
|
723
767
|
const cmetricsPart = cmetrics ? ` ${cmetrics}` : "";
|
|
724
|
-
lines.push(...wrapLine(` ${cglyph} ${child.label}${dim(cmodel)}${dim(cmetricsPart)}`, width));
|
|
768
|
+
lines.push(...wrapLine(` ${cglyph} ${child.label}${dim(cmodel, this.theme)}${dim(cmetricsPart, this.theme)}`, width));
|
|
725
769
|
}
|
|
726
770
|
lines.push("");
|
|
727
771
|
}
|
|
728
|
-
// ── Prompt preview (
|
|
772
|
+
// ── Prompt preview (⏎ open/close, ctrl+o lifts the line cap) ────
|
|
773
|
+
// Model stores the full body (storage-capped only); the view owns
|
|
774
|
+
// clamping: ⏎ toggles the section, the clamp shows PROMPT_CLAMP_LINES,
|
|
775
|
+
// and ctrl+o (the global full-content toggle) reveals everything.
|
|
729
776
|
if (node.promptPreview) {
|
|
730
|
-
const
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
777
|
+
const st = this.controller.getState();
|
|
778
|
+
const expandIcon = promptExpandIcon(st.promptExpanded, this.theme);
|
|
779
|
+
const promptLines = toDisplayLines(node.promptPreview);
|
|
780
|
+
const lineCount = promptLines.length;
|
|
781
|
+
const hint = st.promptExpanded ? (st.logExpanded ? "⏎ collapse · ^o clamp" : "⏎ collapse · ^o full") : "⏎ expand";
|
|
782
|
+
lines.push(...wrapLine(dim(`${expandIcon} Prompt · ${lineCount} lines · ${hint}`, this.theme), width));
|
|
783
|
+
if (st.promptExpanded) {
|
|
784
|
+
const cap = st.logExpanded ? lineCount : PROMPT_CLAMP_LINES;
|
|
785
|
+
for (const pline of promptLines.slice(0, cap)) {
|
|
735
786
|
// Indent wrapped prompt lines by 2 spaces
|
|
736
787
|
const wrapped = wrapLine(pline, Math.max(0, width - 4));
|
|
737
788
|
for (let i = 0; i < wrapped.length; i++) {
|
|
738
|
-
lines.push(dim(i === 0 ? ` ${wrapped[i]}` : ` ${wrapped[i]}
|
|
789
|
+
lines.push(dim(i === 0 ? ` ${wrapped[i]}` : ` ${wrapped[i]}`, this.theme));
|
|
739
790
|
}
|
|
740
791
|
}
|
|
741
|
-
if (lineCount >
|
|
742
|
-
lines.push(dim(` … ${lineCount -
|
|
792
|
+
if (lineCount > cap) {
|
|
793
|
+
lines.push(dim(` … ${lineCount - cap} more lines · ^o expand`, this.theme));
|
|
743
794
|
}
|
|
744
795
|
}
|
|
745
796
|
lines.push("");
|
|
746
797
|
}
|
|
747
|
-
// ── Activity: running
|
|
798
|
+
// ── Activity: running log of all turns ───────────────────────────
|
|
799
|
+
// Entries are stored verbatim in the model (full commands, full
|
|
800
|
+
// errors, newlines and all); ALL display normalization happens here:
|
|
801
|
+
// toDisplayLines splits/sanitizes, wrapLine fits the pane width, and
|
|
802
|
+
// long entries clamp to LOG_CLAMP_ROWS unless expanded (ctrl+o).
|
|
748
803
|
if (node.kind === "leaf" && node.tailBuffer.length > 0) {
|
|
804
|
+
const expanded = this.controller.getState().logExpanded;
|
|
749
805
|
const total = node.tailBuffer.length;
|
|
750
|
-
|
|
806
|
+
const modeHint = expanded ? "^o clamp" : "^o expand";
|
|
807
|
+
lines.push(...wrapLine(dim(`Activity · ${total} log entr${total === 1 ? "y" : "ies"} · ${modeHint}`, this.theme), width));
|
|
751
808
|
for (const tline of node.tailBuffer) {
|
|
752
|
-
const
|
|
753
|
-
|
|
809
|
+
const rows = [];
|
|
810
|
+
for (const displayLine of toDisplayLines(tline)) {
|
|
811
|
+
rows.push(...wrapLine(paintTailLine(displayLine, this.theme), width));
|
|
812
|
+
}
|
|
813
|
+
if (expanded || rows.length <= LOG_CLAMP_ROWS) {
|
|
814
|
+
lines.push(...rows);
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
lines.push(...rows.slice(0, LOG_CLAMP_ROWS));
|
|
818
|
+
lines.push(dim(` …(+${rows.length - LOG_CLAMP_ROWS} rows · ^o expand)`, this.theme));
|
|
819
|
+
}
|
|
754
820
|
}
|
|
755
821
|
lines.push("");
|
|
756
822
|
}
|
|
757
823
|
// ── Outcome ─────────────────────────────────────────────────────
|
|
758
824
|
if (node.outcomePreview) {
|
|
759
|
-
lines.push(dim("Outcome"));
|
|
825
|
+
lines.push(dim("Outcome", this.theme));
|
|
760
826
|
for (const oline of node.outcomePreview.split("\n").slice(0, 8)) {
|
|
761
827
|
const wrapped = wrapLine(oline, Math.max(0, width - 4));
|
|
762
828
|
for (const wl of wrapped) {
|
|
@@ -765,10 +831,11 @@ export class DashboardComponent {
|
|
|
765
831
|
}
|
|
766
832
|
const lineCount = node.outcomePreview.split("\n").length;
|
|
767
833
|
if (lineCount > 8) {
|
|
768
|
-
lines.push(dim(` … ${lineCount - 8} more lines
|
|
834
|
+
lines.push(dim(` … ${lineCount - 8} more lines`, this.theme));
|
|
769
835
|
}
|
|
770
836
|
}
|
|
771
|
-
|
|
837
|
+
// IL2: dual-layer width safety — first guard in screen renderer.
|
|
838
|
+
return truncateLines(lines, width);
|
|
772
839
|
}
|
|
773
840
|
/** Render a cancel-confirmation dialog overlaid on the dashboard.
|
|
774
841
|
* The dashboard content stays visible above and below the dialog.
|
|
@@ -781,34 +848,30 @@ export class DashboardComponent {
|
|
|
781
848
|
overlayCancelConfirm(baseLines, width, targetId) {
|
|
782
849
|
const node = this.controller.getNode(targetId);
|
|
783
850
|
const label = node?.label ?? targetId;
|
|
784
|
-
const dim = (s) => this.theme.fg("dim", s);
|
|
785
|
-
const warn = (s) => this.theme.fg("warning", s);
|
|
786
|
-
const bold = (s) => this.theme.bold(s);
|
|
787
|
-
const brd = (s) => this.theme.fg("border", s);
|
|
788
851
|
// Content width is the full width minus the two outer │ borders.
|
|
789
852
|
const contentWidth = width - 2;
|
|
790
853
|
// Build the dialog box (narrower than the full content area so it
|
|
791
854
|
// floats with padding on each side).
|
|
792
855
|
const dialogW = Math.min(contentWidth, 60);
|
|
793
856
|
const diagLines = [];
|
|
794
|
-
const prompt = warn(`⚠ Cancel ${bold(label)}
|
|
795
|
-
const actions = dim("y confirm · n dismiss · esc close");
|
|
857
|
+
const prompt = warn(`⚠ Cancel ${bold(label, this.theme)}?`, this.theme);
|
|
858
|
+
const actions = dim("y confirm · n dismiss · esc close", this.theme);
|
|
796
859
|
const promptW = visibleWidth(prompt);
|
|
797
860
|
const actionsW = visibleWidth(actions);
|
|
798
|
-
diagLines.push(
|
|
799
|
-
diagLines.push(
|
|
861
|
+
diagLines.push(border("╭", this.theme) + border("─".repeat(dialogW - 2), this.theme) + border("╮", this.theme));
|
|
862
|
+
diagLines.push(border("│", this.theme) + " ".repeat(dialogW - 2) + border("│", this.theme));
|
|
800
863
|
{
|
|
801
864
|
// Place prompt and actions side by side when they fit; stack otherwise.
|
|
802
865
|
const sideBySide = promptW + actionsW + 4 <= dialogW - 2;
|
|
803
866
|
if (sideBySide) {
|
|
804
867
|
const contentGap = Math.max(1, dialogW - 4 - promptW - actionsW);
|
|
805
|
-
const contentLine =
|
|
868
|
+
const contentLine = border("│", this.theme) + " " + prompt + " ".repeat(contentGap) + actions + " " + border("│", this.theme);
|
|
806
869
|
if (visibleWidth(contentLine) < dialogW) {
|
|
807
870
|
// Pad content line to full dialog width.
|
|
808
871
|
const pad = dialogW - 2 - visibleWidth(contentLine.slice(1, -1));
|
|
809
|
-
diagLines.push(
|
|
872
|
+
diagLines.push(border("│", this.theme) +
|
|
810
873
|
" " + prompt + " ".repeat(contentGap + Math.max(0, pad)) + actions +
|
|
811
|
-
" " +
|
|
874
|
+
" " + border("│", this.theme));
|
|
812
875
|
}
|
|
813
876
|
else {
|
|
814
877
|
diagLines.push(contentLine);
|
|
@@ -817,13 +880,13 @@ export class DashboardComponent {
|
|
|
817
880
|
else {
|
|
818
881
|
// Stacked: prompt on one line, actions on the next.
|
|
819
882
|
const promptPad = Math.max(0, dialogW - 2 - 1 - promptW - 1);
|
|
820
|
-
diagLines.push(
|
|
883
|
+
diagLines.push(border("│", this.theme) + " " + prompt + " ".repeat(promptPad) + border("│", this.theme));
|
|
821
884
|
const actionsPad = Math.max(0, dialogW - 2 - 1 - actionsW - 1);
|
|
822
|
-
diagLines.push(
|
|
885
|
+
diagLines.push(border("│", this.theme) + " " + actions + " ".repeat(actionsPad) + border("│", this.theme));
|
|
823
886
|
}
|
|
824
887
|
}
|
|
825
|
-
diagLines.push(
|
|
826
|
-
diagLines.push(
|
|
888
|
+
diagLines.push(border("│", this.theme) + " ".repeat(dialogW - 2) + border("│", this.theme));
|
|
889
|
+
diagLines.push(border("╰", this.theme) + border("─".repeat(dialogW - 2), this.theme) + border("╯", this.theme));
|
|
827
890
|
// Center the dialog vertically within the content rows and
|
|
828
891
|
// horizontally within the content area, preserving the outer │
|
|
829
892
|
// borders on every row so the frame stays intact.
|
|
@@ -838,28 +901,10 @@ export class DashboardComponent {
|
|
|
838
901
|
const rightPad = Math.max(0, contentWidth - leftPad - diagVisW);
|
|
839
902
|
// Preserve the outer │ borders: left border + centered dialog + right border.
|
|
840
903
|
result[startRow + i] =
|
|
841
|
-
|
|
904
|
+
border("│", this.theme) + " ".repeat(leftPad) + diagLine + " ".repeat(rightPad) + border("│", this.theme);
|
|
842
905
|
}
|
|
843
906
|
return result;
|
|
844
907
|
}
|
|
845
|
-
statusLabel(status) {
|
|
846
|
-
switch (status) {
|
|
847
|
-
case "completed":
|
|
848
|
-
return "Completed";
|
|
849
|
-
case "running":
|
|
850
|
-
return "Running";
|
|
851
|
-
case "cancelling":
|
|
852
|
-
return "Cancelling…";
|
|
853
|
-
case "cancelled":
|
|
854
|
-
return "Cancelled";
|
|
855
|
-
case "failed":
|
|
856
|
-
return "Failed";
|
|
857
|
-
case "escalated":
|
|
858
|
-
return "Escalated";
|
|
859
|
-
case "pending":
|
|
860
|
-
return "Pending";
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
908
|
formatMetrics(node) {
|
|
864
909
|
const parts = [];
|
|
865
910
|
if (node.usage.input || node.usage.output || node.usage.cacheRead) {
|