@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,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-aware role template resolver.
|
|
3
|
+
*
|
|
4
|
+
* Extends the legacy `resolveRoleMdPath()` contract from base-role.js to
|
|
5
|
+
* support per-provider variants without breaking existing consumers.
|
|
6
|
+
*
|
|
7
|
+
* Lookup order (first match wins):
|
|
8
|
+
*
|
|
9
|
+
* 1. <projectDir>/.karajan/roles/{role}/{provider}.md project override, per provider
|
|
10
|
+
* 2. <projectDir>/.karajan/roles/{role}/default.md project override, default
|
|
11
|
+
* 3. <projectDir>/.karajan/roles/{role}.md project override, legacy flat
|
|
12
|
+
* 4. <karajanHome>/roles/{role}/{provider}.md user home, per provider
|
|
13
|
+
* 5. <karajanHome>/roles/{role}/default.md user home, default
|
|
14
|
+
* 6. <karajanHome>/roles/{role}.md user home, legacy flat
|
|
15
|
+
* 7. <built-in>/templates/roles/{role}/{provider}.md built-in, per provider
|
|
16
|
+
* 8. <built-in>/templates/roles/{role}/default.md built-in, default
|
|
17
|
+
* 9. <built-in>/templates/roles/{role}.md built-in, legacy flat (back-compat)
|
|
18
|
+
*
|
|
19
|
+
* When `provider` is undefined/null the per-provider entries are skipped and
|
|
20
|
+
* only the default + legacy tiers are tried.
|
|
21
|
+
*
|
|
22
|
+
* If a provider is supplied but no per-provider file exists, we emit a
|
|
23
|
+
* one-time `prompt-resolver:fallback` event/log entry so the user knows their
|
|
24
|
+
* config asked for a variant that isn't present.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import fs from "node:fs/promises";
|
|
28
|
+
import path from "node:path";
|
|
29
|
+
import { getKarajanHome } from "../utils/paths.js";
|
|
30
|
+
import { getTemplatesRoot } from "../utils/templates-root.js";
|
|
31
|
+
import { normalizeProvider } from "../utils/provider-env.js";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Compute the full list of candidate file paths for a role template.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} role - role slug (e.g. "coder")
|
|
37
|
+
* @param {string|null|undefined} provider - provider slug or CLI name;
|
|
38
|
+
* normalized internally
|
|
39
|
+
* @param {string|null|undefined} projectDir
|
|
40
|
+
* @returns {{ perProvider: string[], default: string[], legacy: string[], all: string[], provider: string|null }}
|
|
41
|
+
*/
|
|
42
|
+
export function resolveRolePromptPaths(role, provider, projectDir) {
|
|
43
|
+
if (!role || typeof role !== "string") {
|
|
44
|
+
throw new Error("resolveRolePromptPaths: role name is required");
|
|
45
|
+
}
|
|
46
|
+
const normalized = provider ? normalizeProvider(provider) : null;
|
|
47
|
+
const canonical = normalized && normalized.length > 0 ? normalized : null;
|
|
48
|
+
|
|
49
|
+
const homes = [];
|
|
50
|
+
if (projectDir) homes.push(path.join(projectDir, ".karajan", "roles"));
|
|
51
|
+
homes.push(path.join(getKarajanHome(), "roles"));
|
|
52
|
+
|
|
53
|
+
homes.push(path.join(getTemplatesRoot(), "roles"));
|
|
54
|
+
|
|
55
|
+
const perProvider = [];
|
|
56
|
+
const defaults = [];
|
|
57
|
+
const legacy = [];
|
|
58
|
+
|
|
59
|
+
for (const home of homes) {
|
|
60
|
+
if (canonical) {
|
|
61
|
+
perProvider.push(path.join(home, role, `${canonical}.md`));
|
|
62
|
+
}
|
|
63
|
+
defaults.push(path.join(home, role, "default.md"));
|
|
64
|
+
legacy.push(path.join(home, `${role}.md`));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Interleave: for each home, try per-provider first, then default, then
|
|
68
|
+
// legacy. This gives the user's project override precedence over the
|
|
69
|
+
// built-in default even when they only supplied a legacy flat file.
|
|
70
|
+
const all = [];
|
|
71
|
+
for (const home of homes) {
|
|
72
|
+
if (canonical) all.push(path.join(home, role, `${canonical}.md`));
|
|
73
|
+
all.push(path.join(home, role, "default.md"));
|
|
74
|
+
all.push(path.join(home, `${role}.md`));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return { perProvider, default: defaults, legacy, all, provider: canonical };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Return the contents of the first existing candidate path. Returns null if
|
|
82
|
+
* no template is found.
|
|
83
|
+
*
|
|
84
|
+
* @param {string[]} paths
|
|
85
|
+
* @returns {Promise<{content: string, path: string}|null>}
|
|
86
|
+
*/
|
|
87
|
+
export async function readFirstExisting(paths) {
|
|
88
|
+
for (const p of paths) {
|
|
89
|
+
try {
|
|
90
|
+
const content = await fs.readFile(p, "utf8");
|
|
91
|
+
return { content, path: p };
|
|
92
|
+
} catch { /* file not found, keep trying */ }
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Load role instructions resolved for a specific provider.
|
|
99
|
+
*
|
|
100
|
+
* @param {Object} args
|
|
101
|
+
* @param {string} args.role
|
|
102
|
+
* @param {string|null|undefined} args.provider
|
|
103
|
+
* @param {string|null|undefined} args.projectDir
|
|
104
|
+
* @param {{ warn?: Function, debug?: Function }} [args.logger]
|
|
105
|
+
* @returns {Promise<{ instructions: string|null, path: string|null, resolvedProvider: string|null, fellBack: boolean }>}
|
|
106
|
+
*/
|
|
107
|
+
export async function loadRoleInstructions({ role, provider, projectDir, logger } = {}) {
|
|
108
|
+
const { all, provider: canonical } = resolveRolePromptPaths(role, provider, projectDir);
|
|
109
|
+
const hit = await readFirstExisting(all);
|
|
110
|
+
if (!hit) {
|
|
111
|
+
return { instructions: null, path: null, resolvedProvider: canonical, fellBack: !!canonical };
|
|
112
|
+
}
|
|
113
|
+
// Detect fallback: if the user asked for a provider but we matched a path
|
|
114
|
+
// that is NOT a per-provider file, we consider it a fallback and warn.
|
|
115
|
+
const fellBack = !!canonical && !hit.path.endsWith(`${canonical}.md`);
|
|
116
|
+
if (fellBack && logger?.debug) {
|
|
117
|
+
logger.debug(`prompt-resolver: role "${role}" has no "${canonical}" variant, using ${path.basename(hit.path)}`);
|
|
118
|
+
}
|
|
119
|
+
return { instructions: hit.content, path: hit.path, resolvedProvider: canonical, fellBack };
|
|
120
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { buildRtkInstructions } from "./rtk-snippet.js";
|
|
2
|
+
import { loadAvailableSkills, buildSkillSection } from "../skills/skill-loader.js";
|
|
3
|
+
import { getLanguageInstruction } from "../utils/locale.js";
|
|
4
|
+
import { section, buildPromptLayout, joinLayout, STABLE, VOLATILE } from "./prompt-layout.js";
|
|
5
|
+
import { clipDiff } from "./diff-clip.js";
|
|
6
|
+
import { buildSplitSignal } from "./split-signal.js";
|
|
7
|
+
|
|
8
|
+
const SUBAGENT_PREAMBLE = [
|
|
9
|
+
"IMPORTANT: You are running as a Karajan sub-agent.",
|
|
10
|
+
"Do NOT ask about using Karajan, do NOT mention Karajan, do NOT suggest orchestration.",
|
|
11
|
+
"Do NOT use any MCP tools. Focus only on reviewing the code."
|
|
12
|
+
].join(" ");
|
|
13
|
+
|
|
14
|
+
const SUBAGENT_PREAMBLE_SERENA = [
|
|
15
|
+
"IMPORTANT: You are running as a Karajan sub-agent.",
|
|
16
|
+
"Do NOT ask about using Karajan, do NOT mention Karajan, do NOT suggest orchestration.",
|
|
17
|
+
"Focus only on reviewing the code."
|
|
18
|
+
].join(" ");
|
|
19
|
+
|
|
20
|
+
const SERENA_INSTRUCTIONS = [
|
|
21
|
+
"## Serena MCP — symbol-level code navigation",
|
|
22
|
+
"You have access to Serena MCP tools for efficient code review.",
|
|
23
|
+
"Use these to verify context without reading entire files:",
|
|
24
|
+
"- `find_symbol(name)` — locate a function, class, or variable definition",
|
|
25
|
+
"- `find_referencing_symbols(name)` — find all callers/references of a symbol",
|
|
26
|
+
"Use Serena to check how changed symbols are used across the codebase.",
|
|
27
|
+
"Fall back to reading files only when Serena tools are not sufficient."
|
|
28
|
+
].join("\n");
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Build the reviewer prompt as a { stable, volatile } layout (Φ1,
|
|
32
|
+
* KJC-PCS-0057). The stable block (preamble, mode, scope rules, JSON
|
|
33
|
+
* schema, serena/rtk, contexts, review rules, skills) is identical
|
|
34
|
+
* across reviews of the same project, so prefix-caching providers hit
|
|
35
|
+
* on it; the per-review content (task context + git diff, up to 12 KB
|
|
36
|
+
* and always different) goes last.
|
|
37
|
+
*/
|
|
38
|
+
export async function buildReviewerPromptLayout({ task, diff, reviewRules, mode, serenaEnabled = false, rtkAvailable = false, productContext = null, domainContext = null, projectDir = null, language = "en", provider = null }) {
|
|
39
|
+
const { body: clippedDiff, note: clipNote } = clipDiff(diff);
|
|
40
|
+
// KJC-BUG-0138: full diff on purpose — the moved-to side survives clipping.
|
|
41
|
+
const splitSignal = buildSplitSignal(diff);
|
|
42
|
+
|
|
43
|
+
const langInstruction = getLanguageInstruction(language);
|
|
44
|
+
const rtkSnippet = buildRtkInstructions({ rtkAvailable });
|
|
45
|
+
let skillSection = null;
|
|
46
|
+
if (projectDir) {
|
|
47
|
+
const skills = await loadAvailableSkills(projectDir);
|
|
48
|
+
skillSection = buildSkillSection(skills, { provider, role: "reviewer" });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return buildPromptLayout([
|
|
52
|
+
section(serenaEnabled ? SUBAGENT_PREAMBLE_SERENA : SUBAGENT_PREAMBLE, STABLE),
|
|
53
|
+
section(langInstruction, STABLE),
|
|
54
|
+
section(`You are a code reviewer in ${mode} mode.`, STABLE),
|
|
55
|
+
section("CRITICAL SCOPE RULE: Only review changes that are part of the diff below. Do NOT flag issues in unchanged code, missing features planned for future tasks, or improvements outside the scope of this task. If the diff is correct for what the task asks, approve it — even if the broader codebase has other issues.", STABLE),
|
|
56
|
+
section("Only block approval for issues IN THE DIFF that are bugs, security vulnerabilities, or clear violations of the review rules.", STABLE),
|
|
57
|
+
section("Return only one valid JSON object and nothing else.", STABLE),
|
|
58
|
+
section("JSON schema:", STABLE),
|
|
59
|
+
section('{"approved":boolean,"blocking_issues":[{"id":string,"severity":"critical|high|medium|low","category":"security|correctness|performance|style|other","file":string,"line":number,"description":string,"suggested_fix":string}],"non_blocking_suggestions":[string],"summary":string,"confidence":number}', STABLE),
|
|
60
|
+
section(serenaEnabled ? SERENA_INSTRUCTIONS : null, STABLE),
|
|
61
|
+
section(rtkSnippet, STABLE),
|
|
62
|
+
section(productContext ? `## Product Context\n${productContext}` : null, STABLE),
|
|
63
|
+
section(domainContext ? `## Domain Context\n${domainContext}` : null, STABLE),
|
|
64
|
+
section(`Review rules:\n${reviewRules}`, STABLE),
|
|
65
|
+
section(skillSection, STABLE),
|
|
66
|
+
section(`Task context:\n${task}`, VOLATILE),
|
|
67
|
+
section(`Git diff:\n${clippedDiff}`, VOLATILE),
|
|
68
|
+
section(clipNote, VOLATILE),
|
|
69
|
+
section(splitSignal, VOLATILE),
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function buildReviewerPrompt(options) {
|
|
74
|
+
return joinLayout(await buildReviewerPromptLayout(options));
|
|
75
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTK (Rust Token Killer) prompt instruction snippet.
|
|
3
|
+
* Injected into coder/reviewer prompts when RTK is detected.
|
|
4
|
+
*/
|
|
5
|
+
const RTK_INSTRUCTIONS = [
|
|
6
|
+
"## Token Optimization (RTK detected)",
|
|
7
|
+
"RTK is installed. Prefix ALL Bash tool calls with `rtk` to reduce token usage:",
|
|
8
|
+
"- Use `rtk git status` instead of `git status`",
|
|
9
|
+
"- Use `rtk git diff` instead of `git diff`",
|
|
10
|
+
"- Use `rtk ls` instead of `ls`",
|
|
11
|
+
"- Use `rtk find` instead of `find`",
|
|
12
|
+
"- Use `rtk grep` instead of `grep`",
|
|
13
|
+
"- Use `rtk cat` instead of `cat`",
|
|
14
|
+
"This does NOT apply to non-Bash tools (Read, Write, Edit, Glob, Grep)."
|
|
15
|
+
].join("\n");
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Build RTK instructions when RTK is detected.
|
|
19
|
+
* @param {{ rtkAvailable?: boolean }} options
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
export function buildRtkInstructions({ rtkAvailable = false } = {}) {
|
|
23
|
+
if (!rtkAvailable) return "";
|
|
24
|
+
return RTK_INSTRUCTIONS;
|
|
25
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Prompt builder for the `spec-reviewer` role (KJC-PCS-0048 PR 1).
|
|
2
|
+
// Mirrors src/prompts/triage.js — project-level override at
|
|
3
|
+
// `<projectDir>/.karajan/roles/spec-reviewer.md` is injected via `instructions`.
|
|
4
|
+
|
|
5
|
+
const SUBAGENT_PREAMBLE = [
|
|
6
|
+
"IMPORTANT: You are running as a Karajan sub-agent.",
|
|
7
|
+
"Do NOT execute or plan the task. Do NOT mention Karajan.",
|
|
8
|
+
"Do NOT use any MCP tools. Your only job is to audit the user's spec.",
|
|
9
|
+
].join(" ");
|
|
10
|
+
|
|
11
|
+
const VALID_CATEGORIES = [
|
|
12
|
+
"ambiguity", "missing_scope", "missing_ac", "contradiction",
|
|
13
|
+
"stack", "assumptions", "out_of_scope",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const SCHEMA_HINT = JSON.stringify({
|
|
17
|
+
severity: "ok|info|warn|fail",
|
|
18
|
+
findings: [{
|
|
19
|
+
id: "F-001",
|
|
20
|
+
severity: "info|warn|fail",
|
|
21
|
+
category: VALID_CATEGORIES.join("|"),
|
|
22
|
+
message: "concrete description",
|
|
23
|
+
suggestion: "concrete sentence the user can paste",
|
|
24
|
+
}],
|
|
25
|
+
reasoning: "one or two sentences",
|
|
26
|
+
}, null, 2);
|
|
27
|
+
|
|
28
|
+
export function buildSpecReviewerPrompt({ spec, instructions } = {}) {
|
|
29
|
+
const sections = [SUBAGENT_PREAMBLE];
|
|
30
|
+
if (instructions) sections.push(instructions);
|
|
31
|
+
sections.push(
|
|
32
|
+
"You are the **Spec Reviewer** for Karajan Code.",
|
|
33
|
+
`Categories (pick one per finding): ${VALID_CATEGORIES.join(", ")}.`,
|
|
34
|
+
"Severity: `info` (nuance), `warn` (real gap), `fail` (unworkable). Top-level severity is the WORST of any finding (or `ok` if none).",
|
|
35
|
+
"Return JSON only:",
|
|
36
|
+
"```json", SCHEMA_HINT, "```",
|
|
37
|
+
"## Spec to audit", "```", String(spec || "").trim(), "```",
|
|
38
|
+
);
|
|
39
|
+
return sections.join("\n");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Build the refine prompt — used when the user picks `[r]efine`. The
|
|
44
|
+
* agent must rewrite the spec to fix the listed findings, returning
|
|
45
|
+
* ONLY the rewritten spec (no JSON, no preamble, no fence). The refine
|
|
46
|
+
* loop will persist this verbatim as `spec-v2.md`.
|
|
47
|
+
*/
|
|
48
|
+
export function buildSpecRefinerPrompt({ originalSpec, findings, instructions } = {}) {
|
|
49
|
+
const sections = [SUBAGENT_PREAMBLE];
|
|
50
|
+
if (instructions) sections.push(instructions);
|
|
51
|
+
const findingsBlock = (findings || []).map((f, i) => {
|
|
52
|
+
const idx = i + 1;
|
|
53
|
+
return `${idx}. [${f.severity}/${f.category}] ${f.message}${f.suggestion ? `\n Fix: ${f.suggestion}` : ""}`;
|
|
54
|
+
}).join("\n");
|
|
55
|
+
sections.push(
|
|
56
|
+
"Your task: produce a rewritten version of the user's spec that addresses every finding listed below.",
|
|
57
|
+
"Output the rewritten spec verbatim — no JSON, no preamble, no markdown fences, no commentary.",
|
|
58
|
+
"Preserve the user's intent; do not invent new requirements or scope beyond the existing spec.",
|
|
59
|
+
"## Original spec", "```", String(originalSpec || "").trim(), "```",
|
|
60
|
+
"## Findings to address", findingsBlock || "(none — pass-through)",
|
|
61
|
+
"## Rewritten spec",
|
|
62
|
+
);
|
|
63
|
+
return sections.join("\n");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { VALID_CATEGORIES };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* split-signal — KJC-BUG-0138 (issue #1364). A file split is not a coverage
|
|
3
|
+
* deletion, but the reviewer doesn't correlate a file losing content with new
|
|
4
|
+
* files gaining it (4/13 pure-refactor PRs falsely rejected). Deterministic
|
|
5
|
+
* pre-analysis, zero LLM: significant removed lines reappearing verbatim among
|
|
6
|
+
* another file's ADDITIONS in the same diff are moves — when ≥ MIN_RATIO of a
|
|
7
|
+
* file's removals move, the reviewer gets the correlation as a pipeline note.
|
|
8
|
+
* Exact `--- a/` / `+++ b/` headers only (BUG-0132: `++content` ≠ header).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const MIN_REMOVED = 10; // fewer significant removals ⇒ too small to misread
|
|
12
|
+
const MIN_RATIO = 0.5; // below this, the removal is mostly a real removal
|
|
13
|
+
|
|
14
|
+
// Braces/punctuation reappear by accident — only letter-bearing lines count.
|
|
15
|
+
function significant(text) {
|
|
16
|
+
const t = text.trim();
|
|
17
|
+
return t.length >= 10 && /[a-zA-Z]/.test(t);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** @returns {string|null} pipeline note, or null when nothing moved. Feed the
|
|
21
|
+
* PRE-CLIPPING diff: the added side must inform even when clipped away. */
|
|
22
|
+
export function buildSplitSignal(diff) {
|
|
23
|
+
if (!diff) return null;
|
|
24
|
+
const removedByFile = new Map();
|
|
25
|
+
const addedByFile = new Map();
|
|
26
|
+
let src = null;
|
|
27
|
+
let dst = null;
|
|
28
|
+
for (const raw of diff.split("\n")) {
|
|
29
|
+
if (raw.startsWith("--- ")) {
|
|
30
|
+
src = raw.startsWith("--- a/") ? raw.slice(6) : null;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (raw.startsWith("+++ ")) {
|
|
34
|
+
dst = raw.startsWith("+++ b/") ? raw.slice(6) : null;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (raw.startsWith("+") && dst && significant(raw.slice(1))) {
|
|
38
|
+
const counts = addedByFile.get(dst) ?? new Map();
|
|
39
|
+
const t = raw.slice(1).trim();
|
|
40
|
+
counts.set(t, (counts.get(t) ?? 0) + 1);
|
|
41
|
+
addedByFile.set(dst, counts);
|
|
42
|
+
} else if (raw.startsWith("-") && src && significant(raw.slice(1))) {
|
|
43
|
+
const lines = removedByFile.get(src) ?? [];
|
|
44
|
+
lines.push(raw.slice(1).trim());
|
|
45
|
+
removedByFile.set(src, lines);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const findings = [];
|
|
50
|
+
for (const [file, removed] of removedByFile) {
|
|
51
|
+
if (removed.length < MIN_REMOVED) continue;
|
|
52
|
+
const dests = new Map();
|
|
53
|
+
let moved = 0;
|
|
54
|
+
for (const text of removed) {
|
|
55
|
+
for (const [other, counts] of addedByFile) {
|
|
56
|
+
if (other === file) continue; // in-place edits are not moves
|
|
57
|
+
const n = counts.get(text) ?? 0;
|
|
58
|
+
if (n > 0) {
|
|
59
|
+
counts.set(text, n - 1); // each added line vouches for ONE removal
|
|
60
|
+
dests.set(other, (dests.get(other) ?? 0) + 1);
|
|
61
|
+
moved++;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (moved / removed.length >= MIN_RATIO) {
|
|
67
|
+
const where = [...dests.entries()]
|
|
68
|
+
.sort((a, b) => b[1] - a[1])
|
|
69
|
+
.slice(0, 4)
|
|
70
|
+
.map(([d, n]) => `${d} (${n})`)
|
|
71
|
+
.join(", ");
|
|
72
|
+
findings.push(`- ${file}: ${moved} of ${removed.length} significant removed lines reappear ADDED in ${where}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (findings.length === 0) return null;
|
|
76
|
+
|
|
77
|
+
return [
|
|
78
|
+
"NOTE FROM THE KJ PIPELINE (deterministic pre-analysis, not from the author): this diff MOVES content between files:",
|
|
79
|
+
...findings,
|
|
80
|
+
"Moved content is a file split/relocation, not a deletion. Before reporting removed tests or lost coverage, check the ADDED side listed above in this SAME diff. Do not treat moved lines as deleted.",
|
|
81
|
+
].join("\n");
|
|
82
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// KJC-TSK-0569 (Onboard B) — prompt + intent schema for the StartDecidor.
|
|
2
|
+
//
|
|
3
|
+
// The decider only DECIDES (one intent from a closed set); the safe HOW is
|
|
4
|
+
// deterministic (0570 maps the intent to a saved command). Keep this prompt
|
|
5
|
+
// tight: it routes, it never executes.
|
|
6
|
+
const PREAMBLE = [
|
|
7
|
+
"IMPORTANT: You are running as a Karajan sub-agent (the `kj start` decider).",
|
|
8
|
+
"Do NOT mention Karajan, do NOT use MCP tools, do NOT execute anything.",
|
|
9
|
+
"Your only job: read the project assessment and pick ONE next-step intent.",
|
|
10
|
+
].join(" ");
|
|
11
|
+
|
|
12
|
+
/** Closed set of intents. Anything else degrades to ASK_USER. */
|
|
13
|
+
export const INTENTS = new Set([
|
|
14
|
+
"ASSESS_ONLY",
|
|
15
|
+
"RECOMMEND_HARDEN",
|
|
16
|
+
"RECOMMEND_INDEX",
|
|
17
|
+
"START_TASK",
|
|
18
|
+
"PROPOSE_PLAN",
|
|
19
|
+
"ASK_USER",
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
const INTENT_GUIDE = [
|
|
23
|
+
"- ASSESS_ONLY: the project is healthy and the user gave no goal — just report.",
|
|
24
|
+
"- RECOMMEND_HARDEN: quality gaps exist (no tests/CI, drifting checks, missing config).",
|
|
25
|
+
"- RECOMMEND_INDEX: the codebase has no knowledge index yet.",
|
|
26
|
+
"- START_TASK: the user stated a concrete thing to build or fix.",
|
|
27
|
+
"- PROPOSE_PLAN: legacy/large project, or a goal that needs a modernization/feature plan.",
|
|
28
|
+
"- ASK_USER: intent is unclear — ask ONE open question to disambiguate.",
|
|
29
|
+
].join("\n");
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {{userMessage?: string, assessment?: string, instructions?: string}} input
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
export function buildStartDecisionPrompt({ userMessage = "", assessment = "", instructions } = {}) {
|
|
36
|
+
const sections = [PREAMBLE];
|
|
37
|
+
if (instructions) sections.push(instructions);
|
|
38
|
+
sections.push(
|
|
39
|
+
"You route the next step for a project the user just opened with `kj start`.",
|
|
40
|
+
"## Project assessment (read-only signals)",
|
|
41
|
+
assessment || "(no assessment available)",
|
|
42
|
+
"## User goal",
|
|
43
|
+
userMessage.trim() || "(none given)",
|
|
44
|
+
"## Intents",
|
|
45
|
+
INTENT_GUIDE,
|
|
46
|
+
"Pick the single best intent. Prefer a concrete next step over ASK_USER when the assessment is clear.",
|
|
47
|
+
"If you pick ASK_USER, put the open question in questionToAsk.",
|
|
48
|
+
"Return a single valid JSON object and nothing else.",
|
|
49
|
+
'JSON schema: {"intent":"ASSESS_ONLY|RECOMMEND_HARDEN|RECOMMEND_INDEX|START_TASK|PROPOSE_PLAN|ASK_USER","rationale":string,"questionToAsk":string}',
|
|
50
|
+
);
|
|
51
|
+
return sections.join("\n\n");
|
|
52
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// KJC-TSK-0375 — Prompt builder for the ToolCorrectnessJudge role.
|
|
2
|
+
// Inspired by deepeval's tool-correctness metric.
|
|
3
|
+
|
|
4
|
+
const PREAMBLE = "IMPORTANT: You are running as a Karajan sub-agent. "
|
|
5
|
+
+ "Do NOT use any MCP tools, do NOT mention Karajan. "
|
|
6
|
+
+ "Your job is to judge another agent's tool choices.";
|
|
7
|
+
|
|
8
|
+
export function buildToolCorrectnessJudgePrompt({ task, toolCalls, instructions }) {
|
|
9
|
+
const calls = toolCalls
|
|
10
|
+
.map((c, i) => `${i + 1}. **${c.tool}** — args: ${JSON.stringify(c.args)}`)
|
|
11
|
+
.join("\n");
|
|
12
|
+
const body = [
|
|
13
|
+
"You are the ToolCorrectnessJudge for Karajan Code.",
|
|
14
|
+
"Input: (a) a task description and (b) the ordered tool calls an LLM coder",
|
|
15
|
+
"made (Read/Edit/Write/Bash/Glob/Grep/MultiEdit). Judge each call on:",
|
|
16
|
+
" - tool choice: right tool for the intent?",
|
|
17
|
+
" - argument quality: paths plausible, commands valid, no garbage placeholders?",
|
|
18
|
+
"Per-call verdict: `correct=true|false` + one-sentence `reason`.",
|
|
19
|
+
"Aggregate into a single 0-100 score:",
|
|
20
|
+
" - 100 = every call right with clean args",
|
|
21
|
+
" - 70-99 = mostly right, minor missteps",
|
|
22
|
+
" - 40-69 = several wrong choices, budget wasted",
|
|
23
|
+
" - 0-39 = predominantly bad, retry advised",
|
|
24
|
+
"Return a single valid JSON object and nothing else.",
|
|
25
|
+
'Schema: {"score":0-100,"summary":string,"breakdown":[{"tool":string,"args":object,"correct":boolean,"reason":string}]}',
|
|
26
|
+
].join("\n");
|
|
27
|
+
const sections = [PREAMBLE];
|
|
28
|
+
if (instructions) sections.push(instructions);
|
|
29
|
+
sections.push(body, `## Task\n${task}`, `## Tool calls (${toolCalls.length})\n${calls || "(no tool calls captured)"}`);
|
|
30
|
+
return sections.join("\n\n");
|
|
31
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const SUBAGENT_PREAMBLE = [
|
|
2
|
+
"IMPORTANT: You are running as a Karajan sub-agent.",
|
|
3
|
+
"Do NOT ask about using Karajan, do NOT mention Karajan, do NOT suggest orchestration.",
|
|
4
|
+
"Do NOT use any MCP tools. Focus only on task complexity triage."
|
|
5
|
+
].join(" ");
|
|
6
|
+
|
|
7
|
+
const ROLE_DESCRIPTIONS = [
|
|
8
|
+
{ role: "planner", description: "Generates an implementation plan before coding. Useful for complex multi-file tasks." },
|
|
9
|
+
{ role: "researcher", description: "Investigates the codebase for context before coding. Useful when understanding existing code is needed." },
|
|
10
|
+
{ role: "tester", description: "Runs dedicated testing pass after coding. Ensures tests exist and pass." },
|
|
11
|
+
{ role: "security", description: "Audits code for security vulnerabilities. Checks auth, input validation, injection risks." },
|
|
12
|
+
{ role: "refactorer", description: "Cleans up and refactors code after the main implementation." },
|
|
13
|
+
{ role: "reviewer", description: "Reviews the code diff for quality issues. Standard quality gate." },
|
|
14
|
+
{ role: "architect", description: "Designs solution architecture — layers, patterns, data model, API contracts, tradeoffs. Activate when task creates new module/app, affects data model/APIs, complexity is medium/complex, or design is ambiguous." },
|
|
15
|
+
{ role: "hu-reviewer", description: "Certifies user stories before coding. Activate for medium/complex tasks that need story decomposition." }
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export function buildTriagePrompt({ task, instructions, availableRoles }) {
|
|
19
|
+
const sections = [SUBAGENT_PREAMBLE];
|
|
20
|
+
|
|
21
|
+
if (instructions) {
|
|
22
|
+
sections.push(instructions);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const roles = availableRoles || ROLE_DESCRIPTIONS;
|
|
26
|
+
|
|
27
|
+
sections.push(
|
|
28
|
+
"You are a task triage agent for Karajan Code, a multi-agent coding orchestrator.",
|
|
29
|
+
"Analyze the following task and determine which pipeline roles should be activated.",
|
|
30
|
+
"## Available Roles",
|
|
31
|
+
roles.map((r) => `- **${r.role}**: ${r.description}`).join("\n"),
|
|
32
|
+
"## Decision Guidelines",
|
|
33
|
+
[
|
|
34
|
+
"- **planner**: Enable for complex tasks (multi-file, architectural changes, data model changes). Disable for simple fixes.",
|
|
35
|
+
"- **researcher**: Enable when the task needs codebase context, API understanding, or investigation. Disable for standalone new files.",
|
|
36
|
+
"- **tester**: Enable for any task with logic, APIs, components, services. Disable ONLY for pure documentation, comments, or CSS-only changes.",
|
|
37
|
+
"- **security**: Enable for authentication, APIs, user input handling, data access, external integrations. Disable for UI-only or doc changes.",
|
|
38
|
+
"- **refactorer**: Enable only when explicitly requested or when the task is a refactoring task.",
|
|
39
|
+
"- **reviewer**: Enable for most tasks as a quality gate. Disable only for trivial, single-line changes.",
|
|
40
|
+
"- **architect**: Enable when creating new modules/apps, changing data models or APIs, medium/complex tasks, or when design approach is ambiguous. Disable for simple fixes, doc-only, or CSS-only changes.",
|
|
41
|
+
"- **hu-reviewer**: Enable for medium/complex tasks that benefit from story decomposition and certification. Disable for trivial/simple tasks, doc-only, or CSS-only changes.",
|
|
42
|
+
"- **audit/analysis taskType**: Set taskType to \"audit\" or \"analysis\" for tasks that only require reading/inspecting code without making changes (e.g., audit, review, analyze, check, verify, inspect, scan, auditar, revisar, analizar, comprobar, verificar, inspeccionar). The coder and reviewer will be skipped entirely for these tasks.",
|
|
43
|
+
"- **no-code taskType**: Use no-code when the task is about data analysis, document generation, SQL queries, CSV transformation, report generation, or any non-programming task. The coder will generate output (not source code), and TDD/SonarQube will be disabled. The reviewer still runs to validate logic/correctness.",
|
|
44
|
+
"",
|
|
45
|
+
"Note: coder is ALWAYS active for coding tasks — you don't need to decide on it. However, for audit/analysis taskTypes the coder is skipped."
|
|
46
|
+
].join("\n"),
|
|
47
|
+
"Classify the task complexity, determine its taskType, recommend only the necessary pipeline roles, and assess whether the task should be decomposed into smaller subtasks.",
|
|
48
|
+
"Keep the reasoning short and practical.",
|
|
49
|
+
"Return a single valid JSON object and nothing else.",
|
|
50
|
+
'JSON schema: {"level":"trivial|simple|medium|complex","roles":["planner|researcher|refactorer|reviewer|tester|security|architect|hu-reviewer"],"taskType":"sw|infra|doc|add-tests|refactor|audit|analysis|no-code","reasoning":string,"shouldDecompose":boolean,"subtasks":string[]}',
|
|
51
|
+
`## Task\n${task}`
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
return sections.join("\n\n");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { ROLE_DESCRIPTIONS };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// KJC-TSK-0455 PR2 — Pre-run drift check + post-merge hook installer.
|
|
2
|
+
// Keeps the local RAG index aligned with HEAD so retrieval never serves
|
|
3
|
+
// stale code without the user having to run `kj rag index` by hand.
|
|
4
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { execa } from "execa";
|
|
8
|
+
|
|
9
|
+
import { openVecStore, projectSlug, getLastIndexedCommit, setLastIndexedCommit } from "./vec-store.js";
|
|
10
|
+
import { indexProjectDelta } from "./indexer.js";
|
|
11
|
+
import { makeGovernedEmbedder } from "./governed-embedder.js";
|
|
12
|
+
|
|
13
|
+
const HOOK_SRC = resolve(fileURLToPath(import.meta.url), "../../../scripts/git-hooks/post-merge");
|
|
14
|
+
|
|
15
|
+
export async function maybeAutoUpdate({ projectDir, config, logger = console, flags = {} } = {}) {
|
|
16
|
+
// commander turns `--no-rag-update` into flags.ragUpdate === false.
|
|
17
|
+
if (flags?.ragUpdate === false || config?.rag?.autoUpdate?.onRun === false) return { skipped: true };
|
|
18
|
+
if (!projectDir || !existsSync(join(projectDir, ".git"))) return { skipped: true };
|
|
19
|
+
let head;
|
|
20
|
+
try { const r = await execa("git", ["-C", projectDir, "rev-parse", "HEAD"]); head = r.stdout.trim(); }
|
|
21
|
+
catch { return { skipped: true }; }
|
|
22
|
+
const slug = projectSlug(projectDir);
|
|
23
|
+
const db = openVecStore({ dim: config?.rag?.embedder?.dim || 768 });
|
|
24
|
+
try {
|
|
25
|
+
const since = getLastIndexedCommit(db, slug);
|
|
26
|
+
if (!since || since === head) return { skipped: true, head };
|
|
27
|
+
logger.info?.(`[rag] drift detected (${since.slice(0, 7)} → ${head.slice(0, 7)}); running delta update`);
|
|
28
|
+
const totals = await indexProjectDelta(projectDir, { db, embedder: makeGovernedEmbedder(config), since, logger });
|
|
29
|
+
if (totals.head) setLastIndexedCommit(db, slug, totals.head);
|
|
30
|
+
return { ran: true, totals };
|
|
31
|
+
} catch (err) {
|
|
32
|
+
logger.warn?.(`[rag] auto-update failed (${err.message}); continuing without refresh`);
|
|
33
|
+
return { failed: true, error: err.message };
|
|
34
|
+
} finally { db.close(); }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// KJC-BUG-0100 — Resolve the hooks dir git actually honours. When a repo is
|
|
38
|
+
// hardened `git config core.hooksPath` points at `.karajan/hooks` and git
|
|
39
|
+
// ignores `.git/hooks/` entirely, so a hook written there never fires.
|
|
40
|
+
export async function resolveHooksDir(projectDir) {
|
|
41
|
+
if (!existsSync(join(projectDir, ".git"))) throw new Error(`Not a git repository: ${projectDir}`);
|
|
42
|
+
let hooksPath = "";
|
|
43
|
+
try {
|
|
44
|
+
const r = await execa("git", ["-C", projectDir, "config", "--local", "core.hooksPath"]);
|
|
45
|
+
hooksPath = r.stdout.trim();
|
|
46
|
+
} catch { /* unset → git uses .git/hooks */ }
|
|
47
|
+
if (hooksPath) {
|
|
48
|
+
return { dir: isAbsolute(hooksPath) ? hooksPath : join(projectDir, hooksPath), hooksPath };
|
|
49
|
+
}
|
|
50
|
+
return { dir: join(projectDir, ".git", "hooks"), hooksPath: "" };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function installPostMergeHook({ projectDir, logger = console } = {}) {
|
|
54
|
+
const { dir: hooksDir, hooksPath } = await resolveHooksDir(projectDir);
|
|
55
|
+
if (!existsSync(hooksDir)) mkdirSync(hooksDir, { recursive: true });
|
|
56
|
+
const target = join(hooksDir, "post-merge");
|
|
57
|
+
const src = readFileSync(HOOK_SRC, "utf8");
|
|
58
|
+
if (existsSync(target)) {
|
|
59
|
+
const current = readFileSync(target, "utf8");
|
|
60
|
+
// Another kj-managed hook (e.g. harden's post-merge) already reindexes.
|
|
61
|
+
if (!current.includes("KJC-TSK-0455") && /kj\s+rag\s+index/.test(current)) {
|
|
62
|
+
return { skipped: true, covered: true, target, hooksPath };
|
|
63
|
+
}
|
|
64
|
+
if (!current.includes("KJC-TSK-0455")) {
|
|
65
|
+
logger.warn?.(`[rag] ${target} already exists and was not installed by kj; leaving untouched`);
|
|
66
|
+
return { skipped: true, target, hooksPath };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
writeFileSync(target, src);
|
|
70
|
+
chmodSync(target, 0o755);
|
|
71
|
+
return { installed: true, target, hooksPath };
|
|
72
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// KJC-TSK-0444 — AST-aware source chunker. Replaces the regex-based
|
|
2
|
+
// chunkSource for JS/TS/JSX files. Each top-level declaration (function,
|
|
3
|
+
// class, var/const, export named/default) becomes one chunk whose `text`
|
|
4
|
+
// is the literal source slice [node.start, node.end]. Comments
|
|
5
|
+
// immediately preceding a declaration are folded in (JSDoc + leading
|
|
6
|
+
// line comments) so the chunk reads like a doc-aware snippet.
|
|
7
|
+
//
|
|
8
|
+
// Falls back to the regex chunker if @babel/parser cannot parse the
|
|
9
|
+
// file (errorRecovery: true catches most cases; a hard syntax error
|
|
10
|
+
// returns null so the caller can fall back).
|
|
11
|
+
import { parse } from "@babel/parser";
|
|
12
|
+
|
|
13
|
+
const PLUGINS = ["typescript", "jsx", "decorators-legacy", "classProperties", "topLevelAwait"];
|
|
14
|
+
|
|
15
|
+
export function chunkSourceAST(text, { path = "<src>", limit = 800, overlap = 100 } = {}) {
|
|
16
|
+
let ast;
|
|
17
|
+
try { ast = parse(text, { sourceType: "module", errorRecovery: true, plugins: PLUGINS }); }
|
|
18
|
+
catch { return null; }
|
|
19
|
+
const body = ast?.program?.body;
|
|
20
|
+
if (!Array.isArray(body) || body.length === 0) return null;
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const node of body) {
|
|
23
|
+
const sym = extractSymbol(node);
|
|
24
|
+
const start = leadingCommentsStart(node);
|
|
25
|
+
const slice = text.slice(start, node.end ?? start);
|
|
26
|
+
if (!slice.trim()) continue;
|
|
27
|
+
if (slice.length <= limit) out.push({ text: slice, metadata: { source: path, kind: "code", symbol: sym } });
|
|
28
|
+
else for (const piece of windowText(slice, limit, overlap)) out.push({ text: piece, metadata: { source: path, kind: "code", symbol: sym } });
|
|
29
|
+
}
|
|
30
|
+
return out.length === 0 ? null : out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function extractSymbol(node) {
|
|
34
|
+
if (node.type === "ExportNamedDeclaration" && node.declaration) return extractSymbol(node.declaration);
|
|
35
|
+
if (node.type === "ExportDefaultDeclaration") return "default";
|
|
36
|
+
if (node.id?.name) return node.id.name;
|
|
37
|
+
if (node.declarations?.[0]?.id?.name) return node.declarations[0].id.name;
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function leadingCommentsStart(node) {
|
|
42
|
+
const lc = node.leadingComments;
|
|
43
|
+
if (Array.isArray(lc) && lc.length > 0) return lc[0].start ?? node.start ?? 0;
|
|
44
|
+
return node.start ?? 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function windowText(text, limit, overlap) {
|
|
48
|
+
if (text.length <= limit) return [text];
|
|
49
|
+
const step = Math.max(1, limit - overlap);
|
|
50
|
+
const out = [];
|
|
51
|
+
for (let i = 0; i < text.length; i += step) {
|
|
52
|
+
out.push(text.slice(i, i + limit));
|
|
53
|
+
if (i + limit >= text.length) break;
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|