cclaw-cli 6.13.1 → 6.14.1
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/dist/artifact-linter/shared.d.ts +15 -0
- package/dist/artifact-linter/tdd.d.ts +40 -10
- package/dist/artifact-linter/tdd.js +256 -44
- package/dist/artifact-linter.js +10 -2
- package/dist/content/core-agents.js +66 -1
- package/dist/content/hooks.js +160 -3
- package/dist/content/stages/tdd.js +9 -5
- package/dist/content/start-command.js +3 -3
- package/dist/delegation.d.ts +79 -0
- package/dist/delegation.js +122 -2
- package/dist/flow-state.d.ts +45 -0
- package/dist/flow-state.js +18 -0
- package/dist/install.js +88 -0
- package/dist/run-persistence.js +14 -0
- package/package.json +1 -1
package/dist/install.js
CHANGED
|
@@ -1003,6 +1003,90 @@ async function applyPlanLegacyContinuationIfNeeded(projectRoot) {
|
|
|
1003
1003
|
// Best-effort: corrupt/missing state is handled elsewhere on sync.
|
|
1004
1004
|
}
|
|
1005
1005
|
}
|
|
1006
|
+
/**
|
|
1007
|
+
* v6.14.0 — set stream-style defaults on `cclaw-cli sync` and print a
|
|
1008
|
+
* one-line hint when defaults change. Strategy:
|
|
1009
|
+
*
|
|
1010
|
+
* - When `legacyContinuation: true` and `tddCheckpointMode` is unset, force
|
|
1011
|
+
* `tddCheckpointMode: "global-red"` (preserves hox wave protocol).
|
|
1012
|
+
* - When `legacyContinuation: true` and `integrationOverseerMode` is unset,
|
|
1013
|
+
* force `integrationOverseerMode: "always"` (preserves v6.13 behavior).
|
|
1014
|
+
* - When `legacyContinuation` is NOT true (new / standard projects) and
|
|
1015
|
+
* neither field is set, default to `tddCheckpointMode: "per-slice"`,
|
|
1016
|
+
* `integrationOverseerMode: "conditional"`. Also default
|
|
1017
|
+
* `worktreeExecutionMode: "worktree-first"` if unset.
|
|
1018
|
+
*
|
|
1019
|
+
* Returns a one-line hint string (or `null` if nothing changed) so callers
|
|
1020
|
+
* can print it through the standard sync hint surface.
|
|
1021
|
+
*/
|
|
1022
|
+
async function applyV614DefaultsIfNeeded(projectRoot) {
|
|
1023
|
+
// Defensive read — match `applyTddCutoverIfNeeded`'s pattern (raw +
|
|
1024
|
+
// JSON.parse) so corrupt state is left untouched for the downstream
|
|
1025
|
+
// fail-fast check in `materializeRuntime` (which expects to see the
|
|
1026
|
+
// CorruptFlowStateError surfaced via `ensureRunSystem`). Calling
|
|
1027
|
+
// `readFlowState` directly would quarantine the corrupt file and hide
|
|
1028
|
+
// the failure from the caller.
|
|
1029
|
+
const flowStatePath = runtimePath(projectRoot, "state", "flow-state.json");
|
|
1030
|
+
let flowStateRaw;
|
|
1031
|
+
try {
|
|
1032
|
+
flowStateRaw = await fs.readFile(flowStatePath, "utf8");
|
|
1033
|
+
}
|
|
1034
|
+
catch {
|
|
1035
|
+
return null;
|
|
1036
|
+
}
|
|
1037
|
+
let parsed;
|
|
1038
|
+
try {
|
|
1039
|
+
parsed = JSON.parse(flowStateRaw);
|
|
1040
|
+
}
|
|
1041
|
+
catch {
|
|
1042
|
+
return null;
|
|
1043
|
+
}
|
|
1044
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1045
|
+
return null;
|
|
1046
|
+
}
|
|
1047
|
+
const obj = parsed;
|
|
1048
|
+
const updates = {};
|
|
1049
|
+
const summary = [];
|
|
1050
|
+
const tddCheckpointModeSet = obj.tddCheckpointMode === "per-slice" || obj.tddCheckpointMode === "global-red";
|
|
1051
|
+
const integrationOverseerModeSet = obj.integrationOverseerMode === "conditional" || obj.integrationOverseerMode === "always";
|
|
1052
|
+
const worktreeExecutionModeSet = obj.worktreeExecutionMode === "worktree-first" || obj.worktreeExecutionMode === "single-tree";
|
|
1053
|
+
const legacyContinuation = obj.legacyContinuation === true;
|
|
1054
|
+
if (legacyContinuation) {
|
|
1055
|
+
if (!tddCheckpointModeSet) {
|
|
1056
|
+
updates.tddCheckpointMode = "global-red";
|
|
1057
|
+
summary.push("tddCheckpointMode=global-red (legacyContinuation)");
|
|
1058
|
+
}
|
|
1059
|
+
if (!integrationOverseerModeSet) {
|
|
1060
|
+
updates.integrationOverseerMode = "always";
|
|
1061
|
+
summary.push("integrationOverseerMode=always (legacyContinuation)");
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
else {
|
|
1065
|
+
if (!tddCheckpointModeSet) {
|
|
1066
|
+
updates.tddCheckpointMode = "per-slice";
|
|
1067
|
+
summary.push("tddCheckpointMode=per-slice");
|
|
1068
|
+
}
|
|
1069
|
+
if (!integrationOverseerModeSet) {
|
|
1070
|
+
updates.integrationOverseerMode = "conditional";
|
|
1071
|
+
summary.push("integrationOverseerMode=conditional");
|
|
1072
|
+
}
|
|
1073
|
+
if (!worktreeExecutionModeSet) {
|
|
1074
|
+
updates.worktreeExecutionMode = "worktree-first";
|
|
1075
|
+
summary.push("worktreeExecutionMode=worktree-first");
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
if (summary.length === 0) {
|
|
1079
|
+
return null;
|
|
1080
|
+
}
|
|
1081
|
+
const merged = { ...obj, ...updates };
|
|
1082
|
+
try {
|
|
1083
|
+
await writeFileSafe(flowStatePath, `${JSON.stringify(merged, null, 2)}\n`, { mode: 0o600 });
|
|
1084
|
+
}
|
|
1085
|
+
catch {
|
|
1086
|
+
return null;
|
|
1087
|
+
}
|
|
1088
|
+
return `v6.14.0 stream-style defaults applied: ${summary.join(", ")}. To opt out, edit .cclaw/state/flow-state.json directly or pin the legacy mode (tddCheckpointMode="global-red", integrationOverseerMode="always").`;
|
|
1089
|
+
}
|
|
1006
1090
|
async function cleanLegacyArtifacts(projectRoot) {
|
|
1007
1091
|
for (const legacyFolder of DEPRECATED_UTILITY_SKILL_FOLDERS) {
|
|
1008
1092
|
await removeBestEffort(runtimePath(projectRoot, "skills", legacyFolder), true);
|
|
@@ -1178,6 +1262,10 @@ async function materializeRuntime(projectRoot, config, forceStateReset, operatio
|
|
|
1178
1262
|
if (operation === "sync" || operation === "upgrade") {
|
|
1179
1263
|
await applyTddCutoverIfNeeded(projectRoot);
|
|
1180
1264
|
await applyPlanLegacyContinuationIfNeeded(projectRoot);
|
|
1265
|
+
const v614Hint = await applyV614DefaultsIfNeeded(projectRoot);
|
|
1266
|
+
if (v614Hint) {
|
|
1267
|
+
process.stdout.write(`cclaw: ${v614Hint}\n`);
|
|
1268
|
+
}
|
|
1181
1269
|
}
|
|
1182
1270
|
try {
|
|
1183
1271
|
await ensureRunSystem(projectRoot, { createIfMissing: false });
|
package/dist/run-persistence.js
CHANGED
|
@@ -473,6 +473,8 @@ function coerceFlowState(parsed) {
|
|
|
473
473
|
const completedStageMeta = sanitizeCompletedStageMeta(parsed.completedStageMeta);
|
|
474
474
|
const tddCutoverSliceId = coerceTddCutoverSliceId(parsed.tddCutoverSliceId);
|
|
475
475
|
const worktreeExecutionMode = coerceWorktreeExecutionMode(parsed.worktreeExecutionMode);
|
|
476
|
+
const tddCheckpointMode = coerceTddCheckpointMode(parsed.tddCheckpointMode);
|
|
477
|
+
const integrationOverseerMode = coerceIntegrationOverseerMode(parsed.integrationOverseerMode);
|
|
476
478
|
const legacyContinuation = typeof parsed.legacyContinuation === "boolean" ? parsed.legacyContinuation : undefined;
|
|
477
479
|
const state = {
|
|
478
480
|
schemaVersion: FLOW_STATE_SCHEMA_VERSION,
|
|
@@ -488,6 +490,8 @@ function coerceFlowState(parsed) {
|
|
|
488
490
|
...(completedStageMeta ? { completedStageMeta } : {}),
|
|
489
491
|
...(tddCutoverSliceId ? { tddCutoverSliceId } : {}),
|
|
490
492
|
...(worktreeExecutionMode !== undefined ? { worktreeExecutionMode } : {}),
|
|
493
|
+
...(tddCheckpointMode !== undefined ? { tddCheckpointMode } : {}),
|
|
494
|
+
...(integrationOverseerMode !== undefined ? { integrationOverseerMode } : {}),
|
|
491
495
|
...(legacyContinuation !== undefined ? { legacyContinuation } : {}),
|
|
492
496
|
skippedStages: sanitizeSkippedStages(parsed.skippedStages, track),
|
|
493
497
|
staleStages: sanitizeStaleStages(parsed.staleStages),
|
|
@@ -514,6 +518,16 @@ function coerceWorktreeExecutionMode(value) {
|
|
|
514
518
|
return value;
|
|
515
519
|
return undefined;
|
|
516
520
|
}
|
|
521
|
+
function coerceTddCheckpointMode(value) {
|
|
522
|
+
if (value === "per-slice" || value === "global-red")
|
|
523
|
+
return value;
|
|
524
|
+
return undefined;
|
|
525
|
+
}
|
|
526
|
+
function coerceIntegrationOverseerMode(value) {
|
|
527
|
+
if (value === "conditional" || value === "always")
|
|
528
|
+
return value;
|
|
529
|
+
return undefined;
|
|
530
|
+
}
|
|
517
531
|
export class CorruptFlowStateError extends Error {
|
|
518
532
|
statePath;
|
|
519
533
|
quarantinedPath;
|