cclaw-cli 7.7.0 → 8.1.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 +210 -134
- package/dist/artifact-frontmatter.d.ts +51 -0
- package/dist/artifact-frontmatter.js +131 -0
- package/dist/artifact-paths.d.ts +7 -27
- package/dist/artifact-paths.js +20 -249
- package/dist/cancel.d.ts +16 -0
- package/dist/cancel.js +66 -0
- package/dist/cli.d.ts +2 -27
- package/dist/cli.js +90 -508
- package/dist/compound.d.ts +26 -0
- package/dist/compound.js +96 -0
- package/dist/config.d.ts +14 -51
- package/dist/config.js +23 -359
- package/dist/constants.d.ts +11 -18
- package/dist/constants.js +19 -106
- package/dist/content/antipatterns.d.ts +1 -0
- package/dist/content/antipatterns.js +109 -0
- package/dist/content/artifact-templates.d.ts +10 -0
- package/dist/content/artifact-templates.js +550 -0
- package/dist/content/cancel-command.d.ts +2 -2
- package/dist/content/cancel-command.js +25 -17
- package/dist/content/core-agents.d.ts +9 -233
- package/dist/content/core-agents.js +39 -766
- package/dist/content/decision-protocol.d.ts +1 -12
- package/dist/content/decision-protocol.js +27 -20
- package/dist/content/examples.d.ts +8 -42
- package/dist/content/examples.js +293 -425
- package/dist/content/idea-command.d.ts +2 -0
- package/dist/content/idea-command.js +38 -0
- package/dist/content/iron-laws.d.ts +4 -138
- package/dist/content/iron-laws.js +18 -197
- package/dist/content/meta-skill.d.ts +1 -3
- package/dist/content/meta-skill.js +57 -132
- package/dist/content/node-hooks.d.ts +12 -8
- package/dist/content/node-hooks.js +188 -838
- package/dist/content/recovery.d.ts +8 -0
- package/dist/content/recovery.js +179 -0
- package/dist/content/reference-patterns.d.ts +4 -13
- package/dist/content/reference-patterns.js +260 -389
- package/dist/content/research-playbooks.d.ts +8 -8
- package/dist/content/research-playbooks.js +108 -121
- package/dist/content/review-loop.d.ts +6 -192
- package/dist/content/review-loop.js +29 -731
- package/dist/content/skills.d.ts +8 -38
- package/dist/content/skills.js +681 -732
- package/dist/content/specialist-prompts/architect.d.ts +1 -0
- package/dist/content/specialist-prompts/architect.js +225 -0
- package/dist/content/specialist-prompts/brainstormer.d.ts +1 -0
- package/dist/content/specialist-prompts/brainstormer.js +168 -0
- package/dist/content/specialist-prompts/index.d.ts +2 -0
- package/dist/content/specialist-prompts/index.js +14 -0
- package/dist/content/specialist-prompts/planner.d.ts +1 -0
- package/dist/content/specialist-prompts/planner.js +182 -0
- package/dist/content/specialist-prompts/reviewer.d.ts +1 -0
- package/dist/content/specialist-prompts/reviewer.js +193 -0
- package/dist/content/specialist-prompts/security-reviewer.d.ts +1 -0
- package/dist/content/specialist-prompts/security-reviewer.js +133 -0
- package/dist/content/specialist-prompts/slice-builder.d.ts +1 -0
- package/dist/content/specialist-prompts/slice-builder.js +232 -0
- package/dist/content/stage-playbooks.d.ts +8 -0
- package/dist/content/stage-playbooks.js +404 -0
- package/dist/content/start-command.d.ts +2 -12
- package/dist/content/start-command.js +221 -207
- package/dist/flow-state.d.ts +21 -178
- package/dist/flow-state.js +67 -170
- package/dist/fs-utils.d.ts +6 -26
- package/dist/fs-utils.js +29 -162
- package/dist/gitignore.d.ts +2 -1
- package/dist/gitignore.js +51 -34
- package/dist/harness-detect.d.ts +10 -0
- package/dist/harness-detect.js +29 -0
- package/dist/install.d.ts +27 -15
- package/dist/install.js +230 -1342
- package/dist/knowledge-store.d.ts +19 -163
- package/dist/knowledge-store.js +56 -590
- package/dist/logger.d.ts +8 -3
- package/dist/logger.js +13 -4
- package/dist/orchestrator-routing.d.ts +29 -0
- package/dist/orchestrator-routing.js +156 -0
- package/dist/run-persistence.d.ts +7 -118
- package/dist/run-persistence.js +29 -845
- package/dist/runtime/run-hook.entry.d.ts +1 -3
- package/dist/runtime/run-hook.entry.js +19 -4
- package/dist/runtime/run-hook.mjs +13 -1024
- package/dist/types.d.ts +25 -261
- package/dist/types.js +8 -36
- package/package.json +6 -3
- package/dist/artifact-linter/brainstorm.d.ts +0 -2
- package/dist/artifact-linter/brainstorm.js +0 -353
- package/dist/artifact-linter/design.d.ts +0 -18
- package/dist/artifact-linter/design.js +0 -444
- package/dist/artifact-linter/findings-dedup.d.ts +0 -56
- package/dist/artifact-linter/findings-dedup.js +0 -232
- package/dist/artifact-linter/plan.d.ts +0 -2
- package/dist/artifact-linter/plan.js +0 -826
- package/dist/artifact-linter/review-army.d.ts +0 -49
- package/dist/artifact-linter/review-army.js +0 -520
- package/dist/artifact-linter/review.d.ts +0 -2
- package/dist/artifact-linter/review.js +0 -113
- package/dist/artifact-linter/scope.d.ts +0 -2
- package/dist/artifact-linter/scope.js +0 -158
- package/dist/artifact-linter/shared.d.ts +0 -637
- package/dist/artifact-linter/shared.js +0 -2163
- package/dist/artifact-linter/ship.d.ts +0 -2
- package/dist/artifact-linter/ship.js +0 -250
- package/dist/artifact-linter/spec.d.ts +0 -2
- package/dist/artifact-linter/spec.js +0 -176
- package/dist/artifact-linter/tdd.d.ts +0 -118
- package/dist/artifact-linter/tdd.js +0 -1404
- package/dist/artifact-linter.d.ts +0 -15
- package/dist/artifact-linter.js +0 -517
- package/dist/codex-feature-flag.d.ts +0 -58
- package/dist/codex-feature-flag.js +0 -193
- package/dist/content/closeout-guidance.d.ts +0 -14
- package/dist/content/closeout-guidance.js +0 -44
- package/dist/content/diff-command.d.ts +0 -1
- package/dist/content/diff-command.js +0 -43
- package/dist/content/harness-doc.d.ts +0 -1
- package/dist/content/harness-doc.js +0 -65
- package/dist/content/hook-events.d.ts +0 -9
- package/dist/content/hook-events.js +0 -23
- package/dist/content/hook-manifest.d.ts +0 -81
- package/dist/content/hook-manifest.js +0 -156
- package/dist/content/hooks.d.ts +0 -11
- package/dist/content/hooks.js +0 -1972
- package/dist/content/idea.d.ts +0 -60
- package/dist/content/idea.js +0 -416
- package/dist/content/language-policy.d.ts +0 -2
- package/dist/content/language-policy.js +0 -13
- package/dist/content/learnings.d.ts +0 -6
- package/dist/content/learnings.js +0 -141
- package/dist/content/observe.d.ts +0 -19
- package/dist/content/observe.js +0 -86
- package/dist/content/opencode-plugin.d.ts +0 -1
- package/dist/content/opencode-plugin.js +0 -635
- package/dist/content/review-prompts.d.ts +0 -1
- package/dist/content/review-prompts.js +0 -104
- package/dist/content/runtime-shared-snippets.d.ts +0 -8
- package/dist/content/runtime-shared-snippets.js +0 -80
- package/dist/content/session-hooks.d.ts +0 -7
- package/dist/content/session-hooks.js +0 -107
- package/dist/content/skills-elicitation.d.ts +0 -1
- package/dist/content/skills-elicitation.js +0 -167
- package/dist/content/stage-command.d.ts +0 -2
- package/dist/content/stage-command.js +0 -17
- package/dist/content/stage-schema.d.ts +0 -117
- package/dist/content/stage-schema.js +0 -955
- package/dist/content/stages/_lint-metadata/index.d.ts +0 -2
- package/dist/content/stages/_lint-metadata/index.js +0 -97
- package/dist/content/stages/brainstorm.d.ts +0 -2
- package/dist/content/stages/brainstorm.js +0 -184
- package/dist/content/stages/design.d.ts +0 -2
- package/dist/content/stages/design.js +0 -288
- package/dist/content/stages/index.d.ts +0 -8
- package/dist/content/stages/index.js +0 -11
- package/dist/content/stages/plan.d.ts +0 -2
- package/dist/content/stages/plan.js +0 -191
- package/dist/content/stages/review.d.ts +0 -2
- package/dist/content/stages/review.js +0 -240
- package/dist/content/stages/schema-types.d.ts +0 -203
- package/dist/content/stages/schema-types.js +0 -1
- package/dist/content/stages/scope.d.ts +0 -2
- package/dist/content/stages/scope.js +0 -254
- package/dist/content/stages/ship.d.ts +0 -2
- package/dist/content/stages/ship.js +0 -159
- package/dist/content/stages/spec.d.ts +0 -2
- package/dist/content/stages/spec.js +0 -170
- package/dist/content/stages/tdd.d.ts +0 -4
- package/dist/content/stages/tdd.js +0 -273
- package/dist/content/state-contracts.d.ts +0 -1
- package/dist/content/state-contracts.js +0 -63
- package/dist/content/status-command.d.ts +0 -4
- package/dist/content/status-command.js +0 -109
- package/dist/content/subagent-context-skills.d.ts +0 -4
- package/dist/content/subagent-context-skills.js +0 -279
- package/dist/content/subagents.d.ts +0 -3
- package/dist/content/subagents.js +0 -997
- package/dist/content/templates.d.ts +0 -26
- package/dist/content/templates.js +0 -1692
- package/dist/content/track-render-context.d.ts +0 -18
- package/dist/content/track-render-context.js +0 -53
- package/dist/content/tree-command.d.ts +0 -1
- package/dist/content/tree-command.js +0 -64
- package/dist/content/utility-skills.d.ts +0 -30
- package/dist/content/utility-skills.js +0 -160
- package/dist/content/view-command.d.ts +0 -2
- package/dist/content/view-command.js +0 -92
- package/dist/delegation.d.ts +0 -649
- package/dist/delegation.js +0 -1539
- package/dist/early-loop.d.ts +0 -70
- package/dist/early-loop.js +0 -302
- package/dist/execution-topology.d.ts +0 -36
- package/dist/execution-topology.js +0 -73
- package/dist/gate-evidence.d.ts +0 -85
- package/dist/gate-evidence.js +0 -631
- package/dist/harness-adapters.d.ts +0 -151
- package/dist/harness-adapters.js +0 -756
- package/dist/harness-selection.d.ts +0 -31
- package/dist/harness-selection.js +0 -214
- package/dist/hook-schema.d.ts +0 -6
- package/dist/hook-schema.js +0 -114
- package/dist/hook-schemas/claude-hooks.v1.json +0 -10
- package/dist/hook-schemas/codex-hooks.v1.json +0 -10
- package/dist/hook-schemas/cursor-hooks.v1.json +0 -13
- package/dist/init-detect.d.ts +0 -2
- package/dist/init-detect.js +0 -50
- package/dist/internal/advance-stage/advance.d.ts +0 -89
- package/dist/internal/advance-stage/advance.js +0 -655
- package/dist/internal/advance-stage/cancel-run.d.ts +0 -8
- package/dist/internal/advance-stage/cancel-run.js +0 -19
- package/dist/internal/advance-stage/flow-state-coercion.d.ts +0 -3
- package/dist/internal/advance-stage/flow-state-coercion.js +0 -81
- package/dist/internal/advance-stage/helpers.d.ts +0 -14
- package/dist/internal/advance-stage/helpers.js +0 -145
- package/dist/internal/advance-stage/hook.d.ts +0 -8
- package/dist/internal/advance-stage/hook.js +0 -40
- package/dist/internal/advance-stage/parsers.d.ts +0 -72
- package/dist/internal/advance-stage/parsers.js +0 -357
- package/dist/internal/advance-stage/proactive-delegation-trace.d.ts +0 -24
- package/dist/internal/advance-stage/proactive-delegation-trace.js +0 -56
- package/dist/internal/advance-stage/review-loop.d.ts +0 -16
- package/dist/internal/advance-stage/review-loop.js +0 -199
- package/dist/internal/advance-stage/rewind.d.ts +0 -14
- package/dist/internal/advance-stage/rewind.js +0 -108
- package/dist/internal/advance-stage/start-flow.d.ts +0 -13
- package/dist/internal/advance-stage/start-flow.js +0 -241
- package/dist/internal/advance-stage/verify.d.ts +0 -21
- package/dist/internal/advance-stage/verify.js +0 -185
- package/dist/internal/advance-stage.d.ts +0 -7
- package/dist/internal/advance-stage.js +0 -138
- package/dist/internal/cohesion-contract-stub.d.ts +0 -24
- package/dist/internal/cohesion-contract-stub.js +0 -148
- package/dist/internal/compound-readiness.d.ts +0 -23
- package/dist/internal/compound-readiness.js +0 -102
- package/dist/internal/detect-public-api-changes.d.ts +0 -5
- package/dist/internal/detect-public-api-changes.js +0 -45
- package/dist/internal/detect-supply-chain-changes.d.ts +0 -6
- package/dist/internal/detect-supply-chain-changes.js +0 -138
- package/dist/internal/early-loop-status.d.ts +0 -7
- package/dist/internal/early-loop-status.js +0 -93
- package/dist/internal/envelope-validate.d.ts +0 -7
- package/dist/internal/envelope-validate.js +0 -66
- package/dist/internal/flow-state-repair.d.ts +0 -20
- package/dist/internal/flow-state-repair.js +0 -104
- package/dist/internal/plan-split-waves.d.ts +0 -190
- package/dist/internal/plan-split-waves.js +0 -764
- package/dist/internal/runtime-integrity.d.ts +0 -7
- package/dist/internal/runtime-integrity.js +0 -268
- package/dist/internal/slice-commit.d.ts +0 -7
- package/dist/internal/slice-commit.js +0 -619
- package/dist/internal/tdd-loop-status.d.ts +0 -14
- package/dist/internal/tdd-loop-status.js +0 -68
- package/dist/internal/tdd-red-evidence.d.ts +0 -7
- package/dist/internal/tdd-red-evidence.js +0 -153
- package/dist/internal/waiver-grant.d.ts +0 -62
- package/dist/internal/waiver-grant.js +0 -294
- package/dist/internal/wave-status.d.ts +0 -63
- package/dist/internal/wave-status.js +0 -450
- package/dist/managed-resources.d.ts +0 -53
- package/dist/managed-resources.js +0 -313
- package/dist/policy.d.ts +0 -10
- package/dist/policy.js +0 -167
- package/dist/retro-gate.d.ts +0 -9
- package/dist/retro-gate.js +0 -47
- package/dist/run-archive.d.ts +0 -61
- package/dist/run-archive.js +0 -391
- package/dist/runs.d.ts +0 -2
- package/dist/runs.js +0 -2
- package/dist/stack-detection.d.ts +0 -116
- package/dist/stack-detection.js +0 -489
- package/dist/streaming/event-stream.d.ts +0 -31
- package/dist/streaming/event-stream.js +0 -114
- package/dist/tdd-cycle.d.ts +0 -107
- package/dist/tdd-cycle.js +0 -289
- package/dist/tdd-verification-evidence.d.ts +0 -17
- package/dist/tdd-verification-evidence.js +0 -122
- package/dist/track-heuristics.d.ts +0 -27
- package/dist/track-heuristics.js +0 -154
- package/dist/util/slice-id.d.ts +0 -58
- package/dist/util/slice-id.js +0 -89
- package/dist/worktree-manager.d.ts +0 -20
- package/dist/worktree-manager.js +0 -108
package/dist/tdd-cycle.d.ts
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
export type TddCyclePhase = "red" | "green" | "refactor";
|
|
2
|
-
export interface TddCycleEntry {
|
|
3
|
-
ts: string;
|
|
4
|
-
runId: string;
|
|
5
|
-
stage: string;
|
|
6
|
-
slice: string;
|
|
7
|
-
phase: TddCyclePhase;
|
|
8
|
-
command: string;
|
|
9
|
-
files?: string[];
|
|
10
|
-
exitCode?: number;
|
|
11
|
-
note?: string;
|
|
12
|
-
/**
|
|
13
|
-
* Optional acceptance-criterion IDs this log line relates to (e.g. `["AC-1"]`).
|
|
14
|
-
* Used by the Ralph Loop status summary to surface how many ACs have been
|
|
15
|
-
* closed by a GREEN cycle without forcing the user to track them manually.
|
|
16
|
-
*/
|
|
17
|
-
acIds?: string[];
|
|
18
|
-
}
|
|
19
|
-
export interface TddCycleValidation {
|
|
20
|
-
ok: boolean;
|
|
21
|
-
issues: string[];
|
|
22
|
-
openRedSlices: string[];
|
|
23
|
-
sliceCount: number;
|
|
24
|
-
}
|
|
25
|
-
export interface TddCycleParseIssue {
|
|
26
|
-
lineNumber: number;
|
|
27
|
-
reason: string;
|
|
28
|
-
rawLine: string;
|
|
29
|
-
}
|
|
30
|
-
export interface ParseTddCycleLogOptions {
|
|
31
|
-
/**
|
|
32
|
-
* Collect one issue per dropped/malformed line. Callers that care
|
|
33
|
-
* (sync/runtime checks, red-evidence) can surface them; hooks keep soft-fail.
|
|
34
|
-
*/
|
|
35
|
-
issues?: TddCycleParseIssue[];
|
|
36
|
-
/**
|
|
37
|
-
* When true, reject lines that omit required fields instead of
|
|
38
|
-
* back-filling them with defaults. Used by validation paths
|
|
39
|
-
* (`validateTddCycleOrder`, `npx cclaw-cli sync` fail-fast) to avoid silently
|
|
40
|
-
* bucketing unscoped rows into "runId=active, stage=tdd". Soft paths
|
|
41
|
-
* (generated hooks) keep the legacy defaults so a half-written file
|
|
42
|
-
* never takes the session down.
|
|
43
|
-
*/
|
|
44
|
-
strict?: boolean;
|
|
45
|
-
}
|
|
46
|
-
export declare function parseTddCycleLog(text: string, options?: ParseTddCycleLogOptions): TddCycleEntry[];
|
|
47
|
-
export declare function validateTddCycleOrder(entries: TddCycleEntry[], options?: {
|
|
48
|
-
runId?: string;
|
|
49
|
-
}): TddCycleValidation;
|
|
50
|
-
/**
|
|
51
|
-
* Canonical path normalization used by ALL TDD path-matching layers
|
|
52
|
-
* (cycle-log analysis, internal CLI `tdd-red-evidence`, and the
|
|
53
|
-
* inline runtime hook). Previously each layer had its own near-copy,
|
|
54
|
-
* which produced subtle drift (e.g. `./src/app.ts` vs `src/app.ts`
|
|
55
|
-
* differing between hook and CLI). Keep this function in one place
|
|
56
|
-
* so all callers agree.
|
|
57
|
-
*/
|
|
58
|
-
export declare function normalizeTddPath(value: string): string;
|
|
59
|
-
/**
|
|
60
|
-
* Shared "does the recorded file path refer to the target" matcher.
|
|
61
|
-
* Uses canonical normalization plus the traditional `endsWith('/'+x)`
|
|
62
|
-
* rule so a recorded `src/app.ts` matches either `src/app.ts` or
|
|
63
|
-
* `subdir/src/app.ts` but NOT `src/app.test.ts`. All TDD path checks
|
|
64
|
-
* MUST go through this helper.
|
|
65
|
-
*/
|
|
66
|
-
export declare function pathMatchesTarget(candidate: string, target: string): boolean;
|
|
67
|
-
export interface RalphLoopSliceState {
|
|
68
|
-
slice: string;
|
|
69
|
-
redCount: number;
|
|
70
|
-
greenCount: number;
|
|
71
|
-
refactorCount: number;
|
|
72
|
-
redOpen: boolean;
|
|
73
|
-
acIds: string[];
|
|
74
|
-
}
|
|
75
|
-
export interface RalphLoopStatus {
|
|
76
|
-
schemaVersion: 1;
|
|
77
|
-
runId: string;
|
|
78
|
-
/**
|
|
79
|
-
* Number of RED -> GREEN cycles observed for the run — a rough "Ralph Loop"
|
|
80
|
-
* iteration counter that mirrors how many passing tests the loop has
|
|
81
|
-
* delivered so far.
|
|
82
|
-
*/
|
|
83
|
-
loopIteration: number;
|
|
84
|
-
redOpen: boolean;
|
|
85
|
-
redOpenSlices: string[];
|
|
86
|
-
acClosed: string[];
|
|
87
|
-
sliceCount: number;
|
|
88
|
-
slices: RalphLoopSliceState[];
|
|
89
|
-
lastUpdatedAt: string;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Derive a lightweight Ralph Loop summary from parsed tdd-cycle-log entries.
|
|
93
|
-
* The goal is to give the model a single source of truth for "am I done
|
|
94
|
-
* iterating?" — it collapses per-slice progress and distinct closed AC IDs
|
|
95
|
-
* (from GREEN rows) into a single artifact the progression contract reads.
|
|
96
|
-
*/
|
|
97
|
-
export declare function computeRalphLoopStatus(entries: TddCycleEntry[], options?: {
|
|
98
|
-
runId?: string;
|
|
99
|
-
now?: Date;
|
|
100
|
-
}): RalphLoopStatus;
|
|
101
|
-
/**
|
|
102
|
-
* Checks whether the log contains a failing RED record associated with
|
|
103
|
-
* `productionPath` for the active run.
|
|
104
|
-
*/
|
|
105
|
-
export declare function hasFailingTestForPath(entries: TddCycleEntry[], productionPath: string, options?: {
|
|
106
|
-
runId?: string;
|
|
107
|
-
}): boolean;
|
package/dist/tdd-cycle.js
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import { isSliceId } from "./util/slice-id.js";
|
|
2
|
-
export function parseTddCycleLog(text, options = {}) {
|
|
3
|
-
const issues = options.issues;
|
|
4
|
-
const strict = options.strict === true;
|
|
5
|
-
const out = [];
|
|
6
|
-
// Strip a leading UTF-8 BOM on the whole blob so the first line parses
|
|
7
|
-
// cleanly; `trim()` handles BOM on subsequent lines through the same
|
|
8
|
-
// codepath (empty/whitespace-only lines are skipped).
|
|
9
|
-
const normalized = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
|
|
10
|
-
const lines = normalized.split(/\r?\n/);
|
|
11
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
12
|
-
const raw = lines[index] ?? "";
|
|
13
|
-
const line = raw.trim();
|
|
14
|
-
if (!line)
|
|
15
|
-
continue;
|
|
16
|
-
const lineNumber = index + 1;
|
|
17
|
-
let parsed;
|
|
18
|
-
try {
|
|
19
|
-
parsed = JSON.parse(line);
|
|
20
|
-
}
|
|
21
|
-
catch (err) {
|
|
22
|
-
issues?.push({
|
|
23
|
-
lineNumber,
|
|
24
|
-
reason: `json-parse-failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
25
|
-
rawLine: raw
|
|
26
|
-
});
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
const phase = parsed.phase;
|
|
30
|
-
if (phase !== "red" && phase !== "green" && phase !== "refactor") {
|
|
31
|
-
issues?.push({
|
|
32
|
-
lineNumber,
|
|
33
|
-
reason: `invalid-phase: ${JSON.stringify(parsed.phase)}`,
|
|
34
|
-
rawLine: raw
|
|
35
|
-
});
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
const runIdField = typeof parsed.runId === "string" ? parsed.runId : null;
|
|
39
|
-
const stageField = typeof parsed.stage === "string" ? parsed.stage : null;
|
|
40
|
-
const sliceField = typeof parsed.slice === "string" ? parsed.slice : null;
|
|
41
|
-
if (strict) {
|
|
42
|
-
const missing = [];
|
|
43
|
-
if (!runIdField)
|
|
44
|
-
missing.push("runId");
|
|
45
|
-
if (!stageField)
|
|
46
|
-
missing.push("stage");
|
|
47
|
-
if (!sliceField)
|
|
48
|
-
missing.push("slice");
|
|
49
|
-
if (missing.length > 0) {
|
|
50
|
-
issues?.push({
|
|
51
|
-
lineNumber,
|
|
52
|
-
reason: `missing-required-fields: ${missing.join(",")}`,
|
|
53
|
-
rawLine: raw
|
|
54
|
-
});
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
const entry = {
|
|
59
|
-
ts: typeof parsed.ts === "string" ? parsed.ts : "",
|
|
60
|
-
runId: runIdField ?? "active",
|
|
61
|
-
stage: stageField ?? "tdd",
|
|
62
|
-
slice: sliceField ?? "S-unknown",
|
|
63
|
-
phase,
|
|
64
|
-
command: typeof parsed.command === "string" ? parsed.command : "",
|
|
65
|
-
files: Array.isArray(parsed.files)
|
|
66
|
-
? parsed.files.filter((item) => typeof item === "string")
|
|
67
|
-
: undefined,
|
|
68
|
-
exitCode: typeof parsed.exitCode === "number" ? parsed.exitCode : undefined,
|
|
69
|
-
note: typeof parsed.note === "string" ? parsed.note : undefined,
|
|
70
|
-
acIds: Array.isArray(parsed.acIds)
|
|
71
|
-
? parsed.acIds
|
|
72
|
-
.filter((item) => typeof item === "string" && item.length > 0)
|
|
73
|
-
: undefined
|
|
74
|
-
};
|
|
75
|
-
out.push(entry);
|
|
76
|
-
}
|
|
77
|
-
return out;
|
|
78
|
-
}
|
|
79
|
-
export function validateTddCycleOrder(entries, options = {}) {
|
|
80
|
-
const targetRun = options.runId;
|
|
81
|
-
const filtered = targetRun
|
|
82
|
-
? entries.filter((entry) => entry.runId === targetRun)
|
|
83
|
-
: entries;
|
|
84
|
-
const bySlice = new Map();
|
|
85
|
-
for (const entry of filtered) {
|
|
86
|
-
const list = bySlice.get(entry.slice) ?? [];
|
|
87
|
-
list.push(entry);
|
|
88
|
-
bySlice.set(entry.slice, list);
|
|
89
|
-
}
|
|
90
|
-
const issues = [];
|
|
91
|
-
const openRedSlices = [];
|
|
92
|
-
// Reject slices whose ID does not match the stable slice-id contract.
|
|
93
|
-
// Entries that drop the slice field entirely were previously coerced to
|
|
94
|
-
// `S-unknown` and silently bucketed together, which means multiple distinct
|
|
95
|
-
// cycles could appear to share a RED/GREEN pair. 7.6.0 relaxed the shape
|
|
96
|
-
// to allow lettered sub-slice ids (e.g. `S-36a`) so plan amendments can
|
|
97
|
-
// insert work between numeric slices without renumbering.
|
|
98
|
-
for (const slice of bySlice.keys()) {
|
|
99
|
-
if (!isSliceId(slice)) {
|
|
100
|
-
issues.push(`slice "${slice}": id must match S-<number>(<letter><suffix>)? (e.g. S-1, S-36a); repair by re-logging RED/GREEN/REFACTOR with a stable slice id.`);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
for (const [slice, sliceEntries] of bySlice.entries()) {
|
|
104
|
-
let state = "need_red";
|
|
105
|
-
for (const entry of sliceEntries) {
|
|
106
|
-
if (entry.phase === "red") {
|
|
107
|
-
if (entry.exitCode === undefined) {
|
|
108
|
-
issues.push(`slice ${slice}: RED repair needed: red entry must record a non-zero exitCode from a failing test.`);
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
if (entry.exitCode === 0) {
|
|
112
|
-
issues.push(`slice ${slice}: RED repair needed: red entry exitCode must be non-zero; passing output is not RED evidence.`);
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
if (state === "red_open") {
|
|
116
|
-
issues.push(`slice ${slice}: RED/GREEN repair needed: duplicate RED before GREEN; record the GREEN pass that closes the prior RED or split into a new slice.`);
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
state = "red_open";
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (entry.phase === "green") {
|
|
123
|
-
if (entry.exitCode === undefined) {
|
|
124
|
-
issues.push(`slice ${slice}: GREEN repair needed: green entry must record exitCode 0 from the verification command.`);
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
if (entry.exitCode !== 0) {
|
|
128
|
-
issues.push(`slice ${slice}: GREEN repair needed: green entry exitCode must be 0; fix regressions before advancing.`);
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
if (state !== "red_open") {
|
|
132
|
-
issues.push(`slice ${slice}: GREEN repair needed: green logged before RED; add the failing RED test evidence first.`);
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
state = "green_done";
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
// refactor — must preserve the passing state established by green.
|
|
139
|
-
if (entry.exitCode === undefined) {
|
|
140
|
-
issues.push(`slice ${slice}: REFACTOR repair needed: refactor entry must record exitCode 0 proving behavior stayed green.`);
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
if (entry.exitCode !== 0) {
|
|
144
|
-
issues.push(`slice ${slice}: REFACTOR repair needed: tests must stay green after cleanup; rerun/fix before closing the slice.`);
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (state !== "green_done") {
|
|
148
|
-
issues.push(`slice ${slice}: REFACTOR repair needed: refactor logged before GREEN; prove GREEN first, then cleanup.`);
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (state === "red_open") {
|
|
153
|
-
openRedSlices.push(slice);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
ok: issues.length === 0 && openRedSlices.length === 0,
|
|
158
|
-
issues,
|
|
159
|
-
openRedSlices,
|
|
160
|
-
sliceCount: bySlice.size
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Canonical path normalization used by ALL TDD path-matching layers
|
|
165
|
-
* (cycle-log analysis, internal CLI `tdd-red-evidence`, and the
|
|
166
|
-
* inline runtime hook). Previously each layer had its own near-copy,
|
|
167
|
-
* which produced subtle drift (e.g. `./src/app.ts` vs `src/app.ts`
|
|
168
|
-
* differing between hook and CLI). Keep this function in one place
|
|
169
|
-
* so all callers agree.
|
|
170
|
-
*/
|
|
171
|
-
export function normalizeTddPath(value) {
|
|
172
|
-
const trimmed = String(value ?? "").trim();
|
|
173
|
-
return trimmed
|
|
174
|
-
.replace(/\\/gu, "/")
|
|
175
|
-
.replace(/^\.\//u, "")
|
|
176
|
-
.toLowerCase();
|
|
177
|
-
}
|
|
178
|
-
// Legacy alias kept for local callers below.
|
|
179
|
-
function normalizePath(value) {
|
|
180
|
-
return normalizeTddPath(value);
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Shared "does the recorded file path refer to the target" matcher.
|
|
184
|
-
* Uses canonical normalization plus the traditional `endsWith('/'+x)`
|
|
185
|
-
* rule so a recorded `src/app.ts` matches either `src/app.ts` or
|
|
186
|
-
* `subdir/src/app.ts` but NOT `src/app.test.ts`. All TDD path checks
|
|
187
|
-
* MUST go through this helper.
|
|
188
|
-
*/
|
|
189
|
-
export function pathMatchesTarget(candidate, target) {
|
|
190
|
-
const normalizedCandidate = normalizeTddPath(candidate);
|
|
191
|
-
const normalizedTarget = normalizeTddPath(target);
|
|
192
|
-
if (normalizedCandidate.length === 0 || normalizedTarget.length === 0) {
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
if (normalizedCandidate === normalizedTarget) {
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
// Only allow suffix matching for multi-segment targets. A bare basename
|
|
199
|
-
// like `app.ts` is too broad and can match unrelated files in any folder.
|
|
200
|
-
return normalizedTarget.includes("/") && normalizedCandidate.endsWith(`/${normalizedTarget}`);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Derive a lightweight Ralph Loop summary from parsed tdd-cycle-log entries.
|
|
204
|
-
* The goal is to give the model a single source of truth for "am I done
|
|
205
|
-
* iterating?" — it collapses per-slice progress and distinct closed AC IDs
|
|
206
|
-
* (from GREEN rows) into a single artifact the progression contract reads.
|
|
207
|
-
*/
|
|
208
|
-
export function computeRalphLoopStatus(entries, options = {}) {
|
|
209
|
-
const runId = options.runId ?? "active";
|
|
210
|
-
const filtered = entries.filter((entry) => options.runId ? entry.runId === options.runId : true);
|
|
211
|
-
const slicesMap = new Map();
|
|
212
|
-
const acClosedSet = new Set();
|
|
213
|
-
let loopIteration = 0;
|
|
214
|
-
const redOpenSlices = [];
|
|
215
|
-
for (const slice of Array.from(new Set(filtered.map((entry) => entry.slice)))) {
|
|
216
|
-
slicesMap.set(slice, {
|
|
217
|
-
slice,
|
|
218
|
-
redCount: 0,
|
|
219
|
-
greenCount: 0,
|
|
220
|
-
refactorCount: 0,
|
|
221
|
-
redOpen: false,
|
|
222
|
-
acIds: []
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
for (const entry of filtered) {
|
|
226
|
-
const state = slicesMap.get(entry.slice);
|
|
227
|
-
if (!state)
|
|
228
|
-
continue;
|
|
229
|
-
if (entry.phase === "red") {
|
|
230
|
-
state.redCount += 1;
|
|
231
|
-
if (entry.exitCode !== undefined && entry.exitCode !== 0) {
|
|
232
|
-
state.redOpen = true;
|
|
233
|
-
}
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
if (entry.phase === "green") {
|
|
237
|
-
state.greenCount += 1;
|
|
238
|
-
state.redOpen = false;
|
|
239
|
-
loopIteration += 1;
|
|
240
|
-
if (Array.isArray(entry.acIds)) {
|
|
241
|
-
for (const acId of entry.acIds) {
|
|
242
|
-
acClosedSet.add(acId);
|
|
243
|
-
if (!state.acIds.includes(acId))
|
|
244
|
-
state.acIds.push(acId);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
state.refactorCount += 1;
|
|
250
|
-
}
|
|
251
|
-
for (const state of slicesMap.values()) {
|
|
252
|
-
if (state.redOpen)
|
|
253
|
-
redOpenSlices.push(state.slice);
|
|
254
|
-
}
|
|
255
|
-
const slices = Array.from(slicesMap.values()).sort((a, b) => a.slice.localeCompare(b.slice, "en"));
|
|
256
|
-
return {
|
|
257
|
-
schemaVersion: 1,
|
|
258
|
-
runId,
|
|
259
|
-
loopIteration,
|
|
260
|
-
redOpen: redOpenSlices.length > 0,
|
|
261
|
-
redOpenSlices,
|
|
262
|
-
acClosed: Array.from(acClosedSet).sort(),
|
|
263
|
-
sliceCount: slices.length,
|
|
264
|
-
slices,
|
|
265
|
-
lastUpdatedAt: (options.now ?? new Date()).toISOString()
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Checks whether the log contains a failing RED record associated with
|
|
270
|
-
* `productionPath` for the active run.
|
|
271
|
-
*/
|
|
272
|
-
export function hasFailingTestForPath(entries, productionPath, options = {}) {
|
|
273
|
-
const filtered = options.runId
|
|
274
|
-
? entries.filter((entry) => entry.runId === options.runId)
|
|
275
|
-
: entries;
|
|
276
|
-
for (const entry of filtered) {
|
|
277
|
-
if (entry.phase !== "red")
|
|
278
|
-
continue;
|
|
279
|
-
if (entry.exitCode === undefined || entry.exitCode === 0)
|
|
280
|
-
continue;
|
|
281
|
-
if (!Array.isArray(entry.files) || entry.files.length === 0)
|
|
282
|
-
continue;
|
|
283
|
-
const hasMatch = entry.files.some((filePath) => pathMatchesTarget(filePath, productionPath));
|
|
284
|
-
if (hasMatch) {
|
|
285
|
-
return true;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return false;
|
|
289
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare const TEST_COMMAND_HINT_PATTERN: RegExp;
|
|
2
|
-
export declare const SHA_WITH_LABEL_PATTERN: RegExp;
|
|
3
|
-
export declare const PASS_STATUS_PATTERN: RegExp;
|
|
4
|
-
export declare const NO_VCS_ATTESTATION_PATTERN: RegExp;
|
|
5
|
-
export declare const NO_VCS_HASH_PATTERN: RegExp;
|
|
6
|
-
export type TddVerificationRefMode = "auto" | "required" | "disabled";
|
|
7
|
-
export interface TddVerificationEvidenceOptions {
|
|
8
|
-
requireCommand?: boolean;
|
|
9
|
-
requirePassStatus?: boolean;
|
|
10
|
-
}
|
|
11
|
-
export interface TddVerificationEvidenceResult {
|
|
12
|
-
ok: boolean;
|
|
13
|
-
issues: string[];
|
|
14
|
-
mode: TddVerificationRefMode;
|
|
15
|
-
gitPresent: boolean;
|
|
16
|
-
}
|
|
17
|
-
export declare function validateTddVerificationEvidence(projectRoot: string, evidence: string, options?: TddVerificationEvidenceOptions): Promise<TddVerificationEvidenceResult>;
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { promisify } from "node:util";
|
|
4
|
-
import { readConfig, resolveTddCommitMode } from "./config.js";
|
|
5
|
-
import { readDelegationLedger } from "./delegation.js";
|
|
6
|
-
import { exists } from "./fs-utils.js";
|
|
7
|
-
const execFileAsync = promisify(execFile);
|
|
8
|
-
export const TEST_COMMAND_HINT_PATTERN = /\b(?:npm test|npm run test(?::[\w:-]+)?|pnpm test|pnpm [\w:-]*test[\w:-]*|yarn test|yarn [\w:-]*test[\w:-]*|bun test|bun run test(?::[\w:-]+)?|vitest|jest|pytest|go test|cargo test|mvn test|gradle test|\.\/gradlew test|dotnet test)\b/iu;
|
|
9
|
-
export const SHA_WITH_LABEL_PATTERN = /\b(?:sha|commit)(?:\s*[:=]|\s+)\s*[0-9a-f]{7,40}\b/iu;
|
|
10
|
-
export const PASS_STATUS_PATTERN = /\b(?:pass|passed|green|ok)\b/iu;
|
|
11
|
-
export const NO_VCS_ATTESTATION_PATTERN = /\b(?:no[-_ ]?vcs|no git|not a git repo|vcs\s*[:=]\s*none)\b/iu;
|
|
12
|
-
export const NO_VCS_HASH_PATTERN = /\b(?:content|artifact)[-_ ]?hash\s*[:=]\s*(?:sha256:)?[0-9a-f]{16,64}\b|\bsha256\s*[:=]\s*[0-9a-f]{16,64}\b/iu;
|
|
13
|
-
function escapeRegex(value) {
|
|
14
|
-
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
15
|
-
}
|
|
16
|
-
function hasRefactorCoverage(entries) {
|
|
17
|
-
const phases = new Set(entries
|
|
18
|
-
.filter((e) => e.status === "completed" && typeof e.phase === "string")
|
|
19
|
-
.map((e) => e.phase));
|
|
20
|
-
if (phases.has("refactor") || phases.has("refactor-deferred")) {
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
const greenWithOutcome = entries.find((entry) => entry.status === "completed" &&
|
|
24
|
-
entry.phase === "green" &&
|
|
25
|
-
entry.refactorOutcome &&
|
|
26
|
-
(entry.refactorOutcome.mode === "inline" || entry.refactorOutcome.mode === "deferred"));
|
|
27
|
-
if (!greenWithOutcome?.refactorOutcome)
|
|
28
|
-
return false;
|
|
29
|
-
if (greenWithOutcome.refactorOutcome.mode === "inline")
|
|
30
|
-
return true;
|
|
31
|
-
const rationale = greenWithOutcome.refactorOutcome.rationale;
|
|
32
|
-
if (typeof rationale === "string" && rationale.trim().length > 0)
|
|
33
|
-
return true;
|
|
34
|
-
if (!Array.isArray(greenWithOutcome.evidenceRefs))
|
|
35
|
-
return false;
|
|
36
|
-
return greenWithOutcome.evidenceRefs.some((ref) => typeof ref === "string" && ref.trim().length > 0);
|
|
37
|
-
}
|
|
38
|
-
function collectClosedSlices(entries, runId) {
|
|
39
|
-
const bySlice = new Map();
|
|
40
|
-
for (const entry of entries) {
|
|
41
|
-
if (entry.runId !== runId)
|
|
42
|
-
continue;
|
|
43
|
-
if (entry.stage !== "tdd")
|
|
44
|
-
continue;
|
|
45
|
-
if (entry.status !== "completed")
|
|
46
|
-
continue;
|
|
47
|
-
if (typeof entry.sliceId !== "string" || entry.sliceId.length === 0)
|
|
48
|
-
continue;
|
|
49
|
-
if (typeof entry.spanId !== "string" || entry.spanId.length === 0)
|
|
50
|
-
continue;
|
|
51
|
-
const bySpan = bySlice.get(entry.sliceId) ?? new Map();
|
|
52
|
-
const rows = bySpan.get(entry.spanId) ?? [];
|
|
53
|
-
rows.push(entry);
|
|
54
|
-
bySpan.set(entry.spanId, rows);
|
|
55
|
-
bySlice.set(entry.sliceId, bySpan);
|
|
56
|
-
}
|
|
57
|
-
const closedSlices = new Set();
|
|
58
|
-
for (const [sliceId, bySpan] of bySlice.entries()) {
|
|
59
|
-
for (const rows of bySpan.values()) {
|
|
60
|
-
const phases = new Set(rows
|
|
61
|
-
.filter((row) => row.status === "completed" && typeof row.phase === "string")
|
|
62
|
-
.map((row) => row.phase));
|
|
63
|
-
const hasRed = phases.has("red");
|
|
64
|
-
const hasGreen = phases.has("green");
|
|
65
|
-
const hasDoc = phases.has("doc");
|
|
66
|
-
if (hasRed && hasGreen && hasDoc && hasRefactorCoverage(rows)) {
|
|
67
|
-
closedSlices.add(sliceId);
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return [...closedSlices].sort();
|
|
73
|
-
}
|
|
74
|
-
async function hasManagedCommitForSlice(projectRoot, sliceId) {
|
|
75
|
-
const grep = `^${escapeRegex(sliceId)}/`;
|
|
76
|
-
const { stdout } = await execFileAsync("git", ["log", "--format=%s%n%b", "--grep", grep], { cwd: projectRoot });
|
|
77
|
-
return stdout.trim().length > 0;
|
|
78
|
-
}
|
|
79
|
-
export async function validateTddVerificationEvidence(projectRoot, evidence, options = {}) {
|
|
80
|
-
const normalized = evidence.trim();
|
|
81
|
-
const config = await readConfig(projectRoot).catch(() => null);
|
|
82
|
-
const commitMode = resolveTddCommitMode(config);
|
|
83
|
-
const mode = commitMode === "off" ? "disabled" : "auto";
|
|
84
|
-
const gitPresent = await exists(path.join(projectRoot, ".git"));
|
|
85
|
-
const issues = [];
|
|
86
|
-
if (options.requireCommand !== false && !TEST_COMMAND_HINT_PATTERN.test(normalized)) {
|
|
87
|
-
issues.push("GREEN repair needed: include the fresh verification command that was run (for example `npm test`, `pytest`, `go test`, or equivalent).");
|
|
88
|
-
}
|
|
89
|
-
if (options.requirePassStatus !== false && !PASS_STATUS_PATTERN.test(normalized)) {
|
|
90
|
-
issues.push("GREEN repair needed: include explicit success status (for example `PASS` or `GREEN`).");
|
|
91
|
-
}
|
|
92
|
-
if (mode !== "disabled" && commitMode === "managed-per-slice" && gitPresent) {
|
|
93
|
-
const ledger = await readDelegationLedger(projectRoot).catch(() => null);
|
|
94
|
-
if (ledger && typeof ledger.runId === "string" && ledger.runId.length > 0) {
|
|
95
|
-
const closedSlices = collectClosedSlices(ledger.entries, ledger.runId);
|
|
96
|
-
const missing = [];
|
|
97
|
-
for (const sliceId of closedSlices) {
|
|
98
|
-
const hasCommit = await hasManagedCommitForSlice(projectRoot, sliceId).catch(() => false);
|
|
99
|
-
if (!hasCommit) {
|
|
100
|
-
missing.push(sliceId);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (missing.length > 0) {
|
|
104
|
-
issues.push(`managed-per-slice commit check failed: missing git commit(s) for closed slice(s): ${missing.join(", ")}.`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
else if (mode === "auto") {
|
|
109
|
-
const hasSha = SHA_WITH_LABEL_PATTERN.test(normalized);
|
|
110
|
-
const hasNoVcs = NO_VCS_ATTESTATION_PATTERN.test(normalized);
|
|
111
|
-
if (gitPresent && !hasSha) {
|
|
112
|
-
issues.push("must include a commit SHA token prefixed with `sha` or `commit` (for example `sha: abc1234`).");
|
|
113
|
-
}
|
|
114
|
-
else if (!gitPresent && !hasSha && !hasNoVcs) {
|
|
115
|
-
issues.push("must include either a commit SHA or an explicit no-VCS attestation (for example `no-vcs: project has no .git directory`).");
|
|
116
|
-
}
|
|
117
|
-
else if (!gitPresent && hasNoVcs && !NO_VCS_HASH_PATTERN.test(normalized)) {
|
|
118
|
-
issues.push("NO_VCS_MODE repair needed: include a content/artifact hash for no-VCS TDD evidence (for example `artifact-hash: sha256:<hash>`).");
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return { ok: issues.length === 0, issues, mode, gitPresent };
|
|
122
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { DiscoveryMode, FlowStage, FlowTrack, TrackHeuristicRule, TrackHeuristicsConfig } from "./types.js";
|
|
2
|
-
export interface TrackResolution {
|
|
3
|
-
track: FlowTrack;
|
|
4
|
-
reason: string;
|
|
5
|
-
matchedTokens: string[];
|
|
6
|
-
confidence: "high" | "medium" | "low";
|
|
7
|
-
overrideGuidance: string;
|
|
8
|
-
}
|
|
9
|
-
export interface QuestionBudgetHint {
|
|
10
|
-
min: number;
|
|
11
|
-
recommended: number;
|
|
12
|
-
hardCapWarning: number;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Reference implementation of the track classifier the /cc skill prose
|
|
16
|
-
* describes. Tests pin its behavior so the built-in defaults stay honest.
|
|
17
|
-
* This function is not called from cclaw runtime — `/cc` routing happens in
|
|
18
|
-
* the LLM. If you wire this in later, update README to drop the
|
|
19
|
-
* "advisory" language.
|
|
20
|
-
*/
|
|
21
|
-
export declare function resolveTrackFromPrompt(prompt: string, config: TrackHeuristicsConfig | undefined): TrackResolution;
|
|
22
|
-
export declare function questionBudgetHint(modeOrTrack: DiscoveryMode | FlowTrack, stage: FlowStage): QuestionBudgetHint;
|
|
23
|
-
export declare const TRACK_HEURISTICS_DEFAULTS: {
|
|
24
|
-
readonly fallback: "standard";
|
|
25
|
-
readonly evaluationOrder: readonly ("quick" | "medium" | "standard")[];
|
|
26
|
-
readonly tracks: Record<"quick" | "medium" | "standard", TrackHeuristicRule>;
|
|
27
|
-
};
|