cclaw-cli 0.46.4 → 0.46.5

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.
@@ -17,5 +17,5 @@ export declare function preCompactScript(): string;
17
17
  export { claudeHooksJsonWithObservation as claudeHooksJson } from "./observe.js";
18
18
  export { cursorHooksJsonWithObservation as cursorHooksJson } from "./observe.js";
19
19
  export { codexHooksJsonWithObservation as codexHooksJson } from "./observe.js";
20
- export declare function opencodePluginJs(_options?: HookRuntimeOptions): string;
20
+ export { opencodePluginJs } from "./opencode-plugin.js";
21
21
  export declare function hooksAgentsMdBlock(): string;
@@ -1002,293 +1002,7 @@ export { codexHooksJsonWithObservation as codexHooksJson } from "./observe.js";
1002
1002
  // ---------------------------------------------------------------------------
1003
1003
  // OpenCode plugin — JS module
1004
1004
  // ---------------------------------------------------------------------------
1005
- export function opencodePluginJs(_options = {}) {
1006
- return `// cclaw OpenCode plugin — generated by cclaw sync
1007
- import { existsSync, mkdirSync, readFileSync } from "node:fs";
1008
- import { join } from "node:path";
1009
-
1010
- export default function cclawPlugin(ctx) {
1011
- const root = ctx.directory || process.cwd();
1012
- const runtimeDir = join(root, "${RUNTIME_ROOT}");
1013
- const stateDir = join(runtimeDir, "state");
1014
- const flowStatePath = join(stateDir, "flow-state.json");
1015
- const checkpointPath = join(stateDir, "checkpoint.json");
1016
- const activityPath = join(stateDir, "stage-activity.jsonl");
1017
- const contextWarningsPath = join(stateDir, "context-warnings.jsonl");
1018
- const contextModePath = join(stateDir, "context-mode.json");
1019
- const contextsDir = join(runtimeDir, "contexts");
1020
- const sessionDigestPath = join(stateDir, "session-digest.md");
1021
- const knowledgePath = join(runtimeDir, "knowledge.jsonl");
1022
- const knowledgeDigestPath = join(stateDir, "knowledge-digest.md");
1023
- const metaSkillPath = join(runtimeDir, "skills/${META_SKILL_NAME}/SKILL.md");
1024
-
1025
- function ensureRuntimeDirs() {
1026
- try {
1027
- mkdirSync(runtimeDir, { recursive: true });
1028
- } catch {
1029
- // ignore
1030
- }
1031
- try {
1032
- mkdirSync(stateDir, { recursive: true });
1033
- } catch {
1034
- // ignore
1035
- }
1036
- }
1037
-
1038
- function readFlowState() {
1039
- try {
1040
- const raw = readFileSync(flowStatePath, "utf8");
1041
- const state = JSON.parse(raw);
1042
- return {
1043
- stage: typeof state.currentStage === "string" ? state.currentStage : "none",
1044
- completed: Array.isArray(state.completedStages) ? state.completedStages.length : 0,
1045
- activeRunId: typeof state.activeRunId === "string" ? state.activeRunId : "none"
1046
- };
1047
- } catch {
1048
- return { stage: "none", completed: 0, activeRunId: "none" };
1049
- }
1050
- }
1051
-
1052
- function readFileText(filePath) {
1053
- try {
1054
- return readFileSync(filePath, "utf8");
1055
- } catch {
1056
- return "";
1057
- }
1058
- }
1059
-
1060
- function readTailLines(filePath, maxLines) {
1061
- const text = readFileText(filePath).trim();
1062
- if (!text) return [];
1063
- return text.split(/\\r?\\n/).slice(-maxLines);
1064
- }
1065
-
1066
- function readCheckpointSummary() {
1067
- try {
1068
- const raw = readFileText(checkpointPath);
1069
- if (!raw) return "";
1070
- const cp = JSON.parse(raw);
1071
- return \`Checkpoint: stage=\${cp.stage || "none"}, status=\${cp.status || "unknown"}, run=\${cp.runId || "none"}, at=\${cp.timestamp || "unknown"}\`;
1072
- } catch {
1073
- return "";
1074
- }
1075
- }
1076
-
1077
- function readContextMode() {
1078
- let mode = "default";
1079
- try {
1080
- const parsed = JSON.parse(readFileText(contextModePath));
1081
- if (parsed && typeof parsed.activeMode === "string" && parsed.activeMode.trim().length > 0) {
1082
- mode = parsed.activeMode.trim();
1083
- }
1084
- } catch {
1085
- // keep default
1086
- }
1087
- const guidePath = join(contextsDir, mode + ".md");
1088
- const guide = existsSync(guidePath) ? "${RUNTIME_ROOT}/contexts/" + mode + ".md" : "";
1089
- return { mode, guide };
1090
- }
1091
-
1092
- function readRecentActivity() {
1093
- try {
1094
- const lines = readTailLines(activityPath, 5);
1095
- if (lines.length === 0) return [];
1096
- return lines
1097
- .map((line) => {
1098
- try {
1099
- return JSON.parse(line);
1100
- } catch {
1101
- return null;
1102
- }
1103
- })
1104
- .filter(Boolean)
1105
- .map((entry) => \`- \${entry.ts || "unknown"} [\${entry.phase || "unknown"}] \${entry.tool || "unknown"} (stage=\${entry.stage || "unknown"}, run=\${entry.runId || "none"})\`);
1106
- } catch {
1107
- return [];
1108
- }
1109
- }
1110
-
1111
- function readLatestContextWarning() {
1112
- try {
1113
- const line = readTailLines(contextWarningsPath, 1)[0];
1114
- if (!line) return "";
1115
- try {
1116
- const parsed = JSON.parse(line);
1117
- if (parsed && typeof parsed.note === "string") return parsed.note;
1118
- } catch {
1119
- // non-json fallback
1120
- }
1121
- return line;
1122
- } catch {
1123
- return "";
1124
- }
1125
- }
1126
-
1127
- function readKnowledgeDigest() {
1128
- const digest = readFileText(knowledgeDigestPath).trim();
1129
- if (!digest) {
1130
- return readTailLines(knowledgePath, 12);
1131
- }
1132
- return digest
1133
- .split(/\\r?\\n/)
1134
- .map((line) => line.trim())
1135
- .filter((line) => line.length > 0)
1136
- .filter((line) => !line.startsWith("#"));
1137
- }
1138
-
1139
- function buildBootstrap() {
1140
- const flow = readFlowState();
1141
- const parts = [
1142
- \`cclaw loaded. Flow: stage=\${flow.stage} (\${flow.completed}/8 completed, run=\${flow.activeRunId}). Active artifacts: ${RUNTIME_ROOT}/artifacts/\`
1143
- ];
1144
- const contextMode = readContextMode();
1145
- parts.push(
1146
- contextMode.guide
1147
- ? \`Context mode: \${contextMode.mode} (guide: \${contextMode.guide})\`
1148
- : \`Context mode: \${contextMode.mode}\`
1149
- );
1150
-
1151
- const checkpoint = readCheckpointSummary();
1152
- if (checkpoint) parts.push(checkpoint);
1153
-
1154
- const digest = readFileText(sessionDigestPath).trim();
1155
- if (digest) parts.push("Last session:", digest);
1156
-
1157
- const activity = readRecentActivity();
1158
- if (activity.length > 0) parts.push("Recent stage activity:", ...activity);
1159
-
1160
- const warning = readLatestContextWarning();
1161
- if (warning) parts.push("Latest context warning:", warning);
1162
-
1163
- const knowledge = readKnowledgeDigest();
1164
- if (knowledge.length > 0) parts.push("Knowledge digest (top relevant entries):", ...knowledge);
1165
-
1166
- parts.push(
1167
- "If you discover a non-obvious rule or pattern, append one strict-schema JSON line to .cclaw/knowledge.jsonl using type: rule, pattern, lesson, or compound."
1168
- );
1169
-
1170
- const meta = readFileText(metaSkillPath).trim();
1171
- if (meta) parts.push("", meta);
1172
- return parts.join("\\n");
1173
- }
1174
-
1175
- let bootstrapCache = "";
1176
-
1177
- function refreshBootstrapCache() {
1178
- bootstrapCache = buildBootstrap();
1179
- }
1180
-
1181
- function getBootstrap() {
1182
- if (!bootstrapCache) refreshBootstrapCache();
1183
- return bootstrapCache;
1184
- }
1185
-
1186
- async function runHookScript(scriptFileName, payload = {}) {
1187
- const { spawnSync } = await import("node:child_process");
1188
- const scriptPath = join(root, "${RUNTIME_ROOT}/hooks/" + scriptFileName);
1189
- const input = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
1190
- try {
1191
- const result = spawnSync("bash", [scriptPath], {
1192
- cwd: root,
1193
- timeout: 20000,
1194
- stdio: ["pipe", "ignore", "ignore"],
1195
- input
1196
- });
1197
- return typeof result.status === "number" ? result.status === 0 : false;
1198
- } catch {
1199
- return false;
1200
- }
1201
- }
1202
-
1203
- function normalizeToolPayload(input, output) {
1204
- if (typeof output === "undefined") return input ?? {};
1205
- return { input: input ?? {}, output: output ?? {} };
1206
- }
1207
-
1208
- function resolveEventType(payload) {
1209
- if (typeof payload === "string") return payload;
1210
- if (payload && typeof payload === "object") {
1211
- if (typeof payload.type === "string") return payload.type;
1212
- if (typeof payload.name === "string") return payload.name;
1213
- if (payload.event && typeof payload.event === "object") {
1214
- if (typeof payload.event.type === "string") return payload.event.type;
1215
- if (typeof payload.event.name === "string") return payload.event.name;
1216
- }
1217
- }
1218
- return "";
1219
- }
1220
-
1221
- function resolveEventData(payload) {
1222
- if (payload && typeof payload === "object" && payload.event && typeof payload.event === "object") {
1223
- return payload.event;
1224
- }
1225
- return payload;
1226
- }
1227
-
1228
- ensureRuntimeDirs();
1229
-
1230
- return {
1231
- event: async (payload) => {
1232
- const eventType = resolveEventType(payload);
1233
- const eventData = resolveEventData(payload);
1234
- if (
1235
- eventType === "session.created" ||
1236
- eventType === "session.resumed" ||
1237
- eventType === "session.compacted" ||
1238
- eventType === "session.cleared"
1239
- ) {
1240
- // Avoid writing directly to stdout in lifecycle hooks because it can
1241
- // interfere with OpenCode TUI rendering. Bootstrap is injected via
1242
- // the system transform hook instead.
1243
- refreshBootstrapCache();
1244
- }
1245
- if (eventType === "session.idle") {
1246
- await runHookScript("stop-checkpoint.sh", { loop_count: 0 });
1247
- }
1248
- if (eventType === "tool.execute.before") {
1249
- const toolPayload = normalizeToolPayload(eventData, undefined);
1250
- const promptOk = await runHookScript("prompt-guard.sh", toolPayload);
1251
- const workflowOk = await runHookScript("workflow-guard.sh", toolPayload);
1252
- if (!promptOk || !workflowOk) {
1253
- throw new Error(
1254
- "cclaw OpenCode guard blocked tool.execute.before (prompt/workflow guard non-zero exit)."
1255
- );
1256
- }
1257
- }
1258
- if (eventType === "tool.execute.after") {
1259
- const toolPayload = normalizeToolPayload(eventData, undefined);
1260
- await runHookScript("context-monitor.sh", toolPayload);
1261
- }
1262
- },
1263
- "tool.execute.before": async (input, output) => {
1264
- const payload = normalizeToolPayload(input, output);
1265
- const promptOk = await runHookScript("prompt-guard.sh", payload);
1266
- const workflowOk = await runHookScript("workflow-guard.sh", payload);
1267
- if (!promptOk || !workflowOk) {
1268
- throw new Error(
1269
- "cclaw OpenCode guard blocked tool.execute.before (prompt/workflow guard non-zero exit)."
1270
- );
1271
- }
1272
- },
1273
- "tool.execute.after": async (input, output) => {
1274
- const payload = normalizeToolPayload(input, output);
1275
- await runHookScript("context-monitor.sh", payload);
1276
- },
1277
- "experimental.chat.system.transform": (payload) => {
1278
- const bootstrap = getBootstrap();
1279
- if (typeof payload === "string") {
1280
- return payload.includes("cclaw loaded.") ? payload : \`\${payload}\\n\\n\${bootstrap}\`;
1281
- }
1282
- if (payload && typeof payload === "object" && typeof payload.system === "string") {
1283
- if (payload.system.includes("cclaw loaded.")) return payload;
1284
- return { ...payload, system: \`\${payload.system}\\n\\n\${bootstrap}\` };
1285
- }
1286
- return payload;
1287
- }
1288
- };
1289
- }
1290
- `;
1291
- }
1005
+ export { opencodePluginJs } from "./opencode-plugin.js";
1292
1006
  // ---------------------------------------------------------------------------
1293
1007
  // AGENTS.md block for hooks
1294
1008
  // ---------------------------------------------------------------------------
@@ -0,0 +1 @@
1
+ export declare function opencodePluginJs(_options?: Record<string, never>): string;
@@ -0,0 +1,289 @@
1
+ import { RUNTIME_ROOT } from "../constants.js";
2
+ import { META_SKILL_NAME } from "./meta-skill.js";
3
+ export function opencodePluginJs(_options = {}) {
4
+ return `// cclaw OpenCode plugin — generated by cclaw sync
5
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
6
+ import { join } from "node:path";
7
+
8
+ export default function cclawPlugin(ctx) {
9
+ const root = ctx.directory || process.cwd();
10
+ const runtimeDir = join(root, "${RUNTIME_ROOT}");
11
+ const stateDir = join(runtimeDir, "state");
12
+ const flowStatePath = join(stateDir, "flow-state.json");
13
+ const checkpointPath = join(stateDir, "checkpoint.json");
14
+ const activityPath = join(stateDir, "stage-activity.jsonl");
15
+ const contextWarningsPath = join(stateDir, "context-warnings.jsonl");
16
+ const contextModePath = join(stateDir, "context-mode.json");
17
+ const contextsDir = join(runtimeDir, "contexts");
18
+ const sessionDigestPath = join(stateDir, "session-digest.md");
19
+ const knowledgePath = join(runtimeDir, "knowledge.jsonl");
20
+ const knowledgeDigestPath = join(stateDir, "knowledge-digest.md");
21
+ const metaSkillPath = join(runtimeDir, "skills/${META_SKILL_NAME}/SKILL.md");
22
+
23
+ function ensureRuntimeDirs() {
24
+ try {
25
+ mkdirSync(runtimeDir, { recursive: true });
26
+ } catch {
27
+ // ignore
28
+ }
29
+ try {
30
+ mkdirSync(stateDir, { recursive: true });
31
+ } catch {
32
+ // ignore
33
+ }
34
+ }
35
+
36
+ function readFlowState() {
37
+ try {
38
+ const raw = readFileSync(flowStatePath, "utf8");
39
+ const state = JSON.parse(raw);
40
+ return {
41
+ stage: typeof state.currentStage === "string" ? state.currentStage : "none",
42
+ completed: Array.isArray(state.completedStages) ? state.completedStages.length : 0,
43
+ activeRunId: typeof state.activeRunId === "string" ? state.activeRunId : "none"
44
+ };
45
+ } catch {
46
+ return { stage: "none", completed: 0, activeRunId: "none" };
47
+ }
48
+ }
49
+
50
+ function readFileText(filePath) {
51
+ try {
52
+ return readFileSync(filePath, "utf8");
53
+ } catch {
54
+ return "";
55
+ }
56
+ }
57
+
58
+ function readTailLines(filePath, maxLines) {
59
+ const text = readFileText(filePath).trim();
60
+ if (!text) return [];
61
+ return text.split(/\\r?\\n/).slice(-maxLines);
62
+ }
63
+
64
+ function readCheckpointSummary() {
65
+ try {
66
+ const raw = readFileText(checkpointPath);
67
+ if (!raw) return "";
68
+ const cp = JSON.parse(raw);
69
+ return \`Checkpoint: stage=\${cp.stage || "none"}, status=\${cp.status || "unknown"}, run=\${cp.runId || "none"}, at=\${cp.timestamp || "unknown"}\`;
70
+ } catch {
71
+ return "";
72
+ }
73
+ }
74
+
75
+ function readContextMode() {
76
+ let mode = "default";
77
+ try {
78
+ const parsed = JSON.parse(readFileText(contextModePath));
79
+ if (parsed && typeof parsed.activeMode === "string" && parsed.activeMode.trim().length > 0) {
80
+ mode = parsed.activeMode.trim();
81
+ }
82
+ } catch {
83
+ // keep default
84
+ }
85
+ const guidePath = join(contextsDir, mode + ".md");
86
+ const guide = existsSync(guidePath) ? "${RUNTIME_ROOT}/contexts/" + mode + ".md" : "";
87
+ return { mode, guide };
88
+ }
89
+
90
+ function readRecentActivity() {
91
+ try {
92
+ const lines = readTailLines(activityPath, 5);
93
+ if (lines.length === 0) return [];
94
+ return lines
95
+ .map((line) => {
96
+ try {
97
+ return JSON.parse(line);
98
+ } catch {
99
+ return null;
100
+ }
101
+ })
102
+ .filter(Boolean)
103
+ .map((entry) => \`- \${entry.ts || "unknown"} [\${entry.phase || "unknown"}] \${entry.tool || "unknown"} (stage=\${entry.stage || "unknown"}, run=\${entry.runId || "none"})\`);
104
+ } catch {
105
+ return [];
106
+ }
107
+ }
108
+
109
+ function readLatestContextWarning() {
110
+ try {
111
+ const line = readTailLines(contextWarningsPath, 1)[0];
112
+ if (!line) return "";
113
+ try {
114
+ const parsed = JSON.parse(line);
115
+ if (parsed && typeof parsed.note === "string") return parsed.note;
116
+ } catch {
117
+ // non-json fallback
118
+ }
119
+ return line;
120
+ } catch {
121
+ return "";
122
+ }
123
+ }
124
+
125
+ function readKnowledgeDigest() {
126
+ const digest = readFileText(knowledgeDigestPath).trim();
127
+ if (!digest) {
128
+ return readTailLines(knowledgePath, 12);
129
+ }
130
+ return digest
131
+ .split(/\\r?\\n/)
132
+ .map((line) => line.trim())
133
+ .filter((line) => line.length > 0)
134
+ .filter((line) => !line.startsWith("#"));
135
+ }
136
+
137
+ function buildBootstrap() {
138
+ const flow = readFlowState();
139
+ const parts = [
140
+ \`cclaw loaded. Flow: stage=\${flow.stage} (\${flow.completed}/8 completed, run=\${flow.activeRunId}). Active artifacts: ${RUNTIME_ROOT}/artifacts/\`
141
+ ];
142
+ const contextMode = readContextMode();
143
+ parts.push(
144
+ contextMode.guide
145
+ ? \`Context mode: \${contextMode.mode} (guide: \${contextMode.guide})\`
146
+ : \`Context mode: \${contextMode.mode}\`
147
+ );
148
+
149
+ const checkpoint = readCheckpointSummary();
150
+ if (checkpoint) parts.push(checkpoint);
151
+
152
+ const digest = readFileText(sessionDigestPath).trim();
153
+ if (digest) parts.push("Last session:", digest);
154
+
155
+ const activity = readRecentActivity();
156
+ if (activity.length > 0) parts.push("Recent stage activity:", ...activity);
157
+
158
+ const warning = readLatestContextWarning();
159
+ if (warning) parts.push("Latest context warning:", warning);
160
+
161
+ const knowledge = readKnowledgeDigest();
162
+ if (knowledge.length > 0) parts.push("Knowledge digest (top relevant entries):", ...knowledge);
163
+
164
+ parts.push(
165
+ "If you discover a non-obvious rule or pattern, append one strict-schema JSON line to .cclaw/knowledge.jsonl using type: rule, pattern, lesson, or compound."
166
+ );
167
+
168
+ const meta = readFileText(metaSkillPath).trim();
169
+ if (meta) parts.push("", meta);
170
+ return parts.join("\\n");
171
+ }
172
+
173
+ let bootstrapCache = "";
174
+
175
+ function refreshBootstrapCache() {
176
+ bootstrapCache = buildBootstrap();
177
+ }
178
+
179
+ function getBootstrap() {
180
+ if (!bootstrapCache) refreshBootstrapCache();
181
+ return bootstrapCache;
182
+ }
183
+
184
+ async function runHookScript(scriptFileName, payload = {}) {
185
+ const { spawnSync } = await import("node:child_process");
186
+ const scriptPath = join(root, "${RUNTIME_ROOT}/hooks/" + scriptFileName);
187
+ const input = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
188
+ try {
189
+ const result = spawnSync("bash", [scriptPath], {
190
+ cwd: root,
191
+ timeout: 20000,
192
+ stdio: ["pipe", "ignore", "ignore"],
193
+ input
194
+ });
195
+ return typeof result.status === "number" ? result.status === 0 : false;
196
+ } catch {
197
+ return false;
198
+ }
199
+ }
200
+
201
+ function normalizeToolPayload(input, output) {
202
+ if (typeof output === "undefined") return input ?? {};
203
+ return { input: input ?? {}, output: output ?? {} };
204
+ }
205
+
206
+ function resolveEventType(payload) {
207
+ if (typeof payload === "string") return payload;
208
+ if (payload && typeof payload === "object") {
209
+ if (typeof payload.type === "string") return payload.type;
210
+ if (typeof payload.name === "string") return payload.name;
211
+ if (payload.event && typeof payload.event === "object") {
212
+ if (typeof payload.event.type === "string") return payload.event.type;
213
+ if (typeof payload.event.name === "string") return payload.event.name;
214
+ }
215
+ }
216
+ return "";
217
+ }
218
+
219
+ function resolveEventData(payload) {
220
+ if (payload && typeof payload === "object" && payload.event && typeof payload.event === "object") {
221
+ return payload.event;
222
+ }
223
+ return payload;
224
+ }
225
+
226
+ ensureRuntimeDirs();
227
+
228
+ return {
229
+ event: async (payload) => {
230
+ const eventType = resolveEventType(payload);
231
+ const eventData = resolveEventData(payload);
232
+ if (
233
+ eventType === "session.created" ||
234
+ eventType === "session.resumed" ||
235
+ eventType === "session.compacted" ||
236
+ eventType === "session.cleared"
237
+ ) {
238
+ // Avoid writing directly to stdout in lifecycle hooks because it can
239
+ // interfere with OpenCode TUI rendering. Bootstrap is injected via
240
+ // the system transform hook instead.
241
+ refreshBootstrapCache();
242
+ }
243
+ if (eventType === "session.idle") {
244
+ await runHookScript("stop-checkpoint.sh", { loop_count: 0 });
245
+ }
246
+ if (eventType === "tool.execute.before") {
247
+ const toolPayload = normalizeToolPayload(eventData, undefined);
248
+ const promptOk = await runHookScript("prompt-guard.sh", toolPayload);
249
+ const workflowOk = await runHookScript("workflow-guard.sh", toolPayload);
250
+ if (!promptOk || !workflowOk) {
251
+ throw new Error(
252
+ "cclaw OpenCode guard blocked tool.execute.before (prompt/workflow guard non-zero exit)."
253
+ );
254
+ }
255
+ }
256
+ if (eventType === "tool.execute.after") {
257
+ const toolPayload = normalizeToolPayload(eventData, undefined);
258
+ await runHookScript("context-monitor.sh", toolPayload);
259
+ }
260
+ },
261
+ "tool.execute.before": async (input, output) => {
262
+ const payload = normalizeToolPayload(input, output);
263
+ const promptOk = await runHookScript("prompt-guard.sh", payload);
264
+ const workflowOk = await runHookScript("workflow-guard.sh", payload);
265
+ if (!promptOk || !workflowOk) {
266
+ throw new Error(
267
+ "cclaw OpenCode guard blocked tool.execute.before (prompt/workflow guard non-zero exit)."
268
+ );
269
+ }
270
+ },
271
+ "tool.execute.after": async (input, output) => {
272
+ const payload = normalizeToolPayload(input, output);
273
+ await runHookScript("context-monitor.sh", payload);
274
+ },
275
+ "experimental.chat.system.transform": (payload) => {
276
+ const bootstrap = getBootstrap();
277
+ if (typeof payload === "string") {
278
+ return payload.includes("cclaw loaded.") ? payload : \`\${payload}\\n\\n\${bootstrap}\`;
279
+ }
280
+ if (payload && typeof payload === "object" && typeof payload.system === "string") {
281
+ if (payload.system.includes("cclaw loaded.")) return payload;
282
+ return { ...payload, system: \`\${payload.system}\\n\\n\${bootstrap}\` };
283
+ }
284
+ return payload;
285
+ }
286
+ };
287
+ }
288
+ `;
289
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "0.46.4",
3
+ "version": "0.46.5",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {