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.
- package/README.md +60 -77
- package/dist/adapter-discord/index.mjs +2 -2
- package/dist/{chats-Zd_HXDHx.mjs → chats-BcbxvPlj.mjs} +2 -2
- package/dist/{chats-Zd_HXDHx.mjs.map → chats-BcbxvPlj.mjs.map} +1 -1
- package/dist/{chats-DKgTeU7i.mjs → chats-CpRQrNHj.mjs} +2 -2
- package/dist/{chats-DKgTeU7i.mjs.map → chats-CpRQrNHj.mjs.map} +1 -1
- package/dist/cli/index.mjs +4 -3
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lite.mjs +48 -0
- package/dist/cli/lite.mjs.map +1 -1
- package/dist/daemon/index.mjs +311 -19
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/{lite-Dl7WXyaH.mjs → lite-DBUuHsX0.mjs} +2 -2
- package/dist/{lite-Dl7WXyaH.mjs.map → lite-DBUuHsX0.mjs.map} +1 -1
- package/dist/policy-utils-BvfOK6Ih.mjs +114 -0
- package/dist/policy-utils-BvfOK6Ih.mjs.map +1 -0
- package/dist/web/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
- package/dist/web/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
- package/dist/web/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
- package/dist/web/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
- package/dist/web/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
- package/dist/web/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
- package/dist/web/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
- package/dist/web/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
- package/dist/web/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
- package/dist/web/_app/version.json +1 -1
- package/dist/web/index.html +6 -6
- package/dist/{workspace-CSgfo_2J.mjs → workspace-BC1ahx4R.mjs} +13 -2
- package/dist/workspace-BC1ahx4R.mjs.map +1 -0
- package/docs/CLI_REFERENCE.md +35 -0
- package/docs/guides/sandbox_policies.md +12 -5
- package/package.json +1 -1
- package/web/.svelte-kit/ambient.d.ts +2 -6
- package/web/.svelte-kit/generated/server/internal.js +1 -1
- package/web/.svelte-kit/output/client/.vite/manifest.json +25 -25
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
- package/web/.svelte-kit/output/client/_app/version.json +1 -1
- package/web/.svelte-kit/output/server/chunks/internal.js +1 -1
- package/web/.svelte-kit/output/server/manifest-full.js +1 -1
- package/web/.svelte-kit/output/server/manifest.js +1 -1
- package/web/.svelte-kit/output/server/nodes/0.js +1 -1
- package/web/.svelte-kit/output/server/nodes/1.js +1 -1
- package/web/.svelte-kit/output/server/nodes/3.js +1 -1
- package/web/.svelte-kit/output/server/nodes/4.js +1 -1
- package/web/.svelte-kit/output/server/nodes/5.js +1 -1
- package/dist/web/_app/immutable/entry/start.oP1AgKhs.js +0 -1
- package/dist/workspace-CSgfo_2J.mjs.map +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.oP1AgKhs.js +0 -1
package/dist/daemon/index.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { C as
|
|
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-
|
|
4
|
-
import { n as exportLiteToEnvironment } from "../lite-
|
|
5
|
-
import { a as daemonEvents, i as DAEMON_EVENT_TYPING, o as emitTyping, r as DAEMON_EVENT_MESSAGE_APPENDED, t as appendMessage } from "../chats-
|
|
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
|
|
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)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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 =
|
|
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
|
|
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-
|
|
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-
|
|
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;
|