agent-tempo 1.2.0 → 1.4.0
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/CLAUDE.md +253 -219
- package/LICENSE +21 -21
- package/README.md +293 -289
- package/assets/icon-dark.svg +9 -9
- package/assets/icon.svg +9 -9
- package/assets/logo-dark.svg +11 -11
- package/assets/logo-light.svg +11 -11
- package/dashboard/README.md +91 -91
- package/dashboard/dist/assets/{index-D6Xyje_n.js → index-jmYe6rmS.js} +2 -2
- package/dashboard/dist/assets/index-jmYe6rmS.js.map +1 -0
- package/dashboard/dist/index.html +20 -20
- package/dashboard/package.json +47 -47
- package/dist/activities/outbox.d.ts +30 -1
- package/dist/activities/outbox.js +96 -3
- package/dist/adapters/base.js +5 -0
- package/dist/adapters/copilot/adapter.js +12 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +7 -0
- package/dist/adapters/pi/adapter.d.ts +2 -0
- package/dist/adapters/pi/adapter.js +43 -0
- package/dist/adapters/pi/index.d.ts +16 -0
- package/dist/adapters/pi/index.js +10 -0
- package/dist/cli/global-wrapper.d.ts +19 -0
- package/dist/cli/global-wrapper.js +169 -0
- package/dist/cli/help-text.js +97 -97
- package/dist/cli/startup.js +11 -0
- package/dist/cli/upgrade-command.js +81 -81
- package/dist/cli.js +12 -0
- package/dist/client/core.js +9 -2
- package/dist/client/interface.d.ts +6 -0
- package/dist/config.d.ts +79 -0
- package/dist/config.js +74 -0
- package/dist/daemon.js +37 -1
- package/dist/http/aggregate.d.ts +22 -1
- package/dist/http/aggregate.js +41 -0
- package/dist/http/auth.d.ts +94 -8
- package/dist/http/auth.js +93 -9
- package/dist/http/body.d.ts +4 -1
- package/dist/http/body.js +6 -3
- package/dist/http/event-bus.js +1 -0
- package/dist/http/event-types.d.ts +34 -2
- package/dist/http/event-types.js +1 -0
- package/dist/http/gate-audit.d.ts +12 -0
- package/dist/http/gate-audit.js +95 -0
- package/dist/http/gate-registry.d.ts +167 -0
- package/dist/http/gate-registry.js +163 -0
- package/dist/http/gate-routes.d.ts +48 -0
- package/dist/http/gate-routes.js +102 -0
- package/dist/http/ingest-registry.d.ts +30 -0
- package/dist/http/ingest-registry.js +108 -0
- package/dist/http/inner-loop-routes.d.ts +66 -0
- package/dist/http/inner-loop-routes.js +182 -0
- package/dist/http/inner-loop.d.ts +92 -0
- package/dist/http/inner-loop.js +155 -0
- package/dist/http/server.d.ts +38 -3
- package/dist/http/server.js +211 -6
- package/dist/http/snapshot.d.ts +6 -0
- package/dist/http/snapshot.js +6 -0
- package/dist/pi/cue-pump.d.ts +61 -0
- package/dist/pi/cue-pump.js +95 -0
- package/dist/pi/extension.d.ts +45 -0
- package/dist/pi/extension.js +407 -0
- package/dist/pi/gate-client.d.ts +54 -0
- package/dist/pi/gate-client.js +136 -0
- package/dist/pi/headless.d.ts +85 -0
- package/dist/pi/headless.js +224 -0
- package/dist/pi/index.d.ts +28 -0
- package/dist/pi/index.js +43 -0
- package/dist/pi/inner-loop-client.d.ts +67 -0
- package/dist/pi/inner-loop-client.js +164 -0
- package/dist/pi/inner-loop-publisher.d.ts +187 -0
- package/dist/pi/inner-loop-publisher.js +236 -0
- package/dist/pi/lazy-proxy.d.ts +37 -0
- package/dist/pi/lazy-proxy.js +55 -0
- package/dist/pi/mission-control/actions.d.ts +48 -0
- package/dist/pi/mission-control/actions.js +98 -0
- package/dist/pi/mission-control/board.d.ts +53 -0
- package/dist/pi/mission-control/board.js +104 -0
- package/dist/pi/mission-control/extension.d.ts +44 -0
- package/dist/pi/mission-control/extension.js +251 -0
- package/dist/pi/mission-control/index.d.ts +15 -0
- package/dist/pi/mission-control/index.js +32 -0
- package/dist/pi/mission-control/inner-tail.d.ts +48 -0
- package/dist/pi/mission-control/inner-tail.js +76 -0
- package/dist/pi/mission-control/pi-ui.d.ts +43 -0
- package/dist/pi/mission-control/pi-ui.js +10 -0
- package/dist/pi/mission-control/render.d.ts +6 -0
- package/dist/pi/mission-control/render.js +95 -0
- package/dist/pi/phase-driver.d.ts +74 -0
- package/dist/pi/phase-driver.js +122 -0
- package/dist/pi/pi-types.d.ts +208 -0
- package/dist/pi/pi-types.js +21 -0
- package/dist/pi/probe.d.ts +80 -0
- package/dist/pi/probe.js +154 -0
- package/dist/pi/render-tools.d.ts +17 -0
- package/dist/pi/render-tools.js +51 -0
- package/dist/pi/reset-pump.d.ts +47 -0
- package/dist/pi/reset-pump.js +85 -0
- package/dist/pi/tool-capability.d.ts +60 -0
- package/dist/pi/tool-capability.js +156 -0
- package/dist/pi/workflow-client.d.ts +158 -0
- package/dist/pi/workflow-client.js +289 -0
- package/dist/pi/zod-to-typebox.d.ts +74 -0
- package/dist/pi/zod-to-typebox.js +191 -0
- package/dist/scripts/verify-daemon-isolation-guard.js +24 -24
- package/dist/server-tools.d.ts +2 -0
- package/dist/server-tools.js +50 -46
- package/dist/server.js +4 -0
- package/dist/spawn.d.ts +55 -0
- package/dist/spawn.js +84 -12
- package/dist/tools/agent-types.d.ts +2 -2
- package/dist/tools/agent-types.js +22 -17
- package/dist/tools/attachment-info.d.ts +2 -2
- package/dist/tools/attachment-info.js +38 -33
- package/dist/tools/broadcast.d.ts +2 -2
- package/dist/tools/broadcast.js +69 -64
- package/dist/tools/cancel-stage.d.ts +2 -2
- package/dist/tools/cancel-stage.js +20 -15
- package/dist/tools/clear-state.d.ts +2 -2
- package/dist/tools/clear-state.js +25 -20
- package/dist/tools/coat-check-evict.d.ts +2 -2
- package/dist/tools/coat-check-evict.js +30 -25
- package/dist/tools/coat-check-get.d.ts +2 -2
- package/dist/tools/coat-check-get.js +39 -34
- package/dist/tools/coat-check-list.d.ts +2 -2
- package/dist/tools/coat-check-list.js +48 -43
- package/dist/tools/coat-check-put.d.ts +2 -2
- package/dist/tools/coat-check-put.js +41 -36
- package/dist/tools/cue.d.ts +2 -2
- package/dist/tools/cue.js +57 -52
- package/dist/tools/descriptor.d.ts +72 -0
- package/dist/tools/descriptor.js +39 -0
- package/dist/tools/destroy.d.ts +2 -2
- package/dist/tools/destroy.js +153 -148
- package/dist/tools/ensemble.d.ts +2 -2
- package/dist/tools/ensemble.js +71 -66
- package/dist/tools/evaluate-gate.d.ts +2 -2
- package/dist/tools/evaluate-gate.js +33 -27
- package/dist/tools/fetch-state.d.ts +2 -2
- package/dist/tools/fetch-state.js +43 -38
- package/dist/tools/gates.d.ts +2 -2
- package/dist/tools/gates.js +39 -34
- package/dist/tools/hosts.d.ts +2 -2
- package/dist/tools/hosts.js +25 -20
- package/dist/tools/listen.d.ts +2 -2
- package/dist/tools/listen.js +23 -18
- package/dist/tools/load-lineup.d.ts +2 -2
- package/dist/tools/load-lineup.js +324 -319
- package/dist/tools/migrate.d.ts +2 -2
- package/dist/tools/migrate.js +45 -40
- package/dist/tools/pause.d.ts +2 -2
- package/dist/tools/pause.js +34 -29
- package/dist/tools/play.d.ts +2 -2
- package/dist/tools/play.js +53 -48
- package/dist/tools/quality-gate.d.ts +2 -2
- package/dist/tools/quality-gate.js +26 -21
- package/dist/tools/recall.d.ts +2 -2
- package/dist/tools/recall.js +32 -27
- package/dist/tools/recruit.d.ts +2 -2
- package/dist/tools/recruit.js +325 -256
- package/dist/tools/release.d.ts +2 -2
- package/dist/tools/release.js +85 -80
- package/dist/tools/report.d.ts +2 -2
- package/dist/tools/report.js +28 -23
- package/dist/tools/reset.d.ts +3 -0
- package/dist/tools/reset.js +51 -0
- package/dist/tools/restart.d.ts +2 -2
- package/dist/tools/restart.js +51 -46
- package/dist/tools/restore.d.ts +2 -2
- package/dist/tools/restore.js +76 -71
- package/dist/tools/save-lineup.d.ts +2 -2
- package/dist/tools/save-lineup.js +32 -27
- package/dist/tools/save-state.d.ts +2 -2
- package/dist/tools/save-state.js +43 -38
- package/dist/tools/schedule.d.ts +2 -2
- package/dist/tools/schedule.js +133 -128
- package/dist/tools/schedules.d.ts +2 -2
- package/dist/tools/schedules.js +41 -36
- package/dist/tools/set-ensemble-description.d.ts +2 -2
- package/dist/tools/set-ensemble-description.js +26 -21
- package/dist/tools/set-name.d.ts +2 -2
- package/dist/tools/set-name.js +38 -33
- package/dist/tools/set-part.d.ts +2 -2
- package/dist/tools/set-part.js +20 -15
- package/dist/tools/shutdown.d.ts +2 -2
- package/dist/tools/shutdown.js +39 -34
- package/dist/tools/stage.d.ts +2 -2
- package/dist/tools/stage.js +28 -23
- package/dist/tools/stages.d.ts +2 -2
- package/dist/tools/stages.js +36 -31
- package/dist/tools/unschedule.d.ts +2 -2
- package/dist/tools/unschedule.js +30 -25
- package/dist/tools/who-am-i.d.ts +2 -2
- package/dist/tools/who-am-i.js +36 -31
- package/dist/tools/worktree.d.ts +2 -2
- package/dist/tools/worktree.js +134 -129
- package/dist/tui/index.js +6 -6
- package/dist/types.d.ts +47 -2
- package/dist/types.js +1 -1
- package/dist/utils/default-part.js +1 -0
- package/dist/utils/grpc-shutdown-guard.d.ts +52 -0
- package/dist/utils/grpc-shutdown-guard.js +88 -0
- package/dist/utils/sdk-probe.d.ts +23 -0
- package/dist/utils/sdk-probe.js +46 -7
- package/dist/worker.d.ts +3 -1
- package/dist/worker.js +6 -2
- package/dist/workflows/session.js +70 -2
- package/dist/workflows/signals.d.ts +32 -2
- package/dist/workflows/signals.js +25 -2
- package/examples/agents/tempo-composer.md +56 -56
- package/examples/agents/tempo-conductor.md +117 -117
- package/examples/agents/tempo-critic.md +73 -73
- package/examples/agents/tempo-improv.md +74 -74
- package/examples/agents/tempo-liner.md +75 -75
- package/examples/agents/tempo-roadie.md +61 -61
- package/examples/agents/tempo-soloist.md +71 -71
- package/examples/agents/tempo-tuner.md +94 -94
- package/examples/ensembles/tempo-big-band.yaml +146 -146
- package/examples/ensembles/tempo-dev-team.yaml +58 -58
- package/examples/ensembles/tempo-headless-jam.yaml +77 -77
- package/examples/ensembles/tempo-jam-session.yaml +41 -41
- package/examples/ensembles/tempo-mock-jam.yaml +79 -79
- package/examples/ensembles/tempo-review-squad.yaml +32 -32
- package/package.json +176 -173
- package/packaging/launchd/com.agent.tempo.plist +46 -46
- package/packaging/systemd/agent-tempo.service +32 -32
- package/packaging/windows/install-task.ps1 +71 -71
- package/scenarios/conductor-recruit-mock.yaml +33 -33
- package/scenarios/echo-roundtrip.yaml +15 -15
- package/scenarios/multi-player-handoff.yaml +38 -38
- package/scenarios/recruit-cascade.yaml +38 -38
- package/scenarios/two-player-conversation.yaml +33 -33
- package/workflow-bundle.js +97 -6
- package/dashboard/dist/assets/index-D6Xyje_n.js.map +0 -1
- package/dist/activities/claude-stop.d.ts +0 -21
- package/dist/activities/claude-stop.js +0 -94
- package/dist/channel.d.ts +0 -3
- package/dist/channel.js +0 -48
- package/dist/copilot-bridge.d.ts +0 -22
- package/dist/copilot-bridge.js +0 -565
- package/dist/scripts/258-spotcheck.js +0 -303
- package/dist/tools/detach.d.ts +0 -4
- package/dist/tools/detach.js +0 -45
- package/dist/tools/encore.d.ts +0 -4
- package/dist/tools/encore.js +0 -31
- package/dist/tools/helpers.d.ts +0 -21
- package/dist/tools/helpers.js +0 -25
- package/dist/tools/pause-ensemble.d.ts +0 -4
- package/dist/tools/pause-ensemble.js +0 -58
- package/dist/tools/resume-ensemble.d.ts +0 -4
- package/dist/tools/resume-ensemble.js +0 -79
- package/dist/tools/stop.d.ts +0 -4
- package/dist/tools/stop.js +0 -29
- package/dist/tui/client.d.ts +0 -6
- package/dist/tui/client.js +0 -9
- package/dist/tui/components/ActivityLog.d.ts +0 -16
- package/dist/tui/components/ActivityLog.js +0 -36
- package/dist/tui/components/CommandOverlay.d.ts +0 -15
- package/dist/tui/components/CommandOverlay.js +0 -34
- package/dist/tui/components/ConductorChat.d.ts +0 -16
- package/dist/tui/components/ConductorChat.js +0 -32
- package/dist/tui/components/EnsembleListView.d.ts +0 -14
- package/dist/tui/components/EnsembleListView.js +0 -32
- package/dist/tui/components/EnsemblePanel.d.ts +0 -12
- package/dist/tui/components/EnsemblePanel.js +0 -40
- package/dist/tui/components/InputBar.d.ts +0 -13
- package/dist/tui/components/InputBar.js +0 -58
- package/dist/tui/components/ScheduleOverlay.d.ts +0 -13
- package/dist/tui/components/ScheduleOverlay.js +0 -113
- package/dist/tui/components/TopBar.d.ts +0 -12
- package/dist/tui/components/TopBar.js +0 -15
- package/dist/tui/core-api.d.ts +0 -26
- package/dist/tui/core-api.js +0 -67
- package/dist/tui/hooks/useEnsembleDiscovery.d.ts +0 -3
- package/dist/tui/hooks/useEnsembleDiscovery.js +0 -30
- package/dist/tui/hooks/useMaestroPoller.d.ts +0 -3
- package/dist/tui/hooks/useMaestroPoller.js +0 -36
- package/dist/tui/hooks/useSendCommand.d.ts +0 -7
- package/dist/tui/hooks/useSendCommand.js +0 -29
- package/dist/utils/bg-preflight.d.ts +0 -25
- package/dist/utils/bg-preflight.js +0 -154
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en" data-theme="dark" data-density="6" data-accent="terracotta">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<meta name="color-scheme" content="dark light" />
|
|
7
|
-
<meta name="description" content="agent-tempo Maestro Dashboard" />
|
|
8
|
-
<title>agent-tempo · Maestro</title>
|
|
9
|
-
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
10
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
11
|
-
<link
|
|
12
|
-
rel="stylesheet"
|
|
13
|
-
href="https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&display=swap"
|
|
14
|
-
/>
|
|
15
|
-
<script type="module" crossorigin src="/dashboard/assets/index-
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" data-theme="dark" data-density="6" data-accent="terracotta">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="color-scheme" content="dark light" />
|
|
7
|
+
<meta name="description" content="agent-tempo Maestro Dashboard" />
|
|
8
|
+
<title>agent-tempo · Maestro</title>
|
|
9
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
10
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
11
|
+
<link
|
|
12
|
+
rel="stylesheet"
|
|
13
|
+
href="https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&display=swap"
|
|
14
|
+
/>
|
|
15
|
+
<script type="module" crossorigin src="/dashboard/assets/index-jmYe6rmS.js"></script>
|
|
16
16
|
<link rel="stylesheet" crossorigin href="/dashboard/assets/index-CB78ToNE.css">
|
|
17
|
-
</head>
|
|
18
|
-
<body>
|
|
19
|
-
<div id="root"></div>
|
|
20
|
-
</body>
|
|
21
|
-
</html>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<div id="root"></div>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
package/dashboard/package.json
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "agent-tempo-dashboard",
|
|
3
|
-
"private": true,
|
|
4
|
-
"version": "1.
|
|
5
|
-
"type": "module",
|
|
6
|
-
"description": "Web dashboard for agent-tempo. Bundled into the npm package; served by the daemon at /dashboard/*.",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"dev": "vite",
|
|
9
|
-
"build": "tsc -b && vite build",
|
|
10
|
-
"build:overflow": "tsc -b && vite build --mode overflow",
|
|
11
|
-
"preview": "vite preview",
|
|
12
|
-
"lint": "eslint src/ tests/",
|
|
13
|
-
"test": "vitest run",
|
|
14
|
-
"test:watch": "vitest",
|
|
15
|
-
"test:e2e": "playwright test",
|
|
16
|
-
"test:e2e:install": "playwright install chromium",
|
|
17
|
-
"test:overflow": "playwright test --config tests-overflow/playwright.config.ts"
|
|
18
|
-
},
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"@radix-ui/react-dialog": "~1.1.15",
|
|
21
|
-
"@tanstack/react-query": "5.100.5",
|
|
22
|
-
"react": "19.2.5",
|
|
23
|
-
"react-dom": "19.2.5",
|
|
24
|
-
"react-router-dom": "7.14.2",
|
|
25
|
-
"zustand": "^5.0.0"
|
|
26
|
-
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"@eslint/js": "^9.0.0",
|
|
29
|
-
"@playwright/test": "^1.50.0",
|
|
30
|
-
"@tailwindcss/vite": "4.2.4",
|
|
31
|
-
"@testing-library/dom": "^10.0.0",
|
|
32
|
-
"@testing-library/jest-dom": "^6.6.0",
|
|
33
|
-
"@testing-library/react": "^16.1.0",
|
|
34
|
-
"@types/node": "^22.0.0",
|
|
35
|
-
"@types/react": "^19.2.0",
|
|
36
|
-
"@types/react-dom": "^19.2.0",
|
|
37
|
-
"@typescript-eslint/parser": "^8.0.0",
|
|
38
|
-
"@vitejs/plugin-react": "^5.0.0",
|
|
39
|
-
"eslint": "^9.0.0",
|
|
40
|
-
"eslint-plugin-react-hooks": "^5.1.0",
|
|
41
|
-
"jsdom": "^25.0.0",
|
|
42
|
-
"tailwindcss": "4.2.4",
|
|
43
|
-
"typescript": "^5.7.0",
|
|
44
|
-
"vite": "8.0.10",
|
|
45
|
-
"vitest": "^2.1.9"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-tempo-dashboard",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "1.4.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Web dashboard for agent-tempo. Bundled into the npm package; served by the daemon at /dashboard/*.",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "vite",
|
|
9
|
+
"build": "tsc -b && vite build",
|
|
10
|
+
"build:overflow": "tsc -b && vite build --mode overflow",
|
|
11
|
+
"preview": "vite preview",
|
|
12
|
+
"lint": "eslint src/ tests/",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
15
|
+
"test:e2e": "playwright test",
|
|
16
|
+
"test:e2e:install": "playwright install chromium",
|
|
17
|
+
"test:overflow": "playwright test --config tests-overflow/playwright.config.ts"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@radix-ui/react-dialog": "~1.1.15",
|
|
21
|
+
"@tanstack/react-query": "5.100.5",
|
|
22
|
+
"react": "19.2.5",
|
|
23
|
+
"react-dom": "19.2.5",
|
|
24
|
+
"react-router-dom": "7.14.2",
|
|
25
|
+
"zustand": "^5.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@eslint/js": "^9.0.0",
|
|
29
|
+
"@playwright/test": "^1.50.0",
|
|
30
|
+
"@tailwindcss/vite": "4.2.4",
|
|
31
|
+
"@testing-library/dom": "^10.0.0",
|
|
32
|
+
"@testing-library/jest-dom": "^6.6.0",
|
|
33
|
+
"@testing-library/react": "^16.1.0",
|
|
34
|
+
"@types/node": "^22.0.0",
|
|
35
|
+
"@types/react": "^19.2.0",
|
|
36
|
+
"@types/react-dom": "^19.2.0",
|
|
37
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
38
|
+
"@vitejs/plugin-react": "^5.0.0",
|
|
39
|
+
"eslint": "^9.0.0",
|
|
40
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
41
|
+
"jsdom": "^25.0.0",
|
|
42
|
+
"tailwindcss": "4.2.4",
|
|
43
|
+
"typescript": "^5.7.0",
|
|
44
|
+
"vite": "8.0.10",
|
|
45
|
+
"vitest": "^2.1.9"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -2,6 +2,8 @@ import { Client } from '@temporalio/client';
|
|
|
2
2
|
import { Config } from '../config';
|
|
3
3
|
import { AgentType, MockMode, DetachReason } from '../types';
|
|
4
4
|
import type { ClaudeCodeHeadlessPermissionMode } from '../adapters/claude-code-headless/types';
|
|
5
|
+
import type { IngestTokenRegistry } from '../http/ingest-registry';
|
|
6
|
+
import type { GateRegistry } from '../http/gate-registry';
|
|
5
7
|
import { type HardTerminateInput, type HardTerminateResult } from './hard-terminate';
|
|
6
8
|
export interface DeliverCueInput {
|
|
7
9
|
ensemble: string;
|
|
@@ -76,6 +78,17 @@ export interface DeliverDestroyInput {
|
|
|
76
78
|
terminatedBy: string;
|
|
77
79
|
notifyConductor?: boolean;
|
|
78
80
|
}
|
|
81
|
+
export interface DeliverResetInput {
|
|
82
|
+
ensemble: string;
|
|
83
|
+
targetPlayerId: string;
|
|
84
|
+
/** Correlation id (the originating outbox entry id) — the extension acks with it. */
|
|
85
|
+
resetId: string;
|
|
86
|
+
/** Clean-wipe (D14 default true). */
|
|
87
|
+
fresh: boolean;
|
|
88
|
+
reason?: string;
|
|
89
|
+
/** Who requested the reset (audit). */
|
|
90
|
+
requestedBy?: string;
|
|
91
|
+
}
|
|
79
92
|
export interface DeliverRestartInput {
|
|
80
93
|
ensemble: string;
|
|
81
94
|
targetPlayerId: string;
|
|
@@ -155,6 +168,14 @@ export interface SpawnProcessInput {
|
|
|
155
168
|
* exclusive with {@link permissionMode}.
|
|
156
169
|
*/
|
|
157
170
|
dangerouslySkipPermissions?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Phase 3a / MD-C — headless Pi tool-class policy. Forwarded as
|
|
173
|
+
* `AGENT_TEMPO_TOOL_ACCESS`. Only meaningful when `agent === 'pi'`. One of
|
|
174
|
+
* `'restricted'` (default; Bash hard-blocked) | `'standard'` | `'full'`.
|
|
175
|
+
* Inline literal — kept off the workflow-sandbox import path (see the
|
|
176
|
+
* RecruitOutboxEntry note in src/types.ts).
|
|
177
|
+
*/
|
|
178
|
+
toolAccess?: 'restricted' | 'standard' | 'full';
|
|
158
179
|
}
|
|
159
180
|
export interface OutboxActivityResult {
|
|
160
181
|
success: boolean;
|
|
@@ -174,6 +195,7 @@ export interface OutboxActivities {
|
|
|
174
195
|
deliverDetach(input: DeliverDetachInput): Promise<OutboxActivityResult>;
|
|
175
196
|
deliverDestroy(input: DeliverDestroyInput): Promise<OutboxActivityResult>;
|
|
176
197
|
deliverRestart(input: DeliverRestartInput): Promise<OutboxActivityResult>;
|
|
198
|
+
deliverReset(input: DeliverResetInput): Promise<OutboxActivityResult>;
|
|
177
199
|
/**
|
|
178
200
|
* OS-level child-process-tree kill for the target session. Runs on the per-host
|
|
179
201
|
* task queue (`agent-tempo-{hostname}`) so the kill happens where the process
|
|
@@ -184,5 +206,12 @@ export interface OutboxActivities {
|
|
|
184
206
|
/**
|
|
185
207
|
* Create outbox delivery activities bound to a Temporal client and config.
|
|
186
208
|
* The returned object is registered with the worker as activities.
|
|
209
|
+
*
|
|
210
|
+
* @param ingestTokens 3c Tier-2 ingest-auth registry (daemon-owned singleton,
|
|
211
|
+
* shared with the HTTP `/inner/ingest` + `/inner/presence` validators). The pi
|
|
212
|
+
* spawn branch MINTS a per-player token here (single-token-per-workflowId —
|
|
213
|
+
* re-mint REPLACES, so a restart naturally revokes the stale token); the
|
|
214
|
+
* destroy path REVOKES it. Optional: undefined disables ingest-token minting
|
|
215
|
+
* (e.g. the dev test harness that constructs activities without the daemon).
|
|
187
216
|
*/
|
|
188
|
-
export declare function createOutboxActivities(client: Client, config: Config): OutboxActivities;
|
|
217
|
+
export declare function createOutboxActivities(client: Client, config: Config, ingestTokens?: IngestTokenRegistry, gate?: GateRegistry): OutboxActivities;
|
|
@@ -136,8 +136,15 @@ function classifyAndRethrow(err, contextPrefix) {
|
|
|
136
136
|
/**
|
|
137
137
|
* Create outbox delivery activities bound to a Temporal client and config.
|
|
138
138
|
* The returned object is registered with the worker as activities.
|
|
139
|
+
*
|
|
140
|
+
* @param ingestTokens 3c Tier-2 ingest-auth registry (daemon-owned singleton,
|
|
141
|
+
* shared with the HTTP `/inner/ingest` + `/inner/presence` validators). The pi
|
|
142
|
+
* spawn branch MINTS a per-player token here (single-token-per-workflowId —
|
|
143
|
+
* re-mint REPLACES, so a restart naturally revokes the stale token); the
|
|
144
|
+
* destroy path REVOKES it. Optional: undefined disables ingest-token minting
|
|
145
|
+
* (e.g. the dev test harness that constructs activities without the daemon).
|
|
139
146
|
*/
|
|
140
|
-
function createOutboxActivities(client, config) {
|
|
147
|
+
function createOutboxActivities(client, config, ingestTokens, gate) {
|
|
141
148
|
return {
|
|
142
149
|
async deliverCue(input) {
|
|
143
150
|
const { ensemble, fromPlayerId, targetPlayerId, message, broadcastId, attachmentTicket } = input;
|
|
@@ -247,7 +254,7 @@ function createOutboxActivities(client, config) {
|
|
|
247
254
|
// across CAN. Both adapters use the same `model` metadata field
|
|
248
255
|
// (different value shapes — bare vs `provider/model`) — the spawn
|
|
249
256
|
// path inspects `metadata.agentType` to know which env var to set.
|
|
250
|
-
...((agent === 'claude-api' || agent === 'opencode') && model ? { model } : {}),
|
|
257
|
+
...((agent === 'claude-api' || agent === 'opencode' || agent === 'pi') && model ? { model } : {}),
|
|
251
258
|
...(agentDefinition ? { playerType: agentDefinition } : {}),
|
|
252
259
|
...(agentDefinitionDescription ? { playerTypeDescription: agentDefinitionDescription } : {}),
|
|
253
260
|
recruitedBy: fromPlayerId,
|
|
@@ -305,7 +312,7 @@ function createOutboxActivities(client, config) {
|
|
|
305
312
|
}
|
|
306
313
|
},
|
|
307
314
|
async spawnProcess(input) {
|
|
308
|
-
const { targetName, workDir, isConductor, agent, systemPrompt, ensemble, temporalAddress, temporalNamespace, agentDefinition, agentDefinitionPath, nativeResolvable, resume, sessionId, allowedTools, claudeBin, attachmentId, attachmentRunId, adapterId, mockMode, mockScenario, model, permissionMode, dangerouslySkipPermissions } = input;
|
|
315
|
+
const { targetName, workDir, isConductor, agent, systemPrompt, ensemble, temporalAddress, temporalNamespace, agentDefinition, agentDefinitionPath, nativeResolvable, resume, sessionId, allowedTools, claudeBin, attachmentId, attachmentRunId, adapterId, mockMode, mockScenario, model, permissionMode, dangerouslySkipPermissions, toolAccess } = input;
|
|
309
316
|
// Read secrets from the worker's config closure — never from workflow state
|
|
310
317
|
const { temporalApiKey, temporalTlsCertPath, temporalTlsKeyPath } = config;
|
|
311
318
|
try {
|
|
@@ -436,6 +443,43 @@ function createOutboxActivities(client, config) {
|
|
|
436
443
|
});
|
|
437
444
|
log(`Spawned claude-code-headless adapter (pid ${pid}) in ${workDir} as "${targetName}"${permissionMode ? ` (permissionMode=${permissionMode})` : ''}${dangerouslySkipPermissions ? ' (dangerouslySkipPermissions=true)' : ''}${attachmentId ? ` (attachmentId=${attachmentId})` : ''}`);
|
|
438
445
|
}
|
|
446
|
+
else if (agent === 'pi') {
|
|
447
|
+
// Phase 3a — headless Pi runtime. Injects the src/pi extension into
|
|
448
|
+
// Pi's createAgentSession; the module-scope singleton owns the
|
|
449
|
+
// lifecycle (claim/heartbeat/tools/cue-pump). Tool access is governed
|
|
450
|
+
// by the MD-C `toolAccess` policy (restricted hard-blocks Bash via the
|
|
451
|
+
// extension's tool_call gate), NOT per-tool allowlists.
|
|
452
|
+
if (allowedTools && allowedTools.length > 0) {
|
|
453
|
+
log(`Warning: allowedTools [${allowedTools.join(', ')}] specified for pi agent "${targetName}" — Pi tool access is governed by toolAccess (MD-C), skipping allowedTools`);
|
|
454
|
+
}
|
|
455
|
+
// 3c Tier-2 — mint a per-player ingest token scoped to this player's
|
|
456
|
+
// session workflowId so the headless Pi subprocess can authenticate its
|
|
457
|
+
// `POST /inner/ingest` frames. Single-token-per-workflowId (mint
|
|
458
|
+
// REPLACES) means a restart re-mints and naturally revokes the stale
|
|
459
|
+
// token. Injected into the subprocess env as AGENT_TEMPO_INGEST_TOKEN.
|
|
460
|
+
const ingestToken = ingestTokens?.mint((0, config_1.sessionWorkflowId)(ensemble, targetName));
|
|
461
|
+
const { pid } = (0, spawn_1.spawnPiHeadless)({
|
|
462
|
+
name: targetName,
|
|
463
|
+
ensemble,
|
|
464
|
+
temporalAddress,
|
|
465
|
+
temporalNamespace,
|
|
466
|
+
temporalApiKey,
|
|
467
|
+
temporalTlsCertPath,
|
|
468
|
+
temporalTlsKeyPath,
|
|
469
|
+
isConductor,
|
|
470
|
+
workDir,
|
|
471
|
+
model,
|
|
472
|
+
// Restart-resume: continue the prior Pi conversation only on a
|
|
473
|
+
// restart (resume=true); a fresh recruit starts a new Pi session.
|
|
474
|
+
continueSessionId: resume ? sessionId : undefined,
|
|
475
|
+
toolAccess,
|
|
476
|
+
attachmentId,
|
|
477
|
+
attachmentRunId,
|
|
478
|
+
adapterId,
|
|
479
|
+
ingestToken,
|
|
480
|
+
});
|
|
481
|
+
log(`Spawned pi headless adapter (pid ${pid}) in ${workDir} as "${targetName}" (toolAccess=${toolAccess ?? 'restricted'})${model ? ` (model=${model})` : ''}${resume && sessionId ? ` (continue=${sessionId})` : ''}${attachmentId ? ` (attachmentId=${attachmentId})` : ''}`);
|
|
482
|
+
}
|
|
439
483
|
else {
|
|
440
484
|
// Resolve agent flags: --agent (native) > --system-prompt (shipped/legacy)
|
|
441
485
|
let agentFlags = [];
|
|
@@ -551,6 +595,14 @@ function createOutboxActivities(client, config) {
|
|
|
551
595
|
throw activity_1.ApplicationFailure.nonRetryable(`Cannot detach "${targetPlayerId}" — session is destroyed`);
|
|
552
596
|
}
|
|
553
597
|
await handle.signal(signals_1.requestDetachSignal, { reason, deadlineMs });
|
|
598
|
+
// 3c Tier-2 — revoke the player's ingest token on detach so a dead
|
|
599
|
+
// holder's loopback POST /inner/ingest can no longer authenticate once
|
|
600
|
+
// the player goes away. Mirrors the destroy-side revoke; idempotent and a
|
|
601
|
+
// no-op for non-Pi players (they never minted one). Re-attach re-mints.
|
|
602
|
+
ingestTokens?.revoke((0, config_1.sessionWorkflowId)(ensemble, targetPlayerId));
|
|
603
|
+
// 3d MD-G — auto-disarm the gate on detach (the operator's gate posture
|
|
604
|
+
// shouldn't survive the player going away; re-attach re-arms). Idempotent.
|
|
605
|
+
gate?.clearPlayer((0, config_1.sessionWorkflowId)(ensemble, targetPlayerId));
|
|
554
606
|
log(`Detach signaled for "${targetPlayerId}" (deadline=${deadlineMs}ms)`);
|
|
555
607
|
return { success: true };
|
|
556
608
|
}
|
|
@@ -580,6 +632,21 @@ function createOutboxActivities(client, config) {
|
|
|
580
632
|
}],
|
|
581
633
|
});
|
|
582
634
|
log(`Destroyed "${targetPlayerId}"${reason ? ` (reason: ${reason})` : ''}`);
|
|
635
|
+
// 3c Tier-2 — revoke the player's ingest token on destroy so a dead
|
|
636
|
+
// holder's loopback POST /inner/ingest can no longer authenticate.
|
|
637
|
+
// Idempotent; a no-op for non-Pi players (they never minted one).
|
|
638
|
+
// NOTE (security cond. 2): the ingest endpoint authenticates on TOKEN
|
|
639
|
+
// ALONE — it does not inspect workflow phase (neither rejects nor
|
|
640
|
+
// buffers detached-phase players). So the residual surface is bounded
|
|
641
|
+
// not by phase-checking but by (a) this destroy-revoke and (b) the
|
|
642
|
+
// single-token-per-workflowId replacement on re-attach/restart.
|
|
643
|
+
// TODO(Phase 4): wire aggregate player-gone detection →
|
|
644
|
+
// revokeIngestToken(workflowId) on detach — deferred; residual surface
|
|
645
|
+
// negligible (dead holder + loopback-only + single-token replacement).
|
|
646
|
+
ingestTokens?.revoke((0, config_1.sessionWorkflowId)(ensemble, targetPlayerId));
|
|
647
|
+
// 3d MD-G — auto-disarm: drop the gate's armed-state + any pending
|
|
648
|
+
// requests for the destroyed player (idempotent; no-op for non-Pi).
|
|
649
|
+
gate?.clearPlayer((0, config_1.sessionWorkflowId)(ensemble, targetPlayerId));
|
|
583
650
|
if (notifyConductor) {
|
|
584
651
|
try {
|
|
585
652
|
const condId = (0, config_1.conductorWorkflowId)(ensemble);
|
|
@@ -603,6 +670,32 @@ function createOutboxActivities(client, config) {
|
|
|
603
670
|
classifyAndRethrow(err, `Destroy failed for "${targetPlayerId}"`);
|
|
604
671
|
}
|
|
605
672
|
},
|
|
673
|
+
/**
|
|
674
|
+
* D14 `deliverReset` — set a `pendingReset` flag on the target via
|
|
675
|
+
* `setPendingResetSignal` (a signal, like deliverCue — NOT a direct
|
|
676
|
+
* subprocess call). The Pi extension polls `pendingResetQuery`, performs the
|
|
677
|
+
* clean-wipe (`newSession`), then clears it via `ackResetSignal(resetId)`.
|
|
678
|
+
*/
|
|
679
|
+
async deliverReset(input) {
|
|
680
|
+
const { ensemble, targetPlayerId, resetId, fresh, reason, requestedBy } = input;
|
|
681
|
+
try {
|
|
682
|
+
const handle = await (0, resolve_1.resolveSession)(client, ensemble, targetPlayerId);
|
|
683
|
+
if (!handle) {
|
|
684
|
+
throw activity_1.ApplicationFailure.nonRetryable(`No session found for "${targetPlayerId}"`);
|
|
685
|
+
}
|
|
686
|
+
await handle.signal(signals_1.setPendingResetSignal, {
|
|
687
|
+
resetId,
|
|
688
|
+
fresh,
|
|
689
|
+
...(reason !== undefined ? { reason } : {}),
|
|
690
|
+
...(requestedBy !== undefined ? { requestedBy } : {}),
|
|
691
|
+
});
|
|
692
|
+
log(`Reset queued for "${targetPlayerId}"${reason ? ` (reason: ${reason})` : ''}`);
|
|
693
|
+
return { success: true };
|
|
694
|
+
}
|
|
695
|
+
catch (err) {
|
|
696
|
+
classifyAndRethrow(err, `Reset failed for "${targetPlayerId}"`);
|
|
697
|
+
}
|
|
698
|
+
},
|
|
606
699
|
/**
|
|
607
700
|
* PR-D `deliverRestart` — owns the §8.2 restart algorithm on the target.
|
|
608
701
|
* Graceful `requestDetach` → re-query phase → `forceDetach` (if --force
|
package/dist/adapters/base.js
CHANGED
|
@@ -1264,6 +1264,11 @@ class AdapterRegistry {
|
|
|
1264
1264
|
// Claude Code OAuth login so turns bill against subscription extra-usage.
|
|
1265
1265
|
if (agent === 'claude-code-headless')
|
|
1266
1266
|
return 'claude-code-headless';
|
|
1267
|
+
// Phase 3a — headless Pi runtime. The 'pi' descriptor is registry/identity
|
|
1268
|
+
// ONLY: the module-scope Pi extension singleton owns claim/heartbeat/phase
|
|
1269
|
+
// (no BaseAttachment subprocess driver). Opt-in via `recruit({ agent: 'pi' })`.
|
|
1270
|
+
if (agent === 'pi')
|
|
1271
|
+
return 'pi';
|
|
1267
1272
|
return 'claude-code';
|
|
1268
1273
|
}
|
|
1269
1274
|
}
|
|
@@ -274,6 +274,7 @@ class CopilotSdkAttachment extends base_1.SdkAttachment {
|
|
|
274
274
|
// Spawn Copilot SDK client and session
|
|
275
275
|
const copilotClient = new CopilotClient({
|
|
276
276
|
logLevel: 'debug',
|
|
277
|
+
workingDirectory: workDir,
|
|
277
278
|
env: {
|
|
278
279
|
...cleanEnv(),
|
|
279
280
|
...(process.env.GITHUB_TOKEN ? { GITHUB_TOKEN: process.env.GITHUB_TOKEN } : {}),
|
|
@@ -286,7 +287,6 @@ class CopilotSdkAttachment extends base_1.SdkAttachment {
|
|
|
286
287
|
// All tool calls are auto-approved by design — the bridge operator accepts
|
|
287
288
|
// this when launching the bridge process.
|
|
288
289
|
onPermissionRequest: approveAll,
|
|
289
|
-
workingDirectory: workDir,
|
|
290
290
|
mcpServers: {
|
|
291
291
|
'agent-tempo': {
|
|
292
292
|
command: serverCommand,
|
|
@@ -302,6 +302,17 @@ class CopilotSdkAttachment extends base_1.SdkAttachment {
|
|
|
302
302
|
// `--append-system-prompt` argv. Behavior here is unchanged.
|
|
303
303
|
content: (0, system_prompt_1.buildSdkSystemPrompt)({ ensemble: config.ensemble }),
|
|
304
304
|
},
|
|
305
|
+
hooks: {
|
|
306
|
+
// Auto-allow agent-tempo MCP tools to skip the permission prompt round-trip.
|
|
307
|
+
// This eliminates the permission.requested → handler → approval cycle for
|
|
308
|
+
// every MCP tool call, reducing latency.
|
|
309
|
+
onPreToolUse: async (input) => {
|
|
310
|
+
if (input.toolName?.startsWith('mcp__agent-tempo__')) {
|
|
311
|
+
return { permissionDecision: 'allow' };
|
|
312
|
+
}
|
|
313
|
+
return undefined;
|
|
314
|
+
},
|
|
315
|
+
},
|
|
305
316
|
excludedTools: ['write_powershell', 'read_powershell', 'list_powershell'],
|
|
306
317
|
...(model ? { model } : {}),
|
|
307
318
|
};
|
package/dist/adapters/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare const registry: AdapterRegistry;
|
|
|
31
31
|
* Mock adapter is intentionally excluded — it's dev-mode-only and stripped
|
|
32
32
|
* from the npm tarball at prepack time (ADR 0014 §7 gate 1).
|
|
33
33
|
*/
|
|
34
|
-
export declare const CANONICAL_ADAPTER_IDS: readonly ["claude-code", "copilot", "claude-api", "opencode", "claude-code-headless"];
|
|
34
|
+
export declare const CANONICAL_ADAPTER_IDS: readonly ["claude-code", "copilot", "claude-api", "opencode", "claude-code-headless", "pi"];
|
|
35
35
|
export { BaseAttachment, AdapterRegistry } from './base';
|
|
36
36
|
export { SdkAttachment } from './sdk/base';
|
|
37
37
|
export { InteractiveAttachment } from './claude-code';
|
package/dist/adapters/index.js
CHANGED
|
@@ -24,6 +24,7 @@ const copilot_1 = require("./copilot");
|
|
|
24
24
|
const claude_api_1 = require("./claude-api");
|
|
25
25
|
const opencode_1 = require("./opencode");
|
|
26
26
|
const claude_code_headless_1 = require("./claude-code-headless");
|
|
27
|
+
const pi_1 = require("./pi");
|
|
27
28
|
const config_1 = require("../config");
|
|
28
29
|
exports.registry = new base_1.AdapterRegistry();
|
|
29
30
|
exports.registry.register(claude_code_1.claudeCodeDescriptor);
|
|
@@ -45,6 +46,11 @@ exports.registry.register(opencode_1.opencodeDescriptor);
|
|
|
45
46
|
// `claude` binary is a system binary, not an npm dep; recruit pre-flight
|
|
46
47
|
// probes for installation + login state via `pre-flight.ts`.
|
|
47
48
|
exports.registry.register(claude_code_headless_1.claudeCodeHeadlessDescriptor);
|
|
49
|
+
// Phase 3a — headless Pi runtime. Registry/identity descriptor ONLY: the Pi
|
|
50
|
+
// extension singleton (Phase 2) owns the lifecycle, not a BaseAttachment driver
|
|
51
|
+
// (MD-D). Always-registered — the optional `@earendil-works/pi-coding-agent` SDK
|
|
52
|
+
// only matters at spawn time; recruit pre-flight gates on it (or `force: true`).
|
|
53
|
+
exports.registry.register(pi_1.piDescriptor);
|
|
48
54
|
/**
|
|
49
55
|
* Canonical list of production adapters registered at module-import time.
|
|
50
56
|
*
|
|
@@ -65,6 +71,7 @@ exports.CANONICAL_ADAPTER_IDS = [
|
|
|
65
71
|
'claude-api',
|
|
66
72
|
'opencode',
|
|
67
73
|
'claude-code-headless',
|
|
74
|
+
'pi',
|
|
68
75
|
];
|
|
69
76
|
// ADR 0014 §7 gate 2 — import-time registration gate. The mock adapter's
|
|
70
77
|
// descriptor only enters the registry when `isDevMode()` is true.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.main = main;
|
|
4
|
+
/**
|
|
5
|
+
* Headless Pi adapter entry point (Phase 3a). Spawned as a detached subprocess
|
|
6
|
+
* by `spawnPiHeadless` (src/spawn.ts) on a recruited `agent: 'pi'`. Reads its
|
|
7
|
+
* config from the env the spawn set, then delegates to `runHeadlessPi`, which
|
|
8
|
+
* injects the agent-tempo extension into Pi's `createAgentSession`.
|
|
9
|
+
*
|
|
10
|
+
* Unlike the other headless adapters, there is NO `BaseAttachment` driver here:
|
|
11
|
+
* the module-scope Pi extension singleton (Phase 2) owns claim / heartbeat /
|
|
12
|
+
* phase / tool registration / cue pump (MD-D). This file is purely the process
|
|
13
|
+
* entry + env→options wiring.
|
|
14
|
+
*
|
|
15
|
+
* Dual-purpose: importing this module is inert; only running it as the process
|
|
16
|
+
* entry (`require.main === module`) boots the runtime.
|
|
17
|
+
*/
|
|
18
|
+
const config_1 = require("../../config");
|
|
19
|
+
const headless_1 = require("../../pi/headless");
|
|
20
|
+
const log = (...args) => {
|
|
21
|
+
// eslint-disable-next-line no-console
|
|
22
|
+
console.error('[agent-tempo:pi]', ...args);
|
|
23
|
+
};
|
|
24
|
+
/** Normalize the env tool-access value to the MD-C policy (default 'restricted'). */
|
|
25
|
+
function readToolAccess() {
|
|
26
|
+
const raw = process.env[config_1.ENV.TOOL_ACCESS];
|
|
27
|
+
return raw === 'standard' || raw === 'full' ? raw : 'restricted';
|
|
28
|
+
}
|
|
29
|
+
/** Parse the spawn-provided env into options and run. Exported for testing. */
|
|
30
|
+
async function main() {
|
|
31
|
+
await (0, headless_1.runHeadlessPi)({
|
|
32
|
+
toolAccess: readToolAccess(),
|
|
33
|
+
model: process.env[config_1.ENV.PI_MODEL] || undefined,
|
|
34
|
+
continueSessionId: process.env[config_1.ENV.PI_CONTINUE_SESSION] || undefined,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (require.main === module) {
|
|
38
|
+
main().catch((err) => {
|
|
39
|
+
log('FATAL — headless Pi adapter crashed:', err instanceof Error ? (err.stack ?? err.message) : err);
|
|
40
|
+
// eslint-disable-next-line no-process-exit
|
|
41
|
+
process.exit(1);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi adapter — registry/identity descriptor ONLY (Phase 3a).
|
|
3
|
+
*
|
|
4
|
+
* Unlike the other headless adapters (copilot / opencode / claude-api /
|
|
5
|
+
* claude-code-headless), Pi does NOT have a `BaseAttachment` subprocess driver.
|
|
6
|
+
* The headless Pi runtime injects the Phase 2 `src/pi` EXTENSION into Pi's
|
|
7
|
+
* `createAgentSession` as an inline factory; the module-scope extension singleton
|
|
8
|
+
* owns claim / heartbeat / phase / tool registration / cue pump (MD-D). This
|
|
9
|
+
* descriptor exists purely for adapter identity, registry resolution, spawn
|
|
10
|
+
* routing, and heartbeat-cadence config (MD-A: 30s heartbeat, lease = 3×).
|
|
11
|
+
*
|
|
12
|
+
* Spawn entry: `src/adapters/pi/adapter.ts` (A2) → `src/pi/headless.ts`.
|
|
13
|
+
*/
|
|
14
|
+
import type { AdapterDescriptor } from '../../types';
|
|
15
|
+
/** Pi headless adapter descriptor. `sdk` class (blocks on the LLM turn); 30s heartbeat. */
|
|
16
|
+
export declare const piDescriptor: AdapterDescriptor;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.piDescriptor = void 0;
|
|
4
|
+
/** Pi headless adapter descriptor. `sdk` class (blocks on the LLM turn); 30s heartbeat. */
|
|
5
|
+
exports.piDescriptor = {
|
|
6
|
+
adapterId: 'pi',
|
|
7
|
+
adapterClass: 'sdk',
|
|
8
|
+
blocksOnLLMTurn: true,
|
|
9
|
+
heartbeatMs: 30_000,
|
|
10
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refresh the entrypoint pointer so the global wrapper resolves to the
|
|
3
|
+
* currently-running binary. Called on every successful CLI boot — cheap
|
|
4
|
+
* (one `writeFileSync`) and idempotent.
|
|
5
|
+
*/
|
|
6
|
+
export declare function refreshEntrypoint(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Ensure the wrapper scripts exist. Called once per binary version (guarded
|
|
9
|
+
* by the bootstrap cache). Returns `true` if a PATH hint should be shown
|
|
10
|
+
* to the user (i.e., the bin dir is not yet on PATH).
|
|
11
|
+
*/
|
|
12
|
+
export declare function provisionWrapperScripts(): {
|
|
13
|
+
created: boolean;
|
|
14
|
+
needsPathHint: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Returns a one-liner PATH hint appropriate for the current platform/shell.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getPathHint(): string;
|