clawmini 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/adapter-discord/index.mjs +1 -1
  2. package/dist/adapter-google-chat/index.mjs +1 -1
  3. package/dist/cli/index.mjs +2 -2
  4. package/dist/cli/lite.mjs +5 -3
  5. package/dist/cli/lite.mjs.map +1 -1
  6. package/dist/cli/propose-policy.mjs +2 -0
  7. package/dist/cli/propose-policy.mjs.map +1 -1
  8. package/dist/daemon/index.mjs +23 -8
  9. package/dist/daemon/index.mjs.map +1 -1
  10. package/dist/{lite-BbCFgEjn.mjs → lite-CBxOT1y5.mjs} +2 -2
  11. package/dist/{lite-BbCFgEjn.mjs.map → lite-CBxOT1y5.mjs.map} +1 -1
  12. package/{web/.svelte-kit/output/client/_app/immutable/chunks/uD5YsQE1.js → dist/web/_app/immutable/chunks/9nfWZDAH.js} +1 -1
  13. package/{web/.svelte-kit/output/client/_app/immutable/chunks/ByezTNKv.js → dist/web/_app/immutable/chunks/zsjBVtme.js} +1 -1
  14. package/dist/web/_app/immutable/entry/{app.Dkba_ZYl.js → app.CDP4hzOl.js} +2 -2
  15. package/dist/web/_app/immutable/entry/start.k4GcE1y3.js +1 -0
  16. package/dist/web/_app/immutable/nodes/{0.CFkkEWLe.js → 0.BK2mQuoD.js} +1 -1
  17. package/dist/web/_app/immutable/nodes/{1.BVylC0w0.js → 1.DsQuFekn.js} +1 -1
  18. package/dist/web/_app/immutable/nodes/{3.DEhhZBsS.js → 3.BZVFNxO-.js} +1 -1
  19. package/dist/web/_app/immutable/nodes/{4.C_OhFIXf.js → 4.L2HPGZB4.js} +1 -1
  20. package/dist/web/_app/immutable/nodes/{5.Bj0bsDBW.js → 5.B4lC9vS4.js} +1 -1
  21. package/dist/web/_app/version.json +1 -1
  22. package/dist/web/index.html +6 -6
  23. package/dist/{workspace-CEdb2nPR.mjs → workspace-BJmJBfKi.mjs} +3 -1
  24. package/dist/workspace-BJmJBfKi.mjs.map +1 -0
  25. package/docs/23_custom_token_env/development_log.md +31 -0
  26. package/docs/23_custom_token_env/notes.md +16 -0
  27. package/docs/23_custom_token_env/prd.md +42 -0
  28. package/docs/23_custom_token_env/questions.md +8 -0
  29. package/docs/23_custom_token_env/tickets.md +54 -0
  30. package/napkin.md +1 -0
  31. package/package.json +1 -1
  32. package/src/adapter-google-chat/client.test.ts +1 -1
  33. package/src/cli/e2e/daemon.test.ts +103 -0
  34. package/src/cli/e2e/messages.test.ts +5 -2
  35. package/src/cli/lite.ts +10 -3
  36. package/src/daemon/agent/agent-session.ts +20 -4
  37. package/src/daemon/utils/spawn.ts +2 -1
  38. package/src/shared/config.ts +2 -0
  39. package/templates/environments/macos/sandbox.sb +8 -0
  40. package/templates/environments/macos-proxy/allowlist.txt +4 -0
  41. package/templates/environments/macos-proxy/proxy.mjs +25 -20
  42. package/templates/environments/macos-proxy/sandbox.sb +8 -0
  43. package/templates/gemini/.gemini/settings.json +6 -1
  44. package/templates/gemini/settings.json +22 -21
  45. package/templates/gemini-claw/.gemini/settings.json +6 -1
  46. package/templates/gemini-claw/GEMINI.md +1 -1
  47. package/templates/gemini-claw/settings.json +26 -25
  48. package/web/.svelte-kit/generated/server/internal.js +1 -1
  49. package/web/.svelte-kit/output/client/.vite/manifest.json +26 -26
  50. package/{dist/web/_app/immutable/chunks/uD5YsQE1.js → web/.svelte-kit/output/client/_app/immutable/chunks/9nfWZDAH.js} +1 -1
  51. package/{dist/web/_app/immutable/chunks/ByezTNKv.js → web/.svelte-kit/output/client/_app/immutable/chunks/zsjBVtme.js} +1 -1
  52. package/web/.svelte-kit/output/client/_app/immutable/entry/{app.Dkba_ZYl.js → app.CDP4hzOl.js} +2 -2
  53. package/web/.svelte-kit/output/client/_app/immutable/entry/start.k4GcE1y3.js +1 -0
  54. package/web/.svelte-kit/output/client/_app/immutable/nodes/{0.CFkkEWLe.js → 0.BK2mQuoD.js} +1 -1
  55. package/web/.svelte-kit/output/client/_app/immutable/nodes/{1.BVylC0w0.js → 1.DsQuFekn.js} +1 -1
  56. package/web/.svelte-kit/output/client/_app/immutable/nodes/{3.DEhhZBsS.js → 3.BZVFNxO-.js} +1 -1
  57. package/web/.svelte-kit/output/client/_app/immutable/nodes/{4.C_OhFIXf.js → 4.L2HPGZB4.js} +1 -1
  58. package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.Bj0bsDBW.js → 5.B4lC9vS4.js} +1 -1
  59. package/web/.svelte-kit/output/client/_app/version.json +1 -1
  60. package/web/.svelte-kit/output/server/chunks/internal.js +1 -1
  61. package/web/.svelte-kit/output/server/manifest-full.js +1 -1
  62. package/web/.svelte-kit/output/server/manifest.js +1 -1
  63. package/web/.svelte-kit/output/server/nodes/0.js +1 -1
  64. package/web/.svelte-kit/output/server/nodes/1.js +1 -1
  65. package/web/.svelte-kit/output/server/nodes/3.js +1 -1
  66. package/web/.svelte-kit/output/server/nodes/4.js +1 -1
  67. package/web/.svelte-kit/output/server/nodes/5.js +1 -1
  68. package/dist/web/_app/immutable/entry/start.B_seWfvF.js +0 -1
  69. package/dist/workspace-CEdb2nPR.mjs.map +0 -1
  70. package/web/.svelte-kit/output/client/_app/immutable/entry/start.B_seWfvF.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["fs","path","fs","fs","shared.appendMessage","getMessages","findLastMessageFromStorage","crypto","fs","fs","fs","fetchMessages"],"sources":["../../src/daemon/api/trpc.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/request-store.ts","../../src/daemon/policy-utils.ts","../../src/daemon/events.ts","../../src/daemon/chats.ts","../../src/daemon/routers/slash-policies.ts","../../src/daemon/routers/session-timeout.ts","../../src/daemon/routers.ts","../../src/daemon/agent/agent-context.ts","../../src/daemon/agent/agent-extractors.ts","../../src/daemon/agent/utils.ts","../../src/daemon/agent/agent-runner.ts","../../src/daemon/utils/spawn.ts","../../src/daemon/agent/chat-logger.ts","../../src/shared/utils/env.ts","../../src/daemon/auth.ts","../../src/daemon/agent/task-scheduler.ts","../../src/daemon/agent/agent-session.ts","../../src/daemon/message.ts","../../src/daemon/cron.ts","../../src/daemon/api/router-utils.ts","../../src/daemon/api/user-router.ts","../../src/daemon/policy-request-service.ts","../../src/daemon/api/subagent-utils.ts","../../src/daemon/api/subagent-router.ts","../../src/daemon/api/agent-router.ts","../../src/daemon/index.ts"],"sourcesContent":["import { initTRPC, TRPCError } from '@trpc/server';\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","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 const id = crypto.randomUUID();\n return {\n ...state,\n message: newMessage,\n sessionId: id,\n nextSessionId: id,\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 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 normalizedId = normalizePolicyId(request.id);\n request.id = normalizedId;\n const filePath = this.getFilePath(normalizedId);\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 fs from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport path from 'node:path';\nimport { randomBytes } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { pathIsInsideDir } from '../shared/utils/fs.js';\nimport type { PolicyRequest, PolicyDefinition } from '../shared/policies.js';\n\nexport const MAX_SNAPSHOT_SIZE = 5 * 1024 * 1024;\n\nexport async function createSnapshot(\n requestedPath: string,\n agentDir: string,\n snapshotDir: string\n): Promise<string> {\n let realAgentDir: string;\n try {\n realAgentDir = await fs.realpath(agentDir);\n } catch (err) {\n throw new Error(`Agent directory not found or cannot be resolved: ${agentDir}`, { cause: err });\n }\n\n const resolvedRequestedPath = path.resolve(realAgentDir, requestedPath);\n\n // Verify it is inside the allowed agent directory\n if (!pathIsInsideDir(resolvedRequestedPath, realAgentDir, { allowSameDir: true })) {\n throw new Error(\n `Security Error: Path resolves outside the allowed agent directory: ${resolvedRequestedPath}`\n );\n }\n\n // Lstat prevents TOCTOU attacks by not following symlinks\n let stat;\n try {\n stat = await fs.lstat(resolvedRequestedPath);\n } catch (err) {\n throw new Error(`File not found or cannot be accessed: ${requestedPath}`, { cause: err });\n }\n\n if (stat.isSymbolicLink()) {\n throw new Error(`Security Error: Symlinks are not allowed: ${requestedPath}`);\n }\n\n if (!stat.isFile()) {\n throw new Error(`Requested path is not a file: ${requestedPath}`);\n }\n if (stat.size > MAX_SNAPSHOT_SIZE) {\n throw new Error(`File exceeds maximum snapshot size of 5MB: ${requestedPath}`);\n }\n\n // Generate unique filename for the snapshot\n const ext = path.extname(resolvedRequestedPath);\n const base = path.basename(resolvedRequestedPath, ext);\n\n await fs.mkdir(snapshotDir, { recursive: true });\n\n let snapshotPath: string;\n while (true) {\n const uniqueId = randomBytes(8).toString('hex');\n const snapshotFileName = `${base}_${uniqueId}${ext}`;\n snapshotPath = path.join(snapshotDir, snapshotFileName);\n\n try {\n await fs.copyFile(resolvedRequestedPath, snapshotPath, constants.COPYFILE_EXCL);\n break;\n } catch (err: unknown) {\n if (\n err instanceof Error &&\n 'code' in err &&\n (err as Error & { code?: string }).code === 'EEXIST'\n ) {\n continue;\n }\n throw err;\n }\n }\n\n return snapshotPath;\n}\n\nexport function interpolateArgs(args: string[], snapshots: Record<string, string>): string[] {\n return args.map((arg) => {\n let interpolated = arg;\n for (const [key, snapshotPath] of Object.entries(snapshots)) {\n const variable = `{{${key}}}`;\n interpolated = interpolated.replaceAll(variable, snapshotPath);\n }\n return interpolated;\n });\n}\n\nexport function executeSafe(\n command: string,\n args: string[],\n options?: { cwd?: string; env?: NodeJS.ProcessEnv }\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return new Promise((resolve) => {\n // Safe execution: shell is strictly false to prevent command injection\n const p = spawn(command, args, {\n shell: false,\n cwd: options?.cwd,\n env: options?.env,\n });\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n}\n\nexport async function executeRequest(\n request: PolicyRequest,\n policy: PolicyDefinition,\n cwd?: string\n): Promise<{ stdout: string; stderr: string; exitCode: number; commandStr: string }> {\n const fullArgs = [...(policy.args || []), ...request.args];\n const interpolatedArgs = interpolateArgs(fullArgs, request.fileMappings);\n\n const { stdout, stderr, exitCode } = await executeSafe(\n policy.command,\n interpolatedArgs,\n cwd ? { cwd } : undefined\n );\n\n const commandStr = `${policy.command} ${interpolatedArgs.join(' ')}`;\n return { stdout, stderr, exitCode, commandStr };\n}\n\nexport async function generateRequestPreview(request: PolicyRequest): Promise<string> {\n let previewContent = `Sandbox Policy Request: ${request.commandName}\\n`;\n previewContent += `ID: ${request.id}\\n`;\n if (request.args.length > 0) {\n previewContent += `Args: ${request.args.join(' ')}\\n`;\n }\n\n for (const [name, snapPath] of Object.entries(request.fileMappings)) {\n previewContent += `File [${name}]:\\n`;\n try {\n let content = await fs.readFile(snapPath, 'utf8');\n if (content.length > 500) {\n content = content.substring(0, 500) + '\\n... (truncated)\\n';\n }\n previewContent += content;\n } catch (e: unknown) {\n previewContent += `<Error reading file: ${(e as Error).message}>\\n`;\n }\n }\n\n previewContent += `\\nUse /approve ${request.id} or /reject ${request.id} [reason]`;\n return previewContent;\n}\n","import { EventEmitter } from 'node:events';\nimport type { ChatMessage } from '../shared/chats.js';\n\nexport const daemonEvents = new EventEmitter();\n\nexport const DAEMON_EVENT_MESSAGE_APPENDED = 'message-appended';\nexport const DAEMON_EVENT_TYPING = 'typing';\n\nexport function emitMessageAppended(chatId: string, message: ChatMessage) {\n daemonEvents.emit(DAEMON_EVENT_MESSAGE_APPENDED, { chatId, message });\n}\n\nexport function emitTyping(chatId: string) {\n daemonEvents.emit(DAEMON_EVENT_TYPING, { chatId });\n}\n","import * as shared from '../shared/chats.js';\nimport { emitMessageAppended } from './events.js';\n\nexport async function appendMessage(\n id: string,\n message: shared.ChatMessage,\n startDir = process.cwd()\n): Promise<void> {\n await shared.appendMessage(id, message, startDir);\n emitMessageAppended(id, message);\n}\n\nexport {\n type ChatMessage,\n type UserMessage,\n type CommandLogMessage,\n type SystemMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n type SubagentStatusMessage,\n getChatsDir,\n isValidChatId,\n createChat,\n listChats,\n deleteChat,\n getMessages,\n findLastMessage,\n getDefaultChatId,\n setDefaultChatId,\n DEFAULT_CHAT_ID,\n} from '../shared/chats.js';\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 { executeRequest } from '../policy-utils.js';\nimport { appendMessage } from '../chats.js';\nimport type { SystemMessage } 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\n const { stdout, stderr, exitCode } = await executeRequest(req, policy, getWorkspaceRoot());\n\n req.executionResult = { stdout, stderr, exitCode };\n await store.save(req);\n\n const agentMessage = `Request ${id} approved.\\n\\n${wrapInHtml('stdout', stdout)}\\n\\n${wrapInHtml('stderr', stderr)}\\n\\nExit Code: ${exitCode}`;\n\n const logMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_approved',\n displayRole: 'user',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n await appendMessage(state.chatId, logMsg);\n\n return {\n ...state,\n message: agentMessage,\n reply: `Approved request, running ${req.commandName}`,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\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 agentMessage = `Request ${id} rejected. Reason: ${reason}`;\n\n const logMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_rejected',\n displayRole: 'user',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n const userNotificationMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_rejected',\n displayRole: 'agent',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n await appendMessage(state.chatId, logMsg);\n await appendMessage(state.chatId, userNotificationMsg);\n\n return {\n ...state,\n message: agentMessage,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\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 type { RouterState } from './types.js';\nimport { randomUUID } from 'node:crypto';\n\nexport interface SessionTimeoutConfig {\n timeout?: string;\n prompt?: string;\n}\n\n/**\n * Router that automatically starts a new session after a period of inactivity.\n *\n * To register this router, add it to your `~/.gemini/settings.json`:\n * ```json\n * {\n * \"routers\": [\n * {\n * \"use\": \"session-timeout\",\n * \"with\": {\n * \"timeout\": \"60m\",\n * \"prompt\": \"This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.\"\n * }\n * }\n * ]\n * }\n * ```\n */\nexport function createSessionTimeoutRouter(config: SessionTimeoutConfig = {}) {\n const timeStr = config.timeout ?? '60m';\n const prompt =\n config.prompt ??\n 'This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.';\n\n return function (state: RouterState): RouterState {\n if (state.env?.__SESSION_TIMEOUT__ === 'true') {\n return state;\n }\n\n const sessionId = state.sessionId || crypto.randomUUID();\n const jobId = `__session_timeout__${sessionId}`;\n\n const jobs = {\n ...state.jobs,\n remove: [...(state.jobs?.remove || []), jobId, '__session_timeout__'],\n };\n\n return {\n ...state,\n sessionId,\n jobs: {\n ...jobs,\n add: [\n ...(jobs.add || []),\n // Add a job after the timeout that will send the prompt, reply to the user,\n // start a fresh session, and delete the job\n {\n id: jobId,\n schedule: { at: timeStr },\n message: prompt,\n reply: '[@clawmini/session-timeout] Starting a fresh session...',\n nextSessionId: randomUUID(),\n session: { type: 'existing', id: sessionId },\n env: { __SESSION_TIMEOUT__: 'true' },\n jobs: {\n remove: [jobId],\n },\n },\n ],\n },\n };\n };\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';\nimport { createSessionTimeoutRouter } from './routers/session-timeout.js';\nimport type { RouterConfig } from '../shared/config.js';\n\nexport const GLOBAL_ROUTERS: RouterConfig[] = ['@clawmini/session-timeout'];\n\nexport const USER_ROUTERS: RouterConfig[] = [\n '@clawmini/slash-new',\n '@clawmini/slash-command',\n '@clawmini/slash-stop',\n '@clawmini/slash-interrupt',\n '@clawmini/slash-policies',\n];\n\nexport function resolveRouters(\n userRouters: RouterConfig[],\n isUserMessage: boolean\n): RouterConfig[] {\n const resolvedGlobals: RouterConfig[] = [];\n const resolvedUsers: RouterConfig[] = [];\n\n const userConfigMap = new Map<string, unknown>();\n for (const r of userRouters) {\n const name = typeof r === 'string' ? r : r.use;\n const config = typeof r === 'string' ? {} : r.with || {};\n\n if (name.startsWith('@clawmini/')) {\n userConfigMap.set(name, config);\n } else {\n resolvedUsers.push(r);\n }\n }\n\n for (const globalRouter of GLOBAL_ROUTERS) {\n const name = typeof globalRouter === 'string' ? globalRouter : globalRouter.use;\n const baseConfig = typeof globalRouter === 'string' ? {} : globalRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n resolvedGlobals.push({ use: name, with: mergedConfig });\n }\n\n const defaultUserRouters: RouterConfig[] = [];\n for (const defaultUserRouter of USER_ROUTERS) {\n const name = typeof defaultUserRouter === 'string' ? defaultUserRouter : defaultUserRouter.use;\n const baseConfig = typeof defaultUserRouter === 'string' ? {} : defaultUserRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n defaultUserRouters.push({ use: name, with: mergedConfig });\n }\n\n if (isUserMessage) {\n return [...resolvedGlobals, ...defaultUserRouters, ...resolvedUsers];\n } else {\n return resolvedGlobals;\n }\n}\n\nexport async function executeRouterPipeline(\n initialState: RouterState,\n routers: RouterConfig[]\n): Promise<RouterState> {\n let state = { ...initialState };\n\n for (const routerDef of routers) {\n if (state.action === 'stop') {\n break;\n }\n\n const router = typeof routerDef === 'string' ? routerDef : routerDef.use;\n const config = typeof routerDef === 'string' ? {} : routerDef.with || {};\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 if (router === '@clawmini/session-timeout') {\n state = createSessionTimeoutRouter(config)(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 { type FallbackSchema } from '../../shared/config.js';\nimport {\n getActiveEnvironmentInfo,\n getEnvironmentPath,\n readEnvironment,\n} from '../../shared/workspace.js';\nimport { z } from 'zod';\n\nexport type Fallback = z.infer<typeof FallbackSchema>;\n\nfunction formatEnvironmentPrefix(\n prefix: string,\n replacements: { targetPath: string; executionCwd: string; envDir: string; envArgs: string }\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 sandboxExecutionContext(\n initialCommand: string,\n env: Record<string, string>,\n agentSpecificEnvKeys: Set<string>,\n executionCwd: string,\n cwd: string\n): Promise<string> {\n let command = initialCommand;\n const activeEnvInfo = await getActiveEnvironmentInfo(executionCwd, cwd);\n if (!activeEnvInfo) return command;\n\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 agentSpecificEnvKeys.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 agentSpecificEnvKeys.add(key);\n }\n }\n }\n\n if (activeEnv?.prefix) {\n const envArgs = Array.from(agentSpecificEnvKeys)\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: 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 return command;\n}\n","import type { RunCommandFn, RunCommandResult } from './types.js';\nimport type { Agent } from '../../shared/config.js';\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\nexport async function extractMessageContent(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getMessageContent) return {};\n return runExtractionCommand(\n 'getMessageContent',\n context.currentAgent.commands.getMessageContent,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n\nexport async function extractSessionId(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getSessionId) return {};\n return runExtractionCommand(\n 'getSessionId',\n context.currentAgent.commands.getSessionId,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n","export function formatPendingMessages(payloads: string[]): string {\n return payloads.map((text) => `<message>\\n${text}\\n</message>`).join('\\n\\n');\n}\n\nexport function isNewSession(env: Record<string, string>): boolean {\n return env['SESSION_ID'] === undefined;\n}\n","import { emitTyping } from '../events.js';\nimport type { ExecutionResponse, Message, RunCommandFn } from './types.js';\nimport { type Fallback } from './agent-context.js';\nimport { extractMessageContent, extractSessionId } from './agent-extractors.js';\nimport type { AgentSession } from './agent-session.js';\nimport { isNewSession } from './utils.js';\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 class AgentRunner {\n constructor(\n private readonly session: AgentSession,\n private readonly runCommand: RunCommandFn\n ) {}\n\n private async withTypingIndicator<T>(fn: () => Promise<T>): Promise<T> {\n const interval = setInterval(() => emitTyping(this.session.chatId), 5000);\n try {\n return await fn();\n } finally {\n clearInterval(interval);\n }\n }\n\n private *getExecutionAttempts() {\n const fallbacks = this.session.settings.fallbacks || [];\n const executionConfigs = [\n { fallback: undefined, retries: 0, delayMs: 1000 },\n ...fallbacks.map((f) => ({ fallback: f, retries: f.retries, delayMs: f.delayMs })),\n ];\n\n for (let configIdx = 0; configIdx < executionConfigs.length; configIdx++) {\n const config = executionConfigs[configIdx]!;\n const isFallbackConfig = configIdx > 0;\n\n for (let attempt = 0; attempt <= config.retries; attempt++) {\n yield {\n fallback: config.fallback,\n delay: calculateDelay(attempt, config.delayMs, isFallbackConfig),\n };\n }\n }\n }\n\n private async executeSingleAttempt(\n message: Message,\n fallback?: Fallback | undefined,\n signal?: AbortSignal | undefined\n ): Promise<{ success: boolean; response?: ExecutionResponse }> {\n const context = await this.session.buildExecutionContext(\n message.content,\n message.env,\n fallback\n );\n\n if (!context) return { success: false };\n\n const mainResult = await this.withTypingIndicator(() =>\n this.runCommand({\n command: context.command,\n cwd: this.session.workDirectory,\n env: context.env,\n signal,\n })\n );\n\n let success = mainResult.exitCode === 0;\n let finalContent = mainResult.stdout.trim();\n const additonalErrors = [];\n\n if (success && context.currentAgent.commands?.getMessageContent) {\n const extraction = await extractMessageContent(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result !== undefined) finalContent = extraction.result.trim();\n if (!finalContent) success = false;\n }\n\n let extractedSessionId: string | undefined;\n\n if (success && isNewSession(message.env) && context.currentAgent.commands?.getSessionId) {\n const extraction = await extractSessionId(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result) {\n extractedSessionId = extraction.result;\n }\n }\n\n return {\n success,\n response: {\n messageId: message.id,\n content: finalContent,\n command: context.command,\n cwd: this.session.workDirectory,\n extractedSessionId,\n result: {\n ...mainResult,\n stderr: [mainResult.stderr, ...additonalErrors].join('\\n\\n'),\n },\n },\n };\n }\n\n async executeWithFallbacks(\n message: Message,\n signal?: AbortSignal | undefined\n ): Promise<ExecutionResponse | undefined> {\n let lastResponse: ExecutionResponse | undefined;\n\n for (const attempt of this.getExecutionAttempts()) {\n if (attempt.delay > 0) {\n await this.session.logger.logCommandRetry({\n messageId: message.id,\n content: `Error running agent, retrying in ${Math.round(attempt.delay / 1000)} seconds...`,\n cwd: this.session.workDirectory,\n });\n await sleep(attempt.delay);\n }\n\n const attemptResult = await this.executeSingleAttempt(message, attempt.fallback, signal);\n\n lastResponse = attemptResult.response || lastResponse;\n if (attemptResult.success) {\n return lastResponse;\n }\n }\n\n return lastResponse;\n }\n}\n","import { spawn } from 'node:child_process';\nimport type { RunCommandFn } from '../agent/types.js';\n\nconst LOG_TO_TERMINAL = true;\n\nexport const runCommand: RunCommandFn = async ({\n command,\n cwd,\n env,\n stdin,\n signal,\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 (LOG_TO_TERMINAL && !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 (LOG_TO_TERMINAL && !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","import {\n appendMessage,\n getMessages,\n findLastMessage as findLastMessageFromStorage,\n type ChatMessage,\n type CommandLogMessage,\n type UserMessage,\n type SystemMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n type SubagentStatusMessage,\n} from '../chats.js';\nimport type { Logger } from './types.js';\n\nexport function createChatLogger(chatId: string, subagentId?: string): Logger {\n async function append<T extends ChatMessage>(msg: T): Promise<T> {\n const finalMsg = subagentId ? { ...msg, subagentId } : msg;\n await appendMessage(chatId, finalMsg);\n return finalMsg as T;\n }\n\n return {\n append,\n\n getMessages: async (limit?: number) => {\n const msgs = await getMessages(chatId);\n let filtered = msgs.filter((m) => m.subagentId === subagentId);\n if (limit !== undefined && limit > 0) {\n filtered = filtered.slice(-limit);\n }\n return filtered;\n },\n\n findLastMessage: async (predicate) => {\n return findLastMessageFromStorage(chatId, (msg: ChatMessage) => {\n if (msg.subagentId !== subagentId) return false;\n return predicate(msg);\n });\n },\n\n logUserMessage: async (msg) =>\n append({\n id: crypto.randomUUID(),\n role: 'user',\n content: msg,\n timestamp: new Date().toISOString(),\n } satisfies UserMessage),\n\n logCommandResult: async ({ messageId, content, command, cwd, result }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n\n command,\n cwd,\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n }),\n\n logSystemEvent: async ({ content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId: crypto.randomUUID(),\n\n stderr: '',\n command: '',\n cwd: '',\n stdout: '',\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logAutomaticReply: async ({ messageId, content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'system',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n event: 'router',\n displayRole: 'agent',\n } satisfies SystemMessage),\n\n logCommandRetry: async ({ messageId, content, cwd }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n\n // TODO remove these? Or include the actual command that was run?\n command: 'retry-delay',\n stderr: '',\n stdout: '',\n cwd,\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logSystemMessage: async ({ content, event, messageId, displayRole }) => {\n const msg: SystemMessage = {\n id: crypto.randomUUID(),\n role: 'system',\n content,\n event,\n timestamp: new Date().toISOString(),\n };\n if (messageId !== undefined) {\n msg.messageId = messageId;\n }\n if (displayRole !== undefined) {\n msg.displayRole = displayRole;\n }\n return append<SystemMessage>(msg);\n },\n\n logSubagentStatus: async ({ subagentId: targetSubagentId, status }) => {\n const msg: SubagentStatusMessage = {\n id: crypto.randomUUID(),\n role: 'subagent_status',\n content: `Subagent ${status}`,\n subagentId: targetSubagentId,\n status,\n timestamp: new Date().toISOString(),\n };\n return append<SubagentStatusMessage>(msg);\n },\n\n logAgentReply: async ({ content, files }) => {\n const msg: AgentReplyMessage = {\n id: crypto.randomUUID(),\n role: 'agent',\n content,\n timestamp: new Date().toISOString(),\n };\n if (files !== undefined) {\n msg.files = files;\n }\n return append<AgentReplyMessage>(msg);\n },\n\n logToolMessage: async ({ content, messageId, name, payload }) => {\n const msg: ToolMessage = {\n id: crypto.randomUUID(),\n role: 'tool',\n content,\n messageId,\n name,\n payload,\n timestamp: new Date().toISOString(),\n };\n return append<ToolMessage>(msg);\n },\n\n logPolicyRequestMessage: async ({\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n }) => {\n const msg: PolicyRequestMessage = {\n id: crypto.randomUUID(),\n role: 'policy',\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n timestamp: new Date().toISOString(),\n };\n return append<PolicyRequestMessage>(msg);\n },\n };\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","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 subagentId?: 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 interface AgentTask {\n id: string;\n rootChatId: string;\n dirPath: string;\n sessionId: string;\n text?: string;\n execute: (signal: AbortSignal) => Promise<void>;\n}\n\nclass ResourceLock {\n private resources = new Map<\n string,\n {\n activeWorkspace: string;\n count: number;\n waiters: Array<{\n workspaceId: string;\n resolve: () => void;\n reject: (err: Error) => void;\n }>;\n }\n >();\n\n async acquire(resourceId: string, workspaceId: string, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n throw error;\n }\n\n const res = this.resources.get(resourceId);\n if (!res) {\n this.resources.set(resourceId, { activeWorkspace: workspaceId, count: 1, waiters: [] });\n return;\n }\n\n if (res.activeWorkspace === workspaceId) {\n // Allow re-entrancy for the same rootChatId (workspaceId) so that the\n // root agent and its subagents can run in parallel in the same directory.\n // This ensures the root agent remains available to coordinate its subagents,\n // assuming it will manage conflicts appropriately.\n // Note: This risks starvation if agents/subagents from this workspace never release the resource.\n res.count++;\n return;\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter = { workspaceId, resolve, reject };\n res!.waiters.push(waiter);\n\n if (signal) {\n const onAbort = () => {\n const idx = res!.waiters.indexOf(waiter);\n if (idx !== -1) {\n res!.waiters.splice(idx, 1);\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n reject(error);\n }\n };\n signal.addEventListener('abort', onAbort);\n\n // Intercept resolve to clean up the listener\n waiter.resolve = () => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n };\n // Intercept reject to clean up the listener\n waiter.reject = (err: Error) => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n };\n }\n });\n }\n\n release(resourceId: string, _workspaceId: string) {\n const res = this.resources.get(resourceId);\n if (!res) return;\n\n res.count--;\n if (res.count === 0) {\n if (res.waiters.length > 0) {\n const nextWorkspace = res.waiters[0]!.workspaceId;\n res.activeWorkspace = nextWorkspace;\n\n const remainingWaiters = [];\n for (const waiter of res.waiters) {\n if (waiter.workspaceId === nextWorkspace) {\n res.count++;\n waiter.resolve();\n } else {\n remainingWaiters.push(waiter);\n }\n }\n res.waiters = remainingWaiters;\n } else {\n this.resources.delete(resourceId);\n }\n }\n }\n}\n\nclass TaskQueue {\n private queue: Array<{\n task: AgentTask;\n resolve: () => void;\n reject: (err: unknown) => void;\n }> = [];\n private activeTask: { task: AgentTask; controller: AbortController } | null = null;\n private isProcessing = false;\n\n constructor(\n public readonly sessionId: string,\n private resourceLock: ResourceLock,\n private onEmpty: (sessionId: string) => void\n ) {}\n\n enqueue(task: AgentTask): Promise<void> {\n return new Promise((resolve, reject) => {\n this.queue.push({ task, resolve, reject });\n this.process();\n });\n }\n\n private async process() {\n if (this.isProcessing || this.activeTask || this.queue.length === 0) return;\n this.isProcessing = true;\n\n while (this.queue.length > 0) {\n const next = this.queue.shift()!;\n const controller = new AbortController();\n this.activeTask = { task: next.task, controller };\n\n let acquired = false;\n try {\n await this.resourceLock.acquire(next.task.dirPath, next.task.rootChatId, controller.signal);\n acquired = true;\n\n if (!controller.signal.aborted) {\n await next.task.execute(controller.signal);\n }\n next.resolve();\n } catch (err) {\n next.reject(err);\n } finally {\n if (acquired) {\n this.resourceLock.release(next.task.dirPath, next.task.rootChatId);\n }\n this.activeTask = null;\n }\n }\n\n this.isProcessing = false;\n this.onEmpty(this.sessionId);\n }\n\n abortAll() {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n qTask.reject(error);\n }\n this.queue = [];\n }\n\n interruptAndExtract(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n if (this.activeTask.task.text !== undefined) {\n payloads.push(this.activeTask.task.text);\n }\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n extractPending(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task extracted for batching');\n error.name = 'AbortError';\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n hasTasks(): boolean {\n return this.activeTask !== null || this.queue.length > 0;\n }\n}\n\nexport class TaskScheduler {\n private queues = new Map<string, TaskQueue>();\n private resourceLock = new ResourceLock();\n\n private getQueueKey(sessionId: string, rootChatId: string): string {\n return `${rootChatId}:${sessionId}`;\n }\n\n public schedule(task: AgentTask): Promise<void> {\n const key = this.getQueueKey(task.sessionId, task.rootChatId);\n let queue = this.queues.get(key);\n if (!queue) {\n queue = new TaskQueue(task.sessionId, this.resourceLock, () => {\n this.queues.delete(key);\n });\n this.queues.set(key, queue);\n }\n return queue.enqueue(task);\n }\n\n public hasTasks(sessionId: string): boolean {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId && queue.hasTasks()) {\n return true;\n }\n }\n return false;\n }\n\n public extractPending(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.extractPending());\n }\n }\n return payloads;\n }\n\n public abortTasks(sessionId: string): void {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n queue.abortAll();\n }\n }\n }\n\n public interruptTasks(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.interruptAndExtract());\n }\n }\n return payloads;\n }\n}\n\nexport const taskScheduler = new TaskScheduler();\n","import type { Agent, Settings } from '../../shared/config.js';\nimport { AgentRunner } from './agent-runner.js';\nimport type { Logger, Message } from './types.js';\nimport { runCommand } from '../utils/spawn.js';\nimport {\n getAgent,\n getWorkspaceRoot,\n readAgentSessionSettings,\n writeAgentSessionSettings,\n readSettings,\n resolveAgentWorkDir,\n} from '../../shared/workspace.js';\nimport { formatPendingMessages, isNewSession } from './utils.js';\nimport { createChatLogger } from './chat-logger.js';\nimport { sandboxExecutionContext, type Fallback } from './agent-context.js';\nimport { applyEnvOverrides, getActiveEnvKeys } from '../../shared/utils/env.js';\nimport { getApiContext, generateToken } from '../auth.js';\nimport { taskScheduler } from './task-scheduler.js';\nimport { randomUUID } from 'node:crypto';\n\nexport class AgentSession {\n public readonly agentId: string;\n public readonly sessionId: string;\n public readonly chatId: string;\n public readonly subagentId: string | undefined;\n public readonly settings: Agent;\n public readonly workspaceRoot: string;\n public readonly globalSettings: Settings | undefined;\n public readonly logger: Logger;\n\n constructor(config: {\n agentId: string;\n sessionId: string;\n chatId: string;\n subagentId?: string;\n settings: Agent;\n workspaceRoot: string;\n globalSettings: Settings | undefined;\n logger?: Logger;\n }) {\n this.agentId = config.agentId;\n this.sessionId = config.sessionId;\n this.chatId = config.chatId;\n this.subagentId = config.subagentId;\n this.settings = config.settings;\n this.workspaceRoot = config.workspaceRoot;\n this.globalSettings = config.globalSettings;\n\n this.logger = config.logger ?? createChatLogger(this.chatId, this.subagentId);\n }\n\n async buildExecutionContext(\n messageContent: string,\n routerEnv: Record<string, string>,\n fallback?: Fallback\n ): Promise<{ command: string; env: Record<string, string>; currentAgent: Agent } | null> {\n const currentAgent: Agent = {\n ...this.settings,\n commands: {\n ...this.settings.commands,\n ...(fallback?.commands || {}),\n },\n env: {\n ...this.settings.env,\n ...(this.subagentId && this.settings.subagentEnv ? this.settings.subagentEnv : {}),\n ...(fallback?.env || {}),\n },\n };\n\n let initialCommand = currentAgent.commands?.new ?? '';\n const env = {\n ...process.env,\n CLAW_CLI_MESSAGE: messageContent,\n } as Record<string, string>;\n\n applyEnvOverrides(env, currentAgent.env);\n\n if (!isNewSession(routerEnv) && currentAgent.commands?.append) {\n initialCommand = currentAgent.commands.append;\n }\n\n if (!initialCommand) {\n return null;\n }\n\n const agentSpecificEnvKeys = getActiveEnvKeys(currentAgent.env);\n agentSpecificEnvKeys.add('CLAW_CLI_MESSAGE');\n\n Object.assign(env, routerEnv);\n Object.keys(routerEnv).forEach((k) => agentSpecificEnvKeys.add(k));\n\n const apiCtx = getApiContext(this.globalSettings);\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 agentSpecificEnvKeys.add('CLAW_API_URL');\n\n const token = generateToken({\n chatId: this.chatId,\n agentId: this.agentId,\n sessionId: this.sessionId,\n ...(this.subagentId ? { subagentId: this.subagentId } : {}),\n timestamp: Date.now(),\n });\n env['CLAW_API_TOKEN'] = token;\n agentSpecificEnvKeys.add('CLAW_API_TOKEN');\n }\n\n let command = initialCommand;\n command = await sandboxExecutionContext(\n command,\n env,\n agentSpecificEnvKeys,\n this.workDirectory,\n this.workspaceRoot\n );\n\n return { command, env, currentAgent };\n }\n\n createRunner(): AgentRunner {\n return new AgentRunner(this, runCommand);\n }\n\n get workDirectory(): string {\n return resolveAgentWorkDir(this.agentId, this.settings.directory, this.workspaceRoot);\n }\n\n stop() {\n taskScheduler.abortTasks(this.sessionId);\n }\n\n interrupt(message: Message): Message {\n const payloads = taskScheduler.interruptTasks(this.sessionId);\n\n if (payloads.length > 0) {\n // TODO: Figure out how to handle merging payloads when they have different env settings or other config.\n // Currently, we only preserve the text content and drop any specific configuration attached to individual messages.\n const pendingText = formatPendingMessages(payloads);\n return {\n ...message,\n content: `${pendingText}\\n\\n<message>\\n${message.content}\\n</message>`.trim(),\n };\n }\n return message;\n }\n\n async handleMessage(message: Message): Promise<void> {\n if (!message.content.trim()) {\n return;\n }\n\n await taskScheduler.schedule({\n id: `task-${this.agentId}-${randomUUID()}`,\n rootChatId: this.chatId,\n dirPath: this.workDirectory,\n sessionId: this.sessionId,\n text: message.content,\n execute: async (signal) => {\n // Refresh sessionSettings immediately before execution\n const sessionSettings = await readAgentSessionSettings(\n this.agentId,\n this.sessionId,\n this.workspaceRoot\n );\n // TODO: create a copy of the message first\n applyEnvOverrides(message.env, sessionSettings?.env);\n\n const runner = this.createRunner();\n const result = await runner.executeWithFallbacks(message, signal);\n if (!result) {\n // TODO: throw an error? Log an error?\n return;\n }\n\n if (result.extractedSessionId) {\n await writeAgentSessionSettings(\n this.agentId,\n this.sessionId,\n { env: { SESSION_ID: result.extractedSessionId } },\n this.workspaceRoot\n );\n }\n\n await this.logger.logCommandResult(result);\n\n if (!result.content.includes('NO_REPLY_NECESSARY')) {\n await this.logger.logAgentReply({ content: result.content });\n }\n },\n });\n }\n}\n\nexport async function createAgentSession(options: {\n chatId: string;\n agentId: string;\n sessionId: string;\n subagentId?: string;\n cwd: string;\n settings?: Settings | undefined;\n logger?: Logger;\n}) {\n // TODO: make it so that readSettings returns Settings|undefined\n const settings = options.settings ?? (await readSettings(options.cwd)) ?? undefined;\n const mergedAgent = await resolveMergedAgent(options.agentId, settings, options.cwd);\n const workspaceRoot = getWorkspaceRoot(options.cwd);\n\n return new AgentSession({\n agentId: options.agentId,\n sessionId: options.sessionId,\n chatId: options.chatId,\n ...(options.subagentId ? { subagentId: options.subagentId } : {}),\n settings: mergedAgent,\n workspaceRoot,\n globalSettings: settings,\n ...(options.logger ? { logger: options.logger } : {}),\n });\n}\n\nasync function resolveMergedAgent(\n agentId: string,\n settings: Settings | undefined,\n cwd: string\n): Promise<Agent> {\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 return mergedAgent;\n}\n","import { executeRouterPipeline, resolveRouters } from './routers.js';\nimport type { RouterState } from './routers/types.js';\nimport { type ChatSettings, type Settings } from '../shared/config.js';\nimport { readChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { cronManager } from './cron.js';\nimport type { Message } from './agent/types.js';\nimport { createAgentSession } from './agent/agent-session.js';\nimport { createChatLogger } from './agent/chat-logger.js';\n\nexport { calculateDelay } from './agent/agent-runner.js';\n\nexport async function executeDirectMessage(\n chatId: string,\n state: RouterState,\n settings: Settings | undefined,\n cwd: string,\n noWait: boolean = false,\n userMessageContent?: string,\n subagentId?: string,\n systemEvent?:\n | 'cron'\n | 'policy_approved'\n | 'policy_rejected'\n | 'subagent_update'\n | 'router'\n | 'other',\n displayRole?: 'user' | 'agent'\n) {\n const logger = createChatLogger(chatId, subagentId);\n\n let msgId: string;\n if (systemEvent) {\n const sysMsg = await logger.logSystemMessage({\n content: userMessageContent ?? state.message,\n event: systemEvent,\n messageId: state.messageId,\n ...(displayRole ? { displayRole } : {}),\n });\n msgId = sysMsg.id;\n } else {\n const userMsg = await logger.logUserMessage(userMessageContent ?? state.message);\n msgId = userMsg.id;\n }\n\n if (state.reply) {\n await logger.logAutomaticReply({ messageId: msgId, content: state.reply });\n }\n\n if (!state.message.trim() && state.action !== 'stop' && state.action !== 'interrupt') {\n return;\n }\n\n // Load the agent\n const agentSession = await createAgentSession({\n chatId,\n agentId: state.agentId || 'default',\n sessionId: state.sessionId || 'default',\n ...(subagentId ? { subagentId } : {}),\n cwd,\n settings,\n logger,\n });\n let finalMessage: Message = {\n id: state.messageId,\n content: state.message,\n env: state.env ?? {},\n };\n\n // Process actions\n if (state.action === 'stop') {\n agentSession.stop();\n return;\n }\n if (state.action === 'interrupt') {\n finalMessage = agentSession.interrupt(finalMessage);\n }\n\n // Process message\n const taskPromise = agentSession.handleMessage(finalMessage);\n\n if (!noWait) {\n try {\n await taskPromise;\n } catch (err) {\n if (!(err instanceof Error && err.name === 'AbortError')) {\n throw err;\n }\n }\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 chatSettings: Partial<ChatSettings>,\n overrideAgentId?: string,\n overrideSessionId?: string\n): Promise<RouterState> {\n const agentId = overrideAgentId ?? chatSettings.defaultAgent ?? 'default';\n const sessionId = overrideSessionId ?? chatSettings.sessions?.[agentId] ?? 'default';\n const messageId = 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 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 chatSettings,\n overrideAgentId,\n sessionId\n );\n\n const routers = chatSettings.routers ?? settings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, true);\n const finalState = await executeRouterPipeline(initialState, resolvedRouters);\n\n await applyRouterStateUpdates(chatId, cwd, finalState, chatSettings, initialState.agentId);\n\n await executeDirectMessage(chatId, finalState, settings, cwd, noWait, message);\n}\n\nexport async function applyRouterStateUpdates(\n chatId: string,\n cwd: string,\n finalState: RouterState,\n chatSettings: ChatSettings,\n initialAgent: string | undefined\n) {\n const finalAgentId = finalState.agentId;\n const finalSessionId = finalState.sessionId ?? crypto.randomUUID();\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 (finalState.nextSessionId) {\n chatSettings.sessions = chatSettings.sessions || {};\n chatSettings.sessions[currentAgentId] = finalState.nextSessionId;\n settingsChanged = true;\n }\n\n if (finalState.jobs) {\n chatSettings.jobs = chatSettings.jobs || [];\n\n if (finalState.jobs.remove?.length) {\n const removeSet = new Set(finalState.jobs.remove);\n for (const jobId of finalState.jobs.remove) {\n cronManager.unscheduleJob(chatId, jobId);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !removeSet.has(job.id));\n settingsChanged = true;\n }\n\n if (finalState.jobs.add?.length) {\n const addMap = new Map(finalState.jobs.add.map((job) => [job.id, job]));\n for (const job of finalState.jobs.add) {\n cronManager.scheduleJob(chatId, job);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !addMap.has(job.id));\n chatSettings.jobs.push(...finalState.jobs.add);\n settingsChanged = true;\n }\n }\n\n if (settingsChanged) {\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n // Ensure finalSessionId is set on state so extractDirectState gets it.\n if (finalState.sessionId === undefined) {\n finalState.sessionId = finalSessionId;\n }\n if (finalState.agentId === undefined) {\n finalState.agentId = currentAgentId;\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, applyRouterStateUpdates } from './message.js';\nimport { executeRouterPipeline, resolveRouters } from './routers.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';\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() : job.session?.id;\n const chatSettings = (await readChatSettings(chatId, process.cwd())) ?? {};\n let routerState = await getInitialRouterState(\n chatId,\n job.message,\n chatSettings,\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\n const currentAgentId = job.agentId ?? chatSettings.defaultAgent ?? 'default';\n const currentActiveSession = chatSettings.sessions?.[currentAgentId];\n const isOutdatedSession =\n job.session?.type === 'existing' &&\n currentActiveSession !== undefined &&\n currentActiveSession !== job.session.id;\n\n if (job.reply !== undefined && !isOutdatedSession) routerState.reply = job.reply;\n if (job.nextSessionId !== undefined && !isOutdatedSession)\n routerState.nextSessionId = job.nextSessionId;\n if (job.action !== undefined) routerState.action = job.action;\n if (job.jobs !== undefined) routerState.jobs = job.jobs;\n\n const routers = chatSettings.routers ?? globalSettings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n process.cwd(),\n routerState,\n chatSettings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n globalSettings,\n process.cwd(),\n false,\n job.message,\n undefined,\n 'cron'\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","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport {\n getAgent,\n getClawminiDir,\n readChatSettings,\n writeChatSettings,\n} from '../../shared/workspace.js';\nimport { cronManager } from '../cron.js';\nimport type { z } from 'zod';\nimport type { CronJobSchema } from '../../shared/config.js';\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\nexport async 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\nexport async 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\nexport async function validateAttachments(files: string[]): Promise<void> {\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\nexport async function validateLogFile(\n file: string,\n agentDir: string,\n workspaceRoot: string\n): Promise<string> {\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 return path.relative(workspaceRoot, resolvedPath);\n}\n\nexport async function listCronJobsShared(chatId: string) {\n const settings = await readChatSettings(chatId);\n return settings?.jobs ?? [];\n}\n\nexport async function addCronJobShared(chatId: string, job: z.infer<typeof CronJobSchema>) {\n const settings = (await readChatSettings(chatId)) || {};\n const cronJobs = settings.jobs ?? [];\n const existingIndex = cronJobs.findIndex((j) => j.id === job.id);\n if (existingIndex >= 0) {\n cronJobs[existingIndex] = job;\n } else {\n cronJobs.push(job);\n }\n settings.jobs = cronJobs;\n await writeChatSettings(chatId, settings);\n cronManager.scheduleJob(chatId, job);\n return { success: true };\n}\n\nexport async function deleteCronJobShared(chatId: string, id: string) {\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 !== id);\n if (settings.jobs.length !== initialLength) {\n await writeChatSettings(chatId, settings);\n cronManager.unscheduleJob(chatId, id);\n return { success: true, deleted: true };\n }\n return { success: true, deleted: false };\n}\n","import { z } from 'zod';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport { on } from 'node:events';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, DAEMON_EVENT_TYPING } from '../events.js';\nimport {\n getSettingsPath,\n readChatSettings,\n writeChatSettings,\n getWorkspaceRoot,\n listAgents,\n} from '../../shared/workspace.js';\nimport { CronJobSchema } from '../../shared/config.js';\nimport { handleUserMessage } from '../message.js';\nimport { getDefaultChatId, getMessages as fetchMessages, listChats, createChat } from '../chats.js';\nimport { apiProcedure, publicProcedure, router } from './trpc.js';\nimport {\n getUniquePath,\n resolveAgentDir,\n getAgentFilesDir,\n validateAttachments,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const 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 }) => {\n let message = input.data.message;\n const chatId = input.data.chatId ?? (await getDefaultChatId());\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 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(chatId, message, settings, undefined, noWait, sessionId, agentId);\n\n return { success: true };\n });\n\nexport const getMessages = apiProcedure\n .input(z.object({ chatId: z.string().optional(), limit: z.number().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return fetchMessages(chatId, input.limit);\n });\n\nexport const waitForMessages = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n lastMessageId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\n // 1. Check if there are already new messages\n if (input.lastMessageId) {\n const messages = await fetchMessages(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 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\nexport const waitForTyping = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\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\nexport const ping = publicProcedure.query(() => {\n return { status: 'ok' };\n});\n\nexport const 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\nexport const userListCronJobs = apiProcedure\n .input(z.object({ chatId: z.string().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return listCronJobsShared(chatId);\n });\n\nexport const getChats = apiProcedure.query(async () => {\n return listChats();\n});\n\nexport const getAgents = apiProcedure.query(async () => {\n return listAgents();\n});\n\nexport const userCreateChat = apiProcedure\n .input(z.object({ chatId: z.string(), agent: z.string().optional() }))\n .mutation(async ({ input }) => {\n await createChat(input.chatId);\n if (input.agent) {\n await writeChatSettings(input.chatId, { defaultAgent: input.agent });\n }\n return { success: true, chatId: input.chatId };\n });\n\nexport const userAddCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), job: CronJobSchema }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return addCronJobShared(chatId, input.job);\n });\n\nexport const userDeleteCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), id: z.string() }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return deleteCronJobShared(chatId, input.id);\n });\n\nexport const userRouter = router({\n sendMessage,\n getMessages,\n waitForMessages,\n waitForTyping,\n ping,\n shutdown,\n listCronJobs: userListCronJobs,\n addCronJob: userAddCronJob,\n deleteCronJob: userDeleteCronJob,\n getChats,\n getAgents,\n createChat: userCreateChat,\n});\n\nexport type UserRouter = typeof userRouter;\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 skipSave: boolean = false,\n subagentId?: 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: skipSave ? 'Approved' : 'Pending',\n createdAt: Date.now(),\n chatId,\n agentId,\n ...(subagentId ? { subagentId } : {}),\n };\n\n if (!skipSave) {\n await this.store.save(request);\n }\n\n return request;\n }\n\n getInterpolatedArgs(request: PolicyRequest): string[] {\n return interpolateArgs(request.args, request.fileMappings);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { updateChatSettings, readChatSettings } from '../../shared/workspace.js';\nimport { executeDirectMessage, applyRouterStateUpdates } from '../message.js';\nimport { executeRouterPipeline, resolveRouters } from '../routers.js';\nimport type { RouterState } from '../routers/types.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport type { ChatSettings } from '../../shared/config.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\n\nexport function getSubagentDepth(settings: ChatSettings, parentId: string | undefined): number {\n let depth = 0;\n let currentParentId = parentId;\n while (currentParentId && settings.subagents?.[currentParentId]) {\n depth++;\n currentParentId = settings.subagents[currentParentId]?.parentId;\n }\n return depth;\n}\n\nexport async function executeSubagent(\n chatId: string,\n subagentId: string,\n agentId: string,\n sessionId: string,\n prompt: string,\n isAsync: boolean | undefined,\n parentTokenPayload: { agentId?: string; subagentId?: string; sessionId?: string },\n workspaceRoot: string\n) {\n try {\n const settings = (await readChatSettings(chatId)) || {};\n const routers = settings.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n\n let routerState: RouterState = {\n messageId: randomUUID(),\n message: prompt,\n chatId,\n agentId,\n sessionId,\n env: {},\n };\n\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n workspaceRoot,\n routerState,\n settings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n undefined, // settings\n workspaceRoot,\n false, // noWait\n undefined, // userMessageContent\n subagentId // subagentId\n );\n\n if (taskScheduler.hasTasks(sessionId)) {\n return;\n }\n\n // Update status\n await updateChatSettings(chatId, (finalSettings) => {\n if (finalSettings.subagents?.[subagentId]) {\n finalSettings.subagents[subagentId]!.status = 'completed';\n }\n return finalSettings;\n });\n\n const logger = createChatLogger(chatId, subagentId);\n\n // Emit debug message to wake up waiters\n await logger.logSubagentStatus({ subagentId, status: 'completed' });\n\n if (isAsync) {\n const lastLogMessage = await logger.findLastMessage(\n (m) => m.role === 'agent' || m.displayRole === 'agent'\n );\n let outputContent = '';\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = `\\n\\n<subagent_output>\\n${lastLogMessage.content}\\n</subagent_output>`;\n }\n\n console.log(\n 'Notifying parent',\n chatId,\n parentTokenPayload?.agentId,\n parentTokenPayload?.subagentId\n );\n // TODO: We need to overhaul the log system in general, and should not try to do it in this PR.\n // Currently, if the parent is the root agent, this notification is logged as a normal user message\n // and appears in the chat UI, violating the PRD requirement to hide orchestration.\n await executeDirectMessage(\n chatId,\n {\n messageId: randomUUID(),\n message: `<notification>Subagent ${subagentId} completed.</notification>${outputContent}`,\n chatId,\n agentId: parentTokenPayload?.agentId || 'default',\n ...(parentTokenPayload?.subagentId ? { subagentId: parentTokenPayload.subagentId } : {}),\n sessionId: parentTokenPayload?.sessionId || 'default',\n env: {},\n },\n undefined,\n workspaceRoot,\n true,\n undefined,\n parentTokenPayload?.subagentId,\n 'subagent_update'\n );\n }\n } catch {\n // TODO: Wrap this in a safe try-catch to prevent unhandled promise rejections crashing the daemon if disk errors occur\n await updateChatSettings(chatId, (errSettings) => {\n if (errSettings.subagents?.[subagentId]) {\n errSettings.subagents[subagentId]!.status = 'failed';\n }\n return errSettings;\n });\n const logger = createChatLogger(chatId, subagentId);\n await logger.logSubagentStatus({ subagentId, status: 'failed' });\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport { TRPCError } from '@trpc/server';\nimport { getWorkspaceRoot, readChatSettings, updateChatSettings } from '../../shared/workspace.js';\nimport { apiProcedure } from './trpc.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport { on } from 'node:events';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED } from '../events.js';\nimport { createAgentSession } from '../agent/agent-session.js';\nimport { executeSubagent, getSubagentDepth } from './subagent-utils.js';\nimport type { SubagentTracker } from '../../shared/config.js';\n\nconst MAX_SUBAGENT_DEPTH = 2;\n\nexport const subagentSpawn = apiProcedure\n .input(\n z.object({\n subagentId: z.string().optional(),\n targetAgentId: z.string().optional(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const parentAgentId = ctx.tokenPayload.agentId;\n const parentId = ctx.tokenPayload.subagentId;\n\n const id = input.subagentId || randomUUID();\n const sessionId = randomUUID();\n const agentId = input.targetAgentId || parentAgentId;\n let depth = 0;\n\n await updateChatSettings(chatId, (settings) => {\n settings.subagents = settings.subagents || {};\n\n depth = getSubagentDepth(settings, parentId);\n if (depth >= MAX_SUBAGENT_DEPTH) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Max subagent depth reached' });\n }\n\n // Make sure the id does not already exist\n if (settings.subagents[id]) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Subagent ID already exists' });\n }\n\n settings.subagents[id] = {\n id,\n agentId,\n sessionId,\n createdAt: new Date().toISOString(),\n status: 'active',\n parentId,\n };\n\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n const isAsync = input.async ?? depth === 0;\n\n // Execute asynchronously\n executeSubagent(\n chatId,\n id,\n agentId,\n sessionId,\n input.prompt,\n isAsync,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { id, depth, isAsync };\n });\n\nexport const subagentSend = apiProcedure\n .input(\n z.object({\n subagentId: z.string(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let sub: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (!settings.subagents?.[input.subagentId]) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Subagent not found' });\n }\n\n sub = settings.subagents[input.subagentId];\n sub!.status = 'active';\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n // Execute asynchronously\n executeSubagent(\n chatId,\n sub!.id,\n sub!.agentId || 'default',\n sub!.sessionId || 'default',\n input.prompt,\n input.async,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { success: true };\n });\n\nasync function checkSubagentStatus(chatId: string, subagentId: string) {\n const settings = await readChatSettings(chatId);\n const sub = settings?.subagents?.[subagentId];\n if (!sub) throw new TRPCError({ code: 'NOT_FOUND', message: 'Subagent not found' });\n\n if (sub.status === 'completed' || sub.status === 'failed') {\n let outputContent: string | undefined;\n if (sub.status === 'completed') {\n const logger = createChatLogger(chatId, subagentId);\n const lastLogMessage = await logger.findLastMessage((m) => m.role === 'agent');\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = lastLogMessage.content;\n }\n }\n return { status: sub.status, output: outputContent };\n }\n return null;\n}\n\nexport const subagentWait = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx, signal }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const ac = new AbortController();\n const timeout = setTimeout(() => ac.abort(), 60000);\n\n // Bind to the TRPC request abort signal to clean up listeners if client disconnects\n const onAbort = () => {\n clearTimeout(timeout);\n ac.abort();\n };\n if (signal) {\n signal.addEventListener('abort', onAbort);\n }\n\n const eventIterator = on(daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, {\n signal: ac.signal,\n });\n\n try {\n // Check status immediately before listening, but after event iterator is buffering\n const initialStatus = await checkSubagentStatus(chatId, input.subagentId);\n if (initialStatus) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return initialStatus;\n }\n\n for await (const [event] of eventIterator) {\n if (event.chatId === chatId && event.message?.subagentId === input.subagentId) {\n const msg = event.message;\n if (msg.role === 'subagent_status') {\n const status = await checkSubagentStatus(chatId, input.subagentId);\n if (status) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return status;\n }\n }\n }\n }\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'name' in err && err.name === 'AbortError') {\n return { status: 'active' as const, output: undefined };\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n ac.abort();\n }\n\n return { status: 'active' as const, output: undefined };\n });\n\nexport const subagentStop = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToStop: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents) {\n const sub = settings.subagents[input.subagentId];\n if (sub) {\n sub.status = 'failed';\n subToStop = sub;\n }\n }\n return settings;\n });\n\n if (subToStop) {\n const session = await createAgentSession({\n chatId,\n agentId: subToStop.agentId || 'default',\n sessionId: subToStop.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n }\n\n return { success: true };\n });\n\nexport const subagentDelete = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToDelete: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents && settings.subagents[input.subagentId]) {\n subToDelete = settings.subagents[input.subagentId]!;\n delete settings.subagents[input.subagentId];\n }\n return settings;\n });\n\n if (subToDelete) {\n const session = await createAgentSession({\n chatId,\n agentId: subToDelete.agentId || 'default',\n sessionId: subToDelete.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n\n return { success: true, deleted: true };\n }\n\n return { success: true, deleted: false };\n });\n\nexport const subagentList = apiProcedure\n .input(z.object({ blocking: z.boolean().optional() }).optional())\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const settings = await readChatSettings(chatId);\n\n let subagents = Object.values(settings?.subagents || {});\n\n const isSubagent = !!ctx.tokenPayload.subagentId;\n const myId = ctx.tokenPayload.subagentId;\n\n subagents = subagents.filter((s) => s.parentId === myId);\n\n if (input?.blocking) {\n if (!isSubagent) {\n subagents = [];\n } else {\n subagents = subagents.filter((s) => s.status === 'active');\n }\n }\n return { subagents };\n });\n\nexport const subagentTail = apiProcedure\n .input(z.object({ subagentId: z.string(), limit: z.number().optional() }))\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const logger = createChatLogger(chatId, input.subagentId);\n const messages = await logger.getMessages(input.limit);\n\n return { messages };\n });\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport {\n appendMessage,\n type CommandLogMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n} from '../chats.js';\nimport { executeSafe, generateRequestPreview, executeRequest } from '../policy-utils.js';\nimport { getWorkspaceRoot, readPolicies, getClawminiDir } from '../../shared/workspace.js';\nimport { PolicyRequestService } from '../policy-request-service.js';\nimport { RequestStore } from '../request-store.js';\nimport { CronJobSchema } from '../../shared/config.js';\nimport { apiProcedure, router } from './trpc.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\nimport { formatPendingMessages } from '../agent/utils.js';\nimport {\n resolveAgentDir,\n validateLogFile,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const logMessage = apiProcedure\n .input(\n z.object({\n message: z.string().optional(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.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: CommandLogMessage = {\n id,\n messageId: id,\n role: 'command',\n content: messageStr,\n stdout: '',\n stderr: '',\n timestamp,\n command: `clawmini-lite log${filesArgStr}`,\n cwd: process.cwd(),\n exitCode: 0,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logReplyMessage = apiProcedure\n .input(\n z.object({\n message: z.string(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.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 logMsg: AgentReplyMessage = {\n id,\n role: 'agent',\n content: input.message,\n timestamp,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logToolMessage = apiProcedure\n .input(\n z.object({\n name: z.string(),\n payload: z.any().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n const messageId = randomUUID();\n\n const payloadObj = input.payload !== undefined ? input.payload : {};\n let contentStr: string;\n if (typeof payloadObj === 'string') {\n contentStr = payloadObj;\n } else {\n try {\n contentStr = JSON.stringify(payloadObj, null, 2);\n } catch {\n contentStr = String(payloadObj);\n }\n }\n\n const logMsg: ToolMessage = {\n id,\n messageId,\n role: 'tool',\n name: input.name,\n payload: payloadObj,\n content: contentStr,\n timestamp,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const agentListCronJobs = apiProcedure.query(async ({ ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return listCronJobsShared(chatId);\n});\n\nexport const agentAddCronJob = apiProcedure\n .input(z.object({ job: CronJobSchema }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const job = { ...input.job, agentId: ctx.tokenPayload.agentId };\n return addCronJobShared(chatId, job);\n });\n\nexport const agentDeleteCronJob = apiProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return deleteCronJobShared(chatId, input.id);\n });\n\nexport const listPolicies = apiProcedure.query(async () => {\n return await readPolicies();\n});\n\nexport const 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 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\nexport const 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 })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\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 = ctx.tokenPayload.chatId;\n const agentId = ctx.tokenPayload.agentId;\n\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 const isAutoApprove = !!policy.autoApprove;\n\n const request = await service.createRequest(\n input.commandName,\n input.args,\n input.fileMappings,\n chatId,\n agentId,\n isAutoApprove,\n ctx.tokenPayload.subagentId\n );\n\n if (isAutoApprove) {\n const { stdout, stderr, exitCode, commandStr } = await executeRequest(\n request,\n policy,\n getWorkspaceRoot()\n );\n\n request.executionResult = { stdout, stderr, exitCode };\n await store.save(request);\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'approved',\n content: `[Auto-approved] Policy ${input.commandName} was executed.\\n\\nCommand: ${commandStr}\\nExit Code: ${exitCode}\\n\\nStdout:\\n${stdout}\\n\\nStderr:\\n${stderr}`,\n timestamp: new Date().toISOString(),\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n }\n\n const previewContent = await generateRequestPreview(request);\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'pending',\n content: previewContent,\n timestamp: new Date().toISOString(),\n displayRole: 'agent',\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n });\n\nimport { ping } from './user-router.js';\n\nexport const fetchPendingMessages = apiProcedure.mutation(async ({ ctx }) => {\n if (!ctx.tokenPayload?.agentId) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing agent ID' });\n }\n const targetSessionId = ctx.tokenPayload?.sessionId || 'default';\n\n const extracted = taskScheduler.extractPending(targetSessionId);\n if (extracted.length === 0) {\n return { messages: '' };\n }\n\n return { messages: formatPendingMessages(extracted) };\n});\n\nimport {\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n} from './subagent-router.js';\n\nexport const agentRouter = router({\n logMessage,\n logReplyMessage,\n logToolMessage,\n listCronJobs: agentListCronJobs,\n addCronJob: agentAddCronJob,\n deleteCronJob: agentDeleteCronJob,\n listPolicies,\n executePolicyHelp,\n createPolicyRequest,\n fetchPendingMessages,\n ping,\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n});\n\nexport type AgentRouter = typeof agentRouter;\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 { userRouter, agentRouter } from './api/index.js';\nimport {\n getSocketPath,\n getClawminiDir,\n getSettingsPath,\n readSettings,\n readEnvironment,\n getEnvironmentPath,\n getWorkspaceRoot,\n updateChatSettings,\n} from '../shared/workspace.js';\nimport { listChats } from '../shared/chats.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: userRouter,\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 const cleanOrphanedSubagents = async () => {\n try {\n const chats = await listChats();\n for (const chatId of chats) {\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents) {\n for (const subagent of Object.values(settings.subagents)) {\n if (subagent.status === 'active') {\n subagent.status = 'failed';\n }\n }\n }\n return settings;\n });\n }\n } catch (err) {\n console.warn('Failed to clean orphaned subagents:', err);\n }\n };\n await cleanOrphanedSubagents();\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: agentRouter,\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":["fs","path","fs","fs","shared.appendMessage","getMessages","findLastMessageFromStorage","crypto","fs","fs","fs","fetchMessages"],"sources":["../../src/daemon/api/trpc.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/request-store.ts","../../src/daemon/policy-utils.ts","../../src/daemon/events.ts","../../src/daemon/chats.ts","../../src/daemon/routers/slash-policies.ts","../../src/daemon/routers/session-timeout.ts","../../src/daemon/routers.ts","../../src/daemon/agent/agent-context.ts","../../src/daemon/agent/agent-extractors.ts","../../src/daemon/agent/utils.ts","../../src/daemon/agent/agent-runner.ts","../../src/daemon/utils/spawn.ts","../../src/daemon/agent/chat-logger.ts","../../src/shared/utils/env.ts","../../src/daemon/auth.ts","../../src/daemon/agent/task-scheduler.ts","../../src/daemon/agent/agent-session.ts","../../src/daemon/message.ts","../../src/daemon/cron.ts","../../src/daemon/api/router-utils.ts","../../src/daemon/api/user-router.ts","../../src/daemon/policy-request-service.ts","../../src/daemon/api/subagent-utils.ts","../../src/daemon/api/subagent-router.ts","../../src/daemon/api/agent-router.ts","../../src/daemon/index.ts"],"sourcesContent":["import { initTRPC, TRPCError } from '@trpc/server';\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","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 const id = crypto.randomUUID();\n return {\n ...state,\n message: newMessage,\n sessionId: id,\n nextSessionId: id,\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 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 normalizedId = normalizePolicyId(request.id);\n request.id = normalizedId;\n const filePath = this.getFilePath(normalizedId);\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 fs from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport path from 'node:path';\nimport { randomBytes } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { pathIsInsideDir } from '../shared/utils/fs.js';\nimport type { PolicyRequest, PolicyDefinition } from '../shared/policies.js';\n\nexport const MAX_SNAPSHOT_SIZE = 5 * 1024 * 1024;\n\nexport async function createSnapshot(\n requestedPath: string,\n agentDir: string,\n snapshotDir: string\n): Promise<string> {\n let realAgentDir: string;\n try {\n realAgentDir = await fs.realpath(agentDir);\n } catch (err) {\n throw new Error(`Agent directory not found or cannot be resolved: ${agentDir}`, { cause: err });\n }\n\n const resolvedRequestedPath = path.resolve(realAgentDir, requestedPath);\n\n // Verify it is inside the allowed agent directory\n if (!pathIsInsideDir(resolvedRequestedPath, realAgentDir, { allowSameDir: true })) {\n throw new Error(\n `Security Error: Path resolves outside the allowed agent directory: ${resolvedRequestedPath}`\n );\n }\n\n // Lstat prevents TOCTOU attacks by not following symlinks\n let stat;\n try {\n stat = await fs.lstat(resolvedRequestedPath);\n } catch (err) {\n throw new Error(`File not found or cannot be accessed: ${requestedPath}`, { cause: err });\n }\n\n if (stat.isSymbolicLink()) {\n throw new Error(`Security Error: Symlinks are not allowed: ${requestedPath}`);\n }\n\n if (!stat.isFile()) {\n throw new Error(`Requested path is not a file: ${requestedPath}`);\n }\n if (stat.size > MAX_SNAPSHOT_SIZE) {\n throw new Error(`File exceeds maximum snapshot size of 5MB: ${requestedPath}`);\n }\n\n // Generate unique filename for the snapshot\n const ext = path.extname(resolvedRequestedPath);\n const base = path.basename(resolvedRequestedPath, ext);\n\n await fs.mkdir(snapshotDir, { recursive: true });\n\n let snapshotPath: string;\n while (true) {\n const uniqueId = randomBytes(8).toString('hex');\n const snapshotFileName = `${base}_${uniqueId}${ext}`;\n snapshotPath = path.join(snapshotDir, snapshotFileName);\n\n try {\n await fs.copyFile(resolvedRequestedPath, snapshotPath, constants.COPYFILE_EXCL);\n break;\n } catch (err: unknown) {\n if (\n err instanceof Error &&\n 'code' in err &&\n (err as Error & { code?: string }).code === 'EEXIST'\n ) {\n continue;\n }\n throw err;\n }\n }\n\n return snapshotPath;\n}\n\nexport function interpolateArgs(args: string[], snapshots: Record<string, string>): string[] {\n return args.map((arg) => {\n let interpolated = arg;\n for (const [key, snapshotPath] of Object.entries(snapshots)) {\n const variable = `{{${key}}}`;\n interpolated = interpolated.replaceAll(variable, snapshotPath);\n }\n return interpolated;\n });\n}\n\nexport function executeSafe(\n command: string,\n args: string[],\n options?: { cwd?: string; env?: NodeJS.ProcessEnv }\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return new Promise((resolve) => {\n // Safe execution: shell is strictly false to prevent command injection\n const p = spawn(command, args, {\n shell: false,\n cwd: options?.cwd,\n env: options?.env,\n });\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n}\n\nexport async function executeRequest(\n request: PolicyRequest,\n policy: PolicyDefinition,\n cwd?: string\n): Promise<{ stdout: string; stderr: string; exitCode: number; commandStr: string }> {\n const fullArgs = [...(policy.args || []), ...request.args];\n const interpolatedArgs = interpolateArgs(fullArgs, request.fileMappings);\n\n const { stdout, stderr, exitCode } = await executeSafe(\n policy.command,\n interpolatedArgs,\n cwd ? { cwd } : undefined\n );\n\n const commandStr = `${policy.command} ${interpolatedArgs.join(' ')}`;\n return { stdout, stderr, exitCode, commandStr };\n}\n\nexport async function generateRequestPreview(request: PolicyRequest): Promise<string> {\n let previewContent = `Sandbox Policy Request: ${request.commandName}\\n`;\n previewContent += `ID: ${request.id}\\n`;\n if (request.args.length > 0) {\n previewContent += `Args: ${request.args.join(' ')}\\n`;\n }\n\n for (const [name, snapPath] of Object.entries(request.fileMappings)) {\n previewContent += `File [${name}]:\\n`;\n try {\n let content = await fs.readFile(snapPath, 'utf8');\n if (content.length > 500) {\n content = content.substring(0, 500) + '\\n... (truncated)\\n';\n }\n previewContent += content;\n } catch (e: unknown) {\n previewContent += `<Error reading file: ${(e as Error).message}>\\n`;\n }\n }\n\n previewContent += `\\nUse /approve ${request.id} or /reject ${request.id} [reason]`;\n return previewContent;\n}\n","import { EventEmitter } from 'node:events';\nimport type { ChatMessage } from '../shared/chats.js';\n\nexport const daemonEvents = new EventEmitter();\n\nexport const DAEMON_EVENT_MESSAGE_APPENDED = 'message-appended';\nexport const DAEMON_EVENT_TYPING = 'typing';\n\nexport function emitMessageAppended(chatId: string, message: ChatMessage) {\n daemonEvents.emit(DAEMON_EVENT_MESSAGE_APPENDED, { chatId, message });\n}\n\nexport function emitTyping(chatId: string) {\n daemonEvents.emit(DAEMON_EVENT_TYPING, { chatId });\n}\n","import * as shared from '../shared/chats.js';\nimport { emitMessageAppended } from './events.js';\n\nexport async function appendMessage(\n id: string,\n message: shared.ChatMessage,\n startDir = process.cwd()\n): Promise<void> {\n await shared.appendMessage(id, message, startDir);\n emitMessageAppended(id, message);\n}\n\nexport {\n type ChatMessage,\n type UserMessage,\n type CommandLogMessage,\n type SystemMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n type SubagentStatusMessage,\n getChatsDir,\n isValidChatId,\n createChat,\n listChats,\n deleteChat,\n getMessages,\n findLastMessage,\n getDefaultChatId,\n setDefaultChatId,\n DEFAULT_CHAT_ID,\n} from '../shared/chats.js';\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 { executeRequest } from '../policy-utils.js';\nimport { appendMessage } from '../chats.js';\nimport type { SystemMessage } 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\n const { stdout, stderr, exitCode } = await executeRequest(req, policy, getWorkspaceRoot());\n\n req.executionResult = { stdout, stderr, exitCode };\n await store.save(req);\n\n const agentMessage = `Request ${id} approved.\\n\\n${wrapInHtml('stdout', stdout)}\\n\\n${wrapInHtml('stderr', stderr)}\\n\\nExit Code: ${exitCode}`;\n\n const logMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_approved',\n displayRole: 'user',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n await appendMessage(state.chatId, logMsg);\n\n return {\n ...state,\n message: agentMessage,\n reply: `Approved request, running ${req.commandName}`,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\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 agentMessage = `Request ${id} rejected. Reason: ${reason}`;\n\n const logMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_rejected',\n displayRole: 'user',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n const userNotificationMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_rejected',\n displayRole: 'agent',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n await appendMessage(state.chatId, logMsg);\n await appendMessage(state.chatId, userNotificationMsg);\n\n return {\n ...state,\n message: agentMessage,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\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 type { RouterState } from './types.js';\nimport { randomUUID } from 'node:crypto';\n\nexport interface SessionTimeoutConfig {\n timeout?: string;\n prompt?: string;\n}\n\n/**\n * Router that automatically starts a new session after a period of inactivity.\n *\n * To register this router, add it to your `~/.gemini/settings.json`:\n * ```json\n * {\n * \"routers\": [\n * {\n * \"use\": \"session-timeout\",\n * \"with\": {\n * \"timeout\": \"60m\",\n * \"prompt\": \"This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.\"\n * }\n * }\n * ]\n * }\n * ```\n */\nexport function createSessionTimeoutRouter(config: SessionTimeoutConfig = {}) {\n const timeStr = config.timeout ?? '60m';\n const prompt =\n config.prompt ??\n 'This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.';\n\n return function (state: RouterState): RouterState {\n if (state.env?.__SESSION_TIMEOUT__ === 'true') {\n return state;\n }\n\n const sessionId = state.sessionId || crypto.randomUUID();\n const jobId = `__session_timeout__${sessionId}`;\n\n const jobs = {\n ...state.jobs,\n remove: [...(state.jobs?.remove || []), jobId, '__session_timeout__'],\n };\n\n return {\n ...state,\n sessionId,\n jobs: {\n ...jobs,\n add: [\n ...(jobs.add || []),\n // Add a job after the timeout that will send the prompt, reply to the user,\n // start a fresh session, and delete the job\n {\n id: jobId,\n schedule: { at: timeStr },\n message: prompt,\n reply: '[@clawmini/session-timeout] Starting a fresh session...',\n nextSessionId: randomUUID(),\n session: { type: 'existing', id: sessionId },\n env: { __SESSION_TIMEOUT__: 'true' },\n jobs: {\n remove: [jobId],\n },\n },\n ],\n },\n };\n };\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';\nimport { createSessionTimeoutRouter } from './routers/session-timeout.js';\nimport type { RouterConfig } from '../shared/config.js';\n\nexport const GLOBAL_ROUTERS: RouterConfig[] = ['@clawmini/session-timeout'];\n\nexport const USER_ROUTERS: RouterConfig[] = [\n '@clawmini/slash-new',\n '@clawmini/slash-command',\n '@clawmini/slash-stop',\n '@clawmini/slash-interrupt',\n '@clawmini/slash-policies',\n];\n\nexport function resolveRouters(\n userRouters: RouterConfig[],\n isUserMessage: boolean\n): RouterConfig[] {\n const resolvedGlobals: RouterConfig[] = [];\n const resolvedUsers: RouterConfig[] = [];\n\n const userConfigMap = new Map<string, unknown>();\n for (const r of userRouters) {\n const name = typeof r === 'string' ? r : r.use;\n const config = typeof r === 'string' ? {} : r.with || {};\n\n if (name.startsWith('@clawmini/')) {\n userConfigMap.set(name, config);\n } else {\n resolvedUsers.push(r);\n }\n }\n\n for (const globalRouter of GLOBAL_ROUTERS) {\n const name = typeof globalRouter === 'string' ? globalRouter : globalRouter.use;\n const baseConfig = typeof globalRouter === 'string' ? {} : globalRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n resolvedGlobals.push({ use: name, with: mergedConfig });\n }\n\n const defaultUserRouters: RouterConfig[] = [];\n for (const defaultUserRouter of USER_ROUTERS) {\n const name = typeof defaultUserRouter === 'string' ? defaultUserRouter : defaultUserRouter.use;\n const baseConfig = typeof defaultUserRouter === 'string' ? {} : defaultUserRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n defaultUserRouters.push({ use: name, with: mergedConfig });\n }\n\n if (isUserMessage) {\n return [...resolvedGlobals, ...defaultUserRouters, ...resolvedUsers];\n } else {\n return resolvedGlobals;\n }\n}\n\nexport async function executeRouterPipeline(\n initialState: RouterState,\n routers: RouterConfig[]\n): Promise<RouterState> {\n let state = { ...initialState };\n\n for (const routerDef of routers) {\n if (state.action === 'stop') {\n break;\n }\n\n const router = typeof routerDef === 'string' ? routerDef : routerDef.use;\n const config = typeof routerDef === 'string' ? {} : routerDef.with || {};\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 if (router === '@clawmini/session-timeout') {\n state = createSessionTimeoutRouter(config)(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 { type FallbackSchema } from '../../shared/config.js';\nimport {\n getActiveEnvironmentInfo,\n getEnvironmentPath,\n readEnvironment,\n} from '../../shared/workspace.js';\nimport { z } from 'zod';\n\nexport type Fallback = z.infer<typeof FallbackSchema>;\n\nfunction formatEnvironmentPrefix(\n prefix: string,\n replacements: { targetPath: string; executionCwd: string; envDir: string; envArgs: string }\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 sandboxExecutionContext(\n initialCommand: string,\n env: Record<string, string>,\n agentSpecificEnvKeys: Set<string>,\n executionCwd: string,\n cwd: string\n): Promise<string> {\n let command = initialCommand;\n const activeEnvInfo = await getActiveEnvironmentInfo(executionCwd, cwd);\n if (!activeEnvInfo) return command;\n\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 agentSpecificEnvKeys.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 agentSpecificEnvKeys.add(key);\n }\n }\n }\n\n if (activeEnv?.prefix) {\n const envArgs = Array.from(agentSpecificEnvKeys)\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: 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 return command;\n}\n","import type { RunCommandFn, RunCommandResult } from './types.js';\nimport type { Agent } from '../../shared/config.js';\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\nexport async function extractMessageContent(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getMessageContent) return {};\n return runExtractionCommand(\n 'getMessageContent',\n context.currentAgent.commands.getMessageContent,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n\nexport async function extractSessionId(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getSessionId) return {};\n return runExtractionCommand(\n 'getSessionId',\n context.currentAgent.commands.getSessionId,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n","export function formatPendingMessages(payloads: string[]): string {\n return payloads.map((text) => `<message>\\n${text}\\n</message>`).join('\\n\\n');\n}\n\nexport function isNewSession(env: Record<string, string>): boolean {\n return env['SESSION_ID'] === undefined;\n}\n","import { emitTyping } from '../events.js';\nimport type { ExecutionResponse, Message, RunCommandFn } from './types.js';\nimport { type Fallback } from './agent-context.js';\nimport { extractMessageContent, extractSessionId } from './agent-extractors.js';\nimport type { AgentSession } from './agent-session.js';\nimport { isNewSession } from './utils.js';\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 class AgentRunner {\n constructor(\n private readonly session: AgentSession,\n private readonly runCommand: RunCommandFn\n ) {}\n\n private async withTypingIndicator<T>(fn: () => Promise<T>): Promise<T> {\n const interval = setInterval(() => emitTyping(this.session.chatId), 5000);\n try {\n return await fn();\n } finally {\n clearInterval(interval);\n }\n }\n\n private *getExecutionAttempts() {\n const fallbacks = this.session.settings.fallbacks || [];\n const executionConfigs = [\n { fallback: undefined, retries: 0, delayMs: 1000 },\n ...fallbacks.map((f) => ({ fallback: f, retries: f.retries, delayMs: f.delayMs })),\n ];\n\n for (let configIdx = 0; configIdx < executionConfigs.length; configIdx++) {\n const config = executionConfigs[configIdx]!;\n const isFallbackConfig = configIdx > 0;\n\n for (let attempt = 0; attempt <= config.retries; attempt++) {\n yield {\n fallback: config.fallback,\n delay: calculateDelay(attempt, config.delayMs, isFallbackConfig),\n };\n }\n }\n }\n\n private async executeSingleAttempt(\n message: Message,\n fallback?: Fallback | undefined,\n signal?: AbortSignal | undefined\n ): Promise<{ success: boolean; response?: ExecutionResponse }> {\n const context = await this.session.buildExecutionContext(\n message.content,\n message.env,\n fallback\n );\n\n if (!context) return { success: false };\n\n const mainResult = await this.withTypingIndicator(() =>\n this.runCommand({\n command: context.command,\n cwd: this.session.workDirectory,\n env: context.env,\n signal,\n })\n );\n\n let success = mainResult.exitCode === 0;\n let finalContent = mainResult.stdout.trim();\n const additonalErrors = [];\n\n if (success && context.currentAgent.commands?.getMessageContent) {\n const extraction = await extractMessageContent(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result !== undefined) finalContent = extraction.result.trim();\n if (!finalContent) success = false;\n }\n\n let extractedSessionId: string | undefined;\n\n if (success && isNewSession(message.env) && context.currentAgent.commands?.getSessionId) {\n const extraction = await extractSessionId(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result) {\n extractedSessionId = extraction.result;\n }\n }\n\n return {\n success,\n response: {\n messageId: message.id,\n content: finalContent,\n command: context.command,\n cwd: this.session.workDirectory,\n extractedSessionId,\n result: {\n ...mainResult,\n stderr: [mainResult.stderr, ...additonalErrors].join('\\n\\n'),\n },\n },\n };\n }\n\n async executeWithFallbacks(\n message: Message,\n signal?: AbortSignal | undefined\n ): Promise<ExecutionResponse | undefined> {\n let lastResponse: ExecutionResponse | undefined;\n\n for (const attempt of this.getExecutionAttempts()) {\n if (attempt.delay > 0) {\n await this.session.logger.logCommandRetry({\n messageId: message.id,\n content: `Error running agent, retrying in ${Math.round(attempt.delay / 1000)} seconds...`,\n cwd: this.session.workDirectory,\n });\n await sleep(attempt.delay);\n }\n\n const attemptResult = await this.executeSingleAttempt(message, attempt.fallback, signal);\n\n lastResponse = attemptResult.response || lastResponse;\n if (attemptResult.success) {\n return lastResponse;\n }\n }\n\n return lastResponse;\n }\n}\n","import { spawn } from 'node:child_process';\nimport type { RunCommandFn } from '../agent/types.js';\n\nconst LOG_TO_TERMINAL = false;\n\nexport const runCommand: RunCommandFn = async ({\n command,\n cwd,\n env,\n stdin,\n signal,\n}: Parameters<RunCommandFn>[0] & { logToTerminal?: boolean }) => {\n return new Promise<{ stdout: string; stderr: string; exitCode: number }>((resolve, reject) => {\n console.log('RUN: ', command);\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 (LOG_TO_TERMINAL && !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 (LOG_TO_TERMINAL && !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","import {\n appendMessage,\n getMessages,\n findLastMessage as findLastMessageFromStorage,\n type ChatMessage,\n type CommandLogMessage,\n type UserMessage,\n type SystemMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n type SubagentStatusMessage,\n} from '../chats.js';\nimport type { Logger } from './types.js';\n\nexport function createChatLogger(chatId: string, subagentId?: string): Logger {\n async function append<T extends ChatMessage>(msg: T): Promise<T> {\n const finalMsg = subagentId ? { ...msg, subagentId } : msg;\n await appendMessage(chatId, finalMsg);\n return finalMsg as T;\n }\n\n return {\n append,\n\n getMessages: async (limit?: number) => {\n const msgs = await getMessages(chatId);\n let filtered = msgs.filter((m) => m.subagentId === subagentId);\n if (limit !== undefined && limit > 0) {\n filtered = filtered.slice(-limit);\n }\n return filtered;\n },\n\n findLastMessage: async (predicate) => {\n return findLastMessageFromStorage(chatId, (msg: ChatMessage) => {\n if (msg.subagentId !== subagentId) return false;\n return predicate(msg);\n });\n },\n\n logUserMessage: async (msg) =>\n append({\n id: crypto.randomUUID(),\n role: 'user',\n content: msg,\n timestamp: new Date().toISOString(),\n } satisfies UserMessage),\n\n logCommandResult: async ({ messageId, content, command, cwd, result }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n\n command,\n cwd,\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n }),\n\n logSystemEvent: async ({ content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId: crypto.randomUUID(),\n\n stderr: '',\n command: '',\n cwd: '',\n stdout: '',\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logAutomaticReply: async ({ messageId, content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'system',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n event: 'router',\n displayRole: 'agent',\n } satisfies SystemMessage),\n\n logCommandRetry: async ({ messageId, content, cwd }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n\n // TODO remove these? Or include the actual command that was run?\n command: 'retry-delay',\n stderr: '',\n stdout: '',\n cwd,\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logSystemMessage: async ({ content, event, messageId, displayRole }) => {\n const msg: SystemMessage = {\n id: crypto.randomUUID(),\n role: 'system',\n content,\n event,\n timestamp: new Date().toISOString(),\n };\n if (messageId !== undefined) {\n msg.messageId = messageId;\n }\n if (displayRole !== undefined) {\n msg.displayRole = displayRole;\n }\n return append<SystemMessage>(msg);\n },\n\n logSubagentStatus: async ({ subagentId: targetSubagentId, status }) => {\n const msg: SubagentStatusMessage = {\n id: crypto.randomUUID(),\n role: 'subagent_status',\n content: `Subagent ${status}`,\n subagentId: targetSubagentId,\n status,\n timestamp: new Date().toISOString(),\n };\n return append<SubagentStatusMessage>(msg);\n },\n\n logAgentReply: async ({ content, files }) => {\n const msg: AgentReplyMessage = {\n id: crypto.randomUUID(),\n role: 'agent',\n content,\n timestamp: new Date().toISOString(),\n };\n if (files !== undefined) {\n msg.files = files;\n }\n return append<AgentReplyMessage>(msg);\n },\n\n logToolMessage: async ({ content, messageId, name, payload }) => {\n const msg: ToolMessage = {\n id: crypto.randomUUID(),\n role: 'tool',\n content,\n messageId,\n name,\n payload,\n timestamp: new Date().toISOString(),\n };\n return append<ToolMessage>(msg);\n },\n\n logPolicyRequestMessage: async ({\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n }) => {\n const msg: PolicyRequestMessage = {\n id: crypto.randomUUID(),\n role: 'policy',\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n timestamp: new Date().toISOString(),\n };\n return append<PolicyRequestMessage>(msg);\n },\n };\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","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 subagentId?: 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 interface AgentTask {\n id: string;\n rootChatId: string;\n dirPath: string;\n sessionId: string;\n text?: string;\n execute: (signal: AbortSignal) => Promise<void>;\n}\n\nclass ResourceLock {\n private resources = new Map<\n string,\n {\n activeWorkspace: string;\n count: number;\n waiters: Array<{\n workspaceId: string;\n resolve: () => void;\n reject: (err: Error) => void;\n }>;\n }\n >();\n\n async acquire(resourceId: string, workspaceId: string, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n throw error;\n }\n\n const res = this.resources.get(resourceId);\n if (!res) {\n this.resources.set(resourceId, { activeWorkspace: workspaceId, count: 1, waiters: [] });\n return;\n }\n\n if (res.activeWorkspace === workspaceId) {\n // Allow re-entrancy for the same rootChatId (workspaceId) so that the\n // root agent and its subagents can run in parallel in the same directory.\n // This ensures the root agent remains available to coordinate its subagents,\n // assuming it will manage conflicts appropriately.\n // Note: This risks starvation if agents/subagents from this workspace never release the resource.\n res.count++;\n return;\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter = { workspaceId, resolve, reject };\n res!.waiters.push(waiter);\n\n if (signal) {\n const onAbort = () => {\n const idx = res!.waiters.indexOf(waiter);\n if (idx !== -1) {\n res!.waiters.splice(idx, 1);\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n reject(error);\n }\n };\n signal.addEventListener('abort', onAbort);\n\n // Intercept resolve to clean up the listener\n waiter.resolve = () => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n };\n // Intercept reject to clean up the listener\n waiter.reject = (err: Error) => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n };\n }\n });\n }\n\n release(resourceId: string, _workspaceId: string) {\n const res = this.resources.get(resourceId);\n if (!res) return;\n\n res.count--;\n if (res.count === 0) {\n if (res.waiters.length > 0) {\n const nextWorkspace = res.waiters[0]!.workspaceId;\n res.activeWorkspace = nextWorkspace;\n\n const remainingWaiters = [];\n for (const waiter of res.waiters) {\n if (waiter.workspaceId === nextWorkspace) {\n res.count++;\n waiter.resolve();\n } else {\n remainingWaiters.push(waiter);\n }\n }\n res.waiters = remainingWaiters;\n } else {\n this.resources.delete(resourceId);\n }\n }\n }\n}\n\nclass TaskQueue {\n private queue: Array<{\n task: AgentTask;\n resolve: () => void;\n reject: (err: unknown) => void;\n }> = [];\n private activeTask: { task: AgentTask; controller: AbortController } | null = null;\n private isProcessing = false;\n\n constructor(\n public readonly sessionId: string,\n private resourceLock: ResourceLock,\n private onEmpty: (sessionId: string) => void\n ) {}\n\n enqueue(task: AgentTask): Promise<void> {\n return new Promise((resolve, reject) => {\n this.queue.push({ task, resolve, reject });\n this.process();\n });\n }\n\n private async process() {\n if (this.isProcessing || this.activeTask || this.queue.length === 0) return;\n this.isProcessing = true;\n\n while (this.queue.length > 0) {\n const next = this.queue.shift()!;\n const controller = new AbortController();\n this.activeTask = { task: next.task, controller };\n\n let acquired = false;\n try {\n await this.resourceLock.acquire(next.task.dirPath, next.task.rootChatId, controller.signal);\n acquired = true;\n\n if (!controller.signal.aborted) {\n await next.task.execute(controller.signal);\n }\n next.resolve();\n } catch (err) {\n next.reject(err);\n } finally {\n if (acquired) {\n this.resourceLock.release(next.task.dirPath, next.task.rootChatId);\n }\n this.activeTask = null;\n }\n }\n\n this.isProcessing = false;\n this.onEmpty(this.sessionId);\n }\n\n abortAll() {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n qTask.reject(error);\n }\n this.queue = [];\n }\n\n interruptAndExtract(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n if (this.activeTask.task.text !== undefined) {\n payloads.push(this.activeTask.task.text);\n }\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n extractPending(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task extracted for batching');\n error.name = 'AbortError';\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n hasTasks(): boolean {\n return this.activeTask !== null || this.queue.length > 0;\n }\n}\n\nexport class TaskScheduler {\n private queues = new Map<string, TaskQueue>();\n private resourceLock = new ResourceLock();\n\n private getQueueKey(sessionId: string, rootChatId: string): string {\n return `${rootChatId}:${sessionId}`;\n }\n\n public schedule(task: AgentTask): Promise<void> {\n const key = this.getQueueKey(task.sessionId, task.rootChatId);\n let queue = this.queues.get(key);\n if (!queue) {\n queue = new TaskQueue(task.sessionId, this.resourceLock, () => {\n this.queues.delete(key);\n });\n this.queues.set(key, queue);\n }\n return queue.enqueue(task);\n }\n\n public hasTasks(sessionId: string): boolean {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId && queue.hasTasks()) {\n return true;\n }\n }\n return false;\n }\n\n public extractPending(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.extractPending());\n }\n }\n return payloads;\n }\n\n public abortTasks(sessionId: string): void {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n queue.abortAll();\n }\n }\n }\n\n public interruptTasks(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.interruptAndExtract());\n }\n }\n return payloads;\n }\n}\n\nexport const taskScheduler = new TaskScheduler();\n","import type { Agent, Settings } from '../../shared/config.js';\nimport { AgentRunner } from './agent-runner.js';\nimport type { Logger, Message } from './types.js';\nimport { runCommand } from '../utils/spawn.js';\nimport {\n getAgent,\n getWorkspaceRoot,\n readAgentSessionSettings,\n writeAgentSessionSettings,\n readSettings,\n resolveAgentWorkDir,\n} from '../../shared/workspace.js';\nimport { formatPendingMessages, isNewSession } from './utils.js';\nimport { createChatLogger } from './chat-logger.js';\nimport { sandboxExecutionContext, type Fallback } from './agent-context.js';\nimport { applyEnvOverrides, getActiveEnvKeys } from '../../shared/utils/env.js';\nimport { getApiContext, generateToken } from '../auth.js';\nimport { taskScheduler } from './task-scheduler.js';\nimport { randomUUID } from 'node:crypto';\n\nexport class AgentSession {\n public readonly agentId: string;\n public readonly sessionId: string;\n public readonly chatId: string;\n public readonly subagentId: string | undefined;\n public readonly settings: Agent;\n public readonly workspaceRoot: string;\n public readonly globalSettings: Settings | undefined;\n public readonly logger: Logger;\n\n constructor(config: {\n agentId: string;\n sessionId: string;\n chatId: string;\n subagentId?: string;\n settings: Agent;\n workspaceRoot: string;\n globalSettings: Settings | undefined;\n logger?: Logger;\n }) {\n this.agentId = config.agentId;\n this.sessionId = config.sessionId;\n this.chatId = config.chatId;\n this.subagentId = config.subagentId;\n this.settings = config.settings;\n this.workspaceRoot = config.workspaceRoot;\n this.globalSettings = config.globalSettings;\n\n this.logger = config.logger ?? createChatLogger(this.chatId, this.subagentId);\n }\n\n async buildExecutionContext(\n messageContent: string,\n routerEnv: Record<string, string>,\n fallback?: Fallback\n ): Promise<{ command: string; env: Record<string, string>; currentAgent: Agent } | null> {\n const currentAgent: Agent = {\n ...this.settings,\n commands: {\n ...this.settings.commands,\n ...(fallback?.commands || {}),\n },\n env: {\n ...this.settings.env,\n ...(this.subagentId && this.settings.subagentEnv ? this.settings.subagentEnv : {}),\n ...(fallback?.env || {}),\n },\n };\n\n let initialCommand = currentAgent.commands?.new ?? '';\n const env = {\n ...process.env,\n CLAW_CLI_MESSAGE: messageContent,\n } as Record<string, string>;\n\n applyEnvOverrides(env, currentAgent.env);\n\n if (!isNewSession(routerEnv) && currentAgent.commands?.append) {\n initialCommand = currentAgent.commands.append;\n }\n\n if (!initialCommand) {\n return null;\n }\n\n const agentSpecificEnvKeys = getActiveEnvKeys(currentAgent.env);\n agentSpecificEnvKeys.add('CLAW_CLI_MESSAGE');\n\n Object.assign(env, routerEnv);\n Object.keys(routerEnv).forEach((k) => agentSpecificEnvKeys.add(k));\n\n const apiCtx = getApiContext(this.globalSettings);\n if (apiCtx) {\n const proxyUrl = apiCtx.proxy_host\n ? `${apiCtx.proxy_host}:${apiCtx.port}`\n : `http://${apiCtx.host}:${apiCtx.port}`;\n\n if (currentAgent.apiUrlEnvVar) {\n env[currentAgent.apiUrlEnvVar] = proxyUrl;\n agentSpecificEnvKeys.add(currentAgent.apiUrlEnvVar);\n env['CLAW_LITE_URL_VAR'] = currentAgent.apiUrlEnvVar;\n agentSpecificEnvKeys.add('CLAW_LITE_URL_VAR');\n } else {\n env['CLAW_API_URL'] = proxyUrl;\n agentSpecificEnvKeys.add('CLAW_API_URL');\n }\n\n const token = generateToken({\n chatId: this.chatId,\n agentId: this.agentId,\n sessionId: this.sessionId,\n ...(this.subagentId ? { subagentId: this.subagentId } : {}),\n timestamp: Date.now(),\n });\n\n if (currentAgent.apiTokenEnvVar) {\n env[currentAgent.apiTokenEnvVar] = token;\n agentSpecificEnvKeys.add(currentAgent.apiTokenEnvVar);\n env['CLAW_LITE_API_VAR'] = currentAgent.apiTokenEnvVar;\n agentSpecificEnvKeys.add('CLAW_LITE_API_VAR');\n } else {\n env['CLAW_API_TOKEN'] = token;\n agentSpecificEnvKeys.add('CLAW_API_TOKEN');\n }\n }\n\n let command = initialCommand;\n command = await sandboxExecutionContext(\n command,\n env,\n agentSpecificEnvKeys,\n this.workDirectory,\n this.workspaceRoot\n );\n\n return { command, env, currentAgent };\n }\n\n createRunner(): AgentRunner {\n return new AgentRunner(this, runCommand);\n }\n\n get workDirectory(): string {\n return resolveAgentWorkDir(this.agentId, this.settings.directory, this.workspaceRoot);\n }\n\n stop() {\n taskScheduler.abortTasks(this.sessionId);\n }\n\n interrupt(message: Message): Message {\n const payloads = taskScheduler.interruptTasks(this.sessionId);\n\n if (payloads.length > 0) {\n // TODO: Figure out how to handle merging payloads when they have different env settings or other config.\n // Currently, we only preserve the text content and drop any specific configuration attached to individual messages.\n const pendingText = formatPendingMessages(payloads);\n return {\n ...message,\n content: `${pendingText}\\n\\n<message>\\n${message.content}\\n</message>`.trim(),\n };\n }\n return message;\n }\n\n async handleMessage(message: Message): Promise<void> {\n if (!message.content.trim()) {\n return;\n }\n\n await taskScheduler.schedule({\n id: `task-${this.agentId}-${randomUUID()}`,\n rootChatId: this.chatId,\n dirPath: this.workDirectory,\n sessionId: this.sessionId,\n text: message.content,\n execute: async (signal) => {\n // Refresh sessionSettings immediately before execution\n const sessionSettings = await readAgentSessionSettings(\n this.agentId,\n this.sessionId,\n this.workspaceRoot\n );\n // TODO: create a copy of the message first\n applyEnvOverrides(message.env, sessionSettings?.env);\n\n const runner = this.createRunner();\n const result = await runner.executeWithFallbacks(message, signal);\n if (!result) {\n // TODO: throw an error? Log an error?\n return;\n }\n\n if (result.extractedSessionId) {\n await writeAgentSessionSettings(\n this.agentId,\n this.sessionId,\n { env: { SESSION_ID: result.extractedSessionId } },\n this.workspaceRoot\n );\n }\n\n await this.logger.logCommandResult(result);\n\n if (!result.content.includes('NO_REPLY_NECESSARY')) {\n await this.logger.logAgentReply({ content: result.content });\n }\n },\n });\n }\n}\n\nexport async function createAgentSession(options: {\n chatId: string;\n agentId: string;\n sessionId: string;\n subagentId?: string;\n cwd: string;\n settings?: Settings | undefined;\n logger?: Logger;\n}) {\n // TODO: make it so that readSettings returns Settings|undefined\n const settings = options.settings ?? (await readSettings(options.cwd)) ?? undefined;\n const mergedAgent = await resolveMergedAgent(options.agentId, settings, options.cwd);\n const workspaceRoot = getWorkspaceRoot(options.cwd);\n\n return new AgentSession({\n agentId: options.agentId,\n sessionId: options.sessionId,\n chatId: options.chatId,\n ...(options.subagentId ? { subagentId: options.subagentId } : {}),\n settings: mergedAgent,\n workspaceRoot,\n globalSettings: settings,\n ...(options.logger ? { logger: options.logger } : {}),\n });\n}\n\nasync function resolveMergedAgent(\n agentId: string,\n settings: Settings | undefined,\n cwd: string\n): Promise<Agent> {\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 return mergedAgent;\n}\n","import { executeRouterPipeline, resolveRouters } from './routers.js';\nimport type { RouterState } from './routers/types.js';\nimport { type ChatSettings, type Settings } from '../shared/config.js';\nimport { readChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { cronManager } from './cron.js';\nimport type { Message } from './agent/types.js';\nimport { createAgentSession } from './agent/agent-session.js';\nimport { createChatLogger } from './agent/chat-logger.js';\n\nexport { calculateDelay } from './agent/agent-runner.js';\n\nexport async function executeDirectMessage(\n chatId: string,\n state: RouterState,\n settings: Settings | undefined,\n cwd: string,\n noWait: boolean = false,\n userMessageContent?: string,\n subagentId?: string,\n systemEvent?:\n | 'cron'\n | 'policy_approved'\n | 'policy_rejected'\n | 'subagent_update'\n | 'router'\n | 'other',\n displayRole?: 'user' | 'agent'\n) {\n const logger = createChatLogger(chatId, subagentId);\n\n let msgId: string;\n if (systemEvent) {\n const sysMsg = await logger.logSystemMessage({\n content: userMessageContent ?? state.message,\n event: systemEvent,\n messageId: state.messageId,\n ...(displayRole ? { displayRole } : {}),\n });\n msgId = sysMsg.id;\n } else {\n const userMsg = await logger.logUserMessage(userMessageContent ?? state.message);\n msgId = userMsg.id;\n }\n\n if (state.reply) {\n await logger.logAutomaticReply({ messageId: msgId, content: state.reply });\n }\n\n if (!state.message.trim() && state.action !== 'stop' && state.action !== 'interrupt') {\n return;\n }\n\n // Load the agent\n const agentSession = await createAgentSession({\n chatId,\n agentId: state.agentId || 'default',\n sessionId: state.sessionId || 'default',\n ...(subagentId ? { subagentId } : {}),\n cwd,\n settings,\n logger,\n });\n let finalMessage: Message = {\n id: state.messageId,\n content: state.message,\n env: state.env ?? {},\n };\n\n // Process actions\n if (state.action === 'stop') {\n agentSession.stop();\n return;\n }\n if (state.action === 'interrupt') {\n finalMessage = agentSession.interrupt(finalMessage);\n }\n\n // Process message\n const taskPromise = agentSession.handleMessage(finalMessage);\n\n if (!noWait) {\n try {\n await taskPromise;\n } catch (err) {\n if (!(err instanceof Error && err.name === 'AbortError')) {\n throw err;\n }\n }\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 chatSettings: Partial<ChatSettings>,\n overrideAgentId?: string,\n overrideSessionId?: string\n): Promise<RouterState> {\n const agentId = overrideAgentId ?? chatSettings.defaultAgent ?? 'default';\n const sessionId = overrideSessionId ?? chatSettings.sessions?.[agentId] ?? 'default';\n const messageId = 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 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 chatSettings,\n overrideAgentId,\n sessionId\n );\n\n const routers = chatSettings.routers ?? settings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, true);\n const finalState = await executeRouterPipeline(initialState, resolvedRouters);\n\n await applyRouterStateUpdates(chatId, cwd, finalState, chatSettings, initialState.agentId);\n\n await executeDirectMessage(chatId, finalState, settings, cwd, noWait, message);\n}\n\nexport async function applyRouterStateUpdates(\n chatId: string,\n cwd: string,\n finalState: RouterState,\n chatSettings: ChatSettings,\n initialAgent: string | undefined\n) {\n const finalAgentId = finalState.agentId;\n const finalSessionId = finalState.sessionId ?? crypto.randomUUID();\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 (finalState.nextSessionId) {\n chatSettings.sessions = chatSettings.sessions || {};\n chatSettings.sessions[currentAgentId] = finalState.nextSessionId;\n settingsChanged = true;\n }\n\n if (finalState.jobs) {\n chatSettings.jobs = chatSettings.jobs || [];\n\n if (finalState.jobs.remove?.length) {\n const removeSet = new Set(finalState.jobs.remove);\n for (const jobId of finalState.jobs.remove) {\n cronManager.unscheduleJob(chatId, jobId);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !removeSet.has(job.id));\n settingsChanged = true;\n }\n\n if (finalState.jobs.add?.length) {\n const addMap = new Map(finalState.jobs.add.map((job) => [job.id, job]));\n for (const job of finalState.jobs.add) {\n cronManager.scheduleJob(chatId, job);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !addMap.has(job.id));\n chatSettings.jobs.push(...finalState.jobs.add);\n settingsChanged = true;\n }\n }\n\n if (settingsChanged) {\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n // Ensure finalSessionId is set on state so extractDirectState gets it.\n if (finalState.sessionId === undefined) {\n finalState.sessionId = finalSessionId;\n }\n if (finalState.agentId === undefined) {\n finalState.agentId = currentAgentId;\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, applyRouterStateUpdates } from './message.js';\nimport { executeRouterPipeline, resolveRouters } from './routers.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';\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() : job.session?.id;\n const chatSettings = (await readChatSettings(chatId, process.cwd())) ?? {};\n let routerState = await getInitialRouterState(\n chatId,\n job.message,\n chatSettings,\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\n const currentAgentId = job.agentId ?? chatSettings.defaultAgent ?? 'default';\n const currentActiveSession = chatSettings.sessions?.[currentAgentId];\n const isOutdatedSession =\n job.session?.type === 'existing' &&\n currentActiveSession !== undefined &&\n currentActiveSession !== job.session.id;\n\n if (job.reply !== undefined && !isOutdatedSession) routerState.reply = job.reply;\n if (job.nextSessionId !== undefined && !isOutdatedSession)\n routerState.nextSessionId = job.nextSessionId;\n if (job.action !== undefined) routerState.action = job.action;\n if (job.jobs !== undefined) routerState.jobs = job.jobs;\n\n const routers = chatSettings.routers ?? globalSettings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n process.cwd(),\n routerState,\n chatSettings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n globalSettings,\n process.cwd(),\n false,\n job.message,\n undefined,\n 'cron'\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","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport {\n getAgent,\n getClawminiDir,\n readChatSettings,\n writeChatSettings,\n} from '../../shared/workspace.js';\nimport { cronManager } from '../cron.js';\nimport type { z } from 'zod';\nimport type { CronJobSchema } from '../../shared/config.js';\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\nexport async 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\nexport async 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\nexport async function validateAttachments(files: string[]): Promise<void> {\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\nexport async function validateLogFile(\n file: string,\n agentDir: string,\n workspaceRoot: string\n): Promise<string> {\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 return path.relative(workspaceRoot, resolvedPath);\n}\n\nexport async function listCronJobsShared(chatId: string) {\n const settings = await readChatSettings(chatId);\n return settings?.jobs ?? [];\n}\n\nexport async function addCronJobShared(chatId: string, job: z.infer<typeof CronJobSchema>) {\n const settings = (await readChatSettings(chatId)) || {};\n const cronJobs = settings.jobs ?? [];\n const existingIndex = cronJobs.findIndex((j) => j.id === job.id);\n if (existingIndex >= 0) {\n cronJobs[existingIndex] = job;\n } else {\n cronJobs.push(job);\n }\n settings.jobs = cronJobs;\n await writeChatSettings(chatId, settings);\n cronManager.scheduleJob(chatId, job);\n return { success: true };\n}\n\nexport async function deleteCronJobShared(chatId: string, id: string) {\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 !== id);\n if (settings.jobs.length !== initialLength) {\n await writeChatSettings(chatId, settings);\n cronManager.unscheduleJob(chatId, id);\n return { success: true, deleted: true };\n }\n return { success: true, deleted: false };\n}\n","import { z } from 'zod';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport { on } from 'node:events';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, DAEMON_EVENT_TYPING } from '../events.js';\nimport {\n getSettingsPath,\n readChatSettings,\n writeChatSettings,\n getWorkspaceRoot,\n listAgents,\n} from '../../shared/workspace.js';\nimport { CronJobSchema } from '../../shared/config.js';\nimport { handleUserMessage } from '../message.js';\nimport { getDefaultChatId, getMessages as fetchMessages, listChats, createChat } from '../chats.js';\nimport { apiProcedure, publicProcedure, router } from './trpc.js';\nimport {\n getUniquePath,\n resolveAgentDir,\n getAgentFilesDir,\n validateAttachments,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const 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 }) => {\n let message = input.data.message;\n const chatId = input.data.chatId ?? (await getDefaultChatId());\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 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(chatId, message, settings, undefined, noWait, sessionId, agentId);\n\n return { success: true };\n });\n\nexport const getMessages = apiProcedure\n .input(z.object({ chatId: z.string().optional(), limit: z.number().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return fetchMessages(chatId, input.limit);\n });\n\nexport const waitForMessages = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n lastMessageId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\n // 1. Check if there are already new messages\n if (input.lastMessageId) {\n const messages = await fetchMessages(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 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\nexport const waitForTyping = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\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\nexport const ping = publicProcedure.query(() => {\n return { status: 'ok' };\n});\n\nexport const 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\nexport const userListCronJobs = apiProcedure\n .input(z.object({ chatId: z.string().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return listCronJobsShared(chatId);\n });\n\nexport const getChats = apiProcedure.query(async () => {\n return listChats();\n});\n\nexport const getAgents = apiProcedure.query(async () => {\n return listAgents();\n});\n\nexport const userCreateChat = apiProcedure\n .input(z.object({ chatId: z.string(), agent: z.string().optional() }))\n .mutation(async ({ input }) => {\n await createChat(input.chatId);\n if (input.agent) {\n await writeChatSettings(input.chatId, { defaultAgent: input.agent });\n }\n return { success: true, chatId: input.chatId };\n });\n\nexport const userAddCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), job: CronJobSchema }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return addCronJobShared(chatId, input.job);\n });\n\nexport const userDeleteCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), id: z.string() }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return deleteCronJobShared(chatId, input.id);\n });\n\nexport const userRouter = router({\n sendMessage,\n getMessages,\n waitForMessages,\n waitForTyping,\n ping,\n shutdown,\n listCronJobs: userListCronJobs,\n addCronJob: userAddCronJob,\n deleteCronJob: userDeleteCronJob,\n getChats,\n getAgents,\n createChat: userCreateChat,\n});\n\nexport type UserRouter = typeof userRouter;\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 skipSave: boolean = false,\n subagentId?: 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: skipSave ? 'Approved' : 'Pending',\n createdAt: Date.now(),\n chatId,\n agentId,\n ...(subagentId ? { subagentId } : {}),\n };\n\n if (!skipSave) {\n await this.store.save(request);\n }\n\n return request;\n }\n\n getInterpolatedArgs(request: PolicyRequest): string[] {\n return interpolateArgs(request.args, request.fileMappings);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { updateChatSettings, readChatSettings } from '../../shared/workspace.js';\nimport { executeDirectMessage, applyRouterStateUpdates } from '../message.js';\nimport { executeRouterPipeline, resolveRouters } from '../routers.js';\nimport type { RouterState } from '../routers/types.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport type { ChatSettings } from '../../shared/config.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\n\nexport function getSubagentDepth(settings: ChatSettings, parentId: string | undefined): number {\n let depth = 0;\n let currentParentId = parentId;\n while (currentParentId && settings.subagents?.[currentParentId]) {\n depth++;\n currentParentId = settings.subagents[currentParentId]?.parentId;\n }\n return depth;\n}\n\nexport async function executeSubagent(\n chatId: string,\n subagentId: string,\n agentId: string,\n sessionId: string,\n prompt: string,\n isAsync: boolean | undefined,\n parentTokenPayload: { agentId?: string; subagentId?: string; sessionId?: string },\n workspaceRoot: string\n) {\n try {\n const settings = (await readChatSettings(chatId)) || {};\n const routers = settings.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n\n let routerState: RouterState = {\n messageId: randomUUID(),\n message: prompt,\n chatId,\n agentId,\n sessionId,\n env: {},\n };\n\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n workspaceRoot,\n routerState,\n settings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n undefined, // settings\n workspaceRoot,\n false, // noWait\n undefined, // userMessageContent\n subagentId // subagentId\n );\n\n if (taskScheduler.hasTasks(sessionId)) {\n return;\n }\n\n // Update status\n await updateChatSettings(chatId, (finalSettings) => {\n if (finalSettings.subagents?.[subagentId]) {\n finalSettings.subagents[subagentId]!.status = 'completed';\n }\n return finalSettings;\n });\n\n const logger = createChatLogger(chatId, subagentId);\n\n // Emit debug message to wake up waiters\n await logger.logSubagentStatus({ subagentId, status: 'completed' });\n\n if (isAsync) {\n const lastLogMessage = await logger.findLastMessage(\n (m) => m.role === 'agent' || m.displayRole === 'agent'\n );\n let outputContent = '';\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = `\\n\\n<subagent_output>\\n${lastLogMessage.content}\\n</subagent_output>`;\n }\n\n console.log(\n 'Notifying parent',\n chatId,\n parentTokenPayload?.agentId,\n parentTokenPayload?.subagentId\n );\n // TODO: We need to overhaul the log system in general, and should not try to do it in this PR.\n // Currently, if the parent is the root agent, this notification is logged as a normal user message\n // and appears in the chat UI, violating the PRD requirement to hide orchestration.\n await executeDirectMessage(\n chatId,\n {\n messageId: randomUUID(),\n message: `<notification>Subagent ${subagentId} completed.</notification>${outputContent}`,\n chatId,\n agentId: parentTokenPayload?.agentId || 'default',\n ...(parentTokenPayload?.subagentId ? { subagentId: parentTokenPayload.subagentId } : {}),\n sessionId: parentTokenPayload?.sessionId || 'default',\n env: {},\n },\n undefined,\n workspaceRoot,\n true,\n undefined,\n parentTokenPayload?.subagentId,\n 'subagent_update'\n );\n }\n } catch {\n // TODO: Wrap this in a safe try-catch to prevent unhandled promise rejections crashing the daemon if disk errors occur\n await updateChatSettings(chatId, (errSettings) => {\n if (errSettings.subagents?.[subagentId]) {\n errSettings.subagents[subagentId]!.status = 'failed';\n }\n return errSettings;\n });\n const logger = createChatLogger(chatId, subagentId);\n await logger.logSubagentStatus({ subagentId, status: 'failed' });\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport { TRPCError } from '@trpc/server';\nimport { getWorkspaceRoot, readChatSettings, updateChatSettings } from '../../shared/workspace.js';\nimport { apiProcedure } from './trpc.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport { on } from 'node:events';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED } from '../events.js';\nimport { createAgentSession } from '../agent/agent-session.js';\nimport { executeSubagent, getSubagentDepth } from './subagent-utils.js';\nimport type { SubagentTracker } from '../../shared/config.js';\n\nconst MAX_SUBAGENT_DEPTH = 2;\n\nexport const subagentSpawn = apiProcedure\n .input(\n z.object({\n subagentId: z.string().optional(),\n targetAgentId: z.string().optional(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const parentAgentId = ctx.tokenPayload.agentId;\n const parentId = ctx.tokenPayload.subagentId;\n\n const id = input.subagentId || randomUUID();\n const sessionId = randomUUID();\n const agentId = input.targetAgentId || parentAgentId;\n let depth = 0;\n\n await updateChatSettings(chatId, (settings) => {\n settings.subagents = settings.subagents || {};\n\n depth = getSubagentDepth(settings, parentId);\n if (depth >= MAX_SUBAGENT_DEPTH) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Max subagent depth reached' });\n }\n\n // Make sure the id does not already exist\n if (settings.subagents[id]) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Subagent ID already exists' });\n }\n\n settings.subagents[id] = {\n id,\n agentId,\n sessionId,\n createdAt: new Date().toISOString(),\n status: 'active',\n parentId,\n };\n\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n const isAsync = input.async ?? depth === 0;\n\n // Execute asynchronously\n executeSubagent(\n chatId,\n id,\n agentId,\n sessionId,\n input.prompt,\n isAsync,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { id, depth, isAsync };\n });\n\nexport const subagentSend = apiProcedure\n .input(\n z.object({\n subagentId: z.string(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let sub: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (!settings.subagents?.[input.subagentId]) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Subagent not found' });\n }\n\n sub = settings.subagents[input.subagentId];\n sub!.status = 'active';\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n // Execute asynchronously\n executeSubagent(\n chatId,\n sub!.id,\n sub!.agentId || 'default',\n sub!.sessionId || 'default',\n input.prompt,\n input.async,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { success: true };\n });\n\nasync function checkSubagentStatus(chatId: string, subagentId: string) {\n const settings = await readChatSettings(chatId);\n const sub = settings?.subagents?.[subagentId];\n if (!sub) throw new TRPCError({ code: 'NOT_FOUND', message: 'Subagent not found' });\n\n if (sub.status === 'completed' || sub.status === 'failed') {\n let outputContent: string | undefined;\n if (sub.status === 'completed') {\n const logger = createChatLogger(chatId, subagentId);\n const lastLogMessage = await logger.findLastMessage((m) => m.role === 'agent');\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = lastLogMessage.content;\n }\n }\n return { status: sub.status, output: outputContent };\n }\n return null;\n}\n\nexport const subagentWait = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx, signal }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const ac = new AbortController();\n const timeout = setTimeout(() => ac.abort(), 60000);\n\n // Bind to the TRPC request abort signal to clean up listeners if client disconnects\n const onAbort = () => {\n clearTimeout(timeout);\n ac.abort();\n };\n if (signal) {\n signal.addEventListener('abort', onAbort);\n }\n\n const eventIterator = on(daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, {\n signal: ac.signal,\n });\n\n try {\n // Check status immediately before listening, but after event iterator is buffering\n const initialStatus = await checkSubagentStatus(chatId, input.subagentId);\n if (initialStatus) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return initialStatus;\n }\n\n for await (const [event] of eventIterator) {\n if (event.chatId === chatId && event.message?.subagentId === input.subagentId) {\n const msg = event.message;\n if (msg.role === 'subagent_status') {\n const status = await checkSubagentStatus(chatId, input.subagentId);\n if (status) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return status;\n }\n }\n }\n }\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'name' in err && err.name === 'AbortError') {\n return { status: 'active' as const, output: undefined };\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n ac.abort();\n }\n\n return { status: 'active' as const, output: undefined };\n });\n\nexport const subagentStop = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToStop: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents) {\n const sub = settings.subagents[input.subagentId];\n if (sub) {\n sub.status = 'failed';\n subToStop = sub;\n }\n }\n return settings;\n });\n\n if (subToStop) {\n const session = await createAgentSession({\n chatId,\n agentId: subToStop.agentId || 'default',\n sessionId: subToStop.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n }\n\n return { success: true };\n });\n\nexport const subagentDelete = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToDelete: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents && settings.subagents[input.subagentId]) {\n subToDelete = settings.subagents[input.subagentId]!;\n delete settings.subagents[input.subagentId];\n }\n return settings;\n });\n\n if (subToDelete) {\n const session = await createAgentSession({\n chatId,\n agentId: subToDelete.agentId || 'default',\n sessionId: subToDelete.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n\n return { success: true, deleted: true };\n }\n\n return { success: true, deleted: false };\n });\n\nexport const subagentList = apiProcedure\n .input(z.object({ blocking: z.boolean().optional() }).optional())\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const settings = await readChatSettings(chatId);\n\n let subagents = Object.values(settings?.subagents || {});\n\n const isSubagent = !!ctx.tokenPayload.subagentId;\n const myId = ctx.tokenPayload.subagentId;\n\n subagents = subagents.filter((s) => s.parentId === myId);\n\n if (input?.blocking) {\n if (!isSubagent) {\n subagents = [];\n } else {\n subagents = subagents.filter((s) => s.status === 'active');\n }\n }\n return { subagents };\n });\n\nexport const subagentTail = apiProcedure\n .input(z.object({ subagentId: z.string(), limit: z.number().optional() }))\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const logger = createChatLogger(chatId, input.subagentId);\n const messages = await logger.getMessages(input.limit);\n\n return { messages };\n });\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport {\n appendMessage,\n type CommandLogMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n} from '../chats.js';\nimport { executeSafe, generateRequestPreview, executeRequest } from '../policy-utils.js';\nimport { getWorkspaceRoot, readPolicies, getClawminiDir } from '../../shared/workspace.js';\nimport { PolicyRequestService } from '../policy-request-service.js';\nimport { RequestStore } from '../request-store.js';\nimport { CronJobSchema } from '../../shared/config.js';\nimport { apiProcedure, router } from './trpc.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\nimport { formatPendingMessages } from '../agent/utils.js';\nimport {\n resolveAgentDir,\n validateLogFile,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const logMessage = apiProcedure\n .input(\n z.object({\n message: z.string().optional(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.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: CommandLogMessage = {\n id,\n messageId: id,\n role: 'command',\n content: messageStr,\n stdout: '',\n stderr: '',\n timestamp,\n command: `clawmini-lite log${filesArgStr}`,\n cwd: process.cwd(),\n exitCode: 0,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logReplyMessage = apiProcedure\n .input(\n z.object({\n message: z.string(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.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 logMsg: AgentReplyMessage = {\n id,\n role: 'agent',\n content: input.message,\n timestamp,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logToolMessage = apiProcedure\n .input(\n z.object({\n name: z.string(),\n payload: z.any().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n const messageId = randomUUID();\n\n const payloadObj = input.payload !== undefined ? input.payload : {};\n let contentStr: string;\n if (typeof payloadObj === 'string') {\n contentStr = payloadObj;\n } else {\n try {\n contentStr = JSON.stringify(payloadObj, null, 2);\n } catch {\n contentStr = String(payloadObj);\n }\n }\n\n const logMsg: ToolMessage = {\n id,\n messageId,\n role: 'tool',\n name: input.name,\n payload: payloadObj,\n content: contentStr,\n timestamp,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const agentListCronJobs = apiProcedure.query(async ({ ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return listCronJobsShared(chatId);\n});\n\nexport const agentAddCronJob = apiProcedure\n .input(z.object({ job: CronJobSchema }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const job = { ...input.job, agentId: ctx.tokenPayload.agentId };\n return addCronJobShared(chatId, job);\n });\n\nexport const agentDeleteCronJob = apiProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return deleteCronJobShared(chatId, input.id);\n });\n\nexport const listPolicies = apiProcedure.query(async () => {\n return await readPolicies();\n});\n\nexport const 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 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\nexport const 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 })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\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 = ctx.tokenPayload.chatId;\n const agentId = ctx.tokenPayload.agentId;\n\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 const isAutoApprove = !!policy.autoApprove;\n\n const request = await service.createRequest(\n input.commandName,\n input.args,\n input.fileMappings,\n chatId,\n agentId,\n isAutoApprove,\n ctx.tokenPayload.subagentId\n );\n\n if (isAutoApprove) {\n const { stdout, stderr, exitCode, commandStr } = await executeRequest(\n request,\n policy,\n getWorkspaceRoot()\n );\n\n request.executionResult = { stdout, stderr, exitCode };\n await store.save(request);\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'approved',\n content: `[Auto-approved] Policy ${input.commandName} was executed.\\n\\nCommand: ${commandStr}\\nExit Code: ${exitCode}\\n\\nStdout:\\n${stdout}\\n\\nStderr:\\n${stderr}`,\n timestamp: new Date().toISOString(),\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n }\n\n const previewContent = await generateRequestPreview(request);\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'pending',\n content: previewContent,\n timestamp: new Date().toISOString(),\n displayRole: 'agent',\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n });\n\nimport { ping } from './user-router.js';\n\nexport const fetchPendingMessages = apiProcedure.mutation(async ({ ctx }) => {\n if (!ctx.tokenPayload?.agentId) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing agent ID' });\n }\n const targetSessionId = ctx.tokenPayload?.sessionId || 'default';\n\n const extracted = taskScheduler.extractPending(targetSessionId);\n if (extracted.length === 0) {\n return { messages: '' };\n }\n\n return { messages: formatPendingMessages(extracted) };\n});\n\nimport {\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n} from './subagent-router.js';\n\nexport const agentRouter = router({\n logMessage,\n logReplyMessage,\n logToolMessage,\n listCronJobs: agentListCronJobs,\n addCronJob: agentAddCronJob,\n deleteCronJob: agentDeleteCronJob,\n listPolicies,\n executePolicyHelp,\n createPolicyRequest,\n fetchPendingMessages,\n ping,\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n});\n\nexport type AgentRouter = typeof agentRouter;\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 { userRouter, agentRouter } from './api/index.js';\nimport {\n getSocketPath,\n getClawminiDir,\n getSettingsPath,\n readSettings,\n readEnvironment,\n getEnvironmentPath,\n getWorkspaceRoot,\n updateChatSettings,\n} from '../shared/workspace.js';\nimport { listChats } from '../shared/chats.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: userRouter,\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 const cleanOrphanedSubagents = async () => {\n try {\n const chats = await listChats();\n for (const chatId of chats) {\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents) {\n for (const subagent of Object.values(settings.subagents)) {\n if (subagent.status === 'active') {\n subagent.status = 'failed';\n }\n }\n }\n return settings;\n });\n }\n } catch (err) {\n console.warn('Failed to clean orphaned subagents:', err);\n }\n };\n await cleanOrphanedSubagents();\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: agentRouter,\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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"}