@carboncode/cli 0.1.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.
Files changed (159) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/DeepSeek-Reasonix-MIT.txt +21 -0
  3. package/README.md +109 -0
  4. package/README.zh-CN.md +91 -0
  5. package/THIRD_PARTY_NOTICES.md +14 -0
  6. package/dashboard/app.css +3233 -0
  7. package/dashboard/dist/app.js +30444 -0
  8. package/dashboard/dist/app.js.map +1 -0
  9. package/dashboard/dist/vendor-hljs.css +10 -0
  10. package/dashboard/dist/vendor-uplot.css +1 -0
  11. package/dashboard/index.html +19 -0
  12. package/data/deepseek-tokenizer.json.gz +0 -0
  13. package/dist/cli/acp-35C4ME6Y.js +711 -0
  14. package/dist/cli/acp-35C4ME6Y.js.map +1 -0
  15. package/dist/cli/chat-A6UJDPGV.js +51 -0
  16. package/dist/cli/chat-A6UJDPGV.js.map +1 -0
  17. package/dist/cli/chunk-2425HK6U.js +54 -0
  18. package/dist/cli/chunk-2425HK6U.js.map +1 -0
  19. package/dist/cli/chunk-25T6CVUP.js +172 -0
  20. package/dist/cli/chunk-25T6CVUP.js.map +1 -0
  21. package/dist/cli/chunk-2UQP6H6T.js +31 -0
  22. package/dist/cli/chunk-2UQP6H6T.js.map +1 -0
  23. package/dist/cli/chunk-3OAR6NVL.js +96 -0
  24. package/dist/cli/chunk-3OAR6NVL.js.map +1 -0
  25. package/dist/cli/chunk-3T6VBZCL.js +54 -0
  26. package/dist/cli/chunk-3T6VBZCL.js.map +1 -0
  27. package/dist/cli/chunk-4IBIPQVB.js +153 -0
  28. package/dist/cli/chunk-4IBIPQVB.js.map +1 -0
  29. package/dist/cli/chunk-4MQ3VURH.js +3106 -0
  30. package/dist/cli/chunk-4MQ3VURH.js.map +1 -0
  31. package/dist/cli/chunk-4TVNJWMA.js +11619 -0
  32. package/dist/cli/chunk-4TVNJWMA.js.map +1 -0
  33. package/dist/cli/chunk-4VR6XF4P.js +341 -0
  34. package/dist/cli/chunk-4VR6XF4P.js.map +1 -0
  35. package/dist/cli/chunk-5QCB62C4.js +25319 -0
  36. package/dist/cli/chunk-5QCB62C4.js.map +1 -0
  37. package/dist/cli/chunk-6OWJV3YW.js +390 -0
  38. package/dist/cli/chunk-6OWJV3YW.js.map +1 -0
  39. package/dist/cli/chunk-7EO27TB3.js +130 -0
  40. package/dist/cli/chunk-7EO27TB3.js.map +1 -0
  41. package/dist/cli/chunk-7L2WTRNU.js +308 -0
  42. package/dist/cli/chunk-7L2WTRNU.js.map +1 -0
  43. package/dist/cli/chunk-BHTZFEYE.js +47 -0
  44. package/dist/cli/chunk-BHTZFEYE.js.map +1 -0
  45. package/dist/cli/chunk-BSGCXZQN.js +343 -0
  46. package/dist/cli/chunk-BSGCXZQN.js.map +1 -0
  47. package/dist/cli/chunk-BSINVTTL.js +464 -0
  48. package/dist/cli/chunk-BSINVTTL.js.map +1 -0
  49. package/dist/cli/chunk-CPKCNHRR.js +323 -0
  50. package/dist/cli/chunk-CPKCNHRR.js.map +1 -0
  51. package/dist/cli/chunk-CXVWUPA3.js +96 -0
  52. package/dist/cli/chunk-CXVWUPA3.js.map +1 -0
  53. package/dist/cli/chunk-D5NFKRGO.js +160 -0
  54. package/dist/cli/chunk-D5NFKRGO.js.map +1 -0
  55. package/dist/cli/chunk-ECHSFYOY.js +109 -0
  56. package/dist/cli/chunk-ECHSFYOY.js.map +1 -0
  57. package/dist/cli/chunk-FEZK652I.js +3644 -0
  58. package/dist/cli/chunk-FEZK652I.js.map +1 -0
  59. package/dist/cli/chunk-GALC45Q2.js +696 -0
  60. package/dist/cli/chunk-GALC45Q2.js.map +1 -0
  61. package/dist/cli/chunk-IAUOP25G.js +2984 -0
  62. package/dist/cli/chunk-IAUOP25G.js.map +1 -0
  63. package/dist/cli/chunk-ILJOIQ5W.js +163 -0
  64. package/dist/cli/chunk-ILJOIQ5W.js.map +1 -0
  65. package/dist/cli/chunk-IX6XI2RG.js +225 -0
  66. package/dist/cli/chunk-IX6XI2RG.js.map +1 -0
  67. package/dist/cli/chunk-J5BYPUB5.js +62795 -0
  68. package/dist/cli/chunk-J5BYPUB5.js.map +1 -0
  69. package/dist/cli/chunk-J5XJHLWM.js +55 -0
  70. package/dist/cli/chunk-J5XJHLWM.js.map +1 -0
  71. package/dist/cli/chunk-JKGYMRX5.js +101 -0
  72. package/dist/cli/chunk-JKGYMRX5.js.map +1 -0
  73. package/dist/cli/chunk-JMBMLOBP.js +26 -0
  74. package/dist/cli/chunk-JMBMLOBP.js.map +1 -0
  75. package/dist/cli/chunk-LN3B5PMX.js +128 -0
  76. package/dist/cli/chunk-LN3B5PMX.js.map +1 -0
  77. package/dist/cli/chunk-M2UFZUX3.js +635 -0
  78. package/dist/cli/chunk-M2UFZUX3.js.map +1 -0
  79. package/dist/cli/chunk-PJS34556.js +809 -0
  80. package/dist/cli/chunk-PJS34556.js.map +1 -0
  81. package/dist/cli/chunk-QJG7OF27.js +655 -0
  82. package/dist/cli/chunk-QJG7OF27.js.map +1 -0
  83. package/dist/cli/chunk-QVC75MR3.js +232 -0
  84. package/dist/cli/chunk-QVC75MR3.js.map +1 -0
  85. package/dist/cli/chunk-S2KIUQKQ.js +378 -0
  86. package/dist/cli/chunk-S2KIUQKQ.js.map +1 -0
  87. package/dist/cli/chunk-S4XVGLRW.js +499 -0
  88. package/dist/cli/chunk-S4XVGLRW.js.map +1 -0
  89. package/dist/cli/chunk-T5TQ4NDT.js +190 -0
  90. package/dist/cli/chunk-T5TQ4NDT.js.map +1 -0
  91. package/dist/cli/chunk-TH756VLN.js +1924 -0
  92. package/dist/cli/chunk-TH756VLN.js.map +1 -0
  93. package/dist/cli/chunk-TUK7OWJA.js +51 -0
  94. package/dist/cli/chunk-TUK7OWJA.js.map +1 -0
  95. package/dist/cli/chunk-U4IJVG32.js +363 -0
  96. package/dist/cli/chunk-U4IJVG32.js.map +1 -0
  97. package/dist/cli/chunk-UI66BH6D.js +624 -0
  98. package/dist/cli/chunk-UI66BH6D.js.map +1 -0
  99. package/dist/cli/chunk-VPMBGAND.js +53 -0
  100. package/dist/cli/chunk-VPMBGAND.js.map +1 -0
  101. package/dist/cli/chunk-WLHH3OSR.js +522 -0
  102. package/dist/cli/chunk-WLHH3OSR.js.map +1 -0
  103. package/dist/cli/chunk-WRN65TRD.js +908 -0
  104. package/dist/cli/chunk-WRN65TRD.js.map +1 -0
  105. package/dist/cli/chunk-X53B3JIX.js +34320 -0
  106. package/dist/cli/chunk-X53B3JIX.js.map +1 -0
  107. package/dist/cli/chunk-XJ5SRLKK.js +50 -0
  108. package/dist/cli/chunk-XJ5SRLKK.js.map +1 -0
  109. package/dist/cli/chunk-YZSXRGFH.js +54 -0
  110. package/dist/cli/chunk-YZSXRGFH.js.map +1 -0
  111. package/dist/cli/code-4TUTAGO5.js +163 -0
  112. package/dist/cli/code-4TUTAGO5.js.map +1 -0
  113. package/dist/cli/commands-KMOZEYCF.js +356 -0
  114. package/dist/cli/commands-KMOZEYCF.js.map +1 -0
  115. package/dist/cli/commit-DTFA56VQ.js +292 -0
  116. package/dist/cli/commit-DTFA56VQ.js.map +1 -0
  117. package/dist/cli/desktop-7N3MHNBD.js +1274 -0
  118. package/dist/cli/desktop-7N3MHNBD.js.map +1 -0
  119. package/dist/cli/devtools-HW3WDT3Q.js +91 -0
  120. package/dist/cli/devtools-HW3WDT3Q.js.map +1 -0
  121. package/dist/cli/diff-E5OWTF4C.js +165 -0
  122. package/dist/cli/diff-E5OWTF4C.js.map +1 -0
  123. package/dist/cli/doctor-IEJQRJMN.js +27 -0
  124. package/dist/cli/doctor-IEJQRJMN.js.map +1 -0
  125. package/dist/cli/events-4625EGXI.js +340 -0
  126. package/dist/cli/events-4625EGXI.js.map +1 -0
  127. package/dist/cli/index.js +3536 -0
  128. package/dist/cli/index.js.map +1 -0
  129. package/dist/cli/mcp-PDI2PDLG.js +277 -0
  130. package/dist/cli/mcp-PDI2PDLG.js.map +1 -0
  131. package/dist/cli/mcp-browse-OSPXOFPZ.js +178 -0
  132. package/dist/cli/mcp-browse-OSPXOFPZ.js.map +1 -0
  133. package/dist/cli/mcp-inspect-QRFVTHMF.js +148 -0
  134. package/dist/cli/mcp-inspect-QRFVTHMF.js.map +1 -0
  135. package/dist/cli/package.json +3 -0
  136. package/dist/cli/prompt-3CDII3UO.js +16 -0
  137. package/dist/cli/prompt-3CDII3UO.js.map +1 -0
  138. package/dist/cli/prune-sessions-KZX4SXKW.js +44 -0
  139. package/dist/cli/prune-sessions-KZX4SXKW.js.map +1 -0
  140. package/dist/cli/replay-HYOSRQIV.js +291 -0
  141. package/dist/cli/replay-HYOSRQIV.js.map +1 -0
  142. package/dist/cli/run-2ZHADOUP.js +220 -0
  143. package/dist/cli/run-2ZHADOUP.js.map +1 -0
  144. package/dist/cli/server-X75PAZG5.js +3572 -0
  145. package/dist/cli/server-X75PAZG5.js.map +1 -0
  146. package/dist/cli/sessions-POOZA5CQ.js +120 -0
  147. package/dist/cli/sessions-POOZA5CQ.js.map +1 -0
  148. package/dist/cli/setup-YLPFI3OH.js +618 -0
  149. package/dist/cli/setup-YLPFI3OH.js.map +1 -0
  150. package/dist/cli/stats-NXJ3TO2D.js +16 -0
  151. package/dist/cli/stats-NXJ3TO2D.js.map +1 -0
  152. package/dist/cli/update-ZUO5MKQ6.js +15 -0
  153. package/dist/cli/update-ZUO5MKQ6.js.map +1 -0
  154. package/dist/cli/version-NXXWE3WN.js +33 -0
  155. package/dist/cli/version-NXXWE3WN.js.map +1 -0
  156. package/dist/index.d.ts +2523 -0
  157. package/dist/index.js +15408 -0
  158. package/dist/index.js.map +1 -0
  159. package/package.json +112 -0
@@ -0,0 +1,522 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
+ import {
4
+ SkillStore
5
+ } from "./chunk-M2UFZUX3.js";
6
+
7
+ // src/core/event-redaction.ts
8
+ var SECRET_KEY_RE = /(secret|token|password|passphrase|api[-_]?key|authorization|cookie|credential|passwd|pwd)/i;
9
+ function redactEventValue(value) {
10
+ return redactUnknown(value, null);
11
+ }
12
+ function redactUnknown(value, key) {
13
+ if (Array.isArray(value)) return value.map((item) => redactUnknown(item, null));
14
+ if (value && typeof value === "object") {
15
+ const out = {};
16
+ for (const [childKey, childValue] of Object.entries(value)) {
17
+ out[childKey] = redactUnknown(childValue, childKey);
18
+ }
19
+ return out;
20
+ }
21
+ if (typeof value === "string") {
22
+ if (key && SECRET_KEY_RE.test(key) || /^Bearer\s+/i.test(value)) return "[redacted]";
23
+ }
24
+ return value;
25
+ }
26
+
27
+ // src/core/eventize.ts
28
+ var Eventizer = class {
29
+ nextId = 0;
30
+ lastTurn = -1;
31
+ nextToolSeq = 0;
32
+ /** Tool calls announced via tool_call_delta but not yet dispatched. FIFO upgraded by tool_start. */
33
+ preparingCallIds = [];
34
+ /** Tool calls dispatched but not yet finished. FIFO popped by tool result. */
35
+ inflightCallIds = [];
36
+ /** Per-turn dedupe so each toolCallIndex emits exactly one tool.preparing. */
37
+ announcedToolIdx = /* @__PURE__ */ new Set();
38
+ consume(ev, ctx) {
39
+ const out = [];
40
+ if (ev.turn !== this.lastTurn) {
41
+ this.lastTurn = ev.turn;
42
+ this.announcedToolIdx.clear();
43
+ out.push(this.turnStartedEvent(ev.turn, ctx));
44
+ }
45
+ switch (ev.role) {
46
+ case "assistant_delta":
47
+ if (ev.content) out.push(this.deltaEvent(ev.turn, "content", ev.content));
48
+ if (ev.reasoningDelta) out.push(this.deltaEvent(ev.turn, "reasoning", ev.reasoningDelta));
49
+ break;
50
+ case "tool_call_delta": {
51
+ const idx = ev.toolCallIndex;
52
+ const name = ev.toolName;
53
+ if (idx === void 0 || !name) break;
54
+ const key = `${ev.turn}:${idx}`;
55
+ if (this.announcedToolIdx.has(key)) break;
56
+ this.announcedToolIdx.add(key);
57
+ const callId = `tc-${++this.nextToolSeq}`;
58
+ this.preparingCallIds.push(callId);
59
+ out.push(this.toolPreparingEvent(ev.turn, callId, name));
60
+ break;
61
+ }
62
+ case "assistant_final":
63
+ out.push(this.finalEvent(ev));
64
+ break;
65
+ case "tool_start": {
66
+ const callId = this.preparingCallIds.shift() ?? `tc-${++this.nextToolSeq}`;
67
+ this.inflightCallIds.push(callId);
68
+ out.push(this.toolIntentEvent(ev.turn, callId, ev.toolName ?? "", ev.toolArgs ?? ""));
69
+ out.push(this.toolDispatchedEvent(ev.turn, callId));
70
+ break;
71
+ }
72
+ case "tool": {
73
+ const callId = this.inflightCallIds.shift() ?? `tc-orphan-${++this.nextToolSeq}`;
74
+ const ok = !looksLikeToolError(ev.content, ev.toolName);
75
+ out.push(this.toolResultEvent(ev.turn, callId, ok, ev.content, 0));
76
+ break;
77
+ }
78
+ case "warning":
79
+ out.push(this.classifyWarning(ev));
80
+ break;
81
+ case "error":
82
+ out.push(this.errorEvent(ev.turn, ev.error ?? ev.content, false));
83
+ break;
84
+ case "status":
85
+ out.push(this.statusEvent(ev.turn, ev.content));
86
+ break;
87
+ // `done` / `branch_*` intentionally drop — no kernel-level event.
88
+ default:
89
+ break;
90
+ }
91
+ return out;
92
+ }
93
+ emitUserMessage(turn, text) {
94
+ return {
95
+ id: ++this.nextId,
96
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
97
+ turn,
98
+ type: "user.message",
99
+ text
100
+ };
101
+ }
102
+ emitSlashInvoked(turn, name, args) {
103
+ return {
104
+ id: ++this.nextId,
105
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
106
+ turn,
107
+ type: "slash.invoked",
108
+ name,
109
+ args
110
+ };
111
+ }
112
+ emitSessionOpened(turn, name, resumedFromTurn) {
113
+ return {
114
+ id: ++this.nextId,
115
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
116
+ turn,
117
+ type: "session.opened",
118
+ name,
119
+ resumedFromTurn
120
+ };
121
+ }
122
+ emitSessionCompacted(turn, before, after, reason, replacementMessages) {
123
+ return {
124
+ id: ++this.nextId,
125
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
126
+ turn,
127
+ type: "session.compacted",
128
+ beforeMessages: before,
129
+ afterMessages: after,
130
+ reason,
131
+ replacementMessages
132
+ };
133
+ }
134
+ emitToolCall(turn, name, args) {
135
+ return {
136
+ id: ++this.nextId,
137
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
138
+ turn,
139
+ type: "tool.call",
140
+ name,
141
+ args: redactEventValue(args)
142
+ };
143
+ }
144
+ emitToolConfirmAllow(turn, kind, payload) {
145
+ return {
146
+ id: ++this.nextId,
147
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
148
+ turn,
149
+ type: "tool.confirm.allow",
150
+ kind,
151
+ payload: redactEventValue(payload)
152
+ };
153
+ }
154
+ emitToolConfirmDeny(turn, kind, payload, denyContext) {
155
+ return {
156
+ id: ++this.nextId,
157
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
158
+ turn,
159
+ type: "tool.confirm.deny",
160
+ kind,
161
+ payload: redactEventValue(payload),
162
+ denyContext
163
+ };
164
+ }
165
+ emitToolConfirmAlwaysAllow(turn, kind, payload, prefix) {
166
+ return {
167
+ id: ++this.nextId,
168
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
169
+ turn,
170
+ type: "tool.confirm.always_allow",
171
+ kind,
172
+ payload: redactEventValue(payload),
173
+ prefix
174
+ };
175
+ }
176
+ turnStartedEvent(turn, ctx) {
177
+ return {
178
+ id: ++this.nextId,
179
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
180
+ turn,
181
+ type: "model.turn.started",
182
+ model: ctx.model,
183
+ reasoningEffort: ctx.reasoningEffort,
184
+ prefixHash: ctx.prefixHash
185
+ };
186
+ }
187
+ deltaEvent(turn, channel, text) {
188
+ return {
189
+ id: ++this.nextId,
190
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
191
+ turn,
192
+ type: "model.delta",
193
+ channel,
194
+ text
195
+ };
196
+ }
197
+ finalEvent(ev) {
198
+ const usage = ev.stats ? {
199
+ prompt_tokens: ev.stats.usage.promptTokens,
200
+ completion_tokens: ev.stats.usage.completionTokens,
201
+ total_tokens: ev.stats.usage.totalTokens,
202
+ prompt_cache_hit_tokens: ev.stats.usage.promptCacheHitTokens,
203
+ prompt_cache_miss_tokens: ev.stats.usage.promptCacheMissTokens
204
+ } : {};
205
+ const costUsd = ev.stats?.cost ?? 0;
206
+ const out = {
207
+ id: ++this.nextId,
208
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
209
+ turn: ev.turn,
210
+ type: "model.final",
211
+ content: ev.content,
212
+ // toolCalls land later via tool_start → tool.intent — not in this event.
213
+ toolCalls: [],
214
+ usage,
215
+ costUsd
216
+ };
217
+ if (ev.forcedSummary) out.forcedSummary = true;
218
+ return out;
219
+ }
220
+ toolPreparingEvent(turn, callId, name) {
221
+ return {
222
+ id: ++this.nextId,
223
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
224
+ turn,
225
+ type: "tool.preparing",
226
+ callId,
227
+ name
228
+ };
229
+ }
230
+ toolIntentEvent(turn, callId, name, args) {
231
+ return {
232
+ id: ++this.nextId,
233
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
234
+ turn,
235
+ type: "tool.intent",
236
+ callId,
237
+ name,
238
+ args
239
+ };
240
+ }
241
+ toolDispatchedEvent(turn, callId) {
242
+ return {
243
+ id: ++this.nextId,
244
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
245
+ turn,
246
+ type: "tool.dispatched",
247
+ callId
248
+ };
249
+ }
250
+ toolResultEvent(turn, callId, ok, output, durationMs) {
251
+ return {
252
+ id: ++this.nextId,
253
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
254
+ turn,
255
+ type: "tool.result",
256
+ callId,
257
+ ok,
258
+ output,
259
+ durationMs
260
+ };
261
+ }
262
+ statusEvent(turn, text) {
263
+ return {
264
+ id: ++this.nextId,
265
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
266
+ turn,
267
+ type: "status",
268
+ text
269
+ };
270
+ }
271
+ errorEvent(turn, message, recoverable) {
272
+ return {
273
+ id: ++this.nextId,
274
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
275
+ turn,
276
+ type: "error",
277
+ message,
278
+ recoverable
279
+ };
280
+ }
281
+ /** Pattern-match warning text since LoopEvent doesn't carry a typed kind. */
282
+ classifyWarning(ev) {
283
+ const c = ev.content;
284
+ if (/\bauto-escalating to\b|\barmed\b.*pro|NEEDS_PRO/.test(c)) {
285
+ return {
286
+ id: ++this.nextId,
287
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
288
+ turn: ev.turn,
289
+ type: "policy.escalated",
290
+ fromModel: "",
291
+ toModel: "",
292
+ reason: c.includes("armed") ? "user-request" : "self-report"
293
+ };
294
+ }
295
+ if (/budget\b.*\$|\$\d.*\/\s*\$\d/.test(c)) {
296
+ const blocked = /blocked|exceeded|refus/i.test(c);
297
+ return {
298
+ id: ++this.nextId,
299
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
300
+ turn: ev.turn,
301
+ type: blocked ? "policy.budget.blocked" : "policy.budget.warning",
302
+ spentUsd: 0,
303
+ capUsd: 0
304
+ };
305
+ }
306
+ return this.errorEvent(ev.turn, c, true);
307
+ }
308
+ };
309
+ function looksLikeToolError(content, _toolName) {
310
+ if (!content) return false;
311
+ if (content.startsWith("ERROR:")) return true;
312
+ if (content.startsWith("[hook block]")) return true;
313
+ if (/^\{"error"\s*:/.test(content)) return true;
314
+ if (/\bConfirmationError:|\bNeedsConfirmationError\b/.test(content)) return true;
315
+ return false;
316
+ }
317
+
318
+ // src/core/pause-policy.ts
319
+ function shouldAutoResolveCheckpoint(editMode) {
320
+ return editMode === "auto" || editMode === "yolo";
321
+ }
322
+ function autoResolveVerdict(req, editMode) {
323
+ if (req.kind === "plan_checkpoint" && shouldAutoResolveCheckpoint(editMode)) {
324
+ return { type: "continue" };
325
+ }
326
+ if (req.kind === "path_access" && editMode === "yolo") {
327
+ return { type: "run_once" };
328
+ }
329
+ return null;
330
+ }
331
+
332
+ // src/tools/skills.ts
333
+ function registerSkillTools(registry, opts = {}) {
334
+ const store = new SkillStore({
335
+ homeDir: opts.homeDir,
336
+ projectRoot: opts.projectRoot,
337
+ customSkillPaths: opts.customSkillPaths,
338
+ disableBuiltins: opts.disableBuiltins
339
+ });
340
+ const subagentRunner = opts.subagentRunner;
341
+ const onSkillInstalled = opts.onSkillInstalled;
342
+ const hasProjectScope = store.hasProjectScope();
343
+ registry.register({
344
+ name: "run_skill",
345
+ description: "Invoke a playbook from the Skills index pinned in the system prompt. Each entry is a self-contained instruction block. Pass `name` as the BARE skill identifier (e.g. 'explore'), NOT the `[\u{1F9EC} subagent]` tag that appears after it in the index. Entries tagged `[\u{1F9EC} subagent]` spawn an isolated subagent \u2014 only the final distilled answer comes back, the model's tool calls + reasoning during the run never enter your context. Plain skills are inlined: the body becomes a tool result you read and follow. For subagent skills, supply 'arguments' describing the concrete task \u2014 they'll be the only context the subagent has.",
346
+ readOnly: true,
347
+ parallelSafe: true,
348
+ parameters: {
349
+ type: "object",
350
+ properties: {
351
+ name: {
352
+ type: "string",
353
+ description: "Skill identifier as it appears in the pinned Skills index (e.g. 'explore', 'review', 'security-review'). Case-sensitive."
354
+ },
355
+ arguments: {
356
+ type: "string",
357
+ description: "Free-form arguments the skill should act on. For inline skills: appended to the body as an 'Arguments:' line; the skill's own instructions decide how to consume them. For `[\u{1F9EC} subagent]` skills: REQUIRED \u2014 becomes the entire task description the subagent receives, since it has no other context."
358
+ }
359
+ },
360
+ required: ["name"]
361
+ },
362
+ fn: async (args, ctx) => {
363
+ const raw = typeof args.name === "string" ? args.name.trim() : "";
364
+ if (!raw) {
365
+ return JSON.stringify({ error: "run_skill requires a 'name' argument" });
366
+ }
367
+ const stripped = raw.replace(/\[[^\]]*\]/g, " ").trim();
368
+ const tokens = stripped.split(/\s+/).filter(Boolean);
369
+ const name = tokens.find((t) => /^[a-zA-Z0-9]/.test(t)) ?? "";
370
+ if (!name) {
371
+ return JSON.stringify({
372
+ error: "run_skill requires a 'name' argument",
373
+ hint: `'${raw}' is just a marker/tag, not a skill name`
374
+ });
375
+ }
376
+ const skill = store.read(name);
377
+ if (!skill) {
378
+ const available = store.list().map((s) => s.name).join(", ");
379
+ return JSON.stringify({
380
+ error: `unknown skill: ${JSON.stringify(name)}`,
381
+ available: available || "(none \u2014 user has not defined any skills)"
382
+ });
383
+ }
384
+ const rawArgs = typeof args.arguments === "string" ? args.arguments.trim() : "";
385
+ if (skill.runAs === "subagent") {
386
+ if (!subagentRunner) {
387
+ return JSON.stringify({
388
+ error: `run_skill: skill ${JSON.stringify(name)} is marked runAs=subagent but no subagent runner is configured for this session. Skill authors who need isolation should run inside carboncode code (or a library setup that passes subagentRunner to registerSkillTools).`
389
+ });
390
+ }
391
+ if (!rawArgs) {
392
+ return JSON.stringify({
393
+ error: `run_skill: skill ${JSON.stringify(name)} is a subagent and requires 'arguments' \u2014 the subagent has no other context, so describe the concrete task in the arguments field.`
394
+ });
395
+ }
396
+ return subagentRunner(skill, rawArgs, ctx?.signal);
397
+ }
398
+ const header = [
399
+ `# Skill: ${skill.name}`,
400
+ skill.description ? `> ${skill.description}` : "",
401
+ `(scope: ${skill.scope} \xB7 ${skill.path})`
402
+ ].filter(Boolean).join("\n");
403
+ const argsBlock = rawArgs ? `
404
+
405
+ Arguments: ${rawArgs}` : "";
406
+ const inner = `${header}
407
+
408
+ ${skill.body}${argsBlock}`;
409
+ return `<skill-pin name=${JSON.stringify(skill.name)}>
410
+ ${inner}
411
+ </skill-pin>`;
412
+ }
413
+ });
414
+ const installScopeDesc = hasProjectScope ? "'project' (default) writes to <repo>/.carboncode/skills/, scoped to this workspace only; 'global' writes to ~/.carboncode/skills/, available in every project." : "'global' (only option here \u2014 no project workspace) writes to ~/.carboncode/skills/.";
415
+ registry.register({
416
+ name: "install_skill",
417
+ description: "Author and save a new skill \u2014 a reusable playbook future turns can invoke via `run_skill`. Use when the same multi-step instruction would benefit from being callable by name instead of re-pasted. The skill is written to disk and runnable immediately (call `run_skill` with the same name in this very turn); it appears in the pinned Skills index only on the next `/new` or launch. WARNING: skill bodies become prompts for future agent turns \u2014 treat what you write as instructions you are giving your future self.",
418
+ parameters: {
419
+ type: "object",
420
+ properties: {
421
+ name: {
422
+ type: "string",
423
+ description: "Skill identifier \u2014 letters/digits/_/-/., 1-64 chars, starts alnum. Becomes the filename and what callers pass to `run_skill`."
424
+ },
425
+ description: {
426
+ type: "string",
427
+ description: "One-line summary shown in the pinned Skills index. Keep under ~120 chars; this is what future agents read to decide whether to invoke the skill."
428
+ },
429
+ body: {
430
+ type: "string",
431
+ description: "Full skill playbook in markdown \u2014 the instructions a future turn (or subagent) follows when this skill runs. For inline skills, write 'how to do X'. For subagent skills, write the subagent's persona + operating rules; remember the subagent has NO other context besides the `arguments` passed at runtime."
432
+ },
433
+ scope: {
434
+ type: "string",
435
+ enum: ["project", "global"],
436
+ description: installScopeDesc
437
+ },
438
+ runAs: {
439
+ type: "string",
440
+ enum: ["inline", "subagent"],
441
+ description: "'inline' (default) \u2014 body becomes a tool-result the parent agent reads and acts on (cheap, shares parent context). 'subagent' \u2014 spawns an isolated child loop; only the final answer returns to the parent (use when the work would flood context, e.g. exploration / research)."
442
+ },
443
+ model: {
444
+ type: "string",
445
+ description: "Optional model override for subagent skills (e.g. 'deepseek-chat'). Ignored for runAs=inline. Only `deepseek-*` ids are honored."
446
+ },
447
+ allowedTools: {
448
+ type: "array",
449
+ items: { type: "string" },
450
+ description: "Optional tool-name allowlist for subagent skills (e.g. ['read_file','search_content']). When set, the spawned subagent's registry is scoped to these literal names. Ignored for runAs=inline."
451
+ }
452
+ },
453
+ required: ["name", "description", "body"]
454
+ },
455
+ fn: async (args) => {
456
+ const name = typeof args.name === "string" ? args.name.trim() : "";
457
+ const description = typeof args.description === "string" ? args.description.replace(/[\r\n]+/g, " ").trim() : "";
458
+ const body = typeof args.body === "string" ? args.body : "";
459
+ if (!name) return JSON.stringify({ error: "install_skill requires a non-empty 'name'" });
460
+ if (!description) {
461
+ return JSON.stringify({
462
+ error: "install_skill requires a non-empty 'description' \u2014 it is what appears in the Skills index and how future agents decide whether to invoke the skill"
463
+ });
464
+ }
465
+ if (!body.trim()) {
466
+ return JSON.stringify({
467
+ error: "install_skill requires a non-empty 'body' \u2014 the playbook the skill executes when invoked"
468
+ });
469
+ }
470
+ const scopeRaw = typeof args.scope === "string" ? args.scope.trim() : "";
471
+ let scope;
472
+ if (scopeRaw === "global") scope = "global";
473
+ else if (scopeRaw === "project") scope = "project";
474
+ else scope = hasProjectScope ? "project" : "global";
475
+ if (scope === "project" && !hasProjectScope) {
476
+ return JSON.stringify({
477
+ error: "install_skill: scope='project' requires a workspace \u2014 run from `carboncode code`, or use scope='global'"
478
+ });
479
+ }
480
+ const runAsRaw = typeof args.runAs === "string" ? args.runAs.trim() : "";
481
+ const runAs = runAsRaw === "subagent" ? "subagent" : "inline";
482
+ const fmLines = ["---", `name: ${name}`, `description: ${description}`];
483
+ if (runAs === "subagent") {
484
+ fmLines.push("runAs: subagent");
485
+ const model = typeof args.model === "string" ? args.model.trim() : "";
486
+ if (model) fmLines.push(`model: ${model}`);
487
+ if (Array.isArray(args.allowedTools)) {
488
+ const tools = args.allowedTools.filter((t) => typeof t === "string").map((t) => t.trim()).filter(Boolean);
489
+ if (tools.length > 0) fmLines.push(`allowed-tools: ${tools.join(", ")}`);
490
+ }
491
+ }
492
+ fmLines.push("---", "");
493
+ const content = `${fmLines.join("\n")}${body.replace(/\s+$/, "")}
494
+ `;
495
+ const result = store.createWithContent(name, scope, content);
496
+ if ("error" in result) {
497
+ return JSON.stringify({ error: result.error });
498
+ }
499
+ try {
500
+ onSkillInstalled?.({ name, path: result.path, scope });
501
+ } catch {
502
+ }
503
+ return JSON.stringify({
504
+ ok: true,
505
+ name,
506
+ scope,
507
+ path: result.path,
508
+ runAs,
509
+ note: "Skill is callable right now via run_skill({ name }). It will appear in the pinned Skills index after the next /new or launch."
510
+ });
511
+ }
512
+ });
513
+ return registry;
514
+ }
515
+
516
+ export {
517
+ registerSkillTools,
518
+ Eventizer,
519
+ shouldAutoResolveCheckpoint,
520
+ autoResolveVerdict
521
+ };
522
+ //# sourceMappingURL=chunk-WLHH3OSR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/event-redaction.ts","../../src/core/eventize.ts","../../src/core/pause-policy.ts","../../src/tools/skills.ts"],"sourcesContent":["const SECRET_KEY_RE =\n /(secret|token|password|passphrase|api[-_]?key|authorization|cookie|credential|passwd|pwd)/i;\n\nexport function redactEventValue<T>(value: T): T {\n return redactUnknown(value, null) as T;\n}\n\nfunction redactUnknown(value: unknown, key: string | null): unknown {\n if (Array.isArray(value)) return value.map((item) => redactUnknown(item, null));\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n out[childKey] = redactUnknown(childValue, childKey);\n }\n return out;\n }\n if (typeof value === \"string\") {\n if ((key && SECRET_KEY_RE.test(key)) || /^Bearer\\s+/i.test(value)) return \"[redacted]\";\n }\n return value;\n}\n","import type { LoopEvent } from \"../loop.js\";\nimport type { ChatMessage, RawUsage, ToolCall } from \"../types.js\";\nimport { redactEventValue } from \"./event-redaction.js\";\nimport type {\n Event,\n ErrorEvent as KernelErrorEvent,\n ModelDeltaEvent,\n ModelFinalEvent,\n ModelTurnStartedEvent,\n SessionCompactedEvent,\n SessionOpenedEvent,\n SlashInvokedEvent,\n StatusEvent,\n ToolCallEvent,\n ToolConfirmAllowEvent,\n ToolConfirmAlwaysAllowEvent,\n ToolConfirmDenyEvent,\n ToolDispatchedEvent,\n ToolIntentEvent,\n ToolPreparingEvent,\n ToolResultEvent,\n UserMessageEvent,\n} from \"./events.js\";\n\nexport interface EventizeContext {\n model: string;\n prefixHash: string;\n reasoningEffort: \"high\" | \"max\";\n}\n\nexport class Eventizer {\n private nextId = 0;\n private lastTurn = -1;\n private nextToolSeq = 0;\n /** Tool calls announced via tool_call_delta but not yet dispatched. FIFO upgraded by tool_start. */\n private preparingCallIds: string[] = [];\n /** Tool calls dispatched but not yet finished. FIFO popped by tool result. */\n private inflightCallIds: string[] = [];\n /** Per-turn dedupe so each toolCallIndex emits exactly one tool.preparing. */\n private announcedToolIdx = new Set<string>();\n\n consume(ev: LoopEvent, ctx: EventizeContext): Event[] {\n const out: Event[] = [];\n if (ev.turn !== this.lastTurn) {\n this.lastTurn = ev.turn;\n this.announcedToolIdx.clear();\n out.push(this.turnStartedEvent(ev.turn, ctx));\n }\n switch (ev.role) {\n case \"assistant_delta\":\n if (ev.content) out.push(this.deltaEvent(ev.turn, \"content\", ev.content));\n if (ev.reasoningDelta) out.push(this.deltaEvent(ev.turn, \"reasoning\", ev.reasoningDelta));\n break;\n case \"tool_call_delta\": {\n const idx = ev.toolCallIndex;\n const name = ev.toolName;\n if (idx === undefined || !name) break;\n const key = `${ev.turn}:${idx}`;\n if (this.announcedToolIdx.has(key)) break;\n this.announcedToolIdx.add(key);\n const callId = `tc-${++this.nextToolSeq}`;\n this.preparingCallIds.push(callId);\n out.push(this.toolPreparingEvent(ev.turn, callId, name));\n break;\n }\n case \"assistant_final\":\n out.push(this.finalEvent(ev));\n break;\n case \"tool_start\": {\n const callId = this.preparingCallIds.shift() ?? `tc-${++this.nextToolSeq}`;\n this.inflightCallIds.push(callId);\n out.push(this.toolIntentEvent(ev.turn, callId, ev.toolName ?? \"\", ev.toolArgs ?? \"\"));\n out.push(this.toolDispatchedEvent(ev.turn, callId));\n break;\n }\n case \"tool\": {\n const callId = this.inflightCallIds.shift() ?? `tc-orphan-${++this.nextToolSeq}`;\n const ok = !looksLikeToolError(ev.content, ev.toolName);\n out.push(this.toolResultEvent(ev.turn, callId, ok, ev.content, 0));\n break;\n }\n case \"warning\":\n out.push(this.classifyWarning(ev));\n break;\n case \"error\":\n out.push(this.errorEvent(ev.turn, ev.error ?? ev.content, false));\n break;\n case \"status\":\n out.push(this.statusEvent(ev.turn, ev.content));\n break;\n // `done` / `branch_*` intentionally drop — no kernel-level event.\n default:\n break;\n }\n return out;\n }\n\n emitUserMessage(turn: number, text: string): UserMessageEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"user.message\",\n text,\n };\n }\n\n emitSlashInvoked(turn: number, name: string, args: string): SlashInvokedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"slash.invoked\",\n name,\n args,\n };\n }\n\n emitSessionOpened(turn: number, name: string, resumedFromTurn: number): SessionOpenedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"session.opened\",\n name,\n resumedFromTurn,\n };\n }\n\n emitSessionCompacted(\n turn: number,\n before: number,\n after: number,\n reason: \"user\" | \"auto-context-pressure\",\n replacementMessages: ReadonlyArray<ChatMessage>,\n ): SessionCompactedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"session.compacted\",\n beforeMessages: before,\n afterMessages: after,\n reason,\n replacementMessages,\n };\n }\n\n emitToolCall(turn: number, name: string, args: Record<string, unknown>): ToolCallEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.call\",\n name,\n args: redactEventValue(args),\n };\n }\n\n emitToolConfirmAllow(\n turn: number,\n kind: \"run_command\" | \"run_background\",\n payload: { command: string },\n ): ToolConfirmAllowEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.confirm.allow\",\n kind,\n payload: redactEventValue(payload),\n };\n }\n\n emitToolConfirmDeny(\n turn: number,\n kind: \"run_command\" | \"run_background\",\n payload: { command: string },\n denyContext?: string,\n ): ToolConfirmDenyEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.confirm.deny\",\n kind,\n payload: redactEventValue(payload),\n denyContext,\n };\n }\n\n emitToolConfirmAlwaysAllow(\n turn: number,\n kind: \"run_command\" | \"run_background\",\n payload: { command: string },\n prefix: string,\n ): ToolConfirmAlwaysAllowEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.confirm.always_allow\",\n kind,\n payload: redactEventValue(payload),\n prefix,\n };\n }\n\n private turnStartedEvent(turn: number, ctx: EventizeContext): ModelTurnStartedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"model.turn.started\",\n model: ctx.model,\n reasoningEffort: ctx.reasoningEffort,\n prefixHash: ctx.prefixHash,\n };\n }\n\n private deltaEvent(\n turn: number,\n channel: \"content\" | \"reasoning\" | \"tool_args\",\n text: string,\n ): ModelDeltaEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"model.delta\",\n channel,\n text,\n };\n }\n\n private finalEvent(ev: LoopEvent): ModelFinalEvent {\n const usage: RawUsage = ev.stats\n ? {\n prompt_tokens: ev.stats.usage.promptTokens,\n completion_tokens: ev.stats.usage.completionTokens,\n total_tokens: ev.stats.usage.totalTokens,\n prompt_cache_hit_tokens: ev.stats.usage.promptCacheHitTokens,\n prompt_cache_miss_tokens: ev.stats.usage.promptCacheMissTokens,\n }\n : {};\n const costUsd = ev.stats?.cost ?? 0;\n const out: ModelFinalEvent = {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn: ev.turn,\n type: \"model.final\",\n content: ev.content,\n // toolCalls land later via tool_start → tool.intent — not in this event.\n toolCalls: [] as ReadonlyArray<ToolCall>,\n usage,\n costUsd,\n };\n if (ev.forcedSummary) out.forcedSummary = true;\n return out;\n }\n\n private toolPreparingEvent(turn: number, callId: string, name: string): ToolPreparingEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.preparing\",\n callId,\n name,\n };\n }\n\n private toolIntentEvent(\n turn: number,\n callId: string,\n name: string,\n args: string,\n ): ToolIntentEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.intent\",\n callId,\n name,\n args,\n };\n }\n\n private toolDispatchedEvent(turn: number, callId: string): ToolDispatchedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.dispatched\",\n callId,\n };\n }\n\n private toolResultEvent(\n turn: number,\n callId: string,\n ok: boolean,\n output: string,\n durationMs: number,\n ): ToolResultEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.result\",\n callId,\n ok,\n output,\n durationMs,\n };\n }\n\n private statusEvent(turn: number, text: string): StatusEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"status\",\n text,\n };\n }\n\n private errorEvent(turn: number, message: string, recoverable: boolean): KernelErrorEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"error\",\n message,\n recoverable,\n };\n }\n\n /** Pattern-match warning text since LoopEvent doesn't carry a typed kind. */\n private classifyWarning(ev: LoopEvent): Event {\n const c = ev.content;\n if (/\\bauto-escalating to\\b|\\barmed\\b.*pro|NEEDS_PRO/.test(c)) {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn: ev.turn,\n type: \"policy.escalated\",\n fromModel: \"\",\n toModel: \"\",\n reason: c.includes(\"armed\") ? \"user-request\" : \"self-report\",\n };\n }\n if (/budget\\b.*\\$|\\$\\d.*\\/\\s*\\$\\d/.test(c)) {\n const blocked = /blocked|exceeded|refus/i.test(c);\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn: ev.turn,\n type: blocked ? \"policy.budget.blocked\" : \"policy.budget.warning\",\n spentUsd: 0,\n capUsd: 0,\n };\n }\n return this.errorEvent(ev.turn, c, true);\n }\n}\n\nfunction looksLikeToolError(content: string, _toolName: string | undefined): boolean {\n if (!content) return false;\n if (content.startsWith(\"ERROR:\")) return true;\n if (content.startsWith(\"[hook block]\")) return true;\n if (/^\\{\"error\"\\s*:/.test(content)) return true;\n if (/\\bConfirmationError:|\\bNeedsConfirmationError\\b/.test(content)) return true;\n return false;\n}\n","/** Shared editMode → auto-resolve rules so CLI TUI + Tauri desktop don't drift. */\n\nimport type { EditMode } from \"../config.js\";\nimport type { PauseRequest } from \"./pause-gate.js\";\n\n/** Mirrors shell.ts's allowAll bypass: only review still pauses on checkpoints. */\nexport function shouldAutoResolveCheckpoint(editMode: EditMode): boolean {\n return editMode === \"auto\" || editMode === \"yolo\";\n}\n\n/** null = surface to user; non-null = resolve gate immediately with this verdict. */\nexport function autoResolveVerdict(req: PauseRequest, editMode: EditMode): unknown | null {\n if (req.kind === \"plan_checkpoint\" && shouldAutoResolveCheckpoint(editMode)) {\n return { type: \"continue\" };\n }\n // yolo mirrors shell.ts's allowAll bypass — outside-sandbox reads/writes pass\n // through too. Stays \"run_once\" rather than \"always_allow\" so the YOLO session\n // doesn't pollute the on-disk allowlist with every transient path it touched.\n if (req.kind === \"path_access\" && editMode === \"yolo\") {\n return { type: \"run_once\" };\n }\n return null;\n}\n","/** runAs: inline appends the body to the parent log; subagent spawns an isolated child loop and only returns the final answer. */\n\nimport { type Skill, SkillStore } from \"../skills.js\";\nimport type { ToolRegistry } from \"../tools.js\";\n\n/** Returns serialized tool-result string — dispatch path is pure pass-through. */\nexport type SubagentRunner = (skill: Skill, task: string, signal?: AbortSignal) => Promise<string>;\n\n/** Fired after a successful `install_skill` write — host wires this to push a fresh `$skills` event so the desktop sidebar updates without a tab reload. */\nexport type SkillInstalledHook = (info: {\n name: string;\n path: string;\n scope: \"project\" | \"global\";\n}) => void;\n\nexport interface SkillToolsOptions {\n /** Override `$HOME` — tests set this to a tmpdir. */\n homeDir?: string;\n projectRoot?: string;\n customSkillPaths?: readonly string[];\n /** When omitted, subagent skills error rather than silently falling back to inline (loses isolation). */\n subagentRunner?: SubagentRunner;\n /** Hide built-in skills (test-only knob; production callers leave off). */\n disableBuiltins?: boolean;\n /** Called synchronously after `install_skill` successfully writes a new skill file. */\n onSkillInstalled?: SkillInstalledHook;\n}\n\nexport function registerSkillTools(\n registry: ToolRegistry,\n opts: SkillToolsOptions = {},\n): ToolRegistry {\n const store = new SkillStore({\n homeDir: opts.homeDir,\n projectRoot: opts.projectRoot,\n customSkillPaths: opts.customSkillPaths,\n disableBuiltins: opts.disableBuiltins,\n });\n const subagentRunner = opts.subagentRunner;\n const onSkillInstalled = opts.onSkillInstalled;\n const hasProjectScope = store.hasProjectScope();\n\n registry.register({\n name: \"run_skill\",\n description:\n \"Invoke a playbook from the Skills index pinned in the system prompt. Each entry is a self-contained instruction block. Pass `name` as the BARE skill identifier (e.g. 'explore'), NOT the `[🧬 subagent]` tag that appears after it in the index. Entries tagged `[🧬 subagent]` spawn an isolated subagent — only the final distilled answer comes back, the model's tool calls + reasoning during the run never enter your context. Plain skills are inlined: the body becomes a tool result you read and follow. For subagent skills, supply 'arguments' describing the concrete task — they'll be the only context the subagent has.\",\n readOnly: true,\n parallelSafe: true,\n parameters: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description:\n \"Skill identifier as it appears in the pinned Skills index (e.g. 'explore', 'review', 'security-review'). Case-sensitive.\",\n },\n arguments: {\n type: \"string\",\n description:\n \"Free-form arguments the skill should act on. For inline skills: appended to the body as an 'Arguments:' line; the skill's own instructions decide how to consume them. For `[🧬 subagent]` skills: REQUIRED — becomes the entire task description the subagent receives, since it has no other context.\",\n },\n },\n required: [\"name\"],\n },\n fn: async (args: { name?: unknown; arguments?: unknown }, ctx) => {\n const raw = typeof args.name === \"string\" ? args.name.trim() : \"\";\n if (!raw) {\n return JSON.stringify({ error: \"run_skill requires a 'name' argument\" });\n }\n // Defensive: The Skills index writes entries like\n // `explore [🧬 subagent]`, and models sometimes copy the\n // decoration verbatim into the `name` argument instead of just\n // the identifier. Rather than reject those calls:\n // 1. Drop any `[...]` bracketed tag (possibly containing\n // emoji + \"subagent\" label).\n // 2. Find the first whitespace-delimited token whose first\n // char is alphanumeric — that's the skill identifier,\n // whether the tag came before or after the name.\n const stripped = raw.replace(/\\[[^\\]]*\\]/g, \" \").trim();\n const tokens = stripped.split(/\\s+/).filter(Boolean);\n const name = tokens.find((t) => /^[a-zA-Z0-9]/.test(t)) ?? \"\";\n if (!name) {\n return JSON.stringify({\n error: \"run_skill requires a 'name' argument\",\n hint: `'${raw}' is just a marker/tag, not a skill name`,\n });\n }\n const skill = store.read(name);\n if (!skill) {\n const available = store\n .list()\n .map((s) => s.name)\n .join(\", \");\n return JSON.stringify({\n error: `unknown skill: ${JSON.stringify(name)}`,\n available: available || \"(none — user has not defined any skills)\",\n });\n }\n const rawArgs = typeof args.arguments === \"string\" ? args.arguments.trim() : \"\";\n\n if (skill.runAs === \"subagent\") {\n if (!subagentRunner) {\n return JSON.stringify({\n error: `run_skill: skill ${JSON.stringify(name)} is marked runAs=subagent but no subagent runner is configured for this session. Skill authors who need isolation should run inside carboncode code (or a library setup that passes subagentRunner to registerSkillTools).`,\n });\n }\n if (!rawArgs) {\n return JSON.stringify({\n error: `run_skill: skill ${JSON.stringify(name)} is a subagent and requires 'arguments' — the subagent has no other context, so describe the concrete task in the arguments field.`,\n });\n }\n return subagentRunner(skill, rawArgs, ctx?.signal);\n }\n\n const header = [\n `# Skill: ${skill.name}`,\n skill.description ? `> ${skill.description}` : \"\",\n `(scope: ${skill.scope} · ${skill.path})`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n const argsBlock = rawArgs ? `\\n\\nArguments: ${rawArgs}` : \"\";\n const inner = `${header}\\n\\n${skill.body}${argsBlock}`;\n // Sentinel-wrapped so ContextManager.fold preserves the body verbatim instead of paraphrasing it.\n return `<skill-pin name=${JSON.stringify(skill.name)}>\\n${inner}\\n</skill-pin>`;\n },\n });\n\n const installScopeDesc = hasProjectScope\n ? \"'project' (default) writes to <repo>/.carboncode/skills/, scoped to this workspace only; 'global' writes to ~/.carboncode/skills/, available in every project.\"\n : \"'global' (only option here — no project workspace) writes to ~/.carboncode/skills/.\";\n\n registry.register({\n name: \"install_skill\",\n description:\n \"Author and save a new skill — a reusable playbook future turns can invoke via `run_skill`. Use when the same multi-step instruction would benefit from being callable by name instead of re-pasted. The skill is written to disk and runnable immediately (call `run_skill` with the same name in this very turn); it appears in the pinned Skills index only on the next `/new` or launch. WARNING: skill bodies become prompts for future agent turns — treat what you write as instructions you are giving your future self.\",\n parameters: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description:\n \"Skill identifier — letters/digits/_/-/., 1-64 chars, starts alnum. Becomes the filename and what callers pass to `run_skill`.\",\n },\n description: {\n type: \"string\",\n description:\n \"One-line summary shown in the pinned Skills index. Keep under ~120 chars; this is what future agents read to decide whether to invoke the skill.\",\n },\n body: {\n type: \"string\",\n description:\n \"Full skill playbook in markdown — the instructions a future turn (or subagent) follows when this skill runs. For inline skills, write 'how to do X'. For subagent skills, write the subagent's persona + operating rules; remember the subagent has NO other context besides the `arguments` passed at runtime.\",\n },\n scope: {\n type: \"string\",\n enum: [\"project\", \"global\"],\n description: installScopeDesc,\n },\n runAs: {\n type: \"string\",\n enum: [\"inline\", \"subagent\"],\n description:\n \"'inline' (default) — body becomes a tool-result the parent agent reads and acts on (cheap, shares parent context). 'subagent' — spawns an isolated child loop; only the final answer returns to the parent (use when the work would flood context, e.g. exploration / research).\",\n },\n model: {\n type: \"string\",\n description:\n \"Optional model override for subagent skills (e.g. 'deepseek-chat'). Ignored for runAs=inline. Only `deepseek-*` ids are honored.\",\n },\n allowedTools: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Optional tool-name allowlist for subagent skills (e.g. ['read_file','search_content']). When set, the spawned subagent's registry is scoped to these literal names. Ignored for runAs=inline.\",\n },\n },\n required: [\"name\", \"description\", \"body\"],\n },\n fn: async (args: {\n name?: unknown;\n description?: unknown;\n body?: unknown;\n scope?: unknown;\n runAs?: unknown;\n model?: unknown;\n allowedTools?: unknown;\n }) => {\n const name = typeof args.name === \"string\" ? args.name.trim() : \"\";\n const description =\n typeof args.description === \"string\"\n ? args.description.replace(/[\\r\\n]+/g, \" \").trim()\n : \"\";\n const body = typeof args.body === \"string\" ? args.body : \"\";\n if (!name) return JSON.stringify({ error: \"install_skill requires a non-empty 'name'\" });\n if (!description) {\n return JSON.stringify({\n error:\n \"install_skill requires a non-empty 'description' — it is what appears in the Skills index and how future agents decide whether to invoke the skill\",\n });\n }\n if (!body.trim()) {\n return JSON.stringify({\n error:\n \"install_skill requires a non-empty 'body' — the playbook the skill executes when invoked\",\n });\n }\n\n const scopeRaw = typeof args.scope === \"string\" ? args.scope.trim() : \"\";\n let scope: \"project\" | \"global\";\n if (scopeRaw === \"global\") scope = \"global\";\n else if (scopeRaw === \"project\") scope = \"project\";\n else scope = hasProjectScope ? \"project\" : \"global\";\n if (scope === \"project\" && !hasProjectScope) {\n return JSON.stringify({\n error:\n \"install_skill: scope='project' requires a workspace — run from `carboncode code`, or use scope='global'\",\n });\n }\n\n const runAsRaw = typeof args.runAs === \"string\" ? args.runAs.trim() : \"\";\n const runAs: \"inline\" | \"subagent\" = runAsRaw === \"subagent\" ? \"subagent\" : \"inline\";\n\n const fmLines = [\"---\", `name: ${name}`, `description: ${description}`];\n if (runAs === \"subagent\") {\n fmLines.push(\"runAs: subagent\");\n const model = typeof args.model === \"string\" ? args.model.trim() : \"\";\n if (model) fmLines.push(`model: ${model}`);\n if (Array.isArray(args.allowedTools)) {\n const tools = args.allowedTools\n .filter((t): t is string => typeof t === \"string\")\n .map((t) => t.trim())\n .filter(Boolean);\n if (tools.length > 0) fmLines.push(`allowed-tools: ${tools.join(\", \")}`);\n }\n }\n fmLines.push(\"---\", \"\");\n const content = `${fmLines.join(\"\\n\")}${body.replace(/\\s+$/, \"\")}\\n`;\n\n const result = store.createWithContent(name, scope, content);\n if (\"error\" in result) {\n return JSON.stringify({ error: result.error });\n }\n\n try {\n onSkillInstalled?.({ name, path: result.path, scope });\n } catch {\n // host hook failure must not undo a successful write\n }\n\n return JSON.stringify({\n ok: true,\n name,\n scope,\n path: result.path,\n runAs,\n note: \"Skill is callable right now via run_skill({ name }). It will appear in the pinned Skills index after the next /new or launch.\",\n });\n },\n });\n\n return registry;\n}\n"],"mappings":"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","names":[]}