Skip to content

Commit 3c236f3

Browse files
committed
feat(harness): expose native Pi runtime
1 parent fc33dfb commit 3c236f3

29 files changed

Lines changed: 449 additions & 321 deletions

.github/workflows/build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ jobs:
7777
- name: Build enricher
7878
run: pnpm --filter @posthog/enricher build
7979

80+
- name: Build harness
81+
run: pnpm --filter @posthog/harness build
82+
8083
- name: Build agent
8184
run: pnpm --filter agent build
8285

.github/workflows/code-build-test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ jobs:
8888
pnpm --filter @posthog/shared run build
8989
pnpm --filter @posthog/git run build
9090
pnpm --filter @posthog/enricher run build
91+
pnpm --filter @posthog/harness run build
9192
pnpm --filter @posthog/agent run build
9293
9394
# build/Assets.car is gitignored; regenerate it so the packaged app ships
@@ -205,6 +206,7 @@ jobs:
205206
pnpm --filter @posthog/shared run build
206207
pnpm --filter @posthog/git run build
207208
pnpm --filter @posthog/enricher run build
209+
pnpm --filter @posthog/harness run build
208210
pnpm --filter @posthog/agent run build
209211
210212
- name: Build app
@@ -275,6 +277,7 @@ jobs:
275277
pnpm --filter @posthog/shared run build
276278
pnpm --filter @posthog/git run build
277279
pnpm --filter @posthog/enricher run build
280+
pnpm --filter @posthog/harness run build
278281
pnpm --filter @posthog/agent run build
279282
280283
- name: Build app

.github/workflows/code-release.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ jobs:
140140
- name: Build enricher package
141141
run: pnpm --filter @posthog/enricher run build
142142

143+
- name: Build harness package
144+
run: pnpm --filter @posthog/harness run build
145+
143146
- name: Build agent package
144147
run: pnpm --filter @posthog/agent run build
145148

@@ -331,6 +334,9 @@ jobs:
331334
- name: Build enricher package
332335
run: pnpm --filter @posthog/enricher run build
333336

337+
- name: Build harness package
338+
run: pnpm --filter @posthog/harness run build
339+
334340
- name: Build agent package
335341
run: pnpm --filter @posthog/agent run build
336342

@@ -457,6 +463,9 @@ jobs:
457463
- name: Build enricher package
458464
run: pnpm --filter @posthog/enricher run build
459465

466+
- name: Build harness package
467+
run: pnpm --filter @posthog/harness run build
468+
460469
- name: Build agent package
461470
run: pnpm --filter @posthog/agent run build
462471

.github/workflows/code-storybook.yml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,16 +149,20 @@ jobs:
149149
pid2=$!
150150
wait_all "$pid1" "$pid2"
151151
152-
# @posthog/agent imports @posthog/git's dist, so git must finish
153-
# before the last group starts.
154-
pnpm --filter @posthog/git build
155-
156-
pnpm --filter @posthog/enricher build &
152+
# @posthog/agent imports the dist of @posthog/git and
153+
# @posthog/harness, so both must finish before the last group starts.
154+
pnpm --filter @posthog/git build &
157155
pid3=$!
158-
pnpm --filter @posthog/agent build &
156+
pnpm --filter @posthog/harness build &
159157
pid4=$!
160158
wait_all "$pid3" "$pid4"
161159
160+
pnpm --filter @posthog/enricher build &
161+
pid5=$!
162+
pnpm --filter @posthog/agent build &
163+
pid6=$!
164+
wait_all "$pid5" "$pid6"
165+
162166
- name: Build Storybook
163167
working-directory: apps/code
164168
run: pnpm build-storybook

.github/workflows/code-update-e2e.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ jobs:
106106
pnpm --filter @posthog/shared run build
107107
pnpm --filter @posthog/git run build
108108
pnpm --filter @posthog/enricher run build
109+
pnpm --filter @posthog/harness run build
109110
pnpm --filter @posthog/agent run build
110111
111112
- name: Build old + new update pair

.github/workflows/pr-build-installer.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ jobs:
9393
pnpm --filter @posthog/shared run build
9494
pnpm --filter @posthog/git run build
9595
pnpm --filter @posthog/enricher run build
96+
pnpm --filter @posthog/harness run build
9697
pnpm --filter @posthog/agent run build
9798
9899
# build/Assets.car is gitignored; regenerate it so the packaged app ships

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ jobs:
140140
pnpm --filter @posthog/shared build
141141
pnpm --filter @posthog/git build
142142
pnpm --filter @posthog/enricher build
143-
pnpm --filter agent build &
144143
wait
144+
pnpm --filter @posthog/harness build
145+
pnpm --filter agent build
145146
146147
- name: Package Electron app
147148
run: pnpm --filter code run package

packages/agent/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@
8484
"types": "./dist/handoff-checkpoint.d.ts",
8585
"import": "./dist/handoff-checkpoint.js"
8686
},
87+
"./pi": {
88+
"types": "./dist/pi/rpc-client.d.ts",
89+
"import": "./dist/pi/rpc-client.js"
90+
},
8791
"./server": {
8892
"types": "./dist/server/agent-server.d.ts",
8993
"import": "./dist/server/agent-server.js"
@@ -136,13 +140,15 @@
136140
"@agentclientprotocol/sdk": "1.1.0",
137141
"@anthropic-ai/claude-agent-sdk": "0.3.197",
138142
"@anthropic-ai/sdk": "0.109.0",
143+
"@earendil-works/pi-coding-agent": "catalog:",
139144
"@hono/node-server": "^1.19.9",
140145
"@openai/codex": "0.140.0",
141146
"@opentelemetry/api-logs": "^0.208.0",
142147
"@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
143148
"@opentelemetry/resources": "^2.0.0",
144149
"@opentelemetry/sdk-logs": "^0.208.0",
145150
"@opentelemetry/semantic-conventions": "^1.28.0",
151+
"@posthog/harness": "workspace:*",
146152
"@types/jsonwebtoken": "^9.0.10",
147153
"commander": "^14.0.2",
148154
"fflate": "^0.8.2",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { RpcClient } from "@earendil-works/pi-coding-agent";
2+
import { describe, expect, it } from "vitest";
3+
import { createPiRpcClient } from "./rpc-client";
4+
5+
describe("createPiRpcClient", () => {
6+
it("creates Pi's native RPC client for the harness entry", () => {
7+
const client = createPiRpcClient({
8+
cwd: "/workspace",
9+
model: "claude-opus-4-8",
10+
apiKey: "token",
11+
env: { POSTHOG_REGION: "us" },
12+
});
13+
14+
expect(client).toBeInstanceOf(RpcClient);
15+
expect(client).toMatchObject({
16+
options: {
17+
cwd: "/workspace",
18+
model: "claude-opus-4-8",
19+
env: {
20+
POSTHOG_API_KEY: "token",
21+
POSTHOG_REGION: "us",
22+
},
23+
provider: "posthog",
24+
},
25+
});
26+
});
27+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { fileURLToPath } from "node:url";
2+
import {
3+
RpcClient,
4+
type RpcClientOptions,
5+
} from "@earendil-works/pi-coding-agent";
6+
7+
export type PiRpcClient = RpcClient;
8+
9+
export type PiRpcClientOptions = Pick<
10+
RpcClientOptions,
11+
"cwd" | "env" | "model"
12+
> & {
13+
/** PostHog token passed only to the isolated RPC host process. */
14+
apiKey?: string;
15+
};
16+
17+
/**
18+
* Create a native Pi RPC client backed by the PostHog harness.
19+
*
20+
* The client owns an isolated child process. Call `start()` before sending
21+
* commands and `stop()` when the run is finished.
22+
*/
23+
export function createPiRpcClient(
24+
options: PiRpcClientOptions = {},
25+
): PiRpcClient {
26+
const { apiKey, env, ...rpcOptions } = options;
27+
28+
return new RpcClient({
29+
...rpcOptions,
30+
cliPath: fileURLToPath(new URL("./rpc-host.js", import.meta.url)),
31+
env: {
32+
...env,
33+
...(apiKey ? { POSTHOG_API_KEY: apiKey } : {}),
34+
},
35+
provider: "posthog",
36+
});
37+
}

0 commit comments

Comments
 (0)