cclaw-cli 0.51.25 → 0.51.27

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.
@@ -71,6 +71,12 @@ export function harnessShimSkillNames() {
71
71
  export const HARNESS_ADAPTERS = {
72
72
  claude: {
73
73
  id: "claude",
74
+ reality: {
75
+ declaredSupport: "full",
76
+ runtimeLaunch: "native Task launch",
77
+ proofRequired: "spanId+dispatchId or workerRunId+ACK for isolated completion",
78
+ proofSource: ".cclaw/state/delegation-events.jsonl plus delegation-log.json"
79
+ },
74
80
  commandDir: ".claude/commands",
75
81
  shimKind: "command",
76
82
  capabilities: {
@@ -82,6 +88,12 @@ export const HARNESS_ADAPTERS = {
82
88
  },
83
89
  cursor: {
84
90
  id: "cursor",
91
+ reality: {
92
+ declaredSupport: "generic",
93
+ runtimeLaunch: "generic Task/Subagent launch with cclaw role prompt",
94
+ proofRequired: "spanId+dispatchId/evidenceRefs for generic-dispatch completion",
95
+ proofSource: ".cclaw/state/delegation-events.jsonl plus artifact evidenceRefs"
96
+ },
85
97
  commandDir: ".cursor/commands",
86
98
  shimKind: "command",
87
99
  capabilities: {
@@ -97,6 +109,12 @@ export const HARNESS_ADAPTERS = {
97
109
  },
98
110
  opencode: {
99
111
  id: "opencode",
112
+ reality: {
113
+ declaredSupport: "full",
114
+ runtimeLaunch: "prompt-level launch via Task or @agent against generated .opencode/agents",
115
+ proofRequired: "spanId+dispatchId+ackTs+completedTs before isolated completion",
116
+ proofSource: ".opencode/agents/<agent>.md and .cclaw/state/delegation-events.jsonl"
117
+ },
100
118
  commandDir: ".opencode/commands",
101
119
  shimKind: "command",
102
120
  capabilities: {
@@ -119,6 +137,12 @@ export const HARNESS_ADAPTERS = {
119
137
  },
120
138
  codex: {
121
139
  id: "codex",
140
+ reality: {
141
+ declaredSupport: "full",
142
+ runtimeLaunch: "prompt-level launch by asking Codex to spawn generated custom agents",
143
+ proofRequired: "spanId+dispatchId+ackTs+completedTs before isolated completion",
144
+ proofSource: ".codex/agents/<agent>.toml and .cclaw/state/delegation-events.jsonl"
145
+ },
122
146
  // Codex CLI reads skills from the universal `.agents/skills/` path
123
147
  // (OpenAI Codex 0.89, Jan 2026). It does NOT have a native
124
148
  // `.codex/commands/*` slash-command discovery — cclaw installs
@@ -155,11 +179,106 @@ export function harnessDispatchSurface(harnessId) {
155
179
  case "cursor":
156
180
  return "Use Cursor Subagent/Task with a generic subagent_type (explore for read-only mapping, generalPurpose for broader work, shell/browser-use when specifically needed) and paste the cclaw role prompt; record fulfillmentMode: \"generic-dispatch\" with evidenceRefs.";
157
181
  case "opencode":
158
- return "Use OpenCode subagents: invoke the generated .opencode/agents/<agent>.md agent via Task or @<agent>, run independent agents in parallel when safe, then record fulfillmentMode: \"isolated\".";
182
+ return "Use OpenCode subagents: invoke the generated .opencode/agents/<agent>.md agent via Task or @<agent>; record scheduled/launched/acknowledged/completed events with spanId+dispatchId before claiming fulfillmentMode: \"isolated\".";
159
183
  case "codex":
160
- return "Use Codex native subagents: ask Codex to spawn the generated .codex/agents/<agent>.toml agent(s) by name, wait for all results, then record fulfillmentMode: \"isolated\".";
184
+ return "Use Codex native subagents: ask Codex to spawn the generated .codex/agents/<agent>.toml agent(s) by name; record scheduled/launched/acknowledged/completed events with spanId+dispatchId before claiming fulfillmentMode: \"isolated\".";
161
185
  }
162
186
  }
187
+ /**
188
+ * Per-harness lifecycle recipe used by skills and harness docs to render the
189
+ * canonical scheduled -> launched -> acknowledged -> completed sequence in
190
+ * structural form. The recipe never embeds task-specific or domain-specific
191
+ * placeholders — only neutral angle-bracket tokens (`<agent-name>`, `<stage>`,
192
+ * `<span-id>`, `<dispatch-id>`, `<agent-def-path>`, `<iso-ts>`).
193
+ *
194
+ * This function returns the **canonical primary recipe** for each shipped
195
+ * harness — the dispatch surface that maps 1:1 onto the harness's vendor-
196
+ * native subagent surface:
197
+ *
198
+ * - `claude` -> `claude-task` (isolated)
199
+ * - `cursor` -> `cursor-task` (generic-dispatch)
200
+ * - `opencode` -> `opencode-agent` (isolated)
201
+ * - `codex` -> `codex-agent` (isolated)
202
+ *
203
+ * The remaining `--dispatch-surface` enum values (`generic-task`,
204
+ * `role-switch`, `manual`) are universal fallback paths available to any
205
+ * harness when the canonical surface is unavailable; they are documented in
206
+ * the dispatch-surface table in `docs/harnesses.md` rather than per-harness
207
+ * here, because their lifecycle commands are structurally identical except
208
+ * for the surface token. No shipped harness has a non-canonical *primary*
209
+ * surface, so this function only needs to enumerate the four canonical
210
+ * recipes above.
211
+ */
212
+ export function harnessDelegationRecipe(harnessId) {
213
+ const helper = "node .cclaw/hooks/delegation-record.mjs";
214
+ const common = "--stage=<stage> --agent=<agent-name> --mode=mandatory --span-id=<span-id> --dispatch-id=<dispatch-id>";
215
+ switch (harnessId) {
216
+ case "claude":
217
+ return {
218
+ harnessId,
219
+ dispatchSurface: "claude-task",
220
+ agentDefinitionDirectory: ".claude/agents/",
221
+ agentDefinitionExample: ".claude/agents/<agent-name>.md",
222
+ invocationLine: "Call Task with subagent_type=<agent-name> and prompt body that paraphrases the stage skill role.",
223
+ fulfillmentMode: "isolated",
224
+ lifecycleCommands: [
225
+ `${helper} ${common} --status=scheduled --dispatch-surface=claude-task --agent-definition-path=.claude/agents/<agent-name>.md --json`,
226
+ `${helper} ${common} --status=launched --dispatch-surface=claude-task --agent-definition-path=.claude/agents/<agent-name>.md --launched-ts=<iso-ts> --json`,
227
+ `${helper} ${common} --status=acknowledged --dispatch-surface=claude-task --agent-definition-path=.claude/agents/<agent-name>.md --ack-ts=<iso-ts> --json`,
228
+ `${helper} ${common} --status=completed --dispatch-surface=claude-task --agent-definition-path=.claude/agents/<agent-name>.md --completed-ts=<iso-ts> --json`
229
+ ]
230
+ };
231
+ case "cursor":
232
+ return {
233
+ harnessId,
234
+ dispatchSurface: "cursor-task",
235
+ agentDefinitionDirectory: ".cclaw/agents/",
236
+ agentDefinitionExample: ".cclaw/agents/<agent-name>.md",
237
+ invocationLine: "Call Task with a generic subagent_type and paste the cclaw role prompt; capture worker output as evidenceRefs in the artifact.",
238
+ fulfillmentMode: "generic-dispatch",
239
+ lifecycleCommands: [
240
+ `${helper} ${common} --status=scheduled --dispatch-surface=cursor-task --agent-definition-path=.cclaw/agents/<agent-name>.md --json`,
241
+ `${helper} ${common} --status=launched --dispatch-surface=cursor-task --agent-definition-path=.cclaw/agents/<agent-name>.md --launched-ts=<iso-ts> --json`,
242
+ `${helper} ${common} --status=acknowledged --dispatch-surface=cursor-task --agent-definition-path=.cclaw/agents/<agent-name>.md --ack-ts=<iso-ts> --json`,
243
+ `${helper} ${common} --status=completed --dispatch-surface=cursor-task --agent-definition-path=.cclaw/agents/<agent-name>.md --completed-ts=<iso-ts> --evidence-ref=<artifact-anchor> --json`
244
+ ]
245
+ };
246
+ case "opencode":
247
+ return {
248
+ harnessId,
249
+ dispatchSurface: "opencode-agent",
250
+ agentDefinitionDirectory: ".opencode/agents/",
251
+ agentDefinitionExample: ".opencode/agents/<agent-name>.md",
252
+ invocationLine: "Invoke the generated agent via Task or `@<agent-name>`; the agent body lives in `.opencode/agents/<agent-name>.md`.",
253
+ fulfillmentMode: "isolated",
254
+ lifecycleCommands: [
255
+ `${helper} ${common} --status=scheduled --dispatch-surface=opencode-agent --agent-definition-path=.opencode/agents/<agent-name>.md --json`,
256
+ `${helper} ${common} --status=launched --dispatch-surface=opencode-agent --agent-definition-path=.opencode/agents/<agent-name>.md --launched-ts=<iso-ts> --json`,
257
+ `${helper} ${common} --status=acknowledged --dispatch-surface=opencode-agent --agent-definition-path=.opencode/agents/<agent-name>.md --ack-ts=<iso-ts> --json`,
258
+ `${helper} ${common} --status=completed --dispatch-surface=opencode-agent --agent-definition-path=.opencode/agents/<agent-name>.md --completed-ts=<iso-ts> --json`
259
+ ]
260
+ };
261
+ case "codex":
262
+ return {
263
+ harnessId,
264
+ dispatchSurface: "codex-agent",
265
+ agentDefinitionDirectory: ".codex/agents/",
266
+ agentDefinitionExample: ".codex/agents/<agent-name>.toml",
267
+ invocationLine: "Ask Codex to spawn the named custom agent; the agent definition lives in `.codex/agents/<agent-name>.toml`.",
268
+ fulfillmentMode: "isolated",
269
+ lifecycleCommands: [
270
+ `${helper} ${common} --status=scheduled --dispatch-surface=codex-agent --agent-definition-path=.codex/agents/<agent-name>.toml --json`,
271
+ `${helper} ${common} --status=launched --dispatch-surface=codex-agent --agent-definition-path=.codex/agents/<agent-name>.toml --launched-ts=<iso-ts> --json`,
272
+ `${helper} ${common} --status=acknowledged --dispatch-surface=codex-agent --agent-definition-path=.codex/agents/<agent-name>.toml --ack-ts=<iso-ts> --json`,
273
+ `${helper} ${common} --status=completed --dispatch-surface=codex-agent --agent-definition-path=.codex/agents/<agent-name>.toml --completed-ts=<iso-ts> --json`
274
+ ]
275
+ };
276
+ }
277
+ }
278
+ /** All four harness recipes in tier-stable order. */
279
+ export function harnessDelegationRecipes() {
280
+ return harnessesByTier().map((id) => harnessDelegationRecipe(id));
281
+ }
163
282
  export function harnessDispatchFallback(harnessId) {
164
283
  const adapter = HARNESS_ADAPTERS[harnessId];
165
284
  if (adapter.capabilities.subagentFallback !== "role-switch") {
@@ -597,7 +716,7 @@ async function cleanupLegacyCodexSurfaces(projectRoot) {
597
716
  }
598
717
  }
599
718
  function codexAgentToml(agent) {
600
- const instructions = `${agent.body}\n\n${enhancedAgentInstruction(agent.name)}`.trim();
719
+ const instructions = `${agentMarkdown(agent)}\n\n${enhancedAgentInstruction(agent.name)}`.trim();
601
720
  const sandboxMode = agent.tools.some((tool) => ["Write", "Edit", "Bash"].includes(tool))
602
721
  ? "workspace-write"
603
722
  : "read-only";
@@ -625,7 +744,7 @@ permission:
625
744
  ${agentMarkdown(agent)}`;
626
745
  }
627
746
  function enhancedAgentInstruction(agentName) {
628
- return `You are the cclaw ${agentName} subagent. Follow the parent prompt as the task boundary, produce evidence suitable for .cclaw/state/delegation-log.json, and do not recursively orchestrate other agents unless the parent explicitly asks.`;
747
+ return `## Worker ACK Contract\n\nYou are the cclaw ${agentName} subagent. Follow the parent prompt as the task boundary. ACK first with JSON containing spanId, dispatchId or workerRunId, dispatchSurface, agentDefinitionPath, ackTs, and status: "ACK". Finish with the strict return schema plus the same spanId+dispatchId proof so the parent can append .cclaw/state/delegation-events.jsonl and .cclaw/state/delegation-log.json. Do not let the parent claim isolated completion without matching ACK/result proof. Do not recursively orchestrate other agents unless the parent explicitly asks.`;
629
748
  }
630
749
  async function syncAgentFiles(projectRoot, harnesses) {
631
750
  const agentsDir = path.join(projectRoot, RUNTIME_ROOT, "agents");
package/dist/install.js CHANGED
@@ -13,7 +13,7 @@ import { viewCommandContract, viewCommandSkillMarkdown } from "./content/view-co
13
13
  import { subagentDrivenDevSkill, parallelAgentsSkill } from "./content/subagents.js";
14
14
  import { sessionHooksSkillMarkdown } from "./content/session-hooks.js";
15
15
  import { ironLawRuntimeDocument, ironLawsSkillMarkdown } from "./content/iron-laws.js";
16
- import { stageCompleteScript, startFlowScript, runHookCmdScript, opencodePluginJs, claudeHooksJson, codexHooksJson, cursorHooksJson } from "./content/hooks.js";
16
+ import { stageCompleteScript, startFlowScript, runHookCmdScript, delegationRecordScript, opencodePluginJs, claudeHooksJson, codexHooksJson, cursorHooksJson } from "./content/hooks.js";
17
17
  import { nodeHookRuntimeScript } from "./content/node-hooks.js";
18
18
  import { META_SKILL_NAME, usingCclawSkillMarkdown } from "./content/meta-skill.js";
19
19
  import { ARTIFACT_TEMPLATES, CURSOR_WORKFLOW_RULE_MDC, RULEBOOK_MARKDOWN, buildRulesJson } from "./content/templates.js";
@@ -884,6 +884,7 @@ async function writeHooks(projectRoot, config) {
884
884
  compoundRecurrenceThreshold: config.compound?.recurrenceThreshold
885
885
  }));
886
886
  await writeFileSafe(path.join(hooksDir, "run-hook.cmd"), runHookCmdScript());
887
+ await writeFileSafe(path.join(hooksDir, "delegation-record.mjs"), delegationRecordScript());
887
888
  const opencodePluginSource = opencodePluginJs();
888
889
  await writeFileSafe(path.join(hooksDir, "opencode-plugin.mjs"), opencodePluginSource);
889
890
  try {
@@ -892,6 +893,7 @@ async function writeHooks(projectRoot, config) {
892
893
  "start-flow.mjs",
893
894
  "run-hook.mjs",
894
895
  "run-hook.cmd",
896
+ "delegation-record.mjs",
895
897
  "opencode-plugin.mjs"
896
898
  ]) {
897
899
  await fs.chmod(path.join(hooksDir, script), 0o755);
@@ -6,7 +6,7 @@ import { resolveArtifactPath } from "../artifact-paths.js";
6
6
  import { RUNTIME_ROOT, SHIP_FINALIZATION_MODES } from "../constants.js";
7
7
  import { ensureDir } from "../fs-utils.js";
8
8
  import { stageAutoSubagentDispatch, stageSchema } from "../content/stage-schema.js";
9
- import { appendDelegation, checkMandatoryDelegations, readDelegationLedger } from "../delegation.js";
9
+ import { appendDelegation, checkMandatoryDelegations, readDelegationEvents, readDelegationLedger } from "../delegation.js";
10
10
  import { verifyCompletedStagesGateClosure, verifyCurrentStageGateEvidence } from "../gate-evidence.js";
11
11
  import { extractMarkdownSectionBody, parseLearningsSection } from "../artifact-linter.js";
12
12
  import { getAvailableTransitions, getTransitionGuards, isFlowTrack, createInitialFlowState } from "../flow-state.js";
@@ -669,6 +669,9 @@ async function buildValidationReport(projectRoot, flowState, options = {}) {
669
669
  missing: delegation.missing,
670
670
  waived: delegation.waived,
671
671
  missingEvidence: delegation.missingEvidence,
672
+ missingDispatchProof: delegation.missingDispatchProof,
673
+ legacyInferredCompletions: delegation.legacyInferredCompletions,
674
+ corruptEventLines: delegation.corruptEventLines,
672
675
  staleWorkers: delegation.staleWorkers,
673
676
  expectedMode: delegation.expectedMode
674
677
  },
@@ -897,6 +900,48 @@ async function runAdvanceStage(projectRoot, args, io) {
897
900
  allowBlockedReviewRoute: blockedReviewRoute
898
901
  });
899
902
  if (!validation.ok) {
903
+ const ledgerForDiag = await readDelegationLedger(projectRoot).catch(() => ({ entries: [] }));
904
+ const eventsForDiag = await readDelegationEvents(projectRoot).catch(() => ({ events: [], corruptLines: [] }));
905
+ const ledgerEntriesText = await fs.readFile(path.join(projectRoot, ".cclaw/state/delegation-events.jsonl"), "utf8").catch(() => "");
906
+ const corruptSnippets = (() => {
907
+ if (validation.delegation.corruptEventLines.length === 0)
908
+ return [];
909
+ const lines = ledgerEntriesText.split(/\r?\n/u);
910
+ return validation.delegation.corruptEventLines.slice(0, 3).map((lineNo) => {
911
+ const line = lines[lineNo - 1] ?? "";
912
+ const sample = line.length > 120 ? `${line.slice(0, 117)}...` : line;
913
+ return `line ${lineNo}: ${sample}`;
914
+ });
915
+ })();
916
+ const dispatchProofDetails = validation.delegation.missingDispatchProof.flatMap((agent) => {
917
+ const rows = ledgerForDiag.entries.filter((entry) => entry.agent === agent && entry.status === "completed");
918
+ return rows.map((row) => `${agent}(spanId=${row.spanId ?? "unknown"})`);
919
+ });
920
+ const nextActions = [];
921
+ if (validation.delegation.missing.length > 0) {
922
+ nextActions.push(`Complete or waive mandatory delegation(s): ${validation.delegation.missing.join(", ")}. Helper: \`node .cclaw/hooks/stage-complete.mjs ${args.stage} --waive-delegation=${validation.delegation.missing.join(",")} --waiver-reason="<why safe>"\`.`);
923
+ }
924
+ if (validation.delegation.missingEvidence.length > 0) {
925
+ nextActions.push(`Role-switch fallback completion needs --evidence-ref or escalate to a real isolated dispatch surface.`);
926
+ }
927
+ if (validation.delegation.missingDispatchProof.length > 0) {
928
+ nextActions.push(`Isolated completion(s) ${dispatchProofDetails.join(", ") || validation.delegation.missingDispatchProof.join(", ")} lack matching dispatch proof; run the helper lifecycle scheduled -> launched -> acknowledged -> completed with --span-id, --dispatch-id, --dispatch-surface and --agent-definition-path before advancing.`);
929
+ }
930
+ if (validation.delegation.legacyInferredCompletions.length > 0) {
931
+ nextActions.push(`Pre-v3 ledger entries found: ${validation.delegation.legacyInferredCompletions.join(", ")}. Run \`node .cclaw/hooks/delegation-record.mjs --rerecord --span-id=<id> --dispatch-id=<id> --dispatch-surface=<surface> --agent-definition-path=<path>\` to upgrade the row to dispatch-proof shape.`);
932
+ }
933
+ if (validation.delegation.corruptEventLines.length > 0) {
934
+ nextActions.push(`delegation-events.jsonl has ${validation.delegation.corruptEventLines.length} corrupt line(s) at ${validation.delegation.corruptEventLines.slice(0, 3).join(", ")}${validation.delegation.corruptEventLines.length > 3 ? ", ..." : ""}; remove or fix them before advancing.`);
935
+ }
936
+ if (validation.delegation.staleWorkers.length > 0) {
937
+ nextActions.push(`Stale scheduled delegations ${validation.delegation.staleWorkers.join(", ")} have no terminal row sharing the same spanId; emit launched/acknowledged/completed (or failed/stale) before advancing.`);
938
+ }
939
+ if (validation.gates.issues.length > 0) {
940
+ nextActions.push("Fix the artifact/gate issue shown in gates.issues, then rerun stage-complete.");
941
+ }
942
+ if (validation.completedStages.issues.length > 0) {
943
+ nextActions.push("Repair previously completed stage gate closure before advancing.");
944
+ }
900
945
  if (args.json) {
901
946
  io.stdout.write(`${JSON.stringify({
902
947
  ok: false,
@@ -906,23 +951,12 @@ async function runAdvanceStage(projectRoot, args, io) {
906
951
  delegation: validation.delegation,
907
952
  gates: validation.gates,
908
953
  completedStages: validation.completedStages,
909
- nextActions: [
910
- ...(validation.delegation.missing.length > 0
911
- ? [`Complete or waive mandatory delegation(s): ${validation.delegation.missing.join(", ")}.`]
912
- : []),
913
- ...(validation.delegation.missingEvidence.length > 0
914
- ? ["Add evidenceRefs for role-switch delegation completion or use an explicit waiver reason."]
915
- : []),
916
- ...(validation.delegation.staleWorkers.length > 0
917
- ? ["Resolve scheduled delegation span(s) without terminal lifecycle evidence before advancing."]
918
- : []),
919
- ...(validation.gates.issues.length > 0
920
- ? ["Fix the artifact/gate issue shown in gates.issues, then rerun stage-complete."]
921
- : []),
922
- ...(validation.completedStages.issues.length > 0
923
- ? ["Repair previously completed stage gate closure before advancing."]
924
- : [])
925
- ]
954
+ diagnostics: {
955
+ dispatchProofRows: dispatchProofDetails,
956
+ corruptEventSamples: corruptSnippets,
957
+ unawareEvents: eventsForDiag.corruptLines.length
958
+ },
959
+ nextActions
926
960
  })}\n`);
927
961
  }
928
962
  io.stderr.write(`cclaw internal advance-stage: validation failed for stage "${args.stage}".\n`);
@@ -932,9 +966,25 @@ async function runAdvanceStage(projectRoot, args, io) {
932
966
  }
933
967
  if (validation.delegation.missingEvidence.length > 0) {
934
968
  io.stderr.write(`- role-switch evidence missing: ${validation.delegation.missingEvidence.join(", ")}\n`);
969
+ io.stderr.write(` next action: include --evidence-ref=<artifact#anchor> when emitting the completed event, or escalate to a true isolated dispatch surface.\n`);
970
+ }
971
+ if (validation.delegation.missingDispatchProof.length > 0) {
972
+ io.stderr.write(`- isolated completion lacks dispatch proof: ${dispatchProofDetails.join(", ") || validation.delegation.missingDispatchProof.join(", ")}\n`);
973
+ io.stderr.write(` next action: emit scheduled -> launched -> acknowledged -> completed with --span-id, --dispatch-id, --dispatch-surface, --agent-definition-path before advancing.\n`);
974
+ }
975
+ if (validation.delegation.legacyInferredCompletions.length > 0) {
976
+ io.stderr.write(`- legacy-inferred completions need rerecord: ${validation.delegation.legacyInferredCompletions.join(", ")}\n`);
977
+ io.stderr.write(` next action: \`node .cclaw/hooks/delegation-record.mjs --rerecord --span-id=<id> --dispatch-id=<id> --dispatch-surface=<surface> --agent-definition-path=<path>\`.\n`);
978
+ }
979
+ if (validation.delegation.corruptEventLines.length > 0) {
980
+ io.stderr.write(`- corrupt delegation-events.jsonl line(s): ${validation.delegation.corruptEventLines.slice(0, 3).join(", ")}${validation.delegation.corruptEventLines.length > 3 ? `, ... (+${validation.delegation.corruptEventLines.length - 3})` : ""}\n`);
981
+ for (const snippet of corruptSnippets) {
982
+ io.stderr.write(` sample: ${snippet}\n`);
983
+ }
935
984
  }
936
985
  if (validation.delegation.staleWorkers.length > 0) {
937
986
  io.stderr.write(`- stale scheduled delegations: ${validation.delegation.staleWorkers.join(", ")}\n`);
987
+ io.stderr.write(` next action: emit a terminal row (completed/failed/stale) for the same span before advancing.\n`);
938
988
  }
939
989
  if (validation.gates.issues.length > 0) {
940
990
  io.stderr.write(`- gate issues: ${validation.gates.issues.join(" | ")}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "0.51.25",
3
+ "version": "0.51.27",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {