@tacuchi/agent-workflow-cli 25.8.0 → 26.0.0
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 +106 -0
- package/README.md +6 -3
- package/dist/adapters/git-cli.js +225 -17
- package/dist/adapters/git-cli.js.map +1 -1
- package/dist/adapters/node-file-system.js +48 -0
- package/dist/adapters/node-file-system.js.map +1 -1
- package/dist/application/amend-service.js +51 -14
- package/dist/application/amend-service.js.map +1 -1
- package/dist/application/branch-resolver.js +6 -3
- package/dist/application/branch-resolver.js.map +1 -1
- package/dist/application/capability/design-handler.js +218 -43
- package/dist/application/capability/design-handler.js.map +1 -1
- package/dist/application/capability/dispatcher.js +182 -19
- package/dist/application/capability/dispatcher.js.map +1 -1
- package/dist/application/capability/durable-effect.js +3 -0
- package/dist/application/capability/durable-effect.js.map +1 -1
- package/dist/application/capability/readiness.js +8 -54
- package/dist/application/capability/readiness.js.map +1 -1
- package/dist/application/capability/resolution.js +124 -192
- package/dist/application/capability/resolution.js.map +1 -1
- package/dist/application/check-branch-service.js +158 -19
- package/dist/application/check-branch-service.js.map +1 -1
- package/dist/application/checkpoint/markdown.js +2 -2
- package/dist/application/checkpoint/markdown.js.map +1 -1
- package/dist/application/checkpoint/state-reader.js +12 -0
- package/dist/application/checkpoint/state-reader.js.map +1 -1
- package/dist/application/checkpoint-service.js +12 -4
- package/dist/application/checkpoint-service.js.map +1 -1
- package/dist/application/checkpoint-write-service.js +91 -17
- package/dist/application/checkpoint-write-service.js.map +1 -1
- package/dist/application/claims-ledger.js +137 -11
- package/dist/application/claims-ledger.js.map +1 -1
- package/dist/application/claims-recovery.js +85 -44
- package/dist/application/claims-recovery.js.map +1 -1
- package/dist/application/database-tool-catalog.js +33 -0
- package/dist/application/database-tool-catalog.js.map +1 -1
- package/dist/application/design/consumer-document.js +2 -2
- package/dist/application/design/consumer-document.js.map +1 -1
- package/dist/application/design/design-content-gate-service.js +20 -2
- package/dist/application/design/design-content-gate-service.js.map +1 -1
- package/dist/application/design/design-gate-service.js +2 -0
- package/dist/application/design/design-gate-service.js.map +1 -1
- package/dist/application/design/design-index-service.js +4 -0
- package/dist/application/design/design-index-service.js.map +1 -1
- package/dist/application/design/design-publish-service.js +1 -4
- package/dist/application/design/design-publish-service.js.map +1 -1
- package/dist/application/design/design-record-service.js +13 -7
- package/dist/application/design/design-record-service.js.map +1 -1
- package/dist/application/design/design-resolver-service.js +22 -3
- package/dist/application/design/design-resolver-service.js.map +1 -1
- package/dist/application/design/design-simple-service.js +24 -5
- package/dist/application/design/design-simple-service.js.map +1 -1
- package/dist/application/design/digest.js +41 -0
- package/dist/application/design/digest.js.map +1 -0
- package/dist/application/dev-only-services.js +166 -20
- package/dist/application/dev-only-services.js.map +1 -1
- package/dist/application/doc-branch-ledger.js +145 -0
- package/dist/application/doc-branch-ledger.js.map +1 -0
- package/dist/application/docs-canon-service.js +1 -1
- package/dist/application/docs-canon-service.js.map +1 -1
- package/dist/application/doctor/dist-integrity.js +113 -0
- package/dist/application/doctor/dist-integrity.js.map +1 -0
- package/dist/application/doctor/hosts.js +5 -2
- package/dist/application/doctor/hosts.js.map +1 -1
- package/dist/application/doctor/prepare.js +3 -3
- package/dist/application/doctor/prepare.js.map +1 -1
- package/dist/application/doctor/provider-installation.js +39 -19
- package/dist/application/doctor/provider-installation.js.map +1 -1
- package/dist/application/doctor/provider-mcps.js +9 -1
- package/dist/application/doctor/provider-mcps.js.map +1 -1
- package/dist/application/doctor/provider-skills.js +29 -115
- package/dist/application/doctor/provider-skills.js.map +1 -1
- package/dist/application/doctor/provider-visibility.js +76 -3
- package/dist/application/doctor/provider-visibility.js.map +1 -1
- package/dist/application/doctor/provider-workspace-block.js +156 -0
- package/dist/application/doctor/provider-workspace-block.js.map +1 -0
- package/dist/application/doctor/repair-runner.js +36 -39
- package/dist/application/doctor/repair-runner.js.map +1 -1
- package/dist/application/doctor/report.js +24 -4
- package/dist/application/doctor/report.js.map +1 -1
- package/dist/application/export-catalog-check.js +200 -0
- package/dist/application/export-catalog-check.js.map +1 -0
- package/dist/application/export-service.js +716 -79
- package/dist/application/export-service.js.map +1 -1
- package/dist/application/fix-git-service.js +285 -64
- package/dist/application/fix-git-service.js.map +1 -1
- package/dist/application/flow/advance.js +202 -25
- package/dist/application/flow/advance.js.map +1 -1
- package/dist/application/flow/annul-service.js +3 -1
- package/dist/application/flow/annul-service.js.map +1 -1
- package/dist/application/flow/batch-commit.js +189 -0
- package/dist/application/flow/batch-commit.js.map +1 -0
- package/dist/application/flow/checkout-observation.js +63 -10
- package/dist/application/flow/checkout-observation.js.map +1 -1
- package/dist/application/flow/close-artifacts.js +105 -0
- package/dist/application/flow/close-artifacts.js.map +1 -0
- package/dist/application/flow/close-at-boundary.js +25 -14
- package/dist/application/flow/close-at-boundary.js.map +1 -1
- package/dist/application/flow/close-document-guidance.js +70 -0
- package/dist/application/flow/close-document-guidance.js.map +1 -0
- package/dist/application/flow/flow-service.js +46 -3
- package/dist/application/flow/flow-service.js.map +1 -1
- package/dist/application/flow/internal-actions.js +300 -82
- package/dist/application/flow/internal-actions.js.map +1 -1
- package/dist/application/flow/internal-drive.js +24 -1
- package/dist/application/flow/internal-drive.js.map +1 -1
- package/dist/application/flow/plan-entry.js +82 -0
- package/dist/application/flow/plan-entry.js.map +1 -0
- package/dist/application/flow/prove.js +32 -1
- package/dist/application/flow/prove.js.map +1 -1
- package/dist/application/flow/quick-checkouts.js +48 -0
- package/dist/application/flow/quick-checkouts.js.map +1 -0
- package/dist/application/flow/reinfer-batch.js +177 -0
- package/dist/application/flow/reinfer-batch.js.map +1 -0
- package/dist/application/flow/reopen-run.js +12 -5
- package/dist/application/flow/reopen-run.js.map +1 -1
- package/dist/application/flow/run-state-service.js +2 -0
- package/dist/application/flow/run-state-service.js.map +1 -1
- package/dist/application/flow/submit.js +584 -117
- package/dist/application/flow/submit.js.map +1 -1
- package/dist/application/generate-launch-service.js +16 -6
- package/dist/application/generate-launch-service.js.map +1 -1
- package/dist/application/git-flow-service.js +34 -3
- package/dist/application/git-flow-service.js.map +1 -1
- package/dist/application/history-publications.js +24 -0
- package/dist/application/history-publications.js.map +1 -1
- package/dist/application/history-reconcile-service.js +45 -0
- package/dist/application/history-reconcile-service.js.map +1 -0
- package/dist/application/history-table.js +61 -12
- package/dist/application/history-table.js.map +1 -1
- package/dist/application/history-update-service.js +25 -4
- package/dist/application/history-update-service.js.map +1 -1
- package/dist/application/hook-branch-check.js +25 -3
- package/dist/application/hook-branch-check.js.map +1 -1
- package/dist/application/hook-git-commit-advisor.js +3 -4
- package/dist/application/hook-git-commit-advisor.js.map +1 -1
- package/dist/application/hook-turn-start.js +51 -0
- package/dist/application/hook-turn-start.js.map +1 -0
- package/dist/application/host-memory/codex.js +1 -1
- package/dist/application/host-memory/codex.js.map +1 -1
- package/dist/application/hub-registry.js +135 -0
- package/dist/application/hub-registry.js.map +1 -0
- package/dist/application/local-proposal.js +72 -19
- package/dist/application/local-proposal.js.map +1 -1
- package/dist/application/mcp-host-reader.js +1 -1
- package/dist/application/mcp-host-reader.js.map +1 -1
- package/dist/application/mcp-host-writer.js +16 -10
- package/dist/application/mcp-host-writer.js.map +1 -1
- package/dist/application/merge-state-service.js +150 -34
- package/dist/application/merge-state-service.js.map +1 -1
- package/dist/application/multiroot/claude.js +17 -10
- package/dist/application/multiroot/claude.js.map +1 -1
- package/dist/application/multiroot/codex.js +17 -11
- package/dist/application/multiroot/codex.js.map +1 -1
- package/dist/application/multiroot-service.js +52 -28
- package/dist/application/multiroot-service.js.map +1 -1
- package/dist/application/parsers/execution-batches.js +64 -0
- package/dist/application/parsers/execution-batches.js.map +1 -0
- package/dist/application/parsers/phases.js +23 -2
- package/dist/application/parsers/phases.js.map +1 -1
- package/dist/application/parsers/project-block.js +146 -17
- package/dist/application/parsers/project-block.js.map +1 -1
- package/dist/application/parsers/tasks.js +16 -2
- package/dist/application/parsers/tasks.js.map +1 -1
- package/dist/application/parsers/toml.js +19 -0
- package/dist/application/parsers/toml.js.map +1 -0
- package/dist/application/paths-service.js +13 -16
- package/dist/application/paths-service.js.map +1 -1
- package/dist/application/persist-service.js +118 -5
- package/dist/application/persist-service.js.map +1 -1
- package/dist/application/plan-exec-batch-service.js +162 -22
- package/dist/application/plan-exec-batch-service.js.map +1 -1
- package/dist/application/plan-exec-decision-service.js +61 -12
- package/dist/application/plan-exec-decision-service.js.map +1 -1
- package/dist/application/plan-exec-plan-diff.js +105 -0
- package/dist/application/plan-exec-plan-diff.js.map +1 -0
- package/dist/application/plan-lint-service.js +33 -5
- package/dist/application/plan-lint-service.js.map +1 -1
- package/dist/application/plan-passes.js +41 -0
- package/dist/application/plan-passes.js.map +1 -0
- package/dist/application/preparation-receipts.js +58 -0
- package/dist/application/preparation-receipts.js.map +1 -0
- package/dist/application/project-md-upsert-service.js +191 -52
- package/dist/application/project-md-upsert-service.js.map +1 -1
- package/dist/application/project-tab-data.js +40 -10
- package/dist/application/project-tab-data.js.map +1 -1
- package/dist/application/release-data/artifacts.js +15 -7
- package/dist/application/release-data/artifacts.js.map +1 -1
- package/dist/application/release-data/bundles.js +52 -6
- package/dist/application/release-data/bundles.js.map +1 -1
- package/dist/application/release-data/common.js +2 -2
- package/dist/application/release-data/common.js.map +1 -1
- package/dist/application/release-data/rollback.js +7 -0
- package/dist/application/release-data/rollback.js.map +1 -0
- package/dist/application/release-data/sessions.js +2 -2
- package/dist/application/release-data/sessions.js.map +1 -1
- package/dist/application/release-pass-ledger.js +1 -1
- package/dist/application/render/history-row.js +2 -0
- package/dist/application/render/history-row.js.map +1 -1
- package/dist/application/render/project-block.js +28 -11
- package/dist/application/render/project-block.js.map +1 -1
- package/dist/application/reseal-service.js +1 -0
- package/dist/application/reseal-service.js.map +1 -1
- package/dist/application/resume-service.js +55 -8
- package/dist/application/resume-service.js.map +1 -1
- package/dist/application/retirement/apply.js +25 -7
- package/dist/application/retirement/apply.js.map +1 -1
- package/dist/application/retirement/attribution.js +122 -50
- package/dist/application/retirement/attribution.js.map +1 -1
- package/dist/application/retirement/prepare.js +17 -11
- package/dist/application/retirement/prepare.js.map +1 -1
- package/dist/application/retirement/preview.js +2 -1
- package/dist/application/retirement/preview.js.map +1 -1
- package/dist/application/self/clean-legacy.js +1 -2
- package/dist/application/self/clean-legacy.js.map +1 -1
- package/dist/application/self/codex-plugin.js +1 -1
- package/dist/application/self/codex-plugin.js.map +1 -1
- package/dist/application/self/host-states.js +3 -3
- package/dist/application/self/host-states.js.map +1 -1
- package/dist/application/self/install-hooks.js +1 -1
- package/dist/application/self/install-hooks.js.map +1 -1
- package/dist/application/self/install-skill.js +5 -49
- package/dist/application/self/install-skill.js.map +1 -1
- package/dist/application/self/mcp-config.js +19 -11
- package/dist/application/self/mcp-config.js.map +1 -1
- package/dist/application/self/opencode-plugin.js +1 -0
- package/dist/application/self/opencode-plugin.js.map +1 -1
- package/dist/application/self/skill-files.js +29 -0
- package/dist/application/self/skill-files.js.map +1 -0
- package/dist/application/self/uninstall.js +1 -1
- package/dist/application/self/uninstall.js.map +1 -1
- package/dist/application/semantic-operation/protocol.js +66 -5
- package/dist/application/semantic-operation/protocol.js.map +1 -1
- package/dist/application/session-archive-service.js +113 -0
- package/dist/application/session-archive-service.js.map +1 -0
- package/dist/application/session-binding-service.js +35 -0
- package/dist/application/session-binding-service.js.map +1 -1
- package/dist/application/session-close-service.js +390 -54
- package/dist/application/session-close-service.js.map +1 -1
- package/dist/application/session-create-service.js +97 -5
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/session-custody-recorder.js +15 -12
- package/dist/application/session-custody-recorder.js.map +1 -1
- package/dist/application/session-custody-service.js +1 -0
- package/dist/application/session-custody-service.js.map +1 -1
- package/dist/application/session-narrative.js +42 -12
- package/dist/application/session-narrative.js.map +1 -1
- package/dist/application/session-pause-service.js +46 -0
- package/dist/application/session-pause-service.js.map +1 -0
- package/dist/application/session-resolver.js +36 -11
- package/dist/application/session-resolver.js.map +1 -1
- package/dist/application/session-resume-service.js +134 -13
- package/dist/application/session-resume-service.js.map +1 -1
- package/dist/application/sessions-service.js +4 -0
- package/dist/application/sessions-service.js.map +1 -1
- package/dist/application/sessions-sweep-service.js +77 -0
- package/dist/application/sessions-sweep-service.js.map +1 -0
- package/dist/application/settle-service.js +3 -1
- package/dist/application/settle-service.js.map +1 -1
- package/dist/application/skills-resolver-service.js +6 -92
- package/dist/application/skills-resolver-service.js.map +1 -1
- package/dist/application/source-add-service.js +37 -0
- package/dist/application/source-add-service.js.map +1 -0
- package/dist/application/source-boundary-policy.js +105 -8
- package/dist/application/source-boundary-policy.js.map +1 -1
- package/dist/application/source-pipeline.js +68 -0
- package/dist/application/source-pipeline.js.map +1 -0
- package/dist/application/source-remove-service.js +15 -3
- package/dist/application/source-remove-service.js.map +1 -1
- package/dist/application/sources-service.js +71 -16
- package/dist/application/sources-service.js.map +1 -1
- package/dist/application/status-service.js +55 -5
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/unit-dependencies.js +100 -0
- package/dist/application/unit-dependencies.js.map +1 -0
- package/dist/application/unit-membership.js +37 -0
- package/dist/application/unit-membership.js.map +1 -0
- package/dist/application/unit-residue.js +72 -0
- package/dist/application/unit-residue.js.map +1 -0
- package/dist/application/visibility-doctor-service.js +66 -4
- package/dist/application/visibility-doctor-service.js.map +1 -1
- package/dist/application/working-branch-service.js +6 -0
- package/dist/application/working-branch-service.js.map +1 -1
- package/dist/application/workline-graph.js +1 -1
- package/dist/application/workline-graph.js.map +1 -1
- package/dist/application/workline-index-service.js +118 -17
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/application/workspace-commit-service.js +218 -0
- package/dist/application/workspace-commit-service.js.map +1 -0
- package/dist/application/workspace-init-service.js +64 -34
- package/dist/application/workspace-init-service.js.map +1 -1
- package/dist/application/workspace-local-config.js +90 -0
- package/dist/application/workspace-local-config.js.map +1 -0
- package/dist/application/workspace-materialization-service.js +52 -3
- package/dist/application/workspace-materialization-service.js.map +1 -1
- package/dist/application/workspace-migrate/apply.js +525 -4
- package/dist/application/workspace-migrate/apply.js.map +1 -1
- package/dist/application/workspace-migrate/markers.js +9 -6
- package/dist/application/workspace-migrate/markers.js.map +1 -1
- package/dist/application/workspace-migrate/plan.js +97 -5
- package/dist/application/workspace-migrate/plan.js.map +1 -1
- package/dist/application/workspace-move-service.js +270 -0
- package/dist/application/workspace-move-service.js.map +1 -0
- package/dist/application/workspace-untrack-service.js +28 -0
- package/dist/application/workspace-untrack-service.js.map +1 -0
- package/dist/application/worktree-service.js +654 -105
- package/dist/application/worktree-service.js.map +1 -1
- package/dist/cli/ascii.js +2 -0
- package/dist/cli/ascii.js.map +1 -1
- package/dist/cli/commands/add-source.js +38 -0
- package/dist/cli/commands/add-source.js.map +1 -0
- package/dist/cli/commands/amend.js +14 -3
- package/dist/cli/commands/amend.js.map +1 -1
- package/dist/cli/commands/capability.js +23 -4
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/designs.js +14 -5
- package/dist/cli/commands/designs.js.map +1 -1
- package/dist/cli/commands/dev-only.js +19 -6
- package/dist/cli/commands/dev-only.js.map +1 -1
- package/dist/cli/commands/doc-branch.js +184 -0
- package/dist/cli/commands/doc-branch.js.map +1 -0
- package/dist/cli/commands/doctor.js +5 -1
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/export.js +78 -18
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/fix-git.js +89 -14
- package/dist/cli/commands/fix-git.js.map +1 -1
- package/dist/cli/commands/flow.js +120 -15
- package/dist/cli/commands/flow.js.map +1 -1
- package/dist/cli/commands/generate-launch.js +14 -2
- package/dist/cli/commands/generate-launch.js.map +1 -1
- package/dist/cli/commands/history-update.js +1 -1
- package/dist/cli/commands/history-update.js.map +1 -1
- package/dist/cli/commands/history.js +14 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/hook.js +15 -2
- package/dist/cli/commands/hook.js.map +1 -1
- package/dist/cli/commands/index.js +18 -5
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/merge-state.js +2 -2
- package/dist/cli/commands/merge-state.js.map +1 -1
- package/dist/cli/commands/persist.js +6 -5
- package/dist/cli/commands/persist.js.map +1 -1
- package/dist/cli/commands/project-md-upsert.js +5 -3
- package/dist/cli/commands/project-md-upsert.js.map +1 -1
- package/dist/cli/commands/release-pass.js +3 -3
- package/dist/cli/commands/release-pass.js.map +1 -1
- package/dist/cli/commands/resume.js +12 -3
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/commands/self.js +8 -24
- package/dist/cli/commands/self.js.map +1 -1
- package/dist/cli/commands/session-close.js +64 -9
- package/dist/cli/commands/session-close.js.map +1 -1
- package/dist/cli/commands/session-create.js +4 -2
- package/dist/cli/commands/session-create.js.map +1 -1
- package/dist/cli/commands/session-pause.js +14 -0
- package/dist/cli/commands/session-pause.js.map +1 -0
- package/dist/cli/commands/sessions.js +16 -3
- package/dist/cli/commands/sessions.js.map +1 -1
- package/dist/cli/commands/set-branch.js +28 -4
- package/dist/cli/commands/set-branch.js.map +1 -1
- package/dist/cli/commands/set-edit-mode.js +20 -0
- package/dist/cli/commands/set-edit-mode.js.map +1 -0
- package/dist/cli/commands/set-pipeline.js +35 -0
- package/dist/cli/commands/set-pipeline.js.map +1 -0
- package/dist/cli/commands/skills.js +4 -11
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/sources.js +4 -0
- package/dist/cli/commands/sources.js.map +1 -1
- package/dist/cli/commands/status.js +35 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/unknown-flags.js +1 -0
- package/dist/cli/commands/unknown-flags.js.map +1 -1
- package/dist/cli/commands/visibility.js +1 -0
- package/dist/cli/commands/visibility.js.map +1 -1
- package/dist/cli/commands/workspace-commit.js +62 -0
- package/dist/cli/commands/workspace-commit.js.map +1 -0
- package/dist/cli/commands/workspace-init.js +39 -2
- package/dist/cli/commands/workspace-init.js.map +1 -1
- package/dist/cli/commands/workspace-migrate.js +31 -3
- package/dist/cli/commands/workspace-migrate.js.map +1 -1
- package/dist/cli/commands/workspace-move.js +42 -0
- package/dist/cli/commands/workspace-move.js.map +1 -0
- package/dist/cli/commands/worktree.js +4 -4
- package/dist/cli/commands/worktree.js.map +1 -1
- package/dist/cli/context-id.js +6 -0
- package/dist/cli/context-id.js.map +1 -1
- package/dist/cli/full-cli.js +555 -0
- package/dist/cli/full-cli.js.map +1 -0
- package/dist/cli/help-groups.js +76 -19
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/hook-stdin-cache.js +12 -0
- package/dist/cli/hook-stdin-cache.js.map +1 -0
- package/dist/cli/main.js +47 -453
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/parser.js +4 -0
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/tui/app.js +3 -4
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli/tui/components/host-admin-section.js +2 -13
- package/dist/cli/tui/components/host-admin-section.js.map +1 -1
- package/dist/cli/tui/components/tabs-config.js +1 -2
- package/dist/cli/tui/components/tabs-config.js.map +1 -1
- package/dist/cli/tui/components/workspace-init-form.js +4 -1
- package/dist/cli/tui/components/workspace-init-form.js.map +1 -1
- package/dist/cli/tui/data/workflow-content.js +6 -1
- package/dist/cli/tui/data/workflow-content.js.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab.js +4 -3
- package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
- package/dist/cli/tui/tabs/project-tab.js +7 -2
- package/dist/cli/tui/tabs/project-tab.js.map +1 -1
- package/dist/cli/tui/tui-prefs.js +2 -0
- package/dist/cli/tui/tui-prefs.js.map +1 -1
- package/dist/dist-manifest.json +3973 -0
- package/dist/domain/capability/protocol.js +3 -1
- package/dist/domain/capability/protocol.js.map +1 -1
- package/dist/domain/decision-note.js +13 -0
- package/dist/domain/decision-note.js.map +1 -1
- package/dist/domain/design/artifact.js +22 -3
- package/dist/domain/design/artifact.js.map +1 -1
- package/dist/domain/design/capability.js +1 -0
- package/dist/domain/design/capability.js.map +1 -1
- package/dist/domain/design/expansion.js +1 -1
- package/dist/domain/design/expansion.js.map +1 -1
- package/dist/domain/design/maturity.js +16 -0
- package/dist/domain/design/maturity.js.map +1 -1
- package/dist/domain/design/reference.js +5 -0
- package/dist/domain/design/reference.js.map +1 -1
- package/dist/domain/doctor/operations.js +20 -12
- package/dist/domain/doctor/operations.js.map +1 -1
- package/dist/domain/effective-contract.js +3 -1
- package/dist/domain/effective-contract.js.map +1 -1
- package/dist/domain/elicitation.js +1 -1
- package/dist/domain/flow/answer.js +265 -130
- package/dist/domain/flow/answer.js.map +1 -1
- package/dist/domain/flow/authority.js +194 -37
- package/dist/domain/flow/authority.js.map +1 -1
- package/dist/domain/flow/batch-review.js +65 -0
- package/dist/domain/flow/batch-review.js.map +1 -0
- package/dist/domain/flow/decision-schema.js +47 -0
- package/dist/domain/flow/decision-schema.js.map +1 -0
- package/dist/domain/flow/directive.js +16 -0
- package/dist/domain/flow/directive.js.map +1 -1
- package/dist/domain/flow/execution-result.js +91 -2
- package/dist/domain/flow/execution-result.js.map +1 -1
- package/dist/domain/flow/run-state.js +352 -24
- package/dist/domain/flow/run-state.js.map +1 -1
- package/dist/domain/flow/test-run-evidence.js +285 -0
- package/dist/domain/flow/test-run-evidence.js.map +1 -0
- package/dist/domain/flow/unchanged-phase.js +15 -0
- package/dist/domain/flow/unchanged-phase.js.map +1 -0
- package/dist/domain/harnesses.js +14 -5
- package/dist/domain/harnesses.js.map +1 -1
- package/dist/domain/isolation-unit.js +2 -2
- package/dist/domain/isolation-unit.js.map +1 -1
- package/dist/domain/lineage.js +7 -2
- package/dist/domain/lineage.js.map +1 -1
- package/dist/domain/obligation-correspondence.js +4 -2
- package/dist/domain/obligation-correspondence.js.map +1 -1
- package/dist/domain/plan-handoff.js +5 -0
- package/dist/domain/plan-handoff.js.map +1 -0
- package/dist/domain/proposal.js +18 -7
- package/dist/domain/proposal.js.map +1 -1
- package/dist/domain/reservation.js +5 -3
- package/dist/domain/reservation.js.map +1 -1
- package/dist/domain/retirement/proposal.js +1 -0
- package/dist/domain/retirement/proposal.js.map +1 -1
- package/dist/domain/session/custody.js +10 -6
- package/dist/domain/session/custody.js.map +1 -1
- package/dist/domain/session/narrative.js +4 -1
- package/dist/domain/session/narrative.js.map +1 -1
- package/dist/domain/skills.js +4 -6
- package/dist/domain/skills.js.map +1 -1
- package/dist/domain/sql-lexer.js +1 -1
- package/dist/domain/sql-lexer.js.map +1 -1
- package/dist/runtime/namespace-resolver.js +4 -0
- package/dist/runtime/namespace-resolver.js.map +1 -1
- package/dist/runtime/workline-marker.js +35 -8
- package/dist/runtime/workline-marker.js.map +1 -1
- package/dist/runtime/workspace-resolution.js +123 -0
- package/dist/runtime/workspace-resolution.js.map +1 -0
- package/package.json +6 -5
- package/skills/w/SKILL.md +12 -17
- package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +1 -1
- package/skills/w/artifacts/artifacts-core/SCRIPTS.rollback.sql +8 -0
- package/skills/w/artifacts/artifacts-core/SCRIPTS.sql +4 -8
- package/skills/w/commands/export-diagrams.md +3 -3
- package/skills/w/commands/export-manuals.md +6 -6
- package/skills/w/commands/export-reports.md +3 -3
- package/skills/w/commands/export-scripts.md +5 -5
- package/skills/w/commands/fix-git.md +12 -13
- package/skills/w/commands/persist.md +2 -2
- package/skills/w/commands/plan-exec.md +4 -2
- package/skills/w/commands/spec-new.md +1 -1
- package/skills/w/commands/workspace-init.md +2 -0
- package/skills/w/context/MANIFEST.json +1 -1
- package/skills/w/exports/README.md +4 -4
- package/skills/w/exports/export-diagrams/EXPORT.md +4 -4
- package/skills/w/exports/export-manuals/EXPORT.md +14 -16
- package/skills/w/exports/export-reports/EXPORT.md +3 -3
- package/skills/w/exports/export-scripts/EXPORT.md +46 -22
- package/skills/w/harness/HARNESS.md +4 -7
- package/skills/w/hooks/hooks.template.json +6 -4
- package/skills/w/loops/CHASSIS.md +12 -6
- package/skills/w/loops/CODE-POLICIES.md +8 -5
- package/skills/w/loops/README.md +2 -2
- package/skills/w/loops/plan-exec-loop/LOOP.md +23 -22
- package/skills/w/loops/plan-new-loop/LOOP.md +23 -31
- package/skills/w/loops/plan-refine-loop/LOOP.md +8 -2
- package/skills/w/loops/quick-loop/LOOP.md +7 -6
- package/skills/w/loops/spec-refine-loop/LOOP.md +1 -1
- package/skills/w/modules/DESIGN-REFERENCES.md +9 -11
- package/skills/w/modules/PLAN-EXECUTION-BATCHES.md +4 -4
- package/skills/w/modules/SESSION-NUMBERING.md +2 -0
- package/skills/w/roles/README.md +11 -47
- package/skills/w/roles/design/CONTRACT.md +6 -4
- package/skills/w/roles/design/ROLE.md +7 -3
- package/skills/w/roles/diagrams/ROLE.md +1 -1
- package/skills/w/roles/git/ROLE.md +17 -10
- package/skills/w/roles/research/ROLE.md +2 -2
- package/skills/w/roles/sql/ROLE.md +17 -15
- package/skills/w/schemas/design/ui-screen.v1.schema.json +9 -0
- package/dist/application/capability/descriptor-loader.js +0 -109
- package/dist/application/capability/descriptor-loader.js.map +0 -1
- package/dist/application/capability/installed-inventory.js +0 -168
- package/dist/application/capability/installed-inventory.js.map +0 -1
- package/dist/application/self/install-plugin-skills-git.js +0 -226
- package/dist/application/self/install-plugin-skills-git.js.map +0 -1
- package/dist/application/self/install-plugin-skills.js +0 -203
- package/dist/application/self/install-plugin-skills.js.map +0 -1
- package/dist/application/self/plugin-cache-clear.js +0 -133
- package/dist/application/self/plugin-cache-clear.js.map +0 -1
- package/dist/application/self/plugin-cache-reload.js +0 -141
- package/dist/application/self/plugin-cache-reload.js.map +0 -1
- package/dist/application/self/skills-apply.js +0 -623
- package/dist/application/self/skills-apply.js.map +0 -1
- package/dist/application/self/skills-catalog.js +0 -35
- package/dist/application/self/skills-catalog.js.map +0 -1
- package/dist/application/self/skills-change.js +0 -479
- package/dist/application/self/skills-change.js.map +0 -1
- package/dist/application/self/skills-discovery.js +0 -275
- package/dist/application/self/skills-discovery.js.map +0 -1
- package/dist/application/self/skills-manager.js +0 -253
- package/dist/application/self/skills-manager.js.map +0 -1
- package/dist/application/self/skills-payload.js +0 -566
- package/dist/application/self/skills-payload.js.map +0 -1
- package/dist/application/self/skills-registry.js +0 -107
- package/dist/application/self/skills-registry.js.map +0 -1
- package/dist/application/skill-index-service.js +0 -78
- package/dist/application/skill-index-service.js.map +0 -1
- package/dist/cli/commands/plugin-cache.js +0 -25
- package/dist/cli/commands/plugin-cache.js.map +0 -1
- package/dist/cli/commands/skill-index.js +0 -19
- package/dist/cli/commands/skill-index.js.map +0 -1
- package/dist/cli/tui/data/recommended-skills.js +0 -482
- package/dist/cli/tui/data/recommended-skills.js.map +0 -1
- package/dist/cli/tui/tabs/skills-tab.js +0 -664
- package/dist/cli/tui/tabs/skills-tab.js.map +0 -1
|
@@ -1,664 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// [Skills] — external-skills manager (skills.sh model): one list with badges
|
|
3
|
-
// (installed → unmanaged → registered → recommended), a detail that states
|
|
4
|
-
// INSTALLATION and RECOMMENDATION as separate facts, and one journey for every
|
|
5
|
-
// change: selection → preview → applying → result
|
|
6
|
-
// (DES-001@r7 / SCR-001@r3).
|
|
7
|
-
//
|
|
8
|
-
// Since Spec 043 there is no shortcut that mutates: every action prepares a
|
|
9
|
-
// proposal, the preview shows the WHOLE set with its destinations, `Back` is
|
|
10
|
-
// where the focus starts, and `Apply` sends that proposal's own digest as the
|
|
11
|
-
// approval. The result is a view — per destination, with its verification
|
|
12
|
-
// separate — and not a toast that scrolls a partial failure away.
|
|
13
|
-
//
|
|
14
|
-
// The list opens PROJECTED to the recommended catalog and `t` toggles to every
|
|
15
|
-
// detected skill (SPEC 019) — a view mode, not a second data source.
|
|
16
|
-
// Backed by skills-manager (reads), skills-change (prepare) and skills-apply
|
|
17
|
-
// (apply/recover); the `w` bundle administration lives in [Workline].
|
|
18
|
-
import { Box, Text, useInput, useStdout } from "ink";
|
|
19
|
-
import { useCallback, useMemo, useRef, useState } from "react";
|
|
20
|
-
import { formatTuiEvent } from "../../../application/logging/log-events.js";
|
|
21
|
-
import { applySkillChange, readSkillJournal, recoverSkillJournal, } from "../../../application/self/skills-apply.js";
|
|
22
|
-
import { prepareSkillChange, } from "../../../application/self/skills-change.js";
|
|
23
|
-
import { REPLICA_HOST_KEYS, REPLICA_HOST_LABELS, canonicalSkillsRoot, listSkills, resolveSkillSource, } from "../../../application/self/skills-manager.js";
|
|
24
|
-
import { ConfirmBanner } from "../components/confirm-banner.js";
|
|
25
|
-
import { DetailPanel } from "../components/detail-panel.js";
|
|
26
|
-
import { InputPrompt } from "../components/input-prompt.js";
|
|
27
|
-
import { ListRow } from "../components/list-row.js";
|
|
28
|
-
import { notificationStackRows } from "../components/notification-stack.js";
|
|
29
|
-
import { PageHead } from "../components/page-head.js";
|
|
30
|
-
import { QuickActions } from "../components/quick-actions.js";
|
|
31
|
-
import { SectionHead } from "../components/section-head.js";
|
|
32
|
-
import { RECOMMENDED_SKILLS, SKILL_CATALOG } from "../data/recommended-skills.js";
|
|
33
|
-
import { useLockWhile } from "../input-lock.js";
|
|
34
|
-
import { useNotificationItems } from "../notification-center.js";
|
|
35
|
-
import { rowWidth } from "../row-width.js";
|
|
36
|
-
import { colors, icons } from "../theme.js";
|
|
37
|
-
import { useListDetailKeys } from "../use-list-detail-keys.js";
|
|
38
|
-
import { useListWindow, windowRangeHint } from "../use-list-window.js";
|
|
39
|
-
import { useOnMount } from "../use-on-mount.js";
|
|
40
|
-
const REPLICA_LABELS = REPLICA_HOST_LABELS.join(", ");
|
|
41
|
-
// Rows the chrome consumes around the skills list; the window (useListWindow)
|
|
42
|
-
// gets what remains of the viewport:
|
|
43
|
-
// app shell 16 = ScreenFrame border+paddingY 4 · HomeHeader 3 (2 rows +
|
|
44
|
-
// marginBottom) · TabBar 3 (border + row) · tab content box
|
|
45
|
-
// border+paddingY 4 · HomeFooter 2 (marginTop + row)
|
|
46
|
-
// this tab 6 = PageHead 2 (row + marginBottom) · SectionHead 1 ·
|
|
47
|
-
// QuickActions 3 (marginTop + rule + keys)
|
|
48
|
-
const SKILLS_LIST_RESERVED_ROWS = 22;
|
|
49
|
-
// The `filtered` mode's projection: the names of the HABITUAL set, whatever
|
|
50
|
-
// their status — a withdrawn entry leaves it and stays reachable under `all`.
|
|
51
|
-
const RECOMMENDED_NAMES = new Set(RECOMMENDED_SKILLS.map((s) => s.name));
|
|
52
|
-
// What `Recommendation` reads for each verdict, and which ones earn a badge in
|
|
53
|
-
// the list: `keep`/`conditional` are the ordinary cases and stay quiet, while
|
|
54
|
-
// the three that ask for a decision are visible without opening the detail.
|
|
55
|
-
const DISPOSITION_LABEL = {
|
|
56
|
-
keep: "keep",
|
|
57
|
-
conditional: "conditional",
|
|
58
|
-
repair: "repair/replace",
|
|
59
|
-
candidate: "candidate",
|
|
60
|
-
withdrawn: "withdrawn",
|
|
61
|
-
};
|
|
62
|
-
const BADGED_DISPOSITIONS = {
|
|
63
|
-
repair: "warn",
|
|
64
|
-
candidate: "info",
|
|
65
|
-
withdrawn: "warn",
|
|
66
|
-
};
|
|
67
|
-
// Said, never inferred: a field the review did not record is unknown, and
|
|
68
|
-
// unknown is not "compatible".
|
|
69
|
-
const UNKNOWN = "unknown";
|
|
70
|
-
/** Rows visible in the current mode: the whole list, or just the habitual set's. */
|
|
71
|
-
function projectSkills(all, showAll) {
|
|
72
|
-
return showAll ? all : all.filter((s) => RECOMMENDED_NAMES.has(s.name));
|
|
73
|
-
}
|
|
74
|
-
const STATUS_GLYPH = {
|
|
75
|
-
installed: { glyph: "◆", active: true, tone: "ok" },
|
|
76
|
-
unmanaged: { glyph: "◈", active: true, tone: "warn" },
|
|
77
|
-
registered: { glyph: "◇", active: false, tone: "dim" },
|
|
78
|
-
recommended: { glyph: "·", active: false, tone: "info" },
|
|
79
|
-
};
|
|
80
|
-
/** The colour each per-destination status reads in: `applied` is the only one
|
|
81
|
-
* that means "done", and `failed` must never look like it. */
|
|
82
|
-
const RESULT_COLOR = {
|
|
83
|
-
applied: colors.ok,
|
|
84
|
-
pending: colors.warn,
|
|
85
|
-
failed: colors.err,
|
|
86
|
-
unchanged: colors.dim,
|
|
87
|
-
restored: colors.accent,
|
|
88
|
-
};
|
|
89
|
-
export function SkillsTab({ ctx, isActive, onToast }) {
|
|
90
|
-
const [items, setItems] = useState([]);
|
|
91
|
-
const [mode, setMode] = useState({ kind: "list" });
|
|
92
|
-
// View mode, local and unpersisted: every mount opens on the catalog (SPEC 019).
|
|
93
|
-
const [showAll, setShowAll] = useState(false);
|
|
94
|
-
const visibleRef = useRef([]);
|
|
95
|
-
const { stdout } = useStdout();
|
|
96
|
-
const visible = useMemo(() => projectSkills(items, showAll), [items, showAll]);
|
|
97
|
-
visibleRef.current = visible;
|
|
98
|
-
useLockWhile(mode.kind !== "list" && mode.kind !== "detail");
|
|
99
|
-
const actionsLenRef = useRef(0);
|
|
100
|
-
const { cursor, setCursor, actionCursor } = useListDetailKeys({
|
|
101
|
-
isActive,
|
|
102
|
-
phase: mode.kind === "list" || mode.kind === "detail"
|
|
103
|
-
? mode.kind
|
|
104
|
-
: mode.kind === "confirm"
|
|
105
|
-
? "confirm"
|
|
106
|
-
: "off",
|
|
107
|
-
listLen: visible.length,
|
|
108
|
-
actionsLen: actionsLenRef.current,
|
|
109
|
-
onAdd: () => setMode({
|
|
110
|
-
kind: "wizard-source",
|
|
111
|
-
intent: { operation: "install", source: "", withdraw: [] },
|
|
112
|
-
}),
|
|
113
|
-
onOpenDetail: () => setMode({ kind: "detail" }),
|
|
114
|
-
onCloseDetail: () => setMode({ kind: "list" }),
|
|
115
|
-
onRunAction: (i) => {
|
|
116
|
-
const entry = detailActions[i];
|
|
117
|
-
if (entry)
|
|
118
|
-
triggerAction(entry.id);
|
|
119
|
-
},
|
|
120
|
-
onConfirm: (yes) => {
|
|
121
|
-
if (mode.kind !== "confirm" || !current)
|
|
122
|
-
return;
|
|
123
|
-
if (!yes)
|
|
124
|
-
return setMode({ kind: "detail" });
|
|
125
|
-
void prepare({ operation: mode.action, name: current.name }, `preparing ${mode.action} of ${current.name}…`);
|
|
126
|
-
},
|
|
127
|
-
});
|
|
128
|
-
const notifItems = useNotificationItems();
|
|
129
|
-
const listWindow = useListWindow(visible.length, cursor, SKILLS_LIST_RESERVED_ROWS + notificationStackRows(notifItems));
|
|
130
|
-
const reanchorCursor = useCallback((next) => {
|
|
131
|
-
setCursor((c) => {
|
|
132
|
-
const prevName = visibleRef.current[c]?.name;
|
|
133
|
-
const idx = prevName === undefined ? -1 : next.findIndex((s) => s.name === prevName);
|
|
134
|
-
return idx >= 0 ? idx : Math.min(Math.max(0, c), Math.max(0, next.length - 1));
|
|
135
|
-
});
|
|
136
|
-
}, [setCursor]);
|
|
137
|
-
const refresh = useCallback(async () => {
|
|
138
|
-
try {
|
|
139
|
-
const next = await listSkills(ctx, SKILL_CATALOG);
|
|
140
|
-
reanchorCursor(projectSkills(next, showAll));
|
|
141
|
-
setItems(next);
|
|
142
|
-
}
|
|
143
|
-
catch (err) {
|
|
144
|
-
onToast?.({ tone: "err", title: "Error loading skills", body: err.message });
|
|
145
|
-
}
|
|
146
|
-
}, [ctx, onToast, reanchorCursor, showAll]);
|
|
147
|
-
// On mount the tab also asks whether a previous run left an operation
|
|
148
|
-
// half-applied: finding it is what makes the journal worth writing.
|
|
149
|
-
useOnMount(() => {
|
|
150
|
-
void (async () => {
|
|
151
|
-
await refresh();
|
|
152
|
-
const journal = await readSkillJournal(ctx);
|
|
153
|
-
if (journal !== null)
|
|
154
|
-
setMode({ kind: "recovery", journal, cursor: 0 });
|
|
155
|
-
})();
|
|
156
|
-
});
|
|
157
|
-
const current = visible[cursor] ?? null;
|
|
158
|
-
const installedCount = items.filter((s) => s.status === "installed").length;
|
|
159
|
-
const unmanagedCount = items.filter((s) => s.status === "unmanaged").length;
|
|
160
|
-
const registeredCount = items.filter((s) => s.status === "registered").length;
|
|
161
|
-
const recommendedCount = items.filter((s) => s.status === "recommended").length;
|
|
162
|
-
/**
|
|
163
|
-
* Prepares a change and shows its preview. Nothing is applied here: this is
|
|
164
|
-
* the only door to a mutation, and it opens onto a preview.
|
|
165
|
-
*/
|
|
166
|
-
const prepare = useCallback(async (request, label, intent) => {
|
|
167
|
-
setMode({ kind: "busy", label });
|
|
168
|
-
try {
|
|
169
|
-
const outcome = await prepareSkillChange(ctx, request);
|
|
170
|
-
if (outcome.status === "rejected") {
|
|
171
|
-
onToast?.({
|
|
172
|
-
tone: "err",
|
|
173
|
-
title: "Change refused",
|
|
174
|
-
body: `${outcome.rejection.code}: ${outcome.rejection.message}`,
|
|
175
|
-
});
|
|
176
|
-
setMode({ kind: "list" });
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
if (outcome.status === "needs-choice") {
|
|
180
|
-
setMode({
|
|
181
|
-
kind: "selection",
|
|
182
|
-
intent: intent ?? {
|
|
183
|
-
operation: "install",
|
|
184
|
-
source: request.source ?? "",
|
|
185
|
-
withdraw: request.withdraw ?? [],
|
|
186
|
-
},
|
|
187
|
-
inventory: outcome.inventory,
|
|
188
|
-
candidates: outcome.candidates,
|
|
189
|
-
chosen: [],
|
|
190
|
-
cursor: 0,
|
|
191
|
-
note: null,
|
|
192
|
-
});
|
|
193
|
-
await outcome.release();
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
if (outcome.status === "needs-expansion") {
|
|
197
|
-
await outcome.release();
|
|
198
|
-
setMode(expansionSelection(request, outcome.expansions, intent));
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
setMode({
|
|
202
|
-
kind: "preview",
|
|
203
|
-
prepared: { proposal: outcome.proposal, release: outcome.release },
|
|
204
|
-
// `Back` is where the focus starts: Apply is an explicit move.
|
|
205
|
-
cursor: 0,
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
catch (err) {
|
|
209
|
-
onToast?.({ tone: "err", title: "Error", body: err.message });
|
|
210
|
-
setMode({ kind: "list" });
|
|
211
|
-
}
|
|
212
|
-
}, [ctx, onToast]);
|
|
213
|
-
/** Re-opens the selection with the expansion the payload requires. */
|
|
214
|
-
const expansionSelection = useCallback((request, expansions, intent) => {
|
|
215
|
-
const chosen = [...(request.paths ?? [])];
|
|
216
|
-
const candidates = expansions.map((expansion) => ({
|
|
217
|
-
path: expansion.path,
|
|
218
|
-
name: expansion.name,
|
|
219
|
-
directory: expansion.path.split("/").pop() ?? expansion.name,
|
|
220
|
-
}));
|
|
221
|
-
return {
|
|
222
|
-
kind: "selection",
|
|
223
|
-
intent: intent ?? {
|
|
224
|
-
operation: request.operation,
|
|
225
|
-
source: request.source ?? "",
|
|
226
|
-
withdraw: request.withdraw ?? [],
|
|
227
|
-
},
|
|
228
|
-
inventory: {
|
|
229
|
-
source: request.source ?? "",
|
|
230
|
-
kind: "git",
|
|
231
|
-
requestedRef: null,
|
|
232
|
-
resolvedRef: null,
|
|
233
|
-
candidates,
|
|
234
|
-
truncated: false,
|
|
235
|
-
limits: null,
|
|
236
|
-
},
|
|
237
|
-
candidates,
|
|
238
|
-
chosen,
|
|
239
|
-
cursor: 0,
|
|
240
|
-
note: expansions.map((expansion) => expansion.reason).join(" · "),
|
|
241
|
-
};
|
|
242
|
-
}, []);
|
|
243
|
-
const applyPrepared = useCallback(async (prepared) => {
|
|
244
|
-
setMode({ kind: "applying", label: `applying ${prepared.proposal.operation}…` });
|
|
245
|
-
try {
|
|
246
|
-
const outcome = await applySkillChange(ctx, prepared.proposal, prepared.proposal.digest);
|
|
247
|
-
if (outcome.status === "refused") {
|
|
248
|
-
onToast?.({
|
|
249
|
-
tone: "err",
|
|
250
|
-
title: "Apply refused",
|
|
251
|
-
body: `${outcome.refusal.code}: ${outcome.refusal.message}`,
|
|
252
|
-
});
|
|
253
|
-
setMode({ kind: "list" });
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
void ctx.logger?.info(formatTuiEvent(`skills ${prepared.proposal.operation}`, "ok"));
|
|
257
|
-
setMode({ kind: "result", result: outcome.result });
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
catch (err) {
|
|
261
|
-
onToast?.({ tone: "err", title: "Error", body: err.message });
|
|
262
|
-
setMode({ kind: "list" });
|
|
263
|
-
}
|
|
264
|
-
finally {
|
|
265
|
-
await prepared.release();
|
|
266
|
-
await refresh();
|
|
267
|
-
}
|
|
268
|
-
}, [ctx, onToast, refresh]);
|
|
269
|
-
// Detail actions per status. `unmanaged` (outside the registry) is not
|
|
270
|
-
// operable: the ownership guard rejects it, so the row is informational.
|
|
271
|
-
const detailActions = useMemo(() => {
|
|
272
|
-
if (!current || current.status === "unmanaged")
|
|
273
|
-
return [];
|
|
274
|
-
if (current.status === "recommended" || current.status === "registered") {
|
|
275
|
-
const entries = [
|
|
276
|
-
{
|
|
277
|
-
id: "install",
|
|
278
|
-
action: {
|
|
279
|
-
name: "Install",
|
|
280
|
-
description: `Prepare, preview, then materialize (canonical + ${REPLICA_LABELS}).`,
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
];
|
|
284
|
-
if (current.status === "registered") {
|
|
285
|
-
entries.push({
|
|
286
|
-
id: "remove",
|
|
287
|
-
action: { name: "Remove", description: "Drop from the registry.", danger: true },
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
return entries;
|
|
291
|
-
}
|
|
292
|
-
const resolved = resolveSkillSource(current.source, current.ref);
|
|
293
|
-
const gitSource = !("error" in resolved) && resolved.kind === "git";
|
|
294
|
-
const proposed = current.curation?.proposedSource;
|
|
295
|
-
return [
|
|
296
|
-
...(gitSource
|
|
297
|
-
? [
|
|
298
|
-
{
|
|
299
|
-
id: "update",
|
|
300
|
-
action: { name: "Update", description: "Re-fetch the registered ref." },
|
|
301
|
-
},
|
|
302
|
-
]
|
|
303
|
-
: []),
|
|
304
|
-
...(proposed !== undefined
|
|
305
|
-
? [
|
|
306
|
-
{
|
|
307
|
-
id: "replace",
|
|
308
|
-
action: {
|
|
309
|
-
name: "Change source",
|
|
310
|
-
description: `Prepare from ${proposed} and show the differences.`,
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
]
|
|
314
|
-
: []),
|
|
315
|
-
{
|
|
316
|
-
id: "repair",
|
|
317
|
-
action: { name: "Repair", description: "Rebuild the host replicas from the canonical." },
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
id: "uninstall",
|
|
321
|
-
action: {
|
|
322
|
-
name: "Uninstall",
|
|
323
|
-
description: "Delete canonical + replicas; keeps the registration.",
|
|
324
|
-
danger: true,
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
id: "remove",
|
|
329
|
-
action: {
|
|
330
|
-
name: "Remove",
|
|
331
|
-
description: "Uninstall + drop from the registry.",
|
|
332
|
-
danger: true,
|
|
333
|
-
},
|
|
334
|
-
},
|
|
335
|
-
];
|
|
336
|
-
}, [current]);
|
|
337
|
-
actionsLenRef.current = detailActions.length;
|
|
338
|
-
const triggerAction = useCallback((id) => {
|
|
339
|
-
if (!current)
|
|
340
|
-
return;
|
|
341
|
-
if (id === "uninstall" || id === "remove") {
|
|
342
|
-
setMode({ kind: "confirm", action: id });
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
const request = acquiringRequest(id, current);
|
|
346
|
-
if (request === null)
|
|
347
|
-
return;
|
|
348
|
-
void prepare(request, `preparing ${id} of ${current.name}…`, request.operation === "replace" && request.source !== undefined
|
|
349
|
-
? { operation: "replace", source: request.source, withdraw: [current.name] }
|
|
350
|
-
: undefined);
|
|
351
|
-
}, [current, prepare]);
|
|
352
|
-
// input — `t` toggles the list mode (catalog only ↔ every detected skill).
|
|
353
|
-
useInput((input) => {
|
|
354
|
-
if (!isActive || (mode.kind !== "list" && mode.kind !== "detail"))
|
|
355
|
-
return;
|
|
356
|
-
if (input !== "t" && input !== "T")
|
|
357
|
-
return;
|
|
358
|
-
reanchorCursor(projectSkills(items, !showAll));
|
|
359
|
-
setShowAll((v) => !v);
|
|
360
|
-
}, { isActive });
|
|
361
|
-
// input — the source prompt
|
|
362
|
-
useInput((_input, key) => {
|
|
363
|
-
if (!isActive || mode.kind !== "wizard-source")
|
|
364
|
-
return;
|
|
365
|
-
if (key.escape)
|
|
366
|
-
setMode({ kind: "list" });
|
|
367
|
-
}, { isActive });
|
|
368
|
-
// input — selection (↑↓ · space toggles · ⏎ continue · esc cancel)
|
|
369
|
-
useInput((input, key) => {
|
|
370
|
-
if (!isActive || mode.kind !== "selection")
|
|
371
|
-
return;
|
|
372
|
-
if (key.return) {
|
|
373
|
-
// An empty set keeps the selection with its explanation: continuing
|
|
374
|
-
// with nothing chosen would prepare a proposal about nothing.
|
|
375
|
-
if (mode.chosen.length === 0) {
|
|
376
|
-
return void setMode({ ...mode, note: "Choose at least one skill with [space]." });
|
|
377
|
-
}
|
|
378
|
-
void prepare({
|
|
379
|
-
operation: mode.intent.operation,
|
|
380
|
-
source: mode.intent.source,
|
|
381
|
-
paths: mode.chosen,
|
|
382
|
-
...(mode.intent.withdraw.length > 0 ? { withdraw: mode.intent.withdraw } : {}),
|
|
383
|
-
}, `preparing ${mode.chosen.length} skill(s)…`, mode.intent);
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
const next = selectionAfterKey(mode, input, key);
|
|
387
|
-
if (next !== null)
|
|
388
|
-
setMode(next);
|
|
389
|
-
}, { isActive });
|
|
390
|
-
// input — preview (↑↓ Back/Apply · ⏎ run the focused one · esc back)
|
|
391
|
-
useInput((_input, key) => {
|
|
392
|
-
if (!isActive || mode.kind !== "preview")
|
|
393
|
-
return;
|
|
394
|
-
if (key.escape) {
|
|
395
|
-
void mode.prepared.release();
|
|
396
|
-
return void setMode({ kind: "list" });
|
|
397
|
-
}
|
|
398
|
-
if (key.upArrow)
|
|
399
|
-
return void setMode({ ...mode, cursor: 0 });
|
|
400
|
-
if (key.downArrow)
|
|
401
|
-
return void setMode({ ...mode, cursor: 1 });
|
|
402
|
-
if (key.return) {
|
|
403
|
-
if (mode.cursor === 0) {
|
|
404
|
-
void mode.prepared.release();
|
|
405
|
-
setMode({ kind: "list" });
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
void applyPrepared(mode.prepared);
|
|
409
|
-
}
|
|
410
|
-
}, { isActive });
|
|
411
|
-
// input — result: any of the two obvious keys returns to the list
|
|
412
|
-
useInput((_input, key) => {
|
|
413
|
-
if (!isActive || mode.kind !== "result")
|
|
414
|
-
return;
|
|
415
|
-
if (key.escape || key.return)
|
|
416
|
-
setMode({ kind: "list" });
|
|
417
|
-
}, { isActive });
|
|
418
|
-
// input — recovery. A screen with no way out is a trap: `esc` leaves the
|
|
419
|
-
// journal pending and the offer comes back next time the tab opens. What it
|
|
420
|
-
// must never do is let the tab be used as if nothing were unfinished —
|
|
421
|
-
// hence the explicit note on the panel.
|
|
422
|
-
useInput((input, key) => {
|
|
423
|
-
if (!isActive || mode.kind !== "recovery")
|
|
424
|
-
return;
|
|
425
|
-
if (key.escape)
|
|
426
|
-
return void setMode({ kind: "list" });
|
|
427
|
-
if (key.upArrow)
|
|
428
|
-
return void setMode({ ...mode, cursor: 0 });
|
|
429
|
-
if (key.downArrow)
|
|
430
|
-
return void setMode({ ...mode, cursor: 1 });
|
|
431
|
-
const choice = recoveryChoice(input, key.return, mode.cursor);
|
|
432
|
-
if (choice !== null)
|
|
433
|
-
void resolveJournal(choice);
|
|
434
|
-
}, { isActive });
|
|
435
|
-
const resolveJournal = useCallback(async (choice) => {
|
|
436
|
-
setMode({ kind: "applying", label: `resolving the pending operation (${choice})…` });
|
|
437
|
-
try {
|
|
438
|
-
const outcome = await recoverSkillJournal(ctx, choice);
|
|
439
|
-
if (outcome.status === "refused") {
|
|
440
|
-
onToast?.({
|
|
441
|
-
tone: "err",
|
|
442
|
-
title: "Recovery refused",
|
|
443
|
-
body: `${outcome.refusal.code}: ${outcome.refusal.message}`,
|
|
444
|
-
});
|
|
445
|
-
setMode({ kind: "list" });
|
|
446
|
-
}
|
|
447
|
-
else {
|
|
448
|
-
setMode({ kind: "result", result: outcome.result });
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
catch (err) {
|
|
452
|
-
onToast?.({ tone: "err", title: "Error", body: err.message });
|
|
453
|
-
setMode({ kind: "list" });
|
|
454
|
-
}
|
|
455
|
-
finally {
|
|
456
|
-
await refresh();
|
|
457
|
-
}
|
|
458
|
-
}, [ctx, onToast, refresh]);
|
|
459
|
-
const overlayVisible = mode.kind !== "list";
|
|
460
|
-
const home = ctx.env.homeDir();
|
|
461
|
-
const listRangeHint = windowRangeHint(listWindow, visible.length);
|
|
462
|
-
const modeHint = showAll ? "all skills · t show recommended" : "recommended only · t show all";
|
|
463
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(PageHead, { title: "Skills", count: {
|
|
464
|
-
label: `${installedCount} installed${unmanagedCount > 0 ? ` · ${unmanagedCount} unmanaged` : ""} · ${registeredCount} registered · ${recommendedCount} recommended`,
|
|
465
|
-
tone: installedCount > 0 ? "accent" : "warn",
|
|
466
|
-
}, action: _jsx(Text, { color: colors.mute, children: "~/.agents/skills + host replicas" }) }), _jsx(SectionHead, { label: "Skills", count: visible.length, hint: listRangeHint ?? modeHint, ...(mode.kind === "wizard-source" || mode.kind === "selection"
|
|
467
|
-
? { rightAction: "esc cancel" }
|
|
468
|
-
: mode.kind === "detail" || mode.kind === "confirm"
|
|
469
|
-
? { rightAction: "esc to close detail" }
|
|
470
|
-
: {}), marginTop: 0 }), _jsxs(Box, { flexDirection: "row", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingRight: 2, children: [visible.slice(listWindow.start, listWindow.start + listWindow.visible).map((s, i) => {
|
|
471
|
-
const glyph = STATUS_GLYPH[s.status];
|
|
472
|
-
return (_jsx(ListRow, { icon: glyph.glyph, iconActive: glyph.active, title: s.name, subtitle: s.status === "unmanaged" && s.source === ""
|
|
473
|
-
? "outside the registry"
|
|
474
|
-
: `${s.source}${s.ref ? ` #${s.ref}` : ""}`, meta: rowMeta(s), state: { label: s.status, tone: glyph.tone }, chevron: true, active: listWindow.start + i === cursor, dimmed: overlayVisible && mode.kind !== "detail" && mode.kind !== "confirm", widthHint: rowWidth(stdout?.columns, overlayVisible) }, s.name));
|
|
475
|
-
}), mode.kind === "wizard-source" ? (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(SectionHead, { label: "Add skill", hint: "Step 1 \u00B7 Source", rightAction: "\u23CE inspect \u00B7 esc cancel" }), _jsx(Box, { marginLeft: 2, children: _jsx(InputPrompt, { message: "source (owner/repo \u00B7 git URL \u00B7 absolute path):", onSubmit: (value) => {
|
|
476
|
-
const source = value.trim();
|
|
477
|
-
if (!source) {
|
|
478
|
-
setMode({ kind: "list" });
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
void prepare({ operation: "install", source }, "inspecting source…", {
|
|
482
|
-
...mode.intent,
|
|
483
|
-
source,
|
|
484
|
-
});
|
|
485
|
-
}, isActive: isActive }) })] })) : null, mode.kind === "selection" ? (_jsx(SelectionPanel, { mode: mode, columns: stdout?.columns })) : null, mode.kind === "preview" ? (_jsx(PreviewPanel, { proposal: mode.prepared.proposal, cursor: mode.cursor, home: home })) : null, mode.kind === "result" ? _jsx(ResultPanel, { result: mode.result, home: home }) : null, mode.kind === "recovery" ? (_jsx(RecoveryPanel, { journal: mode.journal, cursor: mode.cursor })) : null, mode.kind === "busy" || mode.kind === "applying" ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.warn, children: [icons.spinner, " ", mode.label] }) })) : null] }), current && (mode.kind === "detail" || mode.kind === "confirm") ? (_jsx(DetailPanel, { bordered: true, header: { name: current.name, meta: detailMeta(current, home) }, statePill: {
|
|
486
|
-
label: current.status,
|
|
487
|
-
tone: current.status === "installed"
|
|
488
|
-
? "ok"
|
|
489
|
-
: current.status === "unmanaged"
|
|
490
|
-
? "warn"
|
|
491
|
-
: "dim",
|
|
492
|
-
}, actions: detailActions.map((a) => a.action), focusedAction: actionCursor, banner: mode.kind === "confirm" ? (_jsx(ConfirmBanner, { title: `× ${mode.action === "uninstall" ? "Uninstall" : "Remove"} ${current.name}?`, body: mode.action === "uninstall"
|
|
493
|
-
? "Prepares the removal of canonical + replicas; the registration stays. You still approve the preview."
|
|
494
|
-
: "Prepares the removal and drops the registration. You still approve the preview." })) : null })) : null] }), _jsx(Box, { marginTop: 1, children: _jsx(QuickActions, { actions: [
|
|
495
|
-
{ key: "a", label: "add skill" },
|
|
496
|
-
{ key: "t", label: showAll ? "show recommended" : "show all" },
|
|
497
|
-
] }) })] }));
|
|
498
|
-
}
|
|
499
|
-
/** Explicit selection: every eligible skill by name AND location. */
|
|
500
|
-
function SelectionPanel({ mode, columns, }) {
|
|
501
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(SectionHead, { label: "Select skills", hint: `${mode.chosen.length} of ${mode.candidates.length} chosen`, rightAction: "space toggle \u00B7 \u23CE continue \u00B7 esc cancel" }), mode.note !== null ? (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: colors.warn, children: mode.note }) })) : null, mode.inventory.truncated ? (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: colors.warn, children: "The source walk hit its limit: this list is a floor, not every skill." }) })) : null, _jsx(Box, { flexDirection: "column", children: mode.candidates.map((candidate, i) => (_jsx(ListRow, { icon: mode.chosen.includes(candidate.path) ? "◆" : "·", iconActive: mode.chosen.includes(candidate.path), title: candidate.name, subtitle: candidate.path === "" ? "(source root)" : candidate.path, meta: candidate.name === candidate.directory
|
|
502
|
-
? []
|
|
503
|
-
: [{ label: `dir ${candidate.directory}`, tone: "dim" }], state: mode.chosen.includes(candidate.path)
|
|
504
|
-
? { label: "chosen", tone: "ok" }
|
|
505
|
-
: { label: "available", tone: "dim" }, active: mode.cursor === i, widthHint: rowWidth(columns, true) }, candidate.path))) })] }));
|
|
506
|
-
}
|
|
507
|
-
/** The whole change before Apply: set, sources, destinations and effects. */
|
|
508
|
-
function PreviewPanel({ proposal, cursor, home, }) {
|
|
509
|
-
const short = (path) => path.replace(home, "~");
|
|
510
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(SectionHead, { label: `Proposed changes · ${proposal.operation}`, hint: `${proposal.additions.length} added · ${proposal.withdrawals.length} withdrawn`, rightAction: "\u2191\u2193 choose \u00B7 \u23CE run \u00B7 esc back" }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [proposal.additions.map((skill) => (_jsxs(Text, { color: colors.text, children: ["+ ", skill.name, _jsxs(Text, { color: colors.dim, children: [" ", "\u00B7 ", skill.provenance.source, skill.path === "" ? "" : `/${skill.path}`, skill.provenance.resolvedRef === null
|
|
511
|
-
? ""
|
|
512
|
-
: ` @ ${skill.provenance.resolvedRef.slice(0, 12)}`, " · ", skill.files.length, " files", skill.manifests.length > 1 ? ` · ${skill.manifests.length} SKILL.md` : ""] })] }, skill.name))), proposal.withdrawals.map((name) => (_jsxs(Text, { color: colors.warn, children: ["\u2212 ", name, " ", _jsx(Text, { color: colors.dim, children: "\u00B7 managed installation retired" })] }, name))), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: colors.mute, children: "DESTINATIONS" }), proposal.destinations.map((destination) => (_jsxs(Text, { color: colors.dim, children: [destination.action.padEnd(9), " ", destination.host.padEnd(8), " ", short(destination.location), destination.shared ? " · shared" : "", destination.ownership === "foreign" ? " · foreign, preserved" : ""] }, `${destination.host}-${destination.location}`)))] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: colors.mute, children: ["EFFECTS \u00B7 ", proposal.effects.join(", ")] }), proposal.notes.map((note) => (_jsxs(Text, { color: colors.faint, children: ["\u00B7 ", note] }, note)))] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: cursor === 0 ? colors.bright : colors.dim, children: [cursor === 0 ? icons.focusBar : " ", " Back"] }), _jsxs(Text, { color: cursor === 1 ? colors.err : colors.dim, children: [cursor === 1 ? icons.focusBar : " ", " Apply"] })] })] })] }));
|
|
513
|
-
}
|
|
514
|
-
/** Per destination: what happened, and — separately — what was checked. */
|
|
515
|
-
function ResultPanel({ result, home }) {
|
|
516
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(SectionHead, { label: `Result · ${result.operation}`, hint: result.summary, rightAction: "\u23CE back to the list" }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [result.destinations.map((destination) => (_jsxs(Text, { color: colors.dim, children: [_jsx(Text, { color: RESULT_COLOR[destination.status], children: destination.status.padEnd(10) }), destination.host.padEnd(8), " ", destination.location.replace(home, "~"), destination.verification === null
|
|
517
|
-
? " · not checked"
|
|
518
|
-
: ` · ${destination.verification.passed ? "verified" : "CHECK FAILED"}: ${destination.verification.checked.replace(home, "~")}`, destination.detail === undefined ? "" : ` · ${destination.detail}`] }, destination.location))), result.recovery !== null ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.warn, children: result.recovery.action }) })) : null, result.cleanup !== null ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.faint, children: ["Backups pending removal: ", result.cleanup.pending.join(", ")] }) })) : null, _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.faint, children: "Applied is not \"the host loaded it\": what is checked above is the bytes this manager wrote in the locations it manages." }) })] })] }));
|
|
519
|
-
}
|
|
520
|
-
/** An operation a previous run left pending: put it back, or accept and retry. */
|
|
521
|
-
function RecoveryPanel({ journal, cursor }) {
|
|
522
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(SectionHead, { label: "Unfinished operation", hint: `${journal.operation} · ${journal.destinations.length} destination(s)`, rightAction: "\u2191\u2193 choose \u00B7 \u23CE run \u00B7 esc later" }), _jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsx(Text, { color: colors.warn, children: "A previous run did not finish. Its backups are kept, so the previous state can come back." }), journal.destinations.map((destination) => (_jsxs(Text, { color: colors.dim, children: [destination.status.padEnd(10), " ", destination.location] }, destination.location))), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: cursor === 0 ? colors.bright : colors.dim, children: [cursor === 0 ? icons.focusBar : " ", " [r] Restore the previous state"] }), _jsxs(Text, { color: cursor === 1 ? colors.bright : colors.dim, children: [cursor === 1 ? icons.focusBar : " ", " [k] Keep the current state and start over"] })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.faint, children: "Neither repeats an effect: a new attempt needs a new proposal. `esc` leaves it unfinished \u2014 the backups stay and this offer returns next time." }) })] })] }));
|
|
523
|
-
}
|
|
524
|
-
/** Which way out of a pending operation the keystroke asks for. */
|
|
525
|
-
function recoveryChoice(input, entered, cursor) {
|
|
526
|
-
if (input === "r" || input === "R")
|
|
527
|
-
return "restore";
|
|
528
|
-
if (input === "k" || input === "K")
|
|
529
|
-
return "discard";
|
|
530
|
-
if (!entered)
|
|
531
|
-
return null;
|
|
532
|
-
return cursor === 0 ? "restore" : "discard";
|
|
533
|
-
}
|
|
534
|
-
/** Navigation and toggling inside the selection — the state, not the effect. */
|
|
535
|
-
function selectionAfterKey(mode, input, key) {
|
|
536
|
-
if (key.escape)
|
|
537
|
-
return { kind: "list" };
|
|
538
|
-
if (key.upArrow)
|
|
539
|
-
return { ...mode, cursor: Math.max(0, mode.cursor - 1) };
|
|
540
|
-
if (key.downArrow) {
|
|
541
|
-
return { ...mode, cursor: Math.min(mode.candidates.length - 1, mode.cursor + 1) };
|
|
542
|
-
}
|
|
543
|
-
if (input !== " ")
|
|
544
|
-
return null;
|
|
545
|
-
const path = mode.candidates[mode.cursor]?.path;
|
|
546
|
-
if (path === undefined)
|
|
547
|
-
return null;
|
|
548
|
-
return {
|
|
549
|
-
...mode,
|
|
550
|
-
chosen: mode.chosen.includes(path)
|
|
551
|
-
? mode.chosen.filter((p) => p !== path)
|
|
552
|
-
: [...mode.chosen, path],
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* The request an acquiring action sends to the preparer.
|
|
557
|
-
*
|
|
558
|
-
* The path the catalog reviewed is what makes a NESTED skill reachable; a name
|
|
559
|
-
* is the fallback, and it only resolves while it is unambiguous.
|
|
560
|
-
*/
|
|
561
|
-
function acquiringRequest(id, item) {
|
|
562
|
-
const curation = item.curation;
|
|
563
|
-
const where = curation?.path !== undefined ? { paths: [curation.path] } : { pick: item.name };
|
|
564
|
-
// The registered ref travels with EVERY acquisition, not just Update: a row
|
|
565
|
-
// registered at `#v2` that installs from the default branch would silently
|
|
566
|
-
// drop the pin — the entry is rewritten from what the acquisition resolved.
|
|
567
|
-
const pinned = item.ref !== undefined ? { ref: item.ref } : {};
|
|
568
|
-
if (id === "repair")
|
|
569
|
-
return { operation: "repair", name: item.name };
|
|
570
|
-
if (id === "install")
|
|
571
|
-
return { operation: "install", source: item.source, ...pinned, ...where };
|
|
572
|
-
if (id === "update") {
|
|
573
|
-
return { operation: "update", source: item.source, ...pinned, ...where };
|
|
574
|
-
}
|
|
575
|
-
// An explicit source change: the previous installation is retired in the
|
|
576
|
-
// SAME proposal that brings the new one.
|
|
577
|
-
const source = curation?.proposedSource;
|
|
578
|
-
if (source === undefined)
|
|
579
|
-
return null;
|
|
580
|
-
return { operation: "replace", source, withdraw: [item.name], ...where };
|
|
581
|
-
}
|
|
582
|
-
/** Badges the row carries: the degraded replica, plus a verdict that asks for
|
|
583
|
-
* a decision (an ordinary keep/conditional row stays quiet). */
|
|
584
|
-
function rowMeta(item) {
|
|
585
|
-
const meta = [];
|
|
586
|
-
if (item.mode === "copy")
|
|
587
|
-
meta.push({ label: "copy", tone: "warn" });
|
|
588
|
-
const disposition = item.curation?.disposition;
|
|
589
|
-
const tone = disposition ? BADGED_DISPOSITIONS[disposition] : undefined;
|
|
590
|
-
if (disposition && tone)
|
|
591
|
-
meta.push({ label: DISPOSITION_LABEL[disposition], tone });
|
|
592
|
-
return meta;
|
|
593
|
-
}
|
|
594
|
-
/** Replica line of an installed/registered/unmanaged row. */
|
|
595
|
-
function replicaLine(item) {
|
|
596
|
-
return [
|
|
597
|
-
`agents ${item.replicas.agents ? "✓" : "·"}`,
|
|
598
|
-
// `item.mode` describes the FIRST replica host's materialization (symlink
|
|
599
|
-
// vs copy) — the suffix stays on that one, and the host names come from
|
|
600
|
-
// the engine's list instead of being spelled here.
|
|
601
|
-
...REPLICA_HOST_KEYS.map((key, i) => `${key} ${item.replicas[key] ? "✓" : "·"}${i === 0 && item.mode === "copy" ? " (copy)" : ""}`),
|
|
602
|
-
].join(" · ");
|
|
603
|
-
}
|
|
604
|
-
/** Short form of an inspected revision — enough to compare, never a claim
|
|
605
|
-
* about what an acquisition would resolve. */
|
|
606
|
-
function shortRef(ref) {
|
|
607
|
-
return ref.length > 12 ? ref.slice(0, 12) : ref;
|
|
608
|
-
}
|
|
609
|
-
/** The reviewed verdict, or the honest absence of one. */
|
|
610
|
-
function recommendationLines(curation) {
|
|
611
|
-
if (curation === undefined) {
|
|
612
|
-
return [
|
|
613
|
-
"Recommendation: not in the reviewed catalog",
|
|
614
|
-
`Use when: ${UNKNOWN}`,
|
|
615
|
-
`Known limits: ${UNKNOWN}`,
|
|
616
|
-
];
|
|
617
|
-
}
|
|
618
|
-
const verdict = DISPOSITION_LABEL[curation.disposition];
|
|
619
|
-
return [
|
|
620
|
-
`Recommendation: ${curation.reason ? `${verdict} — ${curation.reason}` : verdict}`,
|
|
621
|
-
`Use when: ${curation.useWhen ?? UNKNOWN}`,
|
|
622
|
-
`Known limits: ${curation.knownLimits ?? UNKNOWN}`,
|
|
623
|
-
];
|
|
624
|
-
}
|
|
625
|
-
/** Where the bytes come from — and, when they differ, where a repair would
|
|
626
|
-
* take them. A divergence is shown, never resolved silently. */
|
|
627
|
-
function sourceLines(item, curation) {
|
|
628
|
-
const source = `${item.source === "" ? UNKNOWN : item.source}${item.ref ? ` #${item.ref}` : ""}`;
|
|
629
|
-
const proposed = curation?.proposedSource;
|
|
630
|
-
const lines = [proposed ? `Installed source: ${source}` : `Source: ${source}`];
|
|
631
|
-
if (proposed)
|
|
632
|
-
lines.push(`Proposed source: ${proposed}`);
|
|
633
|
-
if (curation?.path)
|
|
634
|
-
lines.push(`Path in source: ${curation.path}`);
|
|
635
|
-
if (curation?.skillName && curation.skillName !== item.name) {
|
|
636
|
-
lines.push(`Catalog name: ${item.name}`, `Skill name: ${curation.skillName}`);
|
|
637
|
-
}
|
|
638
|
-
if (curation?.reviewedRef)
|
|
639
|
-
lines.push(`Reviewed rev: ${shortRef(curation.reviewedRef)}`);
|
|
640
|
-
if (curation?.evidence)
|
|
641
|
-
lines.push(`Evidence: ${curation.evidence}`);
|
|
642
|
-
return lines;
|
|
643
|
-
}
|
|
644
|
-
/**
|
|
645
|
-
* Detail body: installation and recommendation as SEPARATE facts (Spec 043 ·
|
|
646
|
-
* DES-001@r7 / SCR-001@r3#detail). Reading it changes nothing.
|
|
647
|
-
*/
|
|
648
|
-
function detailMeta(item, home) {
|
|
649
|
-
const lines = [];
|
|
650
|
-
if (item.description)
|
|
651
|
-
lines.push(item.description, "");
|
|
652
|
-
lines.push(item.status === "recommended"
|
|
653
|
-
? "Status: recommended · not installed"
|
|
654
|
-
: `Status: ${item.status} · ${replicaLine(item)}`);
|
|
655
|
-
lines.push(...recommendationLines(item.curation), ...sourceLines(item, item.curation));
|
|
656
|
-
if (item.status !== "recommended") {
|
|
657
|
-
lines.push(`${canonicalSkillsRoot(home)}/${item.name}`.replace(home, "~"));
|
|
658
|
-
}
|
|
659
|
-
if (item.status === "unmanaged") {
|
|
660
|
-
lines.push("Installed outside the registry (e.g. skills.sh) — not operable from here.");
|
|
661
|
-
}
|
|
662
|
-
return lines.join("\n");
|
|
663
|
-
}
|
|
664
|
-
//# sourceMappingURL=skills-tab.js.map
|