pi-ca-leash 0.10.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/AGENTS.md +77 -0
- package/ARCHITECTURE.md +290 -0
- package/CHANGELOG.md +158 -0
- package/DEVELOPMENT.md +197 -0
- package/KNOWN_LIMITS.md +80 -0
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/extensions/backend-tool-actions.test.ts +59 -0
- package/extensions/backend-tool-actions.ts +31 -0
- package/extensions/command-drivers.test.ts +37 -0
- package/extensions/command-drivers.ts +126 -0
- package/extensions/command-parity.test.ts +560 -0
- package/extensions/command-visibility.test.ts +21 -0
- package/extensions/command-visibility.ts +10 -0
- package/extensions/index.ts +3218 -0
- package/extensions/llm-tools.test.ts +537 -0
- package/extensions/model-catalog.test.ts +34 -0
- package/extensions/model-catalog.ts +173 -0
- package/extensions/peer-history.test.ts +141 -0
- package/extensions/peer-history.ts +90 -0
- package/extensions/peer-naming.test.ts +25 -0
- package/extensions/peer-naming.ts +129 -0
- package/extensions/peer-relay.test.ts +122 -0
- package/extensions/peer-relay.ts +83 -0
- package/extensions/peer-ux.test.ts +239 -0
- package/extensions/peer-ux.ts +327 -0
- package/extensions/persistence.test.ts +68 -0
- package/extensions/persistence.ts +67 -0
- package/extensions/prompts/extension-log-tool.md +5 -0
- package/extensions/prompts/peer-ask-tool.md +5 -0
- package/extensions/prompts/peer-bridge-system.md +4 -0
- package/extensions/prompts/peer-history-tool.md +3 -0
- package/extensions/prompts/peer-init-user-help.md +11 -0
- package/extensions/prompts/peer-init.md +17 -0
- package/extensions/prompts/peer-interrupt-tool.md +2 -0
- package/extensions/prompts/peer-list-tool.md +3 -0
- package/extensions/prompts/peer-no-babysitting.md +6 -0
- package/extensions/prompts/peer-send-tool.md +5 -0
- package/extensions/prompts/peer-start-tool.md +7 -0
- package/extensions/prompts/peer-stop-tool.md +3 -0
- package/extensions/prompts/runtime-models-tool.md +6 -0
- package/extensions/prompts/subagent-list-tool.md +3 -0
- package/extensions/prompts/subagent-run-tool.md +6 -0
- package/extensions/prompts/subagent-status-tool.md +2 -0
- package/extensions/prompts/team-list-tool.md +2 -0
- package/extensions/prompts/team-message-tool.md +2 -0
- package/extensions/prompts/team-spawn-tool.md +5 -0
- package/extensions/prompts/team-stop-tool.md +2 -0
- package/extensions/prompts/team-task-tool.md +3 -0
- package/extensions/prompts.ts +41 -0
- package/extensions/runtime-driver.test.ts +38 -0
- package/extensions/runtime-driver.ts +33 -0
- package/extensions/runtime-safety.test.ts +21 -0
- package/extensions/runtime-safety.ts +49 -0
- package/extensions/support.test.ts +144 -0
- package/extensions/support.ts +205 -0
- package/extensions/tool-inputs.test.ts +45 -0
- package/extensions/tool-inputs.ts +79 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/bridge.d.ts +48 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/bridge.js +406 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/bridge.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/cli.js +18 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/index.d.ts +5 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/index.js +5 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/persistence.d.ts +12 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/persistence.js +31 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/pi-intercom-transport.d.ts +12 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/pi-intercom-transport.js +347 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/pi-intercom-transport.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/types.d.ts +103 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/package.json +32 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/cli.js +26 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/driver-config.d.ts +4 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/driver-config.js +12 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/driver-config.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/claude-sdk.d.ts +8 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/claude-sdk.js +320 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/claude-sdk.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/codex-cli.d.ts +24 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/codex-cli.js +266 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/codex-cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/messages.d.ts +72 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/messages.js +2 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/messages.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/index.d.ts +6 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/index.js +5 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/persistence.d.ts +16 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/persistence.js +94 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/runtime.d.ts +31 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/runtime.js +409 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/runtime.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/types.d.ts +185 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/package.json +32 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/backend.d.ts +34 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/backend.js +327 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/backend.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/cli.js +17 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/index.d.ts +4 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/index.js +4 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/persistence.d.ts +12 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/persistence.js +81 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/types.d.ts +72 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/package.json +32 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/backend.d.ts +27 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/backend.js +194 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/backend.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/cli.js +21 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/index.d.ts +4 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/index.js +4 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/persistence.d.ts +8 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/persistence.js +66 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/types.d.ts +41 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/package.json +33 -0
- package/package.json +98 -0
package/DEVELOPMENT.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
This repository is a local runtime-first MVP. Keep development workflows honest:
|
|
4
|
+
|
|
5
|
+
- automated smoke covers the runtime-backed tool surface only
|
|
6
|
+
- manual smoke covers slash commands, dashboard, widget, and operator UX
|
|
7
|
+
- failing smoke runs are debug artifacts, not release notes
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
You need:
|
|
12
|
+
|
|
13
|
+
- a real `pi` installation
|
|
14
|
+
- working auth/provider setup for whichever runtime driver you use
|
|
15
|
+
- `npm install`
|
|
16
|
+
|
|
17
|
+
## Main commands
|
|
18
|
+
|
|
19
|
+
### Default driver
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm test
|
|
23
|
+
npm run build
|
|
24
|
+
npm run smoke:dev
|
|
25
|
+
npm run smoke:last
|
|
26
|
+
npm run smoke:manual
|
|
27
|
+
npm run smoke:clean
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Codex driver
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm run smoke:dev:codex
|
|
34
|
+
npm run smoke:manual:codex
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Lower-level commands
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run smoke:pi:auto
|
|
41
|
+
npm run smoke:pi:auto:codex
|
|
42
|
+
npm run smoke:pi
|
|
43
|
+
npm run smoke:pi:codex
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Recommended loops
|
|
47
|
+
|
|
48
|
+
### Normal development loop
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm run smoke:dev
|
|
52
|
+
npm run smoke:last
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Use this after meaningful runtime/tool changes.
|
|
56
|
+
|
|
57
|
+
### Manual slash-command follow-up
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm run smoke:manual
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Use this when you changed:
|
|
64
|
+
|
|
65
|
+
- `/peer` command behavior
|
|
66
|
+
- dashboard/widget rendering
|
|
67
|
+
- attention UX
|
|
68
|
+
- startup/operator guidance
|
|
69
|
+
- anything where live interactive feel matters
|
|
70
|
+
|
|
71
|
+
### Codex-specific loop
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm run smoke:dev:codex
|
|
75
|
+
npm run smoke:manual:codex
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Use this when changing driver threading or Codex-specific behavior.
|
|
79
|
+
|
|
80
|
+
## What the automated smoke actually tests
|
|
81
|
+
|
|
82
|
+
`npm run smoke:pi:auto` starts `pi` in JSON mode from this checkout with:
|
|
83
|
+
|
|
84
|
+
- `--no-extensions -e <repo-root>`
|
|
85
|
+
- no builtin tools
|
|
86
|
+
- no context files, skills, prompts, or themes
|
|
87
|
+
|
|
88
|
+
The prompt is fixed and runtime-only. It exercises:
|
|
89
|
+
|
|
90
|
+
- `peer_start`
|
|
91
|
+
- `peer_list`
|
|
92
|
+
- `peer_ask`
|
|
93
|
+
- `peer_history`
|
|
94
|
+
- `peer_stop`
|
|
95
|
+
- `subagent_run`
|
|
96
|
+
- `subagent_list`
|
|
97
|
+
- `subagent_status`
|
|
98
|
+
- `team_spawn`
|
|
99
|
+
- `team_list`
|
|
100
|
+
- `team_task`
|
|
101
|
+
- `team_message`
|
|
102
|
+
- `team_stop`
|
|
103
|
+
|
|
104
|
+
It does **not** try to validate:
|
|
105
|
+
|
|
106
|
+
- dashboard or widget rendering
|
|
107
|
+
- slash-command UX quality
|
|
108
|
+
- manual operator ergonomics
|
|
109
|
+
- broader TUI behavior
|
|
110
|
+
|
|
111
|
+
## Automated smoke artifacts
|
|
112
|
+
|
|
113
|
+
Each automated run writes artifacts under:
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
.pi-ca-leash/smoke/auto/<timestamp-id>/
|
|
117
|
+
prompt.md
|
|
118
|
+
report.md
|
|
119
|
+
events.jsonl
|
|
120
|
+
stderr.log
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
And also refreshes:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
.pi-ca-leash/smoke/auto/latest.md
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### How to read them
|
|
130
|
+
|
|
131
|
+
- `report.md` — human summary and pass/fail result
|
|
132
|
+
- `events.jsonl` — exact event timeline from pi JSON mode
|
|
133
|
+
- `stderr.log` — runtime/host stderr
|
|
134
|
+
- `prompt.md` — exact prompt used for that run
|
|
135
|
+
|
|
136
|
+
## Debugging with smoke artifacts
|
|
137
|
+
|
|
138
|
+
When `smoke:dev` or `smoke:pi:auto` fails:
|
|
139
|
+
|
|
140
|
+
1. read `npm run smoke:last`
|
|
141
|
+
2. inspect the matching run directory
|
|
142
|
+
3. check which tool step failed
|
|
143
|
+
4. inspect `events.jsonl` for sequencing or tool-result details
|
|
144
|
+
5. inspect `stderr.log` for host/runtime issues
|
|
145
|
+
6. fix the bug
|
|
146
|
+
7. rerun the smoke
|
|
147
|
+
8. add or adjust a focused test when the bug deserves permanent coverage
|
|
148
|
+
|
|
149
|
+
Good use of saved runs:
|
|
150
|
+
|
|
151
|
+
- keep interesting failing runs while debugging
|
|
152
|
+
- compare runs before/after behavior changes
|
|
153
|
+
- keep maybe one passing run during a release pass
|
|
154
|
+
|
|
155
|
+
Bad use:
|
|
156
|
+
|
|
157
|
+
- committing raw smoke artifacts
|
|
158
|
+
- treating broad smoke logs as a replacement for tests
|
|
159
|
+
|
|
160
|
+
## Cleanup
|
|
161
|
+
|
|
162
|
+
Remove saved automated smoke artifacts with:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npm run smoke:clean
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The whole `.pi-ca-leash/` tree is already git-ignored.
|
|
169
|
+
|
|
170
|
+
## Manual smoke checklist
|
|
171
|
+
|
|
172
|
+
Use this before claiming the repo is ready to share:
|
|
173
|
+
|
|
174
|
+
1. `npm test`
|
|
175
|
+
2. `npm run build`
|
|
176
|
+
3. `npm run smoke:dev`
|
|
177
|
+
4. `npm run smoke:manual`
|
|
178
|
+
5. in pi, run `/peer`, `/peer start`, `/peer ask`, `/peer list`, `/peer stop`
|
|
179
|
+
6. run `/peer dashboard advanced`
|
|
180
|
+
7. confirm retained backend diagnostics are believable
|
|
181
|
+
8. when explicitly testing installed-package behavior rather than local `-e` loading, restart pi and confirm persisted peers/backends restore honestly
|
|
182
|
+
|
|
183
|
+
## Notes on persistence during development
|
|
184
|
+
|
|
185
|
+
Repository-local runtime state lives under:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
.pi-ca-leash/
|
|
189
|
+
runtime/
|
|
190
|
+
bridge/
|
|
191
|
+
subagents/
|
|
192
|
+
teams/
|
|
193
|
+
extension/
|
|
194
|
+
smoke/
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Delete or move `.pi-ca-leash/` when you need a truly clean local state.
|
package/KNOWN_LIMITS.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Known Limits
|
|
2
|
+
|
|
3
|
+
This file is intentionally blunt.
|
|
4
|
+
|
|
5
|
+
## Product/integration limits
|
|
6
|
+
|
|
7
|
+
1. **No real upstream `pi-subagents` integration is proven here.**
|
|
8
|
+
- This repo contains local backend logic and extension wiring.
|
|
9
|
+
- It should not be described as shipped upstream integration unless that is separately verified.
|
|
10
|
+
|
|
11
|
+
2. **No external `pi-teams` integration exists here.**
|
|
12
|
+
- Teams backend is local to this repository.
|
|
13
|
+
- Do not imply compatibility with a package/product that is not actually present.
|
|
14
|
+
|
|
15
|
+
3. **Claude fork semantics are not supported.**
|
|
16
|
+
- `runner=claude-code-agent` rejects real `fork`.
|
|
17
|
+
- Better an explicit error than a fake branch illusion.
|
|
18
|
+
|
|
19
|
+
4. **Codex support is partial and still not parity-complete.**
|
|
20
|
+
- Runtime has an experimental `codex-cli` driver.
|
|
21
|
+
- Bridge peers can carry driver identity, including `driver: "codex-cli"`.
|
|
22
|
+
- Extension startup can select Codex as the default driver for new peers via `PI_CLAUDE_RUNTIME_DRIVER=codex-cli`.
|
|
23
|
+
- Per-peer driver override exists on the LLM-callable `peer_start` tool.
|
|
24
|
+
- Public `/peer start` slash-command docs can thread driver and model selection, but treat Codex selection as experimental.
|
|
25
|
+
- Subagents and teams backend APIs, demo CLIs, and LLM-callable tools can thread driver selection, but public slash-command UX still does not expose subagent/team driver selection.
|
|
26
|
+
- The bundled model catalog is advisory and generated from Lanista snapshots; it does not prove that the local CLI or account can use every listed model.
|
|
27
|
+
- Workspace tests do not require a real `codex` binary, but local smoke validation can use a real one.
|
|
28
|
+
- Context-window percentage is currently Claude SDK-derived only; Codex-backed peers show no `ctx` value unless a trustworthy context window can be derived later.
|
|
29
|
+
- Codex effective default model can be shown from the bundled catalog, but the runtime still trusts the Codex CLI for actual model resolution.
|
|
30
|
+
|
|
31
|
+
## Runtime/host limits
|
|
32
|
+
|
|
33
|
+
5. **Full extension-host smoke coverage is still environment-dependent.**
|
|
34
|
+
- Workspace/package tests pass.
|
|
35
|
+
- Extension helper/state logic is tested directly.
|
|
36
|
+
- Real pi-host loading still depends on an actual pi installation and host runtime.
|
|
37
|
+
|
|
38
|
+
6. **Live intercom broker transport is optional.**
|
|
39
|
+
- If the broker is unreachable, local runtime-backed peers still work.
|
|
40
|
+
- Live presence/messaging through the broker is unavailable until reconnect.
|
|
41
|
+
- The extension now waits until `/peer init`, another actionable `/peer` command, or an LLM-callable runtime tool before starting background broker checks.
|
|
42
|
+
|
|
43
|
+
7. **Cross-process resurrection is partial, not magical.**
|
|
44
|
+
- Persisted state survives.
|
|
45
|
+
- In-flight control of an already-running host-local process does not fully survive arbitrary host loss.
|
|
46
|
+
|
|
47
|
+
## UX/coordination limits
|
|
48
|
+
|
|
49
|
+
8. **Attention ack/snooze is local extension state.**
|
|
50
|
+
- It is persisted across pi restarts in this repo.
|
|
51
|
+
- It is not a shared multi-host or cross-session control protocol.
|
|
52
|
+
|
|
53
|
+
9. **Teams workflow is intentionally simple.**
|
|
54
|
+
- Task classification is heuristic (`DONE:` / `BLOCKED:` style replies).
|
|
55
|
+
- There is no rich board UI, inbox app, or broader collaboration product layer.
|
|
56
|
+
|
|
57
|
+
10. **Busy handling is strict.**
|
|
58
|
+
- A busy peer can reject concurrent inbound work instead of queueing it.
|
|
59
|
+
- There is no sophisticated queueing/scheduling layer yet.
|
|
60
|
+
|
|
61
|
+
11. **Peer auto-naming is heuristic.**
|
|
62
|
+
- Default `/peer start <prompt>` derives a short readable name from prompt text.
|
|
63
|
+
- Use `/peer start <name> | <prompt>` when you need an exact stable name.
|
|
64
|
+
|
|
65
|
+
12. **Peer working directory is fixed at start time.**
|
|
66
|
+
- Peer tools can choose `cwd` when starting a peer.
|
|
67
|
+
- Changing `cwd` later requires starting a new peer session.
|
|
68
|
+
|
|
69
|
+
13. **Default peer UX is intentionally compressed.**
|
|
70
|
+
- The main window does not stream live peer transcript output.
|
|
71
|
+
- Peer completion is relayed back as one wrapped follow-up turn instead of live transcript spam.
|
|
72
|
+
- Detailed retained backend diagnostics live in `/peer dashboard advanced`.
|
|
73
|
+
- Legacy `/claude-*` slash commands stay hidden unless you start pi with `PI_CA_LEASH_ENABLE_LEGACY_COMMANDS=1`.
|
|
74
|
+
- Old internal diagnostic slash commands also require `PI_CLAUDE_ENABLE_ADVANCED_COMMANDS=1`.
|
|
75
|
+
|
|
76
|
+
## Documentation limits
|
|
77
|
+
|
|
78
|
+
14. **This repo is documented as a local MVP, not a final product.**
|
|
79
|
+
- If the implementation grows, docs must stay equally honest.
|
|
80
|
+
- Remove stale claims rather than letting optimistic historical docs linger.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 durandom
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# pi-ca-leash
|
|
2
|
+
|
|
3
|
+
Harness-aware Claude Code and Codex CLI extension for pi.
|
|
4
|
+
|
|
5
|
+
Claude Code and Codex CLI are more than model endpoints. They are coding harnesses with their own tool loops, session semantics, and increasingly harness-optimized models. `pi-ca-leash` treats them that way.
|
|
6
|
+
|
|
7
|
+
Pi stays in the brain seat — like a human coordinating multiple coding agents. It can start long-lived workers, hand them scoped tasks, wait for results, inspect what they did, and decide what happens next.
|
|
8
|
+
|
|
9
|
+
Claude is the default and most complete path today. Codex works too, but is still experimental and not parity-complete.
|
|
10
|
+
|
|
11
|
+
## What it adds
|
|
12
|
+
|
|
13
|
+
After installation, pi gets:
|
|
14
|
+
- named long-lived peers with `/peer start`, `/peer ask`, `/peer send`, `/peer history`, and `/peer stop`
|
|
15
|
+
- a peer dashboard plus local attention state
|
|
16
|
+
- LLM-callable peer tools such as `peer_start`, `peer_ask`, `peer_send`, `peer_history`, and `runtime_models`
|
|
17
|
+
- optional local subagent-style runs and local persistent teammates behind advanced commands/tools
|
|
18
|
+
- optional live intercom transport when the broker is reachable
|
|
19
|
+
|
|
20
|
+
What this package does **not** claim:
|
|
21
|
+
- no real upstream `pi-subagents` integration
|
|
22
|
+
- no external `pi-teams` integration
|
|
23
|
+
- no real Claude fork/session-tree semantics
|
|
24
|
+
- no host-independent full pi extension smoke test
|
|
25
|
+
|
|
26
|
+
## Example session
|
|
27
|
+
|
|
28
|
+
Fictional but representative flow:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
You: /peer dashboard
|
|
32
|
+
|
|
33
|
+
You: Start a planner peer to understand the auth flow and propose the safest implementation plan.
|
|
34
|
+
|
|
35
|
+
You: Start an implementer peer too, but keep it waiting for my approved plan before editing anything.
|
|
36
|
+
|
|
37
|
+
Pi/main agent:
|
|
38
|
+
- uses peer tools to start both workers
|
|
39
|
+
- keeps control of the conversation
|
|
40
|
+
- receives planner output automatically when it is ready
|
|
41
|
+
- decides what plan to approve
|
|
42
|
+
|
|
43
|
+
Sample peer state:
|
|
44
|
+
- planner idle summarized auth flow and proposed scoped plan
|
|
45
|
+
- implementer waiting ready for approved implementation handoff
|
|
46
|
+
|
|
47
|
+
You: Send the approved plan to the implementer. Keep changes scoped. Report files changed, commands run, tests, and residual risk.
|
|
48
|
+
|
|
49
|
+
Pi/main agent:
|
|
50
|
+
- inspects the implementer result
|
|
51
|
+
- asks follow-up questions if needed
|
|
52
|
+
- gives the final answer to the user
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
That is core idea: pi is not replaced by child agents. Pi orchestrates them.
|
|
56
|
+
|
|
57
|
+
Once peer mode is active, you can often ask for this in natural language instead of manually driving every peer command.
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
For most users, if pi already works on your machine and `pi install` works, you do not need to think about Node directly. `pi install npm:pi-ca-leash` is usually enough.
|
|
62
|
+
|
|
63
|
+
Requirements for normal use:
|
|
64
|
+
- a working pi installation
|
|
65
|
+
- at least one configured runtime:
|
|
66
|
+
- Claude Code configured for Claude-backed execution, or
|
|
67
|
+
- `codex` on `PATH` for experimental Codex-backed runtime checks
|
|
68
|
+
|
|
69
|
+
Requirements for local development or source installs:
|
|
70
|
+
- Node.js 18 or newer
|
|
71
|
+
- npm
|
|
72
|
+
|
|
73
|
+
Install from npm:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pi install npm:pi-ca-leash
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Pin an explicit version when needed:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pi install npm:pi-ca-leash@0.10.0
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Install from a pinned git release:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pi install git:github.com/durandom/pi-ca-leash@v0.10.0
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Try this checkout locally:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npm install
|
|
95
|
+
npm test
|
|
96
|
+
npm run build
|
|
97
|
+
pi install /absolute/path/to/pi-ca-leash
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`npm install` runs the workspace build through `prepare`, so local development and git-based installs have package `dist/` files available.
|
|
101
|
+
|
|
102
|
+
Use Codex as the default runtime driver for newly started peers:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
PI_CLAUDE_RUNTIME_DRIVER=codex-cli pi
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Persisted peers keep their recorded driver.
|
|
109
|
+
|
|
110
|
+
## Try this first
|
|
111
|
+
|
|
112
|
+
Inside pi:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
/peer about
|
|
116
|
+
/peer init
|
|
117
|
+
/peer start reviewer | Review this repo briefly and report one concrete risk.
|
|
118
|
+
# keep working or wait; completion relays automatically
|
|
119
|
+
/peer ask reviewer | Reply with exactly: peer-ok
|
|
120
|
+
/peer dashboard advanced
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
If you want Codex-backed peers, inspect the bundled Codex catalog first:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
/peer models codex-cli
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## How it works
|
|
130
|
+
|
|
131
|
+
After peer mode is active, the main agent can use the peer tools directly, and you can usually steer it in plain language.
|
|
132
|
+
|
|
133
|
+
Mental model:
|
|
134
|
+
- the main agent stays in charge; peers are delegated workers, not replacements for the orchestrator
|
|
135
|
+
- peers are long-lived sessions, so follow-up messages continue the same worker instead of starting from scratch
|
|
136
|
+
- most peers work in the same repository checkout; prefer short prompts plus file-based handoffs over pasting large context
|
|
137
|
+
- start bounded peer jobs, keep working in the main turn, and wait for the automatic completion/block/failure relay
|
|
138
|
+
- use `ask` when you need a reply now, `send` for fire-and-forget follow-up work, and `history` only when you need to scroll back for evidence
|
|
139
|
+
- do not babysit peers with repeated status polling
|
|
140
|
+
|
|
141
|
+
Primary slash-command surface:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
/peer
|
|
145
|
+
/peer help
|
|
146
|
+
/peer about
|
|
147
|
+
/peer init
|
|
148
|
+
/peer dashboard
|
|
149
|
+
/peer dashboard advanced
|
|
150
|
+
/peer start <prompt>
|
|
151
|
+
/peer start <prompt> | <driver> | <model>
|
|
152
|
+
/peer start <name> | <prompt>
|
|
153
|
+
/peer start <name> | <prompt> | <driver> | <model>
|
|
154
|
+
/peer ask <name> | <message>
|
|
155
|
+
/peer send <name> | <message>
|
|
156
|
+
/peer list
|
|
157
|
+
/peer models [claude-sdk|codex-cli] [all|advanced|verbose]
|
|
158
|
+
/peer history <name> [cursor] [limit]
|
|
159
|
+
/peer interrupt <name>
|
|
160
|
+
/peer stop <name>
|
|
161
|
+
/peer stop --all --confirm
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
LLM-callable tools:
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
runtime_models(driver?, verbose?)
|
|
168
|
+
extension_log(category?, severity?, summary, observed?, expected?, reproduction?, suggestedFix?, relatedCommand?, relatedTool?, files?)
|
|
169
|
+
peer_start(prompt, name?, driver?, model?, cwd?)
|
|
170
|
+
peer_list()
|
|
171
|
+
peer_history(name, cursor?, limit?)
|
|
172
|
+
peer_ask(name, message, model?)
|
|
173
|
+
peer_send(name, message, model?)
|
|
174
|
+
peer_interrupt(name)
|
|
175
|
+
peer_stop(name?, all?, confirmAll?)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Advanced LLM-callable backend tools are hidden by default while their integration model is still being refined. Enable them only for development with `PI_CLAUDE_ENABLE_ADVANCED_COMMANDS=1`:
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
subagent_run(task, name?, prompt?, driver?, model?, cwd?, async?)
|
|
182
|
+
subagent_list()
|
|
183
|
+
subagent_status(runId)
|
|
184
|
+
team_spawn(name, prompt, driver?, model?, cwd?)
|
|
185
|
+
team_task(name, title, details)
|
|
186
|
+
team_message(name, message)
|
|
187
|
+
team_list()
|
|
188
|
+
team_stop(name)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Legacy `/claude-*` commands are hidden by default. Re-enable old peer commands only for compatibility:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
PI_CA_LEASH_ENABLE_LEGACY_COMMANDS=1 pi
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Re-enable old internal diagnostics for development:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
PI_CA_LEASH_ENABLE_LEGACY_COMMANDS=1 PI_CLAUDE_ENABLE_ADVANCED_COMMANDS=1 pi
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Behavior
|
|
204
|
+
|
|
205
|
+
The extension is lazy. Loading it registers commands and tools, but it does not start the Peers widget, background monitor, or intercom transport checks immediately. `/peer` with no args opens the dashboard and activates peer mode. `/peer init` also activates the peer workflow, adds the one-time orchestration guide to the main agent context, and shows the user a compact command cheat sheet as a user-only UI notification. The first actionable `/peer` command, such as `/peer models`, `/peer dashboard`, `/peer list`, or `/peer start`, also activates it and adds that agent guide once. `/peer help` and `/peer about` stay passive and show user-only UI notifications. `/peer about` reports the installed package version, package root, state root, default driver, and session mode.
|
|
206
|
+
|
|
207
|
+
Peers are asynchronous workers. The main agent should start a peer, continue useful work, and wait for the automatic peer completion, blocked, or failure relay. It should not poll `peer_list`, `peer_history`, or repeated `peer_ask` just to see whether the peer is done. When a peer returns, the main agent still owns verification, synthesis, and the final answer.
|
|
208
|
+
|
|
209
|
+
The extension keeps peer output quiet by default:
|
|
210
|
+
- peer work does not stream child transcript spam into the main window
|
|
211
|
+
- peer command acknowledgments and reports are user-only UI notifications, not main-agent context
|
|
212
|
+
- peer completion is relayed back as one wrapped follow-up turn with the latest visible peer message
|
|
213
|
+
- detailed backend diagnostics live in `/peer dashboard advanced`
|
|
214
|
+
|
|
215
|
+
Runtime driver notes:
|
|
216
|
+
- `claude-sdk` is the default and most complete path
|
|
217
|
+
- `codex-cli` is supported, but still experimental and not parity-complete
|
|
218
|
+
- `PI_CLAUDE_RUNTIME_DRIVER=codex-cli` changes the default for newly started peers
|
|
219
|
+
- `/peer models` and LLM-callable `runtime_models` show a short recommended model list by default, including advisory use cases
|
|
220
|
+
- `/peer models ... all` and `runtime_models(verbose: true)` expose the full bundled Lanista-derived model catalog
|
|
221
|
+
- LLM-callable `peer_start`, `peer_ask`, and `peer_send` can pass explicit model ids
|
|
222
|
+
- `/peer start` can pass driver and model in pipe syntax
|
|
223
|
+
- common catalog aliases such as `sonnet`, `opus`, `haiku`, `mini`, and `spark` are resolved to exact model ids before runtime launch
|
|
224
|
+
- catalog validation is advisory; unknown model ids are still passed through to the runtime because provider and CLI availability is environment-dependent
|
|
225
|
+
|
|
226
|
+
## Repository Layout
|
|
227
|
+
|
|
228
|
+
```text
|
|
229
|
+
packages/
|
|
230
|
+
runtime/ Claude/Codex runtime abstraction
|
|
231
|
+
intercom-bridge/ named runtime-backed peers
|
|
232
|
+
subagents-backend/ local subagent-style run backend
|
|
233
|
+
teams-backend/ local persistent teammate backend
|
|
234
|
+
extensions/
|
|
235
|
+
index.ts pi extension wiring and command/tool surface
|
|
236
|
+
prompts/ editable operator, tool, peer, and agent guidance text
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Useful docs that should remain current:
|
|
240
|
+
- `ARCHITECTURE.md`
|
|
241
|
+
- `KNOWN_LIMITS.md`
|
|
242
|
+
- `CHANGELOG.md`
|
|
243
|
+
- `DEVELOPMENT.md`
|
|
244
|
+
- `AGENTS.md`
|
|
245
|
+
|
|
246
|
+
## Development
|
|
247
|
+
|
|
248
|
+
Start here:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
npm test
|
|
252
|
+
npm run build
|
|
253
|
+
npm run smoke:dev
|
|
254
|
+
npm run smoke:last
|
|
255
|
+
npm run smoke:manual
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
For the full developer workflow, smoke-command reference, artifact/debugging guide, and manual release checklist, see [`DEVELOPMENT.md`](./DEVELOPMENT.md).
|
|
259
|
+
|
|
260
|
+
## Persistence
|
|
261
|
+
|
|
262
|
+
Repository-local runtime state is written under:
|
|
263
|
+
|
|
264
|
+
```text
|
|
265
|
+
.pi-ca-leash/
|
|
266
|
+
runtime/
|
|
267
|
+
bridge/
|
|
268
|
+
subagents/
|
|
269
|
+
teams/
|
|
270
|
+
extension/
|
|
271
|
+
log.md
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
These paths are ignored by git. `log.md` is an append-only local feedback log for extension UX rough edges, confusing guidance, poor defaults, and repeated interaction problems. Remove `.pi-ca-leash/` when you need a clean local manual-test session.
|
|
275
|
+
|
|
276
|
+
Older local development state may also exist under ignored paths such as `.pi-claude-code-agent/`, `.claude-runtime/`, or `undefined/`. Those are not part of the package.
|
|
277
|
+
|
|
278
|
+
## Limits
|
|
279
|
+
|
|
280
|
+
The short version:
|
|
281
|
+
- full extension-host smoke testing still needs a real pi installation
|
|
282
|
+
- live intercom broker transport is optional
|
|
283
|
+
- Codex support is partial
|
|
284
|
+
- `runner=claude-code-agent` rejects real `fork`
|
|
285
|
+
- teams backend is local-only
|
|
286
|
+
- attention ack/snooze is local extension state
|
|
287
|
+
|
|
288
|
+
See `KNOWN_LIMITS.md` for the detailed version.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { buildSubagentRunRequest, buildTeamSpawnRequest } from "./backend-tool-actions.ts";
|
|
4
|
+
|
|
5
|
+
test("buildSubagentRunRequest threads driver, model, async, and cwd", () => {
|
|
6
|
+
assert.deepEqual(buildSubagentRunRequest({
|
|
7
|
+
task: "do work",
|
|
8
|
+
name: "worker",
|
|
9
|
+
prompt: "be brief",
|
|
10
|
+
driver: "claude-sdk",
|
|
11
|
+
model: "o4-mini",
|
|
12
|
+
cwd: "/tmp/run",
|
|
13
|
+
async: true,
|
|
14
|
+
}, "/base"), {
|
|
15
|
+
agent: {
|
|
16
|
+
name: "worker",
|
|
17
|
+
runner: "claude-code-agent",
|
|
18
|
+
prompt: "be brief",
|
|
19
|
+
cwd: "/tmp/run",
|
|
20
|
+
model: "o4-mini",
|
|
21
|
+
},
|
|
22
|
+
task: "do work",
|
|
23
|
+
driver: "claude-sdk",
|
|
24
|
+
cwd: "/tmp/run",
|
|
25
|
+
model: "o4-mini",
|
|
26
|
+
async: true,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("buildSubagentRunRequest falls back to base cwd", () => {
|
|
31
|
+
const request = buildSubagentRunRequest({
|
|
32
|
+
task: "do work",
|
|
33
|
+
name: "worker",
|
|
34
|
+
prompt: "be brief",
|
|
35
|
+
driver: "codex-cli",
|
|
36
|
+
model: undefined,
|
|
37
|
+
cwd: undefined,
|
|
38
|
+
async: false,
|
|
39
|
+
}, "/base");
|
|
40
|
+
assert.equal(request.driver, "codex-cli");
|
|
41
|
+
assert.equal(request.cwd, "/base");
|
|
42
|
+
assert.equal(request.agent.cwd, "/base");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("buildTeamSpawnRequest threads driver and falls back to base cwd", () => {
|
|
46
|
+
assert.deepEqual(buildTeamSpawnRequest({
|
|
47
|
+
name: "teammate",
|
|
48
|
+
prompt: "hello",
|
|
49
|
+
driver: "codex-cli",
|
|
50
|
+
model: "o4-mini",
|
|
51
|
+
cwd: undefined,
|
|
52
|
+
}, "/base"), {
|
|
53
|
+
name: "teammate",
|
|
54
|
+
prompt: "hello",
|
|
55
|
+
driver: "codex-cli",
|
|
56
|
+
model: "o4-mini",
|
|
57
|
+
cwd: "/base",
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { StartRunInput } from "@pi-claude-code-agent/subagents-backend";
|
|
2
|
+
import type { SpawnTeammateInput } from "@pi-claude-code-agent/teams-backend";
|
|
3
|
+
import type { ParsedSubagentRunToolInput, ParsedTeamSpawnToolInput } from "./tool-inputs.js";
|
|
4
|
+
|
|
5
|
+
export function buildSubagentRunRequest(input: ParsedSubagentRunToolInput, baseCwd: string): StartRunInput {
|
|
6
|
+
const cwd = input.cwd ?? baseCwd;
|
|
7
|
+
return {
|
|
8
|
+
agent: {
|
|
9
|
+
name: input.name,
|
|
10
|
+
runner: "claude-code-agent",
|
|
11
|
+
prompt: input.prompt,
|
|
12
|
+
cwd,
|
|
13
|
+
model: input.model,
|
|
14
|
+
},
|
|
15
|
+
task: input.task,
|
|
16
|
+
driver: input.driver,
|
|
17
|
+
cwd,
|
|
18
|
+
model: input.model,
|
|
19
|
+
async: input.async,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function buildTeamSpawnRequest(input: ParsedTeamSpawnToolInput, baseCwd: string): SpawnTeammateInput {
|
|
24
|
+
return {
|
|
25
|
+
name: input.name,
|
|
26
|
+
prompt: input.prompt,
|
|
27
|
+
driver: input.driver,
|
|
28
|
+
model: input.model,
|
|
29
|
+
cwd: input.cwd ?? baseCwd,
|
|
30
|
+
};
|
|
31
|
+
}
|