karajan-code 4.70.4 → 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/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 -143
- 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 -150
- package/src/commands/go.js +71 -53
- package/src/commands/harden.js +90 -81
- 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 +421 -341
- 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/secrets.js +36 -0
- package/src/config.js +1 -0
- package/src/environment/adr.js +16 -2
- package/src/git/karajan-label.js +20 -8
- package/src/guards/main-guard.js +54 -0
- package/src/harden/hook-templates.js +16 -1
- package/src/harden/sentinel/posttooluse.mjs +18 -6
- package/src/harden/sentinel/pretooluse-sentinel.mjs +64 -36
- package/src/harden/sentinel/sentinel-lib.mjs +129 -26
- package/src/harden/sentinel/sentinel-shell.mjs +5 -16
- package/src/harden/sentinel/sessionstart.mjs +3 -2
- package/src/harden/sentinel/stop.mjs +5 -4
- 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 +1 -35
- package/src/mcp/handlers/management-handlers.js +2 -42
- package/src/mcp/server-handlers.js +16 -22
- package/src/mcp/tools.js +1 -196
- 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/gate-gitignore.js +23 -4
- package/src/review/gate-hook.js +12 -4
- package/src/review/one-shot-review.js +45 -35
- package/src/review/publish-pr.js +14 -2
- package/src/review/repo-docs.js +73 -0
- package/src/review/repo-stack.js +59 -0
- package/src/review/reviewer-fallback.js +19 -4
- 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 +1 -24
- 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/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
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Status dashboard formatter.
|
|
3
|
-
* Builds a structured terminal dashboard from session data and run-log lines.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { HU_STATUS } from "../hu/store.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Status label mapping with visual indicators for terminal output.
|
|
10
|
-
* @type {Record<string, string>}
|
|
11
|
-
*/
|
|
12
|
-
const STATUS_LABELS = {
|
|
13
|
-
[HU_STATUS.PENDING]: "pending",
|
|
14
|
-
[HU_STATUS.CODING]: "coding",
|
|
15
|
-
[HU_STATUS.REVIEWING]: "reviewing",
|
|
16
|
-
[HU_STATUS.DONE]: "done",
|
|
17
|
-
[HU_STATUS.FAILED]: "failed",
|
|
18
|
-
[HU_STATUS.BLOCKED]: "blocked",
|
|
19
|
-
[HU_STATUS.CERTIFIED]: "certified",
|
|
20
|
-
[HU_STATUS.NEEDS_CONTEXT]: "needs_ctx",
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Format a millisecond duration into a human-readable string (e.g. "3m 42s").
|
|
25
|
-
* @param {number} ms
|
|
26
|
-
* @returns {string}
|
|
27
|
-
*/
|
|
28
|
-
export function formatDuration(ms) {
|
|
29
|
-
if (!ms || ms < 0) return "0s";
|
|
30
|
-
const totalSec = Math.floor(ms / 1000);
|
|
31
|
-
const hours = Math.floor(totalSec / 3600);
|
|
32
|
-
const minutes = Math.floor((totalSec % 3600) / 60);
|
|
33
|
-
const seconds = totalSec % 60;
|
|
34
|
-
|
|
35
|
-
const parts = [];
|
|
36
|
-
if (hours > 0) parts.push(`${hours}h`);
|
|
37
|
-
if (minutes > 0) parts.push(`${minutes}m`);
|
|
38
|
-
if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`);
|
|
39
|
-
return parts.join(" ");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Parse the current pipeline stage from log lines.
|
|
44
|
-
* @param {string[]} lines - Raw log lines.
|
|
45
|
-
* @returns {{ currentStage: string|null, lastEvent: string|null }}
|
|
46
|
-
*/
|
|
47
|
-
export function parseStageFromLog(lines) {
|
|
48
|
-
let currentStage = null;
|
|
49
|
-
let lastEvent = null;
|
|
50
|
-
|
|
51
|
-
for (const line of lines) {
|
|
52
|
-
const stageStart = /\[(\w+):start\]/.exec(line);
|
|
53
|
-
if (stageStart) currentStage = stageStart[1];
|
|
54
|
-
|
|
55
|
-
const stageDone = /\[(\w+):done\]|\[(\w+)\] finished/.exec(line);
|
|
56
|
-
if (stageDone) {
|
|
57
|
-
const doneName = stageDone[1] || stageDone[2];
|
|
58
|
-
if (doneName === currentStage) currentStage = "idle";
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (line.includes("[standby]") || line.includes("standby")) {
|
|
62
|
-
currentStage = "standby";
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (line.trim()) lastEvent = line.trim();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return { currentStage, lastEvent };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Format a single HU line for the dashboard.
|
|
73
|
-
* @param {object} story - HU story object.
|
|
74
|
-
* @param {boolean} isCurrent - Whether this is the currently active HU.
|
|
75
|
-
* @returns {string}
|
|
76
|
-
*/
|
|
77
|
-
function formatHuLine(story, isCurrent) {
|
|
78
|
-
const id = (story.id || "???").padEnd(12);
|
|
79
|
-
const rawStatus = story.status || "pending";
|
|
80
|
-
const label = STATUS_LABELS[rawStatus] || rawStatus;
|
|
81
|
-
const statusStr = `[${label}]`.padEnd(13);
|
|
82
|
-
const title = story.title || story.original?.text || "(untitled)";
|
|
83
|
-
const truncTitle = title.length > 40 ? title.slice(0, 37) + "..." : title;
|
|
84
|
-
|
|
85
|
-
let timing = "";
|
|
86
|
-
if (story.duration_ms) {
|
|
87
|
-
timing = formatDuration(story.duration_ms);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const blockedInfo = story.blocked_by?.length
|
|
91
|
-
? ` (needs ${story.blocked_by.join(", ")})`
|
|
92
|
-
: "";
|
|
93
|
-
|
|
94
|
-
const marker = isCurrent ? " <-- current" : "";
|
|
95
|
-
const timingStr = timing ? ` ${timing}` : "";
|
|
96
|
-
|
|
97
|
-
return ` ${id} ${statusStr} ${truncTitle}${blockedInfo}${timingStr}${marker}`;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Build a terminal dashboard string from session data and log lines.
|
|
102
|
-
*
|
|
103
|
-
* @param {object|null} sessionData - Session JSON (from session-store) or null.
|
|
104
|
-
* @param {string[]} logLines - Raw run-log lines.
|
|
105
|
-
* @param {object} [options] - Optional overrides.
|
|
106
|
-
* @param {object[]|null} [options.stories] - HU stories array (from hu batch).
|
|
107
|
-
* @returns {string}
|
|
108
|
-
*/
|
|
109
|
-
export function buildDashboard(sessionData, logLines, options = {}) {
|
|
110
|
-
if (!sessionData) {
|
|
111
|
-
return "No active pipeline";
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const lines = [];
|
|
115
|
-
const config = sessionData.config_snapshot || {};
|
|
116
|
-
const maxIter = config.max_iterations ?? "?";
|
|
117
|
-
const status = sessionData.status || "unknown";
|
|
118
|
-
|
|
119
|
-
// Parse log for current stage info
|
|
120
|
-
const logInfo = parseStageFromLog(logLines || []);
|
|
121
|
-
|
|
122
|
-
// Determine iteration from session or log
|
|
123
|
-
const iteration = sessionData.reviewer_retry_count != null
|
|
124
|
-
? sessionData.reviewer_retry_count + 1
|
|
125
|
-
: null;
|
|
126
|
-
const iterFromLog = parseIterationFromLog(logLines || []);
|
|
127
|
-
const displayIter = iterFromLog || iteration || "?";
|
|
128
|
-
|
|
129
|
-
// Pipeline header
|
|
130
|
-
const statusUpper = status.toUpperCase();
|
|
131
|
-
lines.push(`Pipeline: ${statusUpper} (iteration ${displayIter}/${maxIter})`);
|
|
132
|
-
|
|
133
|
-
// Duration
|
|
134
|
-
const duration = computeDuration(sessionData);
|
|
135
|
-
lines.push(`Duration: ${formatDuration(duration)}`);
|
|
136
|
-
|
|
137
|
-
// Agent info
|
|
138
|
-
const coderProvider = config.coder?.provider || config.roles?.coder?.provider || "?";
|
|
139
|
-
const reviewerProvider = config.reviewer?.provider || config.roles?.reviewer?.provider || "?";
|
|
140
|
-
lines.push(`Agent: ${coderProvider} (coder) / ${reviewerProvider} (reviewer)`);
|
|
141
|
-
|
|
142
|
-
// HU stories section
|
|
143
|
-
const stories = options.stories || [];
|
|
144
|
-
if (stories.length > 0) {
|
|
145
|
-
lines.push("");
|
|
146
|
-
lines.push("HUs:");
|
|
147
|
-
|
|
148
|
-
// Determine which story is currently being worked on
|
|
149
|
-
const currentStory = stories.find(s =>
|
|
150
|
-
s.status === HU_STATUS.CODING || s.status === HU_STATUS.REVIEWING
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
for (const story of stories) {
|
|
154
|
-
const isCurrent = currentStory && story.id === currentStory.id;
|
|
155
|
-
lines.push(formatHuLine(story, isCurrent));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Current stage and last event
|
|
160
|
-
lines.push("");
|
|
161
|
-
const stage = logInfo.currentStage || "idle";
|
|
162
|
-
const iterSuffix = displayIter !== "?" ? ` (iteration ${displayIter})` : "";
|
|
163
|
-
lines.push(`Current stage: ${stage}${iterSuffix}`);
|
|
164
|
-
|
|
165
|
-
if (logInfo.lastEvent) {
|
|
166
|
-
// Truncate last event for display
|
|
167
|
-
const maxLen = 120;
|
|
168
|
-
const event = logInfo.lastEvent.length > maxLen
|
|
169
|
-
? logInfo.lastEvent.slice(0, maxLen - 3) + "..."
|
|
170
|
-
: logInfo.lastEvent;
|
|
171
|
-
lines.push(`Last event: ${event}`);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Errors
|
|
175
|
-
if (sessionData.deferred_issues?.length) {
|
|
176
|
-
lines.push("");
|
|
177
|
-
lines.push(`Deferred issues: ${sessionData.deferred_issues.length}`);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return lines.join("\n");
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Build a structured JSON response for MCP consumers.
|
|
185
|
-
*
|
|
186
|
-
* @param {object|null} sessionData - Session JSON or null.
|
|
187
|
-
* @param {string[]} logLines - Raw run-log lines.
|
|
188
|
-
* @param {object} [options] - Optional overrides.
|
|
189
|
-
* @param {object[]|null} [options.stories] - HU stories array.
|
|
190
|
-
* @returns {object}
|
|
191
|
-
*/
|
|
192
|
-
export function buildDashboardJson(sessionData, logLines, options = {}) {
|
|
193
|
-
if (!sessionData) {
|
|
194
|
-
return { ok: false, message: "No active pipeline" };
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const config = sessionData.config_snapshot || {};
|
|
198
|
-
const logInfo = parseStageFromLog(logLines || []);
|
|
199
|
-
const iterFromLog = parseIterationFromLog(logLines || []);
|
|
200
|
-
const iteration = iterFromLog
|
|
201
|
-
|| (sessionData.reviewer_retry_count != null ? sessionData.reviewer_retry_count + 1 : null);
|
|
202
|
-
|
|
203
|
-
const stories = (options.stories || []).map(s => ({
|
|
204
|
-
id: s.id,
|
|
205
|
-
status: s.status || "pending",
|
|
206
|
-
title: s.title || s.original?.text || null,
|
|
207
|
-
blocked_by: s.blocked_by || [],
|
|
208
|
-
duration_ms: s.duration_ms || null,
|
|
209
|
-
}));
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
ok: true,
|
|
213
|
-
pipeline: {
|
|
214
|
-
status: sessionData.status || "unknown",
|
|
215
|
-
iteration: iteration || null,
|
|
216
|
-
maxIterations: config.max_iterations ?? null,
|
|
217
|
-
duration_ms: computeDuration(sessionData),
|
|
218
|
-
coder: config.coder?.provider || config.roles?.coder?.provider || null,
|
|
219
|
-
reviewer: config.reviewer?.provider || config.roles?.reviewer?.provider || null,
|
|
220
|
-
},
|
|
221
|
-
hus: stories,
|
|
222
|
-
currentStage: logInfo.currentStage || "idle",
|
|
223
|
-
lastEvent: logInfo.lastEvent || null,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Parse iteration number from log lines.
|
|
229
|
-
* @param {string[]} lines
|
|
230
|
-
* @returns {number|null}
|
|
231
|
-
*/
|
|
232
|
-
function parseIterationFromLog(lines) {
|
|
233
|
-
let iteration = null;
|
|
234
|
-
for (const line of lines) {
|
|
235
|
-
const m = /[Ii]teration\s+(\d+)/.exec(line);
|
|
236
|
-
if (m) iteration = Number.parseInt(m[1], 10);
|
|
237
|
-
}
|
|
238
|
-
return iteration;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Compute pipeline duration in milliseconds from session timestamps.
|
|
243
|
-
* @param {object} sessionData
|
|
244
|
-
* @returns {number}
|
|
245
|
-
*/
|
|
246
|
-
function computeDuration(sessionData) {
|
|
247
|
-
const created = sessionData.created_at;
|
|
248
|
-
if (!created) return 0;
|
|
249
|
-
const start = new Date(created).getTime();
|
|
250
|
-
const now = sessionData.updated_at
|
|
251
|
-
? new Date(sessionData.updated_at).getTime()
|
|
252
|
-
: Date.now();
|
|
253
|
-
return Math.max(0, now - start);
|
|
254
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
// KJC-TSK-0375 PR2 — Extract structured tool calls from an agent transcript.
|
|
2
|
-
//
|
|
3
|
-
// The ToolCorrectnessJudgeRole (PR1) consumes a list of `{tool, args}`
|
|
4
|
-
// objects. The coder writes a raw transcript (provider-dependent format) to
|
|
5
|
-
// disk per iteration. This module bridges the two: parse the transcript,
|
|
6
|
-
// return the ordered list of tool invocations.
|
|
7
|
-
//
|
|
8
|
-
// Provider-agnostic interface; Claude stream-json is the only format
|
|
9
|
-
// implemented today. New providers add a branch below — keep parsers
|
|
10
|
-
// pure (no I/O), so the role tests can mock transcripts trivially.
|
|
11
|
-
|
|
12
|
-
const PROVIDER_PARSERS = {
|
|
13
|
-
claude: parseClaudeStreamJson,
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Extract tool calls from a transcript string.
|
|
18
|
-
*
|
|
19
|
-
* @param {object} args
|
|
20
|
-
* @param {string} args.transcript - raw agent output (stdout/stderr buffer).
|
|
21
|
-
* @param {string} [args.provider] - "claude" (default). Unknown returns [].
|
|
22
|
-
* @returns {Array<{tool:string, args:object}>}
|
|
23
|
-
*/
|
|
24
|
-
export function extractToolCalls({ transcript, provider = "claude" } = {}) {
|
|
25
|
-
if (typeof transcript !== "string" || transcript.length === 0) return [];
|
|
26
|
-
const parser = PROVIDER_PARSERS[provider];
|
|
27
|
-
if (!parser) return [];
|
|
28
|
-
return parser(transcript);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Claude emits one JSON event per line. We care about `assistant` events
|
|
32
|
-
// whose `message.content` is an array containing `tool_use` blocks with
|
|
33
|
-
// `{type:"tool_use", name, input}`. Lines that fail to parse, that are
|
|
34
|
-
// not `assistant`, or whose content is not an array are silently skipped:
|
|
35
|
-
// the transcript also carries `system`, `result`, `rate_limit_event`, etc.
|
|
36
|
-
function parseClaudeStreamJson(transcript) {
|
|
37
|
-
const out = [];
|
|
38
|
-
for (const raw of transcript.split("\n")) {
|
|
39
|
-
const line = raw.trim();
|
|
40
|
-
if (!line || line[0] !== "{") continue;
|
|
41
|
-
let obj;
|
|
42
|
-
try { obj = JSON.parse(line); } catch { continue; }
|
|
43
|
-
if (obj?.type !== "assistant") continue;
|
|
44
|
-
const content = obj?.message?.content;
|
|
45
|
-
if (!Array.isArray(content)) continue;
|
|
46
|
-
for (const block of content) {
|
|
47
|
-
if (block?.type === "tool_use" && typeof block.name === "string") {
|
|
48
|
-
out.push({
|
|
49
|
-
tool: block.name,
|
|
50
|
-
args: block.input && typeof block.input === "object" ? block.input : {},
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return out;
|
|
56
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// Chrome DevTools MCP detection and WebPerf skill auto-installation.
|
|
2
|
-
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import os from "node:os";
|
|
6
|
-
import { isOpenSkillsAvailable, listSkills } from "../skills/openskills-client.js";
|
|
7
|
-
|
|
8
|
-
/** Skill names relevant for WebPerf analysis. Already installed globally via openskills. */
|
|
9
|
-
export const WEBPERF_SKILLS = [
|
|
10
|
-
"optimize",
|
|
11
|
-
"audit",
|
|
12
|
-
"polish"
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Check whether Chrome DevTools MCP is configured and available.
|
|
17
|
-
* Checks: (1) config flag, (2) Claude MCP config (~/.claude.json), (3) VS Code MCP settings.
|
|
18
|
-
* @param {object} config - merged Karajan config
|
|
19
|
-
* @returns {boolean}
|
|
20
|
-
*/
|
|
21
|
-
export function isDevToolsMcpAvailable(config) {
|
|
22
|
-
// Explicit config flag takes priority
|
|
23
|
-
if (config?.webperf?.devtools_mcp === true) return true;
|
|
24
|
-
if (config?.webperf?.devtools_mcp === false) return false;
|
|
25
|
-
|
|
26
|
-
// Check cached detection result
|
|
27
|
-
if (_devToolsDetected !== null) return _devToolsDetected;
|
|
28
|
-
|
|
29
|
-
// Not yet detected - return false (async detection runs at init)
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let _devToolsDetected = null;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Auto-detect Chrome DevTools MCP from system configuration.
|
|
37
|
-
* Checks ~/.claude.json and VS Code MCP settings.
|
|
38
|
-
* Call once at pipeline init.
|
|
39
|
-
*/
|
|
40
|
-
export async function detectDevToolsMcp(logger) {
|
|
41
|
-
// Check Claude MCP config
|
|
42
|
-
const claudeConfigPath = path.join(os.homedir(), ".claude.json");
|
|
43
|
-
try {
|
|
44
|
-
const raw = await fs.readFile(claudeConfigPath, "utf8");
|
|
45
|
-
const parsed = JSON.parse(raw);
|
|
46
|
-
const mcpServers = parsed?.mcpServers || parsed?.mcp_servers || {};
|
|
47
|
-
if (mcpServers["chrome-devtools"] || mcpServers["chrome_devtools"]) {
|
|
48
|
-
_devToolsDetected = true;
|
|
49
|
-
logger?.info?.("Chrome DevTools MCP detected in ~/.claude.json");
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
} catch { /* file not found or parse error */ }
|
|
53
|
-
|
|
54
|
-
// Check VS Code MCP settings
|
|
55
|
-
const vscodePaths = [
|
|
56
|
-
path.join(os.homedir(), ".vscode", "settings.json"),
|
|
57
|
-
path.join(process.cwd(), ".vscode", "settings.json")
|
|
58
|
-
];
|
|
59
|
-
for (const vscPath of vscodePaths) {
|
|
60
|
-
try {
|
|
61
|
-
const raw = await fs.readFile(vscPath, "utf8");
|
|
62
|
-
if (raw.includes("chrome-devtools") || raw.includes("chrome_devtools")) {
|
|
63
|
-
_devToolsDetected = true;
|
|
64
|
-
logger?.info?.(`Chrome DevTools MCP detected in ${vscPath}`);
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
} catch { /* not found */ }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
_devToolsDetected = false;
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Ensure WebPerf skills are installed via OpenSkills.
|
|
76
|
-
* Installs any missing skills from WEBPERF_SKILLS.
|
|
77
|
-
* @param {string} projectDir - absolute path to the project root
|
|
78
|
-
* @param {object} [logger] - optional logger ({ info, warn })
|
|
79
|
-
* @returns {Promise<{ installed: string[], alreadyInstalled: string[], skipped: string[] }>}
|
|
80
|
-
*/
|
|
81
|
-
export async function ensureWebPerfSkills(projectDir, logger) {
|
|
82
|
-
const result = { installed: [], alreadyInstalled: [], skipped: [] };
|
|
83
|
-
|
|
84
|
-
const available = await isOpenSkillsAvailable();
|
|
85
|
-
if (!available) {
|
|
86
|
-
logger?.debug?.("OpenSkills CLI not available - WebPerf skills unavailable");
|
|
87
|
-
result.skipped = [...WEBPERF_SKILLS];
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// List skills (includes global installs)
|
|
92
|
-
const listResult = await listSkills({ projectDir });
|
|
93
|
-
const installedNames = new Set(
|
|
94
|
-
(listResult.ok ? listResult.skills : []).map(s => s.name)
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
for (const skill of WEBPERF_SKILLS) {
|
|
98
|
-
if (installedNames.has(skill)) {
|
|
99
|
-
result.alreadyInstalled.push(skill);
|
|
100
|
-
} else {
|
|
101
|
-
// Skills should be installed globally via `openskills install owner/repo`
|
|
102
|
-
// Don't attempt auto-install with bare names — just note they're missing
|
|
103
|
-
result.skipped.push(skill);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (result.alreadyInstalled.length > 0) {
|
|
108
|
-
logger?.info?.(`WebPerf skills available: ${result.alreadyInstalled.join(", ")}`);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return result;
|
|
112
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration helpers that format CWV gate results for the
|
|
3
|
-
* impeccable prompt and for pipeline progress events.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const RATING_ICONS = { good: "PASS", "needs-improvement": "WARN", poor: "FAIL" };
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Build a human-readable section for the impeccable prompt.
|
|
10
|
-
*
|
|
11
|
-
* @param {{ pass: boolean, scores: object, blocking: Array, advisory: Array }} cwvResult
|
|
12
|
-
* @returns {string}
|
|
13
|
-
*/
|
|
14
|
-
export function buildWebPerfSection(cwvResult) {
|
|
15
|
-
const lines = [];
|
|
16
|
-
const verdict = cwvResult.pass ? "PASSED" : "FAILED";
|
|
17
|
-
lines.push(`## WebPerf — Core Web Vitals (${verdict})`);
|
|
18
|
-
lines.push("");
|
|
19
|
-
|
|
20
|
-
for (const [metric, { value, rating }] of Object.entries(cwvResult.scores)) {
|
|
21
|
-
const icon = RATING_ICONS[rating] || rating;
|
|
22
|
-
const unit = metric === "cls" ? "" : "ms";
|
|
23
|
-
lines.push(`- **${metric.toUpperCase()}**: ${value}${unit} [${icon}]`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (cwvResult.blocking.length > 0) {
|
|
27
|
-
lines.push("");
|
|
28
|
-
lines.push("### Blocking issues");
|
|
29
|
-
for (const b of cwvResult.blocking) {
|
|
30
|
-
const unit = b.metric === "cls" ? "" : "ms";
|
|
31
|
-
lines.push(`- ${b.metric.toUpperCase()}: ${b.value}${unit} exceeds poor threshold (${b.threshold}${unit})`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (cwvResult.advisory.length > 0) {
|
|
36
|
-
lines.push("");
|
|
37
|
-
lines.push("### Advisory (needs improvement)");
|
|
38
|
-
for (const a of cwvResult.advisory) {
|
|
39
|
-
const unit = a.metric === "cls" ? "" : "ms";
|
|
40
|
-
lines.push(`- ${a.metric.toUpperCase()}: ${a.value}${unit} exceeds good threshold (${a.threshold}${unit})`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return lines.join("\n");
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Format CWV result for a pipeline progress event payload.
|
|
49
|
-
*
|
|
50
|
-
* @param {{ pass: boolean, scores: object, blocking: Array, advisory: Array }} cwvResult
|
|
51
|
-
* @returns {{ type: string, pass: boolean, metrics: object, blockingCount: number, advisoryCount: number }}
|
|
52
|
-
*/
|
|
53
|
-
export function formatCwvForEvent(cwvResult) {
|
|
54
|
-
const metrics = {};
|
|
55
|
-
for (const [metric, { value, rating }] of Object.entries(cwvResult.scores)) {
|
|
56
|
-
metrics[metric] = { value, rating };
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
type: "webperf-cwv",
|
|
61
|
-
pass: cwvResult.pass,
|
|
62
|
-
metrics,
|
|
63
|
-
blockingCount: cwvResult.blocking.length,
|
|
64
|
-
advisoryCount: cwvResult.advisory.length
|
|
65
|
-
};
|
|
66
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# kj-run — Full Pipeline (Skills Mode)
|
|
2
|
-
|
|
3
|
-
Execute the complete Karajan pipeline as sequential skills.
|
|
4
|
-
|
|
5
|
-
## Your task
|
|
6
|
-
|
|
7
|
-
$ARGUMENTS
|
|
8
|
-
|
|
9
|
-
## Pipeline steps (execute in order)
|
|
10
|
-
|
|
11
|
-
### Step 1 — Discover (optional but recommended)
|
|
12
|
-
Analyze the task for gaps before coding:
|
|
13
|
-
- Identify missing requirements, ambiguities, contradictions
|
|
14
|
-
- If critical gaps found, STOP and ask the user before proceeding
|
|
15
|
-
- If ready, continue
|
|
16
|
-
|
|
17
|
-
### Step 2 — Code (with guardrails)
|
|
18
|
-
Implement the task:
|
|
19
|
-
1. **Tests first** (TDD): write/update tests before implementation
|
|
20
|
-
2. **Implement**: minimal, focused code to fulfill the task
|
|
21
|
-
3. **Verify**: run the test suite
|
|
22
|
-
4. **Security check**: no hardcoded secrets, no injection vectors, no destructive ops in the diff
|
|
23
|
-
5. **Diff check**: run `git diff` and verify only intended lines changed
|
|
24
|
-
6. If any guardrail fails, fix before proceeding
|
|
25
|
-
|
|
26
|
-
### Step 3 — Review (self-review)
|
|
27
|
-
Review your own changes against quality standards:
|
|
28
|
-
1. Run `git diff main...HEAD` (or base branch)
|
|
29
|
-
2. Check: security, correctness, tests, architecture, style (in that order)
|
|
30
|
-
3. Flag blocking issues:
|
|
31
|
-
- Hardcoded credentials or secrets
|
|
32
|
-
- Entire files overwritten instead of targeted edits
|
|
33
|
-
- Missing tests for new code
|
|
34
|
-
- SQL injection, XSS, command injection
|
|
35
|
-
- Destructive operations
|
|
36
|
-
4. If blocking issues found, fix them and re-review
|
|
37
|
-
5. If clean, proceed
|
|
38
|
-
|
|
39
|
-
### Step 4 — Test audit
|
|
40
|
-
Verify test quality:
|
|
41
|
-
1. Every changed source file has corresponding tests
|
|
42
|
-
2. Run `npm test` (or equivalent) — all must pass
|
|
43
|
-
3. No skipped tests for changed code
|
|
44
|
-
4. If tests fail, fix before proceeding
|
|
45
|
-
|
|
46
|
-
### Step 5 — Security scan
|
|
47
|
-
Quick security audit on the diff:
|
|
48
|
-
1. Scan for OWASP top 10 in changed files
|
|
49
|
-
2. Check for leaked secrets, injection vectors, missing auth
|
|
50
|
-
3. If critical/high findings, fix before proceeding
|
|
51
|
-
|
|
52
|
-
### Step 6 — Sonar (if available)
|
|
53
|
-
If SonarQube is running (`docker ps | grep sonarqube`):
|
|
54
|
-
1. Run `npx @sonar/scan`
|
|
55
|
-
2. Check quality gate
|
|
56
|
-
3. Fix blockers and critical issues
|
|
57
|
-
|
|
58
|
-
### Step 7 — Commit
|
|
59
|
-
If all steps pass:
|
|
60
|
-
1. Stage changed files: `git add <specific files>`
|
|
61
|
-
2. Commit with conventional commit message: `feat:`, `fix:`, `refactor:`, etc.
|
|
62
|
-
3. Do NOT push unless the user explicitly asks
|
|
63
|
-
|
|
64
|
-
## HU Board Integration
|
|
65
|
-
If HU Board is enabled (`hu_board.enabled: true` in config), stories and sessions
|
|
66
|
-
are automatically tracked and visible at the board URL. Run `kj board` to start it.
|
|
67
|
-
|
|
68
|
-
## Important rules
|
|
69
|
-
|
|
70
|
-
- **Never skip steps** — execute all applicable steps in order
|
|
71
|
-
- **Fix before proceeding** — if a step finds issues, fix them before moving to the next
|
|
72
|
-
- **Report progress** — after each step, briefly state what was done and the result
|
|
73
|
-
- **Stop on critical** — if a critical security or correctness issue can't be fixed, stop and report
|