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
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { readConfig } from "../config.js";
|
|
4
|
-
import { RUNTIME_ROOT } from "../constants.js";
|
|
5
|
-
import { exists } from "../fs-utils.js";
|
|
6
|
-
import { HARNESS_ADAPTERS, harnessShimFileNames, harnessShimSkillNames } from "../harness-adapters.js";
|
|
7
|
-
import { validateHookDocument } from "../hook-schema.js";
|
|
8
|
-
import { MANAGED_RESOURCE_MANIFEST_REL_PATH, validateManagedResourceManifest } from "../managed-resources.js";
|
|
9
|
-
import { CorruptFlowStateError, readFlowState } from "../runs.js";
|
|
10
|
-
function parseArgs(tokens) {
|
|
11
|
-
const args = { json: false, quiet: false };
|
|
12
|
-
for (const token of tokens) {
|
|
13
|
-
if (token === "--json") {
|
|
14
|
-
args.json = true;
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
if (token === "--quiet") {
|
|
18
|
-
args.quiet = true;
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
throw new Error(`Unknown runtime-integrity flag: ${token}`);
|
|
22
|
-
}
|
|
23
|
-
return args;
|
|
24
|
-
}
|
|
25
|
-
function stripJsonCommentsOutsideStrings(input) {
|
|
26
|
-
let out = "";
|
|
27
|
-
let i = 0;
|
|
28
|
-
let inString = false;
|
|
29
|
-
let escape = false;
|
|
30
|
-
while (i < input.length) {
|
|
31
|
-
const c = input[i];
|
|
32
|
-
if (inString) {
|
|
33
|
-
out += c;
|
|
34
|
-
if (escape) {
|
|
35
|
-
escape = false;
|
|
36
|
-
}
|
|
37
|
-
else if (c === "\\") {
|
|
38
|
-
escape = true;
|
|
39
|
-
}
|
|
40
|
-
else if (c === "\"") {
|
|
41
|
-
inString = false;
|
|
42
|
-
}
|
|
43
|
-
i += 1;
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
if (c === "\"") {
|
|
47
|
-
inString = true;
|
|
48
|
-
out += c;
|
|
49
|
-
i += 1;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
const next = input[i + 1];
|
|
53
|
-
if (c === "/" && next === "/") {
|
|
54
|
-
while (i < input.length && input[i] !== "\n" && input[i] !== "\r")
|
|
55
|
-
i += 1;
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (c === "/" && next === "*") {
|
|
59
|
-
i += 2;
|
|
60
|
-
while (i < input.length - 1 && !(input[i] === "*" && input[i + 1] === "/"))
|
|
61
|
-
i += 1;
|
|
62
|
-
i = Math.min(i + 2, input.length);
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
out += c;
|
|
66
|
-
i += 1;
|
|
67
|
-
}
|
|
68
|
-
return out;
|
|
69
|
-
}
|
|
70
|
-
function parseJsonWithRecovery(raw) {
|
|
71
|
-
try {
|
|
72
|
-
return JSON.parse(raw);
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
// Continue with comment/trailing-comma recovery.
|
|
76
|
-
}
|
|
77
|
-
try {
|
|
78
|
-
const normalized = stripJsonCommentsOutsideStrings(raw).replace(/,\s*([}\]])/gu, "$1");
|
|
79
|
-
return JSON.parse(normalized);
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function okFinding(id, message) {
|
|
86
|
-
return {
|
|
87
|
-
id,
|
|
88
|
-
severity: "error",
|
|
89
|
-
ok: true,
|
|
90
|
-
message
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function errorFinding(id, message, details) {
|
|
94
|
-
return {
|
|
95
|
-
id,
|
|
96
|
-
severity: "error",
|
|
97
|
-
ok: false,
|
|
98
|
-
message,
|
|
99
|
-
...(details && details.length > 0 ? { details } : {})
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
function warningFinding(id, ok, message, details) {
|
|
103
|
-
return {
|
|
104
|
-
id,
|
|
105
|
-
severity: "warning",
|
|
106
|
-
ok,
|
|
107
|
-
message,
|
|
108
|
-
...(details && details.length > 0 ? { details } : {})
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
async function checkStaleSentinel(projectRoot) {
|
|
112
|
-
const sentinelPath = path.join(projectRoot, RUNTIME_ROOT, "state", ".init-in-progress");
|
|
113
|
-
if (!(await exists(sentinelPath))) {
|
|
114
|
-
return warningFinding("stale_init_sentinel", true, "No stale init sentinel detected.");
|
|
115
|
-
}
|
|
116
|
-
let startedAt = "unknown time";
|
|
117
|
-
try {
|
|
118
|
-
const raw = await fs.readFile(sentinelPath, "utf8");
|
|
119
|
-
const parsed = JSON.parse(raw);
|
|
120
|
-
if (parsed && typeof parsed.startedAt === "string" && parsed.startedAt.trim().length > 0) {
|
|
121
|
-
startedAt = parsed.startedAt;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
// best-effort parse only
|
|
126
|
-
}
|
|
127
|
-
return warningFinding("stale_init_sentinel", false, "Detected stale .init-in-progress sentinel from a previous interrupted sync/init run.", [`startedAt: ${startedAt}`, `path: ${sentinelPath}`]);
|
|
128
|
-
}
|
|
129
|
-
async function checkFlowState(projectRoot) {
|
|
130
|
-
try {
|
|
131
|
-
await readFlowState(projectRoot);
|
|
132
|
-
return okFinding("flow_state", "Flow state is readable.");
|
|
133
|
-
}
|
|
134
|
-
catch (error) {
|
|
135
|
-
if (error instanceof CorruptFlowStateError) {
|
|
136
|
-
return errorFinding("flow_state", "Corrupt flow-state detected.", [error.message]);
|
|
137
|
-
}
|
|
138
|
-
return errorFinding("flow_state", "Flow-state read failed.", [
|
|
139
|
-
error instanceof Error ? error.message : String(error)
|
|
140
|
-
]);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
async function checkManagedManifest(projectRoot) {
|
|
144
|
-
const manifestPath = path.join(projectRoot, MANAGED_RESOURCE_MANIFEST_REL_PATH);
|
|
145
|
-
if (!(await exists(manifestPath))) {
|
|
146
|
-
return errorFinding("managed_manifest", "Managed resource manifest is missing.", [`missing: ${manifestPath}`]);
|
|
147
|
-
}
|
|
148
|
-
const rawText = await fs.readFile(manifestPath, "utf8");
|
|
149
|
-
let parsed;
|
|
150
|
-
try {
|
|
151
|
-
parsed = JSON.parse(rawText);
|
|
152
|
-
}
|
|
153
|
-
catch (error) {
|
|
154
|
-
return errorFinding("managed_manifest", "Managed resource manifest is not valid JSON.", [error instanceof Error ? error.message : String(error)]);
|
|
155
|
-
}
|
|
156
|
-
const issues = validateManagedResourceManifest(parsed);
|
|
157
|
-
if (issues.length > 0) {
|
|
158
|
-
const detail = issues.slice(0, 12).map((issue) => {
|
|
159
|
-
const scope = issue.path ?? (issue.index !== undefined ? `resources[${issue.index}]` : "manifest");
|
|
160
|
-
return `${scope}.${issue.field}: ${issue.message}`;
|
|
161
|
-
});
|
|
162
|
-
return errorFinding("managed_manifest", "Managed resource manifest schema validation failed.", detail);
|
|
163
|
-
}
|
|
164
|
-
return okFinding("managed_manifest", "Managed resource manifest is valid.");
|
|
165
|
-
}
|
|
166
|
-
function hookFilePath(projectRoot, harness) {
|
|
167
|
-
if (harness === "claude")
|
|
168
|
-
return path.join(projectRoot, ".claude/hooks/hooks.json");
|
|
169
|
-
if (harness === "cursor")
|
|
170
|
-
return path.join(projectRoot, ".cursor/hooks.json");
|
|
171
|
-
return path.join(projectRoot, ".codex/hooks.json");
|
|
172
|
-
}
|
|
173
|
-
async function checkHookDocument(projectRoot, harness) {
|
|
174
|
-
const hookPath = hookFilePath(projectRoot, harness);
|
|
175
|
-
if (!(await exists(hookPath))) {
|
|
176
|
-
return errorFinding(`hook_document_${harness}`, `Hook document is missing for ${harness}.`, [`missing: ${hookPath}`]);
|
|
177
|
-
}
|
|
178
|
-
const raw = await fs.readFile(hookPath, "utf8");
|
|
179
|
-
const parsed = parseJsonWithRecovery(raw);
|
|
180
|
-
if (parsed === null) {
|
|
181
|
-
return errorFinding(`hook_document_${harness}`, `Hook document for ${harness} is unparseable JSON.`, [`path: ${hookPath}`]);
|
|
182
|
-
}
|
|
183
|
-
const validation = validateHookDocument(harness, parsed);
|
|
184
|
-
if (!validation.ok) {
|
|
185
|
-
return errorFinding(`hook_document_${harness}`, `Hook document for ${harness} is invalid.`, validation.errors);
|
|
186
|
-
}
|
|
187
|
-
return okFinding(`hook_document_${harness}`, `Hook document for ${harness} is valid.`);
|
|
188
|
-
}
|
|
189
|
-
async function checkHarnessShims(projectRoot, harnesses) {
|
|
190
|
-
const findings = [];
|
|
191
|
-
const expectedFiles = harnessShimFileNames();
|
|
192
|
-
const expectedSkillFolders = harnessShimSkillNames();
|
|
193
|
-
for (const harness of harnesses) {
|
|
194
|
-
const adapter = HARNESS_ADAPTERS[harness];
|
|
195
|
-
const base = path.join(projectRoot, adapter.commandDir);
|
|
196
|
-
const missing = [];
|
|
197
|
-
for (const fileName of expectedFiles) {
|
|
198
|
-
const target = adapter.shimKind === "skill"
|
|
199
|
-
? path.join(base, fileName.replace(/\.md$/u, ""), "SKILL.md")
|
|
200
|
-
: path.join(base, fileName);
|
|
201
|
-
if (!(await exists(target))) {
|
|
202
|
-
missing.push(target);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
if (adapter.shimKind === "skill") {
|
|
206
|
-
for (const folder of expectedSkillFolders) {
|
|
207
|
-
const target = path.join(base, folder, "SKILL.md");
|
|
208
|
-
if (!(await exists(target))) {
|
|
209
|
-
missing.push(target);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
if (missing.length > 0) {
|
|
214
|
-
findings.push(errorFinding(`shim_drift_${harness}`, `Harness shim drift detected for ${harness}.`, missing));
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
findings.push(okFinding(`shim_drift_${harness}`, `Harness shims for ${harness} are present.`));
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return findings;
|
|
221
|
-
}
|
|
222
|
-
function buildReport(findings) {
|
|
223
|
-
const errors = findings.filter((finding) => !finding.ok && finding.severity === "error").length;
|
|
224
|
-
const warnings = findings.filter((finding) => !finding.ok && finding.severity === "warning").length;
|
|
225
|
-
return {
|
|
226
|
-
ok: errors === 0,
|
|
227
|
-
generatedAt: new Date().toISOString(),
|
|
228
|
-
findings,
|
|
229
|
-
summary: { errors, warnings }
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
function writeTextReport(io, report) {
|
|
233
|
-
io.stdout.write(`runtime-integrity: ${report.ok ? "ok" : "failed"}\n`);
|
|
234
|
-
io.stdout.write(`errors=${report.summary.errors} warnings=${report.summary.warnings}\n`);
|
|
235
|
-
for (const finding of report.findings) {
|
|
236
|
-
if (finding.ok)
|
|
237
|
-
continue;
|
|
238
|
-
io.stdout.write(`[${finding.severity}] ${finding.id}: ${finding.message}\n`);
|
|
239
|
-
for (const detail of finding.details ?? []) {
|
|
240
|
-
io.stdout.write(` - ${detail}\n`);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
export async function runRuntimeIntegrityCommand(projectRoot, argv, io) {
|
|
245
|
-
const args = parseArgs(argv);
|
|
246
|
-
const config = await readConfig(projectRoot);
|
|
247
|
-
const harnesses = config.harnesses;
|
|
248
|
-
const findings = [];
|
|
249
|
-
findings.push(await checkStaleSentinel(projectRoot));
|
|
250
|
-
findings.push(await checkFlowState(projectRoot));
|
|
251
|
-
findings.push(await checkManagedManifest(projectRoot));
|
|
252
|
-
findings.push(...await checkHarnessShims(projectRoot, harnesses));
|
|
253
|
-
for (const harness of harnesses) {
|
|
254
|
-
if (harness === "claude" || harness === "cursor" || harness === "codex") {
|
|
255
|
-
findings.push(await checkHookDocument(projectRoot, harness));
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
const report = buildReport(findings);
|
|
259
|
-
if (!args.quiet) {
|
|
260
|
-
if (args.json) {
|
|
261
|
-
io.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
writeTextReport(io, report);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
return report.ok ? 0 : 1;
|
|
268
|
-
}
|