@posthog/agent 2.3.349 → 2.3.353
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/claude/permissions/permission-options.d.ts +1 -1
- package/dist/adapters/claude/permissions/permission-options.js +3 -3
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/agent.js +5961 -128
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +227 -53
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +225 -51
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/claude/hooks.ts +9 -2
- package/src/adapters/claude/permissions/permission-handlers.ts +53 -10
- package/src/adapters/claude/permissions/permission-options.ts +3 -3
- package/src/adapters/claude/session/options.test.ts +72 -0
- package/src/adapters/claude/session/options.ts +56 -1
- package/src/adapters/claude/session/repo-path.ts +22 -0
- package/src/adapters/claude/session/settings.test.ts +159 -0
- package/src/adapters/claude/session/settings.ts +92 -6
package/dist/posthog-api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@posthog/agent",
|
|
4
|
-
version: "2.3.
|
|
4
|
+
version: "2.3.353",
|
|
5
5
|
repository: "https://github.com/PostHog/code",
|
|
6
6
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
7
7
|
exports: {
|
package/dist/posthog-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/utils/gateway.ts","../src/posthog-api.ts"],"sourcesContent":["{\n \"name\": \"@posthog/agent\",\n \"version\": \"2.3.349\",\n \"repository\": \"https://github.com/PostHog/code\",\n \"description\": \"TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./agent\": {\n \"types\": \"./dist/agent.d.ts\",\n \"import\": \"./dist/agent.js\"\n },\n \"./gateway-models\": {\n \"types\": \"./dist/gateway-models.d.ts\",\n \"import\": \"./dist/gateway-models.js\"\n },\n \"./posthog-api\": {\n \"types\": \"./dist/posthog-api.d.ts\",\n \"import\": \"./dist/posthog-api.js\"\n },\n \"./types\": {\n \"types\": \"./dist/types.d.ts\",\n \"import\": \"./dist/types.js\"\n },\n \"./adapters/claude/questions/utils\": {\n \"types\": \"./dist/adapters/claude/questions/utils.d.ts\",\n \"import\": \"./dist/adapters/claude/questions/utils.js\"\n },\n \"./adapters/claude/permissions/permission-options\": {\n \"types\": \"./dist/adapters/claude/permissions/permission-options.d.ts\",\n \"import\": \"./dist/adapters/claude/permissions/permission-options.js\"\n },\n \"./adapters/claude/tools\": {\n \"types\": \"./dist/adapters/claude/tools.d.ts\",\n \"import\": \"./dist/adapters/claude/tools.js\"\n },\n \"./adapters/claude/conversion/tool-use-to-acp\": {\n \"types\": \"./dist/adapters/claude/conversion/tool-use-to-acp.d.ts\",\n \"import\": \"./dist/adapters/claude/conversion/tool-use-to-acp.js\"\n },\n \"./adapters/claude/session/jsonl-hydration\": {\n \"types\": \"./dist/adapters/claude/session/jsonl-hydration.d.ts\",\n \"import\": \"./dist/adapters/claude/session/jsonl-hydration.js\"\n },\n \"./adapters/claude/session/models\": {\n \"types\": \"./dist/adapters/claude/session/models.d.ts\",\n \"import\": \"./dist/adapters/claude/session/models.js\"\n },\n \"./adapters/reasoning-effort\": {\n \"types\": \"./dist/adapters/reasoning-effort.d.ts\",\n \"import\": \"./dist/adapters/reasoning-effort.js\"\n },\n \"./execution-mode\": {\n \"types\": \"./dist/execution-mode.d.ts\",\n \"import\": \"./dist/execution-mode.js\"\n },\n \"./server\": {\n \"types\": \"./dist/server/agent-server.d.ts\",\n \"import\": \"./dist/server/agent-server.js\"\n }\n },\n \"bin\": {\n \"agent-server\": \"./dist/server/bin.cjs\"\n },\n \"type\": \"module\",\n \"keywords\": [\n \"posthog\",\n \"claude\",\n \"agent\",\n \"ai\",\n \"git\",\n \"typescript\"\n ],\n \"author\": \"PostHog\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"scripts\": {\n \"build\": \"node ../../scripts/rimraf.mjs dist && tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"pnpm exec tsc --noEmit\",\n \"prepublishOnly\": \"pnpm run build\",\n \"clean\": \"node ../../scripts/rimraf.mjs dist .turbo\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"devDependencies\": {\n \"@posthog/shared\": \"workspace:*\",\n \"@posthog/git\": \"workspace:*\",\n \"@posthog/enricher\": \"workspace:*\",\n \"@types/bun\": \"latest\",\n \"@types/tar\": \"^6.1.13\",\n \"msw\": \"^2.12.7\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.5.0\",\n \"vitest\": \"^2.1.8\"\n },\n \"dependencies\": {\n \"@agentclientprotocol/sdk\": \"0.19.0\",\n \"ajv\": \"^8.17.1\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.2.112\",\n \"@anthropic-ai/sdk\": \"0.89.0\",\n \"@hono/node-server\": \"^1.19.9\",\n \"@opentelemetry/api-logs\": \"^0.208.0\",\n \"@opentelemetry/exporter-logs-otlp-http\": \"^0.208.0\",\n \"@opentelemetry/resources\": \"^2.0.0\",\n \"@opentelemetry/sdk-logs\": \"^0.208.0\",\n \"@opentelemetry/semantic-conventions\": \"^1.28.0\",\n \"@types/jsonwebtoken\": \"^9.0.10\",\n \"commander\": \"^14.0.2\",\n \"hono\": \"^4.11.7\",\n \"jsonwebtoken\": \"^9.0.2\",\n \"minimatch\": \"^10.0.3\",\n \"tar\": \"^7.5.0\",\n \"uuid\": \"13.0.0\",\n \"yoga-wasm-web\": \"^0.3.3\",\n \"zod\": \"^4.2.0\"\n },\n \"files\": [\n \"dist/**/*\",\n \"src/**/*\",\n \"README.md\",\n \"CLAUDE.md\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","export type GatewayProduct = \"posthog_code\" | \"background_agents\";\n\nfunction getGatewayBaseUrl(posthogHost: string): string {\n const url = new URL(posthogHost);\n const hostname = url.hostname;\n\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return `${url.protocol}//localhost:3308`;\n }\n\n if (hostname === \"host.docker.internal\") {\n return `${url.protocol}//host.docker.internal:3308`;\n }\n\n const region = hostname.match(/^(us|eu)\\.posthog\\.com$/)?.[1] ?? \"us\";\n return `https://gateway.${region}.posthog.com`;\n}\n\nexport function getLlmGatewayUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/${product}`;\n}\n\nexport function getGatewayUsageUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/v1/usage/${product}`;\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\nimport type {\n ArtifactType,\n PostHogAPIConfig,\n StoredEntry,\n Task,\n TaskRun,\n TaskRunArtifact,\n} from \"./types\";\nimport { getGatewayUsageUrl, getLlmGatewayUrl } from \"./utils/gateway\";\n\nexport { getGatewayUsageUrl, getLlmGatewayUrl };\n\nconst DEFAULT_USER_AGENT = `posthog/agent.hog.dev; version: ${packageJson.version}`;\n\nexport interface TaskArtifactUploadPayload {\n name: string;\n type: ArtifactType;\n content: string;\n content_type?: string;\n}\n\nexport type TaskRunUpdate = Partial<\n Pick<\n TaskRun,\n | \"status\"\n | \"branch\"\n | \"stage\"\n | \"error_message\"\n | \"output\"\n | \"state\"\n | \"environment\"\n >\n> & {\n state_remove_keys?: string[];\n};\n\nexport class PostHogAPIClient {\n private config: PostHogAPIConfig;\n\n constructor(config: PostHogAPIConfig) {\n this.config = config;\n }\n\n private get baseUrl(): string {\n const host = this.config.apiUrl.endsWith(\"/\")\n ? this.config.apiUrl.slice(0, -1)\n : this.config.apiUrl;\n return host;\n }\n\n private isAuthFailure(status: number): boolean {\n return status === 401 || status === 403;\n }\n\n private async resolveApiKey(forceRefresh = false): Promise<string> {\n if (forceRefresh && this.config.refreshApiKey) {\n return this.config.refreshApiKey();\n }\n\n return this.config.getApiKey();\n }\n\n private async buildHeaders(\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Headers> {\n const headers = new Headers(options.headers);\n headers.set(\n \"Authorization\",\n `Bearer ${await this.resolveApiKey(forceRefresh)}`,\n );\n headers.set(\"Content-Type\", \"application/json\");\n headers.set(\"User-Agent\", this.config.userAgent ?? DEFAULT_USER_AGENT);\n return headers;\n }\n\n private async performRequest(\n endpoint: string,\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Response> {\n const url = `${this.baseUrl}${endpoint}`;\n\n return fetch(url, {\n ...options,\n headers: await this.buildHeaders(options, forceRefresh),\n });\n }\n\n private async performRequestWithRetry(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<Response> {\n let response = await this.performRequest(endpoint, options);\n\n if (!response.ok && this.isAuthFailure(response.status)) {\n response = await this.performRequest(endpoint, options, true);\n }\n\n return response;\n }\n\n private async apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const response = await this.performRequestWithRetry(endpoint, options);\n\n if (!response.ok) {\n let errorMessage: string;\n try {\n const errorResponse = await response.json();\n errorMessage = `Failed request: [${response.status}] ${JSON.stringify(errorResponse)}`;\n } catch {\n errorMessage = `Failed request: [${response.status}] ${response.statusText}`;\n }\n throw new Error(errorMessage);\n }\n\n return response.json();\n }\n\n private getTeamId(): number {\n return this.config.projectId;\n }\n\n async getApiKey(forceRefresh = false): Promise<string> {\n return this.resolveApiKey(forceRefresh);\n }\n\n getLlmGatewayUrl(): string {\n return getLlmGatewayUrl(this.baseUrl);\n }\n\n async getTask(taskId: string): Promise<Task> {\n const teamId = this.getTeamId();\n return this.apiRequest<Task>(`/api/projects/${teamId}/tasks/${taskId}/`);\n }\n\n async getTaskRun(taskId: string, runId: string): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n );\n }\n\n async updateTaskRun(\n taskId: string,\n runId: string,\n payload: TaskRunUpdate,\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(payload),\n },\n );\n }\n\n async setTaskRunOutput(\n taskId: string,\n runId: string,\n output: Record<string, unknown>,\n ): Promise<TaskRun> {\n return this.apiRequest(\n `/api/projects/${this.getTeamId()}/tasks/${taskId}/runs/${runId}/set_output/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(output),\n },\n );\n }\n\n async appendTaskRunLog(\n taskId: string,\n runId: string,\n entries: StoredEntry[],\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/append_log/`,\n {\n method: \"POST\",\n body: JSON.stringify({ entries }),\n },\n );\n }\n\n async relayMessage(\n taskId: string,\n runId: string,\n text: string,\n ): Promise<void> {\n const teamId = this.getTeamId();\n await this.apiRequest<{ status: string }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/relay_message/`,\n {\n method: \"POST\",\n body: JSON.stringify({ text }),\n },\n );\n }\n\n async uploadTaskArtifacts(\n taskId: string,\n runId: string,\n artifacts: TaskArtifactUploadPayload[],\n ): Promise<TaskRunArtifact[]> {\n if (!artifacts.length) {\n return [];\n }\n\n const teamId = this.getTeamId();\n const response = await this.apiRequest<{ artifacts: TaskRunArtifact[] }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/`,\n {\n method: \"POST\",\n body: JSON.stringify({ artifacts }),\n },\n );\n\n return response.artifacts ?? [];\n }\n\n /**\n * Download artifact content by storage path\n * Streams the file through the PostHog backend so the sandbox does not need\n * direct access to object storage.\n */\n async downloadArtifact(\n taskId: string,\n runId: string,\n storagePath: string,\n ): Promise<ArrayBuffer | null> {\n const teamId = this.getTeamId();\n\n try {\n const response = await this.performRequestWithRetry(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/download/`,\n {\n method: \"POST\",\n body: JSON.stringify({ storage_path: storagePath }),\n },\n );\n if (!response.ok) {\n throw new Error(`Failed to download artifact: ${response.status}`);\n }\n return response.arrayBuffer();\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch logs for a task run via the logs API endpoint\n * @param taskRun - The task run to fetch logs for\n * @returns Array of stored entries, or empty array if no logs available\n */\n async fetchTaskRunLogs(taskRun: TaskRun): Promise<StoredEntry[]> {\n const teamId = this.getTeamId();\n const endpoint = `/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`;\n\n try {\n const response = await this.performRequestWithRetry(endpoint);\n\n if (!response.ok) {\n if (response.status === 404) {\n return [];\n }\n throw new Error(\n `Failed to fetch logs: ${response.status} ${response.statusText}`,\n );\n }\n\n const content = await response.text();\n\n if (!content.trim()) {\n return [];\n }\n\n // Parse newline-delimited JSON\n return content\n .trim()\n .split(\"\\n\")\n .map((line) => JSON.parse(line) as StoredEntry);\n } catch (error) {\n throw new Error(\n `Failed to fetch task run logs: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/utils/gateway.ts","../src/posthog-api.ts"],"sourcesContent":["{\n \"name\": \"@posthog/agent\",\n \"version\": \"2.3.353\",\n \"repository\": \"https://github.com/PostHog/code\",\n \"description\": \"TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./agent\": {\n \"types\": \"./dist/agent.d.ts\",\n \"import\": \"./dist/agent.js\"\n },\n \"./gateway-models\": {\n \"types\": \"./dist/gateway-models.d.ts\",\n \"import\": \"./dist/gateway-models.js\"\n },\n \"./posthog-api\": {\n \"types\": \"./dist/posthog-api.d.ts\",\n \"import\": \"./dist/posthog-api.js\"\n },\n \"./types\": {\n \"types\": \"./dist/types.d.ts\",\n \"import\": \"./dist/types.js\"\n },\n \"./adapters/claude/questions/utils\": {\n \"types\": \"./dist/adapters/claude/questions/utils.d.ts\",\n \"import\": \"./dist/adapters/claude/questions/utils.js\"\n },\n \"./adapters/claude/permissions/permission-options\": {\n \"types\": \"./dist/adapters/claude/permissions/permission-options.d.ts\",\n \"import\": \"./dist/adapters/claude/permissions/permission-options.js\"\n },\n \"./adapters/claude/tools\": {\n \"types\": \"./dist/adapters/claude/tools.d.ts\",\n \"import\": \"./dist/adapters/claude/tools.js\"\n },\n \"./adapters/claude/conversion/tool-use-to-acp\": {\n \"types\": \"./dist/adapters/claude/conversion/tool-use-to-acp.d.ts\",\n \"import\": \"./dist/adapters/claude/conversion/tool-use-to-acp.js\"\n },\n \"./adapters/claude/session/jsonl-hydration\": {\n \"types\": \"./dist/adapters/claude/session/jsonl-hydration.d.ts\",\n \"import\": \"./dist/adapters/claude/session/jsonl-hydration.js\"\n },\n \"./adapters/claude/session/models\": {\n \"types\": \"./dist/adapters/claude/session/models.d.ts\",\n \"import\": \"./dist/adapters/claude/session/models.js\"\n },\n \"./adapters/reasoning-effort\": {\n \"types\": \"./dist/adapters/reasoning-effort.d.ts\",\n \"import\": \"./dist/adapters/reasoning-effort.js\"\n },\n \"./execution-mode\": {\n \"types\": \"./dist/execution-mode.d.ts\",\n \"import\": \"./dist/execution-mode.js\"\n },\n \"./server\": {\n \"types\": \"./dist/server/agent-server.d.ts\",\n \"import\": \"./dist/server/agent-server.js\"\n }\n },\n \"bin\": {\n \"agent-server\": \"./dist/server/bin.cjs\"\n },\n \"type\": \"module\",\n \"keywords\": [\n \"posthog\",\n \"claude\",\n \"agent\",\n \"ai\",\n \"git\",\n \"typescript\"\n ],\n \"author\": \"PostHog\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"scripts\": {\n \"build\": \"node ../../scripts/rimraf.mjs dist && tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"pnpm exec tsc --noEmit\",\n \"prepublishOnly\": \"pnpm run build\",\n \"clean\": \"node ../../scripts/rimraf.mjs dist .turbo\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"devDependencies\": {\n \"@posthog/shared\": \"workspace:*\",\n \"@posthog/git\": \"workspace:*\",\n \"@posthog/enricher\": \"workspace:*\",\n \"@types/bun\": \"latest\",\n \"@types/tar\": \"^6.1.13\",\n \"msw\": \"^2.12.7\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.5.0\",\n \"vitest\": \"^2.1.8\"\n },\n \"dependencies\": {\n \"@agentclientprotocol/sdk\": \"0.19.0\",\n \"ajv\": \"^8.17.1\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.2.112\",\n \"@anthropic-ai/sdk\": \"0.89.0\",\n \"@hono/node-server\": \"^1.19.9\",\n \"@opentelemetry/api-logs\": \"^0.208.0\",\n \"@opentelemetry/exporter-logs-otlp-http\": \"^0.208.0\",\n \"@opentelemetry/resources\": \"^2.0.0\",\n \"@opentelemetry/sdk-logs\": \"^0.208.0\",\n \"@opentelemetry/semantic-conventions\": \"^1.28.0\",\n \"@types/jsonwebtoken\": \"^9.0.10\",\n \"commander\": \"^14.0.2\",\n \"hono\": \"^4.11.7\",\n \"jsonwebtoken\": \"^9.0.2\",\n \"minimatch\": \"^10.0.3\",\n \"tar\": \"^7.5.0\",\n \"uuid\": \"13.0.0\",\n \"yoga-wasm-web\": \"^0.3.3\",\n \"zod\": \"^4.2.0\"\n },\n \"files\": [\n \"dist/**/*\",\n \"src/**/*\",\n \"README.md\",\n \"CLAUDE.md\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","export type GatewayProduct = \"posthog_code\" | \"background_agents\";\n\nfunction getGatewayBaseUrl(posthogHost: string): string {\n const url = new URL(posthogHost);\n const hostname = url.hostname;\n\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return `${url.protocol}//localhost:3308`;\n }\n\n if (hostname === \"host.docker.internal\") {\n return `${url.protocol}//host.docker.internal:3308`;\n }\n\n const region = hostname.match(/^(us|eu)\\.posthog\\.com$/)?.[1] ?? \"us\";\n return `https://gateway.${region}.posthog.com`;\n}\n\nexport function getLlmGatewayUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/${product}`;\n}\n\nexport function getGatewayUsageUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/v1/usage/${product}`;\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\nimport type {\n ArtifactType,\n PostHogAPIConfig,\n StoredEntry,\n Task,\n TaskRun,\n TaskRunArtifact,\n} from \"./types\";\nimport { getGatewayUsageUrl, getLlmGatewayUrl } from \"./utils/gateway\";\n\nexport { getGatewayUsageUrl, getLlmGatewayUrl };\n\nconst DEFAULT_USER_AGENT = `posthog/agent.hog.dev; version: ${packageJson.version}`;\n\nexport interface TaskArtifactUploadPayload {\n name: string;\n type: ArtifactType;\n content: string;\n content_type?: string;\n}\n\nexport type TaskRunUpdate = Partial<\n Pick<\n TaskRun,\n | \"status\"\n | \"branch\"\n | \"stage\"\n | \"error_message\"\n | \"output\"\n | \"state\"\n | \"environment\"\n >\n> & {\n state_remove_keys?: string[];\n};\n\nexport class PostHogAPIClient {\n private config: PostHogAPIConfig;\n\n constructor(config: PostHogAPIConfig) {\n this.config = config;\n }\n\n private get baseUrl(): string {\n const host = this.config.apiUrl.endsWith(\"/\")\n ? this.config.apiUrl.slice(0, -1)\n : this.config.apiUrl;\n return host;\n }\n\n private isAuthFailure(status: number): boolean {\n return status === 401 || status === 403;\n }\n\n private async resolveApiKey(forceRefresh = false): Promise<string> {\n if (forceRefresh && this.config.refreshApiKey) {\n return this.config.refreshApiKey();\n }\n\n return this.config.getApiKey();\n }\n\n private async buildHeaders(\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Headers> {\n const headers = new Headers(options.headers);\n headers.set(\n \"Authorization\",\n `Bearer ${await this.resolveApiKey(forceRefresh)}`,\n );\n headers.set(\"Content-Type\", \"application/json\");\n headers.set(\"User-Agent\", this.config.userAgent ?? DEFAULT_USER_AGENT);\n return headers;\n }\n\n private async performRequest(\n endpoint: string,\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Response> {\n const url = `${this.baseUrl}${endpoint}`;\n\n return fetch(url, {\n ...options,\n headers: await this.buildHeaders(options, forceRefresh),\n });\n }\n\n private async performRequestWithRetry(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<Response> {\n let response = await this.performRequest(endpoint, options);\n\n if (!response.ok && this.isAuthFailure(response.status)) {\n response = await this.performRequest(endpoint, options, true);\n }\n\n return response;\n }\n\n private async apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const response = await this.performRequestWithRetry(endpoint, options);\n\n if (!response.ok) {\n let errorMessage: string;\n try {\n const errorResponse = await response.json();\n errorMessage = `Failed request: [${response.status}] ${JSON.stringify(errorResponse)}`;\n } catch {\n errorMessage = `Failed request: [${response.status}] ${response.statusText}`;\n }\n throw new Error(errorMessage);\n }\n\n return response.json();\n }\n\n private getTeamId(): number {\n return this.config.projectId;\n }\n\n async getApiKey(forceRefresh = false): Promise<string> {\n return this.resolveApiKey(forceRefresh);\n }\n\n getLlmGatewayUrl(): string {\n return getLlmGatewayUrl(this.baseUrl);\n }\n\n async getTask(taskId: string): Promise<Task> {\n const teamId = this.getTeamId();\n return this.apiRequest<Task>(`/api/projects/${teamId}/tasks/${taskId}/`);\n }\n\n async getTaskRun(taskId: string, runId: string): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n );\n }\n\n async updateTaskRun(\n taskId: string,\n runId: string,\n payload: TaskRunUpdate,\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(payload),\n },\n );\n }\n\n async setTaskRunOutput(\n taskId: string,\n runId: string,\n output: Record<string, unknown>,\n ): Promise<TaskRun> {\n return this.apiRequest(\n `/api/projects/${this.getTeamId()}/tasks/${taskId}/runs/${runId}/set_output/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(output),\n },\n );\n }\n\n async appendTaskRunLog(\n taskId: string,\n runId: string,\n entries: StoredEntry[],\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/append_log/`,\n {\n method: \"POST\",\n body: JSON.stringify({ entries }),\n },\n );\n }\n\n async relayMessage(\n taskId: string,\n runId: string,\n text: string,\n ): Promise<void> {\n const teamId = this.getTeamId();\n await this.apiRequest<{ status: string }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/relay_message/`,\n {\n method: \"POST\",\n body: JSON.stringify({ text }),\n },\n );\n }\n\n async uploadTaskArtifacts(\n taskId: string,\n runId: string,\n artifacts: TaskArtifactUploadPayload[],\n ): Promise<TaskRunArtifact[]> {\n if (!artifacts.length) {\n return [];\n }\n\n const teamId = this.getTeamId();\n const response = await this.apiRequest<{ artifacts: TaskRunArtifact[] }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/`,\n {\n method: \"POST\",\n body: JSON.stringify({ artifacts }),\n },\n );\n\n return response.artifacts ?? [];\n }\n\n /**\n * Download artifact content by storage path\n * Streams the file through the PostHog backend so the sandbox does not need\n * direct access to object storage.\n */\n async downloadArtifact(\n taskId: string,\n runId: string,\n storagePath: string,\n ): Promise<ArrayBuffer | null> {\n const teamId = this.getTeamId();\n\n try {\n const response = await this.performRequestWithRetry(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/download/`,\n {\n method: \"POST\",\n body: JSON.stringify({ storage_path: storagePath }),\n },\n );\n if (!response.ok) {\n throw new Error(`Failed to download artifact: ${response.status}`);\n }\n return response.arrayBuffer();\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch logs for a task run via the logs API endpoint\n * @param taskRun - The task run to fetch logs for\n * @returns Array of stored entries, or empty array if no logs available\n */\n async fetchTaskRunLogs(taskRun: TaskRun): Promise<StoredEntry[]> {\n const teamId = this.getTeamId();\n const endpoint = `/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`;\n\n try {\n const response = await this.performRequestWithRetry(endpoint);\n\n if (!response.ok) {\n if (response.status === 404) {\n return [];\n }\n throw new Error(\n `Failed to fetch logs: ${response.status} ${response.statusText}`,\n );\n }\n\n const content = await response.text();\n\n if (!content.trim()) {\n return [];\n }\n\n // Parse newline-delimited JSON\n return content\n .trim()\n .split(\"\\n\")\n .map((line) => JSON.parse(line) as StoredEntry);\n } catch (error) {\n throw new Error(\n `Failed to fetch task run logs: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8564,6 +8564,32 @@ async function getCurrentBranch(baseDir, options) {
|
|
|
8564
8564
|
return branch === "HEAD" ? null : branch;
|
|
8565
8565
|
}, { signal: options?.abortSignal });
|
|
8566
8566
|
}
|
|
8567
|
+
async function listWorktrees(baseDir, options) {
|
|
8568
|
+
const manager = getGitOperationManager();
|
|
8569
|
+
return manager.executeRead(baseDir, async (git) => {
|
|
8570
|
+
const output = await git.raw(["worktree", "list", "--porcelain"]);
|
|
8571
|
+
const worktrees = [];
|
|
8572
|
+
let current2 = {};
|
|
8573
|
+
for (const line of output.split("\n")) {
|
|
8574
|
+
if (line.startsWith("worktree ")) {
|
|
8575
|
+
if (current2.path) {
|
|
8576
|
+
worktrees.push(current2);
|
|
8577
|
+
}
|
|
8578
|
+
current2 = { path: line.slice(9), branch: null };
|
|
8579
|
+
} else if (line.startsWith("HEAD ")) {
|
|
8580
|
+
current2.head = line.slice(5);
|
|
8581
|
+
} else if (line.startsWith("branch ")) {
|
|
8582
|
+
current2.branch = line.slice(7).replace("refs/heads/", "");
|
|
8583
|
+
} else if (line === "detached") {
|
|
8584
|
+
current2.branch = null;
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
if (current2.path) {
|
|
8588
|
+
worktrees.push(current2);
|
|
8589
|
+
}
|
|
8590
|
+
return worktrees;
|
|
8591
|
+
}, { signal: options?.abortSignal });
|
|
8592
|
+
}
|
|
8567
8593
|
async function getHeadSha(baseDir, options) {
|
|
8568
8594
|
const manager = getGitOperationManager();
|
|
8569
8595
|
return manager.executeRead(baseDir, (git) => git.revparse(["HEAD"]), {
|
|
@@ -8577,7 +8603,7 @@ import { Hono } from "hono";
|
|
|
8577
8603
|
// package.json
|
|
8578
8604
|
var package_default = {
|
|
8579
8605
|
name: "@posthog/agent",
|
|
8580
|
-
version: "2.3.
|
|
8606
|
+
version: "2.3.353",
|
|
8581
8607
|
repository: "https://github.com/PostHog/code",
|
|
8582
8608
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8583
8609
|
exports: {
|
|
@@ -12621,7 +12647,7 @@ var createPostToolUseHook = ({ onModeChange, logger }) => async (input, toolUseI
|
|
|
12621
12647
|
var SUBAGENT_REWRITES = {
|
|
12622
12648
|
Explore: "ph-explore"
|
|
12623
12649
|
};
|
|
12624
|
-
var createSubagentRewriteHook = (logger) => async (input, _toolUseID) => {
|
|
12650
|
+
var createSubagentRewriteHook = (logger, registeredAgents) => async (input, _toolUseID) => {
|
|
12625
12651
|
if (input.hook_event_name !== "PreToolUse") {
|
|
12626
12652
|
return { continue: true };
|
|
12627
12653
|
}
|
|
@@ -12634,6 +12660,12 @@ var createSubagentRewriteHook = (logger) => async (input, _toolUseID) => {
|
|
|
12634
12660
|
return { continue: true };
|
|
12635
12661
|
}
|
|
12636
12662
|
const target = SUBAGENT_REWRITES[subagentType];
|
|
12663
|
+
if (!registeredAgents.has(target)) {
|
|
12664
|
+
logger.warn(
|
|
12665
|
+
`[SubagentRewriteHook] Skipping rewrite ${subagentType} \u2192 ${target}: target agent not registered for this session. Falling back to built-in ${subagentType}.`
|
|
12666
|
+
);
|
|
12667
|
+
return { continue: true };
|
|
12668
|
+
}
|
|
12637
12669
|
logger.info(
|
|
12638
12670
|
`[SubagentRewriteHook] Rewriting subagent_type: ${subagentType} \u2192 ${target}`
|
|
12639
12671
|
);
|
|
@@ -14106,16 +14138,16 @@ function permissionOptions(allowAlwaysLabel) {
|
|
|
14106
14138
|
}
|
|
14107
14139
|
];
|
|
14108
14140
|
}
|
|
14109
|
-
function buildPermissionOptions(toolName, toolInput,
|
|
14141
|
+
function buildPermissionOptions(toolName, toolInput, repoRoot, suggestions) {
|
|
14110
14142
|
if (BASH_TOOLS.has(toolName)) {
|
|
14111
14143
|
const rawRuleContent = suggestions?.flatMap((s) => "rules" in s ? s.rules : []).find((r) => r.toolName === "Bash" && r.ruleContent)?.ruleContent;
|
|
14112
14144
|
const ruleContent = rawRuleContent?.replace(/:?\*$/, "");
|
|
14113
14145
|
const command = toolInput?.command;
|
|
14114
14146
|
const cmdName = command?.split(/\s+/)[0] ?? "this command";
|
|
14115
|
-
const
|
|
14147
|
+
const scopeLabel = repoRoot ? ` in ${repoRoot}` : "";
|
|
14116
14148
|
const label = ruleContent ?? `\`${cmdName}\` commands`;
|
|
14117
14149
|
return permissionOptions(
|
|
14118
|
-
`Yes, and don't ask again for ${label}${
|
|
14150
|
+
`Yes, and don't ask again for ${label}${scopeLabel}`
|
|
14119
14151
|
);
|
|
14120
14152
|
}
|
|
14121
14153
|
if (toolName === "BashOutput") {
|
|
@@ -14401,7 +14433,7 @@ async function handleDefaultPermissionFlow(context) {
|
|
|
14401
14433
|
const options = buildPermissionOptions(
|
|
14402
14434
|
toolName,
|
|
14403
14435
|
toolInput,
|
|
14404
|
-
session
|
|
14436
|
+
session.settingsManager.getRepoRoot(),
|
|
14405
14437
|
suggestions
|
|
14406
14438
|
);
|
|
14407
14439
|
const response = await client.requestPermission({
|
|
@@ -14421,17 +14453,19 @@ async function handleDefaultPermissionFlow(context) {
|
|
|
14421
14453
|
}
|
|
14422
14454
|
if (response.outcome?.outcome === "selected" && (response.outcome.optionId === "allow" || response.outcome.optionId === "allow_always")) {
|
|
14423
14455
|
if (response.outcome.optionId === "allow_always") {
|
|
14456
|
+
const rules = extractAllowRules(suggestions, toolName);
|
|
14457
|
+
try {
|
|
14458
|
+
await session.settingsManager.addAllowRules(rules);
|
|
14459
|
+
} catch (error) {
|
|
14460
|
+
context.logger.warn(
|
|
14461
|
+
"[canUseTool] Failed to persist allow rules to repository settings",
|
|
14462
|
+
{ error: error instanceof Error ? error.message : String(error) }
|
|
14463
|
+
);
|
|
14464
|
+
}
|
|
14424
14465
|
return {
|
|
14425
14466
|
behavior: "allow",
|
|
14426
14467
|
updatedInput: toolInput,
|
|
14427
|
-
updatedPermissions: suggestions
|
|
14428
|
-
{
|
|
14429
|
-
type: "addRules",
|
|
14430
|
-
rules: [{ toolName }],
|
|
14431
|
-
behavior: "allow",
|
|
14432
|
-
destination: "localSettings"
|
|
14433
|
-
}
|
|
14434
|
-
]
|
|
14468
|
+
updatedPermissions: buildSessionPermissions(suggestions, rules)
|
|
14435
14469
|
};
|
|
14436
14470
|
}
|
|
14437
14471
|
return {
|
|
@@ -14464,6 +14498,26 @@ function handlePlanFileException(context) {
|
|
|
14464
14498
|
updatedInput: toolInput
|
|
14465
14499
|
};
|
|
14466
14500
|
}
|
|
14501
|
+
function extractAllowRules(suggestions, toolName) {
|
|
14502
|
+
if (!suggestions || suggestions.length === 0) {
|
|
14503
|
+
return [{ toolName }];
|
|
14504
|
+
}
|
|
14505
|
+
return suggestions.filter(
|
|
14506
|
+
(update) => update.type === "addRules" && update.behavior === "allow"
|
|
14507
|
+
).flatMap((update) => "rules" in update ? update.rules : []);
|
|
14508
|
+
}
|
|
14509
|
+
function buildSessionPermissions(suggestions, rules) {
|
|
14510
|
+
const passthrough = (suggestions ?? []).filter(
|
|
14511
|
+
(update) => !(update.type === "addRules" && update.behavior === "allow")
|
|
14512
|
+
).map((update) => ({ ...update, destination: "session" }));
|
|
14513
|
+
if (rules.length === 0) {
|
|
14514
|
+
return passthrough;
|
|
14515
|
+
}
|
|
14516
|
+
return [
|
|
14517
|
+
{ type: "addRules", rules, behavior: "allow", destination: "session" },
|
|
14518
|
+
...passthrough
|
|
14519
|
+
];
|
|
14520
|
+
}
|
|
14467
14521
|
function extractDomainFromUrl(url) {
|
|
14468
14522
|
try {
|
|
14469
14523
|
return new URL(url).hostname;
|
|
@@ -14747,7 +14801,7 @@ function buildEnvironment() {
|
|
|
14747
14801
|
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1"
|
|
14748
14802
|
};
|
|
14749
14803
|
}
|
|
14750
|
-
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache) {
|
|
14804
|
+
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents) {
|
|
14751
14805
|
const postToolUseHooks = [createPostToolUseHook({ onModeChange, logger })];
|
|
14752
14806
|
if (enrichmentDeps && enrichedReadCache) {
|
|
14753
14807
|
postToolUseHooks.push(
|
|
@@ -14765,12 +14819,49 @@ function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichment
|
|
|
14765
14819
|
{
|
|
14766
14820
|
hooks: [
|
|
14767
14821
|
createPreToolUseHook(settingsManager, logger),
|
|
14768
|
-
createSubagentRewriteHook(logger)
|
|
14822
|
+
createSubagentRewriteHook(logger, registeredAgents)
|
|
14769
14823
|
]
|
|
14770
14824
|
}
|
|
14771
14825
|
]
|
|
14772
14826
|
};
|
|
14773
14827
|
}
|
|
14828
|
+
var PH_EXPLORE_AGENT = {
|
|
14829
|
+
description: 'Fast agent for exploring and understanding codebases. Use this when you need to find files by pattern (eg. "src/components/**/*.tsx"), search for code or keywords (eg. "where is the auth middleware?"), or answer questions about how the codebase works (eg. "how does the session service handle reconnects?"). When calling this agent, specify a thoroughness level: "quick" for targeted lookups, "medium" for broader exploration, or "very thorough" for comprehensive analysis across multiple locations.',
|
|
14830
|
+
model: "haiku",
|
|
14831
|
+
prompt: `You are a fast, read-only codebase exploration agent.
|
|
14832
|
+
|
|
14833
|
+
Your job is to find files, search code, read the most relevant sources, and report findings clearly.
|
|
14834
|
+
|
|
14835
|
+
Rules:
|
|
14836
|
+
- Never create, modify, delete, move, or copy files.
|
|
14837
|
+
- Never use shell redirection or any command that changes system state.
|
|
14838
|
+
- Use Glob for broad file pattern matching.
|
|
14839
|
+
- Use Grep for searching file contents.
|
|
14840
|
+
- Use Read when you know the exact file path to inspect.
|
|
14841
|
+
- Use Bash only for safe read-only commands like ls, git status, git log, git diff, find, cat, head, and tail.
|
|
14842
|
+
- Adapt your search approach based on the thoroughness level specified by the caller.
|
|
14843
|
+
- Return file paths as absolute paths in your final response.
|
|
14844
|
+
- Avoid using emojis.
|
|
14845
|
+
- Wherever possible, spawn multiple parallel tool calls for grepping and reading files.
|
|
14846
|
+
- Search efficiently, then read only the most relevant files.
|
|
14847
|
+
- Return findings directly in your final response \u2014 do not create files.`,
|
|
14848
|
+
tools: [
|
|
14849
|
+
"Bash",
|
|
14850
|
+
"Glob",
|
|
14851
|
+
"Grep",
|
|
14852
|
+
"Read",
|
|
14853
|
+
"WebFetch",
|
|
14854
|
+
"WebSearch",
|
|
14855
|
+
"NotebookRead",
|
|
14856
|
+
"TodoWrite"
|
|
14857
|
+
]
|
|
14858
|
+
};
|
|
14859
|
+
function buildAgents(userAgents) {
|
|
14860
|
+
return {
|
|
14861
|
+
"ph-explore": PH_EXPLORE_AGENT,
|
|
14862
|
+
...userAgents || {}
|
|
14863
|
+
};
|
|
14864
|
+
}
|
|
14774
14865
|
function getAbortController(userProvidedController) {
|
|
14775
14866
|
const controller = userProvidedController ?? new AbortController();
|
|
14776
14867
|
if (controller.signal.aborted) {
|
|
@@ -14856,6 +14947,8 @@ function ensureLocalSettings(cwd) {
|
|
|
14856
14947
|
function buildSessionOptions(params) {
|
|
14857
14948
|
ensureLocalSettings(params.cwd);
|
|
14858
14949
|
const tools = params.userProvidedOptions?.tools ?? (params.disableBuiltInTools ? [] : { type: "preset", preset: "claude_code" });
|
|
14950
|
+
const agents = buildAgents(params.userProvidedOptions?.agents);
|
|
14951
|
+
const registeredAgentNames = new Set(Object.keys(agents));
|
|
14859
14952
|
const options = {
|
|
14860
14953
|
...params.userProvidedOptions,
|
|
14861
14954
|
betas: ["context-1m-2025-08-07"],
|
|
@@ -14869,6 +14962,7 @@ function buildSessionOptions(params) {
|
|
|
14869
14962
|
canUseTool: params.canUseTool,
|
|
14870
14963
|
executable: "node",
|
|
14871
14964
|
tools,
|
|
14965
|
+
agents,
|
|
14872
14966
|
extraArgs: {
|
|
14873
14967
|
...params.userProvidedOptions?.extraArgs,
|
|
14874
14968
|
"replay-user-messages": ""
|
|
@@ -14884,7 +14978,8 @@ function buildSessionOptions(params) {
|
|
|
14884
14978
|
params.settingsManager,
|
|
14885
14979
|
params.logger,
|
|
14886
14980
|
params.enrichmentDeps,
|
|
14887
|
-
params.enrichedReadCache
|
|
14981
|
+
params.enrichedReadCache,
|
|
14982
|
+
registeredAgentNames
|
|
14888
14983
|
),
|
|
14889
14984
|
outputFormat: params.outputFormat,
|
|
14890
14985
|
abortController: getAbortController(
|
|
@@ -14932,6 +15027,47 @@ import * as fs7 from "fs";
|
|
|
14932
15027
|
import * as os3 from "os";
|
|
14933
15028
|
import * as path9 from "path";
|
|
14934
15029
|
import { minimatch } from "minimatch";
|
|
15030
|
+
|
|
15031
|
+
// src/utils/async-mutex.ts
|
|
15032
|
+
var AsyncMutex = class {
|
|
15033
|
+
locked = false;
|
|
15034
|
+
queue = [];
|
|
15035
|
+
async acquire() {
|
|
15036
|
+
if (!this.locked) {
|
|
15037
|
+
this.locked = true;
|
|
15038
|
+
return;
|
|
15039
|
+
}
|
|
15040
|
+
return new Promise((resolve4) => {
|
|
15041
|
+
this.queue.push(resolve4);
|
|
15042
|
+
});
|
|
15043
|
+
}
|
|
15044
|
+
release() {
|
|
15045
|
+
const next = this.queue.shift();
|
|
15046
|
+
if (next) {
|
|
15047
|
+
next();
|
|
15048
|
+
} else {
|
|
15049
|
+
this.locked = false;
|
|
15050
|
+
}
|
|
15051
|
+
}
|
|
15052
|
+
isLocked() {
|
|
15053
|
+
return this.locked;
|
|
15054
|
+
}
|
|
15055
|
+
get queueLength() {
|
|
15056
|
+
return this.queue.length;
|
|
15057
|
+
}
|
|
15058
|
+
};
|
|
15059
|
+
|
|
15060
|
+
// src/adapters/claude/session/repo-path.ts
|
|
15061
|
+
async function resolveMainRepoPath(cwd) {
|
|
15062
|
+
try {
|
|
15063
|
+
const worktrees = await listWorktrees(cwd);
|
|
15064
|
+
return worktrees[0]?.path ?? cwd;
|
|
15065
|
+
} catch {
|
|
15066
|
+
return cwd;
|
|
15067
|
+
}
|
|
15068
|
+
}
|
|
15069
|
+
|
|
15070
|
+
// src/adapters/claude/session/settings.ts
|
|
14935
15071
|
var ACP_TOOL_NAME_PREFIX = "mcp__acp__";
|
|
14936
15072
|
var acpToolNames = {
|
|
14937
15073
|
read: `${ACP_TOOL_NAME_PREFIX}Read`,
|
|
@@ -14988,7 +15124,7 @@ function matchesGlob(pattern, filePath, cwd) {
|
|
|
14988
15124
|
});
|
|
14989
15125
|
}
|
|
14990
15126
|
function matchesRule(rule, toolName, toolInput, cwd) {
|
|
14991
|
-
const ruleAppliesToTool = rule.toolName === "Bash" && toolName === acpToolNames.bash || rule.toolName === "Edit" && FILE_EDITING_TOOLS.includes(toolName) || rule.toolName === "Read" && FILE_READING_TOOLS.includes(toolName);
|
|
15127
|
+
const ruleAppliesToTool = rule.toolName === "Bash" && toolName === acpToolNames.bash || rule.toolName === "Edit" && FILE_EDITING_TOOLS.includes(toolName) || rule.toolName === "Read" && FILE_READING_TOOLS.includes(toolName) || rule.toolName === toolName && !rule.argument;
|
|
14992
15128
|
if (!ruleAppliesToTool) {
|
|
14993
15129
|
return false;
|
|
14994
15130
|
}
|
|
@@ -15018,6 +15154,19 @@ function matchesRule(rule, toolName, toolInput, cwd) {
|
|
|
15018
15154
|
}
|
|
15019
15155
|
return matchesGlob(rule.argument, actualArg, cwd);
|
|
15020
15156
|
}
|
|
15157
|
+
function formatRule(rule) {
|
|
15158
|
+
return rule.ruleContent ? `${rule.toolName}(${rule.ruleContent})` : rule.toolName;
|
|
15159
|
+
}
|
|
15160
|
+
async function writeFileAtomic(filePath, data) {
|
|
15161
|
+
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
15162
|
+
await fs7.promises.writeFile(tmpPath, data);
|
|
15163
|
+
try {
|
|
15164
|
+
await fs7.promises.rename(tmpPath, filePath);
|
|
15165
|
+
} catch (error) {
|
|
15166
|
+
await fs7.promises.rm(tmpPath, { force: true });
|
|
15167
|
+
throw error;
|
|
15168
|
+
}
|
|
15169
|
+
}
|
|
15021
15170
|
async function loadSettingsFile(filePath) {
|
|
15022
15171
|
if (!filePath) {
|
|
15023
15172
|
return {};
|
|
@@ -15036,6 +15185,17 @@ async function loadSettingsFile(filePath) {
|
|
|
15036
15185
|
return {};
|
|
15037
15186
|
}
|
|
15038
15187
|
}
|
|
15188
|
+
async function readSettingsFileForUpdate(filePath) {
|
|
15189
|
+
try {
|
|
15190
|
+
const content = await fs7.promises.readFile(filePath, "utf-8");
|
|
15191
|
+
return JSON.parse(content);
|
|
15192
|
+
} catch (error) {
|
|
15193
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
15194
|
+
return {};
|
|
15195
|
+
}
|
|
15196
|
+
throw error;
|
|
15197
|
+
}
|
|
15198
|
+
}
|
|
15039
15199
|
function getManagedSettingsPath() {
|
|
15040
15200
|
switch (process.platform) {
|
|
15041
15201
|
case "darwin":
|
|
@@ -15050,6 +15210,7 @@ function getManagedSettingsPath() {
|
|
|
15050
15210
|
}
|
|
15051
15211
|
var SettingsManager = class {
|
|
15052
15212
|
cwd;
|
|
15213
|
+
repoRoot;
|
|
15053
15214
|
userSettings = {};
|
|
15054
15215
|
projectSettings = {};
|
|
15055
15216
|
localSettings = {};
|
|
@@ -15057,8 +15218,10 @@ var SettingsManager = class {
|
|
|
15057
15218
|
mergedSettings = {};
|
|
15058
15219
|
initialized = false;
|
|
15059
15220
|
initPromise = null;
|
|
15221
|
+
writeMutex = new AsyncMutex();
|
|
15060
15222
|
constructor(cwd) {
|
|
15061
15223
|
this.cwd = cwd;
|
|
15224
|
+
this.repoRoot = cwd;
|
|
15062
15225
|
}
|
|
15063
15226
|
async initialize() {
|
|
15064
15227
|
if (this.initialized) return;
|
|
@@ -15076,10 +15239,16 @@ var SettingsManager = class {
|
|
|
15076
15239
|
getProjectSettingsPath() {
|
|
15077
15240
|
return path9.join(this.cwd, ".claude", "settings.json");
|
|
15078
15241
|
}
|
|
15242
|
+
/**
|
|
15243
|
+
* Local settings are anchored to the primary worktree so every worktree of
|
|
15244
|
+
* the same repository shares a single `.claude/settings.local.json`. This
|
|
15245
|
+
* avoids re-prompting for the same permission in every worktree.
|
|
15246
|
+
*/
|
|
15079
15247
|
getLocalSettingsPath() {
|
|
15080
|
-
return path9.join(this.
|
|
15248
|
+
return path9.join(this.repoRoot, ".claude", "settings.local.json");
|
|
15081
15249
|
}
|
|
15082
15250
|
async loadAllSettings() {
|
|
15251
|
+
this.repoRoot = await resolveMainRepoPath(this.cwd);
|
|
15083
15252
|
const [userSettings, projectSettings, localSettings, enterpriseSettings] = await Promise.all([
|
|
15084
15253
|
loadSettingsFile(this.getUserSettingsPath()),
|
|
15085
15254
|
loadSettingsFile(this.getProjectSettingsPath()),
|
|
@@ -15136,9 +15305,6 @@ var SettingsManager = class {
|
|
|
15136
15305
|
this.mergedSettings = merged;
|
|
15137
15306
|
}
|
|
15138
15307
|
checkPermission(toolName, toolInput) {
|
|
15139
|
-
if (!toolName.startsWith(ACP_TOOL_NAME_PREFIX)) {
|
|
15140
|
-
return { decision: "ask" };
|
|
15141
|
-
}
|
|
15142
15308
|
const permissions = this.mergedSettings.permissions;
|
|
15143
15309
|
if (!permissions) {
|
|
15144
15310
|
return { decision: "ask" };
|
|
@@ -15169,6 +15335,43 @@ var SettingsManager = class {
|
|
|
15169
15335
|
getCwd() {
|
|
15170
15336
|
return this.cwd;
|
|
15171
15337
|
}
|
|
15338
|
+
getRepoRoot() {
|
|
15339
|
+
return this.repoRoot;
|
|
15340
|
+
}
|
|
15341
|
+
/**
|
|
15342
|
+
* Persists allow rules to `<primary-worktree>/.claude/settings.local.json`.
|
|
15343
|
+
* Because local settings are resolved against the primary worktree, every
|
|
15344
|
+
* worktree of the same repository picks up the new rule on next load.
|
|
15345
|
+
*
|
|
15346
|
+
* Writes are serialised via `writeMutex` to prevent concurrent callers from
|
|
15347
|
+
* clobbering each other, and use a temp-file + rename to keep the file
|
|
15348
|
+
* consistent if the process dies mid-write.
|
|
15349
|
+
*/
|
|
15350
|
+
async addAllowRules(rules) {
|
|
15351
|
+
if (rules.length === 0) return;
|
|
15352
|
+
if (!this.initialized) await this.initialize();
|
|
15353
|
+
await this.writeMutex.acquire();
|
|
15354
|
+
try {
|
|
15355
|
+
const filePath = this.getLocalSettingsPath();
|
|
15356
|
+
const existing = await readSettingsFileForUpdate(filePath);
|
|
15357
|
+
const permissions = {
|
|
15358
|
+
...existing.permissions ?? {}
|
|
15359
|
+
};
|
|
15360
|
+
const current2 = new Set(permissions.allow ?? []);
|
|
15361
|
+
for (const rule of rules) {
|
|
15362
|
+
current2.add(formatRule(rule));
|
|
15363
|
+
}
|
|
15364
|
+
permissions.allow = Array.from(current2);
|
|
15365
|
+
const next = { ...existing, permissions };
|
|
15366
|
+
await fs7.promises.mkdir(path9.dirname(filePath), { recursive: true });
|
|
15367
|
+
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
15368
|
+
`);
|
|
15369
|
+
this.localSettings = next;
|
|
15370
|
+
this.mergeAllSettings();
|
|
15371
|
+
} finally {
|
|
15372
|
+
this.writeMutex.release();
|
|
15373
|
+
}
|
|
15374
|
+
}
|
|
15172
15375
|
async setCwd(cwd) {
|
|
15173
15376
|
if (this.cwd === cwd) return;
|
|
15174
15377
|
if (this.initPromise) await this.initPromise;
|
|
@@ -16524,7 +16727,7 @@ function parseCodexToml(content, cwd) {
|
|
|
16524
16727
|
// src/adapters/codex/spawn.ts
|
|
16525
16728
|
import { spawn as spawn3 } from "child_process";
|
|
16526
16729
|
import { existsSync as existsSync4 } from "fs";
|
|
16527
|
-
import { delimiter, dirname as
|
|
16730
|
+
import { delimiter, dirname as dirname4 } from "path";
|
|
16528
16731
|
function buildConfigArgs(options) {
|
|
16529
16732
|
const args2 = [];
|
|
16530
16733
|
args2.push("-c", `features.remote_models=false`);
|
|
@@ -16575,7 +16778,7 @@ function spawnCodexProcess(options) {
|
|
|
16575
16778
|
}
|
|
16576
16779
|
const { command, args: args2 } = findCodexBinary(options);
|
|
16577
16780
|
if (options.binaryPath && existsSync4(options.binaryPath)) {
|
|
16578
|
-
const binDir =
|
|
16781
|
+
const binDir = dirname4(options.binaryPath);
|
|
16579
16782
|
env.PATH = `${binDir}${delimiter}${env.PATH ?? ""}`;
|
|
16580
16783
|
}
|
|
16581
16784
|
logger.info("Spawning codex-acp process", {
|
|
@@ -18758,35 +18961,6 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
18758
18961
|
}
|
|
18759
18962
|
};
|
|
18760
18963
|
|
|
18761
|
-
// src/utils/async-mutex.ts
|
|
18762
|
-
var AsyncMutex = class {
|
|
18763
|
-
locked = false;
|
|
18764
|
-
queue = [];
|
|
18765
|
-
async acquire() {
|
|
18766
|
-
if (!this.locked) {
|
|
18767
|
-
this.locked = true;
|
|
18768
|
-
return;
|
|
18769
|
-
}
|
|
18770
|
-
return new Promise((resolve4) => {
|
|
18771
|
-
this.queue.push(resolve4);
|
|
18772
|
-
});
|
|
18773
|
-
}
|
|
18774
|
-
release() {
|
|
18775
|
-
const next = this.queue.shift();
|
|
18776
|
-
if (next) {
|
|
18777
|
-
next();
|
|
18778
|
-
} else {
|
|
18779
|
-
this.locked = false;
|
|
18780
|
-
}
|
|
18781
|
-
}
|
|
18782
|
-
isLocked() {
|
|
18783
|
-
return this.locked;
|
|
18784
|
-
}
|
|
18785
|
-
get queueLength() {
|
|
18786
|
-
return this.queue.length;
|
|
18787
|
-
}
|
|
18788
|
-
};
|
|
18789
|
-
|
|
18790
18964
|
// src/server/cloud-prompt.ts
|
|
18791
18965
|
function normalizeCloudPromptContent(content) {
|
|
18792
18966
|
if (typeof content === "string") {
|