vgxness 1.20.4 → 1.20.6
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/dist/adapters/claude/agent-renderer.js +82 -0
- package/dist/{mcp → adapters/claude/install}/claude-code-agent-config.js +64 -9
- package/dist/{mcp → adapters/claude/install}/claude-code-config.js +28 -6
- package/dist/{mcp → adapters/claude/install}/claude-code-project-memory.js +35 -5
- package/dist/{mcp → adapters/claude/install}/claude-code-scope.js +12 -3
- package/dist/{mcp → adapters/claude/install}/claude-code-user-config.js +26 -5
- package/dist/{mcp → adapters/claude/install}/claude-code-user-memory.js +47 -7
- package/dist/{mcp → adapters/claude/install}/client-install-claude-code-contract.js +45 -8
- package/dist/{mcp → adapters/claude/install}/client-install-claude-code.js +98 -14
- package/dist/adapters/json/agent-renderer.js +104 -0
- package/dist/adapters/opencode/agent-renderer.js +113 -0
- package/dist/{mcp → adapters/opencode/install}/client-install-opencode-contract.js +2 -2
- package/dist/{mcp → adapters/opencode/install}/client-install-opencode.js +1 -1
- package/dist/{mcp → adapters/opencode/install}/opencode-default-agent-config.js +2 -2
- package/dist/{mcp → adapters/opencode/install}/opencode-handoff-preview.js +60 -7
- package/dist/{mcp → adapters/opencode/install}/opencode-visibility.js +1 -1
- package/dist/adapters/provider-renderer.js +6 -0
- package/dist/agents/agent-activation-service.js +1 -263
- package/dist/agents/agent-lookup-contexts.js +1 -28
- package/dist/agents/agent-registry-service.js +1 -81
- package/dist/agents/agent-resolver.js +1 -287
- package/dist/agents/agent-seed-service.js +1 -157
- package/dist/agents/agent-seed-upgrade-service.js +1 -231
- package/dist/agents/agent-selector-resolver.js +1 -28
- package/dist/agents/boot-upgrade.js +1 -59
- package/dist/agents/canonical-agent-manifest.js +1 -245
- package/dist/agents/canonical-agent-projection.js +1 -236
- package/dist/agents/manager-profile-overlay-service.js +1 -60
- package/dist/agents/profile-model-routing.js +1 -30
- package/dist/agents/renderers/claude-renderer.js +1 -82
- package/dist/agents/renderers/index.js +1 -14
- package/dist/agents/renderers/json-renderer.js +1 -104
- package/dist/agents/renderers/opencode-renderer.js +1 -113
- package/dist/agents/renderers/provider-adapter.js +1 -6
- package/dist/agents/repositories/agent-seed-history.js +1 -128
- package/dist/agents/repositories/agents.js +1 -200
- package/dist/agents/repositories/manager-profile-overlays.js +1 -90
- package/dist/agents/schema.js +1 -1
- package/dist/application/agents/agent-activation-service.js +261 -0
- package/dist/application/agents/agent-lookup-contexts.js +28 -0
- package/dist/application/agents/agent-registry-service.js +81 -0
- package/dist/application/agents/agent-resolver.js +287 -0
- package/dist/application/agents/agent-seed-service.js +157 -0
- package/dist/application/agents/agent-seed-upgrade-service.js +231 -0
- package/dist/application/agents/agent-selector-resolver.js +28 -0
- package/dist/application/agents/boot-upgrade.js +59 -0
- package/dist/application/agents/canonical-agent-projection.js +236 -0
- package/dist/application/agents/manager-profile-overlay-service.js +68 -0
- package/dist/application/agents/profile-model-routing.js +30 -0
- package/dist/application/agents/renderers/claude-renderer.js +1 -0
- package/dist/application/agents/renderers/index.js +14 -0
- package/dist/application/agents/renderers/json-renderer.js +1 -0
- package/dist/application/agents/renderers/opencode-renderer.js +1 -0
- package/dist/application/agents/renderers/provider-adapter.js +1 -0
- package/dist/application/memory/active-work-preview.js +75 -0
- package/dist/application/memory/agent-memory-capture-service.js +498 -0
- package/dist/application/memory/import/dry-run-planner.js +58 -0
- package/dist/application/memory/import/index.js +3 -0
- package/dist/application/memory/import/observation-writer.js +226 -0
- package/dist/application/memory/import/package.js +179 -0
- package/dist/application/memory/memory-service.js +202 -0
- package/dist/application/memory/search.js +11 -0
- package/dist/{mcp → application/provider-setup}/provider-change-plan.js +74 -13
- package/dist/{mcp → application/provider-setup}/provider-doctor.js +201 -31
- package/dist/{mcp → application/provider-setup}/provider-health-types.js +1 -1
- package/dist/{mcp → application/provider-setup}/provider-status.js +170 -33
- package/dist/application/runs/execution-planning.js +180 -0
- package/dist/application/runs/operation-execution.js +1 -0
- package/dist/application/runs/operation-retry.js +129 -0
- package/dist/application/runs/resume-after-approval-result.js +88 -0
- package/dist/application/runs/run-insights.js +270 -0
- package/dist/application/runs/run-service.js +1480 -0
- package/dist/application/runs/run-snapshot-export-service.js +31 -0
- package/dist/application/runs/sandbox-process-execution.js +244 -0
- package/dist/application/runs/sandbox-worktree-planning.js +59 -0
- package/dist/application/runs/task-scoped-command-grant-service.js +224 -0
- package/dist/application/sdd/artifact-portability-service.js +137 -0
- package/dist/application/sdd/cockpit-read-model.js +195 -0
- package/dist/application/sdd/sdd-continuation-plan.js +265 -0
- package/dist/application/sdd/sdd-workflow-service.js +892 -0
- package/dist/application/skills/boot-seed.js +42 -0
- package/dist/application/skills/personal-skills.js +41 -0
- package/dist/application/skills/skill-export-service.js +34 -0
- package/dist/application/skills/skill-index-service.js +126 -0
- package/dist/application/skills/skill-payload.js +186 -0
- package/dist/application/skills/skill-registry-service.js +648 -0
- package/dist/application/skills/skill-resolver.js +368 -0
- package/dist/application/skills/skill-seed-service.js +242 -0
- package/dist/application/skills/skill-status-service.js +147 -0
- package/dist/cli/bun-bin.js +0 -0
- package/dist/cli/cli-flags.js +1 -387
- package/dist/cli/cli-help.js +1 -173
- package/dist/cli/cli-helpers.js +1 -77
- package/dist/cli/cli-types.js +1 -1
- package/dist/cli/commands/agent-skill-dispatcher.js +1 -700
- package/dist/cli/commands/index.js +1 -9
- package/dist/cli/commands/interactive-entrypoint-dispatcher.js +1 -14
- package/dist/cli/commands/mcp-dispatcher.js +1 -232
- package/dist/cli/commands/memory-sdd-dispatcher.js +1 -367
- package/dist/cli/commands/run-permission-dispatcher.js +1 -455
- package/dist/cli/commands/setup-dispatcher.js +1 -496
- package/dist/cli/commands/status-dispatcher.js +1 -130
- package/dist/cli/commands/verification-dispatcher.js +1 -47
- package/dist/cli/commands/workflow-dispatcher.js +1 -566
- package/dist/cli/dispatcher.js +1 -247
- package/dist/cli/doctor-renderer.js +1 -26
- package/dist/cli/home-tui-app.js +1 -411
- package/dist/cli/home-tui-controller.js +1 -314
- package/dist/cli/mcp-start-path.js +1 -21
- package/dist/cli/product-resume-renderer.js +1 -32
- package/dist/cli/product-status-renderer.js +1 -81
- package/dist/cli/sdd-renderer.js +1 -247
- package/dist/cli/setup-plan-renderer.js +1 -79
- package/dist/cli/setup-status-renderer.js +1 -50
- package/dist/cli/setup-tui-app.js +1 -130
- package/dist/cli/setup-tui-controller.js +1 -89
- package/dist/cli/tui/focus-reducer.js +1 -0
- package/dist/cli/tui/focus-types.js +1 -0
- package/dist/cli/tui/ink/app-shell.js +1 -0
- package/dist/cli/tui/ink/components.js +1 -38
- package/dist/cli/tui/ink/help-overlay.js +1 -0
- package/dist/cli/tui/ink/state-components.js +1 -0
- package/dist/cli/tui/ink/theme.js +1 -36
- package/dist/cli/tui/key-intents.js +1 -0
- package/dist/cli/tui/keymap.js +1 -20
- package/dist/cli/tui/navigation.js +1 -10
- package/dist/cli/tui/screen-registry.js +1 -0
- package/dist/cli/tui/terminal-capabilities.js +1 -12
- package/dist/cli/tui/tui-types.js +1 -1
- package/dist/cli/tui/visual/badges.js +1 -19
- package/dist/cli/tui/visual/footer.js +1 -27
- package/dist/cli/tui/visual/index.js +1 -3
- package/dist/cli/tui/visual/viewport.js +1 -11
- package/dist/cli/tui-render-helpers.js +1 -200
- package/dist/cli/verification-plan-renderer.js +1 -25
- package/dist/cli/verification-report-renderer.js +1 -19
- package/dist/domain/agents/canonical-agent-manifest.js +355 -0
- package/dist/domain/agents/schema.js +1 -0
- package/dist/domain/memory/active-work-topics.js +64 -0
- package/dist/domain/memory/memory-capture-schema.js +1 -0
- package/dist/domain/memory/schema.js +1 -0
- package/dist/domain/runs/schema.js +5 -0
- package/dist/domain/sdd/cockpit-types.js +1 -0
- package/dist/domain/sdd/schema.js +111 -0
- package/dist/domain/skills/schema.js +1 -0
- package/dist/governance/risk-classifier.js +2 -0
- package/dist/interfaces/cli/bun-bin.js +46 -0
- package/dist/interfaces/cli/cli-flags.js +391 -0
- package/dist/interfaces/cli/cli-help.js +173 -0
- package/dist/interfaces/cli/cli-helpers.js +77 -0
- package/dist/interfaces/cli/cli-types.js +1 -0
- package/dist/interfaces/cli/commands/agent-skill-dispatcher.js +700 -0
- package/dist/interfaces/cli/commands/index.js +9 -0
- package/dist/interfaces/cli/commands/interactive-entrypoint-dispatcher.js +14 -0
- package/dist/interfaces/cli/commands/mcp-dispatcher.js +252 -0
- package/dist/interfaces/cli/commands/memory-sdd-dispatcher.js +367 -0
- package/dist/interfaces/cli/commands/run-permission-dispatcher.js +460 -0
- package/dist/interfaces/cli/commands/setup-dispatcher.js +496 -0
- package/dist/interfaces/cli/commands/status-dispatcher.js +130 -0
- package/dist/interfaces/cli/commands/verification-dispatcher.js +47 -0
- package/dist/interfaces/cli/commands/workflow-dispatcher.js +566 -0
- package/dist/interfaces/cli/dispatcher.js +247 -0
- package/dist/interfaces/cli/doctor-renderer.js +26 -0
- package/dist/interfaces/cli/home-tui-app.js +462 -0
- package/dist/interfaces/cli/home-tui-controller.js +341 -0
- package/dist/interfaces/cli/index.js +27 -0
- package/dist/interfaces/cli/mcp-start-path.js +21 -0
- package/dist/interfaces/cli/product-resume-renderer.js +32 -0
- package/dist/interfaces/cli/product-status-renderer.js +81 -0
- package/dist/interfaces/cli/sdd-renderer.js +247 -0
- package/dist/interfaces/cli/setup-plan-renderer.js +79 -0
- package/dist/interfaces/cli/setup-status-renderer.js +50 -0
- package/dist/interfaces/cli/setup-tui-app.js +135 -0
- package/dist/interfaces/cli/setup-tui-controller.js +89 -0
- package/dist/interfaces/cli/tui/focus-reducer.js +60 -0
- package/dist/interfaces/cli/tui/focus-types.js +10 -0
- package/dist/interfaces/cli/tui/ink/app-shell.js +16 -0
- package/dist/interfaces/cli/tui/ink/components.js +38 -0
- package/dist/interfaces/cli/tui/ink/help-overlay.js +6 -0
- package/dist/interfaces/cli/tui/ink/state-components.js +22 -0
- package/dist/interfaces/cli/tui/ink/theme.js +36 -0
- package/dist/interfaces/cli/tui/key-intents.js +33 -0
- package/dist/interfaces/cli/tui/keymap.js +20 -0
- package/dist/interfaces/cli/tui/navigation.js +10 -0
- package/dist/interfaces/cli/tui/screen-registry.js +43 -0
- package/dist/interfaces/cli/tui/terminal-capabilities.js +12 -0
- package/dist/interfaces/cli/tui/tui-types.js +1 -0
- package/dist/interfaces/cli/tui/visual/badges.js +19 -0
- package/dist/interfaces/cli/tui/visual/footer.js +27 -0
- package/dist/interfaces/cli/tui/visual/index.js +3 -0
- package/dist/interfaces/cli/tui/visual/viewport.js +11 -0
- package/dist/interfaces/cli/tui-render-helpers.js +200 -0
- package/dist/interfaces/cli/verification-plan-renderer.js +25 -0
- package/dist/interfaces/cli/verification-report-renderer.js +19 -0
- package/dist/interfaces/mcp/contracts/agents.js +1 -0
- package/dist/interfaces/mcp/contracts/context.js +1 -0
- package/dist/interfaces/mcp/contracts/governance.js +1 -0
- package/dist/interfaces/mcp/contracts/index.js +1 -0
- package/dist/interfaces/mcp/contracts/memory.js +1 -0
- package/dist/interfaces/mcp/contracts/providers.js +1 -0
- package/dist/interfaces/mcp/contracts/runs.js +1 -0
- package/dist/interfaces/mcp/contracts/sdd.js +1 -0
- package/dist/interfaces/mcp/contracts/sessions.js +1 -0
- package/dist/interfaces/mcp/contracts/skills.js +1 -0
- package/dist/interfaces/mcp/contracts/verification.js +1 -0
- package/dist/interfaces/mcp/control-plane/handlers/agents.js +38 -0
- package/dist/interfaces/mcp/control-plane/handlers/context.js +12 -0
- package/dist/interfaces/mcp/control-plane/handlers/memory.js +95 -0
- package/dist/interfaces/mcp/control-plane/handlers/providers.js +19 -0
- package/dist/interfaces/mcp/control-plane/handlers/runs.js +134 -0
- package/dist/interfaces/mcp/control-plane/handlers/sdd.js +225 -0
- package/dist/interfaces/mcp/control-plane/handlers/sessions.js +39 -0
- package/dist/interfaces/mcp/control-plane/handlers/skills.js +82 -0
- package/dist/interfaces/mcp/control-plane/handlers/verification.js +11 -0
- package/dist/interfaces/mcp/control-plane/types.js +1 -0
- package/dist/interfaces/mcp/control-plane.js +235 -0
- package/dist/interfaces/mcp/schema.js +174 -0
- package/dist/interfaces/mcp/schemas/common.js +121 -0
- package/dist/interfaces/mcp/schemas/inputs/agents.js +69 -0
- package/dist/interfaces/mcp/schemas/inputs/context.js +32 -0
- package/dist/interfaces/mcp/schemas/inputs/governance.js +23 -0
- package/dist/interfaces/mcp/schemas/inputs/index.js +10 -0
- package/dist/interfaces/mcp/schemas/inputs/memory.js +50 -0
- package/dist/interfaces/mcp/schemas/inputs/providers.js +35 -0
- package/dist/interfaces/mcp/schemas/inputs/runs.js +146 -0
- package/dist/interfaces/mcp/schemas/inputs/sdd.js +102 -0
- package/dist/interfaces/mcp/schemas/inputs/sessions.js +32 -0
- package/dist/interfaces/mcp/schemas/inputs/skills.js +231 -0
- package/dist/interfaces/mcp/schemas/inputs/verification.js +9 -0
- package/dist/interfaces/mcp/schemas/outputs/index.js +2 -0
- package/dist/interfaces/mcp/schemas/outputs/providers.js +28 -0
- package/dist/interfaces/mcp/schemas/outputs/sdd.js +166 -0
- package/dist/interfaces/mcp/stdio-server.js +116 -0
- package/dist/interfaces/mcp/validation/agents.js +189 -0
- package/dist/interfaces/mcp/validation/common.js +415 -0
- package/dist/interfaces/mcp/validation/governance.js +50 -0
- package/dist/interfaces/mcp/validation/memory.js +133 -0
- package/dist/interfaces/mcp/validation/providers.js +94 -0
- package/dist/interfaces/mcp/validation/runs.js +514 -0
- package/dist/interfaces/mcp/validation/sdd.js +247 -0
- package/dist/interfaces/mcp/validation/sessions.js +51 -0
- package/dist/interfaces/mcp/validation/skills.js +685 -0
- package/dist/interfaces/mcp/validation/verification.js +24 -0
- package/dist/interfaces/mcp/validation.js +149 -0
- package/dist/mcp/control-plane-snapshot-service.js +65 -2
- package/dist/mcp/control-plane.js +1 -646
- package/dist/mcp/doctor.js +1 -1
- package/dist/mcp/index.js +17 -17
- package/dist/mcp/schema.js +1 -1072
- package/dist/mcp/stdio-server.js +1 -116
- package/dist/mcp/validation.js +1 -2239
- package/dist/memory/active-work-preview.js +1 -75
- package/dist/memory/active-work-topics.js +1 -64
- package/dist/memory/agent-memory-capture-service.js +1 -497
- package/dist/memory/import/dry-run-planner.js +1 -58
- package/dist/memory/import/index.js +1 -3
- package/dist/memory/import/observation-writer.js +1 -226
- package/dist/memory/import/package.js +1 -179
- package/dist/memory/memory-capture-schema.js +1 -1
- package/dist/memory/memory-service.js +1 -201
- package/dist/memory/repositories/artifacts.js +1 -67
- package/dist/memory/repositories/observations.js +1 -217
- package/dist/memory/repositories/sessions.js +1 -125
- package/dist/memory/repositories/traces.js +1 -78
- package/dist/memory/schema.js +1 -1
- package/dist/memory/search.js +1 -11
- package/dist/memory/sqlite/database.js +1 -228
- package/dist/memory/storage-paths.js +1 -72
- package/dist/payload/context-budget-policy.js +10 -0
- package/dist/payload/context-budget-service.js +26 -0
- package/dist/payload/payload-diagnostics.js +50 -0
- package/dist/permissions/explicit-request-authorization.js +126 -0
- package/dist/permissions/policy-evaluator.js +54 -14
- package/dist/runs/execution-planning.js +1 -178
- package/dist/runs/operation-execution.js +1 -1
- package/dist/runs/operation-retry.js +1 -129
- package/dist/runs/repositories/runs.js +1 -676
- package/dist/runs/repositories/task-scoped-command-grants.js +1 -462
- package/dist/runs/resume-after-approval-result.js +1 -84
- package/dist/runs/run-insights.js +1 -270
- package/dist/runs/run-service.js +1 -1439
- package/dist/runs/run-snapshot-export-service.js +1 -31
- package/dist/runs/sandbox-process-execution.js +1 -240
- package/dist/runs/sandbox-worktree-planning.js +1 -59
- package/dist/runs/schema.js +1 -5
- package/dist/runs/task-scoped-command-grant-service.js +1 -216
- package/dist/sdd/artifact-portability-service.js +1 -137
- package/dist/sdd/cockpit-read-model.js +1 -195
- package/dist/sdd/cockpit-types.js +1 -1
- package/dist/sdd/schema.js +1 -111
- package/dist/sdd/sdd-continuation-plan.js +1 -265
- package/dist/sdd/sdd-workflow-service.js +1 -822
- package/dist/setup/providers/claude-setup-adapter.js +11 -4
- package/dist/setup/providers/opencode-setup-adapter.js +10 -7
- package/dist/setup/setup-plan.js +20 -7
- package/dist/skills/boot-seed.js +1 -42
- package/dist/skills/personal-skills.js +1 -41
- package/dist/skills/repositories/skill-evaluation-requests.js +1 -190
- package/dist/skills/repositories/skill-evaluation-scenarios.js +1 -305
- package/dist/skills/repositories/skill-improvement-proposals.js +1 -355
- package/dist/skills/repositories/skills.js +1 -1077
- package/dist/skills/schema.js +1 -1
- package/dist/skills/skill-export-service.js +1 -34
- package/dist/skills/skill-index-service.js +1 -126
- package/dist/skills/skill-payload.js +1 -186
- package/dist/skills/skill-registry-service.js +1 -644
- package/dist/skills/skill-resolver.js +1 -368
- package/dist/skills/skill-seed-service.js +1 -242
- package/dist/skills/skill-status-service.js +1 -147
- package/dist/storage/agents/repositories/agent-seed-history.js +128 -0
- package/dist/storage/agents/repositories/agents.js +200 -0
- package/dist/storage/agents/repositories/manager-profile-overlays.js +90 -0
- package/dist/storage/memory/repositories/artifacts.js +67 -0
- package/dist/storage/memory/repositories/observations.js +217 -0
- package/dist/storage/memory/repositories/sessions.js +125 -0
- package/dist/storage/memory/repositories/traces.js +78 -0
- package/dist/storage/memory/sqlite/database.js +228 -0
- package/dist/storage/memory/storage-paths.js +72 -0
- package/dist/storage/runs/repositories/runs.js +676 -0
- package/dist/storage/runs/repositories/task-scoped-command-grants.js +464 -0
- package/dist/storage/skills/repositories/skill-evaluation-requests.js +190 -0
- package/dist/storage/skills/repositories/skill-evaluation-scenarios.js +305 -0
- package/dist/storage/skills/repositories/skill-improvement-proposals.js +355 -0
- package/dist/storage/skills/repositories/skills.js +1084 -0
- package/docs/architecture.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/mcp.md +1 -1
- package/docs/module-boundaries.md +114 -0
- package/docs/prd.md +1 -1
- package/docs/project-health-audit-v1.10.x.md +1 -1
- package/docs/providers.md +2 -2
- package/docs/safety.md +3 -3
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/apply-progress.md +122 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/archive-report.md +61 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/design.md +66 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/proposal.md +79 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/spec.md +67 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/tasks.md +63 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/verify-report.md +71 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/apply-progress.md +68 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/archive-report.md +61 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/design.md +43 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/proposal.md +61 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/spec.md +31 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/tasks.md +27 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/verify-report.md +58 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/apply-progress.md +65 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/archive-report.md +53 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/design.md +64 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/proposal.md +62 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/spec.md +51 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/tasks.md +50 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/verify-report.md +66 -0
- package/docs/storage.md +2 -2
- package/package.json +2 -2
- /package/dist/{mcp → adapters/claude/install}/claude-code-cli.js +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/001_initial.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/002_observation_revisions.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/003_agent_registry.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/004_run_runtime.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/005_run_approvals.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/006_run_operation_attempts.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/007_abandoned_operation_attempts.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/008_run_execution_plan_events.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/009_multiple_operation_attempts.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/010_skill_registry.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/011_skill_usage_resolution_outcomes.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/012_skill_improvement_proposals.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/013_skill_evaluation_scenarios.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/014_manager_profile_overlays.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/015_artifact_metadata.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/016_agent_seed_history.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/017_intent_signal_skill_targets.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/018_skill_system_v2.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/019_task_scoped_command_grants.sql +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from 'ink';
|
|
3
|
+
import { getTuiScreenDefinition } from '../screen-registry.js';
|
|
4
|
+
import { TuiFooter, TuiHeader, TuiSummaryBar } from './components.js';
|
|
5
|
+
import { TuiHelpOverlay } from './help-overlay.js';
|
|
6
|
+
import { normalizeInkTuiWidth } from './theme.js';
|
|
7
|
+
export function AppShell({ project, width, focus, subtitle, summaryItems = [], children }) {
|
|
8
|
+
const screen = getTuiScreenDefinition(focus.screenId);
|
|
9
|
+
const cardWidth = normalizeInkTuiWidth(width);
|
|
10
|
+
return (_jsxs(Box, { flexDirection: "column", width: cardWidth, paddingX: 1, paddingY: 1, children: [_jsx(TuiHeader, { title: screen.title, subtitle: subtitle ?? subtitleForScreen(screen), project: project }), summaryItems.length === 0 ? null : _jsx(TuiSummaryBar, { items: summaryItems }), _jsx(Box, { marginTop: 1, children: focus.helpOpen ? _jsx(TuiHelpOverlay, { screen: screen }) : children }), _jsx(TuiFooter, { text: screen.footer })] }));
|
|
11
|
+
}
|
|
12
|
+
function subtitleForScreen(screen) {
|
|
13
|
+
if (screen.id === 'unavailable')
|
|
14
|
+
return `Requested screen '${screen.requestedId}' is unavailable · safe read-only state`;
|
|
15
|
+
return `${screen.title} cockpit · read-only`;
|
|
16
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { colorForTone, inkTuiTheme } from './theme.js';
|
|
4
|
+
export function TuiHeader({ title, subtitle, project }) {
|
|
5
|
+
return (_jsxs(Box, { borderStyle: "round", borderColor: colorForTone('info'), paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Text, { bold: true, color: colorForTone('info'), children: [inkTuiTheme.symbols.brand, " ", title] }), _jsx(Text, { children: " " }), _jsx(TuiBadge, { label: inkTuiTheme.copy.readOnlyBadge, tone: "warning" }), _jsx(Text, { children: " " }), _jsx(TuiBadge, { label: inkTuiTheme.copy.previewOnlyBadge, tone: "warning" })] }), _jsxs(Text, { color: colorForTone('neutral'), children: [subtitle, " \u00B7 ", project] })] }));
|
|
6
|
+
}
|
|
7
|
+
export function TuiTabs({ items, selectedKey }) {
|
|
8
|
+
return (_jsx(Box, { marginTop: 1, gap: 2, children: items.map((item) => {
|
|
9
|
+
const selected = item.key === selectedKey;
|
|
10
|
+
return (_jsxs(Text, { color: selected ? colorForTone('info') : colorForTone('neutral'), bold: selected, children: [selected ? inkTuiTheme.symbols.selected : inkTuiTheme.symbols.unselected, " ", item.label] }, item.key));
|
|
11
|
+
}) }));
|
|
12
|
+
}
|
|
13
|
+
export function TuiSummaryBar({ items }) {
|
|
14
|
+
return (_jsx(Box, { marginTop: 1, gap: 1, children: items.map((item) => {
|
|
15
|
+
const tone = item.tone ?? 'neutral';
|
|
16
|
+
const color = colorForTone(tone);
|
|
17
|
+
return (_jsxs(Box, { borderStyle: "single", borderColor: color, paddingX: 1, flexDirection: "column", children: [_jsx(Text, { color: color, bold: true, children: item.value }), _jsx(Text, { color: colorForTone('neutral'), children: item.label })] }, `${item.label}:${item.value}`));
|
|
18
|
+
}) }));
|
|
19
|
+
}
|
|
20
|
+
export function TuiCard({ title, badge, tone = 'info', lines, children }) {
|
|
21
|
+
const color = colorForTone(tone);
|
|
22
|
+
return (_jsxs(Box, { borderStyle: "round", borderColor: color, paddingX: 1, flexDirection: "column", width: "100%", children: [_jsxs(Text, { bold: true, color: color, children: [title, badge === undefined ? '' : ` [${badge}]`] }), (lines ?? []).map((line, index) => (line.length === 0 ? _jsx(Text, { children: " " }, lineKey(line, index)) : _jsx(Text, { children: line }, lineKey(line, index)))), children] }));
|
|
23
|
+
}
|
|
24
|
+
export function TuiFooter({ text }) {
|
|
25
|
+
return (_jsx(Box, { marginTop: 1, borderStyle: "single", borderColor: colorForTone('neutral'), paddingX: 1, children: _jsx(Text, { color: colorForTone('neutral'), children: text }) }));
|
|
26
|
+
}
|
|
27
|
+
export function TuiBadge({ label, tone }) {
|
|
28
|
+
return _jsxs(Text, { color: colorForTone(tone), children: ["[", label, "]"] });
|
|
29
|
+
}
|
|
30
|
+
export function TuiFocusedLine({ label, focused }) {
|
|
31
|
+
if (focused) {
|
|
32
|
+
return (_jsxs(Text, { color: colorForTone('info'), bold: true, children: [inkTuiTheme.symbols.selected, " ", label] }));
|
|
33
|
+
}
|
|
34
|
+
return _jsxs(Text, { children: [" ", label] });
|
|
35
|
+
}
|
|
36
|
+
function lineKey(line, index) {
|
|
37
|
+
return `${index}:${line}`;
|
|
38
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { colorForTone } from './theme.js';
|
|
4
|
+
export function TuiHelpOverlay({ screen }) {
|
|
5
|
+
return (_jsxs(Box, { borderStyle: "round", borderColor: colorForTone('info'), paddingX: 1, flexDirection: "column", children: [_jsxs(Text, { bold: true, color: colorForTone('info'), children: ["Help \u00B7 ", screen.title] }), _jsx(Text, { children: "Read-only milestone: keys inspect local views only; no mutating setup, SDD, run, approval, git, package, or provider operations are exposed." }), screen.help.map((binding) => (_jsxs(Text, { children: [binding.key, " \u2014 ", binding.label] }, `${binding.scope}:${binding.key}:${binding.intent}`))), _jsxs(Text, { color: colorForTone('neutral'), children: ["Safety: ", screen.safety] })] }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { TuiCard } from './components.js';
|
|
4
|
+
import { colorForTone } from './theme.js';
|
|
5
|
+
export function TuiEmptyState(props) {
|
|
6
|
+
return _jsx(TuiSafeStateCard, { ...props, badge: "empty", tone: "neutral" });
|
|
7
|
+
}
|
|
8
|
+
export function TuiLoadingState(props) {
|
|
9
|
+
return _jsx(TuiSafeStateCard, { ...props, badge: "loading", tone: "info" });
|
|
10
|
+
}
|
|
11
|
+
export function TuiErrorState(props) {
|
|
12
|
+
return _jsx(TuiSafeStateCard, { ...props, badge: "unavailable", tone: "warning" });
|
|
13
|
+
}
|
|
14
|
+
export function TuiReadOnlyState(props) {
|
|
15
|
+
return _jsx(TuiSafeStateCard, { ...props, badge: "read-only", tone: "info" });
|
|
16
|
+
}
|
|
17
|
+
export function TuiGatedState(props) {
|
|
18
|
+
return _jsx(TuiSafeStateCard, { ...props, badge: "gated", tone: "warning" });
|
|
19
|
+
}
|
|
20
|
+
function TuiSafeStateCard({ title, message, details = [], badge, tone }) {
|
|
21
|
+
return (_jsxs(TuiCard, { title: title, badge: badge, tone: tone, children: [_jsx(Text, { children: message }), _jsx(Text, { color: colorForTone('neutral'), children: "No active mutation action is available from this TUI state." }), details.length === 0 ? null : (_jsx(Box, { flexDirection: "column", marginTop: 1, children: details.map((detail) => (_jsxs(Text, { children: ["- ", detail] }, detail))) }))] }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const inkTuiTheme = {
|
|
2
|
+
app: {
|
|
3
|
+
minWidth: 60,
|
|
4
|
+
maxWidth: 88,
|
|
5
|
+
},
|
|
6
|
+
colors: {
|
|
7
|
+
neutral: 'gray',
|
|
8
|
+
info: 'cyan',
|
|
9
|
+
success: 'green',
|
|
10
|
+
warning: 'yellow',
|
|
11
|
+
danger: 'red',
|
|
12
|
+
},
|
|
13
|
+
symbols: {
|
|
14
|
+
brand: '◆',
|
|
15
|
+
selected: '›',
|
|
16
|
+
unselected: ' ',
|
|
17
|
+
},
|
|
18
|
+
copy: {
|
|
19
|
+
homeTitle: 'VGXNESS Home',
|
|
20
|
+
homeSubtitle: 'Local-first control plane · read-only cockpit',
|
|
21
|
+
setupTitle: 'VGXNESS Setup',
|
|
22
|
+
setupSubtitle: 'Modern setup cockpit · provider-safe preview',
|
|
23
|
+
readOnlyBadge: 'read-only',
|
|
24
|
+
previewOnlyBadge: 'preview-only',
|
|
25
|
+
keyboardHelp: 'Keys: ↑/↓ or j/k move · Enter continue/select · Tab/Shift+Tab next/back · Esc/q cancel · ? help',
|
|
26
|
+
actionHelp: 'Action help: Enter/Space preview confirmation · ↑/↓ choose action · Tab changes tab · q exits',
|
|
27
|
+
readOnlyConfirmation: 'This TUI is read-only and did not apply the action.',
|
|
28
|
+
manualApplyCommand: 'Run manually after review: vgxness setup apply --yes',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export function colorForTone(tone) {
|
|
32
|
+
return inkTuiTheme.colors[tone];
|
|
33
|
+
}
|
|
34
|
+
export function normalizeInkTuiWidth(width) {
|
|
35
|
+
return Math.max(inkTuiTheme.app.minWidth, Math.min(width, inkTuiTheme.app.maxWidth));
|
|
36
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const globalReadOnlyKeyBindings = [
|
|
2
|
+
{ key: '↑/k', intent: 'move-up', label: 'Move focus up', scope: 'global' },
|
|
3
|
+
{ key: '↓/j', intent: 'move-down', label: 'Move focus down', scope: 'global' },
|
|
4
|
+
{ key: 'Tab', intent: 'next', label: 'Next focus item', scope: 'global' },
|
|
5
|
+
{ key: 'Shift+Tab', intent: 'previous', label: 'Previous focus item', scope: 'global' },
|
|
6
|
+
{ key: 'Enter', intent: 'activate', label: 'Open read-only detail', scope: 'global' },
|
|
7
|
+
{ key: 'Esc', intent: 'back', label: 'Close help or go back', scope: 'global' },
|
|
8
|
+
{ key: '?', intent: 'toggle-help', label: 'Toggle help', scope: 'global' },
|
|
9
|
+
{ key: 'q', intent: 'quit', label: 'Request exit', scope: 'global' },
|
|
10
|
+
];
|
|
11
|
+
export function keyIntentFromInput(input) {
|
|
12
|
+
if (input === '\u001B[A' || input === 'k')
|
|
13
|
+
return 'move-up';
|
|
14
|
+
if (input === '\u001B[B' || input === 'j')
|
|
15
|
+
return 'move-down';
|
|
16
|
+
if (input === '\t')
|
|
17
|
+
return 'next';
|
|
18
|
+
if (input === '\u001B[Z')
|
|
19
|
+
return 'previous';
|
|
20
|
+
if (input === '\r' || input === '\n')
|
|
21
|
+
return 'activate';
|
|
22
|
+
if (input === '\u001B')
|
|
23
|
+
return 'back';
|
|
24
|
+
if (input === '?')
|
|
25
|
+
return 'toggle-help';
|
|
26
|
+
if (input === 'q')
|
|
27
|
+
return 'quit';
|
|
28
|
+
return 'unknown';
|
|
29
|
+
}
|
|
30
|
+
export function footerTextForBindings(bindings = globalReadOnlyKeyBindings) {
|
|
31
|
+
const labels = bindings.map((binding) => `${binding.key} ${binding.label.toLowerCase()}`);
|
|
32
|
+
return `Keys: ${labels.join(' · ')} · read-only`;
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const setupTuiKeyboardHelp = 'Keys: ↑/↓ or j/k move · Enter continue/select · Tab/Shift+Tab next/back · Esc/q cancel · ? help';
|
|
2
|
+
export function navigationIntentFromInput(input) {
|
|
3
|
+
if (input === '\u001B[A' || input === 'k')
|
|
4
|
+
return 'up';
|
|
5
|
+
if (input === '\u001B[B' || input === 'j')
|
|
6
|
+
return 'down';
|
|
7
|
+
if (input === '\r' || input === '\n')
|
|
8
|
+
return 'next';
|
|
9
|
+
if (input === '\t')
|
|
10
|
+
return 'next';
|
|
11
|
+
if (input === '\u001B[Z')
|
|
12
|
+
return 'back';
|
|
13
|
+
if (input === '\u001B' || input === 'q')
|
|
14
|
+
return 'cancel';
|
|
15
|
+
if (input === '?' || input === 'h')
|
|
16
|
+
return 'help';
|
|
17
|
+
if (input === ' ')
|
|
18
|
+
return 'select';
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function moveIndex(current, delta, length) {
|
|
2
|
+
if (length <= 0)
|
|
3
|
+
return 0;
|
|
4
|
+
return Math.max(0, Math.min(current + delta, length - 1));
|
|
5
|
+
}
|
|
6
|
+
export function nextItem(items, current, delta) {
|
|
7
|
+
const index = items.indexOf(current);
|
|
8
|
+
const nextIndex = moveIndex(index < 0 ? 0 : index, delta, items.length);
|
|
9
|
+
return items[nextIndex] ?? current;
|
|
10
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { footerTextForBindings, globalReadOnlyKeyBindings } from './key-intents.js';
|
|
2
|
+
const screenDefinitions = [
|
|
3
|
+
screen('home', 'Home', 'setup-plan', ['Setup readiness', 'Runs summary', 'SDD summary', 'Provider status']),
|
|
4
|
+
screen('runs', 'Runs', 'runs-read-model', ['Recent runs', 'Interrupted runs', 'Selected run detail']),
|
|
5
|
+
screen('sdd', 'SDD', 'sdd-read-model', ['Phase status', 'Human acceptance', 'Next guidance']),
|
|
6
|
+
screen('setup', 'Setup', 'setup-plan', ['Preview status', 'Conflicts', 'Future confirmation requirements']),
|
|
7
|
+
screen('doctor', 'Doctor', 'doctor-plan', ['Provider health', 'Config diagnostics', 'Safe recovery guidance']),
|
|
8
|
+
screen('provider', 'Provider', 'provider-plan', ['Provider adapter', 'Expected config', 'Preview-only plan']),
|
|
9
|
+
];
|
|
10
|
+
export const registeredTuiScreens = screenDefinitions;
|
|
11
|
+
export function getTuiScreenDefinition(id) {
|
|
12
|
+
const definition = screenDefinitions.find((screenDefinition) => screenDefinition.id === id);
|
|
13
|
+
if (definition !== undefined)
|
|
14
|
+
return definition;
|
|
15
|
+
return {
|
|
16
|
+
id: 'unavailable',
|
|
17
|
+
requestedId: id,
|
|
18
|
+
title: 'Unavailable screen',
|
|
19
|
+
help: globalReadOnlyKeyBindings,
|
|
20
|
+
footer: footerTextForBindings(),
|
|
21
|
+
sections: [{ id: 'safe-state', title: 'Safe unavailable state' }],
|
|
22
|
+
readModelRequirement: 'none',
|
|
23
|
+
safety: 'read-only',
|
|
24
|
+
state: 'unavailable',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function screen(id, title, readModelRequirement, sectionTitles) {
|
|
28
|
+
return {
|
|
29
|
+
id,
|
|
30
|
+
title,
|
|
31
|
+
help: globalReadOnlyKeyBindings,
|
|
32
|
+
footer: footerTextForBindings(),
|
|
33
|
+
sections: sectionTitles.map((sectionTitle) => ({
|
|
34
|
+
id: sectionTitle
|
|
35
|
+
.toLowerCase()
|
|
36
|
+
.replaceAll(/[^a-z0-9]+/g, '-')
|
|
37
|
+
.replace(/^-|-$/g, ''),
|
|
38
|
+
title: sectionTitle,
|
|
39
|
+
})),
|
|
40
|
+
readModelRequirement,
|
|
41
|
+
safety: 'read-only',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function detectTerminalCapabilities(input, output) {
|
|
2
|
+
return {
|
|
3
|
+
interactive: input?.isTTY === true && output?.isTTY === true,
|
|
4
|
+
supportsRawMode: input?.setRawMode !== undefined,
|
|
5
|
+
columns: output?.columns ?? 80,
|
|
6
|
+
rows: output?.rows ?? 24,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function canRunInteractiveTui(input, output) {
|
|
10
|
+
const capabilities = detectTerminalCapabilities(input, output);
|
|
11
|
+
return capabilities.interactive && capabilities.supportsRawMode;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const tuiBadges = {
|
|
2
|
+
ready: '[Ready]',
|
|
3
|
+
blocked: '[Blocked]',
|
|
4
|
+
focused: '[Focused]',
|
|
5
|
+
selected: '[Selected]',
|
|
6
|
+
previewOnly: '[Preview-only]',
|
|
7
|
+
readOnly: '[Read-only]',
|
|
8
|
+
requiresConfirmation: '[Requires confirmation]',
|
|
9
|
+
noProviderWrites: '[No provider writes]',
|
|
10
|
+
manual: '[Manual]',
|
|
11
|
+
exit: '[Exit]',
|
|
12
|
+
};
|
|
13
|
+
export function badgeText(badge) {
|
|
14
|
+
return typeof badge === 'string' ? badge : badge.label;
|
|
15
|
+
}
|
|
16
|
+
export function formatBadges(badges) {
|
|
17
|
+
const labels = (badges ?? []).map(badgeText).filter((label) => label.length > 0);
|
|
18
|
+
return labels.length === 0 ? '' : labels.join(' ');
|
|
19
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function formatTuiFooter(hints, width, mode) {
|
|
2
|
+
const visibleHints = mode === 'narrow' ? prioritizeCritical(hints) : hints;
|
|
3
|
+
const footer = visibleHints.map(formatHint).join(' · ');
|
|
4
|
+
if (footer.length <= width)
|
|
5
|
+
return footer;
|
|
6
|
+
const critical = prioritizeCritical(hints);
|
|
7
|
+
const fallback = critical.map(formatHint).join(' · ');
|
|
8
|
+
if (fallback.length <= width)
|
|
9
|
+
return fallback;
|
|
10
|
+
return preserveCriticalText(fallback, width);
|
|
11
|
+
}
|
|
12
|
+
function prioritizeCritical(hints) {
|
|
13
|
+
const critical = hints.filter((hint) => hint.priority === 'critical' || /confirm|cancel|quit|close|exit/i.test(hint.label));
|
|
14
|
+
return critical.length === 0 ? hints.slice(0, 3) : critical;
|
|
15
|
+
}
|
|
16
|
+
function formatHint(hint) {
|
|
17
|
+
return `${hint.key} ${hint.label}`;
|
|
18
|
+
}
|
|
19
|
+
function preserveCriticalText(value, width) {
|
|
20
|
+
if (width <= 0 || value.length <= width)
|
|
21
|
+
return value;
|
|
22
|
+
const protectedPhrases = ['final confirmation', 'confirm and apply', 'requires confirmation', 'cancel', 'quit', 'exit', 'read-only'];
|
|
23
|
+
const phrase = protectedPhrases.find((candidate) => value.toLowerCase().includes(candidate));
|
|
24
|
+
if (phrase === undefined)
|
|
25
|
+
return `${value.slice(0, Math.max(0, width - 1)).trim()}…`;
|
|
26
|
+
return `${value.slice(0, Math.max(0, width - phrase.length - 5)).trim()} ... ${phrase}`.trim();
|
|
27
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function viewportModeForWidth(width) {
|
|
2
|
+
if (width < 72)
|
|
3
|
+
return 'narrow';
|
|
4
|
+
if (width >= 120)
|
|
5
|
+
return 'wide';
|
|
6
|
+
return 'standard';
|
|
7
|
+
}
|
|
8
|
+
export function createTuiViewport(width, fallback = 80) {
|
|
9
|
+
const normalized = width === undefined || !Number.isFinite(width) ? fallback : Math.max(40, Math.floor(width));
|
|
10
|
+
return { width: normalized, mode: viewportModeForWidth(normalized) };
|
|
11
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
export const DEFAULT_TUI_WIDTH = 100;
|
|
2
|
+
export const MIN_TUI_WIDTH = 40;
|
|
3
|
+
const knownBadges = new Set([
|
|
4
|
+
'ready',
|
|
5
|
+
'deferred',
|
|
6
|
+
'blocked',
|
|
7
|
+
'loading',
|
|
8
|
+
'error',
|
|
9
|
+
'empty',
|
|
10
|
+
'external',
|
|
11
|
+
'mutating',
|
|
12
|
+
'no tui writes',
|
|
13
|
+
'no provider writes',
|
|
14
|
+
'writes provider config',
|
|
15
|
+
'requires confirmation',
|
|
16
|
+
'available',
|
|
17
|
+
'preview-only',
|
|
18
|
+
'manual',
|
|
19
|
+
'coming-soon',
|
|
20
|
+
'unsupported',
|
|
21
|
+
'ready-without-project',
|
|
22
|
+
'project-required',
|
|
23
|
+
]);
|
|
24
|
+
export function normalizeRenderWidth(width) {
|
|
25
|
+
if (width === undefined || !Number.isFinite(width))
|
|
26
|
+
return DEFAULT_TUI_WIDTH;
|
|
27
|
+
return Math.max(MIN_TUI_WIDTH, Math.floor(width));
|
|
28
|
+
}
|
|
29
|
+
export function stripAnsi(value) {
|
|
30
|
+
return value.replace(/\u001B\[[0-?]*[ -/]*[@-~]/g, '');
|
|
31
|
+
}
|
|
32
|
+
export function visibleLength(value) {
|
|
33
|
+
return stripAnsi(value).length;
|
|
34
|
+
}
|
|
35
|
+
export function badge(value, options = {}) {
|
|
36
|
+
const normalized = value
|
|
37
|
+
.trim()
|
|
38
|
+
.replace(/[_\s]+/g, ' ')
|
|
39
|
+
.toLowerCase();
|
|
40
|
+
if (normalized.length === 0)
|
|
41
|
+
return styleBadge('[unknown]', 'unknown', options);
|
|
42
|
+
if (knownBadges.has(normalized)) {
|
|
43
|
+
const label = normalized === 'no tui writes' ? 'no TUI writes' : normalized;
|
|
44
|
+
return styleBadge(`[${label}]`, normalized, options);
|
|
45
|
+
}
|
|
46
|
+
return styleBadge(`[unknown: ${normalized}]`, 'unknown', options);
|
|
47
|
+
}
|
|
48
|
+
export function wrapText(text, options = {}) {
|
|
49
|
+
const width = normalizeRenderWidth(options.width);
|
|
50
|
+
const indent = options.indent ?? '';
|
|
51
|
+
const hangingIndent = options.hangingIndent ?? indent;
|
|
52
|
+
const firstAvailable = Math.max(1, width - visibleLength(indent));
|
|
53
|
+
const hangingAvailable = Math.max(1, width - visibleLength(hangingIndent));
|
|
54
|
+
const words = text.trim().length === 0 ? [''] : text.trim().split(/\s+/);
|
|
55
|
+
const lines = [];
|
|
56
|
+
let currentIndent = indent;
|
|
57
|
+
let available = firstAvailable;
|
|
58
|
+
let current = '';
|
|
59
|
+
for (const word of words) {
|
|
60
|
+
if (current.length === 0) {
|
|
61
|
+
current = word;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (visibleLength(`${current} ${word}`) <= available) {
|
|
65
|
+
current = `${current} ${word}`;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
lines.push(`${currentIndent}${current}`);
|
|
69
|
+
currentIndent = hangingIndent;
|
|
70
|
+
available = hangingAvailable;
|
|
71
|
+
current = word;
|
|
72
|
+
}
|
|
73
|
+
lines.push(`${currentIndent}${current}`);
|
|
74
|
+
return lines;
|
|
75
|
+
}
|
|
76
|
+
export function renderPanel(title, bodyLines, options = {}) {
|
|
77
|
+
const width = normalizeRenderWidth(options.width);
|
|
78
|
+
const contentWidth = Math.max(1, width - 4);
|
|
79
|
+
const status = options.status === undefined ? '' : ` ${badge(options.status, options)}`;
|
|
80
|
+
const titleText = ansi(options, 'title', `${title}${status}`);
|
|
81
|
+
const top = borderedTop(titleText, width, options);
|
|
82
|
+
const body = bodyLines.flatMap((line) => line.split('\n')).flatMap((line) => wrapPanelLine(styleKnownBadges(line, options), contentWidth, options));
|
|
83
|
+
const footer = (options.footerLines ?? []).flatMap((line) => wrapPanelLine(styleKnownBadges(line, options), contentWidth, options));
|
|
84
|
+
return [top, ...[...body, ...footer].map((line) => borderedBody(line, width, options)), borderedBottom(width, options)];
|
|
85
|
+
}
|
|
86
|
+
export function styleFocusedRow(value, options = {}) {
|
|
87
|
+
return ansi(options, 'highlight', value);
|
|
88
|
+
}
|
|
89
|
+
export function renderTabRow(items, options = {}) {
|
|
90
|
+
const width = normalizeRenderWidth(options.width);
|
|
91
|
+
const tokens = items.map((item) => renderTabToken(item, options));
|
|
92
|
+
return wrapTokens('Tabs:', tokens, width);
|
|
93
|
+
}
|
|
94
|
+
function renderTabToken(item, options) {
|
|
95
|
+
if (item.selected && item.focused === true)
|
|
96
|
+
return ansi(options, 'highlight', `› [${item.key}] ${item.label} [selected] [focused]`);
|
|
97
|
+
if (item.selected)
|
|
98
|
+
return ansi(options, 'highlight', `› [${item.key}] ${item.label} [selected]`);
|
|
99
|
+
if (item.focused === true)
|
|
100
|
+
return ansi(options, 'focus', `» [${item.key}] ${item.label} [focused]`);
|
|
101
|
+
return ansi(options, 'dim', `[${item.key}] ${item.label}`);
|
|
102
|
+
}
|
|
103
|
+
export function renderFooterGroups(groups, options = {}) {
|
|
104
|
+
const width = normalizeRenderWidth(options.width);
|
|
105
|
+
const lines = [];
|
|
106
|
+
for (const group of groups) {
|
|
107
|
+
lines.push(...wrapTokens(`${group.label}:`, group.items, width));
|
|
108
|
+
}
|
|
109
|
+
return lines;
|
|
110
|
+
}
|
|
111
|
+
export function renderActionLine(label, options = {}) {
|
|
112
|
+
const labels = (options.labels ?? []).map((value) => badge(value)).join(' ');
|
|
113
|
+
const primary = `- ${label}${labels.length === 0 ? '' : ` ${labels}`}`;
|
|
114
|
+
return [
|
|
115
|
+
...wrapText(primary, options),
|
|
116
|
+
...(options.description === undefined ? [] : wrapText(options.description, { ...options, indent: ' ', hangingIndent: ' ' })),
|
|
117
|
+
...(options.command === undefined || options.command.length === 0
|
|
118
|
+
? []
|
|
119
|
+
: wrapText(`Command: ${options.command.join(' ')}`, { ...options, indent: ' ', hangingIndent: ' ' })),
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
export function joinSections(sections) {
|
|
123
|
+
return sections
|
|
124
|
+
.map((section) => (typeof section === 'string' || section === undefined ? section?.trim() : section.join('\n').trim()))
|
|
125
|
+
.filter((section) => section !== undefined && section.length > 0)
|
|
126
|
+
.join('\n\n');
|
|
127
|
+
}
|
|
128
|
+
function wrapTokens(prefix, tokens, width) {
|
|
129
|
+
const lines = [];
|
|
130
|
+
let current = prefix;
|
|
131
|
+
for (const token of tokens) {
|
|
132
|
+
const separator = current === prefix ? ' ' : ' · ';
|
|
133
|
+
const candidate = `${current}${separator}${token}`;
|
|
134
|
+
if (visibleLength(candidate) <= width || current === prefix) {
|
|
135
|
+
current = candidate;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
lines.push(current);
|
|
139
|
+
current = `${' '.repeat(prefix.length)} ${token}`;
|
|
140
|
+
}
|
|
141
|
+
lines.push(current);
|
|
142
|
+
return lines;
|
|
143
|
+
}
|
|
144
|
+
function wrapPanelLine(line, contentWidth, options) {
|
|
145
|
+
if (visibleLength(line) <= contentWidth)
|
|
146
|
+
return [line];
|
|
147
|
+
return wrapText(line, { ...options, width: contentWidth });
|
|
148
|
+
}
|
|
149
|
+
function borderedTop(title, width, options) {
|
|
150
|
+
const prefix = `┌─ ${title} `;
|
|
151
|
+
return `${ansi(options, 'border', prefix)}${ansi(options, 'border', '─'.repeat(Math.max(0, width - visibleLength(prefix) - 1)))}${ansi(options, 'border', '┐')}`;
|
|
152
|
+
}
|
|
153
|
+
function borderedBody(line, width, options) {
|
|
154
|
+
const padded = `${line}${' '.repeat(Math.max(0, width - visibleLength(line) - 4))}`;
|
|
155
|
+
return `${ansi(options, 'border', '│')} ${padded} ${ansi(options, 'border', '│')}`;
|
|
156
|
+
}
|
|
157
|
+
function borderedBottom(width, options) {
|
|
158
|
+
return ansi(options, 'border', `└${'─'.repeat(Math.max(0, width - 2))}┘`);
|
|
159
|
+
}
|
|
160
|
+
function styleKnownBadges(line, options) {
|
|
161
|
+
if (options.style !== 'ansi')
|
|
162
|
+
return line;
|
|
163
|
+
return line.replace(/\[([^\]]+)\]/g, (match, raw) => {
|
|
164
|
+
const normalized = raw
|
|
165
|
+
.trim()
|
|
166
|
+
.replace(/[_\s]+/g, ' ')
|
|
167
|
+
.toLowerCase();
|
|
168
|
+
return knownBadges.has(normalized) ? styleBadge(match, normalized, options) : match;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function styleBadge(value, status, options) {
|
|
172
|
+
if (options.style !== 'ansi')
|
|
173
|
+
return value;
|
|
174
|
+
if (['ready', 'available', 'ready-without-project'].includes(status))
|
|
175
|
+
return ansi(options, 'green', value);
|
|
176
|
+
if (['blocked', 'error', 'mutating', 'writes provider config'].includes(status))
|
|
177
|
+
return ansi(options, 'red', value);
|
|
178
|
+
if (['deferred', 'loading', 'manual', 'requires confirmation', 'preview-only', 'coming-soon', 'project-required'].includes(status))
|
|
179
|
+
return ansi(options, 'yellow', value);
|
|
180
|
+
if (['external', 'no tui writes', 'no provider writes'].includes(status))
|
|
181
|
+
return ansi(options, 'cyan', value);
|
|
182
|
+
return ansi(options, 'dim', value);
|
|
183
|
+
}
|
|
184
|
+
function ansi(options, role, value) {
|
|
185
|
+
if (options.style !== 'ansi')
|
|
186
|
+
return value;
|
|
187
|
+
const codes = {
|
|
188
|
+
bold: '1',
|
|
189
|
+
title: '1;96',
|
|
190
|
+
dim: '2',
|
|
191
|
+
highlight: '1;7;36',
|
|
192
|
+
focus: '1;36',
|
|
193
|
+
border: '36',
|
|
194
|
+
green: '32',
|
|
195
|
+
red: '31',
|
|
196
|
+
yellow: '33',
|
|
197
|
+
cyan: '36',
|
|
198
|
+
};
|
|
199
|
+
return `\u001B[${codes[role]}m${value}\u001B[0m`;
|
|
200
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function renderVerificationPlan(plan) {
|
|
2
|
+
const lines = [
|
|
3
|
+
'Verification plan',
|
|
4
|
+
`Type: ${plan.selectedChangeType}`,
|
|
5
|
+
'',
|
|
6
|
+
'Recommendations:',
|
|
7
|
+
...plan.recommendations.map((recommendation) => {
|
|
8
|
+
const safety = recommendation.classification === 'allowlisted-command' ? `allowlisted: ${recommendation.commandId}` : 'manual/copy-only';
|
|
9
|
+
const script = recommendation.packageScript === undefined ? '' : ` (${recommendation.packageScript})`;
|
|
10
|
+
return `${recommendation.order}. ${recommendation.title} — ${safety}${script}. ${recommendation.description}`;
|
|
11
|
+
}),
|
|
12
|
+
'',
|
|
13
|
+
'Manual checks:',
|
|
14
|
+
...plan.manualChecks.map((check) => `${check.order}. ${check.title} — ${check.description}`),
|
|
15
|
+
'',
|
|
16
|
+
'Rationale:',
|
|
17
|
+
...plan.rationale.map((reason) => `- ${reason}`),
|
|
18
|
+
'',
|
|
19
|
+
'Safety:',
|
|
20
|
+
'- Read-only plan; commands are not executed.',
|
|
21
|
+
'- Provider config is not written; verification results are not persisted.',
|
|
22
|
+
'- SDD artifacts and human acceptance are not mutated or inferred.',
|
|
23
|
+
];
|
|
24
|
+
return `${lines.join('\n')}\n`;
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { normalizeSddArtifact } from '../../sdd/schema.js';
|
|
2
|
+
export function renderVerificationReportArtifact(input) {
|
|
3
|
+
const normalized = normalizeSddArtifact(input.artifact);
|
|
4
|
+
const lines = [
|
|
5
|
+
'Verification report artifact',
|
|
6
|
+
`Project: ${input.project}`,
|
|
7
|
+
`Change: ${input.change}`,
|
|
8
|
+
`Topic key: ${input.artifact.topicKey}`,
|
|
9
|
+
`Artifact ID: ${input.artifact.id}`,
|
|
10
|
+
`State: ${normalized.metadata.status}`,
|
|
11
|
+
`Accepted: ${normalized.metadata.status === 'accepted' ? 'yes' : 'no'}`,
|
|
12
|
+
'',
|
|
13
|
+
'Safety: manual file-only report; no commands were executed and acceptance is not inferred.',
|
|
14
|
+
'',
|
|
15
|
+
'--- Content ---',
|
|
16
|
+
input.artifact.content,
|
|
17
|
+
];
|
|
18
|
+
return `${lines.join('\n')}\n`;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|