@posthog/agent 2.3.386 → 2.3.387
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/session/jsonl-hydration.d.ts +1 -0
- package/dist/agent.d.ts +1 -0
- package/dist/agent.js +13 -2
- package/dist/agent.js.map +1 -1
- package/dist/handoff-checkpoint.d.ts +39 -0
- package/dist/handoff-checkpoint.js +6679 -0
- package/dist/handoff-checkpoint.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/posthog-api.d.ts +1 -0
- package/dist/posthog-api.js +11 -2
- package/dist/posthog-api.js.map +1 -1
- package/dist/resume.d.ts +3 -1
- package/dist/resume.js +41 -4
- package/dist/resume.js.map +1 -1
- package/dist/server/agent-server.d.ts +5 -15
- package/dist/server/agent-server.js +1330 -394
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +1332 -396
- package/dist/server/bin.cjs.map +1 -1
- package/dist/server/schemas.d.ts +191 -0
- package/dist/server/schemas.js +108 -0
- package/dist/server/schemas.js.map +1 -0
- package/dist/tree-tracker.d.ts +1 -0
- package/dist/tree-tracker.js +18 -4
- package/dist/tree-tracker.js.map +1 -1
- package/dist/types.d.ts +18 -1
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -1
- package/package.json +9 -1
- package/src/acp-extensions.ts +3 -0
- package/src/handoff-checkpoint.test.ts +183 -0
- package/src/handoff-checkpoint.ts +361 -0
- package/src/posthog-api.test.ts +29 -0
- package/src/posthog-api.ts +5 -1
- package/src/resume.ts +7 -1
- package/src/sagas/apply-snapshot-saga.ts +7 -0
- package/src/sagas/capture-tree-saga.ts +10 -3
- package/src/sagas/resume-saga.ts +32 -0
- package/src/sagas/test-fixtures.ts +46 -0
- package/src/server/agent-server.ts +74 -1
- package/src/server/schemas.ts +21 -2
- package/src/types.ts +24 -0
package/src/resume.ts
CHANGED
|
@@ -19,12 +19,17 @@ import type { ContentBlock } from "@agentclientprotocol/sdk";
|
|
|
19
19
|
import { selectRecentTurns } from "./adapters/claude/session/jsonl-hydration";
|
|
20
20
|
import type { PostHogAPIClient } from "./posthog-api";
|
|
21
21
|
import { ResumeSaga } from "./sagas/resume-saga";
|
|
22
|
-
import type {
|
|
22
|
+
import type {
|
|
23
|
+
DeviceInfo,
|
|
24
|
+
GitCheckpointEvent,
|
|
25
|
+
TreeSnapshotEvent,
|
|
26
|
+
} from "./types";
|
|
23
27
|
import { Logger } from "./utils/logger";
|
|
24
28
|
|
|
25
29
|
export interface ResumeState {
|
|
26
30
|
conversation: ConversationTurn[];
|
|
27
31
|
latestSnapshot: TreeSnapshotEvent | null;
|
|
32
|
+
latestGitCheckpoint: GitCheckpointEvent | null;
|
|
28
33
|
/** Whether the tree snapshot was successfully applied (files restored) */
|
|
29
34
|
snapshotApplied: boolean;
|
|
30
35
|
interrupted: boolean;
|
|
@@ -96,6 +101,7 @@ export async function resumeFromLog(
|
|
|
96
101
|
return {
|
|
97
102
|
conversation: result.data.conversation as ConversationTurn[],
|
|
98
103
|
latestSnapshot: result.data.latestSnapshot,
|
|
104
|
+
latestGitCheckpoint: result.data.latestGitCheckpoint,
|
|
99
105
|
snapshotApplied: result.data.snapshotApplied,
|
|
100
106
|
interrupted: result.data.interrupted,
|
|
101
107
|
lastDevice: result.data.lastDevice,
|
|
@@ -59,6 +59,13 @@ export class ApplySnapshotSaga extends Saga<
|
|
|
59
59
|
const base64Content = Buffer.from(arrayBuffer).toString("utf-8");
|
|
60
60
|
const binaryContent = Buffer.from(base64Content, "base64");
|
|
61
61
|
await writeFile(archivePath, binaryContent);
|
|
62
|
+
this.log.info("Tree archive downloaded", {
|
|
63
|
+
treeHash: snapshot.treeHash,
|
|
64
|
+
snapshotBytes: binaryContent.byteLength,
|
|
65
|
+
snapshotWireBytes: arrayBuffer.byteLength,
|
|
66
|
+
totalBytes: binaryContent.byteLength,
|
|
67
|
+
totalWireBytes: arrayBuffer.byteLength,
|
|
68
|
+
});
|
|
62
69
|
},
|
|
63
70
|
rollback: async () => {
|
|
64
71
|
if (this.archivePath) {
|
|
@@ -113,6 +113,8 @@ export class CaptureTreeSaga extends Saga<CaptureTreeInput, CaptureTreeOutput> {
|
|
|
113
113
|
execute: async () => {
|
|
114
114
|
const archiveContent = await readFile(archivePath);
|
|
115
115
|
const base64Content = archiveContent.toString("base64");
|
|
116
|
+
const snapshotBytes = archiveContent.byteLength;
|
|
117
|
+
const snapshotWireBytes = Buffer.byteLength(base64Content, "utf-8");
|
|
116
118
|
|
|
117
119
|
const artifacts = await apiClient.uploadTaskArtifacts(taskId, runId, [
|
|
118
120
|
{
|
|
@@ -123,12 +125,17 @@ export class CaptureTreeSaga extends Saga<CaptureTreeInput, CaptureTreeOutput> {
|
|
|
123
125
|
},
|
|
124
126
|
]);
|
|
125
127
|
|
|
126
|
-
|
|
128
|
+
const uploadedArtifact = artifacts[0];
|
|
129
|
+
if (uploadedArtifact?.storage_path) {
|
|
127
130
|
this.log.info("Tree archive uploaded", {
|
|
128
|
-
storagePath:
|
|
131
|
+
storagePath: uploadedArtifact.storage_path,
|
|
129
132
|
treeHash,
|
|
133
|
+
snapshotBytes,
|
|
134
|
+
snapshotWireBytes,
|
|
135
|
+
totalBytes: snapshotBytes,
|
|
136
|
+
totalWireBytes: snapshotWireBytes,
|
|
130
137
|
});
|
|
131
|
-
return
|
|
138
|
+
return uploadedArtifact.storage_path;
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
return undefined;
|
package/src/sagas/resume-saga.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { PostHogAPIClient } from "../posthog-api";
|
|
|
5
5
|
import { TreeTracker } from "../tree-tracker";
|
|
6
6
|
import type {
|
|
7
7
|
DeviceInfo,
|
|
8
|
+
GitCheckpointEvent,
|
|
8
9
|
StoredNotification,
|
|
9
10
|
TreeSnapshotEvent,
|
|
10
11
|
} from "../types";
|
|
@@ -34,6 +35,7 @@ export interface ResumeInput {
|
|
|
34
35
|
export interface ResumeOutput {
|
|
35
36
|
conversation: ConversationTurn[];
|
|
36
37
|
latestSnapshot: TreeSnapshotEvent | null;
|
|
38
|
+
latestGitCheckpoint: GitCheckpointEvent | null;
|
|
37
39
|
snapshotApplied: boolean;
|
|
38
40
|
interrupted: boolean;
|
|
39
41
|
lastDevice?: DeviceInfo;
|
|
@@ -75,6 +77,11 @@ export class ResumeSaga extends Saga<ResumeInput, ResumeOutput> {
|
|
|
75
77
|
Promise.resolve(this.findLatestTreeSnapshot(entries)),
|
|
76
78
|
);
|
|
77
79
|
|
|
80
|
+
const latestGitCheckpoint = await this.readOnlyStep(
|
|
81
|
+
"find_git_checkpoint",
|
|
82
|
+
() => Promise.resolve(this.findLatestGitCheckpoint(entries)),
|
|
83
|
+
);
|
|
84
|
+
|
|
78
85
|
// Step 4: Apply snapshot if present (wrapped in step for consistent logging)
|
|
79
86
|
// Note: We use a try/catch inside the step because snapshot failure should NOT fail the saga
|
|
80
87
|
let snapshotApplied = false;
|
|
@@ -158,6 +165,7 @@ export class ResumeSaga extends Saga<ResumeInput, ResumeOutput> {
|
|
|
158
165
|
return {
|
|
159
166
|
conversation,
|
|
160
167
|
latestSnapshot,
|
|
168
|
+
latestGitCheckpoint,
|
|
161
169
|
snapshotApplied,
|
|
162
170
|
interrupted: latestSnapshot?.interrupted ?? false,
|
|
163
171
|
lastDevice,
|
|
@@ -169,6 +177,7 @@ export class ResumeSaga extends Saga<ResumeInput, ResumeOutput> {
|
|
|
169
177
|
return {
|
|
170
178
|
conversation: [],
|
|
171
179
|
latestSnapshot: null,
|
|
180
|
+
latestGitCheckpoint: null,
|
|
172
181
|
snapshotApplied: false,
|
|
173
182
|
interrupted: false,
|
|
174
183
|
logEntryCount: 0,
|
|
@@ -197,6 +206,29 @@ export class ResumeSaga extends Saga<ResumeInput, ResumeOutput> {
|
|
|
197
206
|
return null;
|
|
198
207
|
}
|
|
199
208
|
|
|
209
|
+
private findLatestGitCheckpoint(
|
|
210
|
+
entries: StoredNotification[],
|
|
211
|
+
): GitCheckpointEvent | null {
|
|
212
|
+
const sdkPrefixedMethod = `_${POSTHOG_NOTIFICATIONS.GIT_CHECKPOINT}`;
|
|
213
|
+
|
|
214
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
215
|
+
const entry = entries[i];
|
|
216
|
+
const method = entry.notification?.method;
|
|
217
|
+
if (
|
|
218
|
+
method === sdkPrefixedMethod ||
|
|
219
|
+
method === POSTHOG_NOTIFICATIONS.GIT_CHECKPOINT
|
|
220
|
+
) {
|
|
221
|
+
const params = entry.notification?.params as
|
|
222
|
+
| GitCheckpointEvent
|
|
223
|
+
| undefined;
|
|
224
|
+
if (params?.checkpointId && params?.checkpointRef) {
|
|
225
|
+
return params;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
200
232
|
private findLastDeviceInfo(
|
|
201
233
|
entries: StoredNotification[],
|
|
202
234
|
): DeviceInfo | undefined {
|
|
@@ -67,6 +67,52 @@ export async function createTestRepo(prefix = "test-repo"): Promise<TestRepo> {
|
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
export async function cloneTestRepo(
|
|
71
|
+
sourcePath: string,
|
|
72
|
+
prefix = "test-repo-clone",
|
|
73
|
+
): Promise<TestRepo> {
|
|
74
|
+
const clonePath = join(
|
|
75
|
+
tmpdir(),
|
|
76
|
+
`${prefix}-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
77
|
+
);
|
|
78
|
+
await execFileAsync("git", ["clone", sourcePath, clonePath]);
|
|
79
|
+
await execFileAsync("git", ["config", "user.email", "test@test.com"], {
|
|
80
|
+
cwd: clonePath,
|
|
81
|
+
});
|
|
82
|
+
await execFileAsync("git", ["config", "user.name", "Test"], {
|
|
83
|
+
cwd: clonePath,
|
|
84
|
+
});
|
|
85
|
+
await execFileAsync("git", ["config", "commit.gpgsign", "false"], {
|
|
86
|
+
cwd: clonePath,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const git = async (args: string[]): Promise<string> => {
|
|
90
|
+
const { stdout } = await execFileAsync("git", args, { cwd: clonePath });
|
|
91
|
+
return stdout.trim();
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
path: clonePath,
|
|
96
|
+
cleanup: () => rm(clonePath, { recursive: true, force: true }),
|
|
97
|
+
git,
|
|
98
|
+
writeFile: async (relativePath: string, content: string) => {
|
|
99
|
+
const fullPath = join(clonePath, relativePath);
|
|
100
|
+
const dir = join(fullPath, "..");
|
|
101
|
+
await mkdir(dir, { recursive: true });
|
|
102
|
+
await writeFile(fullPath, content);
|
|
103
|
+
},
|
|
104
|
+
readFile: async (relativePath: string) => {
|
|
105
|
+
return readFile(join(clonePath, relativePath), "utf-8");
|
|
106
|
+
},
|
|
107
|
+
deleteFile: async (relativePath: string) => {
|
|
108
|
+
await rm(join(clonePath, relativePath), { force: true });
|
|
109
|
+
},
|
|
110
|
+
exists: (relativePath: string) => {
|
|
111
|
+
return existsSync(join(clonePath, relativePath));
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
70
116
|
export function createMockLogger(): SagaLogger {
|
|
71
117
|
return {
|
|
72
118
|
info: vi.fn(),
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "../adapters/claude/conversion/sdk-to-acp";
|
|
28
28
|
import type { PermissionMode } from "../execution-mode";
|
|
29
29
|
import { DEFAULT_CODEX_MODEL } from "../gateway-models";
|
|
30
|
+
import { HandoffCheckpointTracker } from "../handoff-checkpoint";
|
|
30
31
|
import { PostHogAPIClient } from "../posthog-api";
|
|
31
32
|
import {
|
|
32
33
|
formatConversationForResume,
|
|
@@ -38,6 +39,8 @@ import { TreeTracker } from "../tree-tracker";
|
|
|
38
39
|
import type {
|
|
39
40
|
AgentMode,
|
|
40
41
|
DeviceInfo,
|
|
42
|
+
GitCheckpointEvent,
|
|
43
|
+
HandoffLocalGitState,
|
|
41
44
|
LogLevel,
|
|
42
45
|
TaskRun,
|
|
43
46
|
TaskRunArtifact,
|
|
@@ -52,7 +55,11 @@ import {
|
|
|
52
55
|
promptBlocksToText,
|
|
53
56
|
} from "./cloud-prompt";
|
|
54
57
|
import { type JwtPayload, JwtValidationError, validateJwt } from "./jwt";
|
|
55
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
handoffLocalGitStateSchema,
|
|
60
|
+
jsonRpcRequestSchema,
|
|
61
|
+
validateCommandParams,
|
|
62
|
+
} from "./schemas";
|
|
56
63
|
import type { AgentServerConfig } from "./types";
|
|
57
64
|
|
|
58
65
|
const agentErrorClassificationSchema = z.enum([
|
|
@@ -185,6 +192,7 @@ interface ActiveSession {
|
|
|
185
192
|
permissionMode: PermissionMode;
|
|
186
193
|
/** Whether a desktop client has ever connected via SSE during this session */
|
|
187
194
|
hasDesktopConnected: boolean;
|
|
195
|
+
pendingHandoffGitState?: HandoffLocalGitState;
|
|
188
196
|
}
|
|
189
197
|
|
|
190
198
|
function getTaskRunStateString(
|
|
@@ -661,6 +669,10 @@ export class AgentServer {
|
|
|
661
669
|
case POSTHOG_NOTIFICATIONS.CLOSE:
|
|
662
670
|
case "close": {
|
|
663
671
|
this.logger.debug("Close requested");
|
|
672
|
+
const localGitState = this.extractHandoffLocalGitState(params);
|
|
673
|
+
if (localGitState && this.session) {
|
|
674
|
+
this.session.pendingHandoffGitState = localGitState;
|
|
675
|
+
}
|
|
664
676
|
await this.cleanupSession();
|
|
665
677
|
return { closed: true };
|
|
666
678
|
}
|
|
@@ -958,6 +970,7 @@ export class AgentServer {
|
|
|
958
970
|
logWriter,
|
|
959
971
|
permissionMode: initialPermissionMode,
|
|
960
972
|
hasDesktopConnected: sseController !== null,
|
|
973
|
+
pendingHandoffGitState: undefined,
|
|
961
974
|
};
|
|
962
975
|
|
|
963
976
|
this.logger = new Logger({
|
|
@@ -2104,6 +2117,12 @@ ${attributionInstructions}
|
|
|
2104
2117
|
|
|
2105
2118
|
this.logger.debug("Cleaning up session");
|
|
2106
2119
|
|
|
2120
|
+
try {
|
|
2121
|
+
await this.captureHandoffCheckpoint();
|
|
2122
|
+
} catch (error) {
|
|
2123
|
+
this.logger.error("Failed to capture handoff checkpoint", error);
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2107
2126
|
try {
|
|
2108
2127
|
await this.captureTreeState();
|
|
2109
2128
|
} catch (error) {
|
|
@@ -2180,6 +2199,60 @@ ${attributionInstructions}
|
|
|
2180
2199
|
}
|
|
2181
2200
|
}
|
|
2182
2201
|
|
|
2202
|
+
private async captureHandoffCheckpoint(): Promise<void> {
|
|
2203
|
+
if (!this.session?.treeTracker || !this.session.pendingHandoffGitState) {
|
|
2204
|
+
return;
|
|
2205
|
+
}
|
|
2206
|
+
if (!this.posthogAPI) {
|
|
2207
|
+
this.logger.warn(
|
|
2208
|
+
"Skipping handoff checkpoint capture: PostHog API client is not configured",
|
|
2209
|
+
);
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
const tracker = new HandoffCheckpointTracker({
|
|
2214
|
+
repositoryPath: this.config.repositoryPath ?? "/tmp/workspace",
|
|
2215
|
+
taskId: this.session.payload.task_id,
|
|
2216
|
+
runId: this.session.payload.run_id,
|
|
2217
|
+
apiClient: this.posthogAPI,
|
|
2218
|
+
logger: this.logger.child("HandoffCheckpoint"),
|
|
2219
|
+
});
|
|
2220
|
+
|
|
2221
|
+
const checkpoint = await tracker.captureForHandoff(
|
|
2222
|
+
this.session.pendingHandoffGitState,
|
|
2223
|
+
);
|
|
2224
|
+
if (!checkpoint) return;
|
|
2225
|
+
|
|
2226
|
+
const checkpointWithDevice: GitCheckpointEvent = {
|
|
2227
|
+
...checkpoint,
|
|
2228
|
+
device: this.session.deviceInfo,
|
|
2229
|
+
};
|
|
2230
|
+
|
|
2231
|
+
const notification = {
|
|
2232
|
+
jsonrpc: "2.0" as const,
|
|
2233
|
+
method: POSTHOG_NOTIFICATIONS.GIT_CHECKPOINT,
|
|
2234
|
+
params: checkpointWithDevice,
|
|
2235
|
+
};
|
|
2236
|
+
|
|
2237
|
+
this.broadcastEvent({
|
|
2238
|
+
type: "notification",
|
|
2239
|
+
timestamp: new Date().toISOString(),
|
|
2240
|
+
notification,
|
|
2241
|
+
});
|
|
2242
|
+
|
|
2243
|
+
this.session.logWriter.appendRawLine(
|
|
2244
|
+
this.session.payload.run_id,
|
|
2245
|
+
JSON.stringify(notification),
|
|
2246
|
+
);
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
private extractHandoffLocalGitState(
|
|
2250
|
+
params: Record<string, unknown>,
|
|
2251
|
+
): HandoffLocalGitState | null {
|
|
2252
|
+
const result = handoffLocalGitStateSchema.safeParse(params.localGitState);
|
|
2253
|
+
return result.success ? result.data : null;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2183
2256
|
private broadcastTurnComplete(stopReason: string): void {
|
|
2184
2257
|
if (!this.session) return;
|
|
2185
2258
|
this.broadcastEvent({
|
package/src/server/schemas.ts
CHANGED
|
@@ -5,6 +5,19 @@ const httpHeaderSchema = z.object({
|
|
|
5
5
|
value: z.string(),
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
+
const nullishString = z
|
|
9
|
+
.string()
|
|
10
|
+
.nullish()
|
|
11
|
+
.transform((value) => value ?? null);
|
|
12
|
+
|
|
13
|
+
export const handoffLocalGitStateSchema = z.object({
|
|
14
|
+
head: nullishString,
|
|
15
|
+
branch: nullishString,
|
|
16
|
+
upstreamHead: nullishString,
|
|
17
|
+
upstreamRemote: nullishString,
|
|
18
|
+
upstreamMergeRef: nullishString,
|
|
19
|
+
});
|
|
20
|
+
|
|
8
21
|
const remoteMcpServerSchema = z.object({
|
|
9
22
|
type: z.enum(["http", "sse"]),
|
|
10
23
|
name: z.string().min(1, "MCP server name is required"),
|
|
@@ -83,13 +96,19 @@ export const refreshSessionParamsSchema = z.object({
|
|
|
83
96
|
mcpServers: mcpServersSchema,
|
|
84
97
|
});
|
|
85
98
|
|
|
99
|
+
export const closeParamsSchema = z
|
|
100
|
+
.object({
|
|
101
|
+
localGitState: handoffLocalGitStateSchema.optional(),
|
|
102
|
+
})
|
|
103
|
+
.optional();
|
|
104
|
+
|
|
86
105
|
export const commandParamsSchemas = {
|
|
87
106
|
user_message: userMessageParamsSchema,
|
|
88
107
|
"posthog/user_message": userMessageParamsSchema,
|
|
89
108
|
cancel: z.object({}).optional(),
|
|
90
109
|
"posthog/cancel": z.object({}).optional(),
|
|
91
|
-
close:
|
|
92
|
-
"posthog/close":
|
|
110
|
+
close: closeParamsSchema,
|
|
111
|
+
"posthog/close": closeParamsSchema,
|
|
93
112
|
permission_response: permissionResponseParamsSchema,
|
|
94
113
|
"posthog/permission_response": permissionResponseParamsSchema,
|
|
95
114
|
set_config_option: setConfigOptionParamsSchema,
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GitHandoffCheckpoint,
|
|
3
|
+
HandoffLocalGitState as GitHandoffLocalGitState,
|
|
4
|
+
} from "@posthog/git/handoff";
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Stored custom notification following ACP extensibility model.
|
|
3
8
|
* Custom notifications use underscore-prefixed methods (e.g., `_posthog/phase_start`).
|
|
@@ -196,3 +201,22 @@ export interface TreeSnapshot {
|
|
|
196
201
|
export interface TreeSnapshotEvent extends TreeSnapshot {
|
|
197
202
|
device?: DeviceInfo;
|
|
198
203
|
}
|
|
204
|
+
|
|
205
|
+
export type HandoffLocalGitState = GitHandoffLocalGitState;
|
|
206
|
+
|
|
207
|
+
export interface GitCheckpoint extends GitHandoffCheckpoint {
|
|
208
|
+
artifactPath?: string;
|
|
209
|
+
indexArtifactPath?: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface GitCheckpointEvent extends GitCheckpoint {
|
|
213
|
+
device?: DeviceInfo;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Keeps the emitted `@posthog/agent/types` entrypoint as a runtime ESM module.
|
|
218
|
+
*
|
|
219
|
+
* `export {}` is stripped by tsup in this package, which leaves `dist/types.js`
|
|
220
|
+
* empty and breaks downstream type resolution for the exported subpath.
|
|
221
|
+
*/
|
|
222
|
+
export const AGENT_TYPES_MODULE = true;
|