@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,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Board access verification (KJC-TSK-0685). User rule: Karajan does not
|
|
3
|
+
* run without a board — it is what guarantees ordered, card-first work and
|
|
4
|
+
* meaningful lanes. There is NO "none". init/env-install verify an
|
|
5
|
+
* OPERATIONAL access path to the declared backend:
|
|
6
|
+
* - hu-board → always ok (ships inside the kj tarball).
|
|
7
|
+
* - planning-game → its MCP appears in a host agent config.
|
|
8
|
+
* - external → the named board's MCP appears in a host agent
|
|
9
|
+
* config, OR an API token is exported (conventional
|
|
10
|
+
* env var, or the one declared in board.token_env).
|
|
11
|
+
* Detection is presence-based and format-agnostic (the MCP config files
|
|
12
|
+
* are scanned as text) — v1 verifies a path exists, not connectivity.
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
15
|
+
import os from "node:os";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
|
|
18
|
+
const TOKEN_CONVENTIONS = {
|
|
19
|
+
linear: ["LINEAR_API_KEY"],
|
|
20
|
+
trello: ["TRELLO_TOKEN", "TRELLO_API_KEY"],
|
|
21
|
+
jira: ["JIRA_API_TOKEN"],
|
|
22
|
+
github: ["GITHUB_TOKEN", "GH_TOKEN"],
|
|
23
|
+
asana: ["ASANA_ACCESS_TOKEN"],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function mcpConfigPaths(projectDir, home) {
|
|
27
|
+
return [
|
|
28
|
+
path.join(projectDir, ".mcp.json"),
|
|
29
|
+
path.join(home, ".claude.json"),
|
|
30
|
+
path.join(home, ".codex", "config.toml"),
|
|
31
|
+
path.join(home, ".gemini", "settings.json"),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function mcpConfigsMention(slug, projectDir, home) {
|
|
36
|
+
const needle = slug.toLowerCase();
|
|
37
|
+
for (const p of mcpConfigPaths(projectDir, home)) {
|
|
38
|
+
try {
|
|
39
|
+
if (existsSync(p) && readFileSync(p, "utf8").toLowerCase().includes(needle)) return p;
|
|
40
|
+
} catch { /* unreadable config — keep looking */ }
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Boards reachable from this machine (KJC-TSK-0709): the bundled HU Board
|
|
47
|
+
* always; planning-game / external candidates when their MCP appears in a
|
|
48
|
+
* host config or a conventional token is exported. Presence-based, like
|
|
49
|
+
* verifyBoardAccess — an OPTION list, not a connectivity check.
|
|
50
|
+
*/
|
|
51
|
+
export function detectAvailableBoards({ projectDir = process.cwd(), env = process.env, home = os.homedir() } = {}) {
|
|
52
|
+
const boards = [{ value: "hu-board", label: "HU Board (bundled, zero setup)" }];
|
|
53
|
+
if (mcpConfigsMention("planning-game", projectDir, home)) {
|
|
54
|
+
boards.push({ value: "planning-game", label: "Planning Game (MCP detected)" });
|
|
55
|
+
}
|
|
56
|
+
for (const [slug, envs] of Object.entries(TOKEN_CONVENTIONS)) {
|
|
57
|
+
const token = envs.find((k) => env[k]);
|
|
58
|
+
if (token) boards.push({ value: `external:${slug}`, label: `${slug} (token ${token})` });
|
|
59
|
+
else if (mcpConfigsMention(slug, projectDir, home)) boards.push({ value: `external:${slug}`, label: `${slug} (MCP detected)` });
|
|
60
|
+
}
|
|
61
|
+
return boards;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function verifyBoardAccess({ config = {}, projectDir = process.cwd(), env = process.env, home = os.homedir() } = {}) {
|
|
65
|
+
const backend = config.state_backend || "hu-board";
|
|
66
|
+
|
|
67
|
+
if (backend === "planning-game") {
|
|
68
|
+
const hit = mcpConfigsMention("planning-game", projectDir, home);
|
|
69
|
+
if (hit) return { ok: true, backend, via: `planning-game MCP (${hit})` };
|
|
70
|
+
return {
|
|
71
|
+
ok: false, backend,
|
|
72
|
+
needed: ["configure the planning-game MCP in your host agent (project .mcp.json or the agent's global config)"],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (backend === "external") {
|
|
77
|
+
const name = String(config.board?.name || "").trim();
|
|
78
|
+
if (!name) return { ok: false, backend, needed: ["declare board.name in kj.config.yml (e.g. Linear, Trello, Jira, GitHub Issues)"] };
|
|
79
|
+
const slug = name.toLowerCase().split(/\s+/)[0];
|
|
80
|
+
const hit = mcpConfigsMention(slug, projectDir, home);
|
|
81
|
+
if (hit) return { ok: true, backend, via: `${name} MCP detected (${hit})` };
|
|
82
|
+
const tokenEnvs = config.board?.token_env ? [config.board.token_env] : (TOKEN_CONVENTIONS[slug] || []);
|
|
83
|
+
const found = tokenEnvs.find((k) => env[k]);
|
|
84
|
+
if (found) return { ok: true, backend, via: `API token ${found}` };
|
|
85
|
+
return {
|
|
86
|
+
ok: false, backend, name,
|
|
87
|
+
needed: [
|
|
88
|
+
`configure the ${name} MCP in your host agent (project .mcp.json or the agent's global config), or`,
|
|
89
|
+
tokenEnvs.length > 0
|
|
90
|
+
? `export an API token: ${tokenEnvs.join(" or ")}`
|
|
91
|
+
: "declare board.token_env in kj.config.yml and export that variable",
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return { ok: true, backend: "hu-board", via: "bundled HU Board" };
|
|
97
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* board-select (KJC-TSK-0709) — never hu-board silently when alternatives
|
|
3
|
+
* are reachable. Field case 2026-08-02: an install defaulted to hu-board
|
|
4
|
+
* with the user's Planning Game MCP sitting configured and detectable.
|
|
5
|
+
* Interactive installs ASK and persist the choice; headless installs name
|
|
6
|
+
* the default and the exact line to change it. Declared = never asked.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from "node:fs/promises";
|
|
10
|
+
import os from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { parse as parseYaml, parseDocument } from "yaml";
|
|
13
|
+
import { detectAvailableBoards } from "./board-access.js";
|
|
14
|
+
import { getConfigPath, getProjectConfigPath } from "../config.js";
|
|
15
|
+
|
|
16
|
+
// "Declared" means the USER wrote state_backend in a config FILE — the
|
|
17
|
+
// merged config object always carries the hu-board default (defaults.js),
|
|
18
|
+
// so it can never tell a choice from a fallback.
|
|
19
|
+
async function declaredStateBackend(projectDir) {
|
|
20
|
+
for (const p of [getProjectConfigPath(projectDir), getConfigPath()]) {
|
|
21
|
+
try {
|
|
22
|
+
const raw = parseYaml(await fs.readFile(p, "utf8")) || {};
|
|
23
|
+
if (raw.state_backend) return { backend: raw.state_backend, boardName: raw.board?.name || null };
|
|
24
|
+
} catch { /* missing or unreadable — keep looking */ }
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function persistStateBackend(projectDir, backend, boardName) {
|
|
30
|
+
const configPath = getProjectConfigPath(projectDir);
|
|
31
|
+
let source = "";
|
|
32
|
+
try { source = await fs.readFile(configPath, "utf8"); } catch { /* no config yet — create it */ }
|
|
33
|
+
const doc = parseDocument(source || "{}");
|
|
34
|
+
doc.setIn(["state_backend"], backend);
|
|
35
|
+
if (boardName) doc.setIn(["board", "name"], boardName);
|
|
36
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
37
|
+
await fs.writeFile(configPath, doc.toString(), "utf8");
|
|
38
|
+
return configPath;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function pickStateBackend({ projectDir = process.cwd(), home = os.homedir(), env = process.env, wizard = null, isTTY = false, logger = console } = {}) {
|
|
42
|
+
const declared = await declaredStateBackend(projectDir);
|
|
43
|
+
if (declared) return { ...declared, source: "declared" };
|
|
44
|
+
const boards = detectAvailableBoards({ projectDir, home, env });
|
|
45
|
+
if (boards.length <= 1) return { backend: "hu-board", boardName: null, source: "default" };
|
|
46
|
+
if (!wizard || !isTTY) {
|
|
47
|
+
logger.info?.(`⚠ board: defaulting to the bundled HU Board, but this machine can reach: ${boards.slice(1).map((b) => b.label).join(", ")} — switch with \`state_backend: planning-game\` (or \`external\` + board.name) in .karajan/kj.config.yml and re-run kj env install`);
|
|
48
|
+
return { backend: "hu-board", boardName: null, source: "default-informed" };
|
|
49
|
+
}
|
|
50
|
+
logger.info?.("Karajan needs a board (there is no 'none') — pick where card-first work lives:");
|
|
51
|
+
const value = await wizard.select("Which board governs this project?", boards);
|
|
52
|
+
const external = value.startsWith("external:");
|
|
53
|
+
const backend = external ? "external" : value;
|
|
54
|
+
const boardName = external ? value.slice("external:".length) : null;
|
|
55
|
+
await persistStateBackend(projectDir, backend, boardName);
|
|
56
|
+
const suffix = boardName ? ` (${boardName})` : "";
|
|
57
|
+
logger.info?.(`✓ board: ${backend}${suffix} — persisted in .karajan/kj.config.yml`);
|
|
58
|
+
return { backend, boardName, source: "chosen" };
|
|
59
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role briefs (AB-C, KJC-TSK-0652; outcome-first rewrite AB-C2,
|
|
3
|
+
* KJC-TSK-0653) — the method of each role, exposed to the brain via
|
|
4
|
+
* `kj brief <role>`.
|
|
5
|
+
*
|
|
6
|
+
* Format is Mission + Invariants + Deliverable, never step scripts:
|
|
7
|
+
* frontier models choose better paths than a script would force, but they
|
|
8
|
+
* need the hard limits explicit. The real guarantee lives in the git
|
|
9
|
+
* gates, not in this text. Subprocess prompts stay in headless.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const brief = (title, mission, invariants, deliverable) => [
|
|
13
|
+
`# ${title} brief`, "",
|
|
14
|
+
`Mission: ${mission}`, "",
|
|
15
|
+
"Invariants:",
|
|
16
|
+
...invariants.map((i) => `- ${i}`), "",
|
|
17
|
+
`Deliverable: ${deliverable}`,
|
|
18
|
+
].join("\n");
|
|
19
|
+
|
|
20
|
+
const B = {
|
|
21
|
+
triage: {
|
|
22
|
+
purpose: "Size the task before touching anything",
|
|
23
|
+
render: () => brief("Triage",
|
|
24
|
+
"before any code exists, the task has a type (sw|infra|doc|add-tests|refactor), an honest size, its risk surfaces named (auth, persistence, external I/O, money, PII), and a DONE-statement that is falsifiable.",
|
|
25
|
+
[
|
|
26
|
+
"The RAG answers before you assume (`kj rag query`) — never size from guesses.",
|
|
27
|
+
"A task too big for one ~150-net-line PR is split into HUs BEFORE coding starts.",
|
|
28
|
+
],
|
|
29
|
+
"type, size, risks, done-statement — or the HU split."),
|
|
30
|
+
},
|
|
31
|
+
planner: {
|
|
32
|
+
purpose: "Turn the task into an ordered, committable plan",
|
|
33
|
+
render: () => brief("Planner",
|
|
34
|
+
"the smallest ordered plan whose steps each fit one commit, name their files, and reach the done-statement — with an explicit out-of-scope list.",
|
|
35
|
+
[
|
|
36
|
+
"Behavior changes carry their test in the same step.",
|
|
37
|
+
"Data-model or API changes never share a step with anything else.",
|
|
38
|
+
"No PR beyond ~150 net lines — partition upfront, not at the gate.",
|
|
39
|
+
"Non-trivial task? Name at least two approaches — one as if the codebase didn't exist — and say why the winner won.",
|
|
40
|
+
],
|
|
41
|
+
"numbered-free plan: steps {description, files}, risks, out-of-scope."),
|
|
42
|
+
},
|
|
43
|
+
researcher: {
|
|
44
|
+
purpose: "Ground the task in how the codebase actually works",
|
|
45
|
+
render: () => brief("Researcher",
|
|
46
|
+
"the design starts from how this codebase actually does things: the existing pattern for this kind of change is found and mimicked, the load-bearing files and the tests that pin them are known.",
|
|
47
|
+
[
|
|
48
|
+
"Facts carry file:line references — a claim without one is a guess.",
|
|
49
|
+
"Unknowns are listed explicitly, never papered over.",
|
|
50
|
+
],
|
|
51
|
+
"grounded facts with references + the open unknowns."),
|
|
52
|
+
},
|
|
53
|
+
architect: {
|
|
54
|
+
purpose: "Decide structure before code when the change is cross-cutting",
|
|
55
|
+
render: () => brief("Architect",
|
|
56
|
+
"for medium/complex changes, one design is chosen over named alternatives, existing ADRs and module boundaries are respected, and any data-model/API change has a migration and compatibility story.",
|
|
57
|
+
[
|
|
58
|
+
"Check the ADRs before deciding — never against an accepted one.",
|
|
59
|
+
"Prefer the design that deletes code over the one that adds layers.",
|
|
60
|
+
"One alternative answers: what would you build as if the codebase didn't exist? Picking the legacy-shaped path is fine — picking it by inertia is not.",
|
|
61
|
+
"Ground that alternative in the canon: `kj rag query --library \"<problem signature>\"` serves distilled pattern cards with when-NOT-to-apply and citations.",
|
|
62
|
+
],
|
|
63
|
+
"chosen design, discarded alternatives with reasons, affected boundaries."),
|
|
64
|
+
},
|
|
65
|
+
tester: {
|
|
66
|
+
purpose: "Prove the change does what DONE says",
|
|
67
|
+
render: (config) => {
|
|
68
|
+
const tdd = config?.development?.methodology !== "standard";
|
|
69
|
+
return brief("Tester",
|
|
70
|
+
"every behavior change is pinned by a test that fails without it, sad paths included (invalid input, empty state, boundaries), and the FULL suite is green.",
|
|
71
|
+
[
|
|
72
|
+
...(tdd ? ["TDD is ON: the failing test exists FIRST, then the code."] : []),
|
|
73
|
+
"The suite is never left red, and never goes green by deleting or skipping tests.",
|
|
74
|
+
...(config?.method_gates?.mutation
|
|
75
|
+
? ["Green is not proof: run `kj mutate --since <base>` after the suite passes and BEFORE review — kill surviving mutants (weak asserts) first."]
|
|
76
|
+
: []),
|
|
77
|
+
],
|
|
78
|
+
"green suite + the list of new/changed tests and what each one pins.");
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
security: {
|
|
82
|
+
purpose: "The security pass the brain absorbs — non-negotiable",
|
|
83
|
+
render: () => brief("Security",
|
|
84
|
+
"when you finish, no user-controlled data reaches HTML, shell, SQL or file paths unsanitized; no secret, key or credential lives in code, config, logs or commits; and every new endpoint/action checks identity AND permission.",
|
|
85
|
+
[
|
|
86
|
+
"These findings are never overridable — not even by Solomon arbitration.",
|
|
87
|
+
"PII is never logged; new dependencies need a reason and a pinned version.",
|
|
88
|
+
"Sensitive surface (auth, user input, secrets, network, deps)? Self-invoke `kj audit --security` — deterministic, zero tokens: prompt-injection over the agent-context files + OSV + Semgrep + Sonar — and remediate the findings before requesting review.",
|
|
89
|
+
],
|
|
90
|
+
"findings with severity, category and file:line — or an explicit 'no security surface touched'."),
|
|
91
|
+
},
|
|
92
|
+
board: {
|
|
93
|
+
purpose: "What the HU Board is and how to act on it without breaking it",
|
|
94
|
+
render: () => brief("Board",
|
|
95
|
+
"the HU Board is the permanent record of work: every card traces to who created it and what happened to it — a dashboard warning is fixed with the command it names, never by rebuilding the board.",
|
|
96
|
+
[
|
|
97
|
+
"Before `kj hu add`, ALWAYS run `kj hu list`: if a card already covers the work (same scope, any plan), work THAT card instead of creating a twin.",
|
|
98
|
+
"Cards are NEVER deleted or recreated — not to fix warnings, not to tidy up. Discard = `kj hu move <id> skipped` (archived, history kept).",
|
|
99
|
+
"States move only via `kj hu move <id> <pending|running|done|failed|skipped>`.",
|
|
100
|
+
"A duplicate short_id or title means the card already exists: update that card, never add a twin.",
|
|
101
|
+
"A warning is information, not damage: run the command it names; if it looks like a kj bug, `kj report-issue` — never work around it by destroying state.",
|
|
102
|
+
],
|
|
103
|
+
"the board reflects reality: the same cards before and after your action, with truthful states and provenance intact."),
|
|
104
|
+
},
|
|
105
|
+
audit: {
|
|
106
|
+
purpose: "Final look before shipping — does the whole thing hold?",
|
|
107
|
+
render: () => brief("Audit",
|
|
108
|
+
"the done-statement from triage is literally true, the diff carries no debug leftovers or card-less TODOs, user-visible behavior changes have their minimal doc, and suite + lint + review gate are verified green.",
|
|
109
|
+
[
|
|
110
|
+
"Verified means you ran it — never assumed from an earlier state.",
|
|
111
|
+
"There is no 'ship with caveats': it ships or it has a must-fix list.",
|
|
112
|
+
],
|
|
113
|
+
"SHIP, or the concrete must-fix list."),
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const BRIEF_ROLES = Object.keys(B);
|
|
118
|
+
|
|
119
|
+
export function listBriefs() {
|
|
120
|
+
return BRIEF_ROLES.map((role) => ({ role, purpose: B[role].purpose }));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function renderBrief(role, config = {}) {
|
|
124
|
+
const entry = B[role];
|
|
125
|
+
if (!entry) {
|
|
126
|
+
throw new Error(`unknown role "${role}" — available: ${BRIEF_ROLES.join(", ")}`);
|
|
127
|
+
}
|
|
128
|
+
return entry.render(config);
|
|
129
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue reporting core (AB-F, KJC-TSK-0655) — the self-healing loop: any
|
|
3
|
+
* user's brain diagnoses a kj friction and reports it to the public repo,
|
|
4
|
+
* so field feedback reaches the maintainer's board without a human relay.
|
|
5
|
+
*
|
|
6
|
+
* A public issue is a privacy boundary. sanitize() strips home paths,
|
|
7
|
+
* usernames and emails; the composer only ever includes what the brain
|
|
8
|
+
* explicitly passed (command, error, description) plus kj/node/platform
|
|
9
|
+
* metadata — never project code.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const REPO = "manufosela/karajan-code";
|
|
13
|
+
|
|
14
|
+
export function sanitize(text) {
|
|
15
|
+
return String(text || "")
|
|
16
|
+
// any /home/<user>/ or /Users/<user>/ prefix collapses to ~/
|
|
17
|
+
.replaceAll(/\/(?:home|Users)\/[^/\s]+/g, "~")
|
|
18
|
+
// emails never belong in a public issue
|
|
19
|
+
.replaceAll(/[\w.+-]+@[\w-]+\.[\w.]+/g, "[redacted-email]");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function composeIssue({ title, description = "", command = "", error = "", env = {} }) {
|
|
23
|
+
const body = [
|
|
24
|
+
sanitize(description),
|
|
25
|
+
command ? `\n**Command:** \`${sanitize(command)}\`` : "",
|
|
26
|
+
error ? `\n**Error:**\n\`\`\`\n${sanitize(error)}\n\`\`\`` : "",
|
|
27
|
+
"\n**Environment:**",
|
|
28
|
+
`- kj ${env.kjVersion || "unknown"}`,
|
|
29
|
+
`- node ${env.nodeVersion || "unknown"}`,
|
|
30
|
+
`- ${env.platform || "unknown"}`,
|
|
31
|
+
"\n---",
|
|
32
|
+
"_Reported via `kj report-issue` (sanitized: no project code, paths or personal data)._",
|
|
33
|
+
].filter(Boolean).join("\n");
|
|
34
|
+
return { title: sanitize(title), body };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const STOPWORDS = new Set(["the", "a", "an", "is", "are", "from", "with", "for", "and", "not", "kj", "karajan"]);
|
|
38
|
+
|
|
39
|
+
function meaningfulWords(title) {
|
|
40
|
+
return title.toLowerCase().split(/[^a-z0-9-]+/)
|
|
41
|
+
.filter((w) => w.length > 3 && !STOPWORDS.has(w));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Look for open issues that share meaningful title words (≥2 overlaps, or
|
|
46
|
+
* 1 when the title is short). Read-only public API — no auth needed. Any
|
|
47
|
+
* failure degrades to [] : dedup must never block reporting.
|
|
48
|
+
*/
|
|
49
|
+
export async function findSimilarIssues(title, { fetchFn = globalThis.fetch } = {}) {
|
|
50
|
+
try {
|
|
51
|
+
const res = await fetchFn(`https://api.github.com/repos/${REPO}/issues?state=open&per_page=100`, {
|
|
52
|
+
headers: { accept: "application/vnd.github+json" },
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok) return [];
|
|
55
|
+
const issues = await res.json();
|
|
56
|
+
const words = meaningfulWords(title);
|
|
57
|
+
const needed = Math.min(2, Math.max(1, words.length));
|
|
58
|
+
return issues.filter((issue) => {
|
|
59
|
+
const theirs = new Set(meaningfulWords(issue.title || ""));
|
|
60
|
+
const overlap = words.filter((w) => theirs.has(w)).length;
|
|
61
|
+
return overlap >= needed;
|
|
62
|
+
}).map(({ number, title: t, html_url }) => ({ number, title: t, html_url }));
|
|
63
|
+
} catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Prefilled new-issue URL — publishing stays a human click by default. */
|
|
69
|
+
export function newIssueUrl({ title, body }) {
|
|
70
|
+
const params = new URLSearchParams({ title, body });
|
|
71
|
+
return `https://github.com/${REPO}/issues/new?${params.toString().replaceAll("+", "%20")}`;
|
|
72
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp-wiring — RAG as a NATIVE tool (KJC-TSK-0711). Field case 2026-08-03:
|
|
3
|
+
* agents in karajan projects grep code by hand because the RAG is only "a
|
|
4
|
+
* Bash command a text line told them about". Agents use the tools in their
|
|
5
|
+
* toolbox, so env install wires kj's RAG-only MCP server (`kj-rag-mcp`,
|
|
6
|
+
* ships with the package) into the project's `.mcp.json` — the official
|
|
7
|
+
* path must be cheaper than the shortcut. Merge preserves the user's
|
|
8
|
+
* entries; invalid JSON is left untouched (preserve, never clobber).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
|
|
14
|
+
export function installProjectMcp({ projectDir = process.cwd(), logger = console } = {}) {
|
|
15
|
+
const mcpPath = join(projectDir, ".mcp.json");
|
|
16
|
+
let cfg = {};
|
|
17
|
+
if (existsSync(mcpPath)) {
|
|
18
|
+
try {
|
|
19
|
+
cfg = JSON.parse(readFileSync(mcpPath, "utf8"));
|
|
20
|
+
} catch {
|
|
21
|
+
logger.warn?.(`kj env: ${mcpPath} is not valid JSON — leaving it untouched (wire kj-rag-mcp manually for native RAG queries)`);
|
|
22
|
+
return { wired: false, reason: "invalid-json" };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (cfg.mcpServers && typeof cfg.mcpServers !== "object") {
|
|
26
|
+
logger.warn?.(`kj env: ${mcpPath} has a non-object mcpServers — leaving it untouched`);
|
|
27
|
+
return { wired: false, reason: "unexpected-shape" };
|
|
28
|
+
}
|
|
29
|
+
cfg.mcpServers = cfg.mcpServers || {};
|
|
30
|
+
// Wired = the LAUNCH SPEC runs kj-rag-mcp (command or an arg, so `npx
|
|
31
|
+
// kj-rag-mcp` and absolute paths count) — never env/description fields.
|
|
32
|
+
const launchesRagMcp = (s) =>
|
|
33
|
+
Boolean(s) && typeof s === "object" && (
|
|
34
|
+
(typeof s.command === "string" && s.command.includes("kj-rag-mcp")) ||
|
|
35
|
+
(Array.isArray(s.args) && s.args.some((a) => typeof a === "string" && a.includes("kj-rag-mcp")))
|
|
36
|
+
);
|
|
37
|
+
const present = Object.values(cfg.mcpServers).some(launchesRagMcp);
|
|
38
|
+
if (!present) {
|
|
39
|
+
cfg.mcpServers["kj-rag"] = { command: "kj-rag-mcp", args: [] };
|
|
40
|
+
writeFileSync(mcpPath, `${JSON.stringify(cfg, null, 2)}\n`);
|
|
41
|
+
logger.info?.("✓ kj_rag_query wired as a NATIVE tool (.mcp.json → kj-rag-mcp): querying the RAG is now the agent's cheapest path");
|
|
42
|
+
}
|
|
43
|
+
return { wired: true, added: !present };
|
|
44
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Karajan Environment playbook (ENV-A1, KJC-TSK-0639).
|
|
3
|
+
*
|
|
4
|
+
* ONE source renders the method for every host agent: a managed block in
|
|
5
|
+
* CLAUDE.md (Claude Code) and AGENTS.md (Codex). The body is data here —
|
|
6
|
+
* not a template file — so it never counts as a repo AI-rule file and can
|
|
7
|
+
* be parameterized later (rag/gate state, backend) without forking copies.
|
|
8
|
+
*
|
|
9
|
+
* The playbook is agent context: every line costs attention on every turn,
|
|
10
|
+
* so it stays under 60 lines by test. Method over prose.
|
|
11
|
+
*/
|
|
12
|
+
import fs from "node:fs/promises";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import { upsertManagedBlock } from "../utils/managed-markers.js";
|
|
15
|
+
|
|
16
|
+
// AB-A (KJC-TSK-0650): any agent can be the brain. AGENTS.md is the
|
|
17
|
+
// emerging standard (Codex, Cursor and most new CLIs read it); GEMINI.md
|
|
18
|
+
// covers Gemini CLI. "both" is kept as a legacy alias of claude+codex.
|
|
19
|
+
export const PLAYBOOK_TARGETS = ["claude", "codex", "gemini", "both", "all"];
|
|
20
|
+
|
|
21
|
+
const TARGET_FILES = {
|
|
22
|
+
claude: ["CLAUDE.md"],
|
|
23
|
+
codex: ["AGENTS.md"],
|
|
24
|
+
gemini: ["GEMINI.md"],
|
|
25
|
+
both: ["CLAUDE.md", "AGENTS.md"],
|
|
26
|
+
all: ["CLAUDE.md", "AGENTS.md", "GEMINI.md"],
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// ENV-D1 (KJC-TSK-0642): the tracking invariant names the CHOSEN state
|
|
30
|
+
// backend — a playbook that says "board or PG" makes the host guess.
|
|
31
|
+
// KJC-TSK-0684 (issue #1287): external boards (Linear, Trello, Jira…) are
|
|
32
|
+
// first-class — card-first points at THE project's board, worked through
|
|
33
|
+
// the host agent's own MCP/tools. kj never mirrors it: a half-empty
|
|
34
|
+
// parallel board is worse than none.
|
|
35
|
+
const BACKEND_TRACKING = {
|
|
36
|
+
"hu-board": "Every piece of work has a tracked story/bug in the HU Board (`kj hu add` / `kj board`) before it starts — and `kj hu list` BEFORE `kj hu add`: reuse the existing card if one covers the work. Cards are permanent — never delete or recreate one; discard with `kj hu move <id> skipped`. `kj brief board` explains the board.",
|
|
37
|
+
"planning-game": "Every piece of work has a tracked card in the Planning Game MCP before it starts (In Progress while you work it).",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const externalTracking = (boardName) =>
|
|
41
|
+
`Every piece of work has a tracked card in ${boardName} — the project's board — before it starts (use its MCP/tools; move the card as you work it). kj does not mirror it: never create a parallel HU Board.`;
|
|
42
|
+
|
|
43
|
+
function trackingLine(stateBackend, boardName) {
|
|
44
|
+
if (stateBackend === "external") return externalTracking(boardName || "the project's external board");
|
|
45
|
+
return BACKEND_TRACKING[stateBackend] || BACKEND_TRACKING["hu-board"];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// AB-C2 (KJC-TSK-0653): outcome-first — invariants over step scripts.
|
|
49
|
+
// Frontier models choose their own path best; what they need explicit are
|
|
50
|
+
// the limits. The git gates enforce these regardless of what any brain does.
|
|
51
|
+
const playbookBody = (stateBackend, boardName) => `# Karajan method (v4)
|
|
52
|
+
|
|
53
|
+
You are the orchestrator; Karajan governs. A task is DONE when its
|
|
54
|
+
done-statement is literally true, the full suite is green, and every commit
|
|
55
|
+
carries a cross-AI verdict.
|
|
56
|
+
|
|
57
|
+
Invariants (the git gates enforce these — they are not suggestions):
|
|
58
|
+
|
|
59
|
+
- The project RAG answers before you assume: \`kj rag query\` — never guess
|
|
60
|
+
what the codebase does. In MCP hosts the same index is the native
|
|
61
|
+
\`kj_rag_query\` tool: reach for it before grepping by hand.
|
|
62
|
+
- ${trackingLine(stateBackend, boardName)}
|
|
63
|
+
- Tests prove behavior: the failing test exists first (TDD), and the suite
|
|
64
|
+
is never left red. Green is not proof: with \`method_gates.mutation\`
|
|
65
|
+
declared, run \`kj mutate --since <base>\` after green and BEFORE the
|
|
66
|
+
review — a surviving mutant is a weak assert; kill it first.
|
|
67
|
+
- Every diff is reviewed by a DIFFERENT AI before it is committed
|
|
68
|
+
(\`kj review --staged\`): verdicts bind to the exact diff — change the code
|
|
69
|
+
and it must be reviewed again. Disagree with a rejection? \`kj solomon\`.
|
|
70
|
+
- Security findings are never overridable — not even by arbitration. You
|
|
71
|
+
absorb the security role: \`kj brief security\` states what must be true.
|
|
72
|
+
Task touches auth, user input, secrets, network or deps? Run
|
|
73
|
+
\`kj audit --security\` (zero tokens) and remediate BEFORE the review.
|
|
74
|
+
- A design decision the card's AC don't cover belongs to the USER: record
|
|
75
|
+
it as a proposed ADR (\`kj adr add\`) and ask — never bury it in a PR
|
|
76
|
+
bullet. An oversized-diff warning is not an opinion either: partition,
|
|
77
|
+
or get an explicit OK.
|
|
78
|
+
- A non-trivial plan names at least two approaches — one as if the
|
|
79
|
+
codebase didn't exist — and says why the winner won. Following the
|
|
80
|
+
legacy line is a choice, never a default.
|
|
81
|
+
- Publishing ANY artifact (a build's dist/, a docs site, a tarball)?
|
|
82
|
+
\`kj privacy scan <dir>\` first — nothing personal or secret-shaped ships.
|
|
83
|
+
- Branch first: never commit on the base branch — every change reaches it
|
|
84
|
+
through an atomic PR (~150 net lines, Conventional Commits). More than one
|
|
85
|
+
task, or the base tree must stay untouched? \`kj worktree start <slug>\`
|
|
86
|
+
(one lane per task; \`kj worktree done <slug>\` after merge). Never CLAIM
|
|
87
|
+
isolation without proof: in a lane, \`git rev-parse --git-dir\` differs
|
|
88
|
+
from \`--git-common-dir\`.
|
|
89
|
+
|
|
90
|
+
Commands: \`kj rag query\` · \`kj brief <role>\` (triage, planner, researcher,
|
|
91
|
+
architect, tester, security, audit, board) · \`kj hu add|move|list\` ·
|
|
92
|
+
\`kj worktree start|list|done\` · \`kj adr add|list\` ·
|
|
93
|
+
\`kj review --staged\` · \`kj review --check\` · \`kj solomon --position\` ·
|
|
94
|
+
\`kj agent run <agent>\` · \`kj report\` · \`kj check\`
|
|
95
|
+
|
|
96
|
+
Hit a kj bug or friction? Diagnose it and file it upstream with
|
|
97
|
+
\`kj report-issue\` (sanitized; ask your user before \`--publish\`).
|
|
98
|
+
kj announces a newer version? Tell your user what it brings and ask —
|
|
99
|
+
never run \`kj update\` on your own.
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
export function renderPlaybook({ stateBackend = "hu-board", boardName = null } = {}) {
|
|
103
|
+
return playbookBody(stateBackend, boardName);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Install/refresh the playbook block in the target agent files.
|
|
108
|
+
* User content outside the managed block is never touched.
|
|
109
|
+
*/
|
|
110
|
+
export async function installPlaybook({ projectDir, target = "all", version = "1", stateBackend = "hu-board", boardName = null }) {
|
|
111
|
+
if (!PLAYBOOK_TARGETS.includes(target)) {
|
|
112
|
+
throw new Error(`unknown target "${target}" — use one of: ${PLAYBOOK_TARGETS.join(", ")}`);
|
|
113
|
+
}
|
|
114
|
+
const files = [];
|
|
115
|
+
for (const file of TARGET_FILES[target]) {
|
|
116
|
+
const fullPath = path.join(projectDir, file);
|
|
117
|
+
let source = "";
|
|
118
|
+
try { source = await fs.readFile(fullPath, "utf8"); } catch { /* new file */ }
|
|
119
|
+
const { content, action } = upsertManagedBlock({
|
|
120
|
+
source, blockId: "playbook", version, body: renderPlaybook({ stateBackend, boardName }), style: "html",
|
|
121
|
+
note: "do not edit: regenerated by kj env install",
|
|
122
|
+
});
|
|
123
|
+
if (action !== "unchanged") await fs.writeFile(fullPath, content);
|
|
124
|
+
files.push(file);
|
|
125
|
+
}
|
|
126
|
+
return { files, target };
|
|
127
|
+
}
|