@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
package/src/bootstrap.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project bootstrap — mandatory prerequisite gate.
|
|
3
|
+
*
|
|
4
|
+
* Before any KJ tool that executes agents (kj_run, kj_code, kj_review, etc.),
|
|
5
|
+
* this module validates that ALL environment prerequisites are met.
|
|
6
|
+
*
|
|
7
|
+
* Philosophy: NEVER degrade gracefully. If something is missing, STOP and
|
|
8
|
+
* tell the user exactly what to fix. No silent fallbacks, no auto-disabling.
|
|
9
|
+
*
|
|
10
|
+
* Results are cached in `.kj-ready.json` per project (TTL-based) so that
|
|
11
|
+
* slow checks (SonarQube reachability, agent detection) don't repeat on
|
|
12
|
+
* every invocation.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import fs from "node:fs/promises";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
import { ensureGitRepo } from "./utils/git.js";
|
|
20
|
+
import { runCommand } from "./utils/process.js";
|
|
21
|
+
import { checkBinary } from "./utils/agent-detect.js";
|
|
22
|
+
import { exists } from "./utils/fs.js";
|
|
23
|
+
import { getConfigPath, resolveRole } from "./config.js";
|
|
24
|
+
import { isSonarReachable, sonarUp } from "./sonar/manager.js";
|
|
25
|
+
import { withDocLink } from "./utils/doc-links.js";
|
|
26
|
+
|
|
27
|
+
const BOOTSTRAP_VERSION = 1;
|
|
28
|
+
const BOOTSTRAP_TTL_HOURS = 24;
|
|
29
|
+
const BOOTSTRAP_FILENAME = ".kj-ready.json";
|
|
30
|
+
|
|
31
|
+
function getPackageVersion() {
|
|
32
|
+
const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../package.json");
|
|
33
|
+
return JSON.parse(readFileSync(pkgPath, "utf8")).version;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ── Individual checks ────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
async function checkGitRepo() {
|
|
39
|
+
let ok;
|
|
40
|
+
try {
|
|
41
|
+
ok = await ensureGitRepo();
|
|
42
|
+
} catch { /* git may not be installed */
|
|
43
|
+
ok = false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!ok) {
|
|
47
|
+
// Auto-init: initialize git repo for new projects
|
|
48
|
+
const initResult = await runCommand("git", ["init"]);
|
|
49
|
+
if (initResult.exitCode !== 0) {
|
|
50
|
+
return {
|
|
51
|
+
name: "gitRepo",
|
|
52
|
+
ok: false,
|
|
53
|
+
detail: "Not a git repository and git init failed",
|
|
54
|
+
fix: "Ensure git is installed and you have write permissions to this directory."
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return { name: "gitRepo", ok: true, detail: "Initialized new git repository", fix: null };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { name: "gitRepo", ok: true, detail: "Inside a git repository", fix: null };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function checkGitRemote() {
|
|
64
|
+
try {
|
|
65
|
+
const res = await runCommand("git", ["remote", "get-url", "origin"]);
|
|
66
|
+
if (res.exitCode === 0 && res.stdout.trim()) {
|
|
67
|
+
return { name: "gitRemote", ok: true, detail: res.stdout.trim(), fix: null };
|
|
68
|
+
}
|
|
69
|
+
} catch { /* fall through */ }
|
|
70
|
+
// No remote is acceptable for new projects — non-blocking
|
|
71
|
+
return {
|
|
72
|
+
name: "gitRemote",
|
|
73
|
+
ok: true,
|
|
74
|
+
detail: "No remote configured (new project)",
|
|
75
|
+
fix: null
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function checkConfigExists() {
|
|
80
|
+
const configPath = getConfigPath();
|
|
81
|
+
const configOk = await exists(configPath);
|
|
82
|
+
return {
|
|
83
|
+
name: "config",
|
|
84
|
+
ok: configOk,
|
|
85
|
+
detail: configOk ? configPath : "Config file not found",
|
|
86
|
+
fix: configOk ? null : "Run 'kj_init' to create your Karajan config file."
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function checkCoreBinaries() {
|
|
91
|
+
const missing = [];
|
|
92
|
+
for (const bin of ["node", "npm", "git"]) {
|
|
93
|
+
const result = await checkBinary(bin);
|
|
94
|
+
if (!result.ok) {
|
|
95
|
+
missing.push(bin);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (missing.length > 0) {
|
|
99
|
+
return {
|
|
100
|
+
name: "coreBinaries",
|
|
101
|
+
ok: false,
|
|
102
|
+
detail: `Missing: ${missing.join(", ")}`,
|
|
103
|
+
fix: `Install missing binaries: ${missing.join(", ")}.`
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return { name: "coreBinaries", ok: true, detail: "node, npm, git available", fix: null };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function checkConfiguredAgents(config) {
|
|
110
|
+
const { provider } = resolveRole(config, "coder");
|
|
111
|
+
if (!provider) {
|
|
112
|
+
return {
|
|
113
|
+
name: "agents",
|
|
114
|
+
ok: false,
|
|
115
|
+
detail: "No coder provider configured",
|
|
116
|
+
fix: "Run 'kj_init' or set a coder provider in kj.config.yml."
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const result = await checkBinary(provider);
|
|
120
|
+
if (!result.ok) {
|
|
121
|
+
return {
|
|
122
|
+
name: "agents",
|
|
123
|
+
ok: false,
|
|
124
|
+
detail: `Coder agent "${provider}" not found`,
|
|
125
|
+
fix: `Install "${provider}" CLI. Run 'kj_doctor' for installation instructions.`
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return { name: "agents", ok: true, detail: `coder: ${provider}`, fix: null };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function checkSonarQubeReady(config) {
|
|
132
|
+
if (config.sonarqube?.enabled === false) {
|
|
133
|
+
return { name: "sonarqube", ok: true, detail: "Disabled in config", fix: null };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const host = config.sonarqube?.host || "http://localhost:9000";
|
|
137
|
+
|
|
138
|
+
// First attempt
|
|
139
|
+
let reachable = await isSonarReachable(host);
|
|
140
|
+
if (reachable) {
|
|
141
|
+
return { name: "sonarqube", ok: true, detail: `Reachable at ${host}`, fix: null };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Auto-remediation: start and wait up to 60s for SonarQube to be ready
|
|
145
|
+
try {
|
|
146
|
+
await sonarUp(host);
|
|
147
|
+
const deadline = Date.now() + 60000;
|
|
148
|
+
while (Date.now() < deadline) {
|
|
149
|
+
reachable = await isSonarReachable(host);
|
|
150
|
+
if (reachable) {
|
|
151
|
+
return { name: "sonarqube", ok: true, detail: `Started and reachable at ${host}`, fix: null };
|
|
152
|
+
}
|
|
153
|
+
await new Promise(r => setTimeout(r, 5000));
|
|
154
|
+
}
|
|
155
|
+
} catch { /* fall through */ }
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
name: "sonarqube",
|
|
159
|
+
ok: false,
|
|
160
|
+
detail: `Not reachable at ${host}`,
|
|
161
|
+
fix: `Start SonarQube: 'docker start karajan-sonarqube', or disable it: set sonarqube.enabled: false in kj.config.yml, or pass --no-sonar.`
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ── Bootstrap file management ────────────────────────────────────────
|
|
166
|
+
|
|
167
|
+
function bootstrapPath(projectDir) {
|
|
168
|
+
return path.join(projectDir, BOOTSTRAP_FILENAME);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function readBootstrapFile(projectDir) {
|
|
172
|
+
try {
|
|
173
|
+
const raw = await fs.readFile(bootstrapPath(projectDir), "utf8");
|
|
174
|
+
return JSON.parse(raw);
|
|
175
|
+
} catch { /* bootstrap file may not exist or contain invalid JSON */
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function isBootstrapValid(bootstrap, projectDir) {
|
|
181
|
+
if (!bootstrap || bootstrap.version !== BOOTSTRAP_VERSION) return false;
|
|
182
|
+
if (bootstrap.karajanVersion !== getPackageVersion()) return false;
|
|
183
|
+
if (bootstrap.projectDir !== projectDir) return false;
|
|
184
|
+
const age = Date.now() - new Date(bootstrap.createdAt).getTime();
|
|
185
|
+
if (age > BOOTSTRAP_TTL_HOURS * 3600 * 1000) return false;
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function writeBootstrapFile(projectDir, checks) {
|
|
190
|
+
const data = {
|
|
191
|
+
version: BOOTSTRAP_VERSION,
|
|
192
|
+
karajanVersion: getPackageVersion(),
|
|
193
|
+
createdAt: new Date().toISOString(),
|
|
194
|
+
projectDir,
|
|
195
|
+
checks: Object.fromEntries(checks.map(c => [c.name, { ok: c.ok, detail: c.detail }]))
|
|
196
|
+
};
|
|
197
|
+
await fs.writeFile(bootstrapPath(projectDir), JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function formatBootstrapFailure(failures) {
|
|
201
|
+
const lines = failures.map(f =>
|
|
202
|
+
` FAIL ${f.name}: ${f.detail}\n Fix: ${f.fix}`
|
|
203
|
+
);
|
|
204
|
+
return withDocLink([
|
|
205
|
+
"BOOTSTRAP FAILED — Environment not ready for Karajan Code.\n",
|
|
206
|
+
"The following prerequisite(s) are not met:\n",
|
|
207
|
+
...lines,
|
|
208
|
+
"",
|
|
209
|
+
"Run 'kj_doctor' for a complete environment diagnostic.",
|
|
210
|
+
"Do NOT work around these issues — fix them properly."
|
|
211
|
+
].join("\n"), "bootstrap_failed");
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ── Public API ───────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Ensure the project environment is ready for KJ execution.
|
|
218
|
+
* Reads cached `.kj-ready.json` if valid; otherwise runs all checks.
|
|
219
|
+
* Throws Error with actionable message if any prerequisite fails.
|
|
220
|
+
*/
|
|
221
|
+
export async function ensureBootstrap(projectDir, config) {
|
|
222
|
+
// Plugin discovery runs unconditionally on every bootstrap, regardless
|
|
223
|
+
// of whether the bootstrap cache says environment is valid. A user
|
|
224
|
+
// dropping a new file into `.karajan/plugins/` expects it to be picked
|
|
225
|
+
// up without running `kj init` again.
|
|
226
|
+
//
|
|
227
|
+
// Pre-v2.7.5 this was never called — `loadPlugins()` was exported but
|
|
228
|
+
// never imported from production code, so any plugin the user added
|
|
229
|
+
// was silently ignored. Fixed in TSK-0329.
|
|
230
|
+
try {
|
|
231
|
+
const { loadPlugins } = await import("./plugins/loader.js");
|
|
232
|
+
await loadPlugins({ projectDir });
|
|
233
|
+
} catch { /* plugin system failed — non-blocking, continue bootstrap */ }
|
|
234
|
+
|
|
235
|
+
// TSK-0339: register the Planning Game adapter in the integrations registry
|
|
236
|
+
// when enabled. The orchestrator no longer imports `src/planning-game/*`
|
|
237
|
+
// directly — it calls `getIntegration("tracker")?.hookName(...)` instead.
|
|
238
|
+
// Other trackers (GitHub Projects, Jira, Linear, …) drop in by writing
|
|
239
|
+
// a sibling adapter that calls `registerIntegration("tracker", …)`.
|
|
240
|
+
if (config?.planning_game?.enabled) {
|
|
241
|
+
try {
|
|
242
|
+
const { registerPgAdapter } = await import("./planning-game/pipeline-adapter.js");
|
|
243
|
+
await registerPgAdapter();
|
|
244
|
+
} catch { /* PG registration failed — non-blocking, continue bootstrap */ }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const cached = await readBootstrapFile(projectDir);
|
|
248
|
+
if (isBootstrapValid(cached, projectDir)) {
|
|
249
|
+
return; // Environment already validated
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const checks = await Promise.all([
|
|
253
|
+
checkGitRepo(),
|
|
254
|
+
checkGitRemote(),
|
|
255
|
+
checkConfigExists(),
|
|
256
|
+
checkCoreBinaries(),
|
|
257
|
+
checkConfiguredAgents(config),
|
|
258
|
+
checkSonarQubeReady(config)
|
|
259
|
+
]);
|
|
260
|
+
|
|
261
|
+
const failures = checks.filter(c => !c.ok);
|
|
262
|
+
if (failures.length > 0) {
|
|
263
|
+
throw new Error(formatBootstrapFailure(failures));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
await writeBootstrapFile(projectDir, checks);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Delete `.kj-ready.json` to force re-validation on next run.
|
|
271
|
+
*/
|
|
272
|
+
export async function invalidateBootstrap(projectDir) {
|
|
273
|
+
try {
|
|
274
|
+
await fs.unlink(bootstrapPath(projectDir));
|
|
275
|
+
} catch { /* file may not exist */ }
|
|
276
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// KJC-TSK-0411: clasificador universal de errores de agente IA.
|
|
2
|
+
//
|
|
3
|
+
// Devuelve clase rica + metadata accionable para que Brain (TSK-0412)
|
|
4
|
+
// decida retry/standby/hibernar/abortar sin tener que repetir lógica
|
|
5
|
+
// de parsing en cada stage.
|
|
6
|
+
//
|
|
7
|
+
// Reutiliza parseCooldown del rate-limit-detector legacy para no
|
|
8
|
+
// duplicar regex. Este módulo extiende la clasificación:
|
|
9
|
+
// - RATE_LIMIT_SHORT vs QUOTA_EXHAUSTED_DAILY se distinguen por
|
|
10
|
+
// cooldownMs (threshold 1h).
|
|
11
|
+
// - SILENCED se detecta por exit 143/null + "killed after Nms".
|
|
12
|
+
// - AUTH_FAILED por 401/403 + "Unauthorized"/"invalid api key".
|
|
13
|
+
// - NETWORK_TIMEOUT por ECONN*/socket hang up sin cooldown.
|
|
14
|
+
|
|
15
|
+
import { parseCooldown } from "../utils/rate-limit-detector.js";
|
|
16
|
+
|
|
17
|
+
export const ERROR_CLASS = Object.freeze({
|
|
18
|
+
RATE_LIMIT_SHORT: "RATE_LIMIT_SHORT",
|
|
19
|
+
QUOTA_EXHAUSTED_DAILY: "QUOTA_EXHAUSTED_DAILY",
|
|
20
|
+
// KJC-TSK-0415: Anthropic Max 20x cambia a $200/mes Agent SDK desde
|
|
21
|
+
// 15-jun-2026. Cuando llegues al cap mensual, el reset es 1-mes —
|
|
22
|
+
// muy distinto del daily de Claude Pro. Esta clase distingue ambos.
|
|
23
|
+
QUOTA_EXHAUSTED_MONTHLY: "QUOTA_EXHAUSTED_MONTHLY",
|
|
24
|
+
API_DOWN: "API_DOWN",
|
|
25
|
+
AUTH_FAILED: "AUTH_FAILED",
|
|
26
|
+
NETWORK_TIMEOUT: "NETWORK_TIMEOUT",
|
|
27
|
+
SILENCED: "SILENCED",
|
|
28
|
+
UNKNOWN_FATAL: "UNKNOWN_FATAL",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const ONE_HOUR_MS = 60 * 60 * 1000;
|
|
32
|
+
const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
33
|
+
|
|
34
|
+
// `error\s+authenticating` + `IneligibleTierError` (KJC-BUG-0113): the
|
|
35
|
+
// retired Gemini Code Assist CLI fails with "Error authenticating:
|
|
36
|
+
// IneligibleTierError … migrate to Antigravity" — it classified as
|
|
37
|
+
// UNKNOWN_FATAL and left the run without the AUTH escalation message.
|
|
38
|
+
const AUTH_PATTERNS = /\b401\b|\b403\b|unauthorized|invalid\s+api\s+key|authentication\s+failed|expired\s+token|error\s+authenticating|IneligibleTierError/i;
|
|
39
|
+
const SILENCED_PATTERNS = /killed\s+after\s+\d+\s*ms|silence\s*timeout|no\s+output\s+for\s+\d+/i;
|
|
40
|
+
// `session\s+limit` / `weekly\s+limit` cover Claude Code's usage caps
|
|
41
|
+
// ("You've hit your session limit · resets 10:10pm"). Without them the
|
|
42
|
+
// message fell through to UNKNOWN_FATAL and the run aborted instead of
|
|
43
|
+
// hibernating until the reset.
|
|
44
|
+
// Decomposed by family (S5843, complexity 36 → 3 named groups). The
|
|
45
|
+
// union of tokens is identical to the original single alternation.
|
|
46
|
+
const RATE_LIMIT_GROUPS = [
|
|
47
|
+
/rate\s*limit|too\s+many\s+requests|\b429\b|throttl/i,
|
|
48
|
+
/exceeded\s+your\s+current\s+quota|resource\s+exhausted|quota\s+exceeded|token\s+limit\s+reached/i,
|
|
49
|
+
/usage\s+limit|monthly\s+limit|weekly\s+limit|daily\s+limit|session\s+limit/i,
|
|
50
|
+
];
|
|
51
|
+
const RATE_LIMIT_PATTERNS = { test: (text) => RATE_LIMIT_GROUPS.some((re) => re.test(text)) };
|
|
52
|
+
const API_DOWN_PATTERNS = /\b50[0-4]\b|bad\s+gateway|service\s+unavailable|gateway\s+timeout|overloaded|internal\s+server\s+error/i;
|
|
53
|
+
const NETWORK_PATTERNS = /ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket\s+hang\s+up|fetch\s+failed|network\s+error/i;
|
|
54
|
+
|
|
55
|
+
function pickMessage(combined, pattern) {
|
|
56
|
+
const line = combined.split("\n").find((l) => pattern.test(l));
|
|
57
|
+
return (line || combined).trim().slice(0, 300);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {object} args
|
|
62
|
+
* @param {string} [args.provider] - claude|codex|gemini|opencode|aider
|
|
63
|
+
* @param {string} [args.stdout]
|
|
64
|
+
* @param {string} [args.stderr]
|
|
65
|
+
* @param {number|null} [args.exitCode]
|
|
66
|
+
* @returns {{ class: string, provider: string, message: string, retryAfter: number|null, retryUntil: string|null, recoverable: boolean, exitCode: number|null }}
|
|
67
|
+
*/
|
|
68
|
+
export function classifyAgentError({ provider = "unknown", stdout = "", stderr = "", exitCode = null }) {
|
|
69
|
+
const combined = `${stderr}\n${stdout}`;
|
|
70
|
+
const base = { provider, exitCode, retryAfter: null, retryUntil: null };
|
|
71
|
+
|
|
72
|
+
// 1. AUTH_FAILED tiene prioridad absoluta — no es recuperable, escalar al usuario.
|
|
73
|
+
if (AUTH_PATTERNS.test(combined)) {
|
|
74
|
+
return { ...base, class: ERROR_CLASS.AUTH_FAILED, message: pickMessage(combined, AUTH_PATTERNS), recoverable: false };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 2. SILENCED: subprocess killed por silenceTimeout. exit=143 (SIGTERM) o null.
|
|
78
|
+
// También detectamos por mensaje aunque exitCode no encaje (resiliente).
|
|
79
|
+
if (SILENCED_PATTERNS.test(combined) || (exitCode === 143 && !combined.trim())) {
|
|
80
|
+
return { ...base, class: ERROR_CLASS.SILENCED, message: pickMessage(combined, SILENCED_PATTERNS) || "Agent silenciado por timeout", recoverable: true };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 3. RATE_LIMIT con cooldown. Thresholds:
|
|
84
|
+
// cooldown > 7d → MONTHLY (Anthropic Agent SDK $200/mes desde jun-2026)
|
|
85
|
+
// cooldown > 1h → DAILY (Claude Pro daily, OpenAI rate-limit-by-day)
|
|
86
|
+
// cooldown <= 1h → SHORT (rate limit transitorio)
|
|
87
|
+
if (RATE_LIMIT_PATTERNS.test(combined)) {
|
|
88
|
+
const msg = pickMessage(combined, RATE_LIMIT_PATTERNS);
|
|
89
|
+
const { cooldownUntil, cooldownMs } = parseCooldown(msg) ?? {};
|
|
90
|
+
let quotaClass;
|
|
91
|
+
if (cooldownMs != null && cooldownMs > ONE_WEEK_MS) quotaClass = ERROR_CLASS.QUOTA_EXHAUSTED_MONTHLY;
|
|
92
|
+
else if (cooldownMs != null && cooldownMs > ONE_HOUR_MS) quotaClass = ERROR_CLASS.QUOTA_EXHAUSTED_DAILY;
|
|
93
|
+
else quotaClass = ERROR_CLASS.RATE_LIMIT_SHORT;
|
|
94
|
+
return {
|
|
95
|
+
...base,
|
|
96
|
+
class: quotaClass,
|
|
97
|
+
message: msg,
|
|
98
|
+
retryAfter: cooldownMs ?? null,
|
|
99
|
+
retryUntil: cooldownUntil ?? null,
|
|
100
|
+
recoverable: true,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 4. NETWORK errors antes que API_DOWN — ECONN* es a nivel socket, no respuesta HTTP.
|
|
105
|
+
if (NETWORK_PATTERNS.test(combined)) {
|
|
106
|
+
return { ...base, class: ERROR_CLASS.NETWORK_TIMEOUT, message: pickMessage(combined, NETWORK_PATTERNS), recoverable: true };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 5. API_DOWN: 5xx, overloaded.
|
|
110
|
+
if (API_DOWN_PATTERNS.test(combined)) {
|
|
111
|
+
return { ...base, class: ERROR_CLASS.API_DOWN, message: pickMessage(combined, API_DOWN_PATTERNS), recoverable: true };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 6. UNKNOWN_FATAL: salida no clasificada con exitCode != 0.
|
|
115
|
+
return { ...base, class: ERROR_CLASS.UNKNOWN_FATAL, message: combined.trim().slice(0, 300) || `exit ${exitCode}`, recoverable: false };
|
|
116
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks every routing decision the Brain makes during a session and enforces
|
|
3
|
+
* safety limits (max decisions per session, indecision-loop detection).
|
|
4
|
+
*
|
|
5
|
+
* Decisions are appended to `session.brainDecisions`. Consumers call
|
|
6
|
+
* `recordDecision(tracker, decision, context)` after a buildDecision() call
|
|
7
|
+
* and `checkLimits(tracker)` before making another decision.
|
|
8
|
+
*
|
|
9
|
+
* The limits are soft guards, not hard failures: hitting a limit surfaces
|
|
10
|
+
* a status that the orchestrator can use to escalate to Solomon or pause
|
|
11
|
+
* the session for human input.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { setBrainDecisions } from "../session/mutators.js";
|
|
15
|
+
|
|
16
|
+
export const DEFAULT_MAX_DECISIONS = 20;
|
|
17
|
+
export const INDECISION_REPEAT_THRESHOLD = 3; // 3 identical classifications in a row
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} RecordedDecision
|
|
21
|
+
* @property {number} seq
|
|
22
|
+
* @property {string} at - ISO timestamp
|
|
23
|
+
* @property {string} intent - e.g. "sw:medium" (taskType:level)
|
|
24
|
+
* @property {string[]} rolesOn
|
|
25
|
+
* @property {"low"|"medium"|"high"} confidence
|
|
26
|
+
* @property {string} rationale
|
|
27
|
+
* @property {string[]} appliedOverrides
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {Object} TrackerStatus
|
|
32
|
+
* @property {"ok"|"max-reached"|"indecision"} status
|
|
33
|
+
* @property {number} decisionCount
|
|
34
|
+
* @property {string} [detail]
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Initialize a tracker bound to a session. If the session already has a
|
|
39
|
+
* `brainDecisions` array (e.g. from a resumed session), keep it.
|
|
40
|
+
*
|
|
41
|
+
* @param {Object} session
|
|
42
|
+
* @param {{ max?: number }} [options]
|
|
43
|
+
* @returns {{ session: Object, max: number }}
|
|
44
|
+
*/
|
|
45
|
+
export function createTracker(session, { max = DEFAULT_MAX_DECISIONS } = {}) {
|
|
46
|
+
if (!Array.isArray(session.brainDecisions)) {
|
|
47
|
+
setBrainDecisions(session, []);
|
|
48
|
+
}
|
|
49
|
+
return { session, max };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Append a decision to the tracker.
|
|
54
|
+
*
|
|
55
|
+
* @param {{ session: Object, max: number }} tracker
|
|
56
|
+
* @param {Object} decision - output of buildDecision()
|
|
57
|
+
* @param {{ taskType?: string, level?: string }} intent
|
|
58
|
+
* @returns {RecordedDecision}
|
|
59
|
+
*/
|
|
60
|
+
export function recordDecision(tracker, decision, intent = {}) {
|
|
61
|
+
const seq = tracker.session.brainDecisions.length + 1;
|
|
62
|
+
const entry = {
|
|
63
|
+
seq,
|
|
64
|
+
at: new Date().toISOString(),
|
|
65
|
+
intent: `${intent.taskType || "?"}:${intent.level || "?"}`,
|
|
66
|
+
rolesOn: Array.isArray(decision.rolesOn) ? [...decision.rolesOn] : [],
|
|
67
|
+
confidence: decision.confidence || "medium",
|
|
68
|
+
rationale: decision.rationale || "",
|
|
69
|
+
appliedOverrides: Array.isArray(decision.appliedOverrides) ? [...decision.appliedOverrides] : [],
|
|
70
|
+
};
|
|
71
|
+
tracker.session.brainDecisions.push(entry);
|
|
72
|
+
return entry;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Compute status of the tracker. Called BEFORE recording a new decision so
|
|
77
|
+
* the orchestrator can decide to escalate instead of calling the Brain again.
|
|
78
|
+
*
|
|
79
|
+
* @param {{ session: Object, max: number }} tracker
|
|
80
|
+
* @returns {TrackerStatus}
|
|
81
|
+
*/
|
|
82
|
+
export function checkLimits(tracker) {
|
|
83
|
+
const decisions = tracker.session.brainDecisions || [];
|
|
84
|
+
const decisionCount = decisions.length;
|
|
85
|
+
|
|
86
|
+
if (decisionCount >= tracker.max) {
|
|
87
|
+
return {
|
|
88
|
+
status: "max-reached",
|
|
89
|
+
decisionCount,
|
|
90
|
+
detail: `Brain made ${decisionCount} decisions (limit ${tracker.max}). Escalate to Solomon or human.`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Indecision loop: last N decisions share the exact same intent.
|
|
95
|
+
const window = decisions.slice(-INDECISION_REPEAT_THRESHOLD);
|
|
96
|
+
if (window.length >= INDECISION_REPEAT_THRESHOLD && window.every((d) => d.intent === window[0].intent)) {
|
|
97
|
+
return {
|
|
98
|
+
status: "indecision",
|
|
99
|
+
decisionCount,
|
|
100
|
+
detail: `Brain classified the same intent (${window[0].intent}) ${INDECISION_REPEAT_THRESHOLD} times in a row — loop detected.`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { status: "ok", decisionCount };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Build a short summary of all decisions made in the session. Useful for the
|
|
109
|
+
* final report and for debugging.
|
|
110
|
+
*
|
|
111
|
+
* @param {{ session: Object }} tracker
|
|
112
|
+
* @returns {{ total: number, byIntent: Record<string,number>, lastRationale: string }}
|
|
113
|
+
*/
|
|
114
|
+
export function summarize(tracker) {
|
|
115
|
+
const decisions = tracker.session.brainDecisions || [];
|
|
116
|
+
const byIntent = {};
|
|
117
|
+
for (const d of decisions) {
|
|
118
|
+
byIntent[d.intent] = (byIntent[d.intent] || 0) + 1;
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
total: decisions.length,
|
|
122
|
+
byIntent,
|
|
123
|
+
lastRationale: decisions.at(-1)?.rationale ?? "",
|
|
124
|
+
};
|
|
125
|
+
}
|