clawmini 0.0.1 → 0.0.2

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 (56) hide show
  1. package/README.md +60 -77
  2. package/dist/adapter-discord/index.mjs +2 -2
  3. package/dist/{chats-Zd_HXDHx.mjs → chats-BcbxvPlj.mjs} +2 -2
  4. package/dist/{chats-Zd_HXDHx.mjs.map → chats-BcbxvPlj.mjs.map} +1 -1
  5. package/dist/{chats-DKgTeU7i.mjs → chats-CpRQrNHj.mjs} +2 -2
  6. package/dist/{chats-DKgTeU7i.mjs.map → chats-CpRQrNHj.mjs.map} +1 -1
  7. package/dist/cli/index.mjs +4 -3
  8. package/dist/cli/index.mjs.map +1 -1
  9. package/dist/cli/lite.mjs +48 -0
  10. package/dist/cli/lite.mjs.map +1 -1
  11. package/dist/daemon/index.mjs +311 -19
  12. package/dist/daemon/index.mjs.map +1 -1
  13. package/dist/{lite-Dl7WXyaH.mjs → lite-DBUuHsX0.mjs} +2 -2
  14. package/dist/{lite-Dl7WXyaH.mjs.map → lite-DBUuHsX0.mjs.map} +1 -1
  15. package/dist/policy-utils-BvfOK6Ih.mjs +114 -0
  16. package/dist/policy-utils-BvfOK6Ih.mjs.map +1 -0
  17. package/dist/web/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
  18. package/dist/web/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
  19. package/dist/web/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
  20. package/dist/web/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
  21. package/dist/web/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
  22. package/dist/web/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
  23. package/dist/web/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
  24. package/dist/web/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
  25. package/dist/web/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
  26. package/dist/web/_app/version.json +1 -1
  27. package/dist/web/index.html +6 -6
  28. package/dist/{workspace-CSgfo_2J.mjs → workspace-BC1ahx4R.mjs} +13 -2
  29. package/dist/workspace-BC1ahx4R.mjs.map +1 -0
  30. package/docs/CLI_REFERENCE.md +35 -0
  31. package/docs/guides/sandbox_policies.md +12 -5
  32. package/package.json +1 -1
  33. package/web/.svelte-kit/ambient.d.ts +2 -6
  34. package/web/.svelte-kit/generated/server/internal.js +1 -1
  35. package/web/.svelte-kit/output/client/.vite/manifest.json +25 -25
  36. package/web/.svelte-kit/output/client/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
  37. package/web/.svelte-kit/output/client/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
  38. package/web/.svelte-kit/output/client/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
  39. package/web/.svelte-kit/output/client/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
  40. package/web/.svelte-kit/output/client/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
  41. package/web/.svelte-kit/output/client/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
  42. package/web/.svelte-kit/output/client/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
  43. package/web/.svelte-kit/output/client/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
  44. package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
  45. package/web/.svelte-kit/output/client/_app/version.json +1 -1
  46. package/web/.svelte-kit/output/server/chunks/internal.js +1 -1
  47. package/web/.svelte-kit/output/server/manifest-full.js +1 -1
  48. package/web/.svelte-kit/output/server/manifest.js +1 -1
  49. package/web/.svelte-kit/output/server/nodes/0.js +1 -1
  50. package/web/.svelte-kit/output/server/nodes/1.js +1 -1
  51. package/web/.svelte-kit/output/server/nodes/3.js +1 -1
  52. package/web/.svelte-kit/output/server/nodes/4.js +1 -1
  53. package/web/.svelte-kit/output/server/nodes/5.js +1 -1
  54. package/dist/web/_app/immutable/entry/start.oP1AgKhs.js +0 -1
  55. package/dist/workspace-CSgfo_2J.mjs.map +0 -1
  56. package/web/.svelte-kit/output/client/_app/immutable/entry/start.oP1AgKhs.js +0 -1
@@ -1,8 +1,9 @@
1
- import { C as SettingsSchema, S as CronJobSchema, a as getAgent, b as writeChatSettings, c as getSettingsPath, g as readSettings, h as readEnvironment, i as getActiveEnvironmentInfo, l as getSocketPath, m as readChatSettings, o as getClawminiDir, p as readAgentSessionSettings, s as getEnvironmentPath, u as getWorkspaceRoot, v as writeAgentSessionSettings } from "../workspace-CSgfo_2J.mjs";
1
+ import { C as CronJobSchema, _ as readSettings, a as getAgent, c as getSettingsPath, g as readPolicies, h as readEnvironment, i as getActiveEnvironmentInfo, l as getSocketPath, m as readChatSettings, o as getClawminiDir, p as readAgentSessionSettings, s as getEnvironmentPath, u as getWorkspaceRoot, w as SettingsSchema, x as writeChatSettings, y as writeAgentSessionSettings } from "../workspace-BC1ahx4R.mjs";
2
2
  import { n as pathIsInsideDir } from "../fs-B5wW0oaH.mjs";
3
- import { l as listChats, o as getDefaultChatId, s as getMessages } from "../chats-DKgTeU7i.mjs";
4
- import { n as exportLiteToEnvironment } from "../lite-Dl7WXyaH.mjs";
5
- import { a as daemonEvents, i as DAEMON_EVENT_TYPING, o as emitTyping, r as DAEMON_EVENT_MESSAGE_APPENDED, t as appendMessage } from "../chats-Zd_HXDHx.mjs";
3
+ import { l as listChats, o as getDefaultChatId, s as getMessages } from "../chats-CpRQrNHj.mjs";
4
+ import { n as exportLiteToEnvironment } from "../lite-DBUuHsX0.mjs";
5
+ import { a as daemonEvents, i as DAEMON_EVENT_TYPING, o as emitTyping, r as DAEMON_EVENT_MESSAGE_APPENDED, t as appendMessage } from "../chats-BcbxvPlj.mjs";
6
+ import { n as executeSafe, r as interpolateArgs, t as createSnapshot } from "../policy-utils-BvfOK6Ih.mjs";
6
7
  import fs from "node:fs";
7
8
  import path from "node:path";
8
9
  import { execSync, spawn } from "node:child_process";
@@ -12,9 +13,128 @@ import http from "node:http";
12
13
  import net from "node:net";
13
14
  import { createHTTPHandler } from "@trpc/server/adapters/standalone";
14
15
  import { TRPCError, initTRPC } from "@trpc/server";
15
- import crypto$1 from "node:crypto";
16
+ import fs$2 from "fs/promises";
17
+ import path$1 from "path";
18
+ import { randomInt } from "crypto";
19
+ import crypto$1, { randomUUID } from "node:crypto";
16
20
  import schedule from "node-schedule";
17
21
 
22
+ //#region src/daemon/request-store.ts
23
+ const PolicyRequestSchema = z.object({
24
+ id: z.string(),
25
+ commandName: z.string(),
26
+ args: z.array(z.string()),
27
+ fileMappings: z.record(z.string(), z.string()),
28
+ state: z.enum([
29
+ "Pending",
30
+ "Approved",
31
+ "Rejected"
32
+ ]),
33
+ createdAt: z.number(),
34
+ rejectionReason: z.string().optional(),
35
+ chatId: z.string(),
36
+ agentId: z.string()
37
+ });
38
+ function isENOENT(err) {
39
+ return Boolean(err && typeof err === "object" && "code" in err && err.code === "ENOENT");
40
+ }
41
+ var RequestStore = class {
42
+ baseDir;
43
+ constructor(startDir = process.cwd()) {
44
+ this.baseDir = path$1.join(getClawminiDir(startDir), "tmp", "requests");
45
+ }
46
+ async init() {
47
+ await fs$2.mkdir(this.baseDir, { recursive: true });
48
+ }
49
+ getFilePath(id) {
50
+ return path$1.join(this.baseDir, `${id}.json`);
51
+ }
52
+ async save(request) {
53
+ await this.init();
54
+ const filePath = this.getFilePath(request.id);
55
+ await fs$2.writeFile(filePath, JSON.stringify(request, null, 2), "utf8");
56
+ }
57
+ async load(id) {
58
+ const normalizedId = normalizePolicyId(id);
59
+ const filePath = this.getFilePath(normalizedId);
60
+ try {
61
+ const data = await fs$2.readFile(filePath, "utf8");
62
+ return PolicyRequestSchema.parse(JSON.parse(data));
63
+ } catch (err) {
64
+ if (isENOENT(err)) return null;
65
+ const msg = err instanceof Error ? err.message : String(err);
66
+ console.warn(`Failed to parse request file ${filePath}:`, msg);
67
+ return null;
68
+ }
69
+ }
70
+ async list() {
71
+ await this.init();
72
+ const requests = [];
73
+ try {
74
+ const files = await fs$2.readdir(this.baseDir);
75
+ for (const file of files) {
76
+ if (!file.endsWith(".json")) continue;
77
+ const id = path$1.basename(file, ".json");
78
+ const req = await this.load(id);
79
+ if (req) requests.push(req);
80
+ }
81
+ } catch (err) {
82
+ if (!isENOENT(err)) throw err;
83
+ }
84
+ return requests.sort((a, b) => b.createdAt - a.createdAt);
85
+ }
86
+ };
87
+ function generateRandomAlphaNumericString(length) {
88
+ const characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
89
+ let result = "";
90
+ for (let i = 0; i < length; i++) result += characters[Math.floor(randomInt(36))];
91
+ return result;
92
+ }
93
+ function normalizePolicyId(id) {
94
+ return id.toLocaleUpperCase().trim();
95
+ }
96
+
97
+ //#endregion
98
+ //#region src/daemon/policy-request-service.ts
99
+ var PolicyRequestService = class {
100
+ store;
101
+ maxPending;
102
+ agentDir;
103
+ snapshotDir;
104
+ constructor(store, agentDir, snapshotDir, maxPending = 100) {
105
+ this.store = store;
106
+ this.agentDir = agentDir;
107
+ this.snapshotDir = snapshotDir;
108
+ this.maxPending = maxPending;
109
+ }
110
+ async createRequest(commandName, args, fileMappings, chatId, agentId) {
111
+ const allRequests = await this.store.list();
112
+ if (allRequests.filter((r) => r.state === "Pending").length >= this.maxPending) throw new Error(`Maximum number of pending requests (${this.maxPending}) reached.`);
113
+ const snapshotMappings = {};
114
+ for (const [key, requestedPath] of Object.entries(fileMappings)) snapshotMappings[key] = await createSnapshot(requestedPath, this.agentDir, this.snapshotDir);
115
+ let id = "";
116
+ do
117
+ id = generateRandomAlphaNumericString(3);
118
+ while (allRequests.some((r) => r.id === id));
119
+ const request = {
120
+ id,
121
+ commandName,
122
+ args,
123
+ fileMappings: snapshotMappings,
124
+ state: "Pending",
125
+ createdAt: Date.now(),
126
+ chatId,
127
+ agentId
128
+ };
129
+ await this.store.save(request);
130
+ return request;
131
+ }
132
+ getInterpolatedArgs(request) {
133
+ return interpolateArgs(request.args, request.fileMappings);
134
+ }
135
+ };
136
+
137
+ //#endregion
18
138
  //#region src/daemon/queue.ts
19
139
  var Queue = class {
20
140
  pending = [];
@@ -154,18 +274,135 @@ const slashStop = createSlashActionRouter("stop", "stop", "Stopping current task
154
274
  //#region src/daemon/routers/slash-interrupt.ts
155
275
  const slashInterrupt = createSlashActionRouter("interrupt", "interrupt", "Interrupting current task...");
156
276
 
277
+ //#endregion
278
+ //#region src/daemon/routers/slash-policies.ts
279
+ async function loadAndValidateRequest(id, state) {
280
+ const store = new RequestStore(getWorkspaceRoot());
281
+ const req = await store.load(id);
282
+ if (!req) return { error: {
283
+ ...state,
284
+ message: "",
285
+ reply: `Request not found: ${id}`
286
+ } };
287
+ if (req.chatId && req.chatId !== state.chatId) return { error: {
288
+ ...state,
289
+ message: "",
290
+ reply: `Request belongs to a different chat: ${req.chatId}`
291
+ } };
292
+ if (req.state !== "Pending") return { error: {
293
+ ...state,
294
+ message: "",
295
+ reply: `Request is not pending: ${id}`
296
+ } };
297
+ return {
298
+ req,
299
+ store
300
+ };
301
+ }
302
+ async function slashPolicies(state) {
303
+ const message = state.message.trim();
304
+ if (message === "/pending") {
305
+ const pending = (await new RequestStore(getWorkspaceRoot()).list()).filter((r) => r.state === "Pending");
306
+ let reply = `Pending Requests (${pending.length}):\n`;
307
+ for (const req of pending) reply += `- ID: ${req.id} | Command: ${req.commandName} ${req.args.join(" ")}\n`;
308
+ return {
309
+ ...state,
310
+ reply,
311
+ action: "stop"
312
+ };
313
+ }
314
+ const approveMatch = message.match(/^\/approve\s+([^\s]+)/);
315
+ if (approveMatch) {
316
+ const id = approveMatch[1];
317
+ if (!id) return state;
318
+ const { req, store, error } = await loadAndValidateRequest(id, state);
319
+ if (error) return error;
320
+ if (!req || !store) return state;
321
+ const policy = (await readPolicies())?.policies?.[req.commandName];
322
+ if (!policy) return {
323
+ ...state,
324
+ message: "",
325
+ reply: `Policy not found: ${req.commandName}`
326
+ };
327
+ req.state = "Approved";
328
+ await store.save(req);
329
+ const interpolatedArgs = interpolateArgs([...policy.args || [], ...req.args], req.fileMappings);
330
+ const { stdout, stderr, exitCode } = await executeSafe(policy.command, interpolatedArgs, { cwd: getWorkspaceRoot() });
331
+ const commandStr = `${policy.command} ${interpolatedArgs.join(" ")}`;
332
+ const logMsg = {
333
+ id: randomUUID(),
334
+ messageId: state.messageId,
335
+ role: "log",
336
+ source: "router",
337
+ content: `Request ${id} approved and executed.`,
338
+ stderr,
339
+ stdout,
340
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
341
+ command: commandStr,
342
+ cwd: getWorkspaceRoot(),
343
+ exitCode
344
+ };
345
+ await appendMessage(state.chatId, logMsg);
346
+ const agentMessage = `Request ${id} approved.\n\n${wrapInHtml("stdout", stdout)}\n\n${wrapInHtml("stderr", stderr)}\n\nExit Code: ${exitCode}`;
347
+ return {
348
+ ...state,
349
+ message: agentMessage,
350
+ reply: `Approved request, running ${req.commandName}`
351
+ };
352
+ }
353
+ const rejectMatch = message.match(/^\/reject\s+([^\s]+)(?:\s+(.*))?/);
354
+ if (rejectMatch) {
355
+ const id = rejectMatch[1];
356
+ if (!id) return state;
357
+ const reason = rejectMatch[2] || "No reason provided";
358
+ const { req, store, error } = await loadAndValidateRequest(id, state);
359
+ if (error) return error;
360
+ if (!req || !store) return state;
361
+ req.state = "Rejected";
362
+ req.rejectionReason = reason;
363
+ await store.save(req);
364
+ const logMsg = {
365
+ id: randomUUID(),
366
+ messageId: state.messageId,
367
+ role: "log",
368
+ source: "router",
369
+ content: `Request ${id} rejected. Reason: ${reason}`,
370
+ stderr: "",
371
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
372
+ command: `policy-request-reject ${id}`,
373
+ cwd: getWorkspaceRoot(),
374
+ exitCode: 1
375
+ };
376
+ await appendMessage(state.chatId, logMsg);
377
+ const agentMessage = `Request ${id} rejected. Reason: ${reason}`;
378
+ return {
379
+ ...state,
380
+ message: agentMessage
381
+ };
382
+ }
383
+ return state;
384
+ }
385
+ function wrapInHtml(tag, text) {
386
+ if (text.trim().length === 0) return `<${tag}></${tag}>`;
387
+ return `<${tag}>\n${text.trim()}\n</${tag}>`;
388
+ }
389
+
157
390
  //#endregion
158
391
  //#region src/daemon/routers.ts
159
392
  async function executeRouterPipeline(initialState, routers) {
160
393
  let state = { ...initialState };
161
- for (const router of routers) if (router === "@clawmini/slash-new") state = slashNew(state);
162
- else if (router === "@clawmini/slash-command") state = await slashCommand(state);
163
- else if (router === "@clawmini/slash-stop") state = slashStop(state);
164
- else if (router === "@clawmini/slash-interrupt") state = slashInterrupt(state);
165
- else try {
166
- state = await executeCustomRouter(router, state);
167
- } catch (err) {
168
- console.error(`Router error [${router}]:`, err);
394
+ for (const router of routers) {
395
+ if (state.action === "stop") break;
396
+ if (router === "@clawmini/slash-new") state = slashNew(state);
397
+ else if (router === "@clawmini/slash-command") state = await slashCommand(state);
398
+ else if (router === "@clawmini/slash-stop") state = slashStop(state);
399
+ else if (router === "@clawmini/slash-interrupt") state = slashInterrupt(state);
400
+ else if (router === "@clawmini/slash-policies") state = await slashPolicies(state);
401
+ else try {
402
+ state = await executeCustomRouter(router, state);
403
+ } catch (err) {
404
+ console.error(`Router error [${router}]:`, err);
405
+ }
169
406
  }
170
407
  return state;
171
408
  }
@@ -374,9 +611,9 @@ function formatEnvironmentPrefix(prefix, replacements) {
374
611
  };
375
612
  return prefix.replace(/{(WORKSPACE_DIR|AGENT_DIR|ENV_DIR|HOME_DIR|ENV_ARGS)}/g, (match) => map[match] || match);
376
613
  }
377
- async function executeDirectMessage(chatId, state, settings, cwd, runCommand, noWait = true, userMessageContent) {
614
+ async function executeDirectMessage(chatId, state, settings, cwd, runCommand, noWait = false, userMessageContent) {
378
615
  const userMsg = {
379
- id: crypto.randomUUID(),
616
+ id: state.messageId ?? crypto.randomUUID(),
380
617
  role: "user",
381
618
  content: userMessageContent ?? state.message,
382
619
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -576,14 +813,16 @@ async function executeDirectMessage(chatId, state, settings, cwd, runCommand, no
576
813
  if (err.name !== "AbortError") console.error("Task execution error:", err);
577
814
  });
578
815
  }
579
- async function getInitialRouterState(chatId, message, cwd = process.cwd(), overrideAgentId, overrideSessionId) {
816
+ async function getInitialRouterState(chatId, message, cwd = process.cwd(), overrideAgentId, overrideSessionId, overrideMessageId) {
580
817
  const chatSettings = await readChatSettings(chatId, cwd) ?? {};
581
818
  const agentId = overrideAgentId ?? chatSettings.defaultAgent ?? "default";
819
+ const sessionId = overrideSessionId ?? chatSettings.sessions?.[agentId] ?? "default";
582
820
  return {
821
+ messageId: overrideMessageId ?? crypto.randomUUID(),
583
822
  message,
584
823
  chatId,
585
824
  agentId,
586
- sessionId: overrideSessionId ?? chatSettings.sessions?.[agentId] ?? "default",
825
+ sessionId,
587
826
  env: {}
588
827
  };
589
828
  }
@@ -613,6 +852,7 @@ async function handleUserMessage(chatId, message, settings, cwd = process.cwd(),
613
852
  }
614
853
  if (settingsChanged) await writeChatSettings(chatId, chatSettings, cwd);
615
854
  const directState = {
855
+ messageId: finalState.messageId,
616
856
  message: finalMessage,
617
857
  chatId,
618
858
  env: routerEnv
@@ -845,7 +1085,7 @@ async function getAgentFilesDir(agentId, chatId, settings, workspaceRoot) {
845
1085
  }
846
1086
  async function validateAttachments(files) {
847
1087
  const { pathIsInsideDir } = await import("../fs-B5wW0oaH.mjs").then((n) => n.t);
848
- const { getClawminiDir } = await import("../workspace-CSgfo_2J.mjs").then((n) => n._);
1088
+ const { getClawminiDir } = await import("../workspace-BC1ahx4R.mjs").then((n) => n.v);
849
1089
  const tmpDir = path.join(getClawminiDir(process.cwd()), "tmp");
850
1090
  for (const file of files) {
851
1091
  const absoluteFile = path.resolve(process.cwd(), file);
@@ -1018,7 +1258,7 @@ const AppRouter = router({
1018
1258
  exitCode: 0,
1019
1259
  ...filePaths.length > 0 ? { files: filePaths } : {}
1020
1260
  };
1021
- await import("../chats-Zd_HXDHx.mjs").then((n) => n.n).then((m) => m.appendMessage(chatId, logMsg));
1261
+ await import("../chats-BcbxvPlj.mjs").then((n) => n.n).then((m) => m.appendMessage(chatId, logMsg));
1022
1262
  return { success: true };
1023
1263
  }),
1024
1264
  listCronJobs: apiProcedure.input(z.object({ chatId: z.string().optional() })).query(async ({ input, ctx }) => {
@@ -1063,6 +1303,58 @@ const AppRouter = router({
1063
1303
  success: true,
1064
1304
  deleted: false
1065
1305
  };
1306
+ }),
1307
+ listPolicies: apiProcedure.query(async () => {
1308
+ return await readPolicies();
1309
+ }),
1310
+ executePolicyHelp: apiProcedure.input(z.object({ commandName: z.string() })).query(async ({ input }) => {
1311
+ const policy = (await readPolicies())?.policies?.[input.commandName];
1312
+ if (!policy) throw new TRPCError({
1313
+ code: "NOT_FOUND",
1314
+ message: `Policy not found: ${input.commandName}`
1315
+ });
1316
+ if (!policy.allowHelp) return {
1317
+ stdout: "",
1318
+ stderr: "This command does not support --help\n",
1319
+ exitCode: 1
1320
+ };
1321
+ const { executeSafe } = await import("../policy-utils-BvfOK6Ih.mjs").then((n) => n.i);
1322
+ const fullArgs = [...policy.args || [], "--help"];
1323
+ const { stdout, stderr, exitCode } = await executeSafe(policy.command, fullArgs, { cwd: getWorkspaceRoot() });
1324
+ return {
1325
+ stdout,
1326
+ stderr,
1327
+ exitCode
1328
+ };
1329
+ }),
1330
+ createPolicyRequest: apiProcedure.input(z.object({
1331
+ commandName: z.string(),
1332
+ args: z.array(z.string()),
1333
+ fileMappings: z.record(z.string(), z.string()),
1334
+ chatId: z.string().optional()
1335
+ })).mutation(async ({ input, ctx }) => {
1336
+ const workspaceRoot = getWorkspaceRoot(process.cwd());
1337
+ const snapshotDir = path.join(getClawminiDir(process.cwd()), "tmp", "snapshots");
1338
+ const service = new PolicyRequestService(new RequestStore(process.cwd()), await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot), snapshotDir);
1339
+ const chatId = await resolveAndCheckChatId(ctx, input.chatId);
1340
+ const agentId = ctx.tokenPayload?.agentId ?? "unknown";
1341
+ const request = await service.createRequest(input.commandName, input.args, input.fileMappings, chatId, agentId);
1342
+ const { generateRequestPreview } = await import("../policy-utils-BvfOK6Ih.mjs").then((n) => n.i);
1343
+ const previewContent = await generateRequestPreview(request);
1344
+ const logMsg = {
1345
+ id: (await import("node:crypto")).randomUUID(),
1346
+ messageId: (await import("node:crypto")).randomUUID(),
1347
+ role: "log",
1348
+ source: "router",
1349
+ content: previewContent,
1350
+ stderr: "",
1351
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1352
+ command: "policy-request",
1353
+ cwd: process.cwd(),
1354
+ exitCode: 0
1355
+ };
1356
+ await import("../chats-BcbxvPlj.mjs").then((n) => n.n).then((m) => m.appendMessage(chatId, logMsg));
1357
+ return request;
1066
1358
  })
1067
1359
  });
1068
1360
  const appRouter = AppRouter;