@posthog/agent 2.3.280 → 2.3.282

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.
@@ -28,8 +28,8 @@ var availableModes = [
28
28
  if (ALLOW_BYPASS) {
29
29
  availableModes.push({
30
30
  id: "bypassPermissions",
31
- name: "Bypass Permissions",
32
- description: "Bypass all permission prompts"
31
+ name: "Auto-accept Permissions",
32
+ description: "Auto-accept all permission requests"
33
33
  });
34
34
  }
35
35
  var codexModes = [
@@ -48,7 +48,7 @@ if (ALLOW_BYPASS) {
48
48
  codexModes.push({
49
49
  id: "full-access",
50
50
  name: "Full Access",
51
- description: "Bypass all permission prompts"
51
+ description: "Auto-accept all permission requests"
52
52
  });
53
53
  }
54
54
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/utils/common.ts","../../../../src/execution-mode.ts","../../../../src/adapters/claude/tools.ts","../../../../src/adapters/claude/permissions/permission-options.ts"],"sourcesContent":["import type { Logger } from \"./logger\";\n\n/**\n * Races an operation against a timeout.\n * Returns success with the value if the operation completes in time,\n * or timeout if the operation takes longer than the specified duration.\n */\nexport async function withTimeout<T>(\n operation: Promise<T>,\n timeoutMs: number,\n): Promise<{ result: \"success\"; value: T } | { result: \"timeout\" }> {\n const timeoutPromise = new Promise<{ result: \"timeout\" }>((resolve) =>\n setTimeout(() => resolve({ result: \"timeout\" }), timeoutMs),\n );\n const operationPromise = operation.then((value) => ({\n result: \"success\" as const,\n value,\n }));\n return Promise.race([operationPromise, timeoutPromise]);\n}\n\nexport const IS_ROOT =\n typeof process !== \"undefined\" &&\n (process.geteuid?.() ?? process.getuid?.()) === 0;\n\nexport function unreachable(value: never, logger: Logger): void {\n let valueAsString: string;\n try {\n valueAsString = JSON.stringify(value);\n } catch {\n valueAsString = String(value);\n }\n logger.error(`Unexpected case: ${valueAsString}`);\n}\n","import { IS_ROOT } from \"./utils/common\";\n\nexport interface ModeInfo {\n id: string;\n name: string;\n description: string;\n}\n\n// Helper constant that can easily be toggled for env/feature flag/etc\nconst ALLOW_BYPASS = !IS_ROOT;\n\nconst availableModes: ModeInfo[] = [\n {\n id: \"default\",\n name: \"Default\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n {\n id: \"acceptEdits\",\n name: \"Accept Edits\",\n description: \"Auto-accept file edit operations\",\n },\n {\n id: \"plan\",\n name: \"Plan Mode\",\n description: \"Planning mode, no actual tool execution\",\n },\n // {\n // id: \"dontAsk\",\n // name: \"Don't Ask\",\n // description: \"Don't prompt for permissions, deny if not pre-approved\",\n // },\n];\n\nif (ALLOW_BYPASS) {\n availableModes.push({\n id: \"bypassPermissions\",\n name: \"Bypass Permissions\",\n description: \"Bypass all permission prompts\",\n });\n}\n\n// Expose execution mode IDs in type-safe order for type checks\nexport const CODE_EXECUTION_MODES = [\n \"default\",\n \"acceptEdits\",\n \"plan\",\n // \"dontAsk\",\n \"bypassPermissions\",\n] as const;\n\nexport type CodeExecutionMode = (typeof CODE_EXECUTION_MODES)[number];\n\nexport function getAvailableModes(): ModeInfo[] {\n // When IS_ROOT, do not allow bypassPermissions\n return IS_ROOT\n ? availableModes.filter((m) => m.id !== \"bypassPermissions\")\n : availableModes;\n}\n\n// --- Codex-native modes ---\n\nexport const CODEX_NATIVE_MODES = [\"auto\", \"read-only\", \"full-access\"] as const;\n\nexport type CodexNativeMode = (typeof CODEX_NATIVE_MODES)[number];\n\n/** Union of all permission mode IDs across adapters */\nexport type PermissionMode = CodeExecutionMode | CodexNativeMode;\n\nconst codexModes: ModeInfo[] = [\n {\n id: \"read-only\",\n name: \"Read Only\",\n description: \"Read-only access, no file modifications\",\n },\n {\n id: \"auto\",\n name: \"Auto\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n];\n\nif (ALLOW_BYPASS) {\n codexModes.push({\n id: \"full-access\",\n name: \"Full Access\",\n description: \"Bypass all permission prompts\",\n });\n}\n\nexport function getAvailableCodexModes(): ModeInfo[] {\n return IS_ROOT\n ? codexModes.filter((m) => m.id !== \"full-access\")\n : codexModes;\n}\n","export {\n CODE_EXECUTION_MODES,\n type CodeExecutionMode,\n getAvailableModes,\n type ModeInfo,\n} from \"../../execution-mode\";\n\nimport type { CodeExecutionMode } from \"../../execution-mode\";\nimport { isMcpToolReadOnly } from \"./mcp/tool-metadata\";\n\nexport const READ_TOOLS: Set<string> = new Set([\"Read\", \"NotebookRead\"]);\n\nexport const WRITE_TOOLS: Set<string> = new Set([\n \"Edit\",\n \"Write\",\n \"NotebookEdit\",\n]);\n\nexport const BASH_TOOLS: Set<string> = new Set([\n \"Bash\",\n \"BashOutput\",\n \"KillShell\",\n]);\n\nexport const SEARCH_TOOLS: Set<string> = new Set([\"Glob\", \"Grep\", \"LS\"]);\n\nexport const WEB_TOOLS: Set<string> = new Set([\"WebSearch\", \"WebFetch\"]);\n\nexport const AGENT_TOOLS: Set<string> = new Set([\n \"Task\",\n \"Agent\",\n \"TodoWrite\",\n \"Skill\",\n]);\n\nconst BASE_ALLOWED_TOOLS = [\n ...READ_TOOLS,\n ...SEARCH_TOOLS,\n ...WEB_TOOLS,\n ...AGENT_TOOLS,\n];\n\nconst AUTO_ALLOWED_TOOLS: Record<string, Set<string>> = {\n default: new Set(BASE_ALLOWED_TOOLS),\n acceptEdits: new Set([...BASE_ALLOWED_TOOLS, ...WRITE_TOOLS]),\n plan: new Set(BASE_ALLOWED_TOOLS),\n // dontAsk: new Set(BASE_ALLOWED_TOOLS),\n};\n\nexport function isToolAllowedForMode(\n toolName: string,\n mode: CodeExecutionMode,\n): boolean {\n if (mode === \"bypassPermissions\") {\n return true;\n }\n if (AUTO_ALLOWED_TOOLS[mode]?.has(toolName) === true) {\n return true;\n }\n if (isMcpToolReadOnly(toolName)) {\n return true;\n }\n return false;\n}\n","import type { PermissionUpdate } from \"@anthropic-ai/claude-agent-sdk\";\nimport { IS_ROOT } from \"../../../utils/common\";\nimport { BASH_TOOLS, READ_TOOLS, SEARCH_TOOLS, WRITE_TOOLS } from \"../tools\";\n\nexport interface PermissionOption {\n kind: \"allow_once\" | \"allow_always\" | \"reject_once\" | \"reject_always\";\n name: string;\n optionId: string;\n _meta?: { description?: string; customInput?: boolean };\n}\n\nfunction permissionOptions(allowAlwaysLabel: string): PermissionOption[] {\n return [\n { kind: \"allow_once\", name: \"Yes\", optionId: \"allow\" },\n { kind: \"allow_always\", name: allowAlwaysLabel, optionId: \"allow_always\" },\n {\n kind: \"reject_once\",\n name: \"No, and tell the agent what to do differently\",\n optionId: \"reject\",\n _meta: { customInput: true },\n },\n ];\n}\n\nexport function buildPermissionOptions(\n toolName: string,\n toolInput: Record<string, unknown>,\n cwd?: string,\n suggestions?: PermissionUpdate[],\n): PermissionOption[] {\n if (BASH_TOOLS.has(toolName)) {\n const rawRuleContent = suggestions\n ?.flatMap((s) => (\"rules\" in s ? s.rules : []))\n .find((r) => r.toolName === \"Bash\" && r.ruleContent)?.ruleContent;\n const ruleContent = rawRuleContent?.replace(/:?\\*$/, \"\");\n\n const command = toolInput?.command as string | undefined;\n const cmdName = command?.split(/\\s+/)[0] ?? \"this command\";\n const cwdLabel = cwd ? ` in ${cwd}` : \"\";\n const label = ruleContent ?? `\\`${cmdName}\\` commands`;\n\n return permissionOptions(\n `Yes, and don't ask again for ${label}${cwdLabel}`,\n );\n }\n\n if (toolName === \"BashOutput\") {\n return permissionOptions(\"Yes, allow all background process reads\");\n }\n\n if (toolName === \"KillShell\") {\n return permissionOptions(\"Yes, allow killing processes\");\n }\n\n if (WRITE_TOOLS.has(toolName)) {\n return permissionOptions(\"Yes, allow all edits during this session\");\n }\n\n if (READ_TOOLS.has(toolName)) {\n return permissionOptions(\"Yes, allow all reads during this session\");\n }\n\n if (SEARCH_TOOLS.has(toolName)) {\n return permissionOptions(\"Yes, allow all searches during this session\");\n }\n\n if (toolName === \"WebFetch\") {\n const url = toolInput?.url as string | undefined;\n let domain = \"\";\n try {\n domain = url ? new URL(url).hostname : \"\";\n } catch {}\n return permissionOptions(\n domain\n ? `Yes, allow all fetches from ${domain}`\n : \"Yes, allow all fetches\",\n );\n }\n\n if (toolName === \"WebSearch\") {\n return permissionOptions(\"Yes, allow all web searches\");\n }\n\n if (toolName === \"Task\") {\n return permissionOptions(\"Yes, allow all sub-tasks\");\n }\n\n if (toolName === \"TodoWrite\") {\n return permissionOptions(\"Yes, allow all todo updates\");\n }\n\n return permissionOptions(\"Yes, always allow\");\n}\n\nconst ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;\n\nexport function buildExitPlanModePermissionOptions(): PermissionOption[] {\n const options: PermissionOption[] = [];\n\n if (ALLOW_BYPASS) {\n options.push({\n kind: \"allow_always\",\n name: \"Yes, bypass all permissions\",\n optionId: \"bypassPermissions\",\n });\n }\n\n options.push(\n {\n kind: \"allow_always\",\n name: \"Yes, and auto-accept edits\",\n optionId: \"acceptEdits\",\n },\n {\n kind: \"allow_once\",\n name: \"Yes, and manually approve edits\",\n optionId: \"default\",\n },\n {\n kind: \"reject_once\",\n name: \"No, and tell the agent what to do differently\",\n optionId: \"reject_with_feedback\",\n _meta: { customInput: true },\n },\n );\n\n return options;\n}\n"],"mappings":"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","names":["ALLOW_BYPASS"]}
1
+ {"version":3,"sources":["../../../../src/utils/common.ts","../../../../src/execution-mode.ts","../../../../src/adapters/claude/tools.ts","../../../../src/adapters/claude/permissions/permission-options.ts"],"sourcesContent":["import type { Logger } from \"./logger\";\n\n/**\n * Races an operation against a timeout.\n * Returns success with the value if the operation completes in time,\n * or timeout if the operation takes longer than the specified duration.\n */\nexport async function withTimeout<T>(\n operation: Promise<T>,\n timeoutMs: number,\n): Promise<{ result: \"success\"; value: T } | { result: \"timeout\" }> {\n const timeoutPromise = new Promise<{ result: \"timeout\" }>((resolve) =>\n setTimeout(() => resolve({ result: \"timeout\" }), timeoutMs),\n );\n const operationPromise = operation.then((value) => ({\n result: \"success\" as const,\n value,\n }));\n return Promise.race([operationPromise, timeoutPromise]);\n}\n\nexport const IS_ROOT =\n typeof process !== \"undefined\" &&\n (process.geteuid?.() ?? process.getuid?.()) === 0;\n\nexport function unreachable(value: never, logger: Logger): void {\n let valueAsString: string;\n try {\n valueAsString = JSON.stringify(value);\n } catch {\n valueAsString = String(value);\n }\n logger.error(`Unexpected case: ${valueAsString}`);\n}\n","import { IS_ROOT } from \"./utils/common\";\n\nexport interface ModeInfo {\n id: string;\n name: string;\n description: string;\n}\n\n// Helper constant that can easily be toggled for env/feature flag/etc\nconst ALLOW_BYPASS = !IS_ROOT;\n\nconst availableModes: ModeInfo[] = [\n {\n id: \"default\",\n name: \"Default\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n {\n id: \"acceptEdits\",\n name: \"Accept Edits\",\n description: \"Auto-accept file edit operations\",\n },\n {\n id: \"plan\",\n name: \"Plan Mode\",\n description: \"Planning mode, no actual tool execution\",\n },\n // {\n // id: \"dontAsk\",\n // name: \"Don't Ask\",\n // description: \"Don't prompt for permissions, deny if not pre-approved\",\n // },\n];\n\nif (ALLOW_BYPASS) {\n availableModes.push({\n id: \"bypassPermissions\",\n name: \"Auto-accept Permissions\",\n description: \"Auto-accept all permission requests\",\n });\n}\n\n// Expose execution mode IDs in type-safe order for type checks\nexport const CODE_EXECUTION_MODES = [\n \"default\",\n \"acceptEdits\",\n \"plan\",\n // \"dontAsk\",\n \"bypassPermissions\",\n] as const;\n\nexport type CodeExecutionMode = (typeof CODE_EXECUTION_MODES)[number];\n\nexport function isCodeExecutionMode(mode: string): mode is CodeExecutionMode {\n return (CODE_EXECUTION_MODES as readonly string[]).includes(mode);\n}\n\nexport function getAvailableModes(): ModeInfo[] {\n return IS_ROOT\n ? availableModes.filter((m) => m.id !== \"bypassPermissions\")\n : availableModes;\n}\n\n// --- Codex-native modes ---\n\nexport const CODEX_NATIVE_MODES = [\"auto\", \"read-only\", \"full-access\"] as const;\n\nexport type CodexNativeMode = (typeof CODEX_NATIVE_MODES)[number];\n\n/** Union of all permission mode IDs across adapters */\nexport type PermissionMode = CodeExecutionMode | CodexNativeMode;\n\nexport function isCodexNativeMode(mode: string): mode is CodexNativeMode {\n return (CODEX_NATIVE_MODES as readonly string[]).includes(mode);\n}\n\nconst codexModes: ModeInfo[] = [\n {\n id: \"read-only\",\n name: \"Read Only\",\n description: \"Read-only access, no file modifications\",\n },\n {\n id: \"auto\",\n name: \"Auto\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n];\n\nif (ALLOW_BYPASS) {\n codexModes.push({\n id: \"full-access\",\n name: \"Full Access\",\n description: \"Auto-accept all permission requests\",\n });\n}\n\nexport function getAvailableCodexModes(): ModeInfo[] {\n return IS_ROOT\n ? codexModes.filter((m) => m.id !== \"full-access\")\n : codexModes;\n}\n","export {\n CODE_EXECUTION_MODES,\n type CodeExecutionMode,\n getAvailableModes,\n type ModeInfo,\n} from \"../../execution-mode\";\n\nimport type { CodeExecutionMode } from \"../../execution-mode\";\nimport { isMcpToolReadOnly } from \"./mcp/tool-metadata\";\n\nexport const READ_TOOLS: Set<string> = new Set([\"Read\", \"NotebookRead\"]);\n\nexport const WRITE_TOOLS: Set<string> = new Set([\n \"Edit\",\n \"Write\",\n \"NotebookEdit\",\n]);\n\nexport const BASH_TOOLS: Set<string> = new Set([\n \"Bash\",\n \"BashOutput\",\n \"KillShell\",\n]);\n\nexport const SEARCH_TOOLS: Set<string> = new Set([\"Glob\", \"Grep\", \"LS\"]);\n\nexport const WEB_TOOLS: Set<string> = new Set([\"WebSearch\", \"WebFetch\"]);\n\nexport const AGENT_TOOLS: Set<string> = new Set([\n \"Task\",\n \"Agent\",\n \"TodoWrite\",\n \"Skill\",\n]);\n\nconst BASE_ALLOWED_TOOLS = [\n ...READ_TOOLS,\n ...SEARCH_TOOLS,\n ...WEB_TOOLS,\n ...AGENT_TOOLS,\n];\n\nconst AUTO_ALLOWED_TOOLS: Record<string, Set<string>> = {\n default: new Set(BASE_ALLOWED_TOOLS),\n acceptEdits: new Set([...BASE_ALLOWED_TOOLS, ...WRITE_TOOLS]),\n plan: new Set(BASE_ALLOWED_TOOLS),\n // dontAsk: new Set(BASE_ALLOWED_TOOLS),\n};\n\nexport function isToolAllowedForMode(\n toolName: string,\n mode: CodeExecutionMode,\n): boolean {\n if (mode === \"bypassPermissions\") {\n return true;\n }\n if (AUTO_ALLOWED_TOOLS[mode]?.has(toolName) === true) {\n return true;\n }\n if (isMcpToolReadOnly(toolName)) {\n return true;\n }\n return false;\n}\n","import type { PermissionUpdate } from \"@anthropic-ai/claude-agent-sdk\";\nimport { IS_ROOT } from \"../../../utils/common\";\nimport { BASH_TOOLS, READ_TOOLS, SEARCH_TOOLS, WRITE_TOOLS } from \"../tools\";\n\nexport interface PermissionOption {\n kind: \"allow_once\" | \"allow_always\" | \"reject_once\" | \"reject_always\";\n name: string;\n optionId: string;\n _meta?: { description?: string; customInput?: boolean };\n}\n\nfunction permissionOptions(allowAlwaysLabel: string): PermissionOption[] {\n return [\n { kind: \"allow_once\", name: \"Yes\", optionId: \"allow\" },\n { kind: \"allow_always\", name: allowAlwaysLabel, optionId: \"allow_always\" },\n {\n kind: \"reject_once\",\n name: \"No, and tell the agent what to do differently\",\n optionId: \"reject\",\n _meta: { customInput: true },\n },\n ];\n}\n\nexport function buildPermissionOptions(\n toolName: string,\n toolInput: Record<string, unknown>,\n cwd?: string,\n suggestions?: PermissionUpdate[],\n): PermissionOption[] {\n if (BASH_TOOLS.has(toolName)) {\n const rawRuleContent = suggestions\n ?.flatMap((s) => (\"rules\" in s ? s.rules : []))\n .find((r) => r.toolName === \"Bash\" && r.ruleContent)?.ruleContent;\n const ruleContent = rawRuleContent?.replace(/:?\\*$/, \"\");\n\n const command = toolInput?.command as string | undefined;\n const cmdName = command?.split(/\\s+/)[0] ?? \"this command\";\n const cwdLabel = cwd ? ` in ${cwd}` : \"\";\n const label = ruleContent ?? `\\`${cmdName}\\` commands`;\n\n return permissionOptions(\n `Yes, and don't ask again for ${label}${cwdLabel}`,\n );\n }\n\n if (toolName === \"BashOutput\") {\n return permissionOptions(\"Yes, allow all background process reads\");\n }\n\n if (toolName === \"KillShell\") {\n return permissionOptions(\"Yes, allow killing processes\");\n }\n\n if (WRITE_TOOLS.has(toolName)) {\n return permissionOptions(\"Yes, allow all edits during this session\");\n }\n\n if (READ_TOOLS.has(toolName)) {\n return permissionOptions(\"Yes, allow all reads during this session\");\n }\n\n if (SEARCH_TOOLS.has(toolName)) {\n return permissionOptions(\"Yes, allow all searches during this session\");\n }\n\n if (toolName === \"WebFetch\") {\n const url = toolInput?.url as string | undefined;\n let domain = \"\";\n try {\n domain = url ? new URL(url).hostname : \"\";\n } catch {}\n return permissionOptions(\n domain\n ? `Yes, allow all fetches from ${domain}`\n : \"Yes, allow all fetches\",\n );\n }\n\n if (toolName === \"WebSearch\") {\n return permissionOptions(\"Yes, allow all web searches\");\n }\n\n if (toolName === \"Task\") {\n return permissionOptions(\"Yes, allow all sub-tasks\");\n }\n\n if (toolName === \"TodoWrite\") {\n return permissionOptions(\"Yes, allow all todo updates\");\n }\n\n return permissionOptions(\"Yes, always allow\");\n}\n\nconst ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;\n\nexport function buildExitPlanModePermissionOptions(): PermissionOption[] {\n const options: PermissionOption[] = [];\n\n if (ALLOW_BYPASS) {\n options.push({\n kind: \"allow_always\",\n name: \"Yes, bypass all permissions\",\n optionId: \"bypassPermissions\",\n });\n }\n\n options.push(\n {\n kind: \"allow_always\",\n name: \"Yes, and auto-accept edits\",\n optionId: \"acceptEdits\",\n },\n {\n kind: \"allow_once\",\n name: \"Yes, and manually approve edits\",\n optionId: \"default\",\n },\n {\n kind: \"reject_once\",\n name: \"No, and tell the agent what to do differently\",\n optionId: \"reject_with_feedback\",\n _meta: { customInput: true },\n },\n );\n\n return options;\n}\n"],"mappings":"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","names":["ALLOW_BYPASS"]}
@@ -28,8 +28,8 @@ var availableModes = [
28
28
  if (ALLOW_BYPASS) {
29
29
  availableModes.push({
30
30
  id: "bypassPermissions",
31
- name: "Bypass Permissions",
32
- description: "Bypass all permission prompts"
31
+ name: "Auto-accept Permissions",
32
+ description: "Auto-accept all permission requests"
33
33
  });
34
34
  }
35
35
  var CODE_EXECUTION_MODES = [
@@ -58,7 +58,7 @@ if (ALLOW_BYPASS) {
58
58
  codexModes.push({
59
59
  id: "full-access",
60
60
  name: "Full Access",
61
- description: "Bypass all permission prompts"
61
+ description: "Auto-accept all permission requests"
62
62
  });
63
63
  }
64
64
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/common.ts","../../../src/execution-mode.ts","../../../src/adapters/claude/mcp/tool-metadata.ts","../../../src/adapters/claude/tools.ts"],"sourcesContent":["import type { Logger } from \"./logger\";\n\n/**\n * Races an operation against a timeout.\n * Returns success with the value if the operation completes in time,\n * or timeout if the operation takes longer than the specified duration.\n */\nexport async function withTimeout<T>(\n operation: Promise<T>,\n timeoutMs: number,\n): Promise<{ result: \"success\"; value: T } | { result: \"timeout\" }> {\n const timeoutPromise = new Promise<{ result: \"timeout\" }>((resolve) =>\n setTimeout(() => resolve({ result: \"timeout\" }), timeoutMs),\n );\n const operationPromise = operation.then((value) => ({\n result: \"success\" as const,\n value,\n }));\n return Promise.race([operationPromise, timeoutPromise]);\n}\n\nexport const IS_ROOT =\n typeof process !== \"undefined\" &&\n (process.geteuid?.() ?? process.getuid?.()) === 0;\n\nexport function unreachable(value: never, logger: Logger): void {\n let valueAsString: string;\n try {\n valueAsString = JSON.stringify(value);\n } catch {\n valueAsString = String(value);\n }\n logger.error(`Unexpected case: ${valueAsString}`);\n}\n","import { IS_ROOT } from \"./utils/common\";\n\nexport interface ModeInfo {\n id: string;\n name: string;\n description: string;\n}\n\n// Helper constant that can easily be toggled for env/feature flag/etc\nconst ALLOW_BYPASS = !IS_ROOT;\n\nconst availableModes: ModeInfo[] = [\n {\n id: \"default\",\n name: \"Default\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n {\n id: \"acceptEdits\",\n name: \"Accept Edits\",\n description: \"Auto-accept file edit operations\",\n },\n {\n id: \"plan\",\n name: \"Plan Mode\",\n description: \"Planning mode, no actual tool execution\",\n },\n // {\n // id: \"dontAsk\",\n // name: \"Don't Ask\",\n // description: \"Don't prompt for permissions, deny if not pre-approved\",\n // },\n];\n\nif (ALLOW_BYPASS) {\n availableModes.push({\n id: \"bypassPermissions\",\n name: \"Bypass Permissions\",\n description: \"Bypass all permission prompts\",\n });\n}\n\n// Expose execution mode IDs in type-safe order for type checks\nexport const CODE_EXECUTION_MODES = [\n \"default\",\n \"acceptEdits\",\n \"plan\",\n // \"dontAsk\",\n \"bypassPermissions\",\n] as const;\n\nexport type CodeExecutionMode = (typeof CODE_EXECUTION_MODES)[number];\n\nexport function getAvailableModes(): ModeInfo[] {\n // When IS_ROOT, do not allow bypassPermissions\n return IS_ROOT\n ? availableModes.filter((m) => m.id !== \"bypassPermissions\")\n : availableModes;\n}\n\n// --- Codex-native modes ---\n\nexport const CODEX_NATIVE_MODES = [\"auto\", \"read-only\", \"full-access\"] as const;\n\nexport type CodexNativeMode = (typeof CODEX_NATIVE_MODES)[number];\n\n/** Union of all permission mode IDs across adapters */\nexport type PermissionMode = CodeExecutionMode | CodexNativeMode;\n\nconst codexModes: ModeInfo[] = [\n {\n id: \"read-only\",\n name: \"Read Only\",\n description: \"Read-only access, no file modifications\",\n },\n {\n id: \"auto\",\n name: \"Auto\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n];\n\nif (ALLOW_BYPASS) {\n codexModes.push({\n id: \"full-access\",\n name: \"Full Access\",\n description: \"Bypass all permission prompts\",\n });\n}\n\nexport function getAvailableCodexModes(): ModeInfo[] {\n return IS_ROOT\n ? codexModes.filter((m) => m.id !== \"full-access\")\n : codexModes;\n}\n","import type { McpServerStatus, Query } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Logger } from \"../../../utils/logger\";\n\nexport interface McpToolMetadata {\n readOnly: boolean;\n name: string;\n description?: string;\n}\n\nconst mcpToolMetadataCache: Map<string, McpToolMetadata> = new Map();\n\nconst PENDING_RETRY_INTERVAL_MS = 1_000;\nconst PENDING_MAX_RETRIES = 10;\n\nfunction buildToolKey(serverName: string, toolName: string): string {\n return `mcp__${serverName}__${toolName}`;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function fetchMcpToolMetadata(\n q: Query,\n logger: Logger = new Logger({ debug: false, prefix: \"[McpToolMetadata]\" }),\n): Promise<void> {\n let retries = 0;\n\n while (retries <= PENDING_MAX_RETRIES) {\n let statuses: McpServerStatus[];\n try {\n statuses = await q.mcpServerStatus();\n } catch (error) {\n logger.error(\"Failed to fetch MCP server status\", {\n error: error instanceof Error ? error.message : String(error),\n });\n return;\n }\n\n const pendingServers = statuses.filter((s) => s.status === \"pending\");\n\n for (const server of statuses) {\n if (server.status !== \"connected\" || !server.tools) {\n continue;\n }\n\n let readOnlyCount = 0;\n for (const tool of server.tools) {\n const toolKey = buildToolKey(server.name, tool.name);\n const readOnly = tool.annotations?.readOnly === true;\n\n mcpToolMetadataCache.set(toolKey, {\n readOnly,\n name: tool.name,\n description: tool.description,\n });\n if (readOnly) readOnlyCount++;\n }\n\n logger.info(\"Fetched MCP tool metadata\", {\n serverName: server.name,\n toolCount: server.tools.length,\n readOnlyCount,\n });\n }\n\n if (pendingServers.length === 0) {\n return;\n }\n\n retries++;\n if (retries > PENDING_MAX_RETRIES) {\n logger.warn(\"Gave up waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n });\n return;\n }\n\n logger.info(\"Waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n retry: retries,\n });\n await delay(PENDING_RETRY_INTERVAL_MS);\n }\n}\n\nexport function getMcpToolMetadata(\n toolName: string,\n): McpToolMetadata | undefined {\n return mcpToolMetadataCache.get(toolName);\n}\n\nexport function isMcpToolReadOnly(toolName: string): boolean {\n const metadata = mcpToolMetadataCache.get(toolName);\n return metadata?.readOnly === true;\n}\n\nexport function getConnectedMcpServerNames(): string[] {\n const names = new Set<string>();\n for (const key of mcpToolMetadataCache.keys()) {\n const parts = key.split(\"__\");\n if (parts.length >= 3) names.add(parts[1]);\n }\n return [...names];\n}\n\nexport function clearMcpToolMetadataCache(): void {\n mcpToolMetadataCache.clear();\n}\n","export {\n CODE_EXECUTION_MODES,\n type CodeExecutionMode,\n getAvailableModes,\n type ModeInfo,\n} from \"../../execution-mode\";\n\nimport type { CodeExecutionMode } from \"../../execution-mode\";\nimport { isMcpToolReadOnly } from \"./mcp/tool-metadata\";\n\nexport const READ_TOOLS: Set<string> = new Set([\"Read\", \"NotebookRead\"]);\n\nexport const WRITE_TOOLS: Set<string> = new Set([\n \"Edit\",\n \"Write\",\n \"NotebookEdit\",\n]);\n\nexport const BASH_TOOLS: Set<string> = new Set([\n \"Bash\",\n \"BashOutput\",\n \"KillShell\",\n]);\n\nexport const SEARCH_TOOLS: Set<string> = new Set([\"Glob\", \"Grep\", \"LS\"]);\n\nexport const WEB_TOOLS: Set<string> = new Set([\"WebSearch\", \"WebFetch\"]);\n\nexport const AGENT_TOOLS: Set<string> = new Set([\n \"Task\",\n \"Agent\",\n \"TodoWrite\",\n \"Skill\",\n]);\n\nconst BASE_ALLOWED_TOOLS = [\n ...READ_TOOLS,\n ...SEARCH_TOOLS,\n ...WEB_TOOLS,\n ...AGENT_TOOLS,\n];\n\nconst AUTO_ALLOWED_TOOLS: Record<string, Set<string>> = {\n default: new Set(BASE_ALLOWED_TOOLS),\n acceptEdits: new Set([...BASE_ALLOWED_TOOLS, ...WRITE_TOOLS]),\n plan: new Set(BASE_ALLOWED_TOOLS),\n // dontAsk: new Set(BASE_ALLOWED_TOOLS),\n};\n\nexport function isToolAllowedForMode(\n toolName: string,\n mode: CodeExecutionMode,\n): boolean {\n if (mode === \"bypassPermissions\") {\n return true;\n }\n if (AUTO_ALLOWED_TOOLS[mode]?.has(toolName) === true) {\n return true;\n }\n if (isMcpToolReadOnly(toolName)) {\n return true;\n }\n return false;\n}\n"],"mappings":";AAqBO,IAAM,UACX,OAAO,YAAY,gBAClB,QAAQ,UAAU,KAAK,QAAQ,SAAS,OAAO;;;ACdlD,IAAM,eAAe,CAAC;AAEtB,IAAM,iBAA6B;AAAA,EACjC;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAMF;AAEA,IAAI,cAAc;AAChB,iBAAe,KAAK;AAAA,IAClB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf,CAAC;AACH;AAGO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AACF;AAIO,SAAS,oBAAgC;AAE9C,SAAO,UACH,eAAe,OAAO,CAAC,MAAM,EAAE,OAAO,mBAAmB,IACzD;AACN;AAWA,IAAM,aAAyB;AAAA,EAC7B;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACF;AAEA,IAAI,cAAc;AAChB,aAAW,KAAK;AAAA,IACd,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf,CAAC;AACH;;;AC/EA,IAAM,uBAAqD,oBAAI,IAAI;AAmF5D,SAAS,kBAAkB,UAA2B;AAC3D,QAAM,WAAW,qBAAqB,IAAI,QAAQ;AAClD,SAAO,UAAU,aAAa;AAChC;;;ACrFO,IAAM,aAA0B,oBAAI,IAAI,CAAC,QAAQ,cAAc,CAAC;AAEhE,IAAM,cAA2B,oBAAI,IAAI;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,aAA0B,oBAAI,IAAI;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,eAA4B,oBAAI,IAAI,CAAC,QAAQ,QAAQ,IAAI,CAAC;AAEhE,IAAM,YAAyB,oBAAI,IAAI,CAAC,aAAa,UAAU,CAAC;AAEhE,IAAM,cAA2B,oBAAI,IAAI;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,qBAAqB;AAAA,EACzB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,IAAM,qBAAkD;AAAA,EACtD,SAAS,IAAI,IAAI,kBAAkB;AAAA,EACnC,aAAa,oBAAI,IAAI,CAAC,GAAG,oBAAoB,GAAG,WAAW,CAAC;AAAA,EAC5D,MAAM,IAAI,IAAI,kBAAkB;AAAA;AAElC;AAEO,SAAS,qBACd,UACA,MACS;AACT,MAAI,SAAS,qBAAqB;AAChC,WAAO;AAAA,EACT;AACA,MAAI,mBAAmB,IAAI,GAAG,IAAI,QAAQ,MAAM,MAAM;AACpD,WAAO;AAAA,EACT;AACA,MAAI,kBAAkB,QAAQ,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/common.ts","../../../src/execution-mode.ts","../../../src/adapters/claude/mcp/tool-metadata.ts","../../../src/adapters/claude/tools.ts"],"sourcesContent":["import type { Logger } from \"./logger\";\n\n/**\n * Races an operation against a timeout.\n * Returns success with the value if the operation completes in time,\n * or timeout if the operation takes longer than the specified duration.\n */\nexport async function withTimeout<T>(\n operation: Promise<T>,\n timeoutMs: number,\n): Promise<{ result: \"success\"; value: T } | { result: \"timeout\" }> {\n const timeoutPromise = new Promise<{ result: \"timeout\" }>((resolve) =>\n setTimeout(() => resolve({ result: \"timeout\" }), timeoutMs),\n );\n const operationPromise = operation.then((value) => ({\n result: \"success\" as const,\n value,\n }));\n return Promise.race([operationPromise, timeoutPromise]);\n}\n\nexport const IS_ROOT =\n typeof process !== \"undefined\" &&\n (process.geteuid?.() ?? process.getuid?.()) === 0;\n\nexport function unreachable(value: never, logger: Logger): void {\n let valueAsString: string;\n try {\n valueAsString = JSON.stringify(value);\n } catch {\n valueAsString = String(value);\n }\n logger.error(`Unexpected case: ${valueAsString}`);\n}\n","import { IS_ROOT } from \"./utils/common\";\n\nexport interface ModeInfo {\n id: string;\n name: string;\n description: string;\n}\n\n// Helper constant that can easily be toggled for env/feature flag/etc\nconst ALLOW_BYPASS = !IS_ROOT;\n\nconst availableModes: ModeInfo[] = [\n {\n id: \"default\",\n name: \"Default\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n {\n id: \"acceptEdits\",\n name: \"Accept Edits\",\n description: \"Auto-accept file edit operations\",\n },\n {\n id: \"plan\",\n name: \"Plan Mode\",\n description: \"Planning mode, no actual tool execution\",\n },\n // {\n // id: \"dontAsk\",\n // name: \"Don't Ask\",\n // description: \"Don't prompt for permissions, deny if not pre-approved\",\n // },\n];\n\nif (ALLOW_BYPASS) {\n availableModes.push({\n id: \"bypassPermissions\",\n name: \"Auto-accept Permissions\",\n description: \"Auto-accept all permission requests\",\n });\n}\n\n// Expose execution mode IDs in type-safe order for type checks\nexport const CODE_EXECUTION_MODES = [\n \"default\",\n \"acceptEdits\",\n \"plan\",\n // \"dontAsk\",\n \"bypassPermissions\",\n] as const;\n\nexport type CodeExecutionMode = (typeof CODE_EXECUTION_MODES)[number];\n\nexport function isCodeExecutionMode(mode: string): mode is CodeExecutionMode {\n return (CODE_EXECUTION_MODES as readonly string[]).includes(mode);\n}\n\nexport function getAvailableModes(): ModeInfo[] {\n return IS_ROOT\n ? availableModes.filter((m) => m.id !== \"bypassPermissions\")\n : availableModes;\n}\n\n// --- Codex-native modes ---\n\nexport const CODEX_NATIVE_MODES = [\"auto\", \"read-only\", \"full-access\"] as const;\n\nexport type CodexNativeMode = (typeof CODEX_NATIVE_MODES)[number];\n\n/** Union of all permission mode IDs across adapters */\nexport type PermissionMode = CodeExecutionMode | CodexNativeMode;\n\nexport function isCodexNativeMode(mode: string): mode is CodexNativeMode {\n return (CODEX_NATIVE_MODES as readonly string[]).includes(mode);\n}\n\nconst codexModes: ModeInfo[] = [\n {\n id: \"read-only\",\n name: \"Read Only\",\n description: \"Read-only access, no file modifications\",\n },\n {\n id: \"auto\",\n name: \"Auto\",\n description: \"Standard behavior, prompts for dangerous operations\",\n },\n];\n\nif (ALLOW_BYPASS) {\n codexModes.push({\n id: \"full-access\",\n name: \"Full Access\",\n description: \"Auto-accept all permission requests\",\n });\n}\n\nexport function getAvailableCodexModes(): ModeInfo[] {\n return IS_ROOT\n ? codexModes.filter((m) => m.id !== \"full-access\")\n : codexModes;\n}\n","import type { McpServerStatus, Query } from \"@anthropic-ai/claude-agent-sdk\";\nimport { Logger } from \"../../../utils/logger\";\n\nexport interface McpToolMetadata {\n readOnly: boolean;\n name: string;\n description?: string;\n}\n\nconst mcpToolMetadataCache: Map<string, McpToolMetadata> = new Map();\n\nconst PENDING_RETRY_INTERVAL_MS = 1_000;\nconst PENDING_MAX_RETRIES = 10;\n\nfunction buildToolKey(serverName: string, toolName: string): string {\n return `mcp__${serverName}__${toolName}`;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function fetchMcpToolMetadata(\n q: Query,\n logger: Logger = new Logger({ debug: false, prefix: \"[McpToolMetadata]\" }),\n): Promise<void> {\n let retries = 0;\n\n while (retries <= PENDING_MAX_RETRIES) {\n let statuses: McpServerStatus[];\n try {\n statuses = await q.mcpServerStatus();\n } catch (error) {\n logger.error(\"Failed to fetch MCP server status\", {\n error: error instanceof Error ? error.message : String(error),\n });\n return;\n }\n\n const pendingServers = statuses.filter((s) => s.status === \"pending\");\n\n for (const server of statuses) {\n if (server.status !== \"connected\" || !server.tools) {\n continue;\n }\n\n let readOnlyCount = 0;\n for (const tool of server.tools) {\n const toolKey = buildToolKey(server.name, tool.name);\n const readOnly = tool.annotations?.readOnly === true;\n\n mcpToolMetadataCache.set(toolKey, {\n readOnly,\n name: tool.name,\n description: tool.description,\n });\n if (readOnly) readOnlyCount++;\n }\n\n logger.info(\"Fetched MCP tool metadata\", {\n serverName: server.name,\n toolCount: server.tools.length,\n readOnlyCount,\n });\n }\n\n if (pendingServers.length === 0) {\n return;\n }\n\n retries++;\n if (retries > PENDING_MAX_RETRIES) {\n logger.warn(\"Gave up waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n });\n return;\n }\n\n logger.info(\"Waiting for pending MCP servers\", {\n pendingServers: pendingServers.map((s) => s.name),\n retry: retries,\n });\n await delay(PENDING_RETRY_INTERVAL_MS);\n }\n}\n\nexport function getMcpToolMetadata(\n toolName: string,\n): McpToolMetadata | undefined {\n return mcpToolMetadataCache.get(toolName);\n}\n\nexport function isMcpToolReadOnly(toolName: string): boolean {\n const metadata = mcpToolMetadataCache.get(toolName);\n return metadata?.readOnly === true;\n}\n\nexport function getConnectedMcpServerNames(): string[] {\n const names = new Set<string>();\n for (const key of mcpToolMetadataCache.keys()) {\n const parts = key.split(\"__\");\n if (parts.length >= 3) names.add(parts[1]);\n }\n return [...names];\n}\n\nexport function clearMcpToolMetadataCache(): void {\n mcpToolMetadataCache.clear();\n}\n","export {\n CODE_EXECUTION_MODES,\n type CodeExecutionMode,\n getAvailableModes,\n type ModeInfo,\n} from \"../../execution-mode\";\n\nimport type { CodeExecutionMode } from \"../../execution-mode\";\nimport { isMcpToolReadOnly } from \"./mcp/tool-metadata\";\n\nexport const READ_TOOLS: Set<string> = new Set([\"Read\", \"NotebookRead\"]);\n\nexport const WRITE_TOOLS: Set<string> = new Set([\n \"Edit\",\n \"Write\",\n \"NotebookEdit\",\n]);\n\nexport const BASH_TOOLS: Set<string> = new Set([\n \"Bash\",\n \"BashOutput\",\n \"KillShell\",\n]);\n\nexport const SEARCH_TOOLS: Set<string> = new Set([\"Glob\", \"Grep\", \"LS\"]);\n\nexport const WEB_TOOLS: Set<string> = new Set([\"WebSearch\", \"WebFetch\"]);\n\nexport const AGENT_TOOLS: Set<string> = new Set([\n \"Task\",\n \"Agent\",\n \"TodoWrite\",\n \"Skill\",\n]);\n\nconst BASE_ALLOWED_TOOLS = [\n ...READ_TOOLS,\n ...SEARCH_TOOLS,\n ...WEB_TOOLS,\n ...AGENT_TOOLS,\n];\n\nconst AUTO_ALLOWED_TOOLS: Record<string, Set<string>> = {\n default: new Set(BASE_ALLOWED_TOOLS),\n acceptEdits: new Set([...BASE_ALLOWED_TOOLS, ...WRITE_TOOLS]),\n plan: new Set(BASE_ALLOWED_TOOLS),\n // dontAsk: new Set(BASE_ALLOWED_TOOLS),\n};\n\nexport function isToolAllowedForMode(\n toolName: string,\n mode: CodeExecutionMode,\n): boolean {\n if (mode === \"bypassPermissions\") {\n return true;\n }\n if (AUTO_ALLOWED_TOOLS[mode]?.has(toolName) === true) {\n return true;\n }\n if (isMcpToolReadOnly(toolName)) {\n return true;\n }\n return false;\n}\n"],"mappings":";AAqBO,IAAM,UACX,OAAO,YAAY,gBAClB,QAAQ,UAAU,KAAK,QAAQ,SAAS,OAAO;;;ACdlD,IAAM,eAAe,CAAC;AAEtB,IAAM,iBAA6B;AAAA,EACjC;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAMF;AAEA,IAAI,cAAc;AAChB,iBAAe,KAAK;AAAA,IAClB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf,CAAC;AACH;AAGO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AACF;AAQO,SAAS,oBAAgC;AAC9C,SAAO,UACH,eAAe,OAAO,CAAC,MAAM,EAAE,OAAO,mBAAmB,IACzD;AACN;AAeA,IAAM,aAAyB;AAAA,EAC7B;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACF;AAEA,IAAI,cAAc;AAChB,aAAW,KAAK;AAAA,IACd,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf,CAAC;AACH;;;ACtFA,IAAM,uBAAqD,oBAAI,IAAI;AAmF5D,SAAS,kBAAkB,UAA2B;AAC3D,QAAM,WAAW,qBAAqB,IAAI,QAAQ;AAClD,SAAO,UAAU,aAAa;AAChC;;;ACrFO,IAAM,aAA0B,oBAAI,IAAI,CAAC,QAAQ,cAAc,CAAC;AAEhE,IAAM,cAA2B,oBAAI,IAAI;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,aAA0B,oBAAI,IAAI;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,eAA4B,oBAAI,IAAI,CAAC,QAAQ,QAAQ,IAAI,CAAC;AAEhE,IAAM,YAAyB,oBAAI,IAAI,CAAC,aAAa,UAAU,CAAC;AAEhE,IAAM,cAA2B,oBAAI,IAAI;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,qBAAqB;AAAA,EACzB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,IAAM,qBAAkD;AAAA,EACtD,SAAS,IAAI,IAAI,kBAAkB;AAAA,EACnC,aAAa,oBAAI,IAAI,CAAC,GAAG,oBAAoB,GAAG,WAAW,CAAC;AAAA,EAC5D,MAAM,IAAI,IAAI,kBAAkB;AAAA;AAElC;AAEO,SAAS,qBACd,UACA,MACS;AACT,MAAI,SAAS,qBAAqB;AAChC,WAAO;AAAA,EACT;AACA,MAAI,mBAAmB,IAAI,GAAG,IAAI,QAAQ,MAAM,MAAM;AACpD,WAAO;AAAA,EACT;AACA,MAAI,kBAAkB,QAAQ,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,SAAO;AACT;","names":[]}
package/dist/agent.js CHANGED
@@ -245,7 +245,7 @@ import { v7 as uuidv7 } from "uuid";
245
245
  // package.json
246
246
  var package_default = {
247
247
  name: "@posthog/agent",
248
- version: "2.3.280",
248
+ version: "2.3.282",
249
249
  repository: "https://github.com/PostHog/code",
250
250
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
251
251
  exports: {
@@ -2146,8 +2146,8 @@ var availableModes = [
2146
2146
  if (ALLOW_BYPASS) {
2147
2147
  availableModes.push({
2148
2148
  id: "bypassPermissions",
2149
- name: "Bypass Permissions",
2150
- description: "Bypass all permission prompts"
2149
+ name: "Auto-accept Permissions",
2150
+ description: "Auto-accept all permission requests"
2151
2151
  });
2152
2152
  }
2153
2153
  var CODE_EXECUTION_MODES = [
@@ -2157,9 +2157,16 @@ var CODE_EXECUTION_MODES = [
2157
2157
  // "dontAsk",
2158
2158
  "bypassPermissions"
2159
2159
  ];
2160
+ function isCodeExecutionMode(mode) {
2161
+ return CODE_EXECUTION_MODES.includes(mode);
2162
+ }
2160
2163
  function getAvailableModes() {
2161
2164
  return IS_ROOT ? availableModes.filter((m) => m.id !== "bypassPermissions") : availableModes;
2162
2165
  }
2166
+ var CODEX_NATIVE_MODES = ["auto", "read-only", "full-access"];
2167
+ function isCodexNativeMode(mode) {
2168
+ return CODEX_NATIVE_MODES.includes(mode);
2169
+ }
2163
2170
  var codexModes = [
2164
2171
  {
2165
2172
  id: "read-only",
@@ -2176,7 +2183,7 @@ if (ALLOW_BYPASS) {
2176
2183
  codexModes.push({
2177
2184
  id: "full-access",
2178
2185
  name: "Full Access",
2179
- description: "Bypass all permission prompts"
2186
+ description: "Auto-accept all permission requests"
2180
2187
  });
2181
2188
  }
2182
2189
 
@@ -4226,10 +4233,24 @@ var AUTO_APPROVED_KINDS = {
4226
4233
  "fetch",
4227
4234
  "switch_mode",
4228
4235
  "other"
4236
+ ]),
4237
+ auto: /* @__PURE__ */ new Set(["read", "search", "fetch", "think"]),
4238
+ "read-only": /* @__PURE__ */ new Set(["read", "search", "fetch", "think"]),
4239
+ "full-access": /* @__PURE__ */ new Set([
4240
+ "read",
4241
+ "edit",
4242
+ "delete",
4243
+ "move",
4244
+ "search",
4245
+ "execute",
4246
+ "think",
4247
+ "fetch",
4248
+ "switch_mode",
4249
+ "other"
4229
4250
  ])
4230
4251
  };
4231
4252
  function shouldAutoApprove(mode, kind) {
4232
- if (mode === "bypassPermissions") return true;
4253
+ if (mode === "bypassPermissions" || mode === "full-access") return true;
4233
4254
  if (!kind) return false;
4234
4255
  return AUTO_APPROVED_KINDS[mode]?.has(kind) ?? false;
4235
4256
  }
@@ -4336,7 +4357,7 @@ function createSessionState(sessionId, cwd, opts) {
4336
4357
  return {
4337
4358
  sessionId,
4338
4359
  cwd,
4339
- modeId: opts?.modeId ?? "default",
4360
+ modeId: opts?.modeId ?? "auto",
4340
4361
  modelId: opts?.modelId,
4341
4362
  configOptions: [],
4342
4363
  accumulatedUsage: {
@@ -4345,7 +4366,7 @@ function createSessionState(sessionId, cwd, opts) {
4345
4366
  cachedReadTokens: 0,
4346
4367
  cachedWriteTokens: 0
4347
4368
  },
4348
- permissionMode: opts?.permissionMode ?? "default",
4369
+ permissionMode: opts?.permissionMode ?? "auto",
4349
4370
  taskRunId: opts?.taskRunId,
4350
4371
  taskId: opts?.taskId
4351
4372
  };
@@ -4540,18 +4561,33 @@ function spawnCodexProcess(options) {
4540
4561
  }
4541
4562
 
4542
4563
  // src/adapters/codex/codex-agent.ts
4543
- function toCodeExecutionMode(mode) {
4544
- if (mode && CODE_EXECUTION_MODES.includes(mode)) {
4564
+ function toCodexPermissionMode(mode) {
4565
+ if (mode && (isCodexNativeMode(mode) || isCodeExecutionMode(mode))) {
4545
4566
  return mode;
4546
4567
  }
4547
- return "default";
4568
+ return "auto";
4548
4569
  }
4549
4570
  var CODEX_NATIVE_MODE = {
4550
- default: "default",
4551
- acceptEdits: "default",
4552
- plan: "plan",
4553
- bypassPermissions: "default"
4571
+ default: "auto",
4572
+ acceptEdits: "auto",
4573
+ plan: "read-only",
4574
+ bypassPermissions: "full-access"
4554
4575
  };
4576
+ function toCodexNativeMode(mode) {
4577
+ if (mode && isCodexNativeMode(mode)) {
4578
+ return mode;
4579
+ }
4580
+ if (mode && isCodeExecutionMode(mode)) {
4581
+ return CODEX_NATIVE_MODE[mode];
4582
+ }
4583
+ return "auto";
4584
+ }
4585
+ function getCurrentPermissionMode(currentModeId, fallbackMode) {
4586
+ if (currentModeId && isCodexNativeMode(currentModeId)) {
4587
+ return currentModeId;
4588
+ }
4589
+ return toCodexPermissionMode(fallbackMode);
4590
+ }
4555
4591
  var CodexAcpAgent = class extends BaseAcpAgent {
4556
4592
  adapterName = "codex";
4557
4593
  codexProcess;
@@ -4611,16 +4647,22 @@ var CodexAcpAgent = class extends BaseAcpAgent {
4611
4647
  }
4612
4648
  async newSession(params) {
4613
4649
  const meta = params._meta;
4650
+ const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
4614
4651
  const response = await this.codexConnection.newSession(params);
4615
4652
  this.sessionState = createSessionState(response.sessionId, params.cwd, {
4616
4653
  taskRunId: meta?.taskRunId,
4617
4654
  taskId: meta?.taskId ?? meta?.persistence?.taskId,
4618
- modeId: response.modes?.currentModeId ?? "default",
4655
+ modeId: response.modes?.currentModeId ?? "auto",
4619
4656
  modelId: response.models?.currentModelId,
4620
- permissionMode: toCodeExecutionMode(meta?.permissionMode)
4657
+ permissionMode: requestedPermissionMode
4621
4658
  });
4622
4659
  this.sessionId = response.sessionId;
4623
4660
  this.sessionState.configOptions = response.configOptions ?? [];
4661
+ await this.applyInitialPermissionMode(
4662
+ response.sessionId,
4663
+ meta?.permissionMode,
4664
+ response.modes?.currentModeId
4665
+ );
4624
4666
  if (meta?.taskRunId) {
4625
4667
  await this.client.extNotification(POSTHOG_NOTIFICATIONS.SDK_SESSION, {
4626
4668
  taskRunId: meta.taskRunId,
@@ -4637,8 +4679,13 @@ var CodexAcpAgent = class extends BaseAcpAgent {
4637
4679
  async loadSession(params) {
4638
4680
  const response = await this.codexConnection.loadSession(params);
4639
4681
  const meta = params._meta;
4682
+ const currentPermissionMode = getCurrentPermissionMode(
4683
+ response.modes?.currentModeId,
4684
+ meta?.permissionMode
4685
+ );
4640
4686
  this.sessionState = createSessionState(params.sessionId, params.cwd, {
4641
- permissionMode: toCodeExecutionMode(meta?.permissionMode)
4687
+ modeId: response.modes?.currentModeId ?? "auto",
4688
+ permissionMode: currentPermissionMode
4642
4689
  });
4643
4690
  this.sessionId = params.sessionId;
4644
4691
  this.sessionState.configOptions = response.configOptions ?? [];
@@ -4651,10 +4698,15 @@ var CodexAcpAgent = class extends BaseAcpAgent {
4651
4698
  mcpServers: params.mcpServers ?? []
4652
4699
  });
4653
4700
  const meta = params._meta;
4701
+ const currentPermissionMode = getCurrentPermissionMode(
4702
+ loadResponse.modes?.currentModeId,
4703
+ meta?.permissionMode
4704
+ );
4654
4705
  this.sessionState = createSessionState(params.sessionId, params.cwd, {
4655
4706
  taskRunId: meta?.taskRunId,
4656
4707
  taskId: meta?.taskId ?? meta?.persistence?.taskId,
4657
- permissionMode: toCodeExecutionMode(meta?.permissionMode)
4708
+ modeId: loadResponse.modes?.currentModeId ?? "auto",
4709
+ permissionMode: currentPermissionMode
4658
4710
  });
4659
4711
  this.sessionId = params.sessionId;
4660
4712
  this.sessionState.configOptions = loadResponse.configOptions ?? [];
@@ -4678,15 +4730,39 @@ var CodexAcpAgent = class extends BaseAcpAgent {
4678
4730
  _meta: params._meta
4679
4731
  });
4680
4732
  const meta = params._meta;
4733
+ const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
4681
4734
  this.sessionState = createSessionState(newResponse.sessionId, params.cwd, {
4682
4735
  taskRunId: meta?.taskRunId,
4683
4736
  taskId: meta?.taskId ?? meta?.persistence?.taskId,
4684
- permissionMode: toCodeExecutionMode(meta?.permissionMode)
4737
+ modeId: newResponse.modes?.currentModeId ?? "auto",
4738
+ permissionMode: requestedPermissionMode
4685
4739
  });
4686
4740
  this.sessionId = newResponse.sessionId;
4687
4741
  this.sessionState.configOptions = newResponse.configOptions ?? [];
4742
+ await this.applyInitialPermissionMode(
4743
+ newResponse.sessionId,
4744
+ meta?.permissionMode,
4745
+ newResponse.modes?.currentModeId
4746
+ );
4688
4747
  return newResponse;
4689
4748
  }
4749
+ async applyInitialPermissionMode(sessionId, permissionMode, currentModeId) {
4750
+ if (!permissionMode) {
4751
+ return;
4752
+ }
4753
+ const nativeMode = toCodexNativeMode(permissionMode);
4754
+ if (nativeMode === currentModeId) {
4755
+ this.sessionState.modeId = nativeMode;
4756
+ this.sessionState.permissionMode = toCodexPermissionMode(permissionMode);
4757
+ return;
4758
+ }
4759
+ await this.codexConnection.setSessionMode({
4760
+ sessionId,
4761
+ modeId: nativeMode
4762
+ });
4763
+ this.sessionState.modeId = nativeMode;
4764
+ this.sessionState.permissionMode = toCodexPermissionMode(permissionMode);
4765
+ }
4690
4766
  async listSessions(params) {
4691
4767
  return this.codexConnection.listSessions(params);
4692
4768
  }
@@ -4732,8 +4808,8 @@ var CodexAcpAgent = class extends BaseAcpAgent {
4732
4808
  });
4733
4809
  }
4734
4810
  async setSessionMode(params) {
4735
- const requestedMode = toCodeExecutionMode(params.modeId);
4736
- const nativeMode = CODEX_NATIVE_MODE[requestedMode];
4811
+ const requestedMode = toCodexPermissionMode(params.modeId);
4812
+ const nativeMode = toCodexNativeMode(params.modeId);
4737
4813
  const response = await this.codexConnection.setSessionMode({
4738
4814
  ...params,
4739
4815
  modeId: nativeMode