karajan-code 4.70.3 → 5.0.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/README.md +2 -2
- package/package.json +6 -14
- package/packages/hu-board/package.json +1 -1
- package/packages/hu-board/public/app.js +4 -18
- package/packages/hu-board/public/index.html +5 -2
- package/packages/hu-board/public/styles.css +26 -0
- package/packages/hu-board/public/utils/api.js +0 -74
- package/packages/hu-board/public/utils/board-tour.js +62 -0
- package/packages/hu-board/public/utils/board-view.js +49 -144
- package/packages/hu-board/public/utils/command-launcher.js +8 -70
- package/packages/hu-board/public/utils/formatters.js +10 -0
- package/packages/hu-board/public/utils/governance-view.js +13 -1
- package/packages/hu-board/public/utils/hu-actions.js +17 -68
- package/packages/hu-board/public/utils/init-listeners.js +7 -8
- package/packages/hu-board/public/utils/log-panel.js +3 -16
- package/packages/hu-board/public/utils/maggle-mode.js +2 -12
- package/packages/hu-board/public/utils/modals.js +7 -0
- package/packages/hu-board/public/utils/project-picker-view.js +1 -1
- package/packages/hu-board/public/utils/server-push.js +3 -22
- package/packages/hu-board/public/utils/shared-board-notice.js +33 -0
- package/packages/hu-board/public/utils/story-detail-view.js +5 -19
- package/packages/hu-board/src/cleanup-zombies.js +0 -1
- package/packages/hu-board/src/command-runner.js +36 -25
- package/packages/hu-board/src/db-connection.js +282 -0
- package/packages/hu-board/src/db-paths.js +113 -0
- package/packages/hu-board/src/db-queries.js +188 -0
- package/packages/hu-board/src/db-tombstones.js +51 -0
- package/packages/hu-board/src/db.js +28 -619
- package/packages/hu-board/src/ephemeral-cleaner.js +2 -3
- package/packages/hu-board/src/hu-zombie-reaper.js +5 -1
- package/packages/hu-board/src/plan-mutations.js +3 -153
- package/packages/hu-board/src/plans-service.js +55 -0
- package/packages/hu-board/src/routes/api/commands.js +122 -0
- package/packages/hu-board/src/routes/api/plans.js +55 -0
- package/packages/hu-board/src/routes/api/projects.js +267 -0
- package/packages/hu-board/src/routes/api/prompts.js +135 -0
- package/packages/hu-board/src/routes/api/sessions.js +95 -0
- package/packages/hu-board/src/routes/api/stories.js +183 -0
- package/packages/hu-board/src/routes/api/system.js +241 -0
- package/packages/hu-board/src/routes/api/tombstones.js +38 -0
- package/packages/hu-board/src/routes/api.js +24 -1371
- package/packages/hu-board/src/routes/governance.js +23 -1
- package/packages/hu-board/src/routes/lanes.js +40 -0
- package/packages/hu-board/src/routes/rag.js +4 -3
- package/packages/hu-board/src/server.js +20 -34
- package/packages/hu-board/src/sync-files.js +318 -0
- package/packages/hu-board/src/sync-project.js +99 -0
- package/packages/hu-board/src/sync.js +22 -566
- package/packages/hu-board/src/zombie-reaper.js +1 -1
- package/scripts/dual-publish.mjs +19 -3
- package/scripts/postinstall.js +15 -2
- package/scripts/verify-pack-mcp.mjs +11 -7
- package/scripts/verify-pack.mjs +4 -4
- package/src/audit/audit-history.js +3 -2
- package/src/audit/dead-exports.js +68 -59
- package/src/audit/deterministic-summary.js +33 -13
- package/src/audit/npm-signatures.js +41 -0
- package/src/audit/sbom.js +35 -0
- package/src/checks/agent-token.js +112 -0
- package/src/checks/ai-surface.js +9 -7
- package/src/checks/config-files.js +8 -7
- package/src/checks/dir-setup.js +34 -1
- package/src/checks/native-build.js +21 -39
- package/src/checks/runner.js +128 -142
- package/src/cli/advanced-commands.js +6 -6
- package/src/cli/register-meta.js +42 -82
- package/src/cli/register-pipeline.js +8 -140
- package/src/cli/register-plan.js +9 -100
- package/src/cli/retired-commands.js +49 -0
- package/src/cli.js +18 -5
- package/src/commands/agent-run.js +40 -26
- package/src/commands/audit.js +127 -124
- package/src/commands/board.js +5 -9
- package/src/commands/check.js +29 -16
- package/src/commands/doctor.js +2 -0
- package/src/commands/env.js +176 -148
- package/src/commands/go.js +76 -55
- package/src/commands/harden.js +105 -86
- package/src/commands/hu-start.js +52 -0
- package/src/commands/hu.js +288 -221
- package/src/commands/identity.js +111 -78
- package/src/commands/init-atril.js +47 -0
- package/src/commands/init.js +11 -40
- package/src/commands/install-tools.js +70 -85
- package/src/commands/main-guard.js +78 -0
- package/src/commands/policy.js +226 -184
- package/src/commands/qmd.js +27 -21
- package/src/commands/rag.js +75 -48
- package/src/commands/review-gate.js +422 -339
- package/src/commands/start.js +4 -5
- package/src/commands/steward.js +96 -47
- package/src/commands/tournament.js +46 -37
- package/src/commands/worktree.js +94 -25
- package/src/config/loader.js +34 -17
- package/src/config/overrides.js +2 -1
- package/src/config/secrets.js +36 -0
- package/src/config.js +1 -0
- package/src/environment/adr.js +16 -2
- package/src/environment/board-access.js +11 -9
- package/src/git/karajan-label.js +20 -8
- package/src/guards/main-guard.js +54 -0
- package/src/harden/branch-protection.js +36 -3
- package/src/harden/hook-templates.js +16 -1
- package/src/harden/sentinel/posttooluse.mjs +18 -6
- package/src/harden/sentinel/pretooluse-sentinel.mjs +81 -35
- package/src/harden/sentinel/sentinel-lib.mjs +149 -23
- package/src/harden/sentinel/sentinel-shell.mjs +64 -0
- package/src/harden/sentinel/sessionstart.mjs +3 -2
- package/src/harden/sentinel/stop.mjs +5 -4
- package/src/harden/workflow-engine.js +12 -1
- package/src/harden/workflow-templates.js +1 -1
- package/src/hu/board-lookup.js +29 -0
- package/src/hu/gh-identity.js +23 -0
- package/src/hu/github-board.js +4 -2
- package/src/hu/lane-prune.js +15 -7
- package/src/hu/lane-setup.js +65 -0
- package/src/hu/lanes.js +66 -0
- package/src/hu/team-board-mirror.js +3 -2
- package/src/infrastructure/command-runner.js +1 -1
- package/src/infrastructure/file-system-service.js +1 -1
- package/src/mcp/handlers/direct-handlers.js +2 -292
- package/src/mcp/handlers/hu-handlers.js +44 -55
- package/src/mcp/handlers/management-handlers.js +2 -42
- package/src/mcp/server-handlers.js +16 -22
- package/src/mcp/tools.js +5 -200
- package/src/plan/lane-plans.js +54 -0
- package/src/plan/plan-store.js +7 -4
- package/src/policy/add.js +26 -12
- package/src/policy/adr-number-check.js +31 -0
- package/src/prompts/audit.js +299 -339
- package/src/prompts/card-context.js +10 -5
- package/src/prompts/reviewer.js +5 -2
- package/src/rag/auto-update.js +56 -43
- package/src/rag/bootstrap-index.js +28 -54
- package/src/rag/migrate.js +1 -1
- package/src/rag/onnx-fallback.js +2 -2
- package/src/rag/pid-lease.js +70 -0
- package/src/rag/project-store.js +2 -12
- package/src/review/card-first.js +57 -46
- package/src/review/dual-review.js +5 -4
- package/src/review/gate-gitignore.js +23 -4
- package/src/review/gate-hook.js +47 -0
- package/src/review/one-shot-review.js +51 -37
- package/src/review/publish-pr.js +18 -3
- package/src/review/repo-docs.js +73 -0
- package/src/review/repo-stack.js +59 -0
- package/src/review/reviewer-fallback.js +34 -3
- package/src/review/seal-commit.js +29 -0
- package/src/review/sonar-pregate.js +59 -44
- package/src/review/third-party-review.js +90 -16
- package/src/review/third-party-size.js +43 -0
- package/src/review/third-party-skills.js +54 -0
- package/src/review/verify-pr.js +2 -26
- package/src/roles/audit-role.js +106 -125
- package/src/skills/atril-skills.js +5 -4
- package/src/sonar/scanner.js +116 -101
- package/src/steward/invariants.js +5 -4
- package/src/steward/phantom-sweep.js +66 -0
- package/src/tournament/judge.js +60 -53
- package/src/utils/agent-home.js +33 -0
- package/src/utils/gh-account.js +37 -0
- package/src/utils/git.js +0 -13
- package/src/utils/home-migration.js +7 -1
- package/src/utils/main-checkout.js +53 -0
- package/src/utils/qmd-collection.js +3 -1
- package/src/utils/welcome.js +3 -3
- package/templates/{skills → atril/commands}/kj-architect.md +5 -0
- package/templates/{skills → atril/commands}/kj-audit.md +5 -0
- package/templates/{skills → atril/commands}/kj-board.md +5 -0
- package/templates/{skills → atril/commands}/kj-code.md +5 -0
- package/templates/{skills → atril/commands}/kj-csv-transform.md +5 -0
- package/templates/{skills → atril/commands}/kj-data-report.md +5 -0
- package/templates/{skills → atril/commands}/kj-discover.md +5 -0
- package/templates/{skills → atril/commands}/kj-rag-query.md +5 -0
- package/templates/{skills → atril/commands}/kj-review.md +5 -0
- package/templates/{skills → atril/commands}/kj-security.md +5 -0
- package/templates/{skills → atril/commands}/kj-sonar.md +5 -0
- package/templates/{skills → atril/commands}/kj-sql-analysis.md +5 -0
- package/templates/{skills → atril/commands}/kj-test.md +5 -0
- package/packages/hu-board/public/utils/run-launcher.js +0 -169
- package/packages/hu-board/src/run-tracker.js +0 -121
- package/src/activity-log.js +0 -59
- package/src/agents/host-agent.js +0 -38
- package/src/agents/model-registry.js +0 -142
- package/src/audit/plan-adherence.js +0 -224
- package/src/autonomy/arbiter-role.js +0 -71
- package/src/autonomy/arbiter.js +0 -22
- package/src/autonomy/decider.js +0 -18
- package/src/autonomy/decision-resolver.js +0 -58
- package/src/autonomy/outcome-report.js +0 -55
- package/src/autonomy/stage-ask.js +0 -30
- package/src/brain/decision-tracker.js +0 -125
- package/src/brain/decisor.js +0 -243
- package/src/brain/solomon-consult.js +0 -171
- package/src/brain/standby-scheduler.js +0 -8
- package/src/budget/comparison.js +0 -96
- package/src/canvas/parse-md.js +0 -238
- package/src/canvas/schema.js +0 -101
- package/src/canvas/to-flat.js +0 -85
- package/src/canvas/validate.js +0 -163
- package/src/ci/dispatch.js +0 -99
- package/src/ci/index.js +0 -3
- package/src/ci/pr-diff.js +0 -26
- package/src/cli/register-standby.js +0 -26
- package/src/commands/architect.js +0 -111
- package/src/commands/autorun.js +0 -49
- package/src/commands/researcher.js +0 -54
- package/src/commands/resume.js +0 -72
- package/src/commands/review.js +0 -89
- package/src/commands/run.js +0 -185
- package/src/commands/standby.js +0 -117
- package/src/commands/status.js +0 -36
- package/src/commands/triage.js +0 -78
- package/src/commands/undo.js +0 -62
- package/src/domains/domain-loader.js +0 -245
- package/src/domains/domain-registry.js +0 -140
- package/src/domains/domain-synthesizer.js +0 -129
- package/src/git/automation.js +0 -433
- package/src/git/coder-commit-guard.js +0 -40
- package/src/git/hu-automation.js +0 -243
- package/src/git/hu-snapshot.js +0 -10
- package/src/git/symlink-targets.js +0 -57
- package/src/golden/asserter.js +0 -92
- package/src/golden/loader.js +0 -52
- package/src/golden/runner.js +0 -92
- package/src/golden/schema.js +0 -41
- package/src/guards/duplicate-members.js +0 -86
- package/src/guards/intent-guard.js +0 -161
- package/src/guards/perf-guard.js +0 -126
- package/src/guards/policy-guard.js +0 -90
- package/src/guards/policy-resolver.js +0 -85
- package/src/guards/secret-redactor.js +0 -71
- package/src/hu/acceptance-runner.js +0 -138
- package/src/hu/lazy-planner.js +0 -109
- package/src/hu/parallel-executor.js +0 -94
- package/src/hu/routing-metrics.js +0 -17
- package/src/hu/split-validator.js +0 -143
- package/src/hu/splitting-detector.js +0 -158
- package/src/hu/splitting-generator.js +0 -175
- package/src/hu/store.js +0 -394
- package/src/infrastructure/mocks.js +0 -182
- package/src/mcp/handlers/run-handler.js +0 -318
- package/src/mcp/sovereignty-guard.js +0 -113
- package/src/mcp/tool-arg-normalizers.js +0 -16
- package/src/mutate/reviewer-signal.js +0 -76
- package/src/orchestrator/agent-fallback.js +0 -81
- package/src/orchestrator/brain-coordinator.js +0 -186
- package/src/orchestrator/ci-integration.js +0 -139
- package/src/orchestrator/config-init.js +0 -426
- package/src/orchestrator/direct-actions.js +0 -217
- package/src/orchestrator/drivers/error-recovery.js +0 -287
- package/src/orchestrator/drivers/init-context.js +0 -238
- package/src/orchestrator/drivers/iteration-loop.js +0 -382
- package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +0 -69
- package/src/orchestrator/drivers/iteration-phases/guards.js +0 -91
- package/src/orchestrator/drivers/iteration-phases/handle-approved.js +0 -29
- package/src/orchestrator/drivers/iteration-phases/quality-gates.js +0 -125
- package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +0 -62
- package/src/orchestrator/drivers/post-loop.js +0 -404
- package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +0 -137
- package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +0 -47
- package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +0 -84
- package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +0 -393
- package/src/orchestrator/drivers/pre-loop.js +0 -524
- package/src/orchestrator/drivers/run-hu-batch.js +0 -468
- package/src/orchestrator/feedback-enrichment.js +0 -140
- package/src/orchestrator/feedback-queue.js +0 -151
- package/src/orchestrator/flow-control.js +0 -170
- package/src/orchestrator/flow-runner.js +0 -365
- package/src/orchestrator/fs-leak-detector.js +0 -228
- package/src/orchestrator/hu-scheduler.js +0 -114
- package/src/orchestrator/hu-sub-pipeline.js +0 -642
- package/src/orchestrator/iteration-gate.js +0 -73
- package/src/orchestrator/iteration-stages.js +0 -9
- package/src/orchestrator/parallel-limiter.js +0 -74
- package/src/orchestrator/pipeline-context.js +0 -72
- package/src/orchestrator/post-loop-stages.js +0 -468
- package/src/orchestrator/pre-loop-stages.js +0 -11
- package/src/orchestrator/preflight-checks.js +0 -487
- package/src/orchestrator/repair/repair-detector.js +0 -117
- package/src/orchestrator/repair/repair-runner.js +0 -142
- package/src/orchestrator/reviewer-fallback.js +0 -45
- package/src/orchestrator/role-output-compressor.js +0 -189
- package/src/orchestrator/session-journal.js +0 -308
- package/src/orchestrator/solomon-escalation.js +0 -331
- package/src/orchestrator/solomon-rules.js +0 -212
- package/src/orchestrator/stages/acceptance-coverage-stage.js +0 -47
- package/src/orchestrator/stages/architect-stage.js +0 -172
- package/src/orchestrator/stages/coder-stage.js +0 -506
- package/src/orchestrator/stages/domain-curator-stage.js +0 -82
- package/src/orchestrator/stages/format-stage.js +0 -61
- package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +0 -127
- package/src/orchestrator/stages/hu-reviewer-stage.js +0 -419
- package/src/orchestrator/stages/perf-stage.js +0 -140
- package/src/orchestrator/stages/planner-stage.js +0 -85
- package/src/orchestrator/stages/rag-context-stage.js +0 -80
- package/src/orchestrator/stages/rag-preload-decisor.js +0 -58
- package/src/orchestrator/stages/research-stage.js +0 -69
- package/src/orchestrator/stages/reviewer-stage.js +0 -431
- package/src/orchestrator/stages/sonar-stage.js +0 -439
- package/src/orchestrator/stages/stage-classes.js +0 -84
- package/src/orchestrator/stages/stage-executor.js +0 -155
- package/src/orchestrator/stages/suite-green-stage.js +0 -62
- package/src/orchestrator/stages/tdd-discipline-stage.js +0 -56
- package/src/orchestrator/stages/tool-judge-stage.js +0 -53
- package/src/orchestrator/stages/triage-stage.js +0 -172
- package/src/orchestrator/standby.js +0 -71
- package/src/orchestrator/verification-gate.js +0 -183
- package/src/orchestrator.js +0 -22
- package/src/plan/adr-generator.js +0 -170
- package/src/plan/adr-loader.js +0 -60
- package/src/plan/plan-executor.js +0 -100
- package/src/plan/plan-validation.js +0 -4
- package/src/prompts/acceptance-coverage.js +0 -32
- package/src/prompts/arbiter.js +0 -38
- package/src/prompts/architect.js +0 -103
- package/src/prompts/hu-reviewer.js +0 -244
- package/src/prompts/tool-correctness-judge.js +0 -31
- package/src/prompts/triage.js +0 -57
- package/src/rag/embedder.js +0 -2
- package/src/rag/embedders/_cloud-base.js +0 -2
- package/src/rag/embedders/cohere.js +0 -2
- package/src/rag/embedders/mistral.js +0 -2
- package/src/rag/embedders/onnx.js +0 -2
- package/src/rag/embedders/openai.js +0 -2
- package/src/rag/embedders/voyage.js +0 -2
- package/src/rag/rerank.js +0 -4
- package/src/rag/where-parser.js +0 -4
- package/src/repeat-detector.js +0 -88
- package/src/review/diff-generator.js +0 -112
- package/src/review/git-stash-helper.js +0 -104
- package/src/review/schema.js +0 -31
- package/src/review/scope-filter.js +0 -152
- package/src/review/snapshot-diff.js +0 -122
- package/src/review/tdd-discipline.js +0 -90
- package/src/review/tdd-policy.js +0 -69
- package/src/roles/acceptance-coverage-role.js +0 -78
- package/src/roles/architect-role.js +0 -77
- package/src/roles/coder-role.js +0 -113
- package/src/roles/commiter-role.js +0 -113
- package/src/roles/domain-curator-role.js +0 -134
- package/src/roles/hu-reviewer-role.js +0 -64
- package/src/roles/impeccable-role.js +0 -85
- package/src/roles/index.js +0 -18
- package/src/roles/karajan-brain-role.js +0 -134
- package/src/roles/perf-role.js +0 -122
- package/src/roles/planner-role.js +0 -151
- package/src/roles/refactorer-role.js +0 -30
- package/src/roles/repairer-role.js +0 -181
- package/src/roles/researcher-role.js +0 -70
- package/src/roles/reviewer-role.js +0 -115
- package/src/roles/security-role.js +0 -73
- package/src/roles/solomon-role.js +0 -271
- package/src/roles/sonar-role.js +0 -72
- package/src/roles/tester-role.js +0 -235
- package/src/roles/tool-correctness-judge-role.js +0 -78
- package/src/roles/triage-role.js +0 -99
- package/src/session/journal/decisions-writer.js +0 -200
- package/src/session/journal/iteration-logger.js +0 -194
- package/src/session/journal/summary-writer.js +0 -320
- package/src/session/journal/tree-writer.js +0 -164
- package/src/session/journal/write-all.js +0 -89
- package/src/session-cleanup.js +0 -116
- package/src/skills/semantic-detector.js +0 -167
- package/src/skills/skill-detector.js +0 -385
- package/src/sonar/cloud-scanner.js +0 -78
- package/src/tracker-bootstrap.js +0 -44
- package/src/types/index.js +0 -38
- package/src/types/policy.js +0 -43
- package/src/types/solomon.js +0 -87
- package/src/utils/async-lock.js +0 -31
- package/src/utils/budget.js +0 -229
- package/src/utils/cwd-confirm.js +0 -39
- package/src/utils/display/event-handlers.js +0 -403
- package/src/utils/display/formatters.js +0 -132
- package/src/utils/display/header.js +0 -47
- package/src/utils/display/session-summary.js +0 -118
- package/src/utils/display/solomon.js +0 -42
- package/src/utils/pricing.js +0 -29
- package/src/utils/quota-simulator.js +0 -56
- package/src/utils/role-assigner.js +0 -137
- package/src/utils/rtk-wrapper.js +0 -87
- package/src/utils/run-registry.js +0 -9
- package/src/utils/status-dashboard.js +0 -254
- package/src/utils/tool-call-extractor.js +0 -56
- package/src/webperf/devtools-detect.js +0 -112
- package/src/webperf/webperf-role-integration.js +0 -66
- package/templates/skills/kj-run.md +0 -73
package/src/cli/register-meta.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { discoverCommand } from "../commands/discover.js";
|
|
2
2
|
import { specRefineCommand } from "../commands/spec-refine.js";
|
|
3
|
-
import {
|
|
4
|
-
import { researcherCommand } from "../commands/researcher.js";
|
|
5
|
-
import { architectCommand } from "../commands/architect.js";
|
|
3
|
+
import { writeSbom } from "../audit/sbom.js";
|
|
6
4
|
import { onboardCommand } from "../commands/onboard.js";
|
|
7
5
|
import { startCommand } from "../commands/start.js";
|
|
8
6
|
import { goCommand } from "../commands/go.js";
|
|
@@ -19,10 +17,8 @@ import { qmdQueryCommand } from "../commands/qmd.js";
|
|
|
19
17
|
import { ragMcpCommand } from "../commands/rag-mcp.js";
|
|
20
18
|
import { watchStartCommand, watchStopCommand, watchStatusCommand } from "../commands/watch.js";
|
|
21
19
|
import { auditCommand } from "../commands/audit.js";
|
|
22
|
-
import { resumeCommand } from "../commands/resume.js";
|
|
23
20
|
import { boardCommand } from "../commands/board.js";
|
|
24
21
|
import { webperfCommand } from "../commands/webperf.js";
|
|
25
|
-
import { undoCommand } from "../commands/undo.js";
|
|
26
22
|
import { syncCommand } from "../commands/sync.js";
|
|
27
23
|
import { cleanCommand } from "../commands/clean.js";
|
|
28
24
|
import { checkCommand } from "../commands/check.js";
|
|
@@ -106,54 +102,6 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
106
102
|
});
|
|
107
103
|
});
|
|
108
104
|
|
|
109
|
-
program
|
|
110
|
-
.command("triage")
|
|
111
|
-
.description("Classify task complexity and recommend pipeline roles")
|
|
112
|
-
.argument("[task]", "Task description (REQUIRED — provide as argument or via --task-file)")
|
|
113
|
-
.option("--task-file <path>", "Read the task from a file (e.g. .md)")
|
|
114
|
-
.option("--triage <name>", "Override triage agent")
|
|
115
|
-
.option("--triage-model <name>", "Override triage model")
|
|
116
|
-
.option("--json", "Output raw JSON")
|
|
117
|
-
.action(async (task, flags) => {
|
|
118
|
-
await withConfig(pkgVersion, "triage", flags, async ({ config, logger }) => {
|
|
119
|
-
const { resolveTaskInput } = await import("../utils/task-file.js");
|
|
120
|
-
const resolvedTask = await resolveTaskInput({ task, taskFile: flags.taskFile, projectDir: config.projectDir, logger, indexFirstBytes: config.docs?.indexFirstBytes });
|
|
121
|
-
await triageCommand({ task: resolvedTask, config, logger, json: flags.json });
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
program
|
|
126
|
-
.command("researcher")
|
|
127
|
-
.description("Research codebase for a task (files, patterns, constraints)")
|
|
128
|
-
.argument("[task]", "Task description (REQUIRED — provide as argument or via --task-file)")
|
|
129
|
-
.option("--task-file <path>", "Read the task from a file (e.g. .md)")
|
|
130
|
-
.option("--researcher <name>", "Override researcher agent")
|
|
131
|
-
.option("--researcher-model <name>", "Override researcher model")
|
|
132
|
-
.action(async (task, flags) => {
|
|
133
|
-
await withConfig(pkgVersion, "researcher", flags, async ({ config, logger }) => {
|
|
134
|
-
const { resolveTaskInput } = await import("../utils/task-file.js");
|
|
135
|
-
const resolvedTask = await resolveTaskInput({ task, taskFile: flags.taskFile, projectDir: config.projectDir, logger, indexFirstBytes: config.docs?.indexFirstBytes });
|
|
136
|
-
await researcherCommand({ task: resolvedTask, config, logger });
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
program
|
|
141
|
-
.command("architect")
|
|
142
|
-
.description("Design solution architecture (layers, patterns, contracts)")
|
|
143
|
-
.argument("[task]", "Task description (REQUIRED — provide as argument or via --task-file)")
|
|
144
|
-
.option("--task-file <path>", "Read the task from a file (e.g. .md)")
|
|
145
|
-
.option("--architect <name>", "Override architect agent")
|
|
146
|
-
.option("--architect-model <name>", "Override architect model")
|
|
147
|
-
.option("--context <text>", "Additional context (e.g. researcher output)")
|
|
148
|
-
.option("--json", "Output raw JSON")
|
|
149
|
-
.action(async (task, flags) => {
|
|
150
|
-
await withConfig(pkgVersion, "architect", flags, async ({ config, logger }) => {
|
|
151
|
-
const { resolveTaskInput } = await import("../utils/task-file.js");
|
|
152
|
-
const resolvedTask = await resolveTaskInput({ task, taskFile: flags.taskFile, projectDir: config.projectDir, logger, indexFirstBytes: config.docs?.indexFirstBytes });
|
|
153
|
-
await architectCommand({ task: resolvedTask, config, logger, context: flags.context, json: flags.json });
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
105
|
program
|
|
158
106
|
.command("onboard")
|
|
159
107
|
.description("Analyze an existing codebase (brownfield) and produce an Architecture Brief")
|
|
@@ -317,7 +265,7 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
317
265
|
// beats ordering a practice an agent can narrate without doing.
|
|
318
266
|
const wt = program.command("worktree").description("Isolated task lanes (git worktrees) for the host agent");
|
|
319
267
|
wt.command("start <slug>")
|
|
320
|
-
.description("Create a lane: worktree + feat/<slug> branch + dependency bootstrap")
|
|
268
|
+
.description("Create a lane: worktree + feat/<slug> branch from origin/<base> + dependency bootstrap")
|
|
321
269
|
.action(async (slug, flags) => {
|
|
322
270
|
await withConfig(pkgVersion, "worktree", flags, async ({ config }) => {
|
|
323
271
|
await worktreeCommand({ config, action: "start", args: [slug], flags });
|
|
@@ -325,14 +273,16 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
325
273
|
});
|
|
326
274
|
wt.command("list")
|
|
327
275
|
.description("List the active lanes")
|
|
276
|
+
.option("--json", "Each lane with its commits ahead of the base and the cards its branch names")
|
|
277
|
+
.option("--prs", "With --json, each lane's PR (one gh call)")
|
|
328
278
|
.action(async (flags) => {
|
|
329
279
|
await withConfig(pkgVersion, "worktree", flags, async ({ config }) => {
|
|
330
280
|
await worktreeCommand({ config, action: "list", flags });
|
|
331
281
|
});
|
|
332
282
|
});
|
|
333
283
|
wt.command("done <slug>")
|
|
334
|
-
.option("--force", "Remove the lane even with uncommitted changes")
|
|
335
|
-
.description("Remove a merged
|
|
284
|
+
.option("--force", "Remove the lane even with uncommitted changes, and delete its branch even if not merged")
|
|
285
|
+
.description("Remove a lane and delete its branch when merged into the base (refuses uncommitted changes without --force)")
|
|
336
286
|
.action(async (slug, flags) => {
|
|
337
287
|
await withConfig(pkgVersion, "worktree", flags, async ({ config }) => {
|
|
338
288
|
await worktreeCommand({ config, action: "done", args: [slug], flags });
|
|
@@ -372,6 +322,16 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
372
322
|
await huCommand({ config, action: "move", args: [id, status], flags });
|
|
373
323
|
});
|
|
374
324
|
});
|
|
325
|
+
// KJC-TSK-1372 (#2853): one step to start a task: card, lane, running.
|
|
326
|
+
hu.command("start <id> [slug]")
|
|
327
|
+
.description("Start a card: open its lane feat/<id>-<slug> from origin/<base> and move it to running (slug from the title if omitted)")
|
|
328
|
+
.option("--code", "Then have the panel coder write the card in the lane (kj code --card)")
|
|
329
|
+
.option("--json", "Machine-readable output")
|
|
330
|
+
.action(async (id, slug, flags) => {
|
|
331
|
+
await withConfig(pkgVersion, "hu", flags, async ({ config }) => {
|
|
332
|
+
await huCommand({ config, action: "start", args: [id, slug].filter(Boolean), flags });
|
|
333
|
+
});
|
|
334
|
+
});
|
|
375
335
|
hu.command("list")
|
|
376
336
|
.option("--json", "Machine-readable output")
|
|
377
337
|
.action(async (flags) => {
|
|
@@ -801,6 +761,19 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
801
761
|
});
|
|
802
762
|
});
|
|
803
763
|
|
|
764
|
+
// KJC-TSK-1369 (ADR 0037): the audit job on every push to the protected branch.
|
|
765
|
+
program.command("main-guard")
|
|
766
|
+
.description("Audit a push to the protected branch: merges without their required checks, and the protection (exit 1 with a markdown report)")
|
|
767
|
+
.requiredOption("--repo <owner/repo>", "GitHub repository")
|
|
768
|
+
.requiredOption("--before <sha>", "The branch tip before the push")
|
|
769
|
+
.requiredOption("--after <sha>", "The branch tip after the push")
|
|
770
|
+
.requiredOption("--require <checks...>", "Required checks that every merge must have passed")
|
|
771
|
+
.option("--branch <name>", "Protected branch", "main")
|
|
772
|
+
.action(async (flags) => {
|
|
773
|
+
const { mainGuardCommand } = await import("../commands/main-guard.js");
|
|
774
|
+
await mainGuardCommand({ flags });
|
|
775
|
+
});
|
|
776
|
+
|
|
804
777
|
const rag = program.command("rag").description("Retrieval-augmented search over Karajan plans, onboarding briefs and project code");
|
|
805
778
|
rag.command("index")
|
|
806
779
|
.description("Index plans + onboarding (and optionally project sources) into the local vector store")
|
|
@@ -947,8 +920,21 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
947
920
|
.option("--deterministic-only", "Skip the LLM analysis entirely. Print/persist only the deterministic findings (basalCost, sonar, stack, growth-delta, webperf). Zero tokens spent. Compatible with --report-file and --json.")
|
|
948
921
|
.option("--security", "Focused deterministic security pass: prompt-injection scan over the agent-context surface (CLAUDE.md/AGENTS.md/templates/.rulesync/.karajan) + OSV + Semgrep + Sonar. Skips basal-cost, webperf, madge, knip, ai-slop, harness and the LLM — zero tokens. Designed for agents to self-invoke when a task touches sensitive surface (KJC-TSK-0695).")
|
|
949
922
|
.option("-y, --yes", "Auto-confirm the 'Continue with LLM analysis?' prompt. Useful in scripts that want the full audit non-interactively. CI/non-TTY paths already auto-confirm without this flag.")
|
|
923
|
+
.option("--sbom <file>", "Only write the CycloneDX SBOM of the npm project's production dependencies to <file> (from package-lock.json) and stop. KJC-TSK-1255.")
|
|
950
924
|
.action(async (task, flags) => {
|
|
951
925
|
await withConfig(pkgVersion, "audit", flags, async ({ config, logger }) => {
|
|
926
|
+
if (flags.sbom) {
|
|
927
|
+
try {
|
|
928
|
+
const res = await writeSbom({ projectDir: config.projectDir || process.cwd(), file: flags.sbom });
|
|
929
|
+
if (flags.json) console.log(JSON.stringify(res));
|
|
930
|
+
else console.log(`SBOM (CycloneDX, ${res.components} components): ${res.file}`);
|
|
931
|
+
} catch (err) {
|
|
932
|
+
if (flags.json) console.log(JSON.stringify({ error: err.message }));
|
|
933
|
+
else logger.error(err.message);
|
|
934
|
+
process.exitCode = 1;
|
|
935
|
+
}
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
952
938
|
let resolvedTask = task;
|
|
953
939
|
if (flags.taskFile) {
|
|
954
940
|
const { readTaskFile } = await import("../utils/task-file.js");
|
|
@@ -997,21 +983,6 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
997
983
|
});
|
|
998
984
|
});
|
|
999
985
|
|
|
1000
|
-
program
|
|
1001
|
-
.command("resume")
|
|
1002
|
-
.description("Resume a paused session")
|
|
1003
|
-
.argument("<sessionId>")
|
|
1004
|
-
.option("--answer <text>", "Answer to the question that caused the pause")
|
|
1005
|
-
.option("--non-interactive", "Agents/CI: auto-answer prompts with their safe defaults; stop when there is none. Also enabled by KJ_NON_INTERACTIVE=1.")
|
|
1006
|
-
.option("--json", "Output JSON only")
|
|
1007
|
-
.action(async (sessionId, flags) => {
|
|
1008
|
-
await withConfig(pkgVersion, "resume", flags, async ({ config, logger }) => {
|
|
1009
|
-
const res = await resumeCommand({ sessionId, answer: flags.answer, config, logger, flags });
|
|
1010
|
-
// KJC-TSK-0674 (issue #1289): same contract as kj run — an aborted
|
|
1011
|
-
// resume must be observable by CI.
|
|
1012
|
-
if (res?.aborted) process.exitCode = 1;
|
|
1013
|
-
});
|
|
1014
|
-
});
|
|
1015
986
|
|
|
1016
987
|
program
|
|
1017
988
|
.command("update")
|
|
@@ -1061,17 +1032,6 @@ export function registerMeta(program, { pkgVersion }) {
|
|
|
1061
1032
|
});
|
|
1062
1033
|
});
|
|
1063
1034
|
|
|
1064
|
-
program
|
|
1065
|
-
.command("undo")
|
|
1066
|
-
.description("Revert last pipeline run")
|
|
1067
|
-
.option("--hard", "Discard all changes (default: soft reset, keeps changes staged)")
|
|
1068
|
-
.action(async (flags) => {
|
|
1069
|
-
await withConfig(pkgVersion, "undo", flags, async ({ logger }) => {
|
|
1070
|
-
const result = await undoCommand({ hard: !!flags.hard, logger });
|
|
1071
|
-
if (!result.ok) process.exit(1);
|
|
1072
|
-
});
|
|
1073
|
-
});
|
|
1074
|
-
|
|
1075
1035
|
program
|
|
1076
1036
|
.command("sync")
|
|
1077
1037
|
.description("Detect drift between code and the latest plan. Read-only by default; --apply writes a patch back to the Canvas.")
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { initCommand } from "../commands/init.js";
|
|
2
2
|
import { ollamaStartCommand, ollamaStopCommand, ollamaStatusCommand, ollamaPullCommand } from "../commands/ollama.js";
|
|
3
3
|
import { configCommand } from "../commands/config.js";
|
|
4
|
+
import { checkSecretsCommand } from "../config/secrets.js";
|
|
4
5
|
import { codeCommand } from "../commands/code.js";
|
|
5
|
-
import {
|
|
6
|
+
import { retire } from "./retired-commands.js";
|
|
6
7
|
import { tournamentCommand } from "../commands/tournament.js";
|
|
7
8
|
import { resolveTaskInput } from "../utils/task-file.js";
|
|
8
9
|
import { reviewGateCommand, solomonCommand } from "../commands/review-gate.js";
|
|
@@ -10,9 +11,6 @@ import { scanCommand } from "../commands/scan.js";
|
|
|
10
11
|
import { installToolsCommand } from "../commands/install-tools.js";
|
|
11
12
|
import { doctorCommand } from "../commands/doctor.js";
|
|
12
13
|
import { reportCommand } from "../commands/report.js";
|
|
13
|
-
import { runCommandHandler } from "../commands/run.js";
|
|
14
|
-
import { statusCommand } from "../commands/status.js";
|
|
15
|
-
import { loadPlan } from "../plan/plan-store.js";
|
|
16
14
|
import { withConfig } from "./_shared.js";
|
|
17
15
|
import { publishPrReview } from "../review/publish-pr.js";
|
|
18
16
|
import { verifyPrReview } from "../review/verify-pr.js";
|
|
@@ -52,136 +50,15 @@ export function registerPipeline(program, { pkgVersion }) {
|
|
|
52
50
|
.description("Show current config")
|
|
53
51
|
.option("--json", "Show as JSON")
|
|
54
52
|
.option("--edit", "Open config in $EDITOR for editing")
|
|
53
|
+
.option("--check-secrets <file>", "Exit 1 when a project kj.config.yml (or - for stdin) holds a secret (ADR 0032)")
|
|
55
54
|
.action(async (flags) => {
|
|
55
|
+
if (flags.checkSecrets) return checkSecretsCommand(flags.checkSecrets);
|
|
56
56
|
await configCommand(flags);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
program
|
|
60
|
-
.command("run")
|
|
61
|
-
.description("Run coder+sonar+reviewer loop")
|
|
62
|
-
.argument("[task]", "Task description (REQUIRED — provide as argument or via --task-file)")
|
|
63
|
-
.option("--task-file <path>", "Read the task from a file (e.g. .md). Alternative to the positional task argument.")
|
|
64
|
-
.option("-y, --yes", "Skip the cwd confirmation prompt (CI / scripted runs).")
|
|
65
|
-
.option("--non-interactive", "Agents/CI: auto-answer prompts with their safe defaults (warn → continue) and stop with exit code 1 when there is none (fail). Also enabled by KJ_NON_INTERACTIVE=1.")
|
|
66
|
-
.option("--planner <name>")
|
|
67
|
-
.option("--coder <name>")
|
|
68
|
-
.option("--reviewer <name>")
|
|
69
|
-
.option("--refactorer <name>")
|
|
70
|
-
.option("--planner-model <name>")
|
|
71
|
-
.option("--coder-model <name>")
|
|
72
|
-
.option("--reviewer-model <name>")
|
|
73
|
-
.option("--refactorer-model <name>")
|
|
74
|
-
.option("--profile <name>", "Model profile for every role without an explicit model: frugal | standard | deep (the reviewer never goes below standard)")
|
|
75
|
-
.option("--enable-planner")
|
|
76
|
-
.option("--enable-reviewer")
|
|
77
|
-
.option("--enable-refactorer")
|
|
78
|
-
.option("--enable-researcher")
|
|
79
|
-
.option("--enable-tester")
|
|
80
|
-
.option("--enable-security")
|
|
81
|
-
.option("--enable-impeccable")
|
|
82
|
-
.option("--enable-perf")
|
|
83
|
-
.option("--enable-triage")
|
|
84
|
-
.option("--enable-discover")
|
|
85
|
-
.option("--enable-architect")
|
|
86
|
-
.option("--plan <planId>", "Plan ID from kj plan. Loads persisted plan context and skips researcher/architect/planner.")
|
|
87
|
-
// PR4: launch a single HU (or comma-separated list) instead of the
|
|
88
|
-
// entire plan. The board uses this for the per-HU ▶ button so the
|
|
89
|
-
// user can re-run only a failed HU without restarting the whole
|
|
90
|
-
// plan. Requires --plan to also be set.
|
|
91
|
-
.option("--hu <huIds>", "Comma-separated HU IDs to run. When set, the plan's other HUs are skipped. Requires --plan.")
|
|
92
|
-
.option("--enable-hu-reviewer")
|
|
93
|
-
.option("--hu-file <path>", "YAML file with HU stories to certify before coding")
|
|
94
|
-
.option("--enable-serena")
|
|
95
|
-
.option("--mode <name>")
|
|
96
|
-
.option("--max-iterations <n>")
|
|
97
|
-
.option("--max-iteration-minutes <n>")
|
|
98
|
-
.option("--max-total-minutes <n>")
|
|
99
|
-
.option("--base-branch <name>")
|
|
100
|
-
.option("--base-ref <ref>")
|
|
101
|
-
.option("--coder-fallback <name>")
|
|
102
|
-
.option("--reviewer-fallback <name>")
|
|
103
|
-
.option("--reviewer-retries <n>")
|
|
104
|
-
.option("--auto-commit")
|
|
105
|
-
.option("--auto-push")
|
|
106
|
-
.option("--auto-pr")
|
|
107
|
-
.option("--enable-ci", "Enable Karajan CI (early PR + dispatch comments/reviews)")
|
|
108
|
-
.option("--branch-prefix <prefix>")
|
|
109
|
-
.option("--task-type <type>", "Explicit task type: sw, infra, doc, add-tests, refactor")
|
|
110
|
-
.option("--methodology <name>")
|
|
111
|
-
.option("--no-auto-rebase")
|
|
112
|
-
.option("--no-sonar")
|
|
113
|
-
.option("--enable-sonarcloud", "Enable SonarCloud scan (complementary to SonarQube)")
|
|
114
|
-
.option("--no-sonarcloud")
|
|
115
|
-
.option("--checkpoint-interval <n>", "Minutes between interactive checkpoints (default: 5)")
|
|
116
|
-
.option("--step", "Pause after each iteration with a report and ask before continuing")
|
|
117
|
-
.option("--parallel <n>", "Concurrent HU lanes for plan runs (default: 1, sequential)")
|
|
118
|
-
.option("--pg-task <cardId>", "Planning Game card ID (e.g., KJC-TSK-0042)")
|
|
119
|
-
.option("--pg-project <projectId>", "Planning Game project ID")
|
|
120
|
-
.option("--auto-simplify", "Auto-simplify pipeline for simple tasks (disable reviewer/tester)")
|
|
121
|
-
.option("--no-auto-simplify", "Force full pipeline regardless of triage level")
|
|
122
|
-
.option("--smart-models", "Enable smart model selection based on triage complexity")
|
|
123
|
-
.option("--no-smart-models", "Disable smart model selection")
|
|
124
|
-
.option("--design", "Activate design refactoring mode (impeccable role applies design changes)")
|
|
125
|
-
.option("--domain <text-or-path>", "Domain knowledge: inline text or path to .md file")
|
|
126
|
-
.option("--skills-mode <mode>", "Skill detection mode: auto|regex|semantic|none (default: auto)")
|
|
127
|
-
.option("--brain <mode>", "Brain decisor: on|off (default: on). When off, only legacy flags drive routing.")
|
|
128
|
-
.option("--skip-role <role...>", "Force one or more roles OFF regardless of triage (e.g. --skip-role tester security)")
|
|
129
|
-
.option("--force-role <role...>", "Force one or more roles ON regardless of triage")
|
|
130
|
-
.option("--skip-spec-review", "Bypass the spec-reviewer pre-pipeline audit")
|
|
131
|
-
.option("--autonomy <level>", "Autonomy level: interactive | assisted | autonomous (default: interactive)")
|
|
132
|
-
.option("--autonomous", "Shortcut for --autonomy autonomous: the Arbiter resolves every gate, no human prompts")
|
|
133
|
-
.option("--no-rag-update", "Skip the pre-run RAG drift check (KJC-TSK-0455). Same as config.rag.autoUpdate.onRun=false.")
|
|
134
|
-
.option("--dry-run", "Show what would be executed without running anything")
|
|
135
|
-
.option("--json", "Output JSON only (no styled display)")
|
|
136
|
-
.option("-q, --quiet", "Show only stage status lines, suppress raw agent output (default)")
|
|
137
|
-
.option("-v, --verbose", "Show full agent output (stream-json, raw lines)")
|
|
138
|
-
.action(async (task, flags) => {
|
|
139
|
-
await withConfig(pkgVersion, "run", flags, async ({ config, logger }) => {
|
|
140
|
-
// If `--plan <id>` was passed and the user didn't provide a task
|
|
141
|
-
// argument or --task-file, fall back to the task embedded in the
|
|
142
|
-
// plan JSON. The whole point of `kj plan generate` is that the
|
|
143
|
-
// task is captured once and re-used; forcing the user to repeat
|
|
144
|
-
// --task-file on every run is friction with no upside.
|
|
145
|
-
let effectiveTask = task;
|
|
146
|
-
if (!task && !flags.taskFile && flags.plan) {
|
|
147
|
-
// config.projectDir is only populated post-init; before runFlow
|
|
148
|
-
// it can still be undefined. Plans are stored under cwd, so
|
|
149
|
-
// that's the correct fallback for the lookup.
|
|
150
|
-
const projectDir = config.projectDir || process.cwd();
|
|
151
|
-
const plan = await loadPlan(projectDir, flags.plan);
|
|
152
|
-
if (plan?.task && String(plan.task).trim()) {
|
|
153
|
-
effectiveTask = plan.task;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
const resolvedTask = await resolveTaskInput({ task: effectiveTask, taskFile: flags.taskFile, projectDir: config.projectDir, logger, indexFirstBytes: config.docs?.indexFirstBytes });
|
|
157
|
-
const res = await runCommandHandler({ task: resolvedTask, config, logger, flags });
|
|
158
|
-
// KJC-TSK-0674 (issue #1289): an aborted run (spec-review cancel,
|
|
159
|
-
// unanswerable non-interactive gate) must be observable by CI.
|
|
160
|
-
if (res?.aborted) process.exitCode = 1;
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
program
|
|
165
|
-
.command("autorun")
|
|
166
|
-
.description("Unattended delivery: spec → plan → run all HUs → outcome (defaults to --autonomous)")
|
|
167
|
-
.argument("[task]", "Spec/task description (or use --task-file)")
|
|
168
|
-
.option("--task-file <path>", "Read the spec from a file (e.g. spec.md)")
|
|
169
|
-
.option("--autonomy <level>", "interactive | assisted | autonomous (default: autonomous)")
|
|
170
|
-
.option("--autonomous", "Shortcut for --autonomy autonomous")
|
|
171
|
-
.option("--skip-spec-review", "Bypass the spec-reviewer pre-pipeline audit")
|
|
172
|
-
.action(async (task, flags) => {
|
|
173
|
-
const code = await withConfig(pkgVersion, "autorun", flags, async ({ config, logger }) => {
|
|
174
|
-
const { autorunCommand } = await import("../commands/autorun.js");
|
|
175
|
-
const resolvedTask = await resolveTaskInput({ task, taskFile: flags.taskFile, projectDir: config.projectDir, logger });
|
|
176
|
-
const res = await autorunCommand({ task: resolvedTask, config, logger, flags });
|
|
177
|
-
return res?.ok ? 0 : 1;
|
|
178
|
-
});
|
|
179
|
-
if (Number.isInteger(code)) process.exit(code);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
59
|
program
|
|
183
60
|
.command("code")
|
|
184
|
-
.description("
|
|
61
|
+
.description("Have the coder declared in your panel write (--agent, --card)")
|
|
185
62
|
.argument("[task]", "Task description (REQUIRED — provide as argument or via --task-file)")
|
|
186
63
|
.option("--task-file <path>", "Read the task from a file (e.g. .md)")
|
|
187
64
|
.option("--coder <name>")
|
|
@@ -242,8 +119,8 @@ export function registerPipeline(program, { pkgVersion }) {
|
|
|
242
119
|
|
|
243
120
|
program
|
|
244
121
|
.command("review")
|
|
245
|
-
.description("
|
|
246
|
-
.argument("[task]", "
|
|
122
|
+
.description("Cross-AI review gate: --staged/--check/--range record a verdict tied to the exact diff")
|
|
123
|
+
.argument("[task]", "What the change does, for the reviewer (optional; or via --task-file)")
|
|
247
124
|
.option("--task-file <path>", "Read the task from a file (e.g. .md)")
|
|
248
125
|
.option("--reviewer <name>")
|
|
249
126
|
.option("--reviewer-model <name>")
|
|
@@ -307,8 +184,7 @@ export function registerPipeline(program, { pkgVersion }) {
|
|
|
307
184
|
await reviewGateCommand({ config, logger, flags: { ...flags, task: gateTask } });
|
|
308
185
|
return;
|
|
309
186
|
}
|
|
310
|
-
|
|
311
|
-
await reviewCommand({ task: resolvedTask, config, logger, baseRef: flags.baseRef });
|
|
187
|
+
retire("review");
|
|
312
188
|
});
|
|
313
189
|
});
|
|
314
190
|
|
|
@@ -361,14 +237,6 @@ export function registerPipeline(program, { pkgVersion }) {
|
|
|
361
237
|
}
|
|
362
238
|
});
|
|
363
239
|
|
|
364
|
-
program
|
|
365
|
-
.command("status")
|
|
366
|
-
.description("Show pipeline dashboard with HU progress")
|
|
367
|
-
.option("-n, --lines <n>", "Max log lines to read", "50")
|
|
368
|
-
.action(async (flags) => {
|
|
369
|
-
await statusCommand({ lines: Number(flags.lines) });
|
|
370
|
-
});
|
|
371
|
-
|
|
372
240
|
program
|
|
373
241
|
.command("report")
|
|
374
242
|
.description("Show latest session report")
|
package/src/cli/register-plan.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
planGenerateCommand,
|
|
3
2
|
planListCommand,
|
|
4
3
|
planShowCommand,
|
|
5
4
|
planReadyCommand,
|
|
@@ -13,113 +12,23 @@ import {
|
|
|
13
12
|
planUnshareCommand,
|
|
14
13
|
} from "../commands/plan.js";
|
|
15
14
|
import { planLicenseCommand } from "../commands/plan/license.js";
|
|
16
|
-
import { parseCanvasMarkdown } from "../canvas/parse-md.js";
|
|
17
|
-
import { validateCanvas } from "../canvas/validate.js";
|
|
18
|
-
import { canvasToTask } from "../canvas/to-flat.js";
|
|
19
15
|
import { withConfig } from "./_shared.js";
|
|
16
|
+
import { retire } from "./retired-commands.js";
|
|
20
17
|
|
|
21
18
|
/**
|
|
22
19
|
* Register the `plan` parent command and every sub-command that lives
|
|
23
|
-
* under it (
|
|
24
|
-
* add-hu / remove-hu). Centralising plan management here keeps the
|
|
25
|
-
* REASONS Canvas auto-detection logic in one file alongside the
|
|
26
|
-
* planner entrypoint.
|
|
20
|
+
* under it (list / show / ready / validate / delete / add-hu / remove-hu...).
|
|
27
21
|
*/
|
|
28
22
|
export function registerPlan(program, { pkgVersion }) {
|
|
29
|
-
const plan = program.command("plan").description("Plan management (
|
|
23
|
+
const plan = program.command("plan").description("Plan management (list, show, validate, approve)");
|
|
30
24
|
|
|
25
|
+
// KJC-TSK-1317: retired in 5.0; it answers to say what replaced it.
|
|
31
26
|
plan
|
|
32
|
-
.command("generate", {
|
|
33
|
-
.
|
|
34
|
-
.
|
|
35
|
-
.
|
|
36
|
-
.
|
|
37
|
-
.option("--planner-model <name>")
|
|
38
|
-
.option("--context <text>", "Additional context for the planner")
|
|
39
|
-
.option("--json", "Output raw JSON plan")
|
|
40
|
-
// Tests-first quality knobs (v2.7.5). Default is "thorough":
|
|
41
|
-
// when the planner skips acceptance_tests on some HUs, run a
|
|
42
|
-
// focused synthesizer pass to fill them in. Disable with these
|
|
43
|
-
// flags only if you explicitly want a fast / sketch plan.
|
|
44
|
-
.option("--no-tests-synth", "Skip the tests-synthesizer pass that fills in missing acceptance_tests")
|
|
45
|
-
.option("--no-plan-review", "Skip the high-level plan reviewer pass (gaps / deps / overlap / order)")
|
|
46
|
-
.option("--skip-spec-review", "Bypass the spec-reviewer pre-pipeline audit")
|
|
47
|
-
.option("--quick", "Sketch mode — skip every quality pass after the initial planner call")
|
|
48
|
-
.option("--no-preflight-hu", "Skip auto-injection of [PREFLIGHT-000] HU at the top of the generated plan")
|
|
49
|
-
.option("--use-onboarding", "Inject the cached Architecture Brief (~/.karajan/onboarding/<slug>.md) into the planner context")
|
|
50
|
-
.option("-y, --yes", "Skip the project-name prompt (use the auto-derived default).")
|
|
51
|
-
.option("--no-interactive", "Force non-interactive mode (no prompts, use defaults).")
|
|
52
|
-
.action(async (task, flags) => {
|
|
53
|
-
await withConfig(pkgVersion, "plan", flags, async ({ config, logger }) => {
|
|
54
|
-
const { resolveTaskInput } = await import("../utils/task-file.js");
|
|
55
|
-
const resolvedTask = await resolveTaskInput({ task, taskFile: flags.taskFile, projectDir: config.projectDir, logger, indexFirstBytes: config.docs?.indexFirstBytes });
|
|
56
|
-
|
|
57
|
-
// REASONS Canvas auto-detection: a SPEC that contains
|
|
58
|
-
// `## REASONS:Section` headings is treated as a structured
|
|
59
|
-
// Canvas — parsed + validated BEFORE the planner runs. This
|
|
60
|
-
// catches broken acceptance tests (jq syntax, bash parse,
|
|
61
|
-
// gherkin missing Given/Then, the 2026-04-29 as-binding
|
|
62
|
-
// misuse class) at plan-time, without spending LLM dollars.
|
|
63
|
-
//
|
|
64
|
-
// Detection by file CONTENTS, not by CLI flag — the Canvas
|
|
65
|
-
// format is the signal. Flat SPECs without REASONS sections
|
|
66
|
-
// continue through the legacy path unchanged (back-compat).
|
|
67
|
-
if (typeof resolvedTask === "string" && /^##\s+REASONS:/m.test(resolvedTask)) {
|
|
68
|
-
let parsed;
|
|
69
|
-
try {
|
|
70
|
-
parsed = parseCanvasMarkdown(resolvedTask);
|
|
71
|
-
} catch (err) {
|
|
72
|
-
throw new Error(`Canvas parse error: ${err.message}`, { cause: err });
|
|
73
|
-
}
|
|
74
|
-
const validation = validateCanvas(parsed);
|
|
75
|
-
if (!validation.valid) {
|
|
76
|
-
const lines = ["Canvas validation failed."];
|
|
77
|
-
if (validation.schemaIssues) {
|
|
78
|
-
lines.push("Schema issues:");
|
|
79
|
-
for (const issue of validation.schemaIssues) {
|
|
80
|
-
lines.push(` - ${issue.path?.map((p) => p.key).join(".") || "(root)"}: ${issue.message}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (validation.testIssues) {
|
|
84
|
-
lines.push("Acceptance test issues:");
|
|
85
|
-
for (const issue of validation.testIssues) {
|
|
86
|
-
lines.push(` - Operation #${issue.operationIndex + 1} "${issue.operationTitle}", test #${issue.testIndex + 1} (${issue.type}, ${issue.kind}):`);
|
|
87
|
-
lines.push(` ${issue.content}`);
|
|
88
|
-
lines.push(` → ${issue.error}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
throw new Error(lines.join("\n"));
|
|
92
|
-
}
|
|
93
|
-
// Pass the Canvas-derived flat task to the existing planner.
|
|
94
|
-
// Norms + Safeguards ride along under explicit headings the
|
|
95
|
-
// coder prompt can grep for.
|
|
96
|
-
const taskFromCanvas = canvasToTask(validation.canvas);
|
|
97
|
-
// KJC-TSK-0348: remember WHERE the Canvas lived on disk so
|
|
98
|
-
// `kj sync --apply` later knows which file to patch.
|
|
99
|
-
let sourceCanvasPath = null;
|
|
100
|
-
if (typeof flags?.taskFile === "string" && flags.taskFile.length > 0) {
|
|
101
|
-
const path = await import("node:path");
|
|
102
|
-
sourceCanvasPath = path.isAbsolute(flags.taskFile)
|
|
103
|
-
? flags.taskFile
|
|
104
|
-
: path.resolve(config.projectDir || process.cwd(), flags.taskFile);
|
|
105
|
-
}
|
|
106
|
-
await planGenerateCommand({ task: taskFromCanvas, config, logger, flags, sourceCanvasPath });
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
await planGenerateCommand({
|
|
110
|
-
task: resolvedTask, config, logger, json: flags.json, context: flags.context,
|
|
111
|
-
flags: {
|
|
112
|
-
noTestsSynth: flags.testsSynth === false,
|
|
113
|
-
noPlanReview: flags.planReview === false,
|
|
114
|
-
quick: Boolean(flags.quick),
|
|
115
|
-
yes: Boolean(flags.yes),
|
|
116
|
-
interactive: flags.interactive,
|
|
117
|
-
preflightHu: flags.preflightHu !== false, // KJC-TSK-0397
|
|
118
|
-
useOnboarding: Boolean(flags.useOnboarding), // KJC-TSK-0384 PR 3
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
});
|
|
27
|
+
.command("generate", { hidden: true })
|
|
28
|
+
.argument("[args...]")
|
|
29
|
+
.allowUnknownOption()
|
|
30
|
+
.allowExcessArguments()
|
|
31
|
+
.action(() => retire("plan generate"));
|
|
123
32
|
|
|
124
33
|
plan.command("list").description("List all plans").action(async (flags) => {
|
|
125
34
|
await withConfig(pkgVersion, "plan", flags, async ({ config }) => {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// KJC-TSK-1317: the pipeline commands retired in 5.0. In v4 the host agent does
|
|
2
|
+
// the work and kj governs it, so kj no longer drives a coder of its own. Each
|
|
3
|
+
// retired command still answers, hidden from the help, to say what replaced it.
|
|
4
|
+
|
|
5
|
+
const GUIDE = "https://github.com/manufosela/karajan-code/blob/main/MIGRATION-v5.md";
|
|
6
|
+
const BY_THE_AGENT = "Your agent (Claude Code, OpenCode...) does the work now and kj governs it: split the task with kj brief planner + kj hu add, one lane per card with kj worktree start, and kj review --staged before every commit.";
|
|
7
|
+
const brief = (role) => `Use kj brief ${role}: your agent applies the role itself.`;
|
|
8
|
+
|
|
9
|
+
/** Retired command → [how it is named, what replaces it]. */
|
|
10
|
+
export const RETIRED = {
|
|
11
|
+
run: ["kj run", BY_THE_AGENT],
|
|
12
|
+
autorun: ["kj autorun", BY_THE_AGENT],
|
|
13
|
+
resume: ["kj resume", BY_THE_AGENT],
|
|
14
|
+
standby: ["kj standby", BY_THE_AGENT],
|
|
15
|
+
"plan generate": ["kj plan generate", "Your agent plans with kj brief planner and puts each piece on the board with kj hu add."],
|
|
16
|
+
status: ["kj status", "The HU board shows the work in progress: kj board start."],
|
|
17
|
+
undo: ["kj undo", "Every reviewed step is its own commit: undo it with git."],
|
|
18
|
+
triage: ["kj triage", brief("triage")],
|
|
19
|
+
researcher: ["kj researcher", brief("researcher")],
|
|
20
|
+
architect: ["kj architect", brief("architect")],
|
|
21
|
+
review: ["kj review with a task", "Use kj review --staged: it reviews the exact diff you are about to commit."],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** The notice a retired command (or MCP tool) answers with. */
|
|
25
|
+
export const retiredMessage = (name) => {
|
|
26
|
+
const [label, instead] = RETIRED[name];
|
|
27
|
+
return `${label} was retired in 5.0. ${instead}\nMigration guide: ${GUIDE}`;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** Print the notice and fail, without starting anything. */
|
|
31
|
+
export const retire = (name) => {
|
|
32
|
+
process.stderr.write(`${retiredMessage(name)}\n`);
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const TOP_LEVEL = ["run", "autorun", "resume", "standby", "status", "undo", "triage", "researcher", "architect"];
|
|
37
|
+
|
|
38
|
+
/** Register the retired top-level commands, hidden, taking any argument. */
|
|
39
|
+
export function registerRetired(program) {
|
|
40
|
+
for (const name of TOP_LEVEL) {
|
|
41
|
+
program
|
|
42
|
+
.command(name, { hidden: true })
|
|
43
|
+
.description("Retired in 5.0")
|
|
44
|
+
.argument("[args...]")
|
|
45
|
+
.allowUnknownOption()
|
|
46
|
+
.allowExcessArguments()
|
|
47
|
+
.action(() => retire(name));
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/cli.js
CHANGED
|
@@ -10,11 +10,12 @@ import { registerPlan } from "./cli/register-plan.js";
|
|
|
10
10
|
import { registerRolesSkills } from "./cli/register-roles-skills.js";
|
|
11
11
|
import { registerMeta } from "./cli/register-meta.js";
|
|
12
12
|
import { registerSonar } from "./cli/register-sonar.js";
|
|
13
|
-
import {
|
|
13
|
+
import { registerRetired } from "./cli/retired-commands.js";
|
|
14
14
|
import { printUpdateNotice } from "./utils/update-check.js";
|
|
15
15
|
import { printWelcomeScreen } from "./utils/welcome.js";
|
|
16
16
|
import { migrateKjToKarajan } from "./utils/home-migration.js";
|
|
17
17
|
import { pinGitDiffFormat } from "./utils/git-diff-format.js";
|
|
18
|
+
import { pinGhAccount } from "./utils/gh-account.js";
|
|
18
19
|
|
|
19
20
|
// KJC-BUG-0408: every git kj runs prints a/ and b/, whatever the user's gitconfig says.
|
|
20
21
|
pinGitDiffFormat();
|
|
@@ -65,8 +66,8 @@ program.addHelpText(
|
|
|
65
66
|
`
|
|
66
67
|
Getting started (the basics — start here):
|
|
67
68
|
kj init Set up Karajan in this project (run once)
|
|
68
|
-
kj
|
|
69
|
-
kj
|
|
69
|
+
kj hu add "<title>" Put a piece of work on the board before it starts
|
|
70
|
+
kj review --staged Have another AI review the diff you are about to commit
|
|
70
71
|
kj doctor Check your environment is ready
|
|
71
72
|
kj harden Add quality git hooks + CI to any repo
|
|
72
73
|
|
|
@@ -78,7 +79,7 @@ registerPlan(program, { pkgVersion: PKG_VERSION });
|
|
|
78
79
|
registerRolesSkills(program, { pkgVersion: PKG_VERSION });
|
|
79
80
|
registerMeta(program, { pkgVersion: PKG_VERSION });
|
|
80
81
|
registerSonar(program);
|
|
81
|
-
|
|
82
|
+
registerRetired(program);
|
|
82
83
|
|
|
83
84
|
/**
|
|
84
85
|
* Find subcommands whose name is "close enough" to a typo. Used by the
|
|
@@ -124,7 +125,7 @@ function levenshtein(a, b) {
|
|
|
124
125
|
program.action(async (_opts, command) => {
|
|
125
126
|
if (command.args.length > 0) {
|
|
126
127
|
const bad = command.args[0];
|
|
127
|
-
const known = program.commands.map((c) => c.name()).sort();
|
|
128
|
+
const known = program.commands.filter((c) => !c._hidden).map((c) => c.name()).sort();
|
|
128
129
|
process.stderr.write(`error: '${bad}' no es un comando válido de kj\n`);
|
|
129
130
|
const suggestions = suggestSimilarCommands(bad, known);
|
|
130
131
|
if (suggestions.length > 0) {
|
|
@@ -140,6 +141,18 @@ program.action(async (_opts, command) => {
|
|
|
140
141
|
printWelcomeScreen({ version: PKG_VERSION, config });
|
|
141
142
|
});
|
|
142
143
|
|
|
144
|
+
// KJC-BUG-0458 (ADR 0040): every gh kj runs uses the repo's account, not whichever another
|
|
145
|
+
// session left active. A broken config is each command's to report; here it only means the
|
|
146
|
+
// account comes from the remote. Kept in a top-level try: the SEA build wraps from here on.
|
|
147
|
+
try {
|
|
148
|
+
const { config } = await loadConfig().catch(() => ({ config: null }));
|
|
149
|
+
const githubAccount = config?.review?.github_account ?? null;
|
|
150
|
+
const ghPin = pinGhAccount({ account: githubAccount });
|
|
151
|
+
if (githubAccount && ghPin.reason) console.warn(`\x1b[33m[warn]\x1b[0m review.github_account: ${ghPin.reason}`);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
console.warn(`\x1b[33m[warn]\x1b[0m gh account not pinned: ${err.message}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
143
156
|
// One-shot ~/.kj/ → ~/.karajan/ consolidation. Idempotent via marker
|
|
144
157
|
// file; failures non-blocking. See src/utils/home-migration.js.
|
|
145
158
|
// Static import — the migrator runs on every kj invocation, no
|