@aliyunrds/ctxdb 1.0.1-beta.2 → 1.0.1

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.
@@ -1,503 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- isCircuitOpen,
4
- isConnectionError,
5
- resetCircuit,
6
- tripCircuit
7
- } from "../chunk-UULWJJT4.js";
3
+ captureTurn
4
+ } from "../chunk-IMYLU5C2.js";
5
+ import "../chunk-TGVURF54.js";
8
6
  import {
9
- CtxdbError,
10
7
  HttpClient,
11
8
  agentFromArgvWithFallback,
12
9
  debug,
13
- isDebug,
14
10
  load,
15
11
  setDebug
16
- } from "../chunk-TKMIWM6Q.js";
12
+ } from "../chunk-6FZL67GH.js";
17
13
  import {
18
14
  shouldSkipHooks
19
15
  } from "../chunk-UEKR2Z3S.js";
20
16
 
21
- // src/lib/capture-orchestrator.ts
22
- import {
23
- filterMessagesForExtraction,
24
- isKnowledgeBaseUploadTurn,
25
- selectTurnMessages
26
- } from "@aliyunrds/ctxdb-shared";
27
-
28
- // src/lib/git-context.ts
29
- import { execSync } from "child_process";
30
- function getGitContext() {
31
- try {
32
- const raw = execSync("git rev-parse --show-toplevel --abbrev-ref HEAD", {
33
- encoding: "utf-8",
34
- timeout: 3e3,
35
- stdio: ["ignore", "pipe", "ignore"]
36
- }).trim();
37
- const lines = raw.split("\n");
38
- if (lines.length < 2) return null;
39
- const project = lines[0].split(/[/\\]/).pop();
40
- if (!project) return null;
41
- const branch = lines[1];
42
- return { project, branch };
43
- } catch {
44
- return null;
45
- }
46
- }
47
-
48
- // src/lib/transcript.ts
49
- import { existsSync, readFileSync } from "fs";
50
- var ANTHROPIC_MESSAGE_TYPES = /* @__PURE__ */ new Set(["user", "assistant"]);
51
- var CODEX_RESPONSE_ITEM = "response_item";
52
- function readTranscript(path) {
53
- if (!existsSync(path)) return [];
54
- let text;
55
- try {
56
- text = readFileSync(path, "utf-8");
57
- } catch {
58
- return [];
59
- }
60
- const out = [];
61
- for (const line of text.split("\n")) {
62
- const s = line.trim();
63
- if (!s) continue;
64
- let obj;
65
- try {
66
- obj = JSON.parse(s);
67
- } catch {
68
- continue;
69
- }
70
- if (!obj || typeof obj !== "object" || Array.isArray(obj)) continue;
71
- const o = obj;
72
- const rawType = typeof o.type === "string" ? o.type : "";
73
- if (rawType === CODEX_RESPONSE_ITEM) {
74
- const payload = o.payload;
75
- if (payload && typeof payload === "object" && !Array.isArray(payload)) {
76
- out.push({ ...o, type: CODEX_RESPONSE_ITEM });
77
- }
78
- continue;
79
- }
80
- const message = o.message;
81
- const role = message && typeof message === "object" ? message.role : void 0;
82
- const inferred = ANTHROPIC_MESSAGE_TYPES.has(rawType) ? rawType : typeof role === "string" && ANTHROPIC_MESSAGE_TYPES.has(role) ? role : null;
83
- if (!inferred) continue;
84
- out.push({ ...o, type: inferred });
85
- }
86
- return out;
87
- }
88
- function toKbDetectionMessages(rows) {
89
- const out = [];
90
- for (const row of rows) {
91
- if (!row || typeof row !== "object") continue;
92
- if (row.type === CODEX_RESPONSE_ITEM) {
93
- const p = row.payload;
94
- if (!p || typeof p !== "object") continue;
95
- const ptype = p.type;
96
- if (ptype === "message") {
97
- const role = p.role;
98
- if (role !== "user" && role !== "assistant") continue;
99
- out.push({ role, content: p.content });
100
- continue;
101
- }
102
- if (ptype === "function_call") {
103
- const name = typeof p.name === "string" ? p.name : "";
104
- const args = parseArgs(p.arguments);
105
- const command = typeof args.cmd === "string" ? args.cmd : typeof args.command === "string" ? args.command : "";
106
- out.push({
107
- role: "assistant",
108
- content: [
109
- {
110
- type: "tool_use",
111
- // Map any codex tool name to "bash" so the shared
112
- // SHELL_TOOL_NAMES set fires; the actual command text is
113
- // preserved in input.command for the regex check.
114
- name: "bash",
115
- input: { command, codex_tool: name }
116
- }
117
- ]
118
- });
119
- continue;
120
- }
121
- continue;
122
- }
123
- const msg = row.message;
124
- if (!msg || typeof msg !== "object") continue;
125
- out.push({ role: msg.role, content: msg.content });
126
- }
127
- return out;
128
- }
129
- function selectTurnRows(rows) {
130
- let turnStart = -1;
131
- for (let ri = rows.length - 1; ri >= 0; ri--) {
132
- if (hasExtractableUserText(rows[ri])) {
133
- turnStart = ri;
134
- while (turnStart > 0 && hasExtractableUserText(rows[turnStart - 1])) {
135
- turnStart--;
136
- }
137
- break;
138
- }
139
- }
140
- return turnStart >= 0 ? rows.slice(turnStart) : [];
141
- }
142
- function hasExtractableUserText(row) {
143
- if (!row || typeof row !== "object") return false;
144
- if (row.type === CODEX_RESPONSE_ITEM) {
145
- const p = row.payload;
146
- if (!p || typeof p !== "object") return false;
147
- if (p.type !== "message" || p.role !== "user") return false;
148
- const content2 = p.content;
149
- if (!Array.isArray(content2)) return false;
150
- return content2.some((block) => {
151
- if (!block || typeof block !== "object") return false;
152
- if (block.type !== "input_text") return false;
153
- const text = block.text;
154
- return typeof text === "string" && text.trim() && !isCodexScaffoldingText(text);
155
- });
156
- }
157
- if (row.isMeta === true) return false;
158
- const msg = row.message;
159
- if (!msg || typeof msg !== "object") return false;
160
- if (msg.role !== "user") return false;
161
- const content = msg.content;
162
- if (typeof content === "string") return Boolean(content.trim());
163
- if (!Array.isArray(content)) return false;
164
- return content.some((block) => {
165
- if (!block || typeof block !== "object") return false;
166
- if (block.type !== "text") return false;
167
- const text = block.text;
168
- return typeof text === "string" && Boolean(text.trim());
169
- });
170
- }
171
- function parseArgs(raw) {
172
- if (typeof raw !== "string") return {};
173
- try {
174
- const parsed = JSON.parse(raw);
175
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
176
- return parsed;
177
- }
178
- } catch {
179
- }
180
- return {};
181
- }
182
- var CODEX_USER_SCAFFOLDING_PREFIXES = [
183
- "<environment_context>",
184
- "<permissions instructions>",
185
- "<collaboration_mode>",
186
- "<apps_instructions>",
187
- "<skills_instructions>",
188
- "<plugins_instructions>",
189
- "# AGENTS.md instructions for "
190
- ];
191
- var CODEX_MEMORY_PREAMBLE_RE = /^## Memory\s+You have access to a memory folder/;
192
- function isCodexScaffoldingText(text) {
193
- const t = text.trimStart();
194
- if (!t) return false;
195
- for (const prefix of CODEX_USER_SCAFFOLDING_PREFIXES) {
196
- if (t.startsWith(prefix)) return true;
197
- }
198
- return CODEX_MEMORY_PREAMBLE_RE.test(t);
199
- }
200
- function toParsedMessages(rows) {
201
- const parsed = [];
202
- let idx = 0;
203
- const push = (role, text) => {
204
- if (text && text.trim()) {
205
- parsed.push({ role, content: text, index: idx });
206
- idx++;
207
- }
208
- };
209
- for (const row of rows) {
210
- if (!row || typeof row !== "object") continue;
211
- if (row.type === CODEX_RESPONSE_ITEM) {
212
- const p = row.payload;
213
- if (!p || typeof p !== "object") continue;
214
- const ptype = p.type;
215
- if (ptype === "message") {
216
- const role2 = p.role;
217
- if (role2 !== "user" && role2 !== "assistant") continue;
218
- const content2 = p.content;
219
- if (!Array.isArray(content2)) continue;
220
- for (const block of content2) {
221
- if (!block || typeof block !== "object") continue;
222
- const btype = block.type;
223
- if (btype === "input_text" || btype === "output_text") {
224
- const v = block.text;
225
- if (typeof v !== "string") continue;
226
- if (role2 === "user" && isCodexScaffoldingText(v)) continue;
227
- push(role2, v);
228
- }
229
- }
230
- continue;
231
- }
232
- if (ptype === "reasoning") continue;
233
- continue;
234
- }
235
- if (row.isMeta === true) continue;
236
- const msg = row.message;
237
- if (!msg || typeof msg !== "object") continue;
238
- const role = msg.role;
239
- if (role !== "user" && role !== "assistant") continue;
240
- const content = msg.content;
241
- if (typeof content === "string") {
242
- push(role, content);
243
- continue;
244
- }
245
- if (Array.isArray(content)) {
246
- for (const block of content) {
247
- if (!block || typeof block !== "object") continue;
248
- const btype = block.type;
249
- let text = null;
250
- if (btype === "text") {
251
- const v = block.text;
252
- if (typeof v === "string") text = v;
253
- }
254
- if (text) push(role, text);
255
- }
256
- }
257
- }
258
- return parsed;
259
- }
260
- var COMMAND_MESSAGE_RE = /<command-message>([\s\S]*?)<\/command-message>/;
261
- var COMMAND_ARGS_RE = /<command-args>([\s\S]*?)<\/command-args>/;
262
- function extractSkillSignals(rows) {
263
- const signals = [];
264
- const seen = /* @__PURE__ */ new Set();
265
- const add = (s) => {
266
- const key = `${s.trigger}:${s.skill}`;
267
- if (seen.has(key)) return;
268
- seen.add(key);
269
- signals.push(s);
270
- };
271
- for (const row of rows) {
272
- if (!row || typeof row !== "object") continue;
273
- if (row.type === "user") {
274
- const msg = row.message;
275
- if (!msg || typeof msg !== "object") continue;
276
- const content = msg.content;
277
- if (typeof content === "string") {
278
- const m = COMMAND_MESSAGE_RE.exec(content);
279
- if (m) {
280
- const argsMatch = COMMAND_ARGS_RE.exec(content);
281
- add({
282
- skill: m[1].trim(),
283
- args: argsMatch?.[1]?.trim() || void 0,
284
- trigger: "command"
285
- });
286
- }
287
- }
288
- }
289
- if (row.type === "assistant") {
290
- const msg = row.message;
291
- if (!msg || typeof msg !== "object") continue;
292
- const content = msg.content;
293
- if (!Array.isArray(content)) continue;
294
- for (const block of content) {
295
- if (block && typeof block === "object" && block.type === "tool_use" && block.name === "Skill") {
296
- const input = block.input;
297
- if (input && typeof input === "object") {
298
- const skill = typeof input.skill === "string" ? input.skill : "";
299
- const args = typeof input.args === "string" ? input.args : void 0;
300
- if (skill) add({ skill, args, trigger: "agent" });
301
- }
302
- }
303
- }
304
- }
305
- }
306
- return signals;
307
- }
308
-
309
- // src/lib/capture-orchestrator.ts
310
- async function captureTurn(transcriptPath, cfg, client, agent = "default", sessionId) {
311
- if (!cfg.apiKey || !cfg.baseUrl) {
312
- return { captured: false, reason: "config_incomplete", messageCount: 0 };
313
- }
314
- if (!cfg.autoCapture) {
315
- return { captured: false, reason: "auto_capture_disabled", messageCount: 0 };
316
- }
317
- if (isCircuitOpen(agent, cfg.baseUrl)) {
318
- return { captured: false, reason: `circuit_open: ${cfg.baseUrl}`, messageCount: 0 };
319
- }
320
- const rows = readTranscript(transcriptPath);
321
- if (rows.length === 0) {
322
- return { captured: false, reason: "empty_transcript", messageCount: 0 };
323
- }
324
- const dbg = isDebug();
325
- if (dbg) debug("capture", "transcript rows", summarizeTranscriptRows(rows));
326
- const parsed = toParsedMessages(rows);
327
- if (dbg) debug("capture", "parsed messages", summarizeTextMessages(parsed));
328
- if (parsed.length === 0) {
329
- return {
330
- captured: false,
331
- reason: `transcript_schema_mismatch: rows=${rows.length} parsed=0`,
332
- messageCount: 0
333
- };
334
- }
335
- const turn = selectTurnMessages(parsed);
336
- if (dbg) debug("capture", "selected turn", summarizeTextMessages(turn));
337
- if (turn.length === 0) {
338
- return { captured: false, reason: "empty_turn_slice", messageCount: 0 };
339
- }
340
- if (!turn.some((m) => m.role === "user")) {
341
- return { captured: false, reason: "no_user_in_turn", messageCount: 0 };
342
- }
343
- const AUTOMATED_REVIEW_PREFIX = "[SYSTEM: This is an automated background review task. It is NOT a user message.";
344
- const userMsgs = turn.filter((m) => m.role === "user");
345
- if (userMsgs.every((m) => m.content.startsWith(AUTOMATED_REVIEW_PREFIX))) {
346
- return { captured: false, reason: "automated_review_skip", messageCount: 0 };
347
- }
348
- const turnRows = selectTurnRows(rows);
349
- if (dbg) debug("capture", "current turn rows", summarizeTranscriptRows(turnRows));
350
- const kb = isKnowledgeBaseUploadTurn(toKbDetectionMessages(turnRows));
351
- if (kb.detected) {
352
- return {
353
- captured: false,
354
- reason: `b3c_skip: ${kb.reason ?? "(no reason)"}`,
355
- messageCount: 0
356
- };
357
- }
358
- const rawMessages = turn.map((m) => ({ role: m.role, content: m.content }));
359
- const filtered = filterMessagesForExtraction(rawMessages);
360
- if (dbg) debug("capture", "filtered messages", summarizeTextMessages(filtered));
361
- if (filtered.length === 0) {
362
- return { captured: false, reason: "all_filtered", messageCount: 0 };
363
- }
364
- const git = getGitContext();
365
- const skills = extractSkillSignals(rows);
366
- const bg = {};
367
- if (git) bg.git = git;
368
- if (skills.length > 0) bg.skills = skills.map(
369
- ({ skill, trigger, args }) => args ? { skill, trigger, args } : { skill, trigger }
370
- );
371
- const hasBackground = Boolean(bg.git || bg.skills);
372
- if (hasBackground) debug("capture", "background", bg);
373
- const messages = hasBackground ? [{ role: "background", content: JSON.stringify(bg) }, ...filtered] : filtered;
374
- const payload = {
375
- messages,
376
- user_id: cfg.userId,
377
- async_mode: true
378
- };
379
- if (cfg.agentId) payload.agent_id = cfg.agentId;
380
- if (cfg.appId) payload.app_id = cfg.appId;
381
- if (sessionId) payload.run_id = sessionId;
382
- let resp;
383
- try {
384
- resp = await client.postJson("/v3/memories/add/", payload);
385
- resetCircuit(agent);
386
- } catch (err) {
387
- const msg = err instanceof CtxdbError ? err.message : String(err);
388
- if (isConnectionError(err)) tripCircuit(agent, cfg.baseUrl, msg);
389
- return {
390
- captured: false,
391
- reason: `http_error: ${msg}`,
392
- messageCount: filtered.length
393
- };
394
- }
395
- return {
396
- captured: true,
397
- reason: "ok",
398
- serverResponse: resp,
399
- messageCount: filtered.length
400
- };
401
- }
402
- var DEBUG_TAIL_LIMIT = 25;
403
- var DEBUG_TEXT_LIMIT = 240;
404
- var DEBUG_BLOCK_LIMIT = 8;
405
- function summarizeTextMessages(messages) {
406
- return {
407
- count: messages.length,
408
- roles: countRoles(messages),
409
- tail: tailWithIndex(messages).map(({ index, item }) => ({
410
- index,
411
- parsedIndex: typeof item.index === "number" ? item.index : void 0,
412
- role: item.role ?? "(unknown)",
413
- content: summarizeText(item.content)
414
- }))
415
- };
416
- }
417
- function summarizeTranscriptRows(rows) {
418
- return {
419
- count: rows.length,
420
- tail: tailWithIndex(rows).map(({ index, item: row }) => ({
421
- index,
422
- type: row.type,
423
- role: rowRole(row),
424
- isMeta: row.isMeta === true || void 0,
425
- payloadType: row.payload?.type,
426
- content: summarizeRowContent(row)
427
- }))
428
- };
429
- }
430
- function tailWithIndex(items) {
431
- const start = Math.max(0, items.length - DEBUG_TAIL_LIMIT);
432
- return items.slice(start).map((item, offset) => ({ index: start + offset, item }));
433
- }
434
- function countRoles(messages) {
435
- const counts = {};
436
- for (const msg of messages) {
437
- const role = msg.role ?? "(unknown)";
438
- counts[role] = (counts[role] ?? 0) + 1;
439
- }
440
- return counts;
441
- }
442
- function rowRole(row) {
443
- const msgRole = row.message && typeof row.message === "object" ? row.message.role : void 0;
444
- if (typeof msgRole === "string") return msgRole;
445
- const payloadRole = row.payload && typeof row.payload === "object" ? row.payload.role : void 0;
446
- return typeof payloadRole === "string" ? payloadRole : void 0;
447
- }
448
- function summarizeRowContent(row) {
449
- if (row.type === "response_item") {
450
- const p = row.payload;
451
- if (!p || typeof p !== "object") return { kind: "missing" };
452
- if (p.type === "function_call") {
453
- return {
454
- kind: "function_call",
455
- name: p.name,
456
- arguments: summarizeText(p.arguments)
457
- };
458
- }
459
- return summarizeContent(p.content);
460
- }
461
- return summarizeContent(row.message?.content);
462
- }
463
- function summarizeContent(content) {
464
- if (typeof content === "string") return summarizeText(content);
465
- if (!Array.isArray(content)) {
466
- return { kind: content === void 0 ? "missing" : typeof content };
467
- }
468
- return {
469
- kind: "blocks",
470
- count: content.length,
471
- blocks: content.slice(0, DEBUG_BLOCK_LIMIT).map((block) => summarizeBlock(block)),
472
- truncated: content.length > DEBUG_BLOCK_LIMIT || void 0
473
- };
474
- }
475
- function summarizeBlock(block) {
476
- if (!block || typeof block !== "object") return { kind: typeof block };
477
- const b = block;
478
- const summary = { type: b.type };
479
- if (typeof b.name === "string") summary.name = b.name;
480
- if (typeof b.text === "string") summary.text = summarizeText(b.text);
481
- if (typeof b.thinking === "string") summary.thinking = summarizeText(b.thinking);
482
- if (typeof b.content === "string") summary.content = summarizeText(b.content);
483
- const input = b.input;
484
- if (input && typeof input === "object" && !Array.isArray(input)) {
485
- const i = input;
486
- summary.inputKeys = Object.keys(i).sort();
487
- if (typeof i.command === "string") summary.command = summarizeText(i.command);
488
- }
489
- return summary;
490
- }
491
- function summarizeText(text) {
492
- if (typeof text !== "string") return { kind: text === void 0 ? "missing" : typeof text };
493
- const normalized = text.replace(/\s+/g, " ").trim();
494
- return {
495
- kind: "text",
496
- length: text.length,
497
- snippet: normalized.length > DEBUG_TEXT_LIMIT ? `${normalized.slice(0, DEBUG_TEXT_LIMIT)}...` : normalized
498
- };
499
- }
500
-
501
17
  // src/hooks/stop.ts
502
18
  async function readStdinJson() {
503
19
  let raw = "";
@@ -1,110 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- fetchKbCatalogBlock,
4
- recallTurn
5
- } from "../chunk-CYCD234A.js";
6
- import "../chunk-6S5RJYBC.js";
7
- import {
8
- isCircuitOpen
9
- } from "../chunk-UULWJJT4.js";
10
- import {
11
- HttpClient,
12
- agentFromArgvWithFallback,
13
- debug,
14
- isComplete,
15
- load,
16
- setDebug
17
- } from "../chunk-TKMIWM6Q.js";
18
- import {
19
- shouldSkipHooks
20
- } from "../chunk-UEKR2Z3S.js";
21
-
22
- // src/hooks/user-prompt-submit.ts
23
- import { pathToFileURL } from "url";
24
- async function composeUserPromptSubmit(cfg, agent, client, prompt) {
25
- const [recall, kbBlock] = await Promise.all([
26
- recallTurn(prompt, cfg, client, agent),
27
- cfg.kbCatalogInjection === "user_prompt_submit" ? fetchKbCatalogBlock(client, agent).catch(() => "") : Promise.resolve("")
28
- ]);
29
- let ctx = recall.additionalContext || "";
30
- if (kbBlock) ctx = ctx ? `${ctx}
31
-
32
- ${kbBlock}` : kbBlock;
33
- return { ctx, recall, kbBlock };
34
- }
35
- function formatUserPromptSubmitStdout(agent, ctx) {
36
- if (agent === "codex") return ctx + "\n";
37
- const out = {
38
- hookSpecificOutput: {
39
- hookEventName: "UserPromptSubmit",
40
- additionalContext: ctx
41
- }
42
- };
43
- return JSON.stringify(out) + "\n";
44
- }
45
- async function readStdinJson() {
46
- let raw = "";
47
- for await (const chunk of process.stdin) raw += chunk;
48
- if (!raw.trim()) return {};
49
- try {
50
- const obj = JSON.parse(raw);
51
- return obj && typeof obj === "object" && !Array.isArray(obj) ? obj : {};
52
- } catch {
53
- return {};
54
- }
55
- }
56
- async function main() {
57
- try {
58
- if (shouldSkipHooks()) return 0;
59
- const event = await readStdinJson();
60
- const { agent, fellBack } = agentFromArgvWithFallback();
61
- if (fellBack) {
62
- process.stderr.write(
63
- `ctxdb recall: agent unspecified, defaulting to ${agent}
64
- `
65
- );
66
- }
67
- const prompt = typeof event.prompt === "string" ? event.prompt : "";
68
- if (!prompt.trim()) return 0;
69
- const cfg = load({ agent });
70
- setDebug(cfg.debug);
71
- debug("recall", "start", { prompt: prompt.slice(0, 200), userId: cfg.userId });
72
- if (!isComplete(cfg) || !cfg.autoRecall) {
73
- debug("recall", "skip (config incomplete or autoRecall=false)");
74
- return 0;
75
- }
76
- if (isCircuitOpen(agent, cfg.baseUrl)) {
77
- debug("recall", "skip (circuit open)");
78
- process.stderr.write(`ctxdb recall: skip (circuit_open: ${cfg.baseUrl})
79
- `);
80
- return 0;
81
- }
82
- const client = new HttpClient({ baseUrl: cfg.baseUrl, apiKey: cfg.apiKey, timeoutMs: 5e3 });
83
- const { ctx, recall, kbBlock } = await composeUserPromptSubmit(cfg, agent, client, prompt);
84
- if (!recall.ok && !recall.additionalContext && !kbBlock) {
85
- const reason = recall.reason ?? "no_context";
86
- debug("recall", `no result: ${reason}`, recall);
87
- if (recall.reason && recall.reason.startsWith("http_error:")) {
88
- process.stderr.write(`ctxdb recall: ${recall.reason}
89
- `);
90
- }
91
- return 0;
92
- }
93
- if (!ctx) return 0;
94
- debug("recall", `ok, additionalContext length=${ctx.length}`);
95
- process.stdout.write(formatUserPromptSubmitStdout(agent, ctx));
96
- return 0;
97
- } catch (err) {
98
- process.stderr.write(`ctxdb recall: unexpected error: ${err?.message ?? err}
99
- `);
100
- return 0;
101
- }
102
- }
103
- if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
104
- main().then((code) => {
105
- process.exitCode = code;
106
- });
107
- }
3
+ composeUserPromptSubmit,
4
+ formatUserPromptSubmitStdout
5
+ } from "../chunk-FD3AMXVU.js";
6
+ import "../chunk-EUQ3OFCQ.js";
7
+ import "../chunk-UH7AJF6F.js";
8
+ import "../chunk-TGVURF54.js";
9
+ import "../chunk-6FZL67GH.js";
10
+ import "../chunk-UEKR2Z3S.js";
108
11
  export {
109
12
  composeUserPromptSubmit,
110
13
  formatUserPromptSubmitStdout