cclaw-cli 0.32.0 → 0.34.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.
@@ -54,16 +54,22 @@ export const HARNESS_ADAPTERS = {
54
54
  capabilities: {
55
55
  nativeSubagentDispatch: "full",
56
56
  hookSurface: "full",
57
- structuredAsk: "AskUserQuestion"
57
+ structuredAsk: "AskUserQuestion",
58
+ subagentFallback: "native"
58
59
  }
59
60
  },
60
61
  cursor: {
61
62
  id: "cursor",
62
63
  commandDir: ".cursor/commands",
63
64
  capabilities: {
64
- nativeSubagentDispatch: "partial",
65
+ // Cursor has a real Task tool with subagent_type (generalPurpose,
66
+ // explore, shell, browser-use, …) but no user-defined named
67
+ // subagents. cclaw maps each named agent (planner/reviewer/…) onto
68
+ // generic dispatch with a role prompt — see the cursor playbook.
69
+ nativeSubagentDispatch: "generic",
65
70
  hookSurface: "full",
66
- structuredAsk: "AskQuestion"
71
+ structuredAsk: "AskQuestion",
72
+ subagentFallback: "generic-dispatch"
67
73
  }
68
74
  },
69
75
  opencode: {
@@ -72,7 +78,8 @@ export const HARNESS_ADAPTERS = {
72
78
  capabilities: {
73
79
  nativeSubagentDispatch: "partial",
74
80
  hookSurface: "plugin",
75
- structuredAsk: "plain-text"
81
+ structuredAsk: "plain-text",
82
+ subagentFallback: "role-switch"
76
83
  }
77
84
  },
78
85
  codex: {
@@ -81,7 +88,8 @@ export const HARNESS_ADAPTERS = {
81
88
  capabilities: {
82
89
  nativeSubagentDispatch: "none",
83
90
  hookSurface: "full",
84
- structuredAsk: "plain-text"
91
+ structuredAsk: "plain-text",
92
+ subagentFallback: "role-switch"
85
93
  }
86
94
  }
87
95
  };
@@ -94,11 +102,22 @@ export function harnessTier(harnessId) {
94
102
  }
95
103
  if (capabilities.hookSurface === "full" ||
96
104
  capabilities.hookSurface === "plugin" ||
105
+ capabilities.nativeSubagentDispatch === "generic" ||
97
106
  capabilities.nativeSubagentDispatch === "partial") {
98
107
  return "tier2";
99
108
  }
100
109
  return "tier3";
101
110
  }
111
+ /**
112
+ * Harness IDs ordered from best (tier1) to least-capable. Stable sort — same
113
+ * tier preserves declaration order.
114
+ */
115
+ export function harnessesByTier() {
116
+ return Object.keys(HARNESS_ADAPTERS).sort((a, b) => {
117
+ const tierOrder = { tier1: 0, tier2: 1, tier3: 2 };
118
+ return tierOrder[harnessTier(a)] - tierOrder[harnessTier(b)];
119
+ });
120
+ }
102
121
  function agentsMdBlock() {
103
122
  return `${CCLAW_MARKER_START}
104
123
  ## Cclaw — Workflow Adapter
package/dist/install.js CHANGED
@@ -37,6 +37,7 @@ import { RESEARCH_PLAYBOOKS } from "./content/research-playbooks.js";
37
37
  import { HARNESS_TOOL_REFS_DIR, HARNESS_TOOL_REFS_INDEX_MD, harnessToolRefMarkdown } from "./content/harness-tool-refs.js";
38
38
  import { DOCTOR_REFERENCE_MARKDOWN } from "./content/doctor-references.js";
39
39
  import { harnessIntegrationDocMarkdown } from "./content/harnesses-doc.js";
40
+ import { HARNESS_PLAYBOOKS_DIR, harnessPlaybookFileName, harnessPlaybookMarkdown, harnessPlaybooksIndexMarkdown } from "./content/harness-playbooks.js";
40
41
  import { HOOK_EVENTS_BY_HARNESS, HOOK_SEMANTIC_EVENTS } from "./content/hook-events.js";
41
42
  import { createInitialFlowState } from "./flow-state.js";
42
43
  import { ensureDir, exists, writeFileSafe } from "./fs-utils.js";
@@ -293,6 +294,15 @@ async function writeSkills(projectRoot, config) {
293
294
  await writeFileSafe(runtimePath(projectRoot, ...doctorRefsDir, fileName), markdown);
294
295
  }
295
296
  await writeFileSafe(runtimePath(projectRoot, "references", "harnesses.md"), harnessIntegrationDocMarkdown());
297
+ // Per-harness parity playbooks. Generated for every supported harness
298
+ // regardless of which harnesses the project installed — the index always
299
+ // resolves, and doctor only asserts presence of the installed harnesses'
300
+ // playbooks (see runtime-integrity checks).
301
+ const playbookDirSegments = HARNESS_PLAYBOOKS_DIR.split("/");
302
+ await writeFileSafe(runtimePath(projectRoot, ...playbookDirSegments, "README.md"), harnessPlaybooksIndexMarkdown());
303
+ for (const harness of harnessIds) {
304
+ await writeFileSafe(runtimePath(projectRoot, ...playbookDirSegments, harnessPlaybookFileName(harness)), harnessPlaybookMarkdown(harness));
305
+ }
296
306
  }
297
307
  async function writeUtilityCommands(projectRoot) {
298
308
  await writeFileSafe(runtimePath(projectRoot, "commands", "learn.md"), learnCommandContract());
@@ -948,15 +958,40 @@ async function writeHarnessGapsState(projectRoot, harnesses) {
948
958
  if (capabilities.structuredAsk === "plain-text") {
949
959
  missingCapabilities.push("structuredAsk:none");
950
960
  }
961
+ const remediation = [];
962
+ switch (capabilities.subagentFallback) {
963
+ case "native":
964
+ // nothing to remediate — harness has first-class dispatch
965
+ break;
966
+ case "generic-dispatch":
967
+ remediation.push(`subagent dispatch → map named cclaw agents onto generic Task subagent_type per ${HARNESS_PLAYBOOKS_DIR}/${harness}-playbook.md`);
968
+ break;
969
+ case "role-switch":
970
+ remediation.push(`subagent dispatch → role-switch in-session with evidenceRefs per ${HARNESS_PLAYBOOKS_DIR}/${harness}-playbook.md`);
971
+ break;
972
+ case "waiver":
973
+ remediation.push(`subagent dispatch → record explicit harness_limitation waiver; no parity path available`);
974
+ break;
975
+ }
976
+ if (capabilities.structuredAsk === "plain-text") {
977
+ remediation.push("structured ask → fall back to a numbered plain-text list; first option is default");
978
+ }
979
+ for (const event of missingHookEvents) {
980
+ remediation.push(`hook event ${event} → schedule the corresponding script manually or accept reduced observability`);
981
+ }
951
982
  return {
952
983
  harness,
953
984
  tier: harnessTier(harness),
985
+ subagentFallback: capabilities.subagentFallback,
986
+ playbookPath: `${RUNTIME_ROOT}/${HARNESS_PLAYBOOKS_DIR}/${harness}-playbook.md`,
954
987
  missingCapabilities,
955
- missingHookEvents
988
+ missingHookEvents,
989
+ remediation
956
990
  };
957
991
  });
958
992
  await writeFileSafe(runtimePath(projectRoot, "state", "harness-gaps.json"), `${JSON.stringify({
959
993
  generatedAt: new Date().toISOString(),
994
+ schemaVersion: 2,
960
995
  harnesses: report
961
996
  }, null, 2)}\n`);
962
997
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "0.32.0",
3
+ "version": "0.34.0",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {