@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,107 @@
|
|
|
1
|
+
const DEFAULT_MODEL_TIERS = {
|
|
2
|
+
claude: { trivial: "haiku", simple: "haiku", medium: "sonnet", complex: "opus" },
|
|
3
|
+
codex: { trivial: "o4-mini", simple: "o4-mini", medium: "o4-mini", complex: "o3" },
|
|
4
|
+
gemini: { trivial: "gemini-2.0-flash", simple: "gemini-2.0-flash", medium: "gemini-2.5-pro", complex: "gemini-2.5-pro" },
|
|
5
|
+
aider: { trivial: null, simple: null, medium: null, complex: null }
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const DEFAULT_ROLE_OVERRIDES = {
|
|
9
|
+
reviewer: { trivial: "medium", simple: "medium" },
|
|
10
|
+
triage: { medium: "simple", complex: "simple" }
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const VALID_LEVELS = new Set(["trivial", "simple", "medium", "complex"]);
|
|
14
|
+
|
|
15
|
+
export function getDefaultModelTiers() {
|
|
16
|
+
return structuredClone(DEFAULT_MODEL_TIERS);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getDefaultRoleOverrides() {
|
|
20
|
+
return structuredClone(DEFAULT_ROLE_OVERRIDES);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function resolveModelForRole({ role, provider, level, tierMap, roleOverrides }) {
|
|
24
|
+
if (!provider || !level || !VALID_LEVELS.has(level)) return null;
|
|
25
|
+
|
|
26
|
+
const tiers = tierMap || DEFAULT_MODEL_TIERS;
|
|
27
|
+
const providerTiers = tiers[provider];
|
|
28
|
+
if (!providerTiers) return null;
|
|
29
|
+
|
|
30
|
+
const overrides = roleOverrides || DEFAULT_ROLE_OVERRIDES;
|
|
31
|
+
const roleOvr = overrides[role];
|
|
32
|
+
|
|
33
|
+
let effectiveLevel = level;
|
|
34
|
+
if (roleOvr?.[level]) {
|
|
35
|
+
const mappedLevel = roleOvr[level];
|
|
36
|
+
if (VALID_LEVELS.has(mappedLevel)) {
|
|
37
|
+
effectiveLevel = mappedLevel;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return providerTiers[effectiveLevel] || null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function selectModelsForRoles({ level, config, roles }) {
|
|
45
|
+
if (!level || !VALID_LEVELS.has(level)) {
|
|
46
|
+
return { modelOverrides: {}, reasoning: "No valid triage level provided" };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const modelSelection = config?.model_selection || {};
|
|
50
|
+
const userTiers = modelSelection.tiers || {};
|
|
51
|
+
const userRoleOverrides = modelSelection.role_overrides || {};
|
|
52
|
+
|
|
53
|
+
const mergedTiers = { ...getDefaultModelTiers() };
|
|
54
|
+
for (const [provider, levels] of Object.entries(userTiers)) {
|
|
55
|
+
mergedTiers[provider] = { ...mergedTiers[provider], ...levels };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const mergedRoleOverrides = { ...getDefaultRoleOverrides() };
|
|
59
|
+
for (const [role, levels] of Object.entries(userRoleOverrides)) {
|
|
60
|
+
mergedRoleOverrides[role] = { ...mergedRoleOverrides[role], ...levels };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const allRoles = roles || Object.keys(config?.roles || {});
|
|
64
|
+
const modelOverrides = {};
|
|
65
|
+
const details = [];
|
|
66
|
+
|
|
67
|
+
for (const role of allRoles) {
|
|
68
|
+
const roleConfig = config?.roles?.[role];
|
|
69
|
+
if (!roleConfig) continue;
|
|
70
|
+
|
|
71
|
+
if (roleConfig.model) {
|
|
72
|
+
details.push(`${role}: skipped (explicit model "${roleConfig.model}")`);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (roleConfig.disabled) {
|
|
77
|
+
details.push(`${role}: skipped (disabled)`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const provider = roleConfig.provider;
|
|
82
|
+
if (!provider) {
|
|
83
|
+
details.push(`${role}: skipped (no provider)`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const model = resolveModelForRole({
|
|
88
|
+
role,
|
|
89
|
+
provider,
|
|
90
|
+
level,
|
|
91
|
+
tierMap: mergedTiers,
|
|
92
|
+
roleOverrides: mergedRoleOverrides
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (model) {
|
|
96
|
+
modelOverrides[role] = model;
|
|
97
|
+
details.push(`${role}: ${model} (level=${level}, provider=${provider})`);
|
|
98
|
+
} else {
|
|
99
|
+
details.push(`${role}: no model for provider "${provider}"`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
modelOverrides,
|
|
105
|
+
reasoning: `Smart model selection (level=${level}): ${details.join("; ")}`
|
|
106
|
+
};
|
|
107
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Detect platform and return OS-appropriate install commands.
|
|
5
|
+
*/
|
|
6
|
+
export function getPlatform() {
|
|
7
|
+
const platform = os.platform();
|
|
8
|
+
if (platform === "win32") return "windows";
|
|
9
|
+
if (platform === "darwin") return "macos";
|
|
10
|
+
return "linux";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const INSTALL_COMMANDS = {
|
|
14
|
+
rtk: {
|
|
15
|
+
macos: "brew install rtk && rtk init --global",
|
|
16
|
+
linux: "curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh && rtk init --global",
|
|
17
|
+
windows: "Download from https://github.com/rtk-ai/rtk/releases and add to PATH"
|
|
18
|
+
},
|
|
19
|
+
squeezr: {
|
|
20
|
+
macos: "npm install -g squeezr-ai",
|
|
21
|
+
linux: "npm install -g squeezr-ai",
|
|
22
|
+
windows: "npm install -g squeezr-ai"
|
|
23
|
+
},
|
|
24
|
+
qmd: {
|
|
25
|
+
macos: "npm install -g @tobilu/qmd",
|
|
26
|
+
linux: "npm install -g @tobilu/qmd",
|
|
27
|
+
windows: "npm install -g @tobilu/qmd"
|
|
28
|
+
},
|
|
29
|
+
claude: {
|
|
30
|
+
macos: "npm install -g @anthropic-ai/claude-code",
|
|
31
|
+
linux: "npm install -g @anthropic-ai/claude-code",
|
|
32
|
+
windows: "npm install -g @anthropic-ai/claude-code"
|
|
33
|
+
},
|
|
34
|
+
codex: {
|
|
35
|
+
macos: "npm install -g @openai/codex",
|
|
36
|
+
linux: "npm install -g @openai/codex",
|
|
37
|
+
windows: "npm install -g @openai/codex"
|
|
38
|
+
},
|
|
39
|
+
gemini: {
|
|
40
|
+
macos: "npm install -g @google/gemini-cli",
|
|
41
|
+
linux: "npm install -g @google/gemini-cli",
|
|
42
|
+
windows: "npm install -g @google/gemini-cli"
|
|
43
|
+
},
|
|
44
|
+
aider: {
|
|
45
|
+
macos: "pipx install aider-chat",
|
|
46
|
+
linux: "pipx install aider-chat || pip3 install aider-chat",
|
|
47
|
+
windows: "pip install aider-chat"
|
|
48
|
+
},
|
|
49
|
+
opencode: {
|
|
50
|
+
macos: "curl -fsSL https://opencode.ai/install | bash",
|
|
51
|
+
linux: "curl -fsSL https://opencode.ai/install | bash",
|
|
52
|
+
windows: "See https://github.com/nicepkg/opencode for Windows install"
|
|
53
|
+
},
|
|
54
|
+
qwen: {
|
|
55
|
+
macos: "npm install -g @qwen-code/qwen-code",
|
|
56
|
+
linux: "npm install -g @qwen-code/qwen-code",
|
|
57
|
+
windows: "npm install -g @qwen-code/qwen-code"
|
|
58
|
+
},
|
|
59
|
+
agy: {
|
|
60
|
+
macos: "curl -fsSL https://antigravity.google/cli/install.sh | bash",
|
|
61
|
+
linux: "curl -fsSL https://antigravity.google/cli/install.sh | bash",
|
|
62
|
+
windows: "irm https://antigravity.google/cli/install.ps1 | iex"
|
|
63
|
+
},
|
|
64
|
+
copilot: {
|
|
65
|
+
macos: "npm install -g @github/copilot",
|
|
66
|
+
linux: "npm install -g @github/copilot",
|
|
67
|
+
windows: "npm install -g @github/copilot"
|
|
68
|
+
},
|
|
69
|
+
docker: {
|
|
70
|
+
macos: "brew install --cask docker",
|
|
71
|
+
linux: "sudo apt install docker.io docker-compose-v2 (or see https://docs.docker.com/engine/install/)",
|
|
72
|
+
windows: "Download Docker Desktop from https://www.docker.com/products/docker-desktop/"
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export function getInstallCommand(tool) {
|
|
77
|
+
const platform = getPlatform();
|
|
78
|
+
return INSTALL_COMMANDS[tool]?.[platform] || INSTALL_COMMANDS[tool]?.linux || `Install ${tool} manually`;
|
|
79
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Shim: paths primitives now live in karajan-core/paths so the
|
|
2
|
+
// hu-board workspace can consume them without a relative dep on the
|
|
3
|
+
// CLI src tree. KJC-TSK-0511 PR3.
|
|
4
|
+
export {
|
|
5
|
+
resolveHome,
|
|
6
|
+
getKarajanHome,
|
|
7
|
+
__resetKjHomeWarningForTests,
|
|
8
|
+
getSessionRoot,
|
|
9
|
+
getSonarComposePath,
|
|
10
|
+
getOllamaComposePath,
|
|
11
|
+
getWebperfDir,
|
|
12
|
+
getPromptsDir,
|
|
13
|
+
} from "karajan-core/paths";
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stop-on-sudo policy (KJC-TSK-0659). When a tool cannot be installed
|
|
3
|
+
* automatically (sudo needed, no package-manager route, or the attempt
|
|
4
|
+
* failed), kj must NOT continue degraded — a RAG with 0 chunks because
|
|
5
|
+
* Docker was missing helps nobody. Instead: emit ONE block with the exact
|
|
6
|
+
* commands for this machine's OS and exit with a distinctive code so a
|
|
7
|
+
* driving agent stops, shows the block, and waits for the user.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const PENDING_EXIT_CODE = 3;
|
|
11
|
+
|
|
12
|
+
const PENDING = new Set(["manual", "failed", "needs-user"]);
|
|
13
|
+
|
|
14
|
+
// Exact per-OS commands for the tools kj cannot install unattended.
|
|
15
|
+
// Multiple lines when the route depends on the distro/package manager.
|
|
16
|
+
const OS_COMMANDS = {
|
|
17
|
+
docker: {
|
|
18
|
+
linux: ["sudo apt-get install -y docker.io # Debian/Ubuntu", "sudo dnf install -y docker # Fedora/RHEL"],
|
|
19
|
+
darwin: ["brew install --cask docker # Docker Desktop, then open it once"],
|
|
20
|
+
win32: ["winget install Docker.DockerDesktop", "wsl --install # if WSL2 is not set up yet"],
|
|
21
|
+
},
|
|
22
|
+
git: {
|
|
23
|
+
linux: ["sudo apt-get install -y git # Debian/Ubuntu", "sudo dnf install -y git # Fedora/RHEL"],
|
|
24
|
+
darwin: ["brew install git # or: xcode-select --install"],
|
|
25
|
+
win32: ["winget install Git.Git"],
|
|
26
|
+
},
|
|
27
|
+
semgrep: {
|
|
28
|
+
// PEP 668 (#1256): system Python is externally managed on modern
|
|
29
|
+
// distros — pipx comes from the distro package manager, never from pip.
|
|
30
|
+
linux: ["sudo apt update && sudo apt install -y pipx && pipx install semgrep # Debian/Ubuntu", "sudo dnf install -y pipx && pipx install semgrep # Fedora/RHEL"],
|
|
31
|
+
darwin: ["brew install semgrep"],
|
|
32
|
+
win32: ["python -m pip install --user semgrep"],
|
|
33
|
+
},
|
|
34
|
+
"osv-scanner": {
|
|
35
|
+
linux: ["go install github.com/google/osv-scanner/v2/cmd/osv-scanner@v2 # or download from GitHub releases"],
|
|
36
|
+
darwin: ["brew install osv-scanner"],
|
|
37
|
+
win32: ["winget install Google.OSVScanner # or download from GitHub releases"],
|
|
38
|
+
},
|
|
39
|
+
lighthouse: {
|
|
40
|
+
linux: ["npm install -g lighthouse"],
|
|
41
|
+
darwin: ["npm install -g lighthouse"],
|
|
42
|
+
win32: ["npm install -g lighthouse"],
|
|
43
|
+
},
|
|
44
|
+
ollama: {
|
|
45
|
+
linux: ["curl -fsSL https://ollama.com/install.sh | sh # official installer (uses sudo)", "ollama pull nomic-embed-text"],
|
|
46
|
+
darwin: ["brew install ollama && brew services start ollama", "ollama pull nomic-embed-text"],
|
|
47
|
+
win32: ["winget install Ollama.Ollama", "ollama pull nomic-embed-text"],
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** Exact commands to install `tool` on `platform` (empty when unknown). */
|
|
52
|
+
export function osCommandsFor(tool, platform = process.platform) {
|
|
53
|
+
return OS_COMMANDS[tool]?.[platform] ?? [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Results that require the USER's hands. `manual`/`failed`/`needs-user`
|
|
58
|
+
* always qualify; `declined` only when nobody actually declined — a non-TTY
|
|
59
|
+
* run without --yes auto-answers the default, which for sudo installs is
|
|
60
|
+
* "no". A real interactive decline stays the user's own decision.
|
|
61
|
+
*/
|
|
62
|
+
export function collectPending(results, { tty = Boolean(process.stdin.isTTY), yes = false } = {}) {
|
|
63
|
+
return results.filter((r) => PENDING.has(r.action) || (r.action === "declined" && !tty && !yes));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The PENDING USER ACTION block: exact commands for THIS OS, then wait. */
|
|
67
|
+
export function renderPendingBlock(pending, { platform = process.platform, retry = "kj install-tools" } = {}) {
|
|
68
|
+
const lines = [
|
|
69
|
+
"════ PENDING USER ACTION ════════════════════════════════════════",
|
|
70
|
+
"kj could not finish this install by itself (sudo or a platform",
|
|
71
|
+
"installer is required). Karajan needs a COMPLETE environment —",
|
|
72
|
+
"do not continue degraded.",
|
|
73
|
+
"",
|
|
74
|
+
"Run in YOUR terminal:",
|
|
75
|
+
"",
|
|
76
|
+
];
|
|
77
|
+
for (const r of pending) {
|
|
78
|
+
const why = r.error ? `install failed: ${r.error}` : r.reason || "no automatic route on this machine";
|
|
79
|
+
lines.push(` ▸ ${r.tool} (${why})`);
|
|
80
|
+
const os = osCommandsFor(r.tool, platform);
|
|
81
|
+
const own = r.commands ?? (r.command ? [r.command] : null) ?? (r.suggested ? [r.suggested] : null);
|
|
82
|
+
// A FAILED install must not be re-suggested verbatim (#1256: the pip
|
|
83
|
+
// route that just broke) — the curated per-OS route goes first there.
|
|
84
|
+
const commands = (r.action === "failed" ? (os.length > 0 ? os : own) : (own ?? (os.length > 0 ? os : null)))
|
|
85
|
+
?? [`see ${r.manualUrl || "the tool's install docs"}`];
|
|
86
|
+
for (const c of commands) lines.push(` ${c}`);
|
|
87
|
+
lines.push("");
|
|
88
|
+
}
|
|
89
|
+
lines.push(
|
|
90
|
+
`When done, re-run: ${retry}`,
|
|
91
|
+
"Agents: STOP here, show this block to your user, and WAIT for their",
|
|
92
|
+
`go-ahead. Exit code ${PENDING_EXIT_CODE} means "pending user action" — never proceed past it.`,
|
|
93
|
+
);
|
|
94
|
+
return lines.join("\n");
|
|
95
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Shim — the real implementation now lives in karajan-core/port-check.
|
|
2
|
+
// Kept here so CLI callers (src/**/*.js) keep importing
|
|
3
|
+
// "../utils/port-check.js" without churn during KJC-TSK-0511 (decouple
|
|
4
|
+
// @karajan/hu-board). Will be retired once every consumer migrates to
|
|
5
|
+
// the karajan-core import.
|
|
6
|
+
export { isPortAvailable, findAvailablePort } from "karajan-core/port-check";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect which process is holding a TCP port. Cross-platform best-effort:
|
|
3
|
+
* - Linux/macOS: try `lsof -iTCP:PORT -sTCP:LISTEN -n -P -Fpcn` (parsable),
|
|
4
|
+
* fall back to `ss -tlnp` for Linux-only pid detection.
|
|
5
|
+
* - Windows: `netstat -ano` + `tasklist` to resolve image name.
|
|
6
|
+
*
|
|
7
|
+
* Returns null if the port is free or we cannot determine the occupant.
|
|
8
|
+
* Never throws — designed to enrich diagnostic messages, not to gate logic.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { runCommand } from "./process.js";
|
|
12
|
+
import { escapeRegExp } from "./escape-regexp.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {Object} PortOccupant
|
|
16
|
+
* @property {number} port
|
|
17
|
+
* @property {number|null} pid
|
|
18
|
+
* @property {string|null} command - process name ("karajan-sonarqube", "node", etc.)
|
|
19
|
+
* @property {string} raw - raw tool output for debugging
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {number} port
|
|
24
|
+
* @returns {Promise<PortOccupant|null>}
|
|
25
|
+
*/
|
|
26
|
+
export async function getPortOccupant(port) {
|
|
27
|
+
if (process.platform === "win32") {
|
|
28
|
+
return detectWindows(port);
|
|
29
|
+
}
|
|
30
|
+
const byLsof = await detectLsof(port);
|
|
31
|
+
if (byLsof) return byLsof;
|
|
32
|
+
return detectSs(port);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function detectLsof(port) {
|
|
36
|
+
try {
|
|
37
|
+
const res = await runCommand("lsof", [
|
|
38
|
+
`-iTCP:${port}`,
|
|
39
|
+
"-sTCP:LISTEN",
|
|
40
|
+
"-n",
|
|
41
|
+
"-P",
|
|
42
|
+
"-Fpcn",
|
|
43
|
+
]);
|
|
44
|
+
if (res.exitCode !== 0 || !res.stdout.trim()) return null;
|
|
45
|
+
// Format: lines starting with p<pid>, c<command>, n<name>
|
|
46
|
+
const lines = res.stdout.split("\n").filter(Boolean);
|
|
47
|
+
let pid = null;
|
|
48
|
+
let command = null;
|
|
49
|
+
for (const line of lines) {
|
|
50
|
+
if (line.startsWith("p")) pid = Number(line.slice(1)) || null;
|
|
51
|
+
else if (line.startsWith("c")) command = line.slice(1) || null;
|
|
52
|
+
}
|
|
53
|
+
return { port, pid, command, raw: res.stdout };
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function detectSs(port) {
|
|
60
|
+
try {
|
|
61
|
+
const res = await runCommand("ss", ["-tlnpH", `sport = :${port}`]);
|
|
62
|
+
if (res.exitCode !== 0 || !res.stdout.trim()) return null;
|
|
63
|
+
// Example line: LISTEN 0 511 0.0.0.0:4000 0.0.0.0:* users:(("node",pid=12345,fd=20))
|
|
64
|
+
const match = res.stdout.match(/users:\(\("([^"]+)",pid=(\d+)/);
|
|
65
|
+
if (!match) return null;
|
|
66
|
+
return { port, pid: Number(match[2]), command: match[1], raw: res.stdout };
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function detectWindows(port) {
|
|
73
|
+
try {
|
|
74
|
+
const netstat = await runCommand("netstat", ["-ano"]);
|
|
75
|
+
if (netstat.exitCode !== 0) return null;
|
|
76
|
+
const line = netstat.stdout
|
|
77
|
+
.split(/\r?\n/)
|
|
78
|
+
.find((l) => l.match(new RegExp(`:${escapeRegExp(port)}\\s+.*LISTENING`)));
|
|
79
|
+
if (!line) return null;
|
|
80
|
+
const parts = line.trim().split(/\s+/);
|
|
81
|
+
const pid = Number(parts[parts.length - 1]) || null;
|
|
82
|
+
if (!pid) return { port, pid: null, command: null, raw: line };
|
|
83
|
+
const tasklist = await runCommand("tasklist", ["/FI", `PID eq ${pid}`, "/FO", "CSV", "/NH"]);
|
|
84
|
+
const command = parseTasklist(tasklist.stdout);
|
|
85
|
+
return { port, pid, command, raw: `${line}\n${tasklist.stdout}` };
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function parseTasklist(stdout) {
|
|
92
|
+
const line = stdout.split(/\r?\n/).find(Boolean);
|
|
93
|
+
if (!line) return null;
|
|
94
|
+
const match = line.match(/^"([^"]+)"/);
|
|
95
|
+
return match ? match[1] : null;
|
|
96
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { buildDefaultPricingTable } from "../agents/model-registry.js";
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_MODEL_PRICING = buildDefaultPricingTable();
|
|
4
|
+
|
|
5
|
+
export function calculateUsageCostUsd({ provider, model, tokens_in, tokens_out, pricing }) {
|
|
6
|
+
const table = pricing || DEFAULT_MODEL_PRICING;
|
|
7
|
+
|
|
8
|
+
let entry = table[model];
|
|
9
|
+
|
|
10
|
+
if (!entry && provider && model) {
|
|
11
|
+
entry = table[`${provider}/${model}`];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!entry && model && model.includes("/")) {
|
|
15
|
+
const [, actualModel] = model.split("/");
|
|
16
|
+
entry = table[actualModel];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!entry) return 0;
|
|
20
|
+
|
|
21
|
+
const inputCost = (tokens_in * entry.input_per_million) / 1_000_000;
|
|
22
|
+
const outputCost = (tokens_out * entry.output_per_million) / 1_000_000;
|
|
23
|
+
return inputCost + outputCost;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function mergePricing(defaults, overrides) {
|
|
27
|
+
if (!overrides || typeof overrides !== "object") return { ...defaults };
|
|
28
|
+
return { ...defaults, ...overrides };
|
|
29
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
// --- JS/TS ---
|
|
5
|
+
const JS_FRAMEWORKS = ["vitest", "jest", "@jest/core", "mocha", "ava", "tap", "playwright", "@playwright/test"];
|
|
6
|
+
const JS_CONFIG_FILES = [
|
|
7
|
+
"vitest.config.js", "vitest.config.ts",
|
|
8
|
+
"jest.config.js", "jest.config.ts", "jest.config.mjs",
|
|
9
|
+
".mocharc.yml", ".mocharc.json",
|
|
10
|
+
"playwright.config.js", "playwright.config.ts"
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
// --- Multi-language project markers ---
|
|
14
|
+
const LANGUAGE_MARKERS = [
|
|
15
|
+
// Java / Kotlin (Maven)
|
|
16
|
+
{ file: "pom.xml", framework: "junit", language: "java" },
|
|
17
|
+
// Java / Kotlin (Gradle)
|
|
18
|
+
{ file: "build.gradle", framework: "junit", language: "java" },
|
|
19
|
+
{ file: "build.gradle.kts", framework: "junit", language: "kotlin" },
|
|
20
|
+
// Python
|
|
21
|
+
{ file: "pytest.ini", framework: "pytest", language: "python" },
|
|
22
|
+
{ file: "pyproject.toml", framework: "pytest", language: "python" },
|
|
23
|
+
{ file: "setup.py", framework: "pytest", language: "python" },
|
|
24
|
+
{ file: "setup.cfg", framework: "pytest", language: "python" },
|
|
25
|
+
{ file: "tox.ini", framework: "pytest", language: "python" },
|
|
26
|
+
// Go
|
|
27
|
+
{ file: "go.mod", framework: "go-test", language: "go" },
|
|
28
|
+
// Rust
|
|
29
|
+
{ file: "Cargo.toml", framework: "cargo-test", language: "rust" },
|
|
30
|
+
// C# / .NET
|
|
31
|
+
{ file: "*.csproj", glob: true, framework: "dotnet-test", language: "csharp" },
|
|
32
|
+
{ file: "*.sln", glob: true, framework: "dotnet-test", language: "csharp" },
|
|
33
|
+
// Ruby
|
|
34
|
+
{ file: "Gemfile", framework: "rspec", language: "ruby" },
|
|
35
|
+
{ file: ".rspec", framework: "rspec", language: "ruby" },
|
|
36
|
+
// PHP
|
|
37
|
+
{ file: "phpunit.xml", framework: "phpunit", language: "php" },
|
|
38
|
+
{ file: "phpunit.xml.dist", framework: "phpunit", language: "php" },
|
|
39
|
+
// Swift
|
|
40
|
+
{ file: "Package.swift", framework: "xctest", language: "swift" },
|
|
41
|
+
// Dart / Flutter
|
|
42
|
+
{ file: "pubspec.yaml", framework: "dart-test", language: "dart" },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// --- Infra (INF-B, KJC-TSK-0759) ---
|
|
46
|
+
// Checked AFTER app-language markers: a mixed repo keeps its app framework.
|
|
47
|
+
// Only unequivocal markers — a stray .yaml never classifies as infra.
|
|
48
|
+
const INFRA_MARKERS = [
|
|
49
|
+
{ file: "*.tf", glob: true, framework: "terraform-validate", language: "infra" },
|
|
50
|
+
{ file: "terraform", framework: "terraform-validate", language: "infra" },
|
|
51
|
+
{ file: "Chart.yaml", framework: "helm-lint", language: "infra" },
|
|
52
|
+
{ file: "kustomization.yaml", framework: "kustomize-build", language: "infra" },
|
|
53
|
+
{ file: "kustomization.yml", framework: "kustomize-build", language: "infra" },
|
|
54
|
+
{ file: "ansible.cfg", framework: "ansible-lint", language: "infra" },
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
/** Test file patterns per language (used by TDD policy). */
|
|
58
|
+
export const TEST_PATTERNS_BY_LANGUAGE = {
|
|
59
|
+
javascript: ["/tests/", "/__tests__/", ".test.", ".spec."],
|
|
60
|
+
java: ["/src/test/", "/test/", "Test.java", "Tests.java", "IT.java"],
|
|
61
|
+
kotlin: ["/src/test/", "/test/", "Test.kt", "Tests.kt", "/src/androidTest/"],
|
|
62
|
+
python: ["/tests/", "/test/", "test_", "_test.py", "tests.py"],
|
|
63
|
+
go: ["_test.go"],
|
|
64
|
+
rust: ["/tests/", "#[test]", "#[cfg(test)]"],
|
|
65
|
+
csharp: ["/Tests/", "/Test/", "Tests.cs", "Test.cs", ".Tests/"],
|
|
66
|
+
ruby: ["/spec/", "/test/", "_spec.rb", "_test.rb"],
|
|
67
|
+
php: ["/tests/", "/test/", "Test.php"],
|
|
68
|
+
swift: ["/Tests/", "Tests.swift"],
|
|
69
|
+
dart: ["/test/", "_test.dart"],
|
|
70
|
+
infra: ["/tests/", "/test/", "_test."],
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
function frameworkFromConfig(filename) {
|
|
74
|
+
if (filename.startsWith("vitest")) return "vitest";
|
|
75
|
+
if (filename.startsWith("jest")) return "jest";
|
|
76
|
+
if (filename.startsWith(".mocha")) return "mocha";
|
|
77
|
+
return "playwright";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Detect if the project has a test framework configured.
|
|
82
|
+
* Checks JS (package.json), then multi-language project markers.
|
|
83
|
+
* @param {string} cwd - Project root
|
|
84
|
+
* @returns {Promise<{hasTests: boolean, framework: string|null, language: string|null}>}
|
|
85
|
+
*/
|
|
86
|
+
export async function detectTestFramework(cwd = process.cwd()) {
|
|
87
|
+
// 1. JS/TS: check package.json
|
|
88
|
+
try {
|
|
89
|
+
const pkgRaw = await fs.readFile(path.join(cwd, "package.json"), "utf8");
|
|
90
|
+
const pkg = JSON.parse(pkgRaw);
|
|
91
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
92
|
+
|
|
93
|
+
for (const fw of JS_FRAMEWORKS) {
|
|
94
|
+
if (allDeps[fw]) {
|
|
95
|
+
return { hasTests: true, framework: fw, language: "javascript" };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch { /* no package.json or parse error */ }
|
|
99
|
+
|
|
100
|
+
// 2. JS/TS: check config files
|
|
101
|
+
for (const cf of JS_CONFIG_FILES) {
|
|
102
|
+
try {
|
|
103
|
+
await fs.access(path.join(cwd, cf));
|
|
104
|
+
return { hasTests: true, framework: frameworkFromConfig(cf), language: "javascript" };
|
|
105
|
+
} catch { /* not found */ }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 3. Multi-language: check project markers
|
|
109
|
+
const lang = await matchMarkers(cwd, LANGUAGE_MARKERS);
|
|
110
|
+
if (lang) return lang;
|
|
111
|
+
|
|
112
|
+
// 4. Infra (INF-B): terraform/helm/kustomize/ansible have their own suite.
|
|
113
|
+
const infra = await matchMarkers(cwd, INFRA_MARKERS);
|
|
114
|
+
if (infra) return infra;
|
|
115
|
+
|
|
116
|
+
return { hasTests: false, framework: null, language: null };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* True when the project carries unequivocal infra markers (terraform, helm,
|
|
121
|
+
* kustomize, ansible) — regardless of the app framework the repo may also
|
|
122
|
+
* have. Used by INF-C's audit collector to gate the checkov scan.
|
|
123
|
+
* @param {string} cwd
|
|
124
|
+
* @returns {Promise<boolean>}
|
|
125
|
+
*/
|
|
126
|
+
export async function detectInfraMarkers(cwd = process.cwd()) {
|
|
127
|
+
return Boolean(await matchMarkers(cwd, INFRA_MARKERS));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function matchMarkers(cwd, markers) {
|
|
131
|
+
for (const marker of markers) {
|
|
132
|
+
try {
|
|
133
|
+
if (marker.glob) {
|
|
134
|
+
const entries = await fs.readdir(cwd);
|
|
135
|
+
const ext = marker.file.replaceAll("*", "");
|
|
136
|
+
if (entries.some((e) => e.endsWith(ext))) {
|
|
137
|
+
return { hasTests: true, framework: marker.framework, language: marker.language };
|
|
138
|
+
}
|
|
139
|
+
} else {
|
|
140
|
+
await fs.access(path.join(cwd, marker.file));
|
|
141
|
+
return { hasTests: true, framework: marker.framework, language: marker.language };
|
|
142
|
+
}
|
|
143
|
+
} catch { /* not found */ }
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Detect if SonarQube is configured for this project.
|
|
150
|
+
* @param {string} cwd - Project root
|
|
151
|
+
* @returns {Promise<{configured: boolean}>}
|
|
152
|
+
*/
|
|
153
|
+
export async function detectSonarConfig(cwd = process.cwd()) {
|
|
154
|
+
try {
|
|
155
|
+
await fs.access(path.join(cwd, "sonar-project.properties"));
|
|
156
|
+
return { configured: true };
|
|
157
|
+
} catch { /* sonar-project.properties does not exist */
|
|
158
|
+
return { configured: false };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR-H: ask the user "Nombre del proyecto?" before saving a plan.
|
|
3
|
+
*
|
|
4
|
+
* The user's words: "El nombre del board debería de deducirse del
|
|
5
|
+
* cwd o del nombre del plan, pero no darlo por hecho, preguntar al
|
|
6
|
+
* usuario siempre, por si quiere cambiarlo."
|
|
7
|
+
*
|
|
8
|
+
* Pre-fills the prompt with the suggested name (derived from the
|
|
9
|
+
* task / cwd) so accepting the default is one ENTER away. Returns
|
|
10
|
+
* the trimmed answer; falls back to the default when the user just
|
|
11
|
+
* hits ENTER (empty input).
|
|
12
|
+
*
|
|
13
|
+
* Caller is responsible for skipping this when stdin/stdout are not
|
|
14
|
+
* a TTY, when --yes is set, or when --json is set.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import readline from "node:readline";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} defaultName — pre-filled suggestion shown in [brackets]
|
|
21
|
+
* @returns {Promise<string>} the user's answer (defaults to defaultName)
|
|
22
|
+
*/
|
|
23
|
+
export async function promptProjectName(defaultName) {
|
|
24
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
25
|
+
const fallback = String(defaultName || "").trim();
|
|
26
|
+
const hint = fallback ? ` [${fallback}]` : "";
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
rl.question(`Nombre del proyecto${hint}: `, (answer) => {
|
|
29
|
+
rl.close();
|
|
30
|
+
const trimmed = String(answer || "").trim();
|
|
31
|
+
resolve(trimmed || fallback);
|
|
32
|
+
});
|
|
33
|
+
rl.on("SIGINT", () => { rl.close(); resolve(fallback); });
|
|
34
|
+
});
|
|
35
|
+
}
|