@karajan-family/code 4.21.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/LICENSE +661 -0
- package/README.md +98 -0
- package/bin/karajan-mcp.js +2 -0
- package/bin/kj-rag-mcp.js +75 -0
- package/bin/kj-tail +361 -0
- package/bin/kj.js +2 -0
- package/docs/README.es.md +80 -0
- package/docs/karajan-code-logo-small.png +0 -0
- package/library/logical-clocks-lamport.md +40 -0
- package/package.json +140 -0
- package/packages/ai-trash/README.md +37 -0
- package/packages/ai-trash/bin/kj-trash.js +10 -0
- package/packages/ai-trash/package.json +43 -0
- package/packages/ai-trash/src/cli.js +200 -0
- package/packages/ai-trash/src/destructive-parser.js +74 -0
- package/packages/ai-trash/src/git-snapshot.js +128 -0
- package/packages/ai-trash/src/hook.js +137 -0
- package/packages/ai-trash/src/index.js +14 -0
- package/packages/ai-trash/src/install.js +73 -0
- package/packages/ai-trash/src/logger.js +60 -0
- package/packages/ai-trash/src/manifest.js +91 -0
- package/packages/ai-trash/src/permissions.js +26 -0
- package/packages/ai-trash/src/snapshot.js +66 -0
- package/packages/ai-trash/src/ulid.js +66 -0
- package/packages/hu-board/README.md +69 -0
- package/packages/hu-board/package.json +28 -0
- package/packages/hu-board/public/app.js +259 -0
- package/packages/hu-board/public/index.html +77 -0
- package/packages/hu-board/public/pipeline.css +132 -0
- package/packages/hu-board/public/pipeline.html +48 -0
- package/packages/hu-board/public/pipeline.js +200 -0
- package/packages/hu-board/public/rag.html +21 -0
- package/packages/hu-board/public/rag.js +39 -0
- package/packages/hu-board/public/styles.css +973 -0
- package/packages/hu-board/public/utils/api.js +139 -0
- package/packages/hu-board/public/utils/board-view.js +473 -0
- package/packages/hu-board/public/utils/command-launcher.js +213 -0
- package/packages/hu-board/public/utils/config-editor.js +181 -0
- package/packages/hu-board/public/utils/dashboard-view.js +103 -0
- package/packages/hu-board/public/utils/formatters.js +300 -0
- package/packages/hu-board/public/utils/graph-view.js +216 -0
- package/packages/hu-board/public/utils/hu-actions.js +224 -0
- package/packages/hu-board/public/utils/init-listeners.js +180 -0
- package/packages/hu-board/public/utils/log-panel.js +222 -0
- package/packages/hu-board/public/utils/modals.js +309 -0
- package/packages/hu-board/public/utils/plan-rollup-view.js +53 -0
- package/packages/hu-board/public/utils/preflight-view.js +89 -0
- package/packages/hu-board/public/utils/project-actions.js +143 -0
- package/packages/hu-board/public/utils/project-picker-view.js +139 -0
- package/packages/hu-board/public/utils/run-launcher.js +169 -0
- package/packages/hu-board/public/utils/server-push.js +252 -0
- package/packages/hu-board/public/utils/sessions-view.js +199 -0
- package/packages/hu-board/public/utils/story-detail-view.js +324 -0
- package/packages/hu-board/public/utils/story-edit-form.js +271 -0
- package/packages/hu-board/public/wiki.html +32 -0
- package/packages/hu-board/public/wiki.js +53 -0
- package/packages/hu-board/src/auth.js +92 -0
- package/packages/hu-board/src/boot-info.js +16 -0
- package/packages/hu-board/src/cleanup-zombies.js +145 -0
- package/packages/hu-board/src/command-runner.js +133 -0
- package/packages/hu-board/src/config-yaml.js +531 -0
- package/packages/hu-board/src/db.js +963 -0
- package/packages/hu-board/src/ephemeral-cleaner.js +196 -0
- package/packages/hu-board/src/event-bus.js +58 -0
- package/packages/hu-board/src/format.js +207 -0
- package/packages/hu-board/src/hu-zombie-reaper.js +103 -0
- package/packages/hu-board/src/journal-parser.js +180 -0
- package/packages/hu-board/src/plan-mutations.js +424 -0
- package/packages/hu-board/src/preflight.js +286 -0
- package/packages/hu-board/src/routes/api.js +1374 -0
- package/packages/hu-board/src/routes/pipeline.js +45 -0
- package/packages/hu-board/src/routes/rag.js +42 -0
- package/packages/hu-board/src/routes/wiki.js +43 -0
- package/packages/hu-board/src/run-tracker.js +121 -0
- package/packages/hu-board/src/server.js +438 -0
- package/packages/hu-board/src/sync.js +732 -0
- package/packages/hu-board/src/token-store.js +56 -0
- package/packages/hu-board/src/zombie-reaper.js +206 -0
- package/scripts/ai-attribution-guard.yml +84 -0
- package/scripts/audit-test-diet.mjs +151 -0
- package/scripts/build-sea.mjs +150 -0
- package/scripts/diet-baseline.mjs +170 -0
- package/scripts/dual-publish.mjs +67 -0
- package/scripts/esbuild-sea.config.mjs +273 -0
- package/scripts/git-hooks/post-merge +18 -0
- package/scripts/install-binary.ps1 +174 -0
- package/scripts/install-binary.sh +159 -0
- package/scripts/install-guard-all-repos.sh +85 -0
- package/scripts/install-kj.sh +193 -0
- package/scripts/install.js +901 -0
- package/scripts/install.sh +7 -0
- package/scripts/postinstall.js +117 -0
- package/scripts/protect-all-repos.sh +88 -0
- package/scripts/quickstart-gate.mjs +97 -0
- package/scripts/regen-arch-stats.sh +71 -0
- package/scripts/setup-multi-instance.sh +150 -0
- package/scripts/verify-pack.mjs +278 -0
- package/src/activity-log.js +59 -0
- package/src/agents/agy-agent.js +62 -0
- package/src/agents/aider-agent.js +78 -0
- package/src/agents/availability.js +52 -0
- package/src/agents/base-agent.js +134 -0
- package/src/agents/claude-agent.js +413 -0
- package/src/agents/codex-agent.js +112 -0
- package/src/agents/copilot-agent.js +65 -0
- package/src/agents/gemini-agent.js +85 -0
- package/src/agents/host-agent.js +38 -0
- package/src/agents/index.js +59 -0
- package/src/agents/kimi-agent.js +45 -0
- package/src/agents/model-registry.js +137 -0
- package/src/agents/opencode-agent.js +72 -0
- package/src/agents/qwen-agent.js +20 -0
- package/src/agents/resolve-bin.js +73 -0
- package/src/audit/agent-readiness.js +259 -0
- package/src/audit/ai-slop-findings.js +102 -0
- package/src/audit/audit-fallback.js +66 -0
- package/src/audit/audit-history-display.js +61 -0
- package/src/audit/audit-history.js +102 -0
- package/src/audit/basal-cost.js +281 -0
- package/src/audit/circular-deps.js +144 -0
- package/src/audit/dead-exports.js +186 -0
- package/src/audit/deterministic-summary.js +327 -0
- package/src/audit/harness-scorecard.js +100 -0
- package/src/audit/harness-section.js +81 -0
- package/src/audit/infra-findings.js +100 -0
- package/src/audit/injection-findings.js +114 -0
- package/src/audit/issue-filter.js +133 -0
- package/src/audit/osv-findings.js +167 -0
- package/src/audit/plan-adherence.js +224 -0
- package/src/audit/semgrep-findings.js +129 -0
- package/src/audit/sonar-findings.js +93 -0
- package/src/audit/webperf-input.js +133 -0
- package/src/autonomy/arbiter-role.js +71 -0
- package/src/autonomy/arbiter.js +22 -0
- package/src/autonomy/decider.js +18 -0
- package/src/autonomy/decision-resolver.js +58 -0
- package/src/autonomy/outcome-report.js +55 -0
- package/src/autonomy/policy.js +41 -0
- package/src/autonomy/stage-ask.js +30 -0
- package/src/bootstrap.js +276 -0
- package/src/brain/agent-error-classifier.js +116 -0
- package/src/brain/decision-tracker.js +125 -0
- package/src/brain/decisor.js +243 -0
- package/src/brain/solomon-consult.js +171 -0
- package/src/brain/standby-scheduler.js +8 -0
- package/src/brain/standby-store.js +12 -0
- package/src/brain/with-brain-recovery.js +235 -0
- package/src/budget/comparison.js +96 -0
- package/src/canvas/parse-md.js +238 -0
- package/src/canvas/schema.js +101 -0
- package/src/canvas/to-flat.js +85 -0
- package/src/canvas/validate.js +163 -0
- package/src/checks/ai-surface.js +79 -0
- package/src/checks/ai-trash.js +34 -0
- package/src/checks/binaries.js +207 -0
- package/src/checks/ci.js +105 -0
- package/src/checks/config-files.js +217 -0
- package/src/checks/dir-setup.js +103 -0
- package/src/checks/guarantee-level.js +38 -0
- package/src/checks/hardware.js +150 -0
- package/src/checks/harness-scorecard.js +41 -0
- package/src/checks/mcp-health.js +169 -0
- package/src/checks/method.js +73 -0
- package/src/checks/native-build.js +67 -0
- package/src/checks/node.js +70 -0
- package/src/checks/ollama.js +41 -0
- package/src/checks/orphans.js +77 -0
- package/src/checks/ports.js +188 -0
- package/src/checks/project-checks.js +245 -0
- package/src/checks/qmd.js +41 -0
- package/src/checks/rag-hooks.js +54 -0
- package/src/checks/release-check.js +102 -0
- package/src/checks/rtk.js +36 -0
- package/src/checks/runner.js +326 -0
- package/src/checks/skills.js +53 -0
- package/src/checks/sonar.js +67 -0
- package/src/checks/squeezr.js +36 -0
- package/src/checks/system.js +53 -0
- package/src/checks/tokens.js +172 -0
- package/src/checks/types.js +103 -0
- package/src/ci/dispatch.js +99 -0
- package/src/ci/index.js +3 -0
- package/src/ci/pr-diff.js +26 -0
- package/src/ci/repo.js +45 -0
- package/src/cli/_shared.js +30 -0
- package/src/cli/advanced-commands.js +61 -0
- package/src/cli/register-meta.js +772 -0
- package/src/cli/register-pipeline.js +335 -0
- package/src/cli/register-plan.js +224 -0
- package/src/cli/register-roles-skills.js +54 -0
- package/src/cli/register-sonar.js +28 -0
- package/src/cli/register-standby.js +26 -0
- package/src/cli.js +155 -0
- package/src/commands/advanced.js +31 -0
- package/src/commands/agent-run.js +63 -0
- package/src/commands/agents.js +105 -0
- package/src/commands/architect.js +123 -0
- package/src/commands/audit.js +430 -0
- package/src/commands/autorun.js +49 -0
- package/src/commands/board.js +458 -0
- package/src/commands/check.js +40 -0
- package/src/commands/clean.js +145 -0
- package/src/commands/code.js +45 -0
- package/src/commands/config.js +74 -0
- package/src/commands/discover.js +105 -0
- package/src/commands/doctor.js +251 -0
- package/src/commands/env.js +207 -0
- package/src/commands/harden.js +203 -0
- package/src/commands/hu.js +210 -0
- package/src/commands/identity.js +60 -0
- package/src/commands/init.js +950 -0
- package/src/commands/install-tools.js +432 -0
- package/src/commands/mutate.js +94 -0
- package/src/commands/ollama.js +44 -0
- package/src/commands/onboard.js +45 -0
- package/src/commands/plan/_shared.js +55 -0
- package/src/commands/plan/add-hu.js +23 -0
- package/src/commands/plan/delete.js +9 -0
- package/src/commands/plan/fix.js +99 -0
- package/src/commands/plan/generate.js +532 -0
- package/src/commands/plan/index.js +13 -0
- package/src/commands/plan/list.js +21 -0
- package/src/commands/plan/migrate-result.js +41 -0
- package/src/commands/plan/ready.js +46 -0
- package/src/commands/plan/remove-hu.js +17 -0
- package/src/commands/plan/share.js +85 -0
- package/src/commands/plan/show.js +81 -0
- package/src/commands/plan/unshare.js +41 -0
- package/src/commands/plan/validate.js +20 -0
- package/src/commands/plan.js +17 -0
- package/src/commands/policy.js +164 -0
- package/src/commands/privacy.js +45 -0
- package/src/commands/qmd.js +86 -0
- package/src/commands/rag-mcp.js +18 -0
- package/src/commands/rag.js +173 -0
- package/src/commands/report-issue.js +77 -0
- package/src/commands/report.js +469 -0
- package/src/commands/researcher.js +54 -0
- package/src/commands/resume.js +68 -0
- package/src/commands/review-gate.js +355 -0
- package/src/commands/review.js +89 -0
- package/src/commands/roles.js +116 -0
- package/src/commands/run.js +185 -0
- package/src/commands/scan.js +18 -0
- package/src/commands/skills.js +86 -0
- package/src/commands/sonar.js +53 -0
- package/src/commands/standby.js +117 -0
- package/src/commands/start.js +121 -0
- package/src/commands/status.js +36 -0
- package/src/commands/sync.js +103 -0
- package/src/commands/telemetry.js +70 -0
- package/src/commands/tournament.js +85 -0
- package/src/commands/triage.js +78 -0
- package/src/commands/undo.js +62 -0
- package/src/commands/watch.js +46 -0
- package/src/commands/webperf.js +162 -0
- package/src/commands/worktree.js +76 -0
- package/src/config/defaults.js +270 -0
- package/src/config/loader.js +204 -0
- package/src/config/overrides.js +220 -0
- package/src/config/role-resolver.js +171 -0
- package/src/config/schema.js +299 -0
- package/src/config/test-harness.js +78 -0
- package/src/config.js +34 -0
- package/src/domains/domain-loader.js +245 -0
- package/src/domains/domain-registry.js +140 -0
- package/src/domains/domain-synthesizer.js +129 -0
- package/src/environment/adr.js +45 -0
- package/src/environment/board-access.js +97 -0
- package/src/environment/board-select.js +59 -0
- package/src/environment/briefs.js +129 -0
- package/src/environment/issue-report.js +72 -0
- package/src/environment/mcp-wiring.js +44 -0
- package/src/environment/playbook.js +127 -0
- package/src/git/automation.js +334 -0
- package/src/git/hu-automation.js +171 -0
- package/src/git/hu-snapshot.js +10 -0
- package/src/golden/asserter.js +92 -0
- package/src/golden/loader.js +52 -0
- package/src/golden/runner.js +92 -0
- package/src/golden/schema.js +41 -0
- package/src/guards/intent-guard.js +161 -0
- package/src/guards/output-guard.js +149 -0
- package/src/guards/perf-guard.js +126 -0
- package/src/guards/policy-guard.js +90 -0
- package/src/guards/policy-resolver.js +85 -0
- package/src/guards/secret-redactor.js +71 -0
- package/src/harden/advisory.js +203 -0
- package/src/harden/alternatives.js +50 -0
- package/src/harden/check.js +81 -0
- package/src/harden/config-engine.js +128 -0
- package/src/harden/config-templates.js +122 -0
- package/src/harden/guidelines-engine.js +48 -0
- package/src/harden/guidelines-templates.js +36 -0
- package/src/harden/harden-engine.js +80 -0
- package/src/harden/harness-hooks.js +107 -0
- package/src/harden/hook-commands.js +25 -0
- package/src/harden/hook-templates.js +183 -0
- package/src/harden/interactive.js +76 -0
- package/src/harden/sentinel-hooks.js +721 -0
- package/src/harden/stack-roots.js +105 -0
- package/src/harden/test-on-push.js +38 -0
- package/src/harden/workflow-engine.js +116 -0
- package/src/harden/workflow-templates.js +285 -0
- package/src/hu/acceptance-runner.js +138 -0
- package/src/hu/auto-generator.js +358 -0
- package/src/hu/graph.js +71 -0
- package/src/hu/lazy-planner.js +109 -0
- package/src/hu/model-router.js +108 -0
- package/src/hu/parallel-executor.js +94 -0
- package/src/hu/split-validator.js +143 -0
- package/src/hu/splitting-detector.js +158 -0
- package/src/hu/splitting-generator.js +175 -0
- package/src/hu/store.js +392 -0
- package/src/hu/worktree-bootstrap.js +59 -0
- package/src/identity/bootstrap.js +48 -0
- package/src/identity/compare.js +38 -0
- package/src/identity/detect.js +51 -0
- package/src/identity/store.js +66 -0
- package/src/infrastructure/command-runner.js +44 -0
- package/src/infrastructure/environment.js +38 -0
- package/src/infrastructure/file-system-service.js +63 -0
- package/src/infrastructure/mocks.js +182 -0
- package/src/lang/chunk-go.js +94 -0
- package/src/lang/chunk-java.js +90 -0
- package/src/lang/chunk-python.js +88 -0
- package/src/lang/chunk-rust.js +102 -0
- package/src/lang/go.js +14 -0
- package/src/lang/java.js +16 -0
- package/src/lang/js.js +8 -0
- package/src/lang/python.js +14 -0
- package/src/lang/registry.js +79 -0
- package/src/lang/rust.js +14 -0
- package/src/lang/tree-sitter-loader.js +45 -0
- package/src/mcp/direct-role-runner.js +112 -0
- package/src/mcp/error-classifiers.js +66 -0
- package/src/mcp/handlers/direct-handlers.js +486 -0
- package/src/mcp/handlers/hu-handlers.js +93 -0
- package/src/mcp/handlers/management-handlers.js +265 -0
- package/src/mcp/handlers/rag-handler.js +52 -0
- package/src/mcp/handlers/run-handler.js +313 -0
- package/src/mcp/orphan-guard.js +131 -0
- package/src/mcp/preflight.js +47 -0
- package/src/mcp/progress.js +149 -0
- package/src/mcp/response-compressor.js +81 -0
- package/src/mcp/run-kj.js +135 -0
- package/src/mcp/server-handlers.js +79 -0
- package/src/mcp/server.js +66 -0
- package/src/mcp/shared-helpers.js +297 -0
- package/src/mcp/sovereignty-guard.js +112 -0
- package/src/mcp/suggest-handler.js +92 -0
- package/src/mcp/tool-arg-normalizers.js +16 -0
- package/src/mcp/tools.js +432 -0
- package/src/mutate/diff-scope.js +105 -0
- package/src/mutate/reviewer-signal.js +76 -0
- package/src/mutate/runner.js +72 -0
- package/src/mutate/tool-registry.js +90 -0
- package/src/onboarder/cache.js +24 -0
- package/src/onboarder/collectors/framework-multilang.js +64 -0
- package/src/onboarder/collectors/index.js +136 -0
- package/src/orchestrator/agent-fallback.js +81 -0
- package/src/orchestrator/brain-coordinator.js +186 -0
- package/src/orchestrator/ci-integration.js +139 -0
- package/src/orchestrator/config-init.js +510 -0
- package/src/orchestrator/direct-actions.js +217 -0
- package/src/orchestrator/drivers/error-recovery.js +287 -0
- package/src/orchestrator/drivers/init-context.js +227 -0
- package/src/orchestrator/drivers/iteration-loop.js +380 -0
- package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +69 -0
- package/src/orchestrator/drivers/iteration-phases/guards.js +84 -0
- package/src/orchestrator/drivers/iteration-phases/handle-approved.js +29 -0
- package/src/orchestrator/drivers/iteration-phases/quality-gates.js +114 -0
- package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +60 -0
- package/src/orchestrator/drivers/post-loop.js +383 -0
- package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +136 -0
- package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +47 -0
- package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +84 -0
- package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +391 -0
- package/src/orchestrator/drivers/pre-loop.js +507 -0
- package/src/orchestrator/drivers/run-hu-batch.js +427 -0
- package/src/orchestrator/feedback-enrichment.js +140 -0
- package/src/orchestrator/feedback-queue.js +151 -0
- package/src/orchestrator/flow-control.js +170 -0
- package/src/orchestrator/flow-runner.js +364 -0
- package/src/orchestrator/fs-leak-detector.js +210 -0
- package/src/orchestrator/hu-scheduler.js +114 -0
- package/src/orchestrator/hu-sub-pipeline.js +616 -0
- package/src/orchestrator/integrations.js +81 -0
- package/src/orchestrator/iteration-gate.js +73 -0
- package/src/orchestrator/iteration-stages.js +9 -0
- package/src/orchestrator/parallel-limiter.js +74 -0
- package/src/orchestrator/pipeline-context.js +72 -0
- package/src/orchestrator/post-loop-stages.js +468 -0
- package/src/orchestrator/pre-loop-stages.js +11 -0
- package/src/orchestrator/preflight-checks.js +462 -0
- package/src/orchestrator/repair/repair-detector.js +117 -0
- package/src/orchestrator/repair/repair-runner.js +142 -0
- package/src/orchestrator/reviewer-fallback.js +45 -0
- package/src/orchestrator/role-output-compressor.js +189 -0
- package/src/orchestrator/session-journal.js +308 -0
- package/src/orchestrator/solomon-escalation.js +305 -0
- package/src/orchestrator/solomon-rules.js +212 -0
- package/src/orchestrator/stages/architect-stage.js +172 -0
- package/src/orchestrator/stages/coder-stage.js +480 -0
- package/src/orchestrator/stages/domain-curator-stage.js +82 -0
- package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +127 -0
- package/src/orchestrator/stages/hu-reviewer-stage.js +394 -0
- package/src/orchestrator/stages/perf-stage.js +140 -0
- package/src/orchestrator/stages/planner-stage.js +85 -0
- package/src/orchestrator/stages/rag-context-stage.js +77 -0
- package/src/orchestrator/stages/rag-preload-decisor.js +58 -0
- package/src/orchestrator/stages/research-stage.js +69 -0
- package/src/orchestrator/stages/reviewer-stage.js +422 -0
- package/src/orchestrator/stages/sonar-stage.js +421 -0
- package/src/orchestrator/stages/stage-classes.js +84 -0
- package/src/orchestrator/stages/stage-executor.js +155 -0
- package/src/orchestrator/stages/tdd-discipline-stage.js +56 -0
- package/src/orchestrator/stages/tool-judge-stage.js +53 -0
- package/src/orchestrator/stages/triage-stage.js +172 -0
- package/src/orchestrator/standby.js +71 -0
- package/src/orchestrator/verification-gate.js +183 -0
- package/src/orchestrator.js +22 -0
- package/src/plan/adr-generator.js +170 -0
- package/src/plan/adr-loader.js +60 -0
- package/src/plan/plan-executor.js +100 -0
- package/src/plan/plan-fixer.js +192 -0
- package/src/plan/plan-hu-ops.js +16 -0
- package/src/plan/plan-id.js +4 -0
- package/src/plan/plan-migrate-result.js +24 -0
- package/src/plan/plan-reviewer.js +236 -0
- package/src/plan/plan-schema.js +334 -0
- package/src/plan/plan-store.js +260 -0
- package/src/plan/plan-structural-pass.js +122 -0
- package/src/plan/plan-validation.js +4 -0
- package/src/plan/preflight-hu.js +105 -0
- package/src/plan/spec-detector.js +61 -0
- package/src/plan/tests-synthesizer.js +131 -0
- package/src/planning-game/adapter.js +108 -0
- package/src/planning-game/architect-adrs.js +45 -0
- package/src/planning-game/client.js +108 -0
- package/src/planning-game/decomposition.js +87 -0
- package/src/planning-game/pipeline-adapter.js +251 -0
- package/src/plugins/loader.js +67 -0
- package/src/policy/add.js +111 -0
- package/src/policy/decisions.js +42 -0
- package/src/policy/engine.js +82 -0
- package/src/policy/exceptions.js +60 -0
- package/src/privacy/onboarding.js +35 -0
- package/src/privacy/scan.js +120 -0
- package/src/prompts/arbiter.js +38 -0
- package/src/prompts/architect.js +103 -0
- package/src/prompts/audit.js +474 -0
- package/src/prompts/coder.js +287 -0
- package/src/prompts/diff-clip.js +27 -0
- package/src/prompts/discover.js +222 -0
- package/src/prompts/hu-reviewer.js +219 -0
- package/src/prompts/planner.js +312 -0
- package/src/prompts/prompt-layout.js +80 -0
- package/src/prompts/prompt-resolver.js +120 -0
- package/src/prompts/reviewer.js +75 -0
- package/src/prompts/rtk-snippet.js +25 -0
- package/src/prompts/spec-reviewer.js +66 -0
- package/src/prompts/split-signal.js +82 -0
- package/src/prompts/start-decision.js +52 -0
- package/src/prompts/tool-correctness-judge.js +31 -0
- package/src/prompts/triage.js +57 -0
- package/src/rag/auto-update.js +72 -0
- package/src/rag/chunker-ast.js +56 -0
- package/src/rag/chunker.js +132 -0
- package/src/rag/embedder.js +2 -0
- package/src/rag/embedders/_cloud-base.js +2 -0
- package/src/rag/embedders/cohere.js +2 -0
- package/src/rag/embedders/factory.js +2 -0
- package/src/rag/embedders/mistral.js +2 -0
- package/src/rag/embedders/onnx.js +2 -0
- package/src/rag/embedders/openai.js +2 -0
- package/src/rag/embedders/voyage.js +2 -0
- package/src/rag/eval.js +61 -0
- package/src/rag/governed-embedder.js +39 -0
- package/src/rag/indexer.js +199 -0
- package/src/rag/library.js +62 -0
- package/src/rag/ollama-capability.js +59 -0
- package/src/rag/ollama-manager.js +98 -0
- package/src/rag/onnx-fallback.js +69 -0
- package/src/rag/rerank.js +4 -0
- package/src/rag/retriever.js +2 -0
- package/src/rag/vec-store.js +17 -0
- package/src/rag/watcher.js +62 -0
- package/src/rag/where-parser.js +4 -0
- package/src/repeat-detector.js +88 -0
- package/src/review/card-first.js +99 -0
- package/src/review/card-verify.js +83 -0
- package/src/review/diff-generator.js +112 -0
- package/src/review/gate-gitignore.js +77 -0
- package/src/review/git-stash-helper.js +104 -0
- package/src/review/mutation-pregate.js +48 -0
- package/src/review/one-shot-review.js +122 -0
- package/src/review/parser.js +80 -0
- package/src/review/policy-gate.js +26 -0
- package/src/review/profiles.js +66 -0
- package/src/review/reviewer-fallback.js +125 -0
- package/src/review/schema.js +31 -0
- package/src/review/scope-filter.js +152 -0
- package/src/review/snapshot-diff.js +122 -0
- package/src/review/solomon-arbitration.js +113 -0
- package/src/review/sonar-pregate.js +63 -0
- package/src/review/tdd-discipline.js +90 -0
- package/src/review/tdd-policy.js +69 -0
- package/src/review/tests-with-code.js +33 -0
- package/src/review/verdict-store.js +87 -0
- package/src/review/workspace.js +21 -0
- package/src/roles/agent-role.js +194 -0
- package/src/roles/architect-role.js +77 -0
- package/src/roles/audit-role.js +258 -0
- package/src/roles/base-role.js +165 -0
- package/src/roles/coder-role.js +107 -0
- package/src/roles/commiter-role.js +110 -0
- package/src/roles/discover-role.js +81 -0
- package/src/roles/domain-curator-role.js +141 -0
- package/src/roles/hu-reviewer-role.js +64 -0
- package/src/roles/impeccable-role.js +85 -0
- package/src/roles/index.js +18 -0
- package/src/roles/karajan-brain-role.js +134 -0
- package/src/roles/onboarder-role.js +61 -0
- package/src/roles/perf-role.js +122 -0
- package/src/roles/planner-role.js +151 -0
- package/src/roles/refactorer-role.js +30 -0
- package/src/roles/repairer-role.js +181 -0
- package/src/roles/researcher-role.js +70 -0
- package/src/roles/reviewer-role.js +104 -0
- package/src/roles/security-role.js +73 -0
- package/src/roles/solomon-role.js +265 -0
- package/src/roles/sonar-role.js +70 -0
- package/src/roles/spec-reviewer-role.js +106 -0
- package/src/roles/tester-role.js +235 -0
- package/src/roles/tool-correctness-judge-role.js +78 -0
- package/src/roles/triage-role.js +99 -0
- package/src/session/journal/decisions-writer.js +200 -0
- package/src/session/journal/iteration-logger.js +194 -0
- package/src/session/journal/summary-writer.js +320 -0
- package/src/session/journal/tree-writer.js +164 -0
- package/src/session/journal/write-all.js +89 -0
- package/src/session/mutators.js +339 -0
- package/src/session/runtime-overrides.js +59 -0
- package/src/session/store.js +106 -0
- package/src/session-cleanup.js +116 -0
- package/src/skills/addyosmani-catalog.js +315 -0
- package/src/skills/addyosmani-role-map.js +139 -0
- package/src/skills/openskills-client.js +157 -0
- package/src/skills/semantic-detector.js +167 -0
- package/src/skills/skill-detector.js +385 -0
- package/src/skills/skill-loader.js +219 -0
- package/src/skills/skills-cache.js +128 -0
- package/src/sonar/api.js +128 -0
- package/src/sonar/cloud-scanner.js +78 -0
- package/src/sonar/config-resolver.js +88 -0
- package/src/sonar/credentials.js +60 -0
- package/src/sonar/discovery.js +124 -0
- package/src/sonar/enforcer.js +19 -0
- package/src/sonar/issue-filter.js +12 -0
- package/src/sonar/manager.js +181 -0
- package/src/sonar/project-key.js +120 -0
- package/src/sonar/scanner.js +307 -0
- package/src/sonar/token-bootstrap.js +205 -0
- package/src/sonar/token-recovery.js +67 -0
- package/src/spec-review/refine-loop.js +58 -0
- package/src/spec-review/run-spec-review.js +119 -0
- package/src/start/assessment.js +74 -0
- package/src/start/maturity.js +73 -0
- package/src/start/start-decider-role.js +79 -0
- package/src/start/sweep.js +157 -0
- package/src/sync/apply-canvas-patch.js +55 -0
- package/src/sync/detect-drift.js +113 -0
- package/src/tournament/crown.js +88 -0
- package/src/tournament/judge.js +150 -0
- package/src/tournament/run.js +142 -0
- package/src/tournament/scoreboard.js +124 -0
- package/src/tracker-bootstrap.js +44 -0
- package/src/types/agent.js +55 -0
- package/src/types/config.js +114 -0
- package/src/types/hu.js +47 -0
- package/src/types/index.js +38 -0
- package/src/types/policy.js +43 -0
- package/src/types/session.js +75 -0
- package/src/types/solomon.js +87 -0
- package/src/types/stage.js +68 -0
- package/src/utils/agent-detect.js +93 -0
- package/src/utils/ai-trash.js +48 -0
- package/src/utils/async-lock.js +31 -0
- package/src/utils/atomic-write.js +6 -0
- package/src/utils/banner.js +66 -0
- package/src/utils/binary-sources.js +70 -0
- package/src/utils/board-prompt-bridge.js +108 -0
- package/src/utils/budget.js +229 -0
- package/src/utils/cli-ask-question.js +93 -0
- package/src/utils/cli-progress.js +220 -0
- package/src/utils/cli-run-log.js +83 -0
- package/src/utils/cwd-confirm.js +39 -0
- package/src/utils/derive-project-name-from-cwd.js +119 -0
- package/src/utils/display/event-handlers.js +403 -0
- package/src/utils/display/formatters.js +132 -0
- package/src/utils/display/header.js +47 -0
- package/src/utils/display/resume-hint.js +41 -0
- package/src/utils/display/session-summary.js +118 -0
- package/src/utils/display/solomon.js +42 -0
- package/src/utils/display/spec-findings.js +44 -0
- package/src/utils/doc-links.js +29 -0
- package/src/utils/docker-install.js +34 -0
- package/src/utils/escape-regexp.js +15 -0
- package/src/utils/events.js +35 -0
- package/src/utils/fs.js +19 -0
- package/src/utils/garbage-collector.js +481 -0
- package/src/utils/git.js +279 -0
- package/src/utils/home-migration.js +87 -0
- package/src/utils/injection-guard.js +186 -0
- package/src/utils/install-hints.js +180 -0
- package/src/utils/json-extract.js +64 -0
- package/src/utils/locale.js +59 -0
- package/src/utils/logger.js +96 -0
- package/src/utils/managed-markers.js +93 -0
- package/src/utils/manifest-sniff.js +82 -0
- package/src/utils/messages.js +61 -0
- package/src/utils/model-selector.js +107 -0
- package/src/utils/os-detect.js +79 -0
- package/src/utils/paths.js +13 -0
- package/src/utils/pending-user-action.js +95 -0
- package/src/utils/port-check.js +6 -0
- package/src/utils/port-occupant.js +96 -0
- package/src/utils/pricing.js +29 -0
- package/src/utils/process.js +4 -0
- package/src/utils/project-detect.js +160 -0
- package/src/utils/prompt-project-name.js +35 -0
- package/src/utils/provider-env.js +116 -0
- package/src/utils/qmd-collection.js +72 -0
- package/src/utils/qmd-detect.js +18 -0
- package/src/utils/qmd-install.js +37 -0
- package/src/utils/quota-simulator.js +56 -0
- package/src/utils/rate-limit-detector.js +181 -0
- package/src/utils/repo-cleaner.js +79 -0
- package/src/utils/retry.js +88 -0
- package/src/utils/role-assigner.js +137 -0
- package/src/utils/role-env.js +58 -0
- package/src/utils/rtk-detect.js +18 -0
- package/src/utils/rtk-install.js +38 -0
- package/src/utils/rtk-wrapper.js +87 -0
- package/src/utils/run-context.js +75 -0
- package/src/utils/run-log.js +217 -0
- package/src/utils/run-registry.js +9 -0
- package/src/utils/shared-paths.js +12 -0
- package/src/utils/squeezr-detect.js +21 -0
- package/src/utils/squeezr-install.js +37 -0
- package/src/utils/stack-detect.js +135 -0
- package/src/utils/stall-detector.js +159 -0
- package/src/utils/status-dashboard.js +254 -0
- package/src/utils/task-file.js +109 -0
- package/src/utils/telemetry.js +124 -0
- package/src/utils/templates-root.js +61 -0
- package/src/utils/tool-call-extractor.js +56 -0
- package/src/utils/tool-governor.js +116 -0
- package/src/utils/tool-installer.js +93 -0
- package/src/utils/update-check.js +280 -0
- package/src/utils/vector-store-orphans.js +89 -0
- package/src/utils/welcome.js +47 -0
- package/src/utils/with-timeout.js +42 -0
- package/src/utils/wizard.js +47 -0
- package/src/webperf/cwv-gate.js +94 -0
- package/src/webperf/devtools-detect.js +112 -0
- package/src/webperf/scanner.js +209 -0
- package/src/webperf/webperf-role-integration.js +66 -0
- package/templates/coder-rules.md +45 -0
- package/templates/docker-compose.sonar.yml +60 -0
- package/templates/domains/example-dental.md +57 -0
- package/templates/kj.config.yml +128 -0
- package/templates/review-rules.md +17 -0
- package/templates/roles/architect/anthropic.md +74 -0
- package/templates/roles/architect/default.md +72 -0
- package/templates/roles/architect/google.md +61 -0
- package/templates/roles/architect/openai.md +60 -0
- package/templates/roles/architect/opencode.md +59 -0
- package/templates/roles/architect.md +76 -0
- package/templates/roles/audit.md +68 -0
- package/templates/roles/coder/anthropic.md +81 -0
- package/templates/roles/coder/default.md +78 -0
- package/templates/roles/coder/google.md +87 -0
- package/templates/roles/coder/openai.md +68 -0
- package/templates/roles/coder/opencode.md +58 -0
- package/templates/roles/coder.md +152 -0
- package/templates/roles/commiter.md +44 -0
- package/templates/roles/discover.md +167 -0
- package/templates/roles/domain-curator.md +52 -0
- package/templates/roles/hu-reviewer.md +236 -0
- package/templates/roles/impeccable-design.md +87 -0
- package/templates/roles/impeccable.md +125 -0
- package/templates/roles/karajan-brain.md +95 -0
- package/templates/roles/onboarder.md +45 -0
- package/templates/roles/planner/anthropic.md +59 -0
- package/templates/roles/planner/default.md +57 -0
- package/templates/roles/planner/google.md +75 -0
- package/templates/roles/planner/openai.md +55 -0
- package/templates/roles/planner/opencode.md +62 -0
- package/templates/roles/planner.md +61 -0
- package/templates/roles/refactorer.md +48 -0
- package/templates/roles/repairer.md +103 -0
- package/templates/roles/researcher.md +41 -0
- package/templates/roles/reviewer/anthropic.md +61 -0
- package/templates/roles/reviewer/default.md +62 -0
- package/templates/roles/reviewer/google.md +63 -0
- package/templates/roles/reviewer/openai.md +57 -0
- package/templates/roles/reviewer/opencode.md +42 -0
- package/templates/roles/reviewer-paranoid.md +38 -0
- package/templates/roles/reviewer-relaxed.md +34 -0
- package/templates/roles/reviewer-strict.md +37 -0
- package/templates/roles/reviewer.md +62 -0
- package/templates/roles/security.md +54 -0
- package/templates/roles/solomon/anthropic.md +71 -0
- package/templates/roles/solomon/default.md +83 -0
- package/templates/roles/solomon/google.md +61 -0
- package/templates/roles/solomon/openai.md +53 -0
- package/templates/roles/solomon/opencode.md +55 -0
- package/templates/roles/solomon.md +83 -0
- package/templates/roles/sonar.md +49 -0
- package/templates/roles/spec-reviewer.md +47 -0
- package/templates/roles/tester.md +50 -0
- package/templates/roles/triage.md +69 -0
- package/templates/skills/kj-architect.md +45 -0
- package/templates/skills/kj-audit.md +63 -0
- package/templates/skills/kj-board.md +16 -0
- package/templates/skills/kj-code.md +51 -0
- package/templates/skills/kj-csv-transform.md +40 -0
- package/templates/skills/kj-data-report.md +44 -0
- package/templates/skills/kj-discover.md +24 -0
- package/templates/skills/kj-rag-query.md +50 -0
- package/templates/skills/kj-review.md +47 -0
- package/templates/skills/kj-run.md +73 -0
- package/templates/skills/kj-security.md +49 -0
- package/templates/skills/kj-sonar.md +41 -0
- package/templates/skills/kj-sql-analysis.md +40 -0
- package/templates/skills/kj-test.md +40 -0
- package/templates/workflows/automerge.yml +30 -0
- package/templates/workflows/houston-override.yml +46 -0
- package/templates/workflows/kj-ci-gateway.yml +58 -0
- package/vendor/tree-sitter-grammars/README.md +21 -0
- package/vendor/tree-sitter-grammars/go.wasm +0 -0
- package/vendor/tree-sitter-grammars/java.wasm +0 -0
- package/vendor/tree-sitter-grammars/python.wasm +0 -0
- package/vendor/tree-sitter-grammars/rust.wasm +0 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { runFlow } from "../orchestrator.js";
|
|
3
|
+
import { assertAgentsAvailable } from "../agents/availability.js";
|
|
4
|
+
import { createActivityLog } from "../activity-log.js";
|
|
5
|
+
import { withCliRunLog } from "../utils/cli-run-log.js";
|
|
6
|
+
import { registerRun, unregisterRun } from "../utils/run-registry.js";
|
|
7
|
+
import { printHeader } from "../utils/display/header.js";
|
|
8
|
+
import { printEvent } from "../utils/display/event-handlers.js";
|
|
9
|
+
import { printResumeHint } from "../utils/display/resume-hint.js";
|
|
10
|
+
import { resolveRole } from "../config.js";
|
|
11
|
+
import { parseCardId } from "../planning-game/adapter.js";
|
|
12
|
+
import { confirmCwd } from "../utils/cwd-confirm.js";
|
|
13
|
+
import { runSpecReview } from "../spec-review/run-spec-review.js";
|
|
14
|
+
import { maybeAutoUpdate } from "../rag/auto-update.js";
|
|
15
|
+
|
|
16
|
+
// Re-export the shared helper so existing imports (tests, MCP wrappers)
|
|
17
|
+
// keep working. KJC-BUG-0081 round 2 split the body into utils/ because
|
|
18
|
+
// resume.js also needs the same contract.
|
|
19
|
+
import { createCliAskQuestion } from "../utils/cli-ask-question.js";
|
|
20
|
+
import { buildDecider } from "../autonomy/decider.js";
|
|
21
|
+
import { createAutonomyAskQuestion } from "../autonomy/stage-ask.js";
|
|
22
|
+
export { createCliAskQuestion };
|
|
23
|
+
|
|
24
|
+
export async function runCommandHandler({ task, config, logger, flags }) {
|
|
25
|
+
// PR-F (cwd confirmation): when launching from an interactive
|
|
26
|
+
// terminal, surface the working directory so the user can abort if
|
|
27
|
+
// they typed `kj run` from the wrong place. The user's words:
|
|
28
|
+
// "todas las que lo lancé desde terminal te garantizo que estaba
|
|
29
|
+
// en la carpeta del proyecto … aún así preguntar por si acaso".
|
|
30
|
+
//
|
|
31
|
+
// Skip the prompt when:
|
|
32
|
+
// - --yes / -y is set (CI / scripted runs),
|
|
33
|
+
// - --json mode is on (machine-readable output, no TTY assumed),
|
|
34
|
+
// - stdin is not a TTY (piped, board-spawned subprocess, MCP).
|
|
35
|
+
const projectDir = config?.projectDir || process.cwd();
|
|
36
|
+
const canPrompt = process.stdin.isTTY && process.stdout.isTTY
|
|
37
|
+
&& !flags?.yes && !flags?.json;
|
|
38
|
+
if (canPrompt) {
|
|
39
|
+
const ok = await confirmCwd(projectDir);
|
|
40
|
+
if (!ok) {
|
|
41
|
+
console.log("Aborted by user.");
|
|
42
|
+
return { ok: false, aborted: true };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// KJC-TSK-0455 — Pre-run drift check. Default ON; opt out with
|
|
47
|
+
// --no-rag-update (flag) or config.rag.autoUpdate.onRun=false. If the
|
|
48
|
+
// local index is behind HEAD we re-embed the delta before the agents
|
|
49
|
+
// start reading from the RAG store; on any failure we log and move on
|
|
50
|
+
// so a broken vector store never blocks a run.
|
|
51
|
+
await maybeAutoUpdate({ projectDir, config, logger, flags });
|
|
52
|
+
|
|
53
|
+
// Best-effort session cleanup before starting
|
|
54
|
+
try {
|
|
55
|
+
const { cleanupExpiredSessions } = await import("../session-cleanup.js");
|
|
56
|
+
await cleanupExpiredSessions({ logger });
|
|
57
|
+
} catch { /* non-blocking */ }
|
|
58
|
+
|
|
59
|
+
const requiredProviders = [
|
|
60
|
+
resolveRole(config, "coder").provider
|
|
61
|
+
];
|
|
62
|
+
if (config.pipeline?.reviewer?.enabled !== false) {
|
|
63
|
+
requiredProviders.push(resolveRole(config, "reviewer").provider);
|
|
64
|
+
}
|
|
65
|
+
if (config.pipeline?.triage?.enabled) requiredProviders.push(resolveRole(config, "triage").provider);
|
|
66
|
+
if (config.pipeline?.planner?.enabled) requiredProviders.push(resolveRole(config, "planner").provider);
|
|
67
|
+
if (config.pipeline?.refactorer?.enabled) requiredProviders.push(resolveRole(config, "refactorer").provider);
|
|
68
|
+
if (config.pipeline?.researcher?.enabled) requiredProviders.push(resolveRole(config, "researcher").provider);
|
|
69
|
+
if (config.pipeline?.tester?.enabled) requiredProviders.push(resolveRole(config, "tester").provider);
|
|
70
|
+
if (config.pipeline?.security?.enabled) requiredProviders.push(resolveRole(config, "security").provider);
|
|
71
|
+
await assertAgentsAvailable(requiredProviders);
|
|
72
|
+
|
|
73
|
+
// --- Planning Game: resolve card ID ---
|
|
74
|
+
const pgCardId = flags?.pgTask || parseCardId(task);
|
|
75
|
+
const pgProject = flags?.pgProject || config.planning_game?.project_id || null;
|
|
76
|
+
|
|
77
|
+
const jsonMode = flags?.json;
|
|
78
|
+
// Quiet mode is the default; --verbose disables it
|
|
79
|
+
const quietMode = config.output?.quiet !== false;
|
|
80
|
+
|
|
81
|
+
return withCliRunLog("run", { projectDir: config?.projectDir, logger }, async ({ runLog, forwardProgress }) => {
|
|
82
|
+
runLog.logText(`[kj_run] task="${String(task).slice(0, 80)}..."`);
|
|
83
|
+
|
|
84
|
+
// KJC-TSK-0396 extensión: registrar el PID + planId + huIds en
|
|
85
|
+
// ~/.karajan/runs/<runId>.json para que el HU Board pueda mostrar
|
|
86
|
+
// el botón ⏹ Stop incluso cuando el run se lanza desde terminal
|
|
87
|
+
// externa (no solo desde el botón ▶ Run del board). Best-effort:
|
|
88
|
+
// si la escritura falla, el run sigue su curso normal. Limpieza
|
|
89
|
+
// garantizada en el finally del withCliRunLog vía registry.unregisterRun.
|
|
90
|
+
const huIdsFromFlag = typeof flags?.hu === "string"
|
|
91
|
+
? flags.hu.split(",").map((s) => s.trim()).filter(Boolean)
|
|
92
|
+
: null;
|
|
93
|
+
const runId = registerRun({
|
|
94
|
+
pid: process.pid,
|
|
95
|
+
planId: flags?.plan || null,
|
|
96
|
+
huIds: huIdsFromFlag,
|
|
97
|
+
projectDir: config?.projectDir || process.cwd(),
|
|
98
|
+
source: "cli",
|
|
99
|
+
});
|
|
100
|
+
const cleanupRegistry = () => { if (runId) unregisterRun(runId); };
|
|
101
|
+
// Cubrir todos los caminos de salida del proceso.
|
|
102
|
+
process.once("exit", cleanupRegistry);
|
|
103
|
+
process.once("SIGTERM", () => { cleanupRegistry(); process.exit(143); });
|
|
104
|
+
process.once("SIGINT", () => { cleanupRegistry(); process.exit(130); });
|
|
105
|
+
|
|
106
|
+
const emitter = new EventEmitter();
|
|
107
|
+
let activityLog = null;
|
|
108
|
+
|
|
109
|
+
// Mirror every progress event into .kj/run.log so kj-tail works identically
|
|
110
|
+
// whether the command came from the MCP server or the CLI (KJC-TSK-0327 follow-up).
|
|
111
|
+
forwardProgress(emitter);
|
|
112
|
+
|
|
113
|
+
emitter.on("progress", (event) => {
|
|
114
|
+
if (!activityLog && event.sessionId) {
|
|
115
|
+
activityLog = createActivityLog(event.sessionId);
|
|
116
|
+
logger.onLog((entry) => activityLog.write(entry));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (activityLog) {
|
|
120
|
+
activityLog.writeEvent(event);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!jsonMode) {
|
|
124
|
+
printEvent(event, { quiet: quietMode });
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
if (!jsonMode) {
|
|
129
|
+
printHeader({ task: task, config });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const askQuestion = createCliAskQuestion({ flags });
|
|
133
|
+
|
|
134
|
+
// Autonomy (KJC-PCS-0062): wire the level to a resolver. In autonomous mode
|
|
135
|
+
// every gate is decided by the Arbiter instead of the human; interactive
|
|
136
|
+
// keeps the human prompts. The decider is threaded into the gates below.
|
|
137
|
+
const { autonomy, resolve: decide } = buildDecider({ config, flags, ask: askQuestion, logger });
|
|
138
|
+
|
|
139
|
+
// Spec-reviewer pre-pipeline audit (KJC-PCS-0048). Runs BEFORE
|
|
140
|
+
// anything else — surfaces ambiguity / missing scope / missing AC.
|
|
141
|
+
// In autonomous mode the Arbiter decides (never aborts); interactive
|
|
142
|
+
// lets the user bail. Bypass with --skip-spec-review.
|
|
143
|
+
const reviewResult = await runSpecReview({ spec: task, config, logger, askQuestion, flags, resolve: decide, autonomy });
|
|
144
|
+
if (!reviewResult.proceed) {
|
|
145
|
+
logger.info("Aborted by user after spec review.");
|
|
146
|
+
cleanupRegistry();
|
|
147
|
+
return { ok: false, aborted: true, reason: "spec-review-cancelled" };
|
|
148
|
+
}
|
|
149
|
+
// If the user refined the spec via [r]efine, downstream runs the
|
|
150
|
+
// REFINED text (not the original) so the pipeline acts on what the
|
|
151
|
+
// user actually approved.
|
|
152
|
+
const effectiveTask = reviewResult.refined && reviewResult.finalSpec ? reviewResult.finalSpec : task;
|
|
153
|
+
|
|
154
|
+
// AUTO-E: in autonomous mode the stages never ask a human or block on the
|
|
155
|
+
// board — they auto-continue with the least-bad choice. interactive/assisted
|
|
156
|
+
// keep the human prompts.
|
|
157
|
+
const stageAsk = createAutonomyAskQuestion({ baseAsk: askQuestion, autonomy, logger });
|
|
158
|
+
|
|
159
|
+
let result;
|
|
160
|
+
try {
|
|
161
|
+
result = await runFlow({ task: effectiveTask, config, logger, flags, emitter, askQuestion: stageAsk, pgTaskId: pgCardId || null, pgProject: pgProject || null });
|
|
162
|
+
} finally {
|
|
163
|
+
// KJC-TSK-0396: limpia el registro pase lo que pase (éxito,
|
|
164
|
+
// throw, o paused). Los handlers de SIGINT/SIGTERM/exit son
|
|
165
|
+
// backstop para casos donde el throw no llega aquí (segfault,
|
|
166
|
+
// kill -9, etc.).
|
|
167
|
+
cleanupRegistry();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (jsonMode) {
|
|
171
|
+
console.log(JSON.stringify(result, null, 2));
|
|
172
|
+
} else {
|
|
173
|
+
// Last line printed: if the run stopped (hibernated / paused /
|
|
174
|
+
// failed), tell the user the exact command to resume it.
|
|
175
|
+
printResumeHint(result);
|
|
176
|
+
}
|
|
177
|
+
// Surface per-HU results so `kj autorun` can build a real outcome report
|
|
178
|
+
// (KJC-BUG-0090: it showed "0/0 met the ask" because only { ok } came back).
|
|
179
|
+
// The plan run returns them as `huResults` (run-hu-batch finalResult).
|
|
180
|
+
const hus = Array.isArray(result?.huResults)
|
|
181
|
+
? result.huResults.map((r) => ({ id: r.huId, met: r.approved === true }))
|
|
182
|
+
: [];
|
|
183
|
+
return { ok: !result?.paused && result?.approved !== false, hus };
|
|
184
|
+
});
|
|
185
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getOpenIssues, getQualityGateStatus } from "../sonar/api.js";
|
|
2
|
+
import { runSonarScan } from "../sonar/scanner.js";
|
|
3
|
+
import { summarizeIssues } from "../sonar/enforcer.js";
|
|
4
|
+
|
|
5
|
+
export async function scanCommand({ config }) {
|
|
6
|
+
const scan = await runSonarScan(config);
|
|
7
|
+
if (!scan.ok) {
|
|
8
|
+
throw new Error(`Sonar scan failed: ${scan.stderr || scan.stdout}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const gate = await getQualityGateStatus(config, scan.projectKey);
|
|
12
|
+
const issues = await getOpenIssues(config, scan.projectKey);
|
|
13
|
+
|
|
14
|
+
console.log(`Project key: ${scan.projectKey}`);
|
|
15
|
+
console.log(`Quality Gate: ${gate.status}`);
|
|
16
|
+
console.log(`Open issues: ${issues.total}`);
|
|
17
|
+
console.log(`By severity: ${summarizeIssues(issues.issues) || "none"}`);
|
|
18
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kj skills` — manage the local OpenSkills cache and the addyosmani catalog.
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* - list : print cached OpenSkills with their age and freshness.
|
|
6
|
+
* - clear-cache : delete all cached metadata (forces re-install on next session).
|
|
7
|
+
* - sync-addyosmani : force a git pull of addyosmani/agent-skills.
|
|
8
|
+
* - list-addyosmani : enumerate slugs available in the cached catalog.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { listCached, clearCache, getCacheRoot, DEFAULT_TTL_MS } from "../skills/skills-cache.js";
|
|
12
|
+
import { refreshIfStale, listAvailableSlugs, getCatalogRoot, loadSkillBySlug } from "../skills/addyosmani-catalog.js";
|
|
13
|
+
|
|
14
|
+
function humanAge(cachedAt) {
|
|
15
|
+
const ms = Date.now() - Date.parse(cachedAt);
|
|
16
|
+
if (!Number.isFinite(ms) || ms < 0) return "unknown";
|
|
17
|
+
const days = ms / (24 * 60 * 60 * 1000);
|
|
18
|
+
if (days < 1) return `${Math.max(1, Math.round(ms / (60 * 60 * 1000)))}h ago`;
|
|
19
|
+
return `${days.toFixed(1)}d ago`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function skillsCommand({ action = "list" } = {}) {
|
|
23
|
+
switch (action) {
|
|
24
|
+
case "list":
|
|
25
|
+
return listAction();
|
|
26
|
+
case "clear-cache":
|
|
27
|
+
return clearAction();
|
|
28
|
+
case "sync-addyosmani":
|
|
29
|
+
return syncAddyosmaniAction();
|
|
30
|
+
case "list-addyosmani":
|
|
31
|
+
return listAddyosmaniAction();
|
|
32
|
+
default:
|
|
33
|
+
console.error(`Unknown action: ${action}. Use: list | clear-cache | sync-addyosmani | list-addyosmani`);
|
|
34
|
+
return 1;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function listAction() {
|
|
39
|
+
const cache = await listCached();
|
|
40
|
+
if (cache.length === 0) {
|
|
41
|
+
console.log(`No cached skills at ${getCacheRoot()}`);
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
console.log(`Cached skills (TTL ${Math.round(DEFAULT_TTL_MS / 86400000)}d) at ${getCacheRoot()}:\n`);
|
|
45
|
+
for (const entry of cache) {
|
|
46
|
+
const flag = entry.fresh ? "FRESH" : "STALE";
|
|
47
|
+
console.log(` ${flag} ${entry.name} (${humanAge(entry.cachedAt)})`);
|
|
48
|
+
}
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function clearAction() {
|
|
53
|
+
const { removed } = await clearCache();
|
|
54
|
+
console.log(`Cleared ${removed} cached skill${removed === 1 ? "" : "s"} from ${getCacheRoot()}`);
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function syncAddyosmaniAction() {
|
|
59
|
+
console.log("Syncing addyosmani/agent-skills catalog...");
|
|
60
|
+
const logger = { warn: (m) => console.warn(` warn: ${m}`), info: (m) => console.log(` ${m}`) };
|
|
61
|
+
const result = await refreshIfStale({ force: true, logger });
|
|
62
|
+
if (!result.ok) {
|
|
63
|
+
console.error(`Sync failed: ${result.error || result.action}`);
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
const slugs = await listAvailableSlugs();
|
|
67
|
+
console.log(`${result.action === "cloned" ? "Cloned" : "Pulled"} at ${getCatalogRoot()}`);
|
|
68
|
+
console.log(`Available slugs: ${slugs.length}`);
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function listAddyosmaniAction() {
|
|
73
|
+
const slugs = await listAvailableSlugs();
|
|
74
|
+
if (slugs.length === 0) {
|
|
75
|
+
console.log(`No addyosmani catalog found at ${getCatalogRoot()}`);
|
|
76
|
+
console.log("Run `kj skills sync-addyosmani` to bootstrap it.");
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
console.log(`addyosmani/agent-skills catalog at ${getCatalogRoot()}\n${slugs.length} slug(s):\n`);
|
|
80
|
+
for (const slug of slugs) {
|
|
81
|
+
const skill = await loadSkillBySlug(slug);
|
|
82
|
+
const desc = skill?.description ? ` — ${skill.description.slice(0, 100)}${skill.description.length > 100 ? "..." : ""}` : "";
|
|
83
|
+
console.log(` ${slug}${desc}`);
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import { sonarDown, sonarLogs, sonarStatus, sonarUp, isSonarReachable } from "../sonar/manager.js";
|
|
3
|
+
import { resolveSonarProjectKey } from "../sonar/project-key.js";
|
|
4
|
+
import { runCommand } from "../utils/process.js";
|
|
5
|
+
|
|
6
|
+
function openBrowserCmd() {
|
|
7
|
+
const platform = os.platform();
|
|
8
|
+
if (platform === "darwin") return "open";
|
|
9
|
+
if (platform === "win32") return "start";
|
|
10
|
+
return "xdg-open";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function sonarOpenCommand({ config }) {
|
|
14
|
+
const host = config?.sonarqube?.host || "http://localhost:9000";
|
|
15
|
+
|
|
16
|
+
if (!(await isSonarReachable(host))) {
|
|
17
|
+
return { ok: false, error: `SonarQube is not reachable at ${host}. Run 'kj sonar start' first.` };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let projectKey;
|
|
21
|
+
try {
|
|
22
|
+
projectKey = await resolveSonarProjectKey(config);
|
|
23
|
+
} catch (err) {
|
|
24
|
+
return { ok: false, error: err.message };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const url = `${host}/dashboard?id=${projectKey}`;
|
|
28
|
+
await runCommand(openBrowserCmd(), [url]);
|
|
29
|
+
return { ok: true, url };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function sonarCommand({ action }) {
|
|
33
|
+
if (action === "start") {
|
|
34
|
+
const res = await sonarUp();
|
|
35
|
+
console.log(res.stdout || res.stderr);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (action === "stop") {
|
|
40
|
+
const res = await sonarDown();
|
|
41
|
+
console.log(res.stdout || res.stderr);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (action === "logs") {
|
|
46
|
+
const res = await sonarLogs();
|
|
47
|
+
console.log(res.stdout || res.stderr);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const res = await sonarStatus();
|
|
52
|
+
console.log(res.stdout || "stopped");
|
|
53
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// KJC-TSK-0414 PR2: comandos kj standby list / kj resume.
|
|
2
|
+
//
|
|
3
|
+
// `kj resume <sessionId>` valida cooldownUntil y, si llegó la hora, re-spawn
|
|
4
|
+
// el comando original capturado en argv. Si cooldown todavía está en el
|
|
5
|
+
// futuro, muestra countdown y aborta. `kj standby list` solo enumera.
|
|
6
|
+
//
|
|
7
|
+
// Estrategia de resume: cada sessionState persiste su argv original (los
|
|
8
|
+
// argumentos con los que se lanzó el `kj` que hibernó). El resume re-spawn
|
|
9
|
+
// EXACTAMENTE ese mismo comando con env preservado. El run reanuda como si
|
|
10
|
+
// fuera un retry — el state interno (HU pendiente, snapshot_sha, etc.) está
|
|
11
|
+
// en el JSON persistido en disco por TSK-0408 + TSK-0414 PR1.
|
|
12
|
+
|
|
13
|
+
import { spawn } from "node:child_process";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { loadStandby, listPendingStandby, markStandbyDone, acquireStandbyLock } from "../brain/standby-store.js";
|
|
17
|
+
|
|
18
|
+
const REPO_KJ_CLI = (() => {
|
|
19
|
+
try {
|
|
20
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
return path.join(here, "..", "cli.js");
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
})();
|
|
26
|
+
|
|
27
|
+
function formatCountdown(ms) {
|
|
28
|
+
if (ms <= 0) return "ahora";
|
|
29
|
+
const s = Math.round(ms / 1000);
|
|
30
|
+
const h = Math.floor(s / 3600);
|
|
31
|
+
const m = Math.floor((s % 3600) / 60);
|
|
32
|
+
const sec = s % 60;
|
|
33
|
+
return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function standbyListCommand({ json } = {}) {
|
|
37
|
+
const sessions = listPendingStandby();
|
|
38
|
+
if (json) {
|
|
39
|
+
console.log(JSON.stringify(sessions, null, 2));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (sessions.length === 0) {
|
|
43
|
+
console.log("No hay sesiones hibernadas.");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
console.log(`Sesiones hibernadas (${sessions.length}):`);
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
for (const s of sessions) {
|
|
49
|
+
const ms = new Date(s.cooldownUntil).getTime() - now;
|
|
50
|
+
const status = ms <= 0 ? "✓ lista para resume" : `⏳ resume en ${formatCountdown(ms)}`;
|
|
51
|
+
console.log(` ${s.sessionId} · ${s.reason || "?"} · ${status}`);
|
|
52
|
+
if (s.planId) {
|
|
53
|
+
const huSuffix = s.huId ? `, HU: ${s.huId}` : "";
|
|
54
|
+
console.log(` plan: ${s.planId}${huSuffix}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Re-spawn el comando original capturado en sessionState.argv.
|
|
61
|
+
* Si cooldownUntil > now y force=false → aborta con mensaje.
|
|
62
|
+
*/
|
|
63
|
+
export async function resumeCommand({ sessionId, force } = {}) {
|
|
64
|
+
if (!sessionId) {
|
|
65
|
+
console.error("kj resume requiere <sessionId>. Usa `kj standby list` para ver pendientes.");
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const state = loadStandby(sessionId);
|
|
70
|
+
if (!state) {
|
|
71
|
+
console.error(`Sesión no encontrada: ${sessionId}`);
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const cooldownMs = new Date(state.cooldownUntil).getTime() - Date.now();
|
|
76
|
+
if (cooldownMs > 0 && !force) {
|
|
77
|
+
console.log(`Sesión ${sessionId} todavía en cooldown ${formatCountdown(cooldownMs)} (hasta ${state.cooldownUntil}).`);
|
|
78
|
+
console.log("Espera o usa `kj resume <sessionId> --force` (no recomendado — la API seguramente seguirá rechazando).");
|
|
79
|
+
process.exitCode = 0;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const lock = acquireStandbyLock(sessionId);
|
|
84
|
+
if (!lock.acquired) {
|
|
85
|
+
console.log(`Sesión ${sessionId} ya está siendo reanudada por otro proceso.`);
|
|
86
|
+
process.exitCode = 0;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
if (!Array.isArray(state.argv) || state.argv.length === 0) {
|
|
92
|
+
console.error(`Sesión ${sessionId} sin argv — no se puede re-spawn. Borra manual y relanza.`);
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!REPO_KJ_CLI) {
|
|
97
|
+
console.error("No se pudo localizar cli.js. ¿Karajan instalado correctamente?");
|
|
98
|
+
process.exitCode = 1;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
console.log(`Reanudando ${sessionId}: kj ${state.argv.join(" ")}`);
|
|
102
|
+
const child = spawn(process.execPath, [REPO_KJ_CLI, ...state.argv], {
|
|
103
|
+
cwd: state.cwd || process.cwd(),
|
|
104
|
+
env: { ...process.env, ...(state.env || {}), KJ_RESUME_FROM: sessionId },
|
|
105
|
+
stdio: "inherit",
|
|
106
|
+
});
|
|
107
|
+
await new Promise((resolve) => {
|
|
108
|
+
child.on("exit", (code) => {
|
|
109
|
+
if (code === 0) markStandbyDone(sessionId);
|
|
110
|
+
process.exitCode = code ?? 0;
|
|
111
|
+
resolve();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
} finally {
|
|
115
|
+
lock.release?.();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// KJC-TSK-0570 (Onboard C) — `kj start`: the single entry point to the Brain.
|
|
2
|
+
// Wires the read-only sweep (0568) → deterministic assessment (0569) → haiku
|
|
3
|
+
// decider (0569), reports the recommended next step, and — interactively only —
|
|
4
|
+
// confirms and dispatches the chosen intent to its saved command
|
|
5
|
+
// (harden/rag/run/plan). --json / --yes / no-TTY stay read-only: emit the
|
|
6
|
+
// assessment + intent and apply nothing. Collaborators are injected for testing.
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { execa } from "execa";
|
|
10
|
+
import { runReadOnlySweep } from "../start/sweep.js";
|
|
11
|
+
import { buildAssessment } from "../start/assessment.js";
|
|
12
|
+
import { StartDecidorRole } from "../start/start-decider-role.js";
|
|
13
|
+
import { createWizard, isTTY } from "../utils/wizard.js";
|
|
14
|
+
|
|
15
|
+
// The recommended next step shown for each intent.
|
|
16
|
+
const NEXT_STEP = {
|
|
17
|
+
ASSESS_ONLY: "Everything looks healthy — nothing to do.",
|
|
18
|
+
RECOMMEND_HARDEN: "Suggested: `kj harden --interactive`",
|
|
19
|
+
RECOMMEND_INDEX: "Suggested: `kj rag index`",
|
|
20
|
+
START_TASK: 'Suggested: `kj run "<task>"`',
|
|
21
|
+
PROPOSE_PLAN: 'Suggested: `kj plan "<goal>"`',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Each writing intent maps to the saved command + args `kj start` dispatches.
|
|
25
|
+
const DISPATCH = {
|
|
26
|
+
RECOMMEND_HARDEN: () => ["harden", "--interactive"],
|
|
27
|
+
RECOMMEND_INDEX: () => ["rag", "index"],
|
|
28
|
+
START_TASK: (task) => ["run", task],
|
|
29
|
+
PROPOSE_PLAN: (task) => ["plan", task],
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const ASK_FALLBACK = "What would you like to do with this project?";
|
|
33
|
+
const CLI_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "cli.js");
|
|
34
|
+
|
|
35
|
+
// Run a saved `kj` subcommand as a child, inheriting stdio so its own prompts
|
|
36
|
+
// (e.g. `harden --interactive`) drive the real terminal. Never throws here.
|
|
37
|
+
async function spawnKj(args, { cwd }) {
|
|
38
|
+
await execa("node", [CLI_PATH, ...args.filter(Boolean)], { cwd, stdio: "inherit", reject: false });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// The decider has its own quota/parse recovery; a spawn-level failure (CLI not
|
|
42
|
+
// installed) still throws, so we degrade here too — `kj start` never crashes.
|
|
43
|
+
async function decide({ task, text, config, logger, makeDecider }) {
|
|
44
|
+
const decider = makeDecider({ config, logger });
|
|
45
|
+
try {
|
|
46
|
+
const decision = await decider.execute({ userMessage: task, assessment: text });
|
|
47
|
+
return decision.result || {};
|
|
48
|
+
} catch (err) {
|
|
49
|
+
logger?.warn?.(`[start] decider unavailable (${err?.message || err}) — asking the user.`);
|
|
50
|
+
return { intent: "ASK_USER", rationale: "Decider unavailable.", questionToAsk: ASK_FALLBACK, degraded: true };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Ask one yes/no, always closing the readline interface afterwards.
|
|
55
|
+
async function confirmApply(makeWizard) {
|
|
56
|
+
const wizard = makeWizard();
|
|
57
|
+
try {
|
|
58
|
+
return await wizard.confirm("Apply this?", true);
|
|
59
|
+
} finally {
|
|
60
|
+
wizard.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Print the rationale + recommended step, or the open question for ASK_USER.
|
|
65
|
+
function render(result) {
|
|
66
|
+
if (result.intent === "ASK_USER") {
|
|
67
|
+
console.log(`❓ ${result.questionToAsk || ASK_FALLBACK}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (result.rationale) console.log(`→ ${result.rationale}`);
|
|
71
|
+
const step = NEXT_STEP[result.intent];
|
|
72
|
+
if (step) console.log(` ${step}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function startCommand({ task = "", config, logger, flags = {}, deps = {} }) {
|
|
76
|
+
const sweep = deps.runReadOnlySweep || runReadOnlySweep;
|
|
77
|
+
const assess = deps.buildAssessment || buildAssessment;
|
|
78
|
+
const makeDecider = deps.makeDecider || ((opts) => new StartDecidorRole(opts));
|
|
79
|
+
const tty = deps.isTTY || isTTY;
|
|
80
|
+
const spawn = deps.spawnKj || spawnKj;
|
|
81
|
+
const makeWizard = deps.makeWizard || (() => createWizard());
|
|
82
|
+
|
|
83
|
+
// KJC-BUG-0145 (campo, #1471): loadConfig never sets projectDir — passing
|
|
84
|
+
// config.projectDir straight through handed `undefined` to the sweep, every
|
|
85
|
+
// collector failed silently and the project read as "new, no source code".
|
|
86
|
+
const projectDir = config.projectDir || process.cwd();
|
|
87
|
+
const bundle = await sweep(projectDir, { declared: flags.maturity || null });
|
|
88
|
+
const { text, summary } = assess(bundle);
|
|
89
|
+
let result = await decide({ task, text, config, logger, makeDecider });
|
|
90
|
+
|
|
91
|
+
if (flags.json) {
|
|
92
|
+
console.log(JSON.stringify({ maturity: summary.maturity, assessment: text, ...result }, null, 2));
|
|
93
|
+
return { ok: true, intent: result.intent };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log(`${text}\n`);
|
|
97
|
+
const interactive = tty() && !flags.yes;
|
|
98
|
+
let goal = task;
|
|
99
|
+
|
|
100
|
+
// ASK_USER: one interactive re-route — the open answer becomes the goal.
|
|
101
|
+
if (result.intent === "ASK_USER" && interactive) {
|
|
102
|
+
const wizard = makeWizard();
|
|
103
|
+
try {
|
|
104
|
+
const answer = await wizard.input(`❓ ${result.questionToAsk || ASK_FALLBACK}`);
|
|
105
|
+
if (answer) {
|
|
106
|
+
goal = answer;
|
|
107
|
+
result = await decide({ task: answer, text, config, logger, makeDecider });
|
|
108
|
+
}
|
|
109
|
+
} finally {
|
|
110
|
+
wizard.close();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
render(result);
|
|
114
|
+
|
|
115
|
+
// Dispatch the chosen intent to its saved command, confirming first (it writes).
|
|
116
|
+
const toArgs = DISPATCH[result.intent];
|
|
117
|
+
if (interactive && toArgs && (await confirmApply(makeWizard))) {
|
|
118
|
+
await spawn(toArgs(goal), { cwd: projectDir });
|
|
119
|
+
}
|
|
120
|
+
return { ok: true, intent: result.intent };
|
|
121
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI status command — shows a terminal dashboard of the current pipeline state.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readRunLog } from "../utils/run-log.js";
|
|
6
|
+
import { loadMostRecentSession } from "../session/store.js";
|
|
7
|
+
import { buildDashboard } from "../utils/status-dashboard.js";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Run the `kj status` command: print a human-readable dashboard to stdout.
|
|
12
|
+
* @param {object} options
|
|
13
|
+
* @param {number} [options.lines=50] - Max log lines to read.
|
|
14
|
+
* @param {string} [options.projectDir] - Project directory override.
|
|
15
|
+
*/
|
|
16
|
+
export async function statusCommand({ lines = 50, projectDir } = {}) {
|
|
17
|
+
const dir = projectDir || process.cwd();
|
|
18
|
+
const logResult = readRunLog(dir, lines);
|
|
19
|
+
|
|
20
|
+
let session = null;
|
|
21
|
+
try {
|
|
22
|
+
session = await loadMostRecentSession();
|
|
23
|
+
} catch { /* no session available */ }
|
|
24
|
+
|
|
25
|
+
let stories = [];
|
|
26
|
+
if (session) {
|
|
27
|
+
try {
|
|
28
|
+
const { loadHuBatch } = await import("../hu/store.js");
|
|
29
|
+
const batch = await loadHuBatch(session.id);
|
|
30
|
+
if (batch?.stories) stories = batch.stories;
|
|
31
|
+
} catch { /* no HU batch */ }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const dashboard = buildDashboard(session, logResult.lines || [], { stories });
|
|
35
|
+
console.log(dashboard);
|
|
36
|
+
}
|