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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["fs","crypto","fs","fs"],"sources":["../../src/daemon/queue.ts","../../src/daemon/routers/slash-new.ts","../../src/daemon/routers/slash-command.ts","../../src/daemon/routers/utils.ts","../../src/daemon/routers/slash-stop.ts","../../src/daemon/routers/slash-interrupt.ts","../../src/daemon/routers.ts","../../src/daemon/auth.ts","../../src/shared/utils/env.ts","../../src/daemon/message.ts","../../src/daemon/utils/spawn.ts","../../src/daemon/cron.ts","../../src/daemon/router.ts","../../src/daemon/index.ts"],"sourcesContent":["export type Task<T = void> = (signal: AbortSignal) => Promise<T>;\n\ninterface QueueEntry<TPayload = string> {\n task: Task;\n payload?: TPayload | undefined;\n resolve: (value: void | PromiseLike<void>) => void;\n reject: (reason?: unknown) => void;\n}\n\nexport class Queue<TPayload = string> {\n private pending: QueueEntry<TPayload>[] = [];\n private isRunning = false;\n private currentController: AbortController | null = null;\n private currentPayload?: TPayload | undefined;\n\n enqueue(task: Task, payload?: TPayload): Promise<void> {\n return new Promise((resolve, reject) => {\n this.pending.push({ task, payload, resolve, reject });\n // We don't await processNext because we want enqueue to return the task's promise\n // and let processNext run in the background.\n this.processNext().catch(() => {});\n });\n }\n\n private async processNext() {\n if (this.isRunning || this.pending.length === 0) return;\n\n this.isRunning = true;\n const entry = this.pending.shift()!;\n this.currentController = new AbortController();\n this.currentPayload = entry.payload;\n\n try {\n await entry.task(this.currentController.signal);\n entry.resolve();\n } catch (error) {\n entry.reject(error);\n } finally {\n this.isRunning = false;\n this.currentController = null;\n this.currentPayload = undefined;\n // Continue processing the next item\n this.processNext().catch(() => {});\n }\n }\n\n abortCurrent(): void {\n if (this.currentController) {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n this.currentController.abort(error);\n }\n }\n\n getCurrentPayload(): TPayload | undefined {\n return this.currentPayload;\n }\n\n clear(reason: string = 'Task cleared'): void {\n const tasksToClear = [...this.pending];\n this.pending = [];\n for (const { reject } of tasksToClear) {\n const error = new Error(reason);\n error.name = 'AbortError';\n reject(error);\n }\n }\n\n extractPending(): TPayload[] {\n const extracted = this.pending\n .map((p) => p.payload)\n .filter((p): p is TPayload => p !== undefined);\n\n this.clear('Task extracted for batching');\n\n return extracted;\n }\n}\n\nconst directoryQueues = new Map<string, Queue>();\n\nexport function getQueue(dir: string): Queue {\n if (!directoryQueues.has(dir)) {\n directoryQueues.set(dir, new Queue());\n }\n return directoryQueues.get(dir)!;\n}\n","import type { RouterState } from './types.js';\n\nexport function slashNew(state: RouterState): RouterState {\n if (/^\\/new(\\s|$)/.test(state.message)) {\n const newMessage = state.message.replace(/^\\/new(\\s+|$)/, '').trim();\n return {\n ...state,\n message: newMessage,\n sessionId: crypto.randomUUID(),\n reply: '[@clawmini/slash-new] Starting a new session...',\n };\n }\n return state;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { RouterState } from './types.js';\nimport { getClawminiDir } from '../../shared/workspace.js';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\n\nexport async function slashCommand(state: RouterState): Promise<RouterState> {\n const commandsDir = path.resolve(getClawminiDir(), 'commands');\n let currentMessage = state.message;\n\n // Regex to match slash commands (e.g., /foo or /foo:bar) that appear as whole words.\n // We use lookbehind and lookahead to ensure it's bounded by whitespace or string start/end.\n const commandRegex = /(?<=^|\\s)\\/([a-zA-Z0-9_\\-:.]+)(?=\\s|$)/g;\n const matches = [...currentMessage.matchAll(commandRegex)];\n\n if (matches.length === 0) {\n return state;\n }\n\n for (const match of matches) {\n const fullMatch = match[0];\n const commandName = match[1];\n if (!commandName) continue;\n\n const targetPathMd = path.resolve(commandsDir, `${commandName}.md`);\n const targetPathTxt = path.resolve(commandsDir, `${commandName}.txt`);\n\n // Strict path traversal protection\n const baseTargetPath = path.resolve(commandsDir, commandName);\n if (!pathIsInsideDir(baseTargetPath, commandsDir)) {\n continue;\n }\n\n let content: string;\n\n try {\n content = await fs.readFile(targetPathMd, 'utf8');\n } catch {\n try {\n content = await fs.readFile(targetPathTxt, 'utf8');\n } catch {\n // If file doesn't exist or can't be read, leave it as is.\n continue;\n }\n }\n\n // Replace the command with the content. We only replace the exact occurrence.\n // Since replace replaces the first occurrence, and we are iterating over all matches,\n // it should replace them sequentially. If there are multiple identical commands,\n // it's fine, each will be replaced in turn.\n currentMessage = currentMessage.replace(fullMatch, content.trim());\n }\n\n return {\n ...state,\n message: currentMessage,\n };\n}\n","import type { RouterState } from './types.js';\n\nexport function createSlashActionRouter(\n command: string,\n action: NonNullable<RouterState['action']>,\n replyMessage: string\n) {\n return function (state: RouterState): RouterState {\n const regex = new RegExp(`^\\\\/${command}(\\\\s|$)`);\n if (regex.test(state.message)) {\n const replaceRegex = new RegExp(`^\\\\/${command}(\\\\s+|$)`);\n const newMessage = state.message.replace(replaceRegex, '').trim();\n return {\n ...state,\n message: newMessage,\n action,\n reply: replyMessage,\n };\n }\n return state;\n };\n}\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashStop = createSlashActionRouter('stop', 'stop', 'Stopping current task...');\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashInterrupt = createSlashActionRouter(\n 'interrupt',\n 'interrupt',\n 'Interrupting current task...'\n);\n","import { spawn } from 'node:child_process';\nimport type { RouterState } from './routers/types.js';\nimport { slashNew } from './routers/slash-new.js';\nimport { slashCommand } from './routers/slash-command.js';\nimport { slashStop } from './routers/slash-stop.js';\nimport { slashInterrupt } from './routers/slash-interrupt.js';\n\nexport async function executeRouterPipeline(\n initialState: RouterState,\n routers: string[]\n): Promise<RouterState> {\n let state = { ...initialState };\n\n for (const router of routers) {\n if (router === '@clawmini/slash-new') {\n state = slashNew(state);\n } else if (router === '@clawmini/slash-command') {\n state = await slashCommand(state);\n } else if (router === '@clawmini/slash-stop') {\n state = slashStop(state);\n } else if (router === '@clawmini/slash-interrupt') {\n state = slashInterrupt(state);\n } else {\n // Execute as custom shell command\n try {\n state = await executeCustomRouter(router, state);\n } catch (err) {\n // Silent failure handling: log but do not halt\n console.error(`Router error [${router}]:`, err);\n }\n }\n }\n\n return state;\n}\n\nasync function executeCustomRouter(command: string, state: RouterState): Promise<RouterState> {\n return new Promise((resolve, reject) => {\n // We run the command via shell\n const child = spawn(command, { shell: true });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (chunk) => {\n stdout += chunk.toString();\n });\n child.stderr.on('data', (chunk) => {\n stderr += chunk.toString();\n });\n\n // timeout fallback to avoid hanging indefinitely\n const timer = setTimeout(() => {\n child.kill();\n reject(new Error('Router execution timed out'));\n }, 10000);\n\n child.on('close', (code) => {\n clearTimeout(timer);\n if (code !== 0) {\n return reject(new Error(`Process exited with code ${code}. Stderr: ${stderr}`));\n }\n\n try {\n const result = JSON.parse(stdout);\n const newState = { ...state };\n\n if (typeof result.message === 'string') newState.message = result.message;\n if (typeof result.agent === 'string') newState.agentId = result.agent;\n if (typeof result.session === 'string') newState.sessionId = result.session;\n if (typeof result.env === 'object' && result.env !== null) {\n newState.env = { ...newState.env, ...result.env };\n }\n if (typeof result.reply === 'string') newState.reply = result.reply;\n if (typeof result.action === 'string') newState.action = result.action;\n\n resolve(newState);\n } catch (err) {\n reject(new Error(`Failed to parse router output: ${err}. Stdout: ${stdout}`));\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n\n // Write state to stdin\n const inputState = {\n message: state.message,\n chatId: state.chatId,\n agentId: state.agentId,\n sessionId: state.sessionId,\n env: state.env,\n action: state.action,\n };\n\n if (child.stdin) {\n child.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n child.stdin.write(JSON.stringify(inputState));\n child.stdin.end();\n }\n });\n}\n","import crypto from 'node:crypto';\nimport type { Settings } from '../shared/config.js';\n\n// In-memory secret generated on daemon startup.\n// Valid tokens will only last for the lifetime of the daemon process.\nconst DAEMON_SECRET = crypto.randomBytes(32);\n\nexport interface TokenPayload {\n chatId: string;\n agentId: string;\n sessionId: string;\n timestamp: number;\n}\n\nexport function generateToken(payload: TokenPayload): string {\n const payloadStr = Buffer.from(JSON.stringify(payload)).toString('base64');\n const hmac = crypto.createHmac('sha256', DAEMON_SECRET).update(payloadStr).digest('hex');\n return `${payloadStr}.${hmac}`;\n}\n\nexport function validateToken(token: string): TokenPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 2) return null;\n\n const [payloadStr, signature] = parts;\n if (!payloadStr || !signature) return null;\n\n const expectedHmac = crypto\n .createHmac('sha256', DAEMON_SECRET)\n .update(payloadStr)\n .digest('hex');\n\n const signatureBuffer = Buffer.from(signature, 'hex');\n const expectedHmacBuffer = Buffer.from(expectedHmac, 'hex');\n\n if (\n signatureBuffer.length !== expectedHmacBuffer.length ||\n !crypto.timingSafeEqual(signatureBuffer, expectedHmacBuffer)\n ) {\n return null;\n }\n\n const payloadJson = Buffer.from(payloadStr, 'base64').toString('utf8');\n return JSON.parse(payloadJson) as TokenPayload;\n } catch {\n return null;\n }\n}\n\nexport function getApiContext(settings?: Settings) {\n if (settings?.api === undefined) return null;\n let isApiEnabled = false;\n let apiHost = '127.0.0.1';\n let apiPort = 3000;\n let proxyHost: string | undefined = undefined;\n\n if (typeof settings.api === 'boolean') {\n isApiEnabled = settings.api;\n } else if (typeof settings.api === 'object') {\n isApiEnabled = true;\n apiHost = settings.api.host ?? '127.0.0.1';\n apiPort = settings.api.port ?? 3000;\n proxyHost = settings.api.proxy_host;\n }\n\n if (!isApiEnabled) return null;\n return { host: apiHost, port: apiPort, proxy_host: proxyHost };\n}\n","export function applyEnvOverrides(\n targetEnv: Record<string, string>,\n overrides?: Record<string, string | boolean>\n): void {\n if (!overrides) return;\n\n for (const [key, val] of Object.entries(overrides)) {\n if (val === true && process.env[key] !== undefined) {\n targetEnv[key] = process.env[key];\n } else if (typeof val === 'string') {\n targetEnv[key] = val;\n }\n }\n}\n\nexport function getActiveEnvKeys(\n ...envs: (Record<string, string | boolean> | undefined)[]\n): Set<string> {\n const keys = new Set<string>();\n for (const env of envs) {\n if (!env) continue;\n Object.entries(env).forEach(([key, val]) => {\n if (val === true || typeof val === 'string') keys.add(key);\n });\n }\n return keys;\n}\n","/* eslint-disable max-lines */\nimport path from 'node:path';\nimport { appendMessage, type UserMessage, type CommandLogMessage } from './chats.js';\nimport { getQueue } from './queue.js';\nimport { executeRouterPipeline } from './routers.js';\nimport type { RouterState } from './routers/types.js';\nimport {\n type Settings,\n type Agent,\n type AgentSessionSettings,\n type FallbackSchema,\n} from '../shared/config.js';\nimport {\n readChatSettings,\n writeChatSettings,\n readAgentSessionSettings,\n writeAgentSessionSettings,\n getAgent,\n getWorkspaceRoot,\n getActiveEnvironmentInfo,\n getEnvironmentPath,\n readEnvironment,\n} from '../shared/workspace.js';\nimport { getApiContext, generateToken } from './auth.js';\nimport { emitTyping } from './events.js';\nimport { applyEnvOverrides, getActiveEnvKeys } from '../shared/utils/env.js';\nimport { z } from 'zod';\n\ntype Fallback = z.infer<typeof FallbackSchema>;\n\nexport function calculateDelay(\n attempt: number,\n baseDelayMs: number,\n isFallback: boolean = false\n): number {\n const effectiveAttempt = isFallback ? attempt + 1 : attempt;\n if (effectiveAttempt <= 0) return 0;\n const delay = baseDelayMs * Math.pow(2, effectiveAttempt - 1);\n return Math.min(delay, 15000);\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport type RunCommandResult = {\n stdout: string;\n stderr: string;\n exitCode: number;\n};\n\nexport type RunCommandFn = (args: {\n command: string;\n cwd: string;\n env: Record<string, string>;\n stdin?: string | undefined;\n signal?: AbortSignal | undefined;\n}) => Promise<RunCommandResult>;\n\nasync function resolveSessionState(\n chatId: string,\n cwd: string,\n sessionId?: string,\n overrideAgentId?: string\n) {\n const chatSettings = await readChatSettings(chatId, cwd);\n const agentId =\n overrideAgentId ??\n (typeof chatSettings?.defaultAgent === 'string' ? chatSettings.defaultAgent : 'default');\n\n let targetSessionId = sessionId;\n if (!targetSessionId) {\n const sessions = chatSettings?.sessions || {};\n targetSessionId = sessions[agentId] || 'default';\n }\n\n const agentSessionSettings = await readAgentSessionSettings(agentId, targetSessionId, cwd);\n const isNewSession = !agentSessionSettings;\n\n return { chatSettings, agentId, targetSessionId, agentSessionSettings, isNewSession };\n}\n\nfunction prepareCommandAndEnv(\n agent: Agent,\n message: string,\n isNewSession: boolean,\n agentSessionSettings: AgentSessionSettings | null,\n fallback?: Fallback\n): { command: string; env: Record<string, string>; currentAgent: Agent } {\n const currentAgent: Agent = {\n ...agent,\n commands: {\n ...agent.commands,\n ...(fallback?.commands || {}),\n },\n env: {\n ...agent.env,\n ...(fallback?.env || {}),\n },\n };\n\n let command = currentAgent.commands?.new ?? '';\n const env = {\n ...process.env,\n CLAW_CLI_MESSAGE: message,\n } as Record<string, string>;\n\n applyEnvOverrides(env, currentAgent.env);\n\n if (!isNewSession && currentAgent.commands?.append) {\n command = currentAgent.commands.append;\n applyEnvOverrides(env, agentSessionSettings?.env);\n }\n\n return { command, env, currentAgent };\n}\n\nasync function runExtractionCommand(\n name: string,\n command: string,\n runCommand: RunCommandFn,\n cwd: string,\n env: Record<string, string>,\n mainResult: RunCommandResult,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n try {\n console.log(`Executing extraction command (${name}): ${command}`);\n const res = await runCommand({\n command,\n cwd,\n env,\n stdin: mainResult.stdout,\n signal,\n });\n if (res.exitCode === 0) {\n return { result: res.stdout.trim() };\n } else {\n return { error: `${name} failed: ${res.stderr}` };\n }\n } catch (e) {\n return { error: `${name} error: ${(e as Error).message}` };\n }\n}\n\n/**\n * Formats the environment prefix string by replacing placeholders with actual values.\n * Available placeholders:\n * - {WORKSPACE_DIR}: The root directory of the workspace.\n * - {AGENT_DIR}: The directory where the agent is executing.\n * - {ENV_DIR}: The directory of the active environment.\n * - {HOME_DIR}: The home directory of the current user.\n * - {ENV_ARGS}: The formatted environment arguments based on envFormat.\n */\nfunction formatEnvironmentPrefix(\n prefix: string,\n replacements: {\n targetPath: string;\n executionCwd: string;\n envDir: string;\n envArgs: string;\n }\n): string {\n const map: Record<string, string> = {\n '{WORKSPACE_DIR}': replacements.targetPath,\n '{AGENT_DIR}': replacements.executionCwd,\n '{ENV_DIR}': replacements.envDir,\n '{HOME_DIR}': process.env.HOME || '',\n '{ENV_ARGS}': replacements.envArgs,\n };\n return prefix.replace(\n /{(WORKSPACE_DIR|AGENT_DIR|ENV_DIR|HOME_DIR|ENV_ARGS)}/g,\n (match) => map[match] || match\n );\n}\n\nexport async function executeDirectMessage(\n chatId: string,\n state: RouterState,\n settings: Settings | undefined,\n cwd: string,\n runCommand: RunCommandFn,\n noWait: boolean = true,\n userMessageContent?: string\n): Promise<void> {\n const userMsg: UserMessage = {\n id: crypto.randomUUID(),\n role: 'user',\n content: userMessageContent ?? state.message,\n timestamp: new Date().toISOString(),\n };\n await appendMessage(chatId, userMsg);\n\n if (state.reply) {\n const routerLogMsg: CommandLogMessage = {\n id: crypto.randomUUID(),\n messageId: userMsg.id,\n role: 'log',\n source: 'router',\n content: state.reply,\n stderr: '',\n timestamp: new Date().toISOString(),\n command: 'router',\n cwd,\n exitCode: 0,\n ...(state.reply.includes('NO_REPLY_NECESSARY') ? { level: 'verbose' as const } : {}),\n };\n await appendMessage(chatId, routerLogMsg);\n }\n\n if (!state.message.trim() && state.action !== 'stop' && state.action !== 'interrupt') {\n return;\n }\n\n const queue = getQueue(cwd);\n\n if (state.action === 'stop') {\n queue.abortCurrent();\n queue.clear();\n return;\n }\n\n if (state.action === 'interrupt') {\n const currentPayload = queue.getCurrentPayload();\n queue.abortCurrent();\n\n const extracted = queue.extractPending();\n const payloads = currentPayload ? [currentPayload, ...extracted] : extracted;\n\n if (payloads.length > 0) {\n const pendingText = payloads.map((text) => `<message>\\n${text}\\n</message>`).join('\\n\\n');\n state.message = `${pendingText}\\n\\n<message>\\n${state.message}\\n</message>`.trim();\n }\n }\n\n if (!state.message.trim()) {\n return;\n }\n\n const routerEnv = state.env ?? {};\n\n const taskPromise = queue.enqueue(async (signal) => {\n const {\n agentId,\n agentSessionSettings,\n isNewSession,\n targetSessionId: finalSessionId,\n } = await resolveSessionState(chatId, cwd, state.sessionId, state.agentId);\n\n let mergedAgent: Agent = settings?.defaultAgent || {};\n if (agentId !== 'default') {\n try {\n const customAgent = await getAgent(agentId, cwd);\n if (customAgent) {\n mergedAgent = {\n ...mergedAgent,\n ...customAgent,\n commands: { ...mergedAgent.commands, ...customAgent.commands },\n env: { ...mergedAgent.env, ...customAgent.env },\n };\n }\n } catch {\n // Fall back to default if agent not found\n }\n }\n\n const fallbacks = mergedAgent.fallbacks || [];\n const executionConfigs: { fallback?: Fallback; retries: number; delayMs: number }[] = [\n { retries: 0, delayMs: 1000 },\n ...fallbacks.map((f) => ({ fallback: f, retries: f.retries, delayMs: f.delayMs })),\n ];\n\n const workspaceRoot = getWorkspaceRoot(cwd);\n let executionCwd = cwd;\n if (mergedAgent.directory) {\n executionCwd = path.resolve(workspaceRoot, mergedAgent.directory);\n } else if (agentId !== 'default') {\n executionCwd = path.resolve(workspaceRoot, agentId);\n }\n\n let lastLogMsg: CommandLogMessage | undefined;\n let success = false;\n\n for (let configIdx = 0; configIdx < executionConfigs.length; configIdx++) {\n const config = executionConfigs[configIdx]!;\n const isFallbackConfig = configIdx > 0;\n for (let attempt = 0; attempt <= config.retries; attempt++) {\n const delay = calculateDelay(attempt, config.delayMs, isFallbackConfig);\n if (delay > 0) {\n const retryLogMsg: CommandLogMessage = {\n id: crypto.randomUUID(),\n messageId: userMsg.id,\n role: 'log',\n content: `Error running agent, retrying in ${Math.round(delay / 1000)} seconds...`,\n stderr: '',\n timestamp: new Date().toISOString(),\n command: 'retry-delay',\n cwd: executionCwd,\n exitCode: 0,\n };\n await appendMessage(chatId, retryLogMsg);\n await sleep(delay);\n }\n\n const {\n env,\n currentAgent,\n command: initialCommand,\n } = prepareCommandAndEnv(\n mergedAgent,\n state.message,\n isNewSession,\n agentSessionSettings,\n config.fallback\n );\n let command = initialCommand;\n\n if (!command) {\n continue;\n }\n\n const agentSpecificEnv = getActiveEnvKeys(\n currentAgent.env,\n !isNewSession ? agentSessionSettings?.env : undefined\n );\n agentSpecificEnv.add('CLAW_CLI_MESSAGE');\n\n Object.assign(env, routerEnv);\n Object.keys(routerEnv).forEach((k) => agentSpecificEnv.add(k));\n\n const apiCtx = getApiContext(settings);\n if (apiCtx) {\n const proxyUrl = apiCtx.proxy_host\n ? `${apiCtx.proxy_host}:${apiCtx.port}`\n : `http://${apiCtx.host}:${apiCtx.port}`;\n env['CLAW_API_URL'] = proxyUrl;\n agentSpecificEnv.add('CLAW_API_URL');\n\n const token = generateToken({\n chatId,\n agentId,\n sessionId: finalSessionId,\n timestamp: Date.now(),\n });\n env['CLAW_API_TOKEN'] = token;\n agentSpecificEnv.add('CLAW_API_TOKEN');\n }\n\n const activeEnvInfo = await getActiveEnvironmentInfo(executionCwd, cwd);\n if (activeEnvInfo) {\n const activeEnvName = activeEnvInfo.name;\n const activeEnv = await readEnvironment(activeEnvName, cwd);\n\n if (activeEnv?.env) {\n for (const [key, value] of Object.entries(activeEnv.env)) {\n if (value === false) {\n delete env[key];\n agentSpecificEnv.delete(key);\n } else {\n let interpolatedValue = String(value);\n interpolatedValue = interpolatedValue.replace(/\\{PATH\\}/g, process.env.PATH || '');\n interpolatedValue = interpolatedValue.replace(\n /\\{ENV_DIR\\}/g,\n getEnvironmentPath(activeEnvName, cwd)\n );\n interpolatedValue = interpolatedValue.replace(\n /\\{WORKSPACE_DIR\\}/g,\n activeEnvInfo.targetPath\n );\n env[key] = interpolatedValue;\n agentSpecificEnv.add(key);\n }\n }\n }\n\n if (activeEnv?.prefix) {\n const envArgs = Array.from(agentSpecificEnv)\n .map((key) => {\n if (activeEnv.envFormat) {\n return activeEnv.envFormat.replace('{key}', key);\n }\n return key;\n })\n .join(' ');\n\n const prefixReplaced = formatEnvironmentPrefix(activeEnv.prefix, {\n targetPath: activeEnvInfo.targetPath,\n executionCwd,\n envDir: getEnvironmentPath(activeEnvName, cwd),\n envArgs,\n });\n\n if (prefixReplaced.includes('{COMMAND}')) {\n command = prefixReplaced.replace('{COMMAND}', command);\n } else {\n command = `${prefixReplaced} ${command}`;\n }\n }\n }\n\n console.log(`Executing command: ${command}`);\n let mainResult;\n const typingInterval = setInterval(() => {\n emitTyping(chatId);\n }, 5000);\n try {\n mainResult = await runCommand({ command, cwd: executionCwd, env, signal });\n } finally {\n clearInterval(typingInterval);\n }\n\n const logMsg: CommandLogMessage = {\n id: crypto.randomUUID(),\n messageId: userMsg.id,\n role: 'log',\n content: mainResult.stdout,\n stdout: mainResult.stdout,\n stderr: '',\n timestamp: new Date().toISOString(),\n command,\n cwd: executionCwd,\n exitCode: mainResult.exitCode,\n ...(mainResult.stdout.includes('NO_REPLY_NECESSARY')\n ? { level: 'verbose' as const }\n : {}),\n };\n\n const errors: string[] = [];\n if (mainResult.stderr) {\n errors.push(mainResult.stderr);\n }\n\n let currentSuccess = mainResult.exitCode === 0;\n\n if (currentSuccess) {\n if (currentAgent.commands?.getMessageContent) {\n const { result, error } = await runExtractionCommand(\n 'getMessageContent',\n currentAgent.commands.getMessageContent,\n runCommand,\n executionCwd,\n env,\n mainResult,\n signal\n );\n if (result !== undefined) {\n logMsg.content = result;\n logMsg.stdout = mainResult.stdout;\n if (result.includes('NO_REPLY_NECESSARY')) {\n logMsg.level = 'verbose';\n } else {\n delete logMsg.level;\n }\n if (result.trim() === '') {\n currentSuccess = false;\n }\n }\n if (error) {\n errors.push(error);\n }\n }\n }\n\n logMsg.stderr = errors.join('\\n\\n');\n lastLogMsg = logMsg;\n\n if (currentSuccess) {\n success = true;\n if (isNewSession && currentAgent.commands?.getSessionId) {\n const { result, error } = await runExtractionCommand(\n 'getSessionId',\n currentAgent.commands.getSessionId,\n runCommand,\n executionCwd,\n env,\n mainResult,\n signal\n );\n if (result) {\n await writeAgentSessionSettings(\n agentId,\n finalSessionId,\n { env: { SESSION_ID: result } },\n cwd\n );\n }\n if (error) {\n // We don't fail the whole thing for getSessionId error, but we log it.\n logMsg.stderr = [logMsg.stderr, error].filter(Boolean).join('\\n\\n');\n }\n }\n break;\n }\n }\n if (success) break;\n }\n\n if (lastLogMsg) {\n await appendMessage(chatId, lastLogMsg);\n }\n }, state.message);\n\n if (!noWait) {\n await taskPromise;\n } else {\n taskPromise.catch((err) => {\n if (err.name !== 'AbortError') {\n console.error('Task execution error:', err);\n }\n });\n }\n}\n\nexport async function getInitialRouterState(\n chatId: string,\n message: string,\n cwd: string = process.cwd(),\n overrideAgentId?: string,\n overrideSessionId?: string\n): Promise<RouterState> {\n const chatSettings = (await readChatSettings(chatId, cwd)) ?? {};\n const agentId = overrideAgentId ?? chatSettings.defaultAgent ?? 'default';\n const sessionId = overrideSessionId ?? chatSettings.sessions?.[agentId] ?? 'default';\n\n return {\n message,\n chatId,\n agentId,\n sessionId,\n env: {},\n };\n}\n\nexport async function handleUserMessage(\n chatId: string,\n message: string,\n settings: Settings | undefined,\n cwd: string = process.cwd(),\n noWait: boolean = false,\n runCommand: RunCommandFn,\n sessionId?: string,\n overrideAgentId?: string\n): Promise<void> {\n const chatSettings = (await readChatSettings(chatId, cwd)) ?? {};\n\n if (overrideAgentId && chatSettings.defaultAgent !== overrideAgentId) {\n chatSettings.defaultAgent = overrideAgentId;\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n const initialState = await getInitialRouterState(\n chatId,\n message,\n cwd,\n overrideAgentId,\n sessionId\n );\n const initialAgent = initialState.agentId;\n\n const routers = chatSettings.routers ?? settings?.routers ?? [];\n\n const finalState = await executeRouterPipeline(initialState, routers);\n\n const finalMessage = finalState.message;\n const finalAgentId = finalState.agentId;\n const finalSessionId = finalState.sessionId ?? crypto.randomUUID();\n const routerEnv = finalState.env ?? {};\n\n const currentAgentId = finalAgentId ?? chatSettings.defaultAgent ?? 'default';\n\n let settingsChanged = false;\n if (finalAgentId && finalAgentId !== initialAgent) {\n chatSettings.defaultAgent = finalAgentId;\n settingsChanged = true;\n }\n\n if (finalSessionId && chatSettings.sessions?.[currentAgentId] !== finalSessionId) {\n chatSettings.sessions = chatSettings.sessions || {};\n chatSettings.sessions[currentAgentId] = finalSessionId;\n settingsChanged = true;\n }\n\n if (settingsChanged) {\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n const directState: RouterState = {\n message: finalMessage,\n chatId,\n env: routerEnv,\n };\n if (finalAgentId !== undefined) directState.agentId = finalAgentId;\n if (finalSessionId !== undefined) directState.sessionId = finalSessionId;\n if (finalState.reply !== undefined) directState.reply = finalState.reply;\n if (finalState.action !== undefined) directState.action = finalState.action;\n\n await executeDirectMessage(chatId, directState, settings, cwd, runCommand, noWait, message);\n}\n","import { spawn } from 'node:child_process';\nimport type { RunCommandFn } from '../message.js';\n\nexport const runCommand: RunCommandFn &\n ((\n args: Parameters<RunCommandFn>[0] & { logToTerminal?: boolean }\n ) => ReturnType<RunCommandFn>) = async ({\n command,\n cwd,\n env,\n stdin,\n signal,\n logToTerminal,\n}: Parameters<RunCommandFn>[0] & { logToTerminal?: boolean }) => {\n return new Promise<{ stdout: string; stderr: string; exitCode: number }>((resolve, reject) => {\n const p = spawn(command, { shell: true, cwd, env, signal });\n\n if (stdin && p.stdin) {\n p.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n p.stdin.write(stdin);\n p.stdin.end();\n }\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n if (logToTerminal && !stdin) {\n process.stdout.write(data);\n }\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n if (logToTerminal && !stdin) {\n process.stderr.write(data);\n }\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n if (err.name === 'AbortError') {\n reject(err);\n return;\n }\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n};\n","// @ts-expect-error - node-schedule types are missing\nimport schedule from 'node-schedule';\nimport { listChats } from '../shared/chats.js';\nimport { readChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { executeDirectMessage, getInitialRouterState } from './message.js';\nimport type { CronJob, Settings } from '../shared/config.js';\nimport fs from 'node:fs/promises';\nimport { getSettingsPath } from '../shared/workspace.js';\nimport { applyEnvOverrides } from '../shared/utils/env.js';\nimport { runCommand } from './utils/spawn.js';\n\nexport class CronManager {\n private jobs = new Map<string, schedule.Job>();\n\n private getJobKey(chatId: string, jobId: string) {\n return `${chatId}::${jobId}`;\n }\n\n async init() {\n const chats = await listChats();\n for (const chatId of chats) {\n const settings = await readChatSettings(chatId);\n if (settings?.jobs) {\n for (const job of settings.jobs) {\n try {\n this.scheduleJob(chatId, job);\n } catch (err) {\n console.error(\n `Failed to initialize job ${job.id} for chat ${chatId}:`,\n err instanceof Error ? err.message : err\n );\n }\n }\n }\n }\n }\n\n scheduleJob(chatId: string, job: CronJob) {\n this.unscheduleJob(chatId, job.id);\n\n let rule: string | Date;\n let isOneOff = false;\n\n if ('cron' in job.schedule) {\n rule = (job.schedule as { cron: string }).cron;\n } else if ('every' in job.schedule) {\n const everyStr = (job.schedule as { every: string }).every;\n const match = everyStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?)$/i);\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n if (unit.startsWith('m')) {\n rule = `*/${val} * * * *`;\n } else if (unit.startsWith('h')) {\n rule = `0 */${val} * * *`;\n } else if (unit.startsWith('d')) {\n rule = `0 0 */${val} * *`;\n } else {\n rule = everyStr;\n }\n } else {\n rule = everyStr;\n }\n } else if ('at' in job.schedule) {\n const atStr = (job.schedule as { at: string }).at;\n const match = atStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?|s|sec|seconds?)$/i);\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n let ms = 0;\n if (unit.startsWith('s')) ms = val * 1000;\n else if (unit.startsWith('m')) ms = val * 60 * 1000;\n else if (unit.startsWith('h')) ms = val * 60 * 60 * 1000;\n else if (unit.startsWith('d')) ms = val * 24 * 60 * 60 * 1000;\n rule = new Date(Date.now() + ms);\n } else {\n rule = new Date(atStr);\n if (isNaN(rule.getTime())) {\n throw new Error(`Invalid date format for 'at' schedule: ${atStr}`);\n }\n }\n isOneOff = true;\n } else {\n console.warn(`Unknown schedule format for job ${job.id}`);\n return;\n }\n\n try {\n const scheduledJob = schedule.scheduleJob(rule, async () => {\n await this.executeJob(chatId, job, isOneOff);\n });\n if (scheduledJob) {\n this.jobs.set(this.getJobKey(chatId, job.id), scheduledJob);\n }\n } catch (err) {\n console.error(`Failed to schedule job ${job.id} for chat ${chatId}:`, err);\n }\n }\n\n unscheduleJob(chatId: string, jobId: string) {\n const key = this.getJobKey(chatId, jobId);\n const job = this.jobs.get(key);\n if (job) {\n job.cancel();\n this.jobs.delete(key);\n }\n }\n\n private async executeJob(chatId: string, job: CronJob, isOneOff: boolean) {\n try {\n const settingsPath = getSettingsPath();\n let globalSettings: Settings | undefined;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n globalSettings = JSON.parse(settingsStr) as Settings;\n } catch {\n globalSettings = undefined;\n }\n\n const overrideSessionId = job.session?.type === 'new' ? crypto.randomUUID() : undefined;\n const routerState = await getInitialRouterState(\n chatId,\n job.message,\n process.cwd(),\n job.agentId,\n overrideSessionId\n );\n\n if (job.env !== undefined) {\n routerState.env = routerState.env || {};\n applyEnvOverrides(routerState.env, job.env);\n }\n if (job.reply !== undefined) routerState.reply = job.reply;\n\n await executeDirectMessage(\n chatId,\n routerState,\n globalSettings,\n process.cwd(),\n runCommand,\n false,\n job.message\n );\n\n if (isOneOff) {\n const chatSettings = await readChatSettings(chatId);\n if (chatSettings && chatSettings.jobs) {\n chatSettings.jobs = chatSettings.jobs.filter((j) => j.id !== job.id);\n await writeChatSettings(chatId, chatSettings);\n }\n this.unscheduleJob(chatId, job.id);\n }\n } catch (err) {\n console.error(`Error executing cron job ${job.id} for chat ${chatId}:`, err);\n }\n }\n}\n\nexport const cronManager = new CronManager();\n","/* eslint-disable max-lines */\nimport { initTRPC, TRPCError } from '@trpc/server';\nimport { z } from 'zod';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, DAEMON_EVENT_TYPING } from './events.js';\nimport {\n getSettingsPath,\n readChatSettings,\n writeChatSettings,\n getAgent,\n getWorkspaceRoot,\n} from '../shared/workspace.js';\nimport { CronJobSchema } from '../shared/config.js';\nimport { handleUserMessage } from './message.js';\nimport { getDefaultChatId, getMessages } from './chats.js';\nimport { runCommand } from './utils/spawn.js';\nimport { cronManager } from './cron.js';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { TokenPayload } from './auth.js';\n\nexport interface Context {\n req?: IncomingMessage | undefined;\n res?: ServerResponse | undefined;\n isApiServer?: boolean | undefined;\n tokenPayload?: TokenPayload | null | undefined;\n}\n\nconst t = initTRPC.context<Context>().create();\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n\nconst apiAuthMiddleware = t.middleware(({ ctx, next }) => {\n if (ctx.isApiServer) {\n if (!ctx.tokenPayload) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing or invalid token' });\n }\n }\n return next({\n ctx: {\n ...ctx,\n tokenPayload: ctx.tokenPayload,\n },\n });\n});\n\nexport const apiProcedure = t.procedure.use(apiAuthMiddleware);\n\nexport async function getUniquePath(p: string): Promise<string> {\n let currentPath = p;\n let counter = 1;\n while (true) {\n try {\n await fs.stat(currentPath);\n const ext = path.extname(p);\n const base = path.basename(p, ext);\n currentPath = path.join(path.dirname(p), `${base}-${counter}${ext}`);\n counter++;\n } catch {\n return currentPath;\n }\n }\n}\n\nasync function resolveAgentDir(\n agentId: string | undefined | null,\n workspaceRoot: string\n): Promise<string> {\n if (agentId && agentId !== 'default') {\n try {\n const agent = await getAgent(agentId, workspaceRoot);\n if (agent && agent.directory) {\n return path.resolve(workspaceRoot, agent.directory);\n }\n } catch (err: unknown) {\n console.warn(`Could not load custom agent '${agentId}' for resolving directory:`, err);\n }\n return path.resolve(workspaceRoot, agentId);\n }\n return workspaceRoot;\n}\n\nasync function resolveAndCheckChatId(ctx: Context, inputChatId?: string): Promise<string> {\n const chatId =\n inputChatId ??\n (ctx.isApiServer && ctx.tokenPayload ? ctx.tokenPayload.chatId : await getDefaultChatId());\n\n if (ctx.isApiServer && ctx.tokenPayload) {\n if (ctx.tokenPayload.chatId !== chatId) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Token not authorized for this chat' });\n }\n }\n\n return chatId;\n}\n\nasync function getAgentFilesDir(\n agentId: string | undefined,\n chatId: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n settings: any,\n workspaceRoot: string\n): Promise<string> {\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n let agentFilesDir = settings?.defaultAgent?.files || './attachments';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n\n if (targetAgentId !== 'default') {\n try {\n const customAgent = await getAgent(targetAgentId, workspaceRoot);\n if (customAgent?.files) {\n agentFilesDir = customAgent.files;\n }\n } catch (err: unknown) {\n console.warn(\n `Could not load custom agent '${targetAgentId}' for resolving files directory:`,\n err\n );\n }\n }\n\n return path.resolve(agentDir, agentFilesDir);\n}\n\nasync function validateAttachments(files: string[]): Promise<void> {\n const { pathIsInsideDir } = await import('../shared/utils/fs.js');\n const { getClawminiDir } = await import('../shared/workspace.js');\n const tmpDir = path.join(getClawminiDir(process.cwd()), 'tmp');\n\n for (const file of files) {\n const absoluteFile = path.resolve(process.cwd(), file);\n if (!pathIsInsideDir(absoluteFile, tmpDir)) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be inside the temporary directory.',\n });\n }\n try {\n await fs.access(absoluteFile);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n }\n}\n\nasync function validateLogFile(\n file: string,\n agentDir: string,\n workspaceRoot: string\n): Promise<string> {\n const { pathIsInsideDir } = await import('../shared/utils/fs.js');\n // The agent sends paths relative to its working directory.\n // We resolve to an absolute path to verify it is within the agent's directory.\n const resolvedPath = path.resolve(agentDir, file);\n\n if (!pathIsInsideDir(resolvedPath, agentDir, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be within the agent workspace.',\n });\n }\n\n try {\n await fs.access(resolvedPath);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n\n // Convert the absolute path to a path relative to the WORKSPACE directory.\n // This allows adapters (like discord-adapter) to easily resolve it against their own view of the workspace.\n return path.relative(workspaceRoot, resolvedPath);\n}\n\nconst AppRouter = router({\n sendMessage: apiProcedure\n .input(\n z.object({\n type: z.literal('send-message'),\n client: z.literal('cli'),\n data: z.object({\n message: z.string(),\n chatId: z.string().optional(),\n sessionId: z.string().optional(),\n agentId: z.string().optional(),\n noWait: z.boolean().optional(),\n files: z.array(z.string()).optional(),\n adapter: z.string().optional(),\n }),\n })\n )\n .mutation(async ({ input, ctx }) => {\n let message = input.data.message;\n const chatId = await resolveAndCheckChatId(ctx, input.data.chatId);\n const noWait = input.data.noWait ?? false;\n const sessionId = input.data.sessionId;\n const agentId = input.data.agentId;\n const settingsPath = getSettingsPath();\n\n let settings;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n settings = JSON.parse(settingsStr);\n } catch (err) {\n throw new Error(`Failed to read settings from ${settingsPath}: ${err}`, { cause: err });\n }\n\n const files = input.data.files;\n if (files && files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n const absoluteFilesDir = await getAgentFilesDir(agentId, chatId, settings, workspaceRoot);\n\n const adapterNamespace = input.data.adapter || 'cli';\n const targetDir = path.join(absoluteFilesDir, adapterNamespace);\n\n const { pathIsInsideDir } = await import('../shared/utils/fs.js');\n\n if (!pathIsInsideDir(targetDir, workspaceRoot, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Target directory must be within the workspace.',\n });\n }\n\n await validateAttachments(files);\n\n await fs.mkdir(targetDir, { recursive: true });\n\n const finalPaths: string[] = [];\n for (const file of files) {\n const fileName = path.basename(file);\n const targetPath = await getUniquePath(path.join(targetDir, fileName));\n\n try {\n await fs.rename(file, targetPath);\n } catch {\n await fs.copyFile(file, targetPath);\n await fs.unlink(file);\n }\n\n finalPaths.push(path.relative(agentDir, targetPath));\n }\n\n const fileList = `Attached files:\\n${finalPaths.map((p) => `- ${p}`).join('\\n')}`;\n message = message ? `${message}\\n\\n${fileList}` : fileList;\n }\n\n await handleUserMessage(\n chatId,\n message,\n settings,\n undefined,\n noWait,\n (args) => runCommand({ ...args, logToTerminal: true }),\n sessionId,\n agentId\n );\n\n return { success: true };\n }),\n getMessages: apiProcedure\n .input(z.object({ chatId: z.string().optional(), limit: z.number().optional() }))\n .query(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n return getMessages(chatId, input.limit);\n }),\n waitForMessages: apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n lastMessageId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, ctx, signal }) {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n\n // 1. Check if there are already new messages\n if (input.lastMessageId) {\n const messages = await getMessages(chatId);\n const lastIndex = messages.findIndex((m) => m.id === input.lastMessageId);\n if (lastIndex !== -1 && lastIndex < messages.length - 1) {\n yield messages.slice(lastIndex + 1);\n }\n }\n\n // 2. Listen for new messages\n const { on } = await import('node:events');\n try {\n for await (const [event] of on(daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, { signal })) {\n if (event.chatId === chatId) {\n yield [event.message];\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n }),\n waitForTyping: apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, ctx, signal }) {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n\n const { on } = await import('node:events');\n try {\n for await (const [event] of on(daemonEvents, DAEMON_EVENT_TYPING, { signal })) {\n if (event.chatId === chatId) {\n yield event;\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n }),\n ping: publicProcedure.query(() => {\n return { status: 'ok' };\n }),\n shutdown: publicProcedure.mutation(() => {\n // Schedule a shutdown shortly after the response is sent\n setTimeout(() => {\n console.log('Shutting down daemon...');\n process.kill(process.pid, 'SIGTERM');\n }, 100);\n return { success: true };\n }),\n logMessage: apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n message: z.string().optional(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n\n const filePaths: string[] = [];\n if (input.files && input.files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n\n for (const file of input.files) {\n const validPath = await validateLogFile(file, agentDir, workspaceRoot);\n filePaths.push(validPath);\n }\n }\n\n const filesArgStr = filePaths.map((p) => ` --file ${p}`).join('');\n const messageStr = input.message || '';\n const logMsg: import('./chats.js').CommandLogMessage = {\n id,\n messageId: id,\n role: 'log',\n source: 'router',\n content: messageStr,\n stderr: '',\n timestamp,\n command: `clawmini-lite log${filesArgStr}`,\n cwd: process.cwd(),\n exitCode: 0,\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await import('./chats.js').then((m) => m.appendMessage(chatId, logMsg));\n return { success: true };\n }),\n listCronJobs: apiProcedure\n .input(z.object({ chatId: z.string().optional() }))\n .query(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const settings = await readChatSettings(chatId);\n return settings?.jobs ?? [];\n }),\n addCronJob: apiProcedure\n .input(z.object({ chatId: z.string().optional(), job: CronJobSchema }))\n .mutation(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const settings = (await readChatSettings(chatId)) || {};\n const cronJobs = settings.jobs ?? [];\n const existingIndex = cronJobs.findIndex((j) => j.id === input.job.id);\n if (existingIndex >= 0) {\n cronJobs[existingIndex] = input.job;\n } else {\n cronJobs.push(input.job);\n }\n settings.jobs = cronJobs;\n await writeChatSettings(chatId, settings);\n cronManager.scheduleJob(chatId, input.job);\n return { success: true };\n }),\n deleteCronJob: apiProcedure\n .input(z.object({ chatId: z.string().optional(), id: z.string() }))\n .mutation(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const settings = await readChatSettings(chatId);\n if (!settings || !settings.jobs) {\n return { success: true, deleted: false };\n }\n const initialLength = settings.jobs.length;\n settings.jobs = settings.jobs.filter((j) => j.id !== input.id);\n if (settings.jobs.length !== initialLength) {\n await writeChatSettings(chatId, settings);\n cronManager.unscheduleJob(chatId, input.id);\n return { success: true, deleted: true };\n }\n return { success: true, deleted: false };\n }),\n});\n\nexport type AppRouter = typeof AppRouter;\nexport const appRouter = AppRouter;\n","import http from 'node:http';\nimport net from 'node:net';\nimport fs from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { createHTTPHandler } from '@trpc/server/adapters/standalone';\nimport { appRouter } from './router.js';\nimport {\n getSocketPath,\n getClawminiDir,\n getSettingsPath,\n readSettings,\n readEnvironment,\n getEnvironmentPath,\n getWorkspaceRoot,\n} from '../shared/workspace.js';\nimport { cronManager } from './cron.js';\nimport { SettingsSchema } from '../shared/config.js';\nimport { validateToken, getApiContext } from './auth.js';\nimport path from 'node:path';\nimport { exportLiteToEnvironment } from '../shared/lite.js';\n\nexport async function initDaemon() {\n const socketPath = getSocketPath();\n const clawminiDir = getClawminiDir();\n\n // Ensure the .clawmini directory exists\n if (!fs.existsSync(clawminiDir)) {\n throw new Error(`${clawminiDir} does not exist`);\n }\n\n // Read settings to check if API is enabled\n const settingsPath = getSettingsPath();\n let apiCtx: ReturnType<typeof getApiContext> = null;\n\n if (fs.existsSync(settingsPath)) {\n try {\n const settingsStr = fs.readFileSync(settingsPath, 'utf8');\n const settings = JSON.parse(settingsStr);\n const parsed = SettingsSchema.safeParse(settings);\n if (parsed.success) {\n apiCtx = getApiContext(parsed.data);\n }\n } catch (err) {\n console.warn(`Failed to read or parse settings from ${settingsPath}:`, err);\n }\n }\n\n const runHooks = async (hookType: 'up' | 'down') => {\n try {\n const currentSettings = await readSettings();\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n if (!currentSettings?.environments) return;\n for (const [envPath, envName] of Object.entries(currentSettings.environments)) {\n try {\n const envConfig = await readEnvironment(envName);\n const envDir = getEnvironmentPath(envName);\n const affectedDir = path.resolve(workspaceRoot, envPath);\n\n // Try to export clawmini-lite to the environment directory\n if (hookType === 'up' && envConfig) {\n await exportLiteToEnvironment(envName, envConfig, affectedDir);\n }\n\n const command = envConfig?.[hookType];\n if (command) {\n console.log(`Executing '${hookType}' hook for environment '${envName}': ${command}`);\n execSync(command, {\n cwd: affectedDir,\n stdio: 'inherit',\n env: { ...process.env, ENV_DIR: envDir },\n timeout: hookType === 'down' ? 10000 : undefined,\n });\n }\n } catch (err) {\n console.error(`Failed to execute '${hookType}' hook for environment '${envName}':`, err);\n if (hookType === 'up') throw err;\n }\n }\n } catch (err) {\n console.error(`Failed to run '${hookType}' hooks:`, err);\n if (hookType === 'up') throw err;\n }\n };\n\n // Ensure the old socket file is removed, but first check if another daemon is actively listening\n if (fs.existsSync(socketPath)) {\n const isSocketInUse = await new Promise<boolean>((resolve) => {\n const client = net.createConnection({ path: socketPath });\n client.on('connect', () => {\n client.destroy();\n resolve(true);\n });\n client.on('error', () => {\n resolve(false);\n });\n });\n\n if (isSocketInUse) {\n console.log('Daemon is already running (socket is active). Exiting.');\n process.exit(0);\n }\n\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore\n }\n }\n\n let isReady = false;\n let readyPromiseResolve: () => void;\n const readyPromise = new Promise<void>((resolve) => {\n readyPromiseResolve = resolve;\n });\n\n const handler = createHTTPHandler({\n router: appRouter,\n createContext: ({ req, res }) => ({ req, res, isApiServer: false }),\n });\n\n const server = http.createServer(async (req, res) => {\n if (!isReady) {\n await readyPromise;\n }\n // Only accept POST requests on /trpc/ path if needed, but since we are running over Unix socket, we map directly\n handler(req, res);\n });\n\n await new Promise<void>((resolve, reject) => {\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log('Daemon is already running (socket bind failed). Exiting.');\n process.exit(0);\n }\n reject(err);\n });\n server.listen(socketPath, () => {\n console.log(`Daemon initialized and listening on ${socketPath}`);\n resolve();\n });\n });\n\n await runHooks('up');\n\n isReady = true;\n readyPromiseResolve!();\n\n // Initialize cron jobs\n cronManager.init().catch((err) => {\n console.error('Failed to initialize cron manager:', err);\n });\n\n let apiServer: http.Server | undefined;\n if (apiCtx) {\n const apiHandler = createHTTPHandler({\n router: appRouter,\n createContext: ({ req, res }) => {\n let tokenPayload = null;\n const authHeader = req.headers.authorization;\n if (authHeader && authHeader.startsWith('Bearer ')) {\n const token = authHeader.substring(7);\n tokenPayload = validateToken(token);\n }\n return { req, res, isApiServer: true, tokenPayload };\n },\n });\n\n apiServer = http.createServer((req, res) => {\n apiHandler(req, res);\n });\n\n const host = apiCtx.host;\n const port = apiCtx.port;\n apiServer.listen(port, host, () => {\n console.log(`Daemon HTTP API initialized and listening on http://${host}:${port}`);\n });\n }\n\n let isShuttingDown = false;\n const shutdown = async () => {\n if (isShuttingDown) return;\n isShuttingDown = true;\n console.log('Daemon shutting down...');\n\n await runHooks('down');\n\n server.close();\n if (apiServer) apiServer.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n process.on('exit', () => {\n if (fs.existsSync(socketPath)) {\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore errors during exit cleanup\n }\n }\n });\n}\n\n// Only auto-initialize if run directly\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n initDaemon().catch((err) => {\n console.error('Daemon initialization failed:', err);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["path","fs","fs","crypto","fs","fs"],"sources":["../../src/daemon/request-store.ts","../../src/daemon/policy-request-service.ts","../../src/daemon/queue.ts","../../src/daemon/routers/slash-new.ts","../../src/daemon/routers/slash-command.ts","../../src/daemon/routers/utils.ts","../../src/daemon/routers/slash-stop.ts","../../src/daemon/routers/slash-interrupt.ts","../../src/daemon/routers/slash-policies.ts","../../src/daemon/routers.ts","../../src/daemon/auth.ts","../../src/shared/utils/env.ts","../../src/daemon/message.ts","../../src/daemon/utils/spawn.ts","../../src/daemon/cron.ts","../../src/daemon/router.ts","../../src/daemon/index.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\nimport { z } from 'zod';\nimport { getClawminiDir } from '../shared/workspace.js';\nimport type { PolicyRequest } from '../shared/policies.js';\nimport { randomInt } from 'crypto';\n\nconst PolicyRequestSchema = z.object({\n id: z.string(),\n commandName: z.string(),\n args: z.array(z.string()),\n fileMappings: z.record(z.string(), z.string()),\n state: z.enum(['Pending', 'Approved', 'Rejected']),\n createdAt: z.number(),\n rejectionReason: z.string().optional(),\n chatId: z.string(),\n agentId: z.string(),\n});\n\nfunction isENOENT(err: unknown): boolean {\n return Boolean(\n err && typeof err === 'object' && 'code' in err && (err as { code: string }).code === 'ENOENT'\n );\n}\n\nexport class RequestStore {\n private baseDir: string;\n\n constructor(startDir = process.cwd()) {\n this.baseDir = path.join(getClawminiDir(startDir), 'tmp', 'requests');\n }\n\n async init(): Promise<void> {\n await fs.mkdir(this.baseDir, { recursive: true });\n }\n\n private getFilePath(id: string): string {\n return path.join(this.baseDir, `${id}.json`);\n }\n\n async save(request: PolicyRequest): Promise<void> {\n await this.init();\n const filePath = this.getFilePath(request.id);\n await fs.writeFile(filePath, JSON.stringify(request, null, 2), 'utf8');\n }\n\n async load(id: string): Promise<PolicyRequest | null> {\n const normalizedId = normalizePolicyId(id);\n const filePath = this.getFilePath(normalizedId);\n try {\n const data = await fs.readFile(filePath, 'utf8');\n return PolicyRequestSchema.parse(JSON.parse(data)) as PolicyRequest;\n } catch (err: unknown) {\n if (isENOENT(err)) {\n return null;\n }\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`Failed to parse request file ${filePath}:`, msg);\n return null;\n }\n }\n\n async list(): Promise<PolicyRequest[]> {\n await this.init();\n const requests: PolicyRequest[] = [];\n try {\n const files = await fs.readdir(this.baseDir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const id = path.basename(file, '.json');\n const req = await this.load(id);\n if (req) {\n requests.push(req);\n }\n }\n } catch (err: unknown) {\n if (!isENOENT(err)) {\n throw err;\n }\n }\n return requests.sort((a, b) => b.createdAt - a.createdAt);\n }\n}\n\nexport function generateRandomAlphaNumericString(length: number): string {\n const characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += characters[Math.floor(randomInt(characters.length))];\n }\n return result;\n}\n\nfunction normalizePolicyId(id: string): string {\n return id.toLocaleUpperCase().trim();\n}\n","import { RequestStore, generateRandomAlphaNumericString } from './request-store.js';\nimport { createSnapshot, interpolateArgs } from './policy-utils.js';\nimport type { PolicyRequest } from '../shared/policies.js';\n\nexport class PolicyRequestService {\n private store: RequestStore;\n private maxPending: number;\n private agentDir: string;\n private snapshotDir: string;\n\n constructor(store: RequestStore, agentDir: string, snapshotDir: string, maxPending = 100) {\n this.store = store;\n this.agentDir = agentDir;\n this.snapshotDir = snapshotDir;\n this.maxPending = maxPending;\n }\n\n async createRequest(\n commandName: string,\n args: string[],\n fileMappings: Record<string, string>,\n chatId: string,\n agentId: string\n ): Promise<PolicyRequest> {\n const allRequests = await this.store.list();\n const pendingCount = allRequests.filter((r) => r.state === 'Pending').length;\n\n if (pendingCount >= this.maxPending) {\n throw new Error(`Maximum number of pending requests (${this.maxPending}) reached.`);\n }\n\n const snapshotMappings: Record<string, string> = {};\n\n for (const [key, requestedPath] of Object.entries(fileMappings)) {\n snapshotMappings[key] = await createSnapshot(requestedPath, this.agentDir, this.snapshotDir);\n }\n\n let id = '';\n do {\n id = generateRandomAlphaNumericString(3);\n } while (allRequests.some((r) => r.id === id));\n\n const request: PolicyRequest = {\n id,\n commandName,\n args,\n fileMappings: snapshotMappings,\n state: 'Pending',\n createdAt: Date.now(),\n chatId,\n agentId,\n };\n\n await this.store.save(request);\n\n return request;\n }\n\n getInterpolatedArgs(request: PolicyRequest): string[] {\n return interpolateArgs(request.args, request.fileMappings);\n }\n}\n","export type Task<T = void> = (signal: AbortSignal) => Promise<T>;\n\ninterface QueueEntry<TPayload = string> {\n task: Task;\n payload?: TPayload | undefined;\n resolve: (value: void | PromiseLike<void>) => void;\n reject: (reason?: unknown) => void;\n}\n\nexport class Queue<TPayload = string> {\n private pending: QueueEntry<TPayload>[] = [];\n private isRunning = false;\n private currentController: AbortController | null = null;\n private currentPayload?: TPayload | undefined;\n\n enqueue(task: Task, payload?: TPayload): Promise<void> {\n return new Promise((resolve, reject) => {\n this.pending.push({ task, payload, resolve, reject });\n // We don't await processNext because we want enqueue to return the task's promise\n // and let processNext run in the background.\n this.processNext().catch(() => {});\n });\n }\n\n private async processNext() {\n if (this.isRunning || this.pending.length === 0) return;\n\n this.isRunning = true;\n const entry = this.pending.shift()!;\n this.currentController = new AbortController();\n this.currentPayload = entry.payload;\n\n try {\n await entry.task(this.currentController.signal);\n entry.resolve();\n } catch (error) {\n entry.reject(error);\n } finally {\n this.isRunning = false;\n this.currentController = null;\n this.currentPayload = undefined;\n // Continue processing the next item\n this.processNext().catch(() => {});\n }\n }\n\n abortCurrent(): void {\n if (this.currentController) {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n this.currentController.abort(error);\n }\n }\n\n getCurrentPayload(): TPayload | undefined {\n return this.currentPayload;\n }\n\n clear(reason: string = 'Task cleared'): void {\n const tasksToClear = [...this.pending];\n this.pending = [];\n for (const { reject } of tasksToClear) {\n const error = new Error(reason);\n error.name = 'AbortError';\n reject(error);\n }\n }\n\n extractPending(): TPayload[] {\n const extracted = this.pending\n .map((p) => p.payload)\n .filter((p): p is TPayload => p !== undefined);\n\n this.clear('Task extracted for batching');\n\n return extracted;\n }\n}\n\nconst directoryQueues = new Map<string, Queue>();\n\nexport function getQueue(dir: string): Queue {\n if (!directoryQueues.has(dir)) {\n directoryQueues.set(dir, new Queue());\n }\n return directoryQueues.get(dir)!;\n}\n","import type { RouterState } from './types.js';\n\nexport function slashNew(state: RouterState): RouterState {\n if (/^\\/new(\\s|$)/.test(state.message)) {\n const newMessage = state.message.replace(/^\\/new(\\s+|$)/, '').trim();\n return {\n ...state,\n message: newMessage,\n sessionId: crypto.randomUUID(),\n reply: '[@clawmini/slash-new] Starting a new session...',\n };\n }\n return state;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { RouterState } from './types.js';\nimport { getClawminiDir } from '../../shared/workspace.js';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\n\nexport async function slashCommand(state: RouterState): Promise<RouterState> {\n const commandsDir = path.resolve(getClawminiDir(), 'commands');\n let currentMessage = state.message;\n\n // Regex to match slash commands (e.g., /foo or /foo:bar) that appear as whole words.\n // We use lookbehind and lookahead to ensure it's bounded by whitespace or string start/end.\n const commandRegex = /(?<=^|\\s)\\/([a-zA-Z0-9_\\-:.]+)(?=\\s|$)/g;\n const matches = [...currentMessage.matchAll(commandRegex)];\n\n if (matches.length === 0) {\n return state;\n }\n\n for (const match of matches) {\n const fullMatch = match[0];\n const commandName = match[1];\n if (!commandName) continue;\n\n const targetPathMd = path.resolve(commandsDir, `${commandName}.md`);\n const targetPathTxt = path.resolve(commandsDir, `${commandName}.txt`);\n\n // Strict path traversal protection\n const baseTargetPath = path.resolve(commandsDir, commandName);\n if (!pathIsInsideDir(baseTargetPath, commandsDir)) {\n continue;\n }\n\n let content: string;\n\n try {\n content = await fs.readFile(targetPathMd, 'utf8');\n } catch {\n try {\n content = await fs.readFile(targetPathTxt, 'utf8');\n } catch {\n // If file doesn't exist or can't be read, leave it as is.\n continue;\n }\n }\n\n // Replace the command with the content. We only replace the exact occurrence.\n // Since replace replaces the first occurrence, and we are iterating over all matches,\n // it should replace them sequentially. If there are multiple identical commands,\n // it's fine, each will be replaced in turn.\n currentMessage = currentMessage.replace(fullMatch, content.trim());\n }\n\n return {\n ...state,\n message: currentMessage,\n };\n}\n","import type { RouterState } from './types.js';\n\nexport function createSlashActionRouter(\n command: string,\n action: NonNullable<RouterState['action']>,\n replyMessage: string\n) {\n return function (state: RouterState): RouterState {\n const regex = new RegExp(`^\\\\/${command}(\\\\s|$)`);\n if (regex.test(state.message)) {\n const replaceRegex = new RegExp(`^\\\\/${command}(\\\\s+|$)`);\n const newMessage = state.message.replace(replaceRegex, '').trim();\n return {\n ...state,\n message: newMessage,\n action,\n reply: replyMessage,\n };\n }\n return state;\n };\n}\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashStop = createSlashActionRouter('stop', 'stop', 'Stopping current task...');\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashInterrupt = createSlashActionRouter(\n 'interrupt',\n 'interrupt',\n 'Interrupting current task...'\n);\n","import { randomUUID } from 'node:crypto';\nimport type { RouterState } from './types.js';\nimport { RequestStore } from '../request-store.js';\nimport { readPolicies, getWorkspaceRoot } from '../../shared/workspace.js';\nimport { executeSafe, interpolateArgs } from '../policy-utils.js';\nimport { appendMessage } from '../chats.js';\nimport type { CommandLogMessage } from '../../shared/chats.js';\n\nasync function loadAndValidateRequest(id: string, state: RouterState) {\n const store = new RequestStore(getWorkspaceRoot());\n const req = await store.load(id);\n if (!req) return { error: { ...state, message: '', reply: `Request not found: ${id}` } };\n if (req.chatId && req.chatId !== state.chatId)\n return {\n error: { ...state, message: '', reply: `Request belongs to a different chat: ${req.chatId}` },\n };\n if (req.state !== 'Pending')\n return { error: { ...state, message: '', reply: `Request is not pending: ${id}` } };\n return { req, store };\n}\n\nexport async function slashPolicies(state: RouterState): Promise<RouterState> {\n const message = state.message.trim();\n\n if (message === '/pending') {\n const store = new RequestStore(getWorkspaceRoot());\n const requests = await store.list();\n const pending = requests.filter((r) => r.state === 'Pending');\n\n let reply = `Pending Requests (${pending.length}):\\n`;\n for (const req of pending) {\n reply += `- ID: ${req.id} | Command: ${req.commandName} ${req.args.join(' ')}\\n`;\n }\n\n return {\n ...state,\n reply,\n action: 'stop',\n };\n }\n\n const approveMatch = message.match(/^\\/approve\\s+([^\\s]+)/);\n if (approveMatch) {\n const id = approveMatch[1];\n if (!id) return state;\n const { req, store, error } = await loadAndValidateRequest(id, state);\n if (error) return error;\n if (!req || !store) return state; // Should not happen if error is undefined\n\n const config = await readPolicies();\n const policy = config?.policies?.[req.commandName];\n if (!policy) {\n return { ...state, message: '', reply: `Policy not found: ${req.commandName}` };\n }\n\n req.state = 'Approved';\n await store.save(req);\n\n const fullArgs = [...(policy.args || []), ...req.args];\n const interpolatedArgs = interpolateArgs(fullArgs, req.fileMappings);\n\n const { stdout, stderr, exitCode } = await executeSafe(policy.command, interpolatedArgs, {\n cwd: getWorkspaceRoot(),\n });\n\n const commandStr = `${policy.command} ${interpolatedArgs.join(' ')}`;\n const logMsg: CommandLogMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'log',\n source: 'router',\n content: `Request ${id} approved and executed.`,\n stderr,\n stdout,\n timestamp: new Date().toISOString(),\n command: commandStr,\n cwd: getWorkspaceRoot(),\n exitCode,\n };\n\n await appendMessage(state.chatId, logMsg);\n\n const agentMessage = `Request ${id} approved.\\n\\n${wrapInHtml('stdout', stdout)}\\n\\n${wrapInHtml('stderr', stderr)}\\n\\nExit Code: ${exitCode}`;\n return {\n ...state,\n message: agentMessage,\n reply: `Approved request, running ${req.commandName}`,\n };\n }\n\n const rejectMatch = message.match(/^\\/reject\\s+([^\\s]+)(?:\\s+(.*))?/);\n if (rejectMatch) {\n const id = rejectMatch[1];\n if (!id) return state;\n const reason = rejectMatch[2] || 'No reason provided';\n const { req, store, error } = await loadAndValidateRequest(id, state);\n if (error) return error;\n if (!req || !store) return state; // Should not happen if error is undefined\n\n req.state = 'Rejected';\n req.rejectionReason = reason;\n await store.save(req);\n\n const logMsg: CommandLogMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'log',\n source: 'router',\n content: `Request ${id} rejected. Reason: ${reason}`,\n stderr: '',\n timestamp: new Date().toISOString(),\n command: `policy-request-reject ${id}`,\n cwd: getWorkspaceRoot(),\n exitCode: 1,\n };\n\n await appendMessage(state.chatId, logMsg);\n\n const agentMessage = `Request ${id} rejected. Reason: ${reason}`;\n return { ...state, message: agentMessage };\n }\n\n return state;\n}\n\nfunction wrapInHtml(tag: string, text: string): string {\n if (text.trim().length === 0) {\n return `<${tag}></${tag}>`;\n }\n return `<${tag}>\\n${text.trim()}\\n</${tag}>`;\n}\n","import { spawn } from 'node:child_process';\nimport type { RouterState } from './routers/types.js';\nimport { slashNew } from './routers/slash-new.js';\nimport { slashCommand } from './routers/slash-command.js';\nimport { slashStop } from './routers/slash-stop.js';\nimport { slashInterrupt } from './routers/slash-interrupt.js';\nimport { slashPolicies } from './routers/slash-policies.js';\n\nexport async function executeRouterPipeline(\n initialState: RouterState,\n routers: string[]\n): Promise<RouterState> {\n let state = { ...initialState };\n\n for (const router of routers) {\n if (state.action === 'stop') {\n break;\n }\n\n if (router === '@clawmini/slash-new') {\n state = slashNew(state);\n } else if (router === '@clawmini/slash-command') {\n state = await slashCommand(state);\n } else if (router === '@clawmini/slash-stop') {\n state = slashStop(state);\n } else if (router === '@clawmini/slash-interrupt') {\n state = slashInterrupt(state);\n } else if (router === '@clawmini/slash-policies') {\n state = await slashPolicies(state);\n } else {\n // Execute as custom shell command\n try {\n state = await executeCustomRouter(router, state);\n } catch (err) {\n // Silent failure handling: log but do not halt\n console.error(`Router error [${router}]:`, err);\n }\n }\n }\n\n return state;\n}\n\nasync function executeCustomRouter(command: string, state: RouterState): Promise<RouterState> {\n return new Promise((resolve, reject) => {\n // We run the command via shell\n const child = spawn(command, { shell: true });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (chunk) => {\n stdout += chunk.toString();\n });\n child.stderr.on('data', (chunk) => {\n stderr += chunk.toString();\n });\n\n // timeout fallback to avoid hanging indefinitely\n const timer = setTimeout(() => {\n child.kill();\n reject(new Error('Router execution timed out'));\n }, 10000);\n\n child.on('close', (code) => {\n clearTimeout(timer);\n if (code !== 0) {\n return reject(new Error(`Process exited with code ${code}. Stderr: ${stderr}`));\n }\n\n try {\n const result = JSON.parse(stdout);\n const newState = { ...state };\n\n if (typeof result.message === 'string') newState.message = result.message;\n if (typeof result.agent === 'string') newState.agentId = result.agent;\n if (typeof result.session === 'string') newState.sessionId = result.session;\n if (typeof result.env === 'object' && result.env !== null) {\n newState.env = { ...newState.env, ...result.env };\n }\n if (typeof result.reply === 'string') newState.reply = result.reply;\n if (typeof result.action === 'string') newState.action = result.action;\n\n resolve(newState);\n } catch (err) {\n reject(new Error(`Failed to parse router output: ${err}. Stdout: ${stdout}`));\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n\n // Write state to stdin\n const inputState = {\n message: state.message,\n chatId: state.chatId,\n agentId: state.agentId,\n sessionId: state.sessionId,\n env: state.env,\n action: state.action,\n };\n\n if (child.stdin) {\n child.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n child.stdin.write(JSON.stringify(inputState));\n child.stdin.end();\n }\n });\n}\n","import crypto from 'node:crypto';\nimport type { Settings } from '../shared/config.js';\n\n// In-memory secret generated on daemon startup.\n// Valid tokens will only last for the lifetime of the daemon process.\nconst DAEMON_SECRET = crypto.randomBytes(32);\n\nexport interface TokenPayload {\n chatId: string;\n agentId: string;\n sessionId: string;\n timestamp: number;\n}\n\nexport function generateToken(payload: TokenPayload): string {\n const payloadStr = Buffer.from(JSON.stringify(payload)).toString('base64');\n const hmac = crypto.createHmac('sha256', DAEMON_SECRET).update(payloadStr).digest('hex');\n return `${payloadStr}.${hmac}`;\n}\n\nexport function validateToken(token: string): TokenPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 2) return null;\n\n const [payloadStr, signature] = parts;\n if (!payloadStr || !signature) return null;\n\n const expectedHmac = crypto\n .createHmac('sha256', DAEMON_SECRET)\n .update(payloadStr)\n .digest('hex');\n\n const signatureBuffer = Buffer.from(signature, 'hex');\n const expectedHmacBuffer = Buffer.from(expectedHmac, 'hex');\n\n if (\n signatureBuffer.length !== expectedHmacBuffer.length ||\n !crypto.timingSafeEqual(signatureBuffer, expectedHmacBuffer)\n ) {\n return null;\n }\n\n const payloadJson = Buffer.from(payloadStr, 'base64').toString('utf8');\n return JSON.parse(payloadJson) as TokenPayload;\n } catch {\n return null;\n }\n}\n\nexport function getApiContext(settings?: Settings) {\n if (settings?.api === undefined) return null;\n let isApiEnabled = false;\n let apiHost = '127.0.0.1';\n let apiPort = 3000;\n let proxyHost: string | undefined = undefined;\n\n if (typeof settings.api === 'boolean') {\n isApiEnabled = settings.api;\n } else if (typeof settings.api === 'object') {\n isApiEnabled = true;\n apiHost = settings.api.host ?? '127.0.0.1';\n apiPort = settings.api.port ?? 3000;\n proxyHost = settings.api.proxy_host;\n }\n\n if (!isApiEnabled) return null;\n return { host: apiHost, port: apiPort, proxy_host: proxyHost };\n}\n","export function applyEnvOverrides(\n targetEnv: Record<string, string>,\n overrides?: Record<string, string | boolean>\n): void {\n if (!overrides) return;\n\n for (const [key, val] of Object.entries(overrides)) {\n if (val === true && process.env[key] !== undefined) {\n targetEnv[key] = process.env[key];\n } else if (typeof val === 'string') {\n targetEnv[key] = val;\n }\n }\n}\n\nexport function getActiveEnvKeys(\n ...envs: (Record<string, string | boolean> | undefined)[]\n): Set<string> {\n const keys = new Set<string>();\n for (const env of envs) {\n if (!env) continue;\n Object.entries(env).forEach(([key, val]) => {\n if (val === true || typeof val === 'string') keys.add(key);\n });\n }\n return keys;\n}\n","/* eslint-disable max-lines */\nimport path from 'node:path';\nimport { appendMessage, type UserMessage, type CommandLogMessage } from './chats.js';\nimport { getQueue } from './queue.js';\nimport { executeRouterPipeline } from './routers.js';\nimport type { RouterState } from './routers/types.js';\nimport {\n type Settings,\n type Agent,\n type AgentSessionSettings,\n type FallbackSchema,\n} from '../shared/config.js';\nimport {\n readChatSettings,\n writeChatSettings,\n readAgentSessionSettings,\n writeAgentSessionSettings,\n getAgent,\n getWorkspaceRoot,\n getActiveEnvironmentInfo,\n getEnvironmentPath,\n readEnvironment,\n} from '../shared/workspace.js';\nimport { getApiContext, generateToken } from './auth.js';\nimport { emitTyping } from './events.js';\nimport { applyEnvOverrides, getActiveEnvKeys } from '../shared/utils/env.js';\nimport { z } from 'zod';\n\ntype Fallback = z.infer<typeof FallbackSchema>;\n\nexport function calculateDelay(\n attempt: number,\n baseDelayMs: number,\n isFallback: boolean = false\n): number {\n const effectiveAttempt = isFallback ? attempt + 1 : attempt;\n if (effectiveAttempt <= 0) return 0;\n const delay = baseDelayMs * Math.pow(2, effectiveAttempt - 1);\n return Math.min(delay, 15000);\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport type RunCommandResult = {\n stdout: string;\n stderr: string;\n exitCode: number;\n};\n\nexport type RunCommandFn = (args: {\n command: string;\n cwd: string;\n env: Record<string, string>;\n stdin?: string | undefined;\n signal?: AbortSignal | undefined;\n}) => Promise<RunCommandResult>;\n\nasync function resolveSessionState(\n chatId: string,\n cwd: string,\n sessionId?: string,\n overrideAgentId?: string\n) {\n const chatSettings = await readChatSettings(chatId, cwd);\n const agentId =\n overrideAgentId ??\n (typeof chatSettings?.defaultAgent === 'string' ? chatSettings.defaultAgent : 'default');\n\n let targetSessionId = sessionId;\n if (!targetSessionId) {\n const sessions = chatSettings?.sessions || {};\n targetSessionId = sessions[agentId] || 'default';\n }\n\n const agentSessionSettings = await readAgentSessionSettings(agentId, targetSessionId, cwd);\n const isNewSession = !agentSessionSettings;\n\n return { chatSettings, agentId, targetSessionId, agentSessionSettings, isNewSession };\n}\n\nfunction prepareCommandAndEnv(\n agent: Agent,\n message: string,\n isNewSession: boolean,\n agentSessionSettings: AgentSessionSettings | null,\n fallback?: Fallback\n): { command: string; env: Record<string, string>; currentAgent: Agent } {\n const currentAgent: Agent = {\n ...agent,\n commands: {\n ...agent.commands,\n ...(fallback?.commands || {}),\n },\n env: {\n ...agent.env,\n ...(fallback?.env || {}),\n },\n };\n\n let command = currentAgent.commands?.new ?? '';\n const env = {\n ...process.env,\n CLAW_CLI_MESSAGE: message,\n } as Record<string, string>;\n\n applyEnvOverrides(env, currentAgent.env);\n\n if (!isNewSession && currentAgent.commands?.append) {\n command = currentAgent.commands.append;\n applyEnvOverrides(env, agentSessionSettings?.env);\n }\n\n return { command, env, currentAgent };\n}\n\nasync function runExtractionCommand(\n name: string,\n command: string,\n runCommand: RunCommandFn,\n cwd: string,\n env: Record<string, string>,\n mainResult: RunCommandResult,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n try {\n console.log(`Executing extraction command (${name}): ${command}`);\n const res = await runCommand({\n command,\n cwd,\n env,\n stdin: mainResult.stdout,\n signal,\n });\n if (res.exitCode === 0) {\n return { result: res.stdout.trim() };\n } else {\n return { error: `${name} failed: ${res.stderr}` };\n }\n } catch (e) {\n return { error: `${name} error: ${(e as Error).message}` };\n }\n}\n\n/**\n * Formats the environment prefix string by replacing placeholders with actual values.\n * Available placeholders:\n * - {WORKSPACE_DIR}: The root directory of the workspace.\n * - {AGENT_DIR}: The directory where the agent is executing.\n * - {ENV_DIR}: The directory of the active environment.\n * - {HOME_DIR}: The home directory of the current user.\n * - {ENV_ARGS}: The formatted environment arguments based on envFormat.\n */\nfunction formatEnvironmentPrefix(\n prefix: string,\n replacements: {\n targetPath: string;\n executionCwd: string;\n envDir: string;\n envArgs: string;\n }\n): string {\n const map: Record<string, string> = {\n '{WORKSPACE_DIR}': replacements.targetPath,\n '{AGENT_DIR}': replacements.executionCwd,\n '{ENV_DIR}': replacements.envDir,\n '{HOME_DIR}': process.env.HOME || '',\n '{ENV_ARGS}': replacements.envArgs,\n };\n return prefix.replace(\n /{(WORKSPACE_DIR|AGENT_DIR|ENV_DIR|HOME_DIR|ENV_ARGS)}/g,\n (match) => map[match] || match\n );\n}\n\nexport async function executeDirectMessage(\n chatId: string,\n state: RouterState,\n settings: Settings | undefined,\n cwd: string,\n runCommand: RunCommandFn,\n noWait: boolean = false,\n userMessageContent?: string\n) {\n const userMsg: UserMessage = {\n id: state.messageId ?? crypto.randomUUID(),\n role: 'user',\n content: userMessageContent ?? state.message,\n timestamp: new Date().toISOString(),\n };\n await appendMessage(chatId, userMsg);\n\n if (state.reply) {\n const routerLogMsg: CommandLogMessage = {\n id: crypto.randomUUID(),\n messageId: userMsg.id,\n role: 'log',\n source: 'router',\n content: state.reply,\n stderr: '',\n timestamp: new Date().toISOString(),\n command: 'router',\n cwd,\n exitCode: 0,\n ...(state.reply.includes('NO_REPLY_NECESSARY') ? { level: 'verbose' as const } : {}),\n };\n await appendMessage(chatId, routerLogMsg);\n }\n\n if (!state.message.trim() && state.action !== 'stop' && state.action !== 'interrupt') {\n return;\n }\n\n const queue = getQueue(cwd);\n\n if (state.action === 'stop') {\n queue.abortCurrent();\n queue.clear();\n return;\n }\n\n if (state.action === 'interrupt') {\n const currentPayload = queue.getCurrentPayload();\n queue.abortCurrent();\n\n const extracted = queue.extractPending();\n const payloads = currentPayload ? [currentPayload, ...extracted] : extracted;\n\n if (payloads.length > 0) {\n const pendingText = payloads.map((text) => `<message>\\n${text}\\n</message>`).join('\\n\\n');\n state.message = `${pendingText}\\n\\n<message>\\n${state.message}\\n</message>`.trim();\n }\n }\n\n if (!state.message.trim()) {\n return;\n }\n\n const routerEnv = state.env ?? {};\n\n const taskPromise = queue.enqueue(async (signal) => {\n const {\n agentId,\n agentSessionSettings,\n isNewSession,\n targetSessionId: finalSessionId,\n } = await resolveSessionState(chatId, cwd, state.sessionId, state.agentId);\n\n let mergedAgent: Agent = settings?.defaultAgent || {};\n if (agentId !== 'default') {\n try {\n const customAgent = await getAgent(agentId, cwd);\n if (customAgent) {\n mergedAgent = {\n ...mergedAgent,\n ...customAgent,\n commands: { ...mergedAgent.commands, ...customAgent.commands },\n env: { ...mergedAgent.env, ...customAgent.env },\n };\n }\n } catch {\n // Fall back to default if agent not found\n }\n }\n\n const fallbacks = mergedAgent.fallbacks || [];\n const executionConfigs: { fallback?: Fallback; retries: number; delayMs: number }[] = [\n { retries: 0, delayMs: 1000 },\n ...fallbacks.map((f) => ({ fallback: f, retries: f.retries, delayMs: f.delayMs })),\n ];\n\n const workspaceRoot = getWorkspaceRoot(cwd);\n let executionCwd = cwd;\n if (mergedAgent.directory) {\n executionCwd = path.resolve(workspaceRoot, mergedAgent.directory);\n } else if (agentId !== 'default') {\n executionCwd = path.resolve(workspaceRoot, agentId);\n }\n\n let lastLogMsg: CommandLogMessage | undefined;\n let success = false;\n\n for (let configIdx = 0; configIdx < executionConfigs.length; configIdx++) {\n const config = executionConfigs[configIdx]!;\n const isFallbackConfig = configIdx > 0;\n for (let attempt = 0; attempt <= config.retries; attempt++) {\n const delay = calculateDelay(attempt, config.delayMs, isFallbackConfig);\n if (delay > 0) {\n const retryLogMsg: CommandLogMessage = {\n id: crypto.randomUUID(),\n messageId: userMsg.id,\n role: 'log',\n content: `Error running agent, retrying in ${Math.round(delay / 1000)} seconds...`,\n stderr: '',\n timestamp: new Date().toISOString(),\n command: 'retry-delay',\n cwd: executionCwd,\n exitCode: 0,\n };\n await appendMessage(chatId, retryLogMsg);\n await sleep(delay);\n }\n\n const {\n env,\n currentAgent,\n command: initialCommand,\n } = prepareCommandAndEnv(\n mergedAgent,\n state.message,\n isNewSession,\n agentSessionSettings,\n config.fallback\n );\n let command = initialCommand;\n\n if (!command) {\n continue;\n }\n\n const agentSpecificEnv = getActiveEnvKeys(\n currentAgent.env,\n !isNewSession ? agentSessionSettings?.env : undefined\n );\n agentSpecificEnv.add('CLAW_CLI_MESSAGE');\n\n Object.assign(env, routerEnv);\n Object.keys(routerEnv).forEach((k) => agentSpecificEnv.add(k));\n\n const apiCtx = getApiContext(settings);\n if (apiCtx) {\n const proxyUrl = apiCtx.proxy_host\n ? `${apiCtx.proxy_host}:${apiCtx.port}`\n : `http://${apiCtx.host}:${apiCtx.port}`;\n env['CLAW_API_URL'] = proxyUrl;\n agentSpecificEnv.add('CLAW_API_URL');\n\n const token = generateToken({\n chatId,\n agentId,\n sessionId: finalSessionId,\n timestamp: Date.now(),\n });\n env['CLAW_API_TOKEN'] = token;\n agentSpecificEnv.add('CLAW_API_TOKEN');\n }\n\n const activeEnvInfo = await getActiveEnvironmentInfo(executionCwd, cwd);\n if (activeEnvInfo) {\n const activeEnvName = activeEnvInfo.name;\n const activeEnv = await readEnvironment(activeEnvName, cwd);\n\n if (activeEnv?.env) {\n for (const [key, value] of Object.entries(activeEnv.env)) {\n if (value === false) {\n delete env[key];\n agentSpecificEnv.delete(key);\n } else {\n let interpolatedValue = String(value);\n interpolatedValue = interpolatedValue.replace(/\\{PATH\\}/g, process.env.PATH || '');\n interpolatedValue = interpolatedValue.replace(\n /\\{ENV_DIR\\}/g,\n getEnvironmentPath(activeEnvName, cwd)\n );\n interpolatedValue = interpolatedValue.replace(\n /\\{WORKSPACE_DIR\\}/g,\n activeEnvInfo.targetPath\n );\n env[key] = interpolatedValue;\n agentSpecificEnv.add(key);\n }\n }\n }\n\n if (activeEnv?.prefix) {\n const envArgs = Array.from(agentSpecificEnv)\n .map((key) => {\n if (activeEnv.envFormat) {\n return activeEnv.envFormat.replace('{key}', key);\n }\n return key;\n })\n .join(' ');\n\n const prefixReplaced = formatEnvironmentPrefix(activeEnv.prefix, {\n targetPath: activeEnvInfo.targetPath,\n executionCwd,\n envDir: getEnvironmentPath(activeEnvName, cwd),\n envArgs,\n });\n\n if (prefixReplaced.includes('{COMMAND}')) {\n command = prefixReplaced.replace('{COMMAND}', command);\n } else {\n command = `${prefixReplaced} ${command}`;\n }\n }\n }\n\n console.log(`Executing command: ${command}`);\n let mainResult;\n const typingInterval = setInterval(() => {\n emitTyping(chatId);\n }, 5000);\n try {\n mainResult = await runCommand({ command, cwd: executionCwd, env, signal });\n } finally {\n clearInterval(typingInterval);\n }\n\n const logMsg: CommandLogMessage = {\n id: crypto.randomUUID(),\n messageId: userMsg.id,\n role: 'log',\n content: mainResult.stdout,\n stdout: mainResult.stdout,\n stderr: '',\n timestamp: new Date().toISOString(),\n command,\n cwd: executionCwd,\n exitCode: mainResult.exitCode,\n ...(mainResult.stdout.includes('NO_REPLY_NECESSARY')\n ? { level: 'verbose' as const }\n : {}),\n };\n\n const errors: string[] = [];\n if (mainResult.stderr) {\n errors.push(mainResult.stderr);\n }\n\n let currentSuccess = mainResult.exitCode === 0;\n\n if (currentSuccess) {\n if (currentAgent.commands?.getMessageContent) {\n const { result, error } = await runExtractionCommand(\n 'getMessageContent',\n currentAgent.commands.getMessageContent,\n runCommand,\n executionCwd,\n env,\n mainResult,\n signal\n );\n if (result !== undefined) {\n logMsg.content = result;\n logMsg.stdout = mainResult.stdout;\n if (result.includes('NO_REPLY_NECESSARY')) {\n logMsg.level = 'verbose';\n } else {\n delete logMsg.level;\n }\n if (result.trim() === '') {\n currentSuccess = false;\n }\n }\n if (error) {\n errors.push(error);\n }\n }\n }\n\n logMsg.stderr = errors.join('\\n\\n');\n lastLogMsg = logMsg;\n\n if (currentSuccess) {\n success = true;\n if (isNewSession && currentAgent.commands?.getSessionId) {\n const { result, error } = await runExtractionCommand(\n 'getSessionId',\n currentAgent.commands.getSessionId,\n runCommand,\n executionCwd,\n env,\n mainResult,\n signal\n );\n if (result) {\n await writeAgentSessionSettings(\n agentId,\n finalSessionId,\n { env: { SESSION_ID: result } },\n cwd\n );\n }\n if (error) {\n // We don't fail the whole thing for getSessionId error, but we log it.\n logMsg.stderr = [logMsg.stderr, error].filter(Boolean).join('\\n\\n');\n }\n }\n break;\n }\n }\n if (success) break;\n }\n\n if (lastLogMsg) {\n await appendMessage(chatId, lastLogMsg);\n }\n }, state.message);\n\n if (!noWait) {\n await taskPromise;\n } else {\n taskPromise.catch((err) => {\n if (err.name !== 'AbortError') {\n console.error('Task execution error:', err);\n }\n });\n }\n}\n\nexport async function getInitialRouterState(\n chatId: string,\n message: string,\n cwd: string = process.cwd(),\n overrideAgentId?: string,\n overrideSessionId?: string,\n overrideMessageId?: string\n): Promise<RouterState> {\n const chatSettings = (await readChatSettings(chatId, cwd)) ?? {};\n const agentId = overrideAgentId ?? chatSettings.defaultAgent ?? 'default';\n const sessionId = overrideSessionId ?? chatSettings.sessions?.[agentId] ?? 'default';\n const messageId = overrideMessageId ?? crypto.randomUUID();\n\n return {\n messageId,\n message,\n chatId,\n agentId,\n sessionId,\n env: {},\n };\n}\n\nexport async function handleUserMessage(\n chatId: string,\n message: string,\n settings: Settings | undefined,\n cwd: string = process.cwd(),\n noWait: boolean = false,\n runCommand: RunCommandFn,\n sessionId?: string,\n overrideAgentId?: string\n): Promise<void> {\n const chatSettings = (await readChatSettings(chatId, cwd)) ?? {};\n\n if (overrideAgentId && chatSettings.defaultAgent !== overrideAgentId) {\n chatSettings.defaultAgent = overrideAgentId;\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n const initialState = await getInitialRouterState(\n chatId,\n message,\n cwd,\n overrideAgentId,\n sessionId\n );\n const initialAgent = initialState.agentId;\n\n const routers = chatSettings.routers ?? settings?.routers ?? [];\n\n const finalState = await executeRouterPipeline(initialState, routers);\n\n const finalMessage = finalState.message;\n const finalAgentId = finalState.agentId;\n const finalSessionId = finalState.sessionId ?? crypto.randomUUID();\n const routerEnv = finalState.env ?? {};\n\n const currentAgentId = finalAgentId ?? chatSettings.defaultAgent ?? 'default';\n\n let settingsChanged = false;\n if (finalAgentId && finalAgentId !== initialAgent) {\n chatSettings.defaultAgent = finalAgentId;\n settingsChanged = true;\n }\n\n if (finalSessionId && chatSettings.sessions?.[currentAgentId] !== finalSessionId) {\n chatSettings.sessions = chatSettings.sessions || {};\n chatSettings.sessions[currentAgentId] = finalSessionId;\n settingsChanged = true;\n }\n\n if (settingsChanged) {\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n const directState: RouterState = {\n messageId: finalState.messageId,\n message: finalMessage,\n chatId,\n env: routerEnv,\n };\n if (finalAgentId !== undefined) directState.agentId = finalAgentId;\n if (finalSessionId !== undefined) directState.sessionId = finalSessionId;\n if (finalState.reply !== undefined) directState.reply = finalState.reply;\n if (finalState.action !== undefined) directState.action = finalState.action;\n\n await executeDirectMessage(chatId, directState, settings, cwd, runCommand, noWait, message);\n}\n","import { spawn } from 'node:child_process';\nimport type { RunCommandFn } from '../message.js';\n\nexport const runCommand: RunCommandFn &\n ((\n args: Parameters<RunCommandFn>[0] & { logToTerminal?: boolean }\n ) => ReturnType<RunCommandFn>) = async ({\n command,\n cwd,\n env,\n stdin,\n signal,\n logToTerminal,\n}: Parameters<RunCommandFn>[0] & { logToTerminal?: boolean }) => {\n return new Promise<{ stdout: string; stderr: string; exitCode: number }>((resolve, reject) => {\n const p = spawn(command, { shell: true, cwd, env, signal });\n\n if (stdin && p.stdin) {\n p.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n p.stdin.write(stdin);\n p.stdin.end();\n }\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n if (logToTerminal && !stdin) {\n process.stdout.write(data);\n }\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n if (logToTerminal && !stdin) {\n process.stderr.write(data);\n }\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n if (err.name === 'AbortError') {\n reject(err);\n return;\n }\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n};\n","// @ts-expect-error - node-schedule types are missing\nimport schedule from 'node-schedule';\nimport { listChats } from '../shared/chats.js';\nimport { readChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { executeDirectMessage, getInitialRouterState } from './message.js';\nimport type { CronJob, Settings } from '../shared/config.js';\nimport fs from 'node:fs/promises';\nimport { getSettingsPath } from '../shared/workspace.js';\nimport { applyEnvOverrides } from '../shared/utils/env.js';\nimport { runCommand } from './utils/spawn.js';\n\nexport class CronManager {\n private jobs = new Map<string, schedule.Job>();\n\n private getJobKey(chatId: string, jobId: string) {\n return `${chatId}::${jobId}`;\n }\n\n async init() {\n const chats = await listChats();\n for (const chatId of chats) {\n const settings = await readChatSettings(chatId);\n if (settings?.jobs) {\n for (const job of settings.jobs) {\n try {\n this.scheduleJob(chatId, job);\n } catch (err) {\n console.error(\n `Failed to initialize job ${job.id} for chat ${chatId}:`,\n err instanceof Error ? err.message : err\n );\n }\n }\n }\n }\n }\n\n scheduleJob(chatId: string, job: CronJob) {\n this.unscheduleJob(chatId, job.id);\n\n let rule: string | Date;\n let isOneOff = false;\n\n if ('cron' in job.schedule) {\n rule = (job.schedule as { cron: string }).cron;\n } else if ('every' in job.schedule) {\n const everyStr = (job.schedule as { every: string }).every;\n const match = everyStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?)$/i);\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n if (unit.startsWith('m')) {\n rule = `*/${val} * * * *`;\n } else if (unit.startsWith('h')) {\n rule = `0 */${val} * * *`;\n } else if (unit.startsWith('d')) {\n rule = `0 0 */${val} * *`;\n } else {\n rule = everyStr;\n }\n } else {\n rule = everyStr;\n }\n } else if ('at' in job.schedule) {\n const atStr = (job.schedule as { at: string }).at;\n const match = atStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?|s|sec|seconds?)$/i);\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n let ms = 0;\n if (unit.startsWith('s')) ms = val * 1000;\n else if (unit.startsWith('m')) ms = val * 60 * 1000;\n else if (unit.startsWith('h')) ms = val * 60 * 60 * 1000;\n else if (unit.startsWith('d')) ms = val * 24 * 60 * 60 * 1000;\n rule = new Date(Date.now() + ms);\n } else {\n rule = new Date(atStr);\n if (isNaN(rule.getTime())) {\n throw new Error(`Invalid date format for 'at' schedule: ${atStr}`);\n }\n }\n isOneOff = true;\n } else {\n console.warn(`Unknown schedule format for job ${job.id}`);\n return;\n }\n\n try {\n const scheduledJob = schedule.scheduleJob(rule, async () => {\n await this.executeJob(chatId, job, isOneOff);\n });\n if (scheduledJob) {\n this.jobs.set(this.getJobKey(chatId, job.id), scheduledJob);\n }\n } catch (err) {\n console.error(`Failed to schedule job ${job.id} for chat ${chatId}:`, err);\n }\n }\n\n unscheduleJob(chatId: string, jobId: string) {\n const key = this.getJobKey(chatId, jobId);\n const job = this.jobs.get(key);\n if (job) {\n job.cancel();\n this.jobs.delete(key);\n }\n }\n\n private async executeJob(chatId: string, job: CronJob, isOneOff: boolean) {\n try {\n const settingsPath = getSettingsPath();\n let globalSettings: Settings | undefined;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n globalSettings = JSON.parse(settingsStr) as Settings;\n } catch {\n globalSettings = undefined;\n }\n\n const overrideSessionId = job.session?.type === 'new' ? crypto.randomUUID() : undefined;\n const routerState = await getInitialRouterState(\n chatId,\n job.message,\n process.cwd(),\n job.agentId,\n overrideSessionId\n );\n\n if (job.env !== undefined) {\n routerState.env = routerState.env || {};\n applyEnvOverrides(routerState.env, job.env);\n }\n if (job.reply !== undefined) routerState.reply = job.reply;\n\n await executeDirectMessage(\n chatId,\n routerState,\n globalSettings,\n process.cwd(),\n runCommand,\n false,\n job.message\n );\n\n if (isOneOff) {\n const chatSettings = await readChatSettings(chatId);\n if (chatSettings && chatSettings.jobs) {\n chatSettings.jobs = chatSettings.jobs.filter((j) => j.id !== job.id);\n await writeChatSettings(chatId, chatSettings);\n }\n this.unscheduleJob(chatId, job.id);\n }\n } catch (err) {\n console.error(`Error executing cron job ${job.id} for chat ${chatId}:`, err);\n }\n }\n}\n\nexport const cronManager = new CronManager();\n","/* eslint-disable max-lines */\nimport { initTRPC, TRPCError } from '@trpc/server';\nimport { z } from 'zod';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, DAEMON_EVENT_TYPING } from './events.js';\nimport {\n getSettingsPath,\n readChatSettings,\n writeChatSettings,\n getAgent,\n getWorkspaceRoot,\n readPolicies,\n getClawminiDir,\n} from '../shared/workspace.js';\nimport { PolicyRequestService } from './policy-request-service.js';\nimport { RequestStore } from './request-store.js';\nimport { CronJobSchema } from '../shared/config.js';\nimport { handleUserMessage } from './message.js';\nimport { getDefaultChatId, getMessages } from './chats.js';\nimport { runCommand } from './utils/spawn.js';\nimport { cronManager } from './cron.js';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { TokenPayload } from './auth.js';\n\nexport interface Context {\n req?: IncomingMessage | undefined;\n res?: ServerResponse | undefined;\n isApiServer?: boolean | undefined;\n tokenPayload?: TokenPayload | null | undefined;\n}\n\nconst t = initTRPC.context<Context>().create();\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n\nconst apiAuthMiddleware = t.middleware(({ ctx, next }) => {\n if (ctx.isApiServer) {\n if (!ctx.tokenPayload) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing or invalid token' });\n }\n }\n return next({\n ctx: {\n ...ctx,\n tokenPayload: ctx.tokenPayload,\n },\n });\n});\n\nexport const apiProcedure = t.procedure.use(apiAuthMiddleware);\n\nexport async function getUniquePath(p: string): Promise<string> {\n let currentPath = p;\n let counter = 1;\n while (true) {\n try {\n await fs.stat(currentPath);\n const ext = path.extname(p);\n const base = path.basename(p, ext);\n currentPath = path.join(path.dirname(p), `${base}-${counter}${ext}`);\n counter++;\n } catch {\n return currentPath;\n }\n }\n}\n\nasync function resolveAgentDir(\n agentId: string | undefined | null,\n workspaceRoot: string\n): Promise<string> {\n if (agentId && agentId !== 'default') {\n try {\n const agent = await getAgent(agentId, workspaceRoot);\n if (agent && agent.directory) {\n return path.resolve(workspaceRoot, agent.directory);\n }\n } catch (err: unknown) {\n console.warn(`Could not load custom agent '${agentId}' for resolving directory:`, err);\n }\n return path.resolve(workspaceRoot, agentId);\n }\n return workspaceRoot;\n}\n\nasync function resolveAndCheckChatId(ctx: Context, inputChatId?: string): Promise<string> {\n const chatId =\n inputChatId ??\n (ctx.isApiServer && ctx.tokenPayload ? ctx.tokenPayload.chatId : await getDefaultChatId());\n\n if (ctx.isApiServer && ctx.tokenPayload) {\n if (ctx.tokenPayload.chatId !== chatId) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Token not authorized for this chat' });\n }\n }\n\n return chatId;\n}\n\nasync function getAgentFilesDir(\n agentId: string | undefined,\n chatId: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n settings: any,\n workspaceRoot: string\n): Promise<string> {\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n let agentFilesDir = settings?.defaultAgent?.files || './attachments';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n\n if (targetAgentId !== 'default') {\n try {\n const customAgent = await getAgent(targetAgentId, workspaceRoot);\n if (customAgent?.files) {\n agentFilesDir = customAgent.files;\n }\n } catch (err: unknown) {\n console.warn(\n `Could not load custom agent '${targetAgentId}' for resolving files directory:`,\n err\n );\n }\n }\n\n return path.resolve(agentDir, agentFilesDir);\n}\n\nasync function validateAttachments(files: string[]): Promise<void> {\n const { pathIsInsideDir } = await import('../shared/utils/fs.js');\n const { getClawminiDir } = await import('../shared/workspace.js');\n const tmpDir = path.join(getClawminiDir(process.cwd()), 'tmp');\n\n for (const file of files) {\n const absoluteFile = path.resolve(process.cwd(), file);\n if (!pathIsInsideDir(absoluteFile, tmpDir)) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be inside the temporary directory.',\n });\n }\n try {\n await fs.access(absoluteFile);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n }\n}\n\nasync function validateLogFile(\n file: string,\n agentDir: string,\n workspaceRoot: string\n): Promise<string> {\n const { pathIsInsideDir } = await import('../shared/utils/fs.js');\n // The agent sends paths relative to its working directory.\n // We resolve to an absolute path to verify it is within the agent's directory.\n const resolvedPath = path.resolve(agentDir, file);\n\n if (!pathIsInsideDir(resolvedPath, agentDir, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be within the agent workspace.',\n });\n }\n\n try {\n await fs.access(resolvedPath);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n\n // Convert the absolute path to a path relative to the WORKSPACE directory.\n // This allows adapters (like discord-adapter) to easily resolve it against their own view of the workspace.\n return path.relative(workspaceRoot, resolvedPath);\n}\n\nconst AppRouter = router({\n sendMessage: apiProcedure\n .input(\n z.object({\n type: z.literal('send-message'),\n client: z.literal('cli'),\n data: z.object({\n message: z.string(),\n chatId: z.string().optional(),\n sessionId: z.string().optional(),\n agentId: z.string().optional(),\n noWait: z.boolean().optional(),\n files: z.array(z.string()).optional(),\n adapter: z.string().optional(),\n }),\n })\n )\n .mutation(async ({ input, ctx }) => {\n let message = input.data.message;\n const chatId = await resolveAndCheckChatId(ctx, input.data.chatId);\n const noWait = input.data.noWait ?? false;\n const sessionId = input.data.sessionId;\n const agentId = input.data.agentId;\n const settingsPath = getSettingsPath();\n\n let settings;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n settings = JSON.parse(settingsStr);\n } catch (err) {\n throw new Error(`Failed to read settings from ${settingsPath}: ${err}`, { cause: err });\n }\n\n const files = input.data.files;\n if (files && files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n const absoluteFilesDir = await getAgentFilesDir(agentId, chatId, settings, workspaceRoot);\n\n const adapterNamespace = input.data.adapter || 'cli';\n const targetDir = path.join(absoluteFilesDir, adapterNamespace);\n\n const { pathIsInsideDir } = await import('../shared/utils/fs.js');\n\n if (!pathIsInsideDir(targetDir, workspaceRoot, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Target directory must be within the workspace.',\n });\n }\n\n await validateAttachments(files);\n\n await fs.mkdir(targetDir, { recursive: true });\n\n const finalPaths: string[] = [];\n for (const file of files) {\n const fileName = path.basename(file);\n const targetPath = await getUniquePath(path.join(targetDir, fileName));\n\n try {\n await fs.rename(file, targetPath);\n } catch {\n await fs.copyFile(file, targetPath);\n await fs.unlink(file);\n }\n\n finalPaths.push(path.relative(agentDir, targetPath));\n }\n\n const fileList = `Attached files:\\n${finalPaths.map((p) => `- ${p}`).join('\\n')}`;\n message = message ? `${message}\\n\\n${fileList}` : fileList;\n }\n\n await handleUserMessage(\n chatId,\n message,\n settings,\n undefined,\n noWait,\n (args) => runCommand({ ...args, logToTerminal: true }),\n sessionId,\n agentId\n );\n\n return { success: true };\n }),\n getMessages: apiProcedure\n .input(z.object({ chatId: z.string().optional(), limit: z.number().optional() }))\n .query(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n return getMessages(chatId, input.limit);\n }),\n waitForMessages: apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n lastMessageId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, ctx, signal }) {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n\n // 1. Check if there are already new messages\n if (input.lastMessageId) {\n const messages = await getMessages(chatId);\n const lastIndex = messages.findIndex((m) => m.id === input.lastMessageId);\n if (lastIndex !== -1 && lastIndex < messages.length - 1) {\n yield messages.slice(lastIndex + 1);\n }\n }\n\n // 2. Listen for new messages\n const { on } = await import('node:events');\n try {\n for await (const [event] of on(daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, { signal })) {\n if (event.chatId === chatId) {\n yield [event.message];\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n }),\n waitForTyping: apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, ctx, signal }) {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n\n const { on } = await import('node:events');\n try {\n for await (const [event] of on(daemonEvents, DAEMON_EVENT_TYPING, { signal })) {\n if (event.chatId === chatId) {\n yield event;\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n }),\n ping: publicProcedure.query(() => {\n return { status: 'ok' };\n }),\n shutdown: publicProcedure.mutation(() => {\n // Schedule a shutdown shortly after the response is sent\n setTimeout(() => {\n console.log('Shutting down daemon...');\n process.kill(process.pid, 'SIGTERM');\n }, 100);\n return { success: true };\n }),\n logMessage: apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n message: z.string().optional(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n\n const filePaths: string[] = [];\n if (input.files && input.files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n\n for (const file of input.files) {\n const validPath = await validateLogFile(file, agentDir, workspaceRoot);\n filePaths.push(validPath);\n }\n }\n\n const filesArgStr = filePaths.map((p) => ` --file ${p}`).join('');\n const messageStr = input.message || '';\n const logMsg: import('./chats.js').CommandLogMessage = {\n id,\n messageId: id,\n role: 'log',\n source: 'router',\n content: messageStr,\n stderr: '',\n timestamp,\n command: `clawmini-lite log${filesArgStr}`,\n cwd: process.cwd(),\n exitCode: 0,\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await import('./chats.js').then((m) => m.appendMessage(chatId, logMsg));\n return { success: true };\n }),\n listCronJobs: apiProcedure\n .input(z.object({ chatId: z.string().optional() }))\n .query(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const settings = await readChatSettings(chatId);\n return settings?.jobs ?? [];\n }),\n addCronJob: apiProcedure\n .input(z.object({ chatId: z.string().optional(), job: CronJobSchema }))\n .mutation(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const settings = (await readChatSettings(chatId)) || {};\n const cronJobs = settings.jobs ?? [];\n const existingIndex = cronJobs.findIndex((j) => j.id === input.job.id);\n if (existingIndex >= 0) {\n cronJobs[existingIndex] = input.job;\n } else {\n cronJobs.push(input.job);\n }\n settings.jobs = cronJobs;\n await writeChatSettings(chatId, settings);\n cronManager.scheduleJob(chatId, input.job);\n return { success: true };\n }),\n deleteCronJob: apiProcedure\n .input(z.object({ chatId: z.string().optional(), id: z.string() }))\n .mutation(async ({ input, ctx }) => {\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const settings = await readChatSettings(chatId);\n if (!settings || !settings.jobs) {\n return { success: true, deleted: false };\n }\n const initialLength = settings.jobs.length;\n settings.jobs = settings.jobs.filter((j) => j.id !== input.id);\n if (settings.jobs.length !== initialLength) {\n await writeChatSettings(chatId, settings);\n cronManager.unscheduleJob(chatId, input.id);\n return { success: true, deleted: true };\n }\n return { success: true, deleted: false };\n }),\n listPolicies: apiProcedure.query(async () => {\n return await readPolicies();\n }),\n executePolicyHelp: apiProcedure\n .input(z.object({ commandName: z.string() }))\n .query(async ({ input }) => {\n const config = await readPolicies();\n const policy = config?.policies?.[input.commandName];\n\n if (!policy) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Policy not found: ${input.commandName}`,\n });\n }\n\n if (!policy.allowHelp) {\n return { stdout: '', stderr: 'This command does not support --help\\n', exitCode: 1 };\n }\n\n const { executeSafe } = await import('./policy-utils.js');\n const fullArgs = [...(policy.args || []), '--help'];\n const { stdout, stderr, exitCode } = await executeSafe(policy.command, fullArgs, {\n cwd: getWorkspaceRoot(),\n });\n\n return { stdout, stderr, exitCode };\n }),\n createPolicyRequest: apiProcedure\n .input(\n z.object({\n commandName: z.string(),\n args: z.array(z.string()),\n fileMappings: z.record(z.string(), z.string()),\n chatId: z.string().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const snapshotDir = path.join(getClawminiDir(process.cwd()), 'tmp', 'snapshots');\n const store = new RequestStore(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n const service = new PolicyRequestService(store, agentDir, snapshotDir);\n\n const chatId = await resolveAndCheckChatId(ctx, input.chatId);\n const agentId = ctx.tokenPayload?.agentId ?? 'unknown';\n\n const request = await service.createRequest(\n input.commandName,\n input.args,\n input.fileMappings,\n chatId,\n agentId\n );\n\n const { generateRequestPreview } = await import('./policy-utils.js');\n const previewContent = await generateRequestPreview(request);\n\n const logMsg = {\n id: (await import('node:crypto')).randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: (await import('node:crypto')).randomUUID(),\n role: 'log' as const,\n source: 'router' as const,\n content: previewContent,\n stderr: '',\n timestamp: new Date().toISOString(),\n command: 'policy-request',\n cwd: process.cwd(),\n exitCode: 0,\n };\n\n await import('./chats.js').then((m) => m.appendMessage(chatId, logMsg));\n return request;\n }),\n});\n\nexport type AppRouter = typeof AppRouter;\nexport const appRouter = AppRouter;\n","import http from 'node:http';\nimport net from 'node:net';\nimport fs from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { createHTTPHandler } from '@trpc/server/adapters/standalone';\nimport { appRouter } from './router.js';\nimport {\n getSocketPath,\n getClawminiDir,\n getSettingsPath,\n readSettings,\n readEnvironment,\n getEnvironmentPath,\n getWorkspaceRoot,\n} from '../shared/workspace.js';\nimport { cronManager } from './cron.js';\nimport { SettingsSchema } from '../shared/config.js';\nimport { validateToken, getApiContext } from './auth.js';\nimport path from 'node:path';\nimport { exportLiteToEnvironment } from '../shared/lite.js';\n\nexport async function initDaemon() {\n const socketPath = getSocketPath();\n const clawminiDir = getClawminiDir();\n\n // Ensure the .clawmini directory exists\n if (!fs.existsSync(clawminiDir)) {\n throw new Error(`${clawminiDir} does not exist`);\n }\n\n // Read settings to check if API is enabled\n const settingsPath = getSettingsPath();\n let apiCtx: ReturnType<typeof getApiContext> = null;\n\n if (fs.existsSync(settingsPath)) {\n try {\n const settingsStr = fs.readFileSync(settingsPath, 'utf8');\n const settings = JSON.parse(settingsStr);\n const parsed = SettingsSchema.safeParse(settings);\n if (parsed.success) {\n apiCtx = getApiContext(parsed.data);\n }\n } catch (err) {\n console.warn(`Failed to read or parse settings from ${settingsPath}:`, err);\n }\n }\n\n const runHooks = async (hookType: 'up' | 'down') => {\n try {\n const currentSettings = await readSettings();\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n if (!currentSettings?.environments) return;\n for (const [envPath, envName] of Object.entries(currentSettings.environments)) {\n try {\n const envConfig = await readEnvironment(envName);\n const envDir = getEnvironmentPath(envName);\n const affectedDir = path.resolve(workspaceRoot, envPath);\n\n // Try to export clawmini-lite to the environment directory\n if (hookType === 'up' && envConfig) {\n await exportLiteToEnvironment(envName, envConfig, affectedDir);\n }\n\n const command = envConfig?.[hookType];\n if (command) {\n console.log(`Executing '${hookType}' hook for environment '${envName}': ${command}`);\n execSync(command, {\n cwd: affectedDir,\n stdio: 'inherit',\n env: { ...process.env, ENV_DIR: envDir },\n timeout: hookType === 'down' ? 10000 : undefined,\n });\n }\n } catch (err) {\n console.error(`Failed to execute '${hookType}' hook for environment '${envName}':`, err);\n if (hookType === 'up') throw err;\n }\n }\n } catch (err) {\n console.error(`Failed to run '${hookType}' hooks:`, err);\n if (hookType === 'up') throw err;\n }\n };\n\n // Ensure the old socket file is removed, but first check if another daemon is actively listening\n if (fs.existsSync(socketPath)) {\n const isSocketInUse = await new Promise<boolean>((resolve) => {\n const client = net.createConnection({ path: socketPath });\n client.on('connect', () => {\n client.destroy();\n resolve(true);\n });\n client.on('error', () => {\n resolve(false);\n });\n });\n\n if (isSocketInUse) {\n console.log('Daemon is already running (socket is active). Exiting.');\n process.exit(0);\n }\n\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore\n }\n }\n\n let isReady = false;\n let readyPromiseResolve: () => void;\n const readyPromise = new Promise<void>((resolve) => {\n readyPromiseResolve = resolve;\n });\n\n const handler = createHTTPHandler({\n router: appRouter,\n createContext: ({ req, res }) => ({ req, res, isApiServer: false }),\n });\n\n const server = http.createServer(async (req, res) => {\n if (!isReady) {\n await readyPromise;\n }\n // Only accept POST requests on /trpc/ path if needed, but since we are running over Unix socket, we map directly\n handler(req, res);\n });\n\n await new Promise<void>((resolve, reject) => {\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log('Daemon is already running (socket bind failed). Exiting.');\n process.exit(0);\n }\n reject(err);\n });\n server.listen(socketPath, () => {\n console.log(`Daemon initialized and listening on ${socketPath}`);\n resolve();\n });\n });\n\n await runHooks('up');\n\n isReady = true;\n readyPromiseResolve!();\n\n // Initialize cron jobs\n cronManager.init().catch((err) => {\n console.error('Failed to initialize cron manager:', err);\n });\n\n let apiServer: http.Server | undefined;\n if (apiCtx) {\n const apiHandler = createHTTPHandler({\n router: appRouter,\n createContext: ({ req, res }) => {\n let tokenPayload = null;\n const authHeader = req.headers.authorization;\n if (authHeader && authHeader.startsWith('Bearer ')) {\n const token = authHeader.substring(7);\n tokenPayload = validateToken(token);\n }\n return { req, res, isApiServer: true, tokenPayload };\n },\n });\n\n apiServer = http.createServer((req, res) => {\n apiHandler(req, res);\n });\n\n const host = apiCtx.host;\n const port = apiCtx.port;\n apiServer.listen(port, host, () => {\n console.log(`Daemon HTTP API initialized and listening on http://${host}:${port}`);\n });\n }\n\n let isShuttingDown = false;\n const shutdown = async () => {\n if (isShuttingDown) return;\n isShuttingDown = true;\n console.log('Daemon shutting down...');\n\n await runHooks('down');\n\n server.close();\n if (apiServer) apiServer.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n process.on('exit', () => {\n if (fs.existsSync(socketPath)) {\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore errors during exit cleanup\n }\n }\n });\n}\n\n// Only auto-initialize if run directly\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n initDaemon().catch((err) => {\n console.error('Daemon initialization failed:', err);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as readSettings, h as readEnvironment, u as getWorkspaceRoot } from "./workspace-BC1ahx4R.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -77,4 +77,4 @@ async function exportLiteToAllEnvironments(startDir = process.cwd()) {
|
|
|
77
77
|
|
|
78
78
|
//#endregion
|
|
79
79
|
export { writeLiteScript as i, exportLiteToEnvironment as n, getLiteScriptContent as r, exportLiteToAllEnvironments as t };
|
|
80
|
-
//# sourceMappingURL=lite-
|
|
80
|
+
//# sourceMappingURL=lite-DBUuHsX0.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lite-
|
|
1
|
+
{"version":3,"file":"lite-DBUuHsX0.mjs","names":[],"sources":["../src/shared/lite.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { readSettings, readEnvironment, getWorkspaceRoot } from './workspace.js';\nimport type { Environment } from './config.js';\n\nexport async function getLiteScriptContent(): Promise<string> {\n let liteScriptContent: string;\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n let liteScriptPath = path.resolve(__dirname, 'cli/lite.mjs'); // if bundled in a shared chunk at dist/\n\n try {\n await fs.access(liteScriptPath);\n } catch {\n try {\n // If bundled in dist/cli or dist/daemon and lite is next to it\n liteScriptPath = path.resolve(__dirname, 'lite.mjs');\n await fs.access(liteScriptPath);\n } catch {\n try {\n // If bundled in dist/daemon, it might be in ../cli/lite.mjs\n liteScriptPath = path.resolve(__dirname, '../cli/lite.mjs');\n await fs.access(liteScriptPath);\n } catch {\n // Fallback for development/testing when running from src/shared\n liteScriptPath = path.resolve(__dirname, '../../dist/cli/lite.mjs');\n }\n }\n }\n\n liteScriptContent = await fs.readFile(liteScriptPath, 'utf8');\n\n // Ensure it has the hashbang (if tsdown stripped it or if missing)\n if (!liteScriptContent.startsWith('#!')) {\n liteScriptContent = '#!/usr/bin/env node\\n' + liteScriptContent;\n }\n return liteScriptContent;\n}\n\nexport async function writeLiteScript(outPath: string): Promise<string> {\n const content = await getLiteScriptContent();\n\n let finalPath = outPath;\n const isDir =\n finalPath.endsWith(path.sep) ||\n !(\n path.extname(finalPath) === '.js' ||\n path.extname(finalPath) === '.mjs' ||\n path.basename(finalPath) === 'clawmini-lite'\n );\n\n try {\n const stat = await fs.stat(finalPath);\n if (stat.isDirectory()) {\n finalPath = path.join(finalPath, 'clawmini-lite.js');\n }\n } catch {\n if (\n isDir &&\n !path.extname(finalPath) &&\n !finalPath.endsWith('clawmini-lite') &&\n !finalPath.endsWith('clawmini-lite.js')\n ) {\n await fs.mkdir(finalPath, { recursive: true });\n finalPath = path.join(finalPath, 'clawmini-lite.js');\n }\n }\n\n const dir = path.dirname(finalPath);\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(finalPath, content, { mode: 0o755 });\n return finalPath;\n}\n\nexport async function exportLiteToEnvironment(\n envName: string,\n envConfig: Environment,\n affectedDir: string\n): Promise<boolean> {\n if (!envConfig?.exportLiteTo) return false;\n\n const finalExportPath = path.resolve(affectedDir, envConfig.exportLiteTo);\n\n if (\n !finalExportPath.startsWith(affectedDir + path.sep) &&\n finalExportPath !== affectedDir &&\n !finalExportPath.startsWith(affectedDir + '/')\n ) {\n console.warn(\n `Skipping export for environment '${envName}': exportLiteTo path '${envConfig.exportLiteTo}' escapes the environment target directory '${affectedDir}'`\n );\n return false;\n }\n\n try {\n const writtenPath = await writeLiteScript(finalExportPath);\n console.log(`Successfully exported clawmini-lite to ${writtenPath} (Environment: ${envName})`);\n return true;\n } catch (err) {\n console.error(\n `Failed to export clawmini-lite to ${finalExportPath} (Environment: ${envName}): ${err instanceof Error ? err.message : String(err)}`\n );\n return false;\n }\n}\n\nexport async function exportLiteToAllEnvironments(startDir = process.cwd()): Promise<boolean> {\n let exportedToEnvironments = false;\n try {\n const workspaceRoot = getWorkspaceRoot(startDir);\n const settings = await readSettings(workspaceRoot);\n if (settings?.environments) {\n for (const [envPath, envName] of Object.entries(settings.environments)) {\n const envConfig = await readEnvironment(envName, workspaceRoot);\n if (envConfig) {\n const affectedDir = path.resolve(workspaceRoot, envPath);\n const exported = await exportLiteToEnvironment(envName, envConfig, affectedDir);\n if (exported) {\n exportedToEnvironments = true;\n }\n }\n }\n }\n } catch {\n // Ignore settings read errors\n }\n return exportedToEnvironments;\n}\n"],"mappings":";;;;;;AAMA,eAAsB,uBAAwC;CAC5D,IAAI;CACJ,MAAM,YAAY,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;CAE9D,IAAI,iBAAiB,KAAK,QAAQ,WAAW,eAAe;AAE5D,KAAI;AACF,QAAM,GAAG,OAAO,eAAe;SACzB;AACN,MAAI;AAEF,oBAAiB,KAAK,QAAQ,WAAW,WAAW;AACpD,SAAM,GAAG,OAAO,eAAe;UACzB;AACN,OAAI;AAEF,qBAAiB,KAAK,QAAQ,WAAW,kBAAkB;AAC3D,UAAM,GAAG,OAAO,eAAe;WACzB;AAEN,qBAAiB,KAAK,QAAQ,WAAW,0BAA0B;;;;AAKzE,qBAAoB,MAAM,GAAG,SAAS,gBAAgB,OAAO;AAG7D,KAAI,CAAC,kBAAkB,WAAW,KAAK,CACrC,qBAAoB,0BAA0B;AAEhD,QAAO;;AAGT,eAAsB,gBAAgB,SAAkC;CACtE,MAAM,UAAU,MAAM,sBAAsB;CAE5C,IAAI,YAAY;CAChB,MAAM,QACJ,UAAU,SAAS,KAAK,IAAI,IAC5B,EACE,KAAK,QAAQ,UAAU,KAAK,SAC5B,KAAK,QAAQ,UAAU,KAAK,UAC5B,KAAK,SAAS,UAAU,KAAK;AAGjC,KAAI;AAEF,OADa,MAAM,GAAG,KAAK,UAAU,EAC5B,aAAa,CACpB,aAAY,KAAK,KAAK,WAAW,mBAAmB;SAEhD;AACN,MACE,SACA,CAAC,KAAK,QAAQ,UAAU,IACxB,CAAC,UAAU,SAAS,gBAAgB,IACpC,CAAC,UAAU,SAAS,mBAAmB,EACvC;AACA,SAAM,GAAG,MAAM,WAAW,EAAE,WAAW,MAAM,CAAC;AAC9C,eAAY,KAAK,KAAK,WAAW,mBAAmB;;;CAIxD,MAAM,MAAM,KAAK,QAAQ,UAAU;AACnC,OAAM,GAAG,MAAM,KAAK,EAAE,WAAW,MAAM,CAAC;AACxC,OAAM,GAAG,UAAU,WAAW,SAAS,EAAE,MAAM,KAAO,CAAC;AACvD,QAAO;;AAGT,eAAsB,wBACpB,SACA,WACA,aACkB;AAClB,KAAI,CAAC,WAAW,aAAc,QAAO;CAErC,MAAM,kBAAkB,KAAK,QAAQ,aAAa,UAAU,aAAa;AAEzE,KACE,CAAC,gBAAgB,WAAW,cAAc,KAAK,IAAI,IACnD,oBAAoB,eACpB,CAAC,gBAAgB,WAAW,cAAc,IAAI,EAC9C;AACA,UAAQ,KACN,oCAAoC,QAAQ,wBAAwB,UAAU,aAAa,8CAA8C,YAAY,GACtJ;AACD,SAAO;;AAGT,KAAI;EACF,MAAM,cAAc,MAAM,gBAAgB,gBAAgB;AAC1D,UAAQ,IAAI,0CAA0C,YAAY,iBAAiB,QAAQ,GAAG;AAC9F,SAAO;UACA,KAAK;AACZ,UAAQ,MACN,qCAAqC,gBAAgB,iBAAiB,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GACpI;AACD,SAAO;;;AAIX,eAAsB,4BAA4B,WAAW,QAAQ,KAAK,EAAoB;CAC5F,IAAI,yBAAyB;AAC7B,KAAI;EACF,MAAM,gBAAgB,iBAAiB,SAAS;EAChD,MAAM,WAAW,MAAM,aAAa,cAAc;AAClD,MAAI,UAAU,aACZ,MAAK,MAAM,CAAC,SAAS,YAAY,OAAO,QAAQ,SAAS,aAAa,EAAE;GACtE,MAAM,YAAY,MAAM,gBAAgB,SAAS,cAAc;AAC/D,OAAI,WAGF;QADiB,MAAM,wBAAwB,SAAS,WADpC,KAAK,QAAQ,eAAe,QAAQ,CACuB,CAE7E,0BAAyB;;;SAK3B;AAGR,QAAO"}
|