@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,74 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import yaml from "js-yaml";
|
|
4
|
+
import { loadConfig, validateConfig, getConfigPath, writeConfig } from "../config.js";
|
|
5
|
+
import { ensureDir } from "../utils/fs.js";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
|
|
8
|
+
function resolveEditor() {
|
|
9
|
+
const raw = process.env.VISUAL || process.env.EDITOR || "vi";
|
|
10
|
+
const parts = raw.split(/\s+/);
|
|
11
|
+
return { cmd: parts[0], args: parts.slice(1) };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function editConfigOnce(configPath) {
|
|
15
|
+
const { cmd, args } = resolveEditor();
|
|
16
|
+
const result = spawnSync(cmd, [...args, configPath], { stdio: "inherit" });
|
|
17
|
+
|
|
18
|
+
if (result.status !== 0) {
|
|
19
|
+
return { ok: false, error: `Editor exited with code ${result.status}` };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let raw;
|
|
23
|
+
try {
|
|
24
|
+
raw = await fs.readFile(configPath, "utf8");
|
|
25
|
+
} catch (err) {
|
|
26
|
+
return { ok: false, error: `Could not read config: ${err.message}` };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let parsed;
|
|
30
|
+
try {
|
|
31
|
+
parsed = yaml.load(raw);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
return { ok: false, error: `Invalid YAML: ${err.message}` };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
validateConfig(parsed || {});
|
|
38
|
+
} catch (err) {
|
|
39
|
+
return { ok: false, error: err.message };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { ok: true, config: parsed };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function configCommand({ json = false, edit = false }) {
|
|
46
|
+
if (edit) {
|
|
47
|
+
const configPath = getConfigPath();
|
|
48
|
+
await ensureDir(path.dirname(configPath));
|
|
49
|
+
const { exists: configExists } = await loadConfig();
|
|
50
|
+
if (!configExists) {
|
|
51
|
+
const { config: defaults } = await loadConfig();
|
|
52
|
+
await writeConfig(configPath, defaults);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const result = await editConfigOnce(configPath);
|
|
56
|
+
if (result.ok) {
|
|
57
|
+
console.log("Configuration saved and validated.");
|
|
58
|
+
} else {
|
|
59
|
+
console.error(`Validation error: ${result.error}`);
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const { config, path: cfgPath, exists } = await loadConfig();
|
|
66
|
+
if (json) {
|
|
67
|
+
console.log(JSON.stringify({ path: cfgPath, exists, config }, null, 2));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log(`Config path: ${cfgPath}`);
|
|
72
|
+
console.log(`Exists: ${exists}`);
|
|
73
|
+
console.log(JSON.stringify(config, null, 2));
|
|
74
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { createAgent } from "../agents/index.js";
|
|
2
|
+
import { assertAgentsAvailable } from "../agents/availability.js";
|
|
3
|
+
import { resolveRole } from "../config.js";
|
|
4
|
+
import { withBrainRecovery } from "../brain/with-brain-recovery.js";
|
|
5
|
+
import { createCliProgressReporter } from "../utils/cli-progress.js";
|
|
6
|
+
import { buildDiscoverPrompt, parseDiscoverOutput } from "../prompts/discover.js";
|
|
7
|
+
|
|
8
|
+
function formatGaps(gaps, lines) {
|
|
9
|
+
lines.push("## Gaps");
|
|
10
|
+
for (const g of gaps) {
|
|
11
|
+
const sev = g.severity ? ` [${g.severity}]` : "";
|
|
12
|
+
lines.push(`- ${g.description || g}${sev}`);
|
|
13
|
+
if (g.suggestedQuestion) lines.push(` → ${g.suggestedQuestion}`);
|
|
14
|
+
}
|
|
15
|
+
lines.push("");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function formatMomTest(questions, lines) {
|
|
19
|
+
lines.push("## Mom Test Questions");
|
|
20
|
+
for (const q of questions) {
|
|
21
|
+
lines.push(`- ${q.question || q}`);
|
|
22
|
+
if (q.rationale) lines.push(` _${q.rationale}_`);
|
|
23
|
+
}
|
|
24
|
+
lines.push("");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function formatWendel(checklist, lines) {
|
|
28
|
+
lines.push("## Wendel Checklist");
|
|
29
|
+
for (const w of checklist) {
|
|
30
|
+
const icon = w.status === "pass" ? "✓" : w.status === "fail" ? "✗" : "?";
|
|
31
|
+
lines.push(`- [${icon}] ${w.condition}: ${w.justification || ""}`);
|
|
32
|
+
}
|
|
33
|
+
lines.push("");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function formatClassification(classification, lines) {
|
|
37
|
+
lines.push("## Classification");
|
|
38
|
+
lines.push(`- Type: ${classification.type}`);
|
|
39
|
+
if (classification.adoptionRisk) lines.push(`- Adoption risk: ${classification.adoptionRisk}`);
|
|
40
|
+
if (classification.frictionEstimate) lines.push(`- Friction: ${classification.frictionEstimate}`);
|
|
41
|
+
lines.push("");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function formatJtbds(jtbds, lines) {
|
|
45
|
+
lines.push("## Jobs-to-be-Done");
|
|
46
|
+
for (const j of jtbds) {
|
|
47
|
+
lines.push(`- **${j.id || ""}**: ${j.functional || j}`);
|
|
48
|
+
}
|
|
49
|
+
lines.push("");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function formatDiscover(result, mode) {
|
|
53
|
+
const lines = [];
|
|
54
|
+
lines.push(`## Discovery (${mode})`);
|
|
55
|
+
lines.push(`**Verdict:** ${result.verdict || "unknown"}`, "");
|
|
56
|
+
|
|
57
|
+
if (result.gaps?.length) formatGaps(result.gaps, lines);
|
|
58
|
+
if (result.momTestQuestions?.length) formatMomTest(result.momTestQuestions, lines);
|
|
59
|
+
if (result.wendelChecklist?.length) formatWendel(result.wendelChecklist, lines);
|
|
60
|
+
if (result.classification) formatClassification(result.classification, lines);
|
|
61
|
+
if (result.jtbds?.length) formatJtbds(result.jtbds, lines);
|
|
62
|
+
if (result.summary) lines.push(`---\n${result.summary}`);
|
|
63
|
+
return lines.join("\n");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function discoverCommand({ task, config, logger, mode, json }) {
|
|
67
|
+
const { withCliRunLog } = await import("../utils/cli-run-log.js");
|
|
68
|
+
return withCliRunLog("discover", { projectDir: config?.projectDir, logger }, async ({ runLog }) => {
|
|
69
|
+
const discoverRole = resolveRole(config, "discover");
|
|
70
|
+
await assertAgentsAvailable([discoverRole.provider]);
|
|
71
|
+
logger.info(`Discover (${discoverRole.provider}) starting — mode: ${mode || "gaps"}...`);
|
|
72
|
+
runLog.logText(`[discover] provider=${discoverRole.provider} mode=${mode || "gaps"}`);
|
|
73
|
+
|
|
74
|
+
const agent = createAgent(discoverRole.provider, config, logger);
|
|
75
|
+
const prompt = buildDiscoverPrompt({ task, mode: mode || "gaps" });
|
|
76
|
+
const progress = createCliProgressReporter({ role: "discover" });
|
|
77
|
+
let result;
|
|
78
|
+
try {
|
|
79
|
+
result = await withBrainRecovery({
|
|
80
|
+
agent, taskArgs: { prompt, onOutput: progress.onOutput, role: "discover" },
|
|
81
|
+
role: "discover", provider: discoverRole.provider, logger,
|
|
82
|
+
});
|
|
83
|
+
progress.finish(result.ok ? "done" : (result.action || "failed"));
|
|
84
|
+
} catch (err) { progress.finish("failed"); throw err; }
|
|
85
|
+
|
|
86
|
+
if (!result.ok) {
|
|
87
|
+
throw new Error(result.error || result.output || "Discover failed");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const parsed = parseDiscoverOutput(result.output);
|
|
91
|
+
|
|
92
|
+
if (json) {
|
|
93
|
+
console.log(JSON.stringify(parsed || result.output, null, 2));
|
|
94
|
+
return { ok: true };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (parsed?.verdict) {
|
|
98
|
+
console.log(formatDiscover(parsed, mode || "gaps"));
|
|
99
|
+
} else {
|
|
100
|
+
console.log(result.output);
|
|
101
|
+
}
|
|
102
|
+
logger.info("Discover completed.");
|
|
103
|
+
return { ok: true };
|
|
104
|
+
});
|
|
105
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kj doctor` command. Runs the unified check runner and prints a
|
|
3
|
+
* human-readable report by default. Supports flags:
|
|
4
|
+
*
|
|
5
|
+
* --check-only : only detect, do not apply fixes
|
|
6
|
+
* --yes / -y : auto-confirm prompts for invasive remediations (CI mode)
|
|
7
|
+
* --json : emit machine-readable JSON to stdout
|
|
8
|
+
* --verbose : include fix hints and timing per check
|
|
9
|
+
*
|
|
10
|
+
* Exit code is 1 whenever any check ends with FAIL (including remediation
|
|
11
|
+
* failures). WARN, OK, FIXED, SKIPPED and TIMEOUT do not fail the command.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import readline from "node:readline";
|
|
15
|
+
import { runChecks as runCheckPipeline, toLegacyShape } from "../checks/runner.js";
|
|
16
|
+
import { collectGuaranteeFacts } from "../checks/guarantee-level.js";
|
|
17
|
+
import { STATUS } from "../checks/types.js";
|
|
18
|
+
import { getSystemChecks } from "../checks/system.js";
|
|
19
|
+
import { getConfigFileChecks } from "../checks/config-files.js";
|
|
20
|
+
import { getBinaryChecks } from "../checks/binaries.js";
|
|
21
|
+
import { getSonarChecks } from "../checks/sonar.js";
|
|
22
|
+
import { getOllamaChecks } from "../checks/ollama.js";
|
|
23
|
+
import { getHarnessScorecardChecks } from "../checks/harness-scorecard.js";
|
|
24
|
+
import { getCiChecks } from "../checks/ci.js";
|
|
25
|
+
import { getRtkChecks } from "../checks/rtk.js";
|
|
26
|
+
import { getSqueezrChecks } from "../checks/squeezr.js";
|
|
27
|
+
import { getAiTrashChecks } from "../checks/ai-trash.js";
|
|
28
|
+
import { getQmdChecks } from "../checks/qmd.js";
|
|
29
|
+
import { getRagHooksChecks } from "../checks/rag-hooks.js";
|
|
30
|
+
import { getNodeChecks } from "../checks/node.js";
|
|
31
|
+
import { getNativeBuildChecks } from "../checks/native-build.js";
|
|
32
|
+
import { getPortChecks } from "../checks/ports.js";
|
|
33
|
+
import { getTokenChecks } from "../checks/tokens.js";
|
|
34
|
+
import { getMcpHealthChecks } from "../checks/mcp-health.js";
|
|
35
|
+
import { getSkillsChecks } from "../checks/skills.js";
|
|
36
|
+
import { getDirSetupChecks } from "../checks/dir-setup.js";
|
|
37
|
+
import { getProjectChecks } from "../checks/project-checks.js";
|
|
38
|
+
import { getHardwareChecks } from "../checks/hardware.js";
|
|
39
|
+
import { getOrphanChecks } from "../checks/orphans.js";
|
|
40
|
+
import { getMethodChecks } from "../checks/method.js";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Build the list of Check objects applicable to the current config.
|
|
44
|
+
*
|
|
45
|
+
* KJC-TSK-0393: cuando `projectOnly === true`, devuelve SOLO los project-aware
|
|
46
|
+
* checks (signals, tools per signal, write perms, .env consistency, gh remote
|
|
47
|
+
* access). Útil para validar un proyecto específico sin re-correr todos los
|
|
48
|
+
* checks globales (CLIs, node, sonar, etc.).
|
|
49
|
+
*
|
|
50
|
+
* @param {Object} config
|
|
51
|
+
* @param {{ projectOnly?: boolean }} [opts]
|
|
52
|
+
* @returns {import("../checks/types.js").Check[]}
|
|
53
|
+
*/
|
|
54
|
+
function buildChecks(config, { projectOnly = false } = {}) {
|
|
55
|
+
const projectDir = config?.projectDir || process.cwd();
|
|
56
|
+
if (projectOnly) {
|
|
57
|
+
return getProjectChecks({ projectDir });
|
|
58
|
+
}
|
|
59
|
+
return [
|
|
60
|
+
...getSystemChecks(),
|
|
61
|
+
...getNodeChecks(),
|
|
62
|
+
...getNativeBuildChecks(),
|
|
63
|
+
...getHardwareChecks(),
|
|
64
|
+
...getDirSetupChecks(),
|
|
65
|
+
...getConfigFileChecks(),
|
|
66
|
+
...getBinaryChecks(),
|
|
67
|
+
...getSonarChecks(),
|
|
68
|
+
...getOllamaChecks(),
|
|
69
|
+
...getHarnessScorecardChecks(),
|
|
70
|
+
...getPortChecks(),
|
|
71
|
+
...getTokenChecks(config),
|
|
72
|
+
...getMcpHealthChecks(),
|
|
73
|
+
...getSkillsChecks(),
|
|
74
|
+
...getCiChecks(),
|
|
75
|
+
...getRtkChecks(),
|
|
76
|
+
...getSqueezrChecks(),
|
|
77
|
+
...getAiTrashChecks(),
|
|
78
|
+
...getOrphanChecks(),
|
|
79
|
+
...getMethodChecks(),
|
|
80
|
+
...getQmdChecks(),
|
|
81
|
+
...getRagHooksChecks({ projectDir }),
|
|
82
|
+
...getProjectChecks({ projectDir }),
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Interactive terminal confirmation. Returns false when stdin is not a TTY
|
|
88
|
+
* so non-interactive contexts don't hang forever.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} describe
|
|
91
|
+
* @returns {Promise<boolean>}
|
|
92
|
+
*/
|
|
93
|
+
function confirmViaTty(describe) {
|
|
94
|
+
return new Promise((resolve) => {
|
|
95
|
+
if (!process.stdin.isTTY) {
|
|
96
|
+
resolve(false);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
100
|
+
rl.question(`? ${describe} [y/N] `, (answer) => {
|
|
101
|
+
rl.close();
|
|
102
|
+
resolve(/^y(es)?$/i.test(answer.trim()));
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Run the full doctor pipeline without CLI formatting. Consumers that need
|
|
109
|
+
* the raw report (preflight, status command) should use this.
|
|
110
|
+
*
|
|
111
|
+
* @param {{ config: Object, checkOnly?: boolean, yes?: boolean, onConfirm?: Function, logger?: Object }} args
|
|
112
|
+
* @returns {Promise<import("../checks/types.js").RunReport>}
|
|
113
|
+
*/
|
|
114
|
+
async function runDoctor({ config, checkOnly = false, yes = false, onConfirm, logger, projectOnly = false }) {
|
|
115
|
+
const checks = buildChecks(config, { projectOnly });
|
|
116
|
+
return runCheckPipeline(checks, { config }, {
|
|
117
|
+
mode: checkOnly ? "check-only" : "fix",
|
|
118
|
+
yes,
|
|
119
|
+
onConfirm: onConfirm ?? confirmViaTty,
|
|
120
|
+
logger,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Legacy shape (backwards-compat for callers that still expect
|
|
126
|
+
* {name,label,ok,detail,fix}). Kept public because tests and the CI gate
|
|
127
|
+
* still rely on it.
|
|
128
|
+
*
|
|
129
|
+
* @param {{ config: Object }} args
|
|
130
|
+
*/
|
|
131
|
+
export async function runChecks({ config }) {
|
|
132
|
+
const report = await runDoctor({ config });
|
|
133
|
+
return toLegacyShape(report);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* `kj doctor` CLI entrypoint. Returns the exit code (0 OK, 1 when FAIL).
|
|
138
|
+
*
|
|
139
|
+
* @param {{ config: Object, checkOnly?: boolean, yes?: boolean, json?: boolean, verbose?: boolean }} args
|
|
140
|
+
* @returns {Promise<number>}
|
|
141
|
+
*/
|
|
142
|
+
export async function doctorCommand({ config, checkOnly = false, yes = false, json = false, verbose = false, projectOnly = false }) {
|
|
143
|
+
const report = await runDoctor({ config, checkOnly, yes, projectOnly });
|
|
144
|
+
// KJC-TSK-0756 (campo, Pedro): el guarantee level del host actual se
|
|
145
|
+
// DECLARA en runtime — la doctrina no vive solo en el README.
|
|
146
|
+
report.guarantee = collectGuaranteeFacts({ projectDir: config?.projectDir || process.cwd() });
|
|
147
|
+
|
|
148
|
+
if (json) {
|
|
149
|
+
console.log(JSON.stringify(report, null, 2));
|
|
150
|
+
} else {
|
|
151
|
+
printHuman(report, { verbose });
|
|
152
|
+
printGuaranteeLevel(report.guarantee);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return hasBlockingFailure(report) ? 1 : 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// KJC-TSK-0756: la seccion de guarantee level — consola es el medio del
|
|
159
|
+
// doctor (excepcion no-console de commands).
|
|
160
|
+
function printGuaranteeLevel(g) {
|
|
161
|
+
const mark = (t) => (t.active ? "ACTIVE " : "OFF ");
|
|
162
|
+
console.log();
|
|
163
|
+
console.log(`Guarantee level (host: ${g.host ?? "desconocido"}) — kj jamas finge una supervision que no puede aplicar:`);
|
|
164
|
+
console.log(` ${mark(g.tierA)} A tool-time (Sentinel en el turno): ${g.tierA.reason}`);
|
|
165
|
+
console.log(` ${mark(g.tierB)} B commit-time (git gates, el SUELO): ${g.tierB.reason}`);
|
|
166
|
+
console.log(` ${mark(g.tierC)} C merge-time (re-check en CI): ${g.tierC.reason}`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function hasBlockingFailure(report) {
|
|
170
|
+
return report.checks.some((c) => c.status === STATUS.FAIL || c.status === STATUS.TIMEOUT);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function statusIcon(status) {
|
|
174
|
+
switch (status) {
|
|
175
|
+
case STATUS.OK: return "OK ";
|
|
176
|
+
case STATUS.FIXED: return "FIXED";
|
|
177
|
+
case STATUS.WARN: return "WARN ";
|
|
178
|
+
case STATUS.FAIL: return "FAIL ";
|
|
179
|
+
case STATUS.SKIPPED: return "SKIP ";
|
|
180
|
+
case STATUS.TIMEOUT: return "TIME ";
|
|
181
|
+
default: return "? ";
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// The `kj` binary bundles no toolchain: it orchestrates external tools. So
|
|
186
|
+
// beyond the per-check wall, spell out what is *required* to run kj at all
|
|
187
|
+
// (git + at least one agent CLI) versus what is *optional* (enables extra
|
|
188
|
+
// features). We derive the verdict from the checks already collected rather
|
|
189
|
+
// than re-probing, so it always agrees with the lines printed above.
|
|
190
|
+
function printPrerequisites(report) {
|
|
191
|
+
const git = report.checks.find((c) => c.name === "git");
|
|
192
|
+
const agents = report.checks.filter((c) => c.name?.startsWith("agent:"));
|
|
193
|
+
const okAgent = agents.find((c) => c.status === STATUS.OK);
|
|
194
|
+
const mark = (ok) => (ok ? "OK" : "MISSING");
|
|
195
|
+
|
|
196
|
+
const gitOk = git?.status === STATUS.OK;
|
|
197
|
+
const agentLabel = okAgent
|
|
198
|
+
? `OK (${okAgent.label.replace(/^Agent:\s*/, "")})`
|
|
199
|
+
: "MISSING — install Claude Code, Codex or Gemini";
|
|
200
|
+
|
|
201
|
+
console.log();
|
|
202
|
+
console.log("Prerequisites (kj orchestrates external tools, it bundles none):");
|
|
203
|
+
console.log(` Required: git ${mark(gitOk)}; agent CLI ${agentLabel}`);
|
|
204
|
+
console.log(" Optional: Docker (local models, SonarQube); Node/npm (helper tools: Squeezr, qmd)");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function printHuman(report, { verbose }) {
|
|
208
|
+
for (const check of report.checks) {
|
|
209
|
+
console.log(`${statusIcon(check.status)} ${check.label}: ${check.detail}`);
|
|
210
|
+
if (check.fix && (check.status === STATUS.FAIL || check.status === STATUS.WARN || verbose)) {
|
|
211
|
+
console.log(` -> ${check.fix}`);
|
|
212
|
+
}
|
|
213
|
+
if (verbose) {
|
|
214
|
+
console.log(` (${check.runMs}ms, strategy=${check.strategy})`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const s = report.summary;
|
|
219
|
+
const total = s.ok + s.fixed + s.warn + s.fail + s.skipped + s.timeout;
|
|
220
|
+
console.log();
|
|
221
|
+
if (s.fail === 0 && s.timeout === 0) {
|
|
222
|
+
const label = s.fixed > 0 ? `All checks passed (${s.fixed} auto-fixed)` : "All checks passed.";
|
|
223
|
+
console.log(label);
|
|
224
|
+
} else {
|
|
225
|
+
console.log(
|
|
226
|
+
`${s.fail + s.timeout} issue(s) found, ${s.fixed} auto-fixed, ${s.warn} warnings, ${s.skipped} skipped out of ${total}.`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
if (Object.keys(report.overrides).length > 0) {
|
|
230
|
+
console.log(`Runtime overrides applied: ${JSON.stringify(report.overrides)}`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
printPrerequisites(report);
|
|
234
|
+
|
|
235
|
+
// KJC-TSK v2.18 — if any external audit tool (semgrep, osv-scanner,
|
|
236
|
+
// lighthouse) reported missing, surface the one-line remediation so
|
|
237
|
+
// the user doesn't have to dig the fix lines out of the wall of
|
|
238
|
+
// checks. The audit-tool checks emit names like "audit-tool:semgrep"
|
|
239
|
+
// and embed { tool, suggested } in `extra` (see binaries.js).
|
|
240
|
+
const installable = report.checks
|
|
241
|
+
.filter((c) => c.name?.startsWith("audit-tool:") && c.status === STATUS.WARN && c.extra?.tool)
|
|
242
|
+
.map((c) => c.extra.tool);
|
|
243
|
+
if (installable.length > 0) {
|
|
244
|
+
console.log();
|
|
245
|
+
const list = installable.join(", ");
|
|
246
|
+
const only = installable.length === 1 ? ` --only ${installable[0]}` : "";
|
|
247
|
+
console.log(`Tip: run \`kj install-tools${only}\` to install: ${list}.`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export const __test = { printHuman, printPrerequisites };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kj env install` (ENV-A1/E1, KJC-TSK-0639/0640) — install/refresh the
|
|
3
|
+
* Karajan Environment playbook as a managed block in the host agents' rule
|
|
4
|
+
* files (CLAUDE.md, AGENTS.md), and make its step 1 real: when the project
|
|
5
|
+
* has no RAG index yet, build it (default ON, `--no-rag` opts out).
|
|
6
|
+
*/
|
|
7
|
+
import { installPlaybook, renderPlaybook } from "../environment/playbook.js";
|
|
8
|
+
import { renderBrief, listBriefs } from "../environment/briefs.js";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { openVecStore, projectSlug, getLastIndexedCommit, dbPath } from "../rag/vec-store.js";
|
|
11
|
+
import { ragIndexCommand } from "./rag.js";
|
|
12
|
+
import { renderPendingBlock, PENDING_EXIT_CODE } from "../utils/pending-user-action.js";
|
|
13
|
+
import { onnxConfig, persistOnnxChoice, resetEmptyStore } from "../rag/onnx-fallback.js";
|
|
14
|
+
import { verifyBoardAccess } from "../environment/board-access.js";
|
|
15
|
+
import { pickStateBackend } from "../environment/board-select.js";
|
|
16
|
+
import { ensurePrivacyList } from "../privacy/onboarding.js";
|
|
17
|
+
import { installProjectMcp } from "../environment/mcp-wiring.js";
|
|
18
|
+
import { createWizard } from "../utils/wizard.js";
|
|
19
|
+
import { hardenCommand } from "./harden.js";
|
|
20
|
+
import { reviewGateCommand } from "./review-gate.js";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
|
|
23
|
+
function hasRagIndex(config, projectDir) {
|
|
24
|
+
// KJC-BUG-0128: probing must never CREATE the store — openVecStore runs
|
|
25
|
+
// the DDL, and a table born at the default dim (768) breaks the ONNX
|
|
26
|
+
// fallback (384) later. No file → no index, without side effects.
|
|
27
|
+
if (!existsSync(dbPath())) return false;
|
|
28
|
+
const db = openVecStore({ dim: config?.rag?.embedder?.dim || 768 });
|
|
29
|
+
try { return Boolean(getLastIndexedCommit(db, projectSlug(projectDir))); }
|
|
30
|
+
finally { db.close(); }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* `kj brief [role]` (AB-C, KJC-TSK-0652) — the distilled method of a role,
|
|
35
|
+
* for the brain to execute or delegate. No role → list them.
|
|
36
|
+
*/
|
|
37
|
+
export function briefCommand({ config = null, flags = {}, role = null }) {
|
|
38
|
+
if (!role) {
|
|
39
|
+
const list = listBriefs();
|
|
40
|
+
if (flags.json) { console.log(JSON.stringify(list, null, 2)); return list; }
|
|
41
|
+
console.log("Available role briefs (kj brief <role>):");
|
|
42
|
+
for (const { role: r, purpose } of list) console.log(` ${r.padEnd(11)} ${purpose}`);
|
|
43
|
+
return list;
|
|
44
|
+
}
|
|
45
|
+
const text = renderBrief(role, config || {});
|
|
46
|
+
if (flags.json) { console.log(JSON.stringify({ role, brief: text })); return { role, brief: text }; }
|
|
47
|
+
console.log(text);
|
|
48
|
+
return { role, brief: text };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function envInstallCommand({ config = null, logger = null, flags = {} }) {
|
|
52
|
+
const projectDir = config?.projectDir || process.cwd();
|
|
53
|
+
|
|
54
|
+
// KJC-TSK-0709 — the board is chosen BEFORE the playbook renders (its
|
|
55
|
+
// tracking line depends on the backend): interactive installs ask when
|
|
56
|
+
// alternatives are reachable, headless installs name the default. The
|
|
57
|
+
// choice persists so it is only ever asked once.
|
|
58
|
+
try {
|
|
59
|
+
const wizard = process.stdin.isTTY && process.stdout.isTTY ? createWizard() : null;
|
|
60
|
+
const sel = await pickStateBackend({ projectDir, wizard, isTTY: Boolean(wizard), logger: console });
|
|
61
|
+
wizard?.close();
|
|
62
|
+
// The effective backend feeds the render on EVERY non-error path —
|
|
63
|
+
// chosen, declared-in-file or default — so the playbook never falls
|
|
64
|
+
// back to hu-board while the selection said otherwise.
|
|
65
|
+
config = { ...config, state_backend: sel.backend, board: sel.boardName ? { ...config?.board, name: sel.boardName } : config?.board };
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.log(`⚠ board selection failed (${err.message}) — continuing with the configured default`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const result = await installPlaybook({
|
|
71
|
+
projectDir, target: flags.target || "all",
|
|
72
|
+
stateBackend: config?.state_backend || "hu-board",
|
|
73
|
+
boardName: config?.board?.name || null,
|
|
74
|
+
});
|
|
75
|
+
console.log(`✓ Karajan playbook installed in: ${result.files.join(", ")}`);
|
|
76
|
+
|
|
77
|
+
// KJC-TSK-0711 — RAG as a native tool: agents use what is in their
|
|
78
|
+
// toolbox, so the official path must be cheaper than the grep shortcut.
|
|
79
|
+
try {
|
|
80
|
+
installProjectMcp({ projectDir, logger: console });
|
|
81
|
+
} catch (err) {
|
|
82
|
+
console.log(`⚠ could not wire kj-rag-mcp into .mcp.json: ${err.message}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// KJC-TSK-0685 (user rule): Karajan does not run without a board — it is
|
|
86
|
+
// what guarantees ordered, card-first work. Verify an OPERATIONAL access
|
|
87
|
+
// path to the declared backend BEFORE anything else; no path → block
|
|
88
|
+
// (exit 3) with the exact steps. The playbook stays installed.
|
|
89
|
+
const access = verifyBoardAccess({ config, projectDir });
|
|
90
|
+
if (!access.ok) {
|
|
91
|
+
result.boardError = access.needed.join(" | ");
|
|
92
|
+
result.exitCode = PENDING_EXIT_CODE;
|
|
93
|
+
console.log(renderPendingBlock(
|
|
94
|
+
[{ tool: `${access.name || access.backend} board`, action: "needs-user", reason: `Karajan does not run without a board. To use ${access.name || access.backend}: ${access.needed.join(" ")}` }],
|
|
95
|
+
{ retry: "kj env install" },
|
|
96
|
+
));
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
if (access.backend !== "hu-board") console.log(`✓ board access verified: ${access.via}`);
|
|
100
|
+
|
|
101
|
+
// KJC-BUG-0133 — installing IS activating. The setup flow used to order
|
|
102
|
+
// harden + the verdict gate as TEXT steps the agent runs (or narrates);
|
|
103
|
+
// a session that skipped them got a decorative method — field case
|
|
104
|
+
// 2026-08-02: installed karajan, then wrote everything by hand with
|
|
105
|
+
// nothing to stop it. env install now does them itself, idempotently.
|
|
106
|
+
if (flags.enforce !== false) {
|
|
107
|
+
if (!existsSync(join(projectDir, ".git"))) {
|
|
108
|
+
result.exitCode = PENDING_EXIT_CODE;
|
|
109
|
+
console.log(renderPendingBlock(
|
|
110
|
+
[{ tool: "git", action: "needs-user", reason: "the enforcement gates live in git hooks — run `git init` (Karajan's guarantees do not exist without git)" }],
|
|
111
|
+
{ retry: "kj env install" },
|
|
112
|
+
));
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const h = await hardenCommand({ projectDir, logger: console });
|
|
117
|
+
if (h?.ok === false) throw new Error(h.error || "kj harden failed");
|
|
118
|
+
await reviewGateCommand({ config, flags: { installGate: true } });
|
|
119
|
+
console.log("✓ enforcement active: git hooks + cross-AI verdict gate — a commit outside the method is rejected, not narrated");
|
|
120
|
+
} catch (err) {
|
|
121
|
+
result.exitCode = PENDING_EXIT_CODE;
|
|
122
|
+
console.log(renderPendingBlock(
|
|
123
|
+
[{ tool: "enforcement", action: "needs-user", reason: `hooks/gate could not be installed: ${err.message} — without them the method is narratable` }],
|
|
124
|
+
{ retry: "kj env install" },
|
|
125
|
+
));
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ENV-E1: RAG-first — the playbook orders "query the RAG before coding",
|
|
131
|
+
// so installing the environment guarantees the index exists. KJC-TSK-0659
|
|
132
|
+
// stop-on-sudo: an index that cannot be built is a BLOCKING condition —
|
|
133
|
+
// "success" with 0 chunks would leave every future session running the
|
|
134
|
+
// method against an empty RAG (field-reproduced: 0/727 without Ollama).
|
|
135
|
+
// The playbook stays installed; the command exits 3 so the driving agent
|
|
136
|
+
// stops, shows the block, and waits for the user.
|
|
137
|
+
if (flags.rag !== false) {
|
|
138
|
+
const provider = config?.rag?.embedder?.provider || "ollama";
|
|
139
|
+
const blockRag = (why) => {
|
|
140
|
+
result.ragError = why;
|
|
141
|
+
result.exitCode = PENDING_EXIT_CODE;
|
|
142
|
+
const item = provider === "ollama"
|
|
143
|
+
? { tool: "ollama", action: "needs-user", reason: `the RAG cannot index: ${why}` }
|
|
144
|
+
: { tool: `${provider} embedder`, action: "needs-user", reason: `the RAG cannot index: ${why} — check rag.embedder in kj config`, manualUrl: "kj config" };
|
|
145
|
+
console.log(renderPendingBlock([item], { retry: "kj rag index --with-sources (then re-run: kj env install)" }));
|
|
146
|
+
};
|
|
147
|
+
// KJC-TSK-0683: on limited machines (no Ollama, no Docker) the DEFAULT
|
|
148
|
+
// provider falls back to the built-in ONNX embedder instead of blocking.
|
|
149
|
+
// Only for the first index and only when the user didn't pick a provider
|
|
150
|
+
// explicitly — the election is persisted (dims differ, it must stick).
|
|
151
|
+
const explicitProvider = Boolean(config?.rag?.embedder?.provider);
|
|
152
|
+
const tryOnnxFallback = async (why) => {
|
|
153
|
+
if (explicitProvider) return false;
|
|
154
|
+
console.log(`⚠ default embedder unavailable (${why}) — trying the built-in ONNX embedder (no install needed)…`);
|
|
155
|
+
try {
|
|
156
|
+
// KJC-BUG-0128: an empty store may carry a vec table at the wrong
|
|
157
|
+
// dim (the old probe created it at 768) — reset it so ONNX (384)
|
|
158
|
+
// can index. A store with data is never touched.
|
|
159
|
+
if (!resetEmptyStore()) {
|
|
160
|
+
console.log(" the vector store already has data at another dimension — not switching automatically");
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const totals = await ragIndexCommand({ config: onnxConfig(config), logger, flags: { withSources: true } });
|
|
164
|
+
if ((totals?.indexed ?? 0) > 0) {
|
|
165
|
+
const p = await persistOnnxChoice(projectDir);
|
|
166
|
+
console.log(`✓ RAG indexed with the built-in ONNX embedder — persisted in ${p}`);
|
|
167
|
+
console.log(" To move to Ollama later: install it, remove the rag.embedder block from .karajan/kj.config.yml,");
|
|
168
|
+
console.log(" delete the store (~/.karajan/rag.db) and run: kj rag index --with-sources");
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
} catch (fallbackErr) {
|
|
172
|
+
console.log(` ONNX fallback also failed: ${fallbackErr.message}`);
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
};
|
|
176
|
+
try {
|
|
177
|
+
if (hasRagIndex(config, projectDir)) {
|
|
178
|
+
console.log("✓ RAG index present");
|
|
179
|
+
} else {
|
|
180
|
+
console.log("⏳ no RAG index for this project — building it (first time only)…");
|
|
181
|
+
const totals = await ragIndexCommand({ config, logger, flags: { withSources: true } });
|
|
182
|
+
if ((totals?.indexed ?? 0) === 0 && (totals?.files ?? 0) > 0) {
|
|
183
|
+
const why = `0 of ${totals.files} files indexed — is the embedder running?`;
|
|
184
|
+
if (!(await tryOnnxFallback(why))) blockRag(why);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
} catch (err) {
|
|
188
|
+
if (!(await tryOnnxFallback(err.message))) blockRag(err.message);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (result.exitCode !== PENDING_EXIT_CODE) {
|
|
192
|
+
// KJC-TSK-0707 (PV-D) — privacy onboarding rides the install: kj asks,
|
|
193
|
+
// kj writes the denylist. Best-effort (stubbed in the SEA binary).
|
|
194
|
+
try {
|
|
195
|
+
const wizard = process.stdin.isTTY && process.stdout.isTTY ? createWizard() : null;
|
|
196
|
+
await ensurePrivacyList({ wizard, logger: console, isTTY: Boolean(wizard) });
|
|
197
|
+
wizard?.close();
|
|
198
|
+
} catch { /* privacy onboarding is best-effort */ }
|
|
199
|
+
console.log(" The host agent now follows the method: RAG first, TDD, cross-AI review before commit.");
|
|
200
|
+
// KJC-BUG-0133 (part 2): a mid-session install lands the playbook in
|
|
201
|
+
// CLAUDE.md, but the running session loaded its context BEFORE — nobody
|
|
202
|
+
// re-reads it. Print the method so it enters THIS conversation now.
|
|
203
|
+
console.log("\n— The Karajan method below is IN EFFECT from this very message. If your session started before this install, apply it from now on:\n");
|
|
204
|
+
console.log(renderPlaybook({ stateBackend: config?.state_backend || "hu-board", boardName: config?.board?.name || null }));
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}
|