@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,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ai-surface — MCP inventory with drift detection (KJC-TSK-0694).
|
|
3
|
+
*
|
|
4
|
+
* Every new tool an agent gains is one more access. An inventory nobody
|
|
5
|
+
* reconciles is "the feeling of control without the control", so kj check
|
|
6
|
+
* flags what APPEARED since the last run and asks the user to own it.
|
|
7
|
+
* A nudge, never a gate. ~/.claude.json is scoped to its global block plus
|
|
8
|
+
* THIS project's entry — other projects' MCPs are not reachable here.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
12
|
+
import os from "node:os";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
|
|
15
|
+
const sources = (projectDir, home) => [
|
|
16
|
+
{ file: path.join(projectDir, ".mcp.json"), format: "json" },
|
|
17
|
+
{ file: path.join(home, ".claude.json"), format: "json" },
|
|
18
|
+
{ file: path.join(home, ".codex", "config.toml"), format: "toml" },
|
|
19
|
+
{ file: path.join(home, ".gemini", "settings.json"), format: "json" },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
function jsonServerNames(text, projectDir) {
|
|
23
|
+
try {
|
|
24
|
+
const parsed = JSON.parse(text);
|
|
25
|
+
const names = new Set(Object.keys(parsed.mcpServers || {}));
|
|
26
|
+
for (const name of Object.keys(parsed.projects?.[projectDir]?.mcpServers || {})) names.add(name);
|
|
27
|
+
return names;
|
|
28
|
+
} catch {
|
|
29
|
+
return new Set();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const tomlServerNames = (text) =>
|
|
34
|
+
new Set([...text.matchAll(/^\s*\[mcp_servers\.["']?([^\]"']+)["']?\]/gm)].map((m) => m[1]));
|
|
35
|
+
|
|
36
|
+
/** Sorted `name (config-file)` entries for every MCP reachable in this project. */
|
|
37
|
+
export function collectAiSurface({ projectDir = process.cwd(), home = os.homedir() } = {}) {
|
|
38
|
+
const surface = new Set();
|
|
39
|
+
for (const { file, format } of sources(projectDir, home)) {
|
|
40
|
+
if (!existsSync(file)) continue;
|
|
41
|
+
let text;
|
|
42
|
+
try { text = readFileSync(file, "utf8"); } catch { continue; }
|
|
43
|
+
const names = format === "toml" ? tomlServerNames(text) : jsonServerNames(text, projectDir);
|
|
44
|
+
for (const name of names) surface.add(`${name} (${path.basename(file)})`);
|
|
45
|
+
}
|
|
46
|
+
return [...surface].sort();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Diff the current surface against the last-seen snapshot and persist the
|
|
51
|
+
* new state. First run records the baseline silently.
|
|
52
|
+
*/
|
|
53
|
+
export function checkAiSurface({ projectDir = process.cwd(), home = os.homedir(), statePath = path.join(os.homedir(), ".karajan", "ai-surface.json"), extraSurface = [] } = {}) {
|
|
54
|
+
// KJC-TSK-0728: extraSurface carries entries the (async) caller collected
|
|
55
|
+
// outside config files — e.g. observed agent CLIs as "grok (cli)" — so
|
|
56
|
+
// they ride the same snapshot and the same "NEW since last check" drift.
|
|
57
|
+
const surface = [...new Set([...collectAiSurface({ projectDir, home }), ...extraSurface])].sort();
|
|
58
|
+
let state = {};
|
|
59
|
+
try { state = JSON.parse(readFileSync(statePath, "utf8")); } catch { /* first run or corrupt → baseline */ }
|
|
60
|
+
const prev = Array.isArray(state[projectDir]) ? state[projectDir] : null;
|
|
61
|
+
const added = prev ? surface.filter((e) => !prev.includes(e)) : [];
|
|
62
|
+
const removed = prev ? prev.filter((e) => !surface.includes(e)) : [];
|
|
63
|
+
state[projectDir] = surface;
|
|
64
|
+
try {
|
|
65
|
+
mkdirSync(path.dirname(statePath), { recursive: true });
|
|
66
|
+
writeFileSync(statePath, JSON.stringify(state, null, 2));
|
|
67
|
+
} catch { /* read-only FS — inventory still reports, just cannot remember */ }
|
|
68
|
+
return { surface, added, removed, first: !prev };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** One line for kj check output. */
|
|
72
|
+
export function formatAiSurface({ surface, added, removed, first }) {
|
|
73
|
+
const head = `ai surface: ${surface.length} MCP(s)`;
|
|
74
|
+
if (first) return `${head} — baseline recorded`;
|
|
75
|
+
const parts = [head];
|
|
76
|
+
if (added.length) parts.push(`NEW since last check: ${added.join(", ")} — approved by you?`);
|
|
77
|
+
if (removed.length) parts.push(`gone: ${removed.join(", ")}`);
|
|
78
|
+
return parts.join(" · ");
|
|
79
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ai-trash safety net availability check (KJC-TSK-0391).
|
|
3
|
+
* Surfaces a WARN in `kj doctor` when the `kj-trash` binary is missing,
|
|
4
|
+
* since the PreToolUse hook cannot snapshot destructive ops without it.
|
|
5
|
+
* The remediation is `kj-trash install --claude-code` once the binary is
|
|
6
|
+
* on PATH (the workspace ships it with karajan-code).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { detectAiTrash } from "../utils/ai-trash.js";
|
|
10
|
+
import { STRATEGY } from "./types.js";
|
|
11
|
+
|
|
12
|
+
function createAiTrashCheck() {
|
|
13
|
+
return {
|
|
14
|
+
name: "ai-trash",
|
|
15
|
+
label: "ai-trash safety net",
|
|
16
|
+
strategy: STRATEGY.MANUAL,
|
|
17
|
+
async detect() {
|
|
18
|
+
const res = await detectAiTrash();
|
|
19
|
+
if (res.available) {
|
|
20
|
+
return { ok: true, severity: "info", detail: "kj-trash present — preventive safety net active" };
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
severity: "warn",
|
|
25
|
+
detail: "kj-trash not found — destructive ops unprotected",
|
|
26
|
+
fix: "Install karajan-code globally (npm i -g karajan-code) so kj-trash is on PATH, then run `kj-trash install --claude-code`",
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getAiTrashChecks() {
|
|
33
|
+
return [createAiTrashCheck()];
|
|
34
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary / CLI availability checks.
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - Agent CLIs (claude, codex, gemini, aider, opencode)
|
|
6
|
+
* - Core binaries (node, npm, git)
|
|
7
|
+
* - Docker
|
|
8
|
+
* - Serena MCP (optional)
|
|
9
|
+
*
|
|
10
|
+
* All binary checks use `strategy: "manual"` because auto-installing binaries
|
|
11
|
+
* is invasive and platform-specific. Exception: Serena is `"prompt"` (we know
|
|
12
|
+
* the install command and can offer to run it).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { checkBinary, KNOWN_AGENTS, detectObservedAgents } from "../utils/agent-detect.js";
|
|
16
|
+
import { runCommand } from "../utils/process.js";
|
|
17
|
+
import { withDocLink } from "../utils/doc-links.js";
|
|
18
|
+
import { getInstallHint, appliesToStack } from "../utils/install-hints.js";
|
|
19
|
+
import { STRATEGY } from "./types.js";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Check the presence of a named agent CLI (claude/codex/gemini/aider).
|
|
23
|
+
*/
|
|
24
|
+
function createAgentCheck(agent) {
|
|
25
|
+
return {
|
|
26
|
+
name: `agent:${agent.name}`,
|
|
27
|
+
label: `Agent: ${agent.name}`,
|
|
28
|
+
strategy: STRATEGY.MANUAL,
|
|
29
|
+
async detect() {
|
|
30
|
+
const result = await checkBinary(agent.name);
|
|
31
|
+
return {
|
|
32
|
+
ok: result.ok,
|
|
33
|
+
severity: "warn", // missing one agent CLI shouldn't block — user may not use it
|
|
34
|
+
detail: result.ok ? `${result.version} (${result.path})` : "Not found",
|
|
35
|
+
fix: result.ok ? undefined : withDocLink(`Install: ${agent.install}`, "agent_not_found"),
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* KJC-TSK-0728 — ONE aggregate line for the observation census (agent CLIs
|
|
43
|
+
* kj sees but does not drive). Only FOUND CLIs are listed; the missing ones
|
|
44
|
+
* make no noise, and the check never fails. `detector` is injectable for
|
|
45
|
+
* tests.
|
|
46
|
+
*/
|
|
47
|
+
export function createObservedAgentsCheck({ detector = detectObservedAgents } = {}) {
|
|
48
|
+
return {
|
|
49
|
+
name: "agents:observed",
|
|
50
|
+
label: "Agent CLIs observed (not driven)",
|
|
51
|
+
strategy: STRATEGY.MANUAL,
|
|
52
|
+
async detect() {
|
|
53
|
+
let found = [];
|
|
54
|
+
try {
|
|
55
|
+
found = (await detector()).filter((a) => a.available);
|
|
56
|
+
} catch { /* census is best-effort */ }
|
|
57
|
+
return {
|
|
58
|
+
ok: true,
|
|
59
|
+
severity: "info",
|
|
60
|
+
detail: found.length
|
|
61
|
+
? found.map((a) => `${a.name} (${(a.version || "").split(" ").at(-1) || "?"})`).join(", ")
|
|
62
|
+
: "none detected",
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Check the presence of a core binary (node, npm, git).
|
|
70
|
+
*/
|
|
71
|
+
function createCoreBinaryCheck(bin) {
|
|
72
|
+
return {
|
|
73
|
+
name: bin,
|
|
74
|
+
label: bin,
|
|
75
|
+
strategy: STRATEGY.MANUAL,
|
|
76
|
+
async detect() {
|
|
77
|
+
const result = await checkBinary(bin);
|
|
78
|
+
return {
|
|
79
|
+
ok: result.ok,
|
|
80
|
+
severity: "fail",
|
|
81
|
+
detail: result.ok ? result.version : "Not found",
|
|
82
|
+
fix: result.ok ? undefined : `Install ${bin} from its official website.`,
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Docker check. Manual strategy (platform-dependent install).
|
|
90
|
+
*/
|
|
91
|
+
function createDockerCheck() {
|
|
92
|
+
return {
|
|
93
|
+
name: "docker",
|
|
94
|
+
label: "Docker",
|
|
95
|
+
strategy: STRATEGY.MANUAL,
|
|
96
|
+
async detect() {
|
|
97
|
+
const docker = await checkBinary("docker", "--version");
|
|
98
|
+
return {
|
|
99
|
+
ok: docker.ok,
|
|
100
|
+
severity: "warn", // only required if Sonar enabled; soft-fail here
|
|
101
|
+
detail: docker.ok ? docker.version : "Not found",
|
|
102
|
+
fix: docker.ok ? undefined : withDocLink("Install Docker: https://docs.docker.com/get-docker/", "sonar_docker"),
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Serena MCP (optional). Prompt strategy: we know how to install it.
|
|
110
|
+
*/
|
|
111
|
+
function createSerenaCheck() {
|
|
112
|
+
return {
|
|
113
|
+
name: "serena",
|
|
114
|
+
label: "Serena MCP",
|
|
115
|
+
strategy: STRATEGY.MANUAL,
|
|
116
|
+
applies: (config) => config.serena?.enabled === true,
|
|
117
|
+
describe: "Install Serena via: uvx --from git+https://github.com/oraios/serena serena",
|
|
118
|
+
async detect() {
|
|
119
|
+
let ok;
|
|
120
|
+
try {
|
|
121
|
+
const res = await runCommand("serena", ["--version"]);
|
|
122
|
+
ok = res.exitCode === 0;
|
|
123
|
+
} catch {
|
|
124
|
+
ok = false;
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
ok,
|
|
128
|
+
severity: "warn",
|
|
129
|
+
detail: ok ? "Available" : "Not found (prompts will still include Serena instructions)",
|
|
130
|
+
fix: ok ? undefined : "Install Serena: uvx --from git+https://github.com/oraios/serena serena --help",
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Audit-side external tool (semgrep, osv-scanner, lighthouse) check.
|
|
138
|
+
*
|
|
139
|
+
* These are not blockers: `kj audit` and `kj webperf` degrade to
|
|
140
|
+
* available:false when missing. We surface them in `kj doctor` so the
|
|
141
|
+
* user can see at a glance which audit dimensions are active, and we
|
|
142
|
+
* point to `kj install-tools` for one-line remediation.
|
|
143
|
+
*
|
|
144
|
+
* `lighthouse` is stack-gated: only flagged when the project is
|
|
145
|
+
* frontend / fullstack. On backend-only projects the check is a no-op
|
|
146
|
+
* (returns ok:true with detail "n/a") to keep doctor output focused.
|
|
147
|
+
*/
|
|
148
|
+
function createAuditToolCheck(tool, { gatedByStack = false, label }) {
|
|
149
|
+
return {
|
|
150
|
+
name: `audit-tool:${tool}`,
|
|
151
|
+
label,
|
|
152
|
+
strategy: STRATEGY.MANUAL,
|
|
153
|
+
async detect({ config } = {}) {
|
|
154
|
+
if (gatedByStack) {
|
|
155
|
+
// Stack detection is best-effort — failing here just means we
|
|
156
|
+
// treat the project as backend-only (skip the check). Keeps the
|
|
157
|
+
// doctor pipeline resilient to weird repos.
|
|
158
|
+
let stack = null;
|
|
159
|
+
try {
|
|
160
|
+
const { detectProjectStack } = await import("../utils/stack-detect.js");
|
|
161
|
+
stack = await detectProjectStack(config?.projectDir || process.cwd());
|
|
162
|
+
} catch { /* ignore */ }
|
|
163
|
+
if (!appliesToStack(tool, stack)) {
|
|
164
|
+
return { ok: true, severity: "info", detail: "n/a (no frontend stack detected)" };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const result = await checkBinary(tool);
|
|
168
|
+
if (result.ok) {
|
|
169
|
+
return { ok: true, severity: "info", detail: result.version || "available" };
|
|
170
|
+
}
|
|
171
|
+
const hint = await getInstallHint(tool);
|
|
172
|
+
const fixLine = hint.command
|
|
173
|
+
? `Run \`kj install-tools --only ${tool}\` or: ${hint.command}`
|
|
174
|
+
: `Run \`kj install-tools --only ${tool}\` or see ${hint.manualUrl}`;
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
severity: "warn",
|
|
178
|
+
detail: "Not found — `kj audit` dimension will degrade",
|
|
179
|
+
fix: fixLine,
|
|
180
|
+
extra: { tool, suggested: hint.command, manager: hint.manager, manualUrl: hint.manualUrl },
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Aggregate: all binary-related checks for the current config.
|
|
188
|
+
* @returns {import("./types.js").Check[]}
|
|
189
|
+
*/
|
|
190
|
+
export function getBinaryChecks() {
|
|
191
|
+
const checks = [];
|
|
192
|
+
for (const agent of KNOWN_AGENTS) {
|
|
193
|
+
checks.push(createAgentCheck(agent));
|
|
194
|
+
}
|
|
195
|
+
checks.push(createObservedAgentsCheck());
|
|
196
|
+
for (const bin of ["node", "npm", "git"]) {
|
|
197
|
+
checks.push(createCoreBinaryCheck(bin));
|
|
198
|
+
}
|
|
199
|
+
checks.push(createDockerCheck());
|
|
200
|
+
checks.push(createSerenaCheck());
|
|
201
|
+
// KJC-TSK v2.18 — surface audit-side tools in doctor so the user knows
|
|
202
|
+
// which dimensions will work. lighthouse is gated to frontend stacks.
|
|
203
|
+
checks.push(createAuditToolCheck("semgrep", { label: "Semgrep (audit/security)" }));
|
|
204
|
+
checks.push(createAuditToolCheck("osv-scanner", { label: "OSV-Scanner (audit/security)" }));
|
|
205
|
+
checks.push(createAuditToolCheck("lighthouse", { label: "Lighthouse (webperf)", gatedByStack: true }));
|
|
206
|
+
return checks;
|
|
207
|
+
}
|
package/src/checks/ci.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CI infrastructure checks: required workflows, gh CLI, and GitHub secrets.
|
|
3
|
+
* Only applies when `config.ci.enabled === true`.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { exists } from "../utils/fs.js";
|
|
8
|
+
import { runCommand } from "../utils/process.js";
|
|
9
|
+
import { checkBinary } from "../utils/agent-detect.js";
|
|
10
|
+
import { STRATEGY } from "./types.js";
|
|
11
|
+
|
|
12
|
+
const REQUIRED_WORKFLOWS = ["kj-ci-gateway.yml", "automerge.yml", "houston-override.yml"];
|
|
13
|
+
|
|
14
|
+
function ciEnabled(config) {
|
|
15
|
+
return config.ci?.enabled === true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function createWorkflowCheck(workflow) {
|
|
19
|
+
return {
|
|
20
|
+
name: `ci:workflow:${workflow}`,
|
|
21
|
+
label: `CI workflow: ${workflow}`,
|
|
22
|
+
strategy: STRATEGY.MANUAL,
|
|
23
|
+
applies: ciEnabled,
|
|
24
|
+
async detect({ config }) {
|
|
25
|
+
const projectDir = config.projectDir || process.cwd();
|
|
26
|
+
const wfPath = path.join(projectDir, ".github", "workflows", workflow);
|
|
27
|
+
const wfExists = await exists(wfPath);
|
|
28
|
+
return {
|
|
29
|
+
ok: wfExists,
|
|
30
|
+
severity: "fail",
|
|
31
|
+
detail: wfExists ? "Found" : "Not found",
|
|
32
|
+
fix: wfExists
|
|
33
|
+
? undefined
|
|
34
|
+
: `Run 'kj init --scaffold-ci' or copy from karajan-code/templates/workflows/${workflow}`,
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function createGhCliCheck() {
|
|
41
|
+
return {
|
|
42
|
+
name: "ci:gh",
|
|
43
|
+
label: "CI: gh CLI",
|
|
44
|
+
strategy: STRATEGY.MANUAL,
|
|
45
|
+
applies: ciEnabled,
|
|
46
|
+
async detect() {
|
|
47
|
+
const gh = await checkBinary("gh");
|
|
48
|
+
return {
|
|
49
|
+
ok: gh.ok,
|
|
50
|
+
severity: "fail",
|
|
51
|
+
detail: gh.ok ? gh.version : "Not found",
|
|
52
|
+
fix: gh.ok ? undefined : "Install GitHub CLI: https://cli.github.com/",
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function createGhSecretsCheck() {
|
|
59
|
+
return {
|
|
60
|
+
name: "ci:secrets",
|
|
61
|
+
label: "CI: GitHub secrets",
|
|
62
|
+
strategy: STRATEGY.MANUAL,
|
|
63
|
+
applies: ciEnabled,
|
|
64
|
+
async detect() {
|
|
65
|
+
try {
|
|
66
|
+
const { detectRepo } = await import("../ci/repo.js");
|
|
67
|
+
const repo = await detectRepo();
|
|
68
|
+
if (!repo) {
|
|
69
|
+
return { ok: true, severity: "info", detail: "No GitHub repo detected (skipped)" };
|
|
70
|
+
}
|
|
71
|
+
const res = await runCommand("gh", ["api", `repos/${repo}/actions/secrets`, "--jq", ".secrets[].name"]);
|
|
72
|
+
if (res.exitCode !== 0) {
|
|
73
|
+
return { ok: true, severity: "info", detail: "Cannot query secrets (gh unauthenticated?)" };
|
|
74
|
+
}
|
|
75
|
+
const names = new Set(res.stdout.split("\n").map((s) => s.trim()));
|
|
76
|
+
const hasAppId = names.has("KJ_CI_APP_ID");
|
|
77
|
+
const hasKey = names.has("KJ_CI_PRIVATE_KEY");
|
|
78
|
+
const secretsOk = hasAppId && hasKey;
|
|
79
|
+
const missing = [!hasAppId && "KJ_CI_APP_ID", !hasKey && "KJ_CI_PRIVATE_KEY"].filter(Boolean).join(" ");
|
|
80
|
+
return {
|
|
81
|
+
ok: secretsOk,
|
|
82
|
+
severity: "fail",
|
|
83
|
+
detail: secretsOk ? "KJ_CI_APP_ID + KJ_CI_PRIVATE_KEY found" : `Missing: ${missing}`,
|
|
84
|
+
fix: secretsOk ? undefined : "Add KJ_CI_APP_ID and KJ_CI_PRIVATE_KEY as GitHub repository secrets",
|
|
85
|
+
};
|
|
86
|
+
} catch {
|
|
87
|
+
return { ok: true, severity: "info", detail: "Cannot check secrets (unexpected error, skipped)" };
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Aggregate of CI checks. Each check carries its own `applies` so the runner
|
|
95
|
+
* marks them SKIPPED when CI is disabled.
|
|
96
|
+
*/
|
|
97
|
+
export function getCiChecks() {
|
|
98
|
+
const checks = [];
|
|
99
|
+
for (const wf of REQUIRED_WORKFLOWS) {
|
|
100
|
+
checks.push(createWorkflowCheck(wf));
|
|
101
|
+
}
|
|
102
|
+
checks.push(createGhCliCheck());
|
|
103
|
+
checks.push(createGhSecretsCheck());
|
|
104
|
+
return checks;
|
|
105
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config and rule-file checks.
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - kj.config.yml existence (strategy: prompt — offer to run kj init)
|
|
6
|
+
* - Review / coder rules discovery (strategy: none, informational)
|
|
7
|
+
* - Agent config files: ~/.claude.json, ~/.codex/config.toml,
|
|
8
|
+
* ~/.karajan/kj.config.yml (strategy: manual — structural fixes needed)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import fs from "node:fs/promises";
|
|
12
|
+
import os from "node:os";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import { exists } from "../utils/fs.js";
|
|
15
|
+
import { getConfigPath } from "../config.js";
|
|
16
|
+
import { resolveRoleMdPath, loadFirstExisting } from "../roles/base-role.js";
|
|
17
|
+
import { withDocLink } from "../utils/doc-links.js";
|
|
18
|
+
import { STRATEGY } from "./types.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* kj.config.yml presence check.
|
|
22
|
+
*/
|
|
23
|
+
function createConfigFileCheck() {
|
|
24
|
+
return {
|
|
25
|
+
name: "config",
|
|
26
|
+
label: "Config file",
|
|
27
|
+
strategy: STRATEGY.PROMPT,
|
|
28
|
+
describe: "Run 'kj init' to scaffold a default kj.config.yml",
|
|
29
|
+
async detect() {
|
|
30
|
+
const configPath = getConfigPath();
|
|
31
|
+
const configExists = await exists(configPath);
|
|
32
|
+
return {
|
|
33
|
+
ok: configExists,
|
|
34
|
+
severity: "fail",
|
|
35
|
+
detail: configExists ? configPath : "Not found",
|
|
36
|
+
fix: configExists ? undefined : withDocLink("Run 'kj init' to create the config file.", "config_missing"),
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Review rules (.md) informational check.
|
|
44
|
+
*/
|
|
45
|
+
function createReviewRulesCheck() {
|
|
46
|
+
return {
|
|
47
|
+
name: "review-rules",
|
|
48
|
+
label: "Reviewer rules (.md)",
|
|
49
|
+
strategy: STRATEGY.NONE,
|
|
50
|
+
async detect({ config }) {
|
|
51
|
+
const projectDir = config.projectDir || process.cwd();
|
|
52
|
+
const paths = resolveRoleMdPath("reviewer", projectDir);
|
|
53
|
+
const rules = await loadFirstExisting(paths);
|
|
54
|
+
return {
|
|
55
|
+
ok: true,
|
|
56
|
+
severity: "info",
|
|
57
|
+
detail: rules ? "Found" : "Not found (will use defaults)",
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Coder rules (.md) informational check.
|
|
65
|
+
*/
|
|
66
|
+
function createCoderRulesCheck() {
|
|
67
|
+
return {
|
|
68
|
+
name: "coder-rules",
|
|
69
|
+
label: "Coder rules (.md)",
|
|
70
|
+
strategy: STRATEGY.NONE,
|
|
71
|
+
async detect({ config }) {
|
|
72
|
+
const projectDir = config.projectDir || process.cwd();
|
|
73
|
+
const paths = resolveRoleMdPath("coder", projectDir);
|
|
74
|
+
const rules = await loadFirstExisting(paths);
|
|
75
|
+
return {
|
|
76
|
+
ok: true,
|
|
77
|
+
severity: "info",
|
|
78
|
+
detail: rules ? "Found" : "Not found (will use defaults)",
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Detect duplicate TOML table headers (e.g. [mcp_servers."karajan-mcp"] twice).
|
|
86
|
+
*/
|
|
87
|
+
function findDuplicateTomlKeys(content) {
|
|
88
|
+
const tableHeaders = [];
|
|
89
|
+
const duplicates = [];
|
|
90
|
+
for (const line of content.split("\n")) {
|
|
91
|
+
const match = line.match(/^\s*\[([^\]]+)\]\s*$/);
|
|
92
|
+
if (match) {
|
|
93
|
+
const key = match[1].trim();
|
|
94
|
+
if (tableHeaders.includes(key)) {
|
|
95
|
+
duplicates.push(key);
|
|
96
|
+
} else {
|
|
97
|
+
tableHeaders.push(key);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return duplicates;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Claude config (~/.claude.json) validity.
|
|
106
|
+
*/
|
|
107
|
+
function createClaudeConfigCheck() {
|
|
108
|
+
return {
|
|
109
|
+
name: "agent-config:claude",
|
|
110
|
+
label: "Agent config: claude (~/.claude.json)",
|
|
111
|
+
strategy: STRATEGY.MANUAL,
|
|
112
|
+
async detect() {
|
|
113
|
+
const home = os.homedir();
|
|
114
|
+
const claudeJsonPath = path.join(home, ".claude.json");
|
|
115
|
+
try {
|
|
116
|
+
const raw = await fs.readFile(claudeJsonPath, "utf8");
|
|
117
|
+
JSON.parse(raw);
|
|
118
|
+
return { ok: true, severity: "info", detail: "Valid JSON" };
|
|
119
|
+
} catch (err) {
|
|
120
|
+
if (err.code === "ENOENT") {
|
|
121
|
+
// Not configured: Claude may not be in use. Informational skip.
|
|
122
|
+
return { ok: true, severity: "info", detail: "Not present (skipped)" };
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
ok: false,
|
|
126
|
+
severity: "warn",
|
|
127
|
+
detail: `Invalid JSON: ${err.message.split("\n")[0]}`,
|
|
128
|
+
fix: "Fix the JSON syntax in ~/.claude.json. Common issues: trailing commas, missing quotes.",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Codex config (~/.codex/config.toml) validity.
|
|
137
|
+
*/
|
|
138
|
+
function createCodexConfigCheck() {
|
|
139
|
+
return {
|
|
140
|
+
name: "agent-config:codex",
|
|
141
|
+
label: "Agent config: codex (~/.codex/config.toml)",
|
|
142
|
+
strategy: STRATEGY.MANUAL,
|
|
143
|
+
async detect() {
|
|
144
|
+
const home = os.homedir();
|
|
145
|
+
const codexTomlPath = path.join(home, ".codex", "config.toml");
|
|
146
|
+
try {
|
|
147
|
+
const raw = await fs.readFile(codexTomlPath, "utf8");
|
|
148
|
+
const duplicates = findDuplicateTomlKeys(raw);
|
|
149
|
+
if (duplicates.length > 0) {
|
|
150
|
+
return {
|
|
151
|
+
ok: false,
|
|
152
|
+
severity: "warn",
|
|
153
|
+
detail: `Duplicate TOML keys: ${duplicates.join(", ")}`,
|
|
154
|
+
fix: `Remove duplicate entries in ~/.codex/config.toml: ${duplicates.join(", ")}`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return { ok: true, severity: "info", detail: "Valid TOML (no duplicate keys)" };
|
|
158
|
+
} catch (err) {
|
|
159
|
+
if (err.code === "ENOENT") {
|
|
160
|
+
return { ok: true, severity: "info", detail: "Not present (skipped)" };
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
ok: false,
|
|
164
|
+
severity: "warn",
|
|
165
|
+
detail: `Cannot read: ${err.message.split("\n")[0]}`,
|
|
166
|
+
fix: "Check file permissions on ~/.codex/config.toml",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* KJ config (~/.karajan/kj.config.yml) YAML validity (separate from existence).
|
|
175
|
+
*/
|
|
176
|
+
function createKjConfigYamlCheck() {
|
|
177
|
+
return {
|
|
178
|
+
name: "agent-config:karajan",
|
|
179
|
+
label: "Agent config: karajan (kj.config.yml)",
|
|
180
|
+
strategy: STRATEGY.MANUAL,
|
|
181
|
+
async detect() {
|
|
182
|
+
const kjConfigPath = getConfigPath();
|
|
183
|
+
try {
|
|
184
|
+
const raw = await fs.readFile(kjConfigPath, "utf8");
|
|
185
|
+
const yaml = await import("js-yaml");
|
|
186
|
+
yaml.default.load(raw);
|
|
187
|
+
return { ok: true, severity: "info", detail: "Valid YAML" };
|
|
188
|
+
} catch (err) {
|
|
189
|
+
if (err.code === "ENOENT") {
|
|
190
|
+
// Covered by createConfigFileCheck — don't duplicate the failure
|
|
191
|
+
return { ok: true, severity: "info", detail: "Not present (covered by config check)" };
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
ok: false,
|
|
195
|
+
severity: "fail",
|
|
196
|
+
detail: `Invalid YAML: ${err.message.split("\n")[0]}`,
|
|
197
|
+
fix: `Fix YAML syntax in ${kjConfigPath}. Run 'kj init' to regenerate if needed.`,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Aggregate: all config-file-related checks.
|
|
206
|
+
* @returns {import("./types.js").Check[]}
|
|
207
|
+
*/
|
|
208
|
+
export function getConfigFileChecks() {
|
|
209
|
+
return [
|
|
210
|
+
createConfigFileCheck(),
|
|
211
|
+
createReviewRulesCheck(),
|
|
212
|
+
createCoderRulesCheck(),
|
|
213
|
+
createClaudeConfigCheck(),
|
|
214
|
+
createCodexConfigCheck(),
|
|
215
|
+
createKjConfigYamlCheck(),
|
|
216
|
+
];
|
|
217
|
+
}
|