cclaw-cli 7.6.0 → 7.7.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 -1
- package/dist/artifact-linter/plan.js +98 -25
- package/dist/artifact-linter/tdd.js +2 -2
- package/dist/config.d.ts +15 -1
- package/dist/config.js +152 -2
- package/dist/content/core-agents.d.ts +1 -1
- package/dist/content/core-agents.js +2 -2
- package/dist/content/meta-skill.js +4 -4
- package/dist/content/skills.js +12 -8
- package/dist/content/stage-schema.js +2 -2
- package/dist/content/stages/plan.js +17 -17
- package/dist/content/stages/tdd.js +13 -10
- package/dist/content/start-command.js +3 -3
- package/dist/content/subagent-context-skills.js +2 -2
- package/dist/content/subagents.js +6 -6
- package/dist/content/templates.js +12 -7
- package/dist/delegation.d.ts +4 -3
- package/dist/delegation.js +14 -8
- package/dist/execution-topology.d.ts +36 -0
- package/dist/execution-topology.js +73 -0
- package/dist/internal/plan-split-waves.d.ts +5 -2
- package/dist/internal/plan-split-waves.js +14 -8
- package/dist/internal/wave-status.d.ts +4 -0
- package/dist/internal/wave-status.js +47 -8
- package/dist/types.d.ts +45 -0
- package/package.json +1 -1
|
@@ -4,6 +4,8 @@ import { RUNTIME_ROOT } from "../constants.js";
|
|
|
4
4
|
import { readDelegationEvents, readDelegationLedger } from "../delegation.js";
|
|
5
5
|
import { readFlowState } from "../runs.js";
|
|
6
6
|
import { DEFAULT_SLICE_STREAM_REL_PATH, readEventStreamFile } from "../streaming/event-stream.js";
|
|
7
|
+
import { readConfig, resolveExecutionStrictness, resolveExecutionTopology, resolveMaxBuilders } from "../config.js";
|
|
8
|
+
import { routeExecutionTopology } from "../execution-topology.js";
|
|
7
9
|
import { mergeParallelWaveDefinitions, parseParallelExecutionPlanWaves, parseWavePlanDirectory } from "./plan-split-waves.js";
|
|
8
10
|
import { compareSliceIds, parseSliceId } from "../util/slice-id.js";
|
|
9
11
|
const PARALLEL_EXEC_MANAGED_START = "<!-- parallel-exec-managed-start -->";
|
|
@@ -82,7 +84,11 @@ function parseManagedWaveClaimedPaths(planMarkdown) {
|
|
|
82
84
|
if (cells.length === 0)
|
|
83
85
|
continue;
|
|
84
86
|
const first = cells[0].toLowerCase();
|
|
85
|
-
if (first === "sliceid" ||
|
|
87
|
+
if (first === "sliceid" ||
|
|
88
|
+
first === "slice id" ||
|
|
89
|
+
first === "unitid" ||
|
|
90
|
+
first === "unit id" ||
|
|
91
|
+
first === "unit") {
|
|
86
92
|
headerIdx = new Map();
|
|
87
93
|
for (let i = 0; i < cells.length; i += 1) {
|
|
88
94
|
const key = cells[i].toLowerCase().replace(/[^a-z0-9]/gu, "");
|
|
@@ -95,10 +101,12 @@ function parseManagedWaveClaimedPaths(planMarkdown) {
|
|
|
95
101
|
if (cells.every((cell) => /^:?-{3,}:?$/u.test(cell))) {
|
|
96
102
|
continue;
|
|
97
103
|
}
|
|
98
|
-
const
|
|
99
|
-
|
|
104
|
+
const firstCell = (cells[0] ?? "").replace(/^`|`$/gu, "").trim();
|
|
105
|
+
const parsedSlice = parseSliceId(firstCell);
|
|
106
|
+
const parsedUnit = /^U-(\d+(?:[a-z][a-z0-9]*)?)$/iu.exec(firstCell);
|
|
107
|
+
if (!parsedSlice && !parsedUnit)
|
|
100
108
|
continue;
|
|
101
|
-
const sliceId = parsedSlice.
|
|
109
|
+
const sliceId = parsedSlice?.id ?? `S-${parsedUnit[1].toLowerCase()}`;
|
|
102
110
|
const pathsIdx = headerIdx.get("claimedpaths");
|
|
103
111
|
const rawPaths = pathsIdx !== undefined ? (cells[pathsIdx] ?? "") : "";
|
|
104
112
|
const claimedPaths = rawPaths.length === 0
|
|
@@ -175,7 +183,10 @@ export async function runWaveStatus(projectRoot, options = {}) {
|
|
|
175
183
|
waveId: null,
|
|
176
184
|
readyToDispatch: [],
|
|
177
185
|
pathConflicts: [],
|
|
178
|
-
mode: "none"
|
|
186
|
+
mode: "none",
|
|
187
|
+
topology: "none",
|
|
188
|
+
topologyReason: "wave plan could not be parsed",
|
|
189
|
+
maxBuilders: 0
|
|
179
190
|
},
|
|
180
191
|
warnings: [
|
|
181
192
|
`wave_plan_parse_error: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -203,7 +214,10 @@ export async function runWaveStatus(projectRoot, options = {}) {
|
|
|
203
214
|
waveId: null,
|
|
204
215
|
readyToDispatch: [],
|
|
205
216
|
pathConflicts: [],
|
|
206
|
-
mode: "none"
|
|
217
|
+
mode: "none",
|
|
218
|
+
topology: "none",
|
|
219
|
+
topologyReason: "wave plan sources conflict",
|
|
220
|
+
maxBuilders: 0
|
|
207
221
|
},
|
|
208
222
|
warnings: [
|
|
209
223
|
`wave_plan_merge_conflict: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -331,12 +345,19 @@ export async function runWaveStatus(projectRoot, options = {}) {
|
|
|
331
345
|
warnings.push("wave_plan_managed_block_missing: <!-- parallel-exec-managed-start --> block not found in 05-plan.md and wave-plans/ has no parseable wave files.");
|
|
332
346
|
}
|
|
333
347
|
let nextDispatch;
|
|
348
|
+
const config = await readConfig(projectRoot).catch(() => null);
|
|
349
|
+
const configuredTopology = resolveExecutionTopology(config);
|
|
350
|
+
const strictness = resolveExecutionStrictness(config);
|
|
351
|
+
const maxBuilders = resolveMaxBuilders(config);
|
|
334
352
|
if (firstOpenWave === null) {
|
|
335
353
|
nextDispatch = {
|
|
336
354
|
waveId: null,
|
|
337
355
|
readyToDispatch: [],
|
|
338
356
|
pathConflicts: [],
|
|
339
|
-
mode: "none"
|
|
357
|
+
mode: "none",
|
|
358
|
+
topology: "none",
|
|
359
|
+
topologyReason: "no open wave has ready units",
|
|
360
|
+
maxBuilders
|
|
340
361
|
};
|
|
341
362
|
}
|
|
342
363
|
else {
|
|
@@ -350,11 +371,28 @@ export async function runWaveStatus(projectRoot, options = {}) {
|
|
|
350
371
|
: readyToDispatch.length === 1
|
|
351
372
|
? "single-slice"
|
|
352
373
|
: "none";
|
|
374
|
+
const topologyDecision = mode === "none"
|
|
375
|
+
? null
|
|
376
|
+
: routeExecutionTopology({
|
|
377
|
+
configuredTopology,
|
|
378
|
+
strictness,
|
|
379
|
+
maxBuilders,
|
|
380
|
+
shape: {
|
|
381
|
+
unitCount: readyToDispatch.length,
|
|
382
|
+
independentUnitCount: conflicts.length > 0 ? 0 : readyToDispatch.length,
|
|
383
|
+
substantialUnitCount: readyToDispatch.length,
|
|
384
|
+
hasPathConflicts: conflicts.length > 0,
|
|
385
|
+
inlineSafe: false
|
|
386
|
+
}
|
|
387
|
+
});
|
|
353
388
|
nextDispatch = {
|
|
354
389
|
waveId: firstOpenWave.waveId,
|
|
355
390
|
readyToDispatch,
|
|
356
391
|
pathConflicts: conflicts,
|
|
357
|
-
mode
|
|
392
|
+
mode,
|
|
393
|
+
topology: topologyDecision?.topology ?? "none",
|
|
394
|
+
topologyReason: topologyDecision?.reason ?? "no ready units",
|
|
395
|
+
maxBuilders: topologyDecision?.maxBuilders ?? maxBuilders
|
|
358
396
|
};
|
|
359
397
|
}
|
|
360
398
|
return {
|
|
@@ -382,6 +420,7 @@ function formatHumanReport(report) {
|
|
|
382
420
|
}
|
|
383
421
|
lines.push(`nextDispatch: wave=${report.nextDispatch.waveId ?? "(none)"} ` +
|
|
384
422
|
`mode=${report.nextDispatch.mode} ` +
|
|
423
|
+
`topology=${report.nextDispatch.topology} ` +
|
|
385
424
|
`ready=[${report.nextDispatch.readyToDispatch.join(",")}]`);
|
|
386
425
|
if (report.warnings.length > 0) {
|
|
387
426
|
lines.push("warnings:");
|
package/dist/types.d.ts
CHANGED
|
@@ -163,6 +163,10 @@ export interface ReviewLoopConfig {
|
|
|
163
163
|
export type VcsMode = "git-with-remote" | "git-local-only" | "none";
|
|
164
164
|
export type TddCommitMode = "managed-per-slice" | "agent-required" | "checkpoint-only" | "off";
|
|
165
165
|
export type TddIsolationMode = "worktree" | "in-place" | "auto";
|
|
166
|
+
export type ExecutionTopology = "auto" | "inline" | "single-builder" | "parallel-builders" | "strict-micro";
|
|
167
|
+
export type ExecutionStrictnessProfile = "fast" | "balanced" | "strict";
|
|
168
|
+
export type PlanSliceGranularity = "feature-atomic" | "strict-micro";
|
|
169
|
+
export type PlanMicroTaskPolicy = "advisory" | "strict";
|
|
166
170
|
/**
|
|
167
171
|
* 7.6.0 — what slice-commit does when a manifest in the slice's
|
|
168
172
|
* claim drifts its corresponding lockfile twin (e.g. Cargo.toml +
|
|
@@ -206,11 +210,52 @@ export interface TddConfig {
|
|
|
206
210
|
*/
|
|
207
211
|
lockfileTwinPolicy?: LockfileTwinPolicy;
|
|
208
212
|
}
|
|
213
|
+
export interface ExecutionConfig {
|
|
214
|
+
/**
|
|
215
|
+
* 7.7.0 — adaptive execution topology for implementation units.
|
|
216
|
+
*
|
|
217
|
+
* - `auto` (default): choose the cheapest safe route from plan shape.
|
|
218
|
+
* - `inline`: controller may execute a low-risk unit inline while still
|
|
219
|
+
* recording RED/GREEN/REFACTOR evidence.
|
|
220
|
+
* - `single-builder`: one slice-builder owns a feature-atomic unit.
|
|
221
|
+
* - `parallel-builders`: fan out independent substantial units only.
|
|
222
|
+
* - `strict-micro`: preserve the pre-7.7 posture where each tiny task is
|
|
223
|
+
* its own schedulable slice.
|
|
224
|
+
*/
|
|
225
|
+
topology?: ExecutionTopology;
|
|
226
|
+
/**
|
|
227
|
+
* 7.7.0 — default calibration for topology and plan-shape advisories.
|
|
228
|
+
* `balanced` is the default: prefer feature-atomic units with internal
|
|
229
|
+
* 2-5 minute TDD steps, warning on microtask-only plans without blocking.
|
|
230
|
+
*/
|
|
231
|
+
strictness?: ExecutionStrictnessProfile;
|
|
232
|
+
/**
|
|
233
|
+
* 7.7.0 — upper bound for simultaneous slice-builder workers when the
|
|
234
|
+
* router selects `parallel-builders`.
|
|
235
|
+
*/
|
|
236
|
+
maxBuilders?: number;
|
|
237
|
+
}
|
|
238
|
+
export interface PlanConfig {
|
|
239
|
+
/**
|
|
240
|
+
* 7.7.0 — default schedulable surface for plan authoring.
|
|
241
|
+
* - feature-atomic: U-* slices contain internal 2-5 minute TDD steps.
|
|
242
|
+
* - strict-micro: one tiny task can remain one schedulable slice.
|
|
243
|
+
*/
|
|
244
|
+
sliceGranularity?: PlanSliceGranularity;
|
|
245
|
+
/**
|
|
246
|
+
* 7.7.0 — how strongly the plan linter reacts to microtask-only plans.
|
|
247
|
+
* `advisory` warns in fast/balanced execution; `strict` treats strict
|
|
248
|
+
* microtask planning as intentional.
|
|
249
|
+
*/
|
|
250
|
+
microTaskPolicy?: PlanMicroTaskPolicy;
|
|
251
|
+
}
|
|
209
252
|
export interface CclawConfig {
|
|
210
253
|
version: string;
|
|
211
254
|
flowVersion: string;
|
|
212
255
|
harnesses: HarnessId[];
|
|
213
256
|
tdd?: TddConfig;
|
|
257
|
+
execution?: ExecutionConfig;
|
|
258
|
+
plan?: PlanConfig;
|
|
214
259
|
}
|
|
215
260
|
export interface TransitionRule {
|
|
216
261
|
from: FlowStage;
|