@posthog/agent 1.30.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +221 -219
  3. package/dist/adapters/claude/conversion/tool-use-to-acp.d.ts +21 -0
  4. package/dist/adapters/claude/conversion/tool-use-to-acp.js +547 -0
  5. package/dist/adapters/claude/conversion/tool-use-to-acp.js.map +1 -0
  6. package/dist/adapters/claude/permissions/permission-options.d.ts +13 -0
  7. package/dist/adapters/claude/permissions/permission-options.js +117 -0
  8. package/dist/adapters/claude/permissions/permission-options.js.map +1 -0
  9. package/dist/adapters/claude/questions/utils.d.ts +132 -0
  10. package/dist/adapters/claude/questions/utils.js +63 -0
  11. package/dist/adapters/claude/questions/utils.js.map +1 -0
  12. package/dist/adapters/claude/tools.d.ts +18 -0
  13. package/dist/adapters/claude/tools.js +95 -0
  14. package/dist/adapters/claude/tools.js.map +1 -0
  15. package/dist/agent-DBQY1BfC.d.ts +123 -0
  16. package/dist/agent.d.ts +5 -0
  17. package/dist/agent.js +3656 -0
  18. package/dist/agent.js.map +1 -0
  19. package/dist/claude-cli/cli.js +3695 -2746
  20. package/dist/claude-cli/vendor/ripgrep/COPYING +3 -0
  21. package/dist/claude-cli/vendor/ripgrep/arm64-darwin/rg +0 -0
  22. package/dist/claude-cli/vendor/ripgrep/arm64-darwin/ripgrep.node +0 -0
  23. package/dist/claude-cli/vendor/ripgrep/arm64-linux/rg +0 -0
  24. package/dist/claude-cli/vendor/ripgrep/arm64-linux/ripgrep.node +0 -0
  25. package/dist/claude-cli/vendor/ripgrep/x64-darwin/rg +0 -0
  26. package/dist/claude-cli/vendor/ripgrep/x64-darwin/ripgrep.node +0 -0
  27. package/dist/claude-cli/vendor/ripgrep/x64-linux/rg +0 -0
  28. package/dist/claude-cli/vendor/ripgrep/x64-linux/ripgrep.node +0 -0
  29. package/dist/claude-cli/vendor/ripgrep/x64-win32/rg.exe +0 -0
  30. package/dist/claude-cli/vendor/ripgrep/x64-win32/ripgrep.node +0 -0
  31. package/dist/gateway-models.d.ts +24 -0
  32. package/dist/gateway-models.js +93 -0
  33. package/dist/gateway-models.js.map +1 -0
  34. package/dist/index.d.ts +172 -1203
  35. package/dist/index.js +3704 -6826
  36. package/dist/index.js.map +1 -1
  37. package/dist/logger-DDBiMOOD.d.ts +24 -0
  38. package/dist/posthog-api.d.ts +40 -0
  39. package/dist/posthog-api.js +175 -0
  40. package/dist/posthog-api.js.map +1 -0
  41. package/dist/server/agent-server.d.ts +41 -0
  42. package/dist/server/agent-server.js +4451 -0
  43. package/dist/server/agent-server.js.map +1 -0
  44. package/dist/server/bin.d.ts +1 -0
  45. package/dist/server/bin.js +4507 -0
  46. package/dist/server/bin.js.map +1 -0
  47. package/dist/types.d.ts +129 -0
  48. package/dist/types.js +1 -0
  49. package/dist/types.js.map +1 -0
  50. package/package.json +66 -14
  51. package/src/acp-extensions.ts +93 -61
  52. package/src/adapters/acp-connection.ts +494 -0
  53. package/src/adapters/base-acp-agent.ts +150 -0
  54. package/src/adapters/claude/claude-agent.ts +596 -0
  55. package/src/adapters/claude/conversion/acp-to-sdk.ts +102 -0
  56. package/src/adapters/claude/conversion/sdk-to-acp.ts +571 -0
  57. package/src/adapters/claude/conversion/tool-use-to-acp.ts +618 -0
  58. package/src/adapters/claude/hooks.ts +64 -0
  59. package/src/adapters/claude/mcp/tool-metadata.ts +102 -0
  60. package/src/adapters/claude/permissions/permission-handlers.ts +433 -0
  61. package/src/adapters/claude/permissions/permission-options.ts +103 -0
  62. package/src/adapters/claude/plan/utils.ts +56 -0
  63. package/src/adapters/claude/questions/utils.ts +92 -0
  64. package/src/adapters/claude/session/commands.ts +38 -0
  65. package/src/adapters/claude/session/mcp-config.ts +37 -0
  66. package/src/adapters/claude/session/models.ts +12 -0
  67. package/src/adapters/claude/session/options.ts +236 -0
  68. package/src/adapters/claude/tool-meta.ts +143 -0
  69. package/src/adapters/claude/tools.ts +53 -611
  70. package/src/adapters/claude/types.ts +61 -0
  71. package/src/adapters/codex/spawn.ts +130 -0
  72. package/src/agent.ts +97 -734
  73. package/src/execution-mode.ts +43 -0
  74. package/src/gateway-models.ts +135 -0
  75. package/src/index.ts +79 -0
  76. package/src/otel-log-writer.test.ts +105 -0
  77. package/src/otel-log-writer.ts +94 -0
  78. package/src/posthog-api.ts +75 -235
  79. package/src/resume.ts +115 -0
  80. package/src/sagas/apply-snapshot-saga.test.ts +690 -0
  81. package/src/sagas/apply-snapshot-saga.ts +88 -0
  82. package/src/sagas/capture-tree-saga.test.ts +892 -0
  83. package/src/sagas/capture-tree-saga.ts +141 -0
  84. package/src/sagas/resume-saga.test.ts +558 -0
  85. package/src/sagas/resume-saga.ts +332 -0
  86. package/src/sagas/test-fixtures.ts +250 -0
  87. package/src/server/agent-server.test.ts +220 -0
  88. package/src/server/agent-server.ts +748 -0
  89. package/src/server/bin.ts +88 -0
  90. package/src/server/jwt.ts +65 -0
  91. package/src/server/schemas.ts +47 -0
  92. package/src/server/types.ts +13 -0
  93. package/src/server/utils/retry.test.ts +122 -0
  94. package/src/server/utils/retry.ts +61 -0
  95. package/src/server/utils/sse-parser.test.ts +93 -0
  96. package/src/server/utils/sse-parser.ts +46 -0
  97. package/src/session-log-writer.test.ts +140 -0
  98. package/src/session-log-writer.ts +137 -0
  99. package/src/test/assertions.ts +114 -0
  100. package/src/test/controllers/sse-controller.ts +107 -0
  101. package/src/test/fixtures/api.ts +111 -0
  102. package/src/test/fixtures/config.ts +33 -0
  103. package/src/test/fixtures/notifications.ts +92 -0
  104. package/src/test/mocks/claude-sdk.ts +251 -0
  105. package/src/test/mocks/msw-handlers.ts +48 -0
  106. package/src/test/setup.ts +114 -0
  107. package/src/test/wait.ts +41 -0
  108. package/src/tree-tracker.ts +173 -0
  109. package/src/types.ts +51 -154
  110. package/src/utils/acp-content.ts +58 -0
  111. package/src/utils/async-mutex.test.ts +104 -0
  112. package/src/utils/async-mutex.ts +31 -0
  113. package/src/utils/common.ts +15 -0
  114. package/src/utils/gateway.ts +9 -6
  115. package/src/utils/logger.ts +0 -30
  116. package/src/utils/streams.ts +220 -0
  117. package/CLAUDE.md +0 -331
  118. package/dist/templates/plan-template.md +0 -41
  119. package/src/adapters/claude/claude.ts +0 -1543
  120. package/src/adapters/claude/mcp-server.ts +0 -810
  121. package/src/adapters/claude/utils.ts +0 -267
  122. package/src/agents/execution.ts +0 -37
  123. package/src/agents/planning.ts +0 -60
  124. package/src/agents/research.ts +0 -160
  125. package/src/file-manager.ts +0 -306
  126. package/src/git-manager.ts +0 -577
  127. package/src/prompt-builder.ts +0 -499
  128. package/src/schemas.ts +0 -241
  129. package/src/session-store.ts +0 -259
  130. package/src/task-manager.ts +0 -163
  131. package/src/template-manager.ts +0 -236
  132. package/src/templates/plan-template.md +0 -41
  133. package/src/todo-manager.ts +0 -180
  134. package/src/tools/registry.ts +0 -129
  135. package/src/tools/types.ts +0 -127
  136. package/src/utils/tapped-stream.ts +0 -60
  137. package/src/workflow/config.ts +0 -53
  138. package/src/workflow/steps/build.ts +0 -135
  139. package/src/workflow/steps/finalize.ts +0 -241
  140. package/src/workflow/steps/plan.ts +0 -167
  141. package/src/workflow/steps/research.ts +0 -223
  142. package/src/workflow/types.ts +0 -62
  143. package/src/workflow/utils.ts +0 -53
  144. package/src/worktree-manager.ts +0 -928
package/src/types.ts CHANGED
@@ -1,12 +1,3 @@
1
- // import and export to keep a single type file
2
-
3
- import type { SessionNotification } from "@agentclientprotocol/sdk";
4
- import type {
5
- CanUseTool,
6
- PermissionResult,
7
- } from "@anthropic-ai/claude-agent-sdk";
8
- export type { CanUseTool, PermissionResult, SessionNotification };
9
-
10
1
  /**
11
2
  * Stored custom notification following ACP extensibility model.
12
3
  * Custom notifications use underscore-prefixed methods (e.g., `_posthog/phase_start`).
@@ -29,7 +20,7 @@ export interface StoredNotification {
29
20
  */
30
21
  export type StoredEntry = StoredNotification;
31
22
 
32
- // PostHog Task model (matches Array's OpenAPI schema)
23
+ // PostHog Task model (matches Twig's OpenAPI schema)
33
24
  export interface Task {
34
25
  id: string;
35
26
  task_number?: number;
@@ -64,7 +55,8 @@ export type ArtifactType =
64
55
  | "context"
65
56
  | "reference"
66
57
  | "output"
67
- | "artifact";
58
+ | "artifact"
59
+ | "tree_snapshot";
68
60
 
69
61
  export interface TaskRunArtifact {
70
62
  name: string;
@@ -104,85 +96,23 @@ export interface TaskRun {
104
96
  completed_at: string | null;
105
97
  }
106
98
 
107
- export interface SupportingFile {
108
- name: string;
109
- content: string;
110
- type: ArtifactType;
111
- created_at: string;
112
- }
113
-
114
- export interface TaskArtifactUploadPayload {
115
- name: string;
116
- type: ArtifactType;
117
- content: string;
118
- content_type?: string;
119
- }
120
-
121
- export enum PermissionMode {
122
- PLAN = "plan",
123
- DEFAULT = "default",
124
- ACCEPT_EDITS = "acceptEdits",
125
- BYPASS = "bypassPermissions",
126
- }
127
-
128
- export interface ExecutionOptions {
129
- repositoryPath?: string;
130
- permissionMode?: PermissionMode;
99
+ export interface ProcessSpawnedCallback {
100
+ onProcessSpawned?: (info: {
101
+ pid: number;
102
+ command: string;
103
+ sessionId?: string;
104
+ }) => void;
105
+ onProcessExited?: (pid: number) => void;
131
106
  }
132
107
 
133
108
  export interface TaskExecutionOptions {
134
109
  repositoryPath?: string;
135
- permissionMode?: PermissionMode;
136
- isCloudMode?: boolean; // Determines local vs cloud behavior (local pauses after each phase)
137
- createPR?: boolean; // Whether to create PR after build (defaults to false)
138
- autoProgress?: boolean;
139
- queryOverrides?: Record<string, unknown>;
140
- // Fine-grained permission control (only applied to build phase)
141
- // See: https://docs.claude.com/en/api/agent-sdk/permissions
142
- canUseTool?: CanUseTool;
143
- skipGitBranch?: boolean; // Skip creating a task-specific git branch
144
- }
145
-
146
- export interface ExecutionResult {
147
- // biome-ignore lint/suspicious/noExplicitAny: Results array contains varying SDK response types
148
- results: any[];
149
- }
150
-
151
- export interface PlanResult {
152
- plan: string;
153
- }
154
-
155
- export interface TaskExecutionResult {
156
- task: Task;
157
- plan?: string;
158
- executionResult?: ExecutionResult;
110
+ adapter?: "claude" | "codex";
111
+ model?: string;
112
+ codexBinaryPath?: string;
113
+ processCallbacks?: ProcessSpawnedCallback;
159
114
  }
160
115
 
161
- // MCP Server configuration types (re-exported from Claude SDK for convenience)
162
- export type McpServerConfig =
163
- | {
164
- type?: "stdio";
165
- command: string;
166
- args?: string[];
167
- env?: Record<string, string>;
168
- }
169
- | {
170
- type: "sse";
171
- url: string;
172
- headers?: Record<string, string>;
173
- }
174
- | {
175
- type: "http";
176
- url: string;
177
- headers?: Record<string, string>;
178
- }
179
- | {
180
- type: "sdk";
181
- name: string;
182
- // biome-ignore lint/suspicious/noExplicitAny: McpServer instance type from external SDK
183
- instance?: any;
184
- };
185
-
186
116
  export type LogLevel = "debug" | "info" | "warn" | "error";
187
117
 
188
118
  export type OnLogCallback = (
@@ -192,90 +122,57 @@ export type OnLogCallback = (
192
122
  data?: unknown,
193
123
  ) => void;
194
124
 
195
- export interface AgentConfig {
196
- workingDirectory?: string;
197
-
198
- // PostHog API configuration (optional - enables PostHog integration when provided)
199
- posthogApiUrl?: string;
200
- getPosthogApiKey?: () => string;
201
- posthogProjectId?: number;
202
-
203
- // PostHog MCP configuration
204
- posthogMcpUrl?: string;
205
-
206
- // MCP Server configuration
207
- // Additional MCP servers (PostHog MCP is always included by default)
208
- // You can override the PostHog MCP config by providing mcpServers.posthog
209
- mcpServers?: Record<string, McpServerConfig>;
210
-
211
- // Logging configuration
212
- debug?: boolean;
213
- onLog?: OnLogCallback;
214
-
215
- // Fine-grained permission control for direct run() calls
216
- // See: https://docs.claude.com/en/api/agent-sdk/permissions
217
- canUseTool?: CanUseTool;
218
- }
219
-
220
125
  export interface PostHogAPIConfig {
221
126
  apiUrl: string;
222
127
  getApiKey: () => string;
223
128
  projectId: number;
224
129
  }
225
130
 
226
- // URL mention types
227
- export type ResourceType =
228
- | "error"
229
- | "experiment"
230
- | "insight"
231
- | "feature_flag"
232
- | "generic";
233
-
234
- export interface PostHogResource {
235
- type: ResourceType;
236
- id: string;
237
- url: string;
238
- title?: string;
239
- content: string;
240
- // biome-ignore lint/suspicious/noExplicitAny: Metadata contains varying resource-specific fields
241
- metadata?: Record<string, any>;
131
+ export interface OtelTransportConfig {
132
+ /** PostHog ingest host, e.g., "https://us.i.posthog.com" */
133
+ host: string;
134
+ /** Project API key */
135
+ apiKey: string;
136
+ /** Override the logs endpoint path (default: /i/v1/logs) */
137
+ logsPath?: string;
242
138
  }
243
139
 
244
- export interface UrlMention {
245
- url: string;
246
- type: ResourceType;
247
- id?: string;
248
- label?: string;
140
+ export interface AgentConfig {
141
+ posthog?: PostHogAPIConfig;
142
+ /** OTEL transport config for shipping logs to PostHog Logs */
143
+ otelTransport?: OtelTransportConfig;
144
+ debug?: boolean;
145
+ onLog?: OnLogCallback;
249
146
  }
250
147
 
251
- // Research evaluation types
252
- export interface ResearchQuestion {
253
- id: string;
254
- question: string;
255
- options: string[];
148
+ // Device info for tracking where work happens
149
+ export interface DeviceInfo {
150
+ type: "local" | "cloud";
151
+ name?: string;
256
152
  }
257
153
 
258
- export interface ResearchAnswer {
259
- questionId: string;
260
- selectedOption: string;
261
- customInput?: string;
154
+ // Agent execution mode - for tracking interactive vs background runs, when backgrounded an agent will continue working without asking questions
155
+ export type AgentMode = "interactive" | "background";
156
+
157
+ // Git file status codes
158
+ export type FileStatus = "A" | "M" | "D";
159
+
160
+ export interface FileChange {
161
+ path: string;
162
+ status: FileStatus;
262
163
  }
263
164
 
264
- export interface ResearchEvaluation {
265
- actionabilityScore: number; // 0-1 confidence score
266
- context: string; // brief summary for planning
267
- keyFiles: string[]; // files needing modification
268
- blockers?: string[]; // what's preventing full confidence
269
- questions?: ResearchQuestion[]; // only if score < 0.7
270
- answered?: boolean; // whether questions have been answered
271
- answers?: ResearchAnswer[]; // user's answers to questions
165
+ // Tree snapshot - what TreeTracker captures
166
+ export interface TreeSnapshot {
167
+ treeHash: string;
168
+ baseCommit: string | null;
169
+ archiveUrl?: string;
170
+ changes: FileChange[];
171
+ timestamp: string;
172
+ interrupted?: boolean;
272
173
  }
273
174
 
274
- // Worktree types for parallel task development
275
- export interface WorktreeInfo {
276
- worktreePath: string;
277
- worktreeName: string;
278
- branchName: string;
279
- baseBranch: string;
280
- createdAt: string;
175
+ // Tree snapshot event - includes device info when sent as notification
176
+ export interface TreeSnapshotEvent extends TreeSnapshot {
177
+ device?: DeviceInfo;
281
178
  }
@@ -0,0 +1,58 @@
1
+ import type { ContentBlock, ToolCallContent } from "@agentclientprotocol/sdk";
2
+
3
+ export function text(value: string): ContentBlock {
4
+ return { type: "text", text: value };
5
+ }
6
+
7
+ export function image(
8
+ data: string,
9
+ mimeType: string,
10
+ uri?: string,
11
+ ): ContentBlock {
12
+ return { type: "image", data, mimeType, uri };
13
+ }
14
+
15
+ export function resourceLink(
16
+ uri: string,
17
+ name: string,
18
+ options?: {
19
+ mimeType?: string;
20
+ title?: string;
21
+ description?: string;
22
+ size?: bigint;
23
+ },
24
+ ): ContentBlock {
25
+ return {
26
+ type: "resource_link",
27
+ uri,
28
+ name,
29
+ ...options,
30
+ };
31
+ }
32
+
33
+ class ToolContentBuilder {
34
+ private items: ToolCallContent[] = [];
35
+
36
+ text(value: string): this {
37
+ this.items.push({ type: "content", content: text(value) });
38
+ return this;
39
+ }
40
+
41
+ image(data: string, mimeType: string, uri?: string): this {
42
+ this.items.push({ type: "content", content: image(data, mimeType, uri) });
43
+ return this;
44
+ }
45
+
46
+ diff(path: string, oldText: string | null, newText: string): this {
47
+ this.items.push({ type: "diff", path, oldText, newText });
48
+ return this;
49
+ }
50
+
51
+ build(): ToolCallContent[] {
52
+ return this.items;
53
+ }
54
+ }
55
+
56
+ export function toolContent(): ToolContentBuilder {
57
+ return new ToolContentBuilder();
58
+ }
@@ -0,0 +1,104 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { AsyncMutex } from "./async-mutex.js";
3
+
4
+ describe("AsyncMutex", () => {
5
+ it("acquires lock when unlocked", async () => {
6
+ const mutex = new AsyncMutex();
7
+
8
+ expect(mutex.isLocked()).toBe(false);
9
+ await mutex.acquire();
10
+ expect(mutex.isLocked()).toBe(true);
11
+ });
12
+
13
+ it("releases lock", async () => {
14
+ const mutex = new AsyncMutex();
15
+
16
+ await mutex.acquire();
17
+ expect(mutex.isLocked()).toBe(true);
18
+
19
+ mutex.release();
20
+ expect(mutex.isLocked()).toBe(false);
21
+ });
22
+
23
+ it("queues concurrent acquires", async () => {
24
+ const mutex = new AsyncMutex();
25
+ const order: number[] = [];
26
+
27
+ await mutex.acquire();
28
+ expect(mutex.queueLength).toBe(0);
29
+
30
+ const promise1 = mutex.acquire().then(() => order.push(1));
31
+ const promise2 = mutex.acquire().then(() => order.push(2));
32
+
33
+ expect(mutex.queueLength).toBe(2);
34
+
35
+ mutex.release();
36
+ await promise1;
37
+ expect(order).toEqual([1]);
38
+
39
+ mutex.release();
40
+ await promise2;
41
+ expect(order).toEqual([1, 2]);
42
+ });
43
+
44
+ it("processes queue in FIFO order", async () => {
45
+ const mutex = new AsyncMutex();
46
+ const order: number[] = [];
47
+
48
+ await mutex.acquire();
49
+
50
+ const promises = [1, 2, 3, 4, 5].map((n) =>
51
+ mutex.acquire().then(() => {
52
+ order.push(n);
53
+ }),
54
+ );
55
+
56
+ expect(mutex.queueLength).toBe(5);
57
+
58
+ for (let i = 0; i < 5; i++) {
59
+ mutex.release();
60
+ await promises[i];
61
+ }
62
+
63
+ expect(order).toEqual([1, 2, 3, 4, 5]);
64
+ });
65
+
66
+ it("serializes concurrent operations", async () => {
67
+ const mutex = new AsyncMutex();
68
+ const results: string[] = [];
69
+
70
+ const operation = async (id: string, delay: number) => {
71
+ await mutex.acquire();
72
+ try {
73
+ results.push(`${id}-start`);
74
+ await new Promise((r) => setTimeout(r, delay));
75
+ results.push(`${id}-end`);
76
+ } finally {
77
+ mutex.release();
78
+ }
79
+ };
80
+
81
+ await Promise.all([
82
+ operation("a", 10),
83
+ operation("b", 5),
84
+ operation("c", 1),
85
+ ]);
86
+
87
+ expect(results).toEqual([
88
+ "a-start",
89
+ "a-end",
90
+ "b-start",
91
+ "b-end",
92
+ "c-start",
93
+ "c-end",
94
+ ]);
95
+ });
96
+
97
+ it("handles release without acquire gracefully", () => {
98
+ const mutex = new AsyncMutex();
99
+
100
+ expect(mutex.isLocked()).toBe(false);
101
+ mutex.release();
102
+ expect(mutex.isLocked()).toBe(false);
103
+ });
104
+ });
@@ -0,0 +1,31 @@
1
+ export class AsyncMutex {
2
+ private locked = false;
3
+ private queue: Array<() => void> = [];
4
+
5
+ async acquire(): Promise<void> {
6
+ if (!this.locked) {
7
+ this.locked = true;
8
+ return;
9
+ }
10
+ return new Promise((resolve) => {
11
+ this.queue.push(resolve);
12
+ });
13
+ }
14
+
15
+ release(): void {
16
+ const next = this.queue.shift();
17
+ if (next) {
18
+ next();
19
+ } else {
20
+ this.locked = false;
21
+ }
22
+ }
23
+
24
+ isLocked(): boolean {
25
+ return this.locked;
26
+ }
27
+
28
+ get queueLength(): number {
29
+ return this.queue.length;
30
+ }
31
+ }
@@ -0,0 +1,15 @@
1
+ import type { Logger } from "./logger.js";
2
+
3
+ export const IS_ROOT =
4
+ typeof process !== "undefined" &&
5
+ (process.geteuid?.() ?? process.getuid?.()) === 0;
6
+
7
+ export function unreachable(value: never, logger: Logger): void {
8
+ let valueAsString: string;
9
+ try {
10
+ valueAsString = JSON.stringify(value);
11
+ } catch {
12
+ valueAsString = value;
13
+ }
14
+ logger.error(`Unexpected case: ${valueAsString}`);
15
+ }
@@ -2,14 +2,17 @@ export function getLlmGatewayUrl(posthogHost: string): string {
2
2
  const url = new URL(posthogHost);
3
3
  const hostname = url.hostname;
4
4
 
5
+ // Local development (normalize 127.0.0.1 to localhost)
5
6
  if (hostname === "localhost" || hostname === "127.0.0.1") {
6
- return `${url.protocol}//localhost:3308`;
7
+ return `${url.protocol}//localhost:3308/twig`;
7
8
  }
8
9
 
9
- // Extract region from hostname (us.posthog.com, eu.posthog.com)
10
- // app.posthog.com is legacy US
11
- const regionMatch = hostname.match(/^(us|eu)\.posthog\.com$/);
12
- const region = regionMatch ? regionMatch[1] : "us";
10
+ // Docker containers accessing host
11
+ if (hostname === "host.docker.internal") {
12
+ return `${url.protocol}//host.docker.internal:3308/twig`;
13
+ }
13
14
 
14
- return `https://gateway.${region}.posthog.com`;
15
+ // Production - extract region from hostname, default to US
16
+ const region = hostname.match(/^(us|eu)\.posthog\.com$/)?.[1] ?? "us";
17
+ return `https://gateway.${region}.posthog.com/twig`;
15
18
  }
@@ -1,15 +1,5 @@
1
1
  import type { LogLevel as LogLevelType, OnLogCallback } from "../types.js";
2
2
 
3
- /**
4
- * Simple logger utility with configurable debug mode and external log forwarding
5
- */
6
- export enum LogLevel {
7
- ERROR = 0,
8
- WARN = 1,
9
- INFO = 2,
10
- DEBUG = 3,
11
- }
12
-
13
3
  export interface LoggerConfig {
14
4
  debug?: boolean;
15
5
  prefix?: string;
@@ -30,14 +20,6 @@ export class Logger {
30
20
  this.onLog = config.onLog;
31
21
  }
32
22
 
33
- setDebug(enabled: boolean) {
34
- this.debugEnabled = enabled;
35
- }
36
-
37
- setOnLog(onLog: OnLogCallback | undefined) {
38
- this.onLog = onLog;
39
- }
40
-
41
23
  private formatMessage(
42
24
  level: string,
43
25
  message: string,
@@ -87,18 +69,6 @@ export class Logger {
87
69
  this.emitLog("debug", message, data);
88
70
  }
89
71
 
90
- log(level: LogLevelType, message: string, data?: unknown, scope?: string) {
91
- const originalScope = this.scope;
92
- if (scope) {
93
- this.scope = scope;
94
- }
95
- this.emitLog(level, message, data);
96
- this.scope = originalScope;
97
- }
98
-
99
- /**
100
- * Create a child logger with additional prefix and scope
101
- */
102
72
  child(childPrefix: string): Logger {
103
73
  return new Logger({
104
74
  debug: this.debugEnabled,