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.
- package/README.md +47 -19
- package/dist/content/diff-command.js +66 -20
- package/dist/content/harness-playbooks.d.ts +24 -0
- package/dist/content/harness-playbooks.js +292 -0
- package/dist/content/harnesses-doc.js +13 -3
- package/dist/content/status-command.js +89 -27
- package/dist/content/subagents.js +14 -8
- package/dist/content/tree-command.js +66 -16
- package/dist/delegation.d.ts +28 -0
- package/dist/delegation.js +47 -7
- package/dist/doctor.js +18 -2
- package/dist/harness-adapters.d.ts +40 -1
- package/dist/harness-adapters.js +24 -5
- package/dist/install.js +36 -1
- package/package.json +1 -1
package/dist/harness-adapters.js
CHANGED
|
@@ -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
|
-
|
|
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
|
}
|