pi-superagent 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ADAPTATION.md CHANGED
@@ -1,13 +1,18 @@
1
1
  # Adaptation ledger
2
2
 
3
- The engine in `src/core/` is DeepSeek's, copied from upstream without a single change. This file is the
4
- record that keeps that true: the commit it was copied from, how to prove the copy is exact, and where
5
- everything that is *not* upstream plugs in.
3
+ If you follow a request from GitHub into the code, you’ll cross a boundary at `src/core/`.
4
+ DeepSeek’s dsh-superagent-prototype supplies the rules for opening a ticket, assigning a worker
5
+ and recording the outcome. This project supplies the pieces that talk to GitHub, run pi and keep
6
+ the worker’s terminal open in herdr.
7
+
8
+ That split gives maintainers a place to start. For a question about what a *ready* report means,
9
+ look in the engine. For a question about how that report becomes a GitHub comment, look in
10
+ `src/pi/`. The tables below identify the upstream files and the local code on either side.
6
11
 
7
12
  ## The baseline
8
13
 
9
- Upstream commit `8c32a9dc5d72c033816c6a8110b37f40cf94fba4`, also recorded in
10
- `vendor/dsh-superagent/UPSTREAM_SHA`. At that commit these are byte-identical:
14
+ The files below match upstream commit `8c32a9dc5d72c033816c6a8110b37f40cf94fba4` byte for byte.
15
+ The pinned revision is recorded in `vendor/dsh-superagent/UPSTREAM_SHA`.
11
16
 
12
17
  | Here | Upstream |
13
18
  | --- | --- |
@@ -16,7 +21,7 @@ Upstream commit `8c32a9dc5d72c033816c6a8110b37f40cf94fba4`, also recorded in
16
21
  | `vendor/dsh-superagent/docs/` | `docs/` |
17
22
  | `vendor/dsh-superagent/LICENSE` | `LICENSE` |
18
23
 
19
- To prove it, compare against a fresh clone. Every `diff` should print nothing:
24
+ Run these comparisons from the repository root. Each `diff` exits successfully for an exact match.
20
25
 
21
26
  ```sh
22
27
  git clone https://github.com/deepseek-ai/dsh-superagent-prototype /tmp/upstream
@@ -24,50 +29,43 @@ git -C /tmp/upstream checkout "$(cat vendor/dsh-superagent/UPSTREAM_SHA)"
24
29
  diff -r /tmp/upstream/src/core src/core
25
30
  diff /tmp/upstream/tests/core-engine.spec.ts test/core-engine.spec.ts
26
31
  diff -r /tmp/upstream/docs vendor/dsh-superagent/docs
32
+ diff /tmp/upstream/LICENSE vendor/dsh-superagent/LICENSE
27
33
  ```
28
34
 
29
35
  ## Deviations
30
36
 
31
- None. If one is ever unavoidable, list it here with the file, the upstream commit it was measured
32
- against, what changed and why, so that the next upstream fix can still be merged by hand.
37
+ There are currently no local deviations. Record any future change here with the affected file, upstream
38
+ revision and reason. Maintainers will need that history when they apply the next upstream fix.
33
39
 
34
- ## Where this repository plugs in
40
+ ## Local adapters
35
41
 
36
- The engine is synchronous and does no I/O of its own. Everything that touches a process, the network or
37
- a model reaches it through an interface in `src/core/ports.ts`, and every binding of those interfaces
38
- lives in `src/pi/`:
42
+ The engine is synchronous and does no I/O of its own. The interfaces in `src/core/ports.ts` connect it to storage, processes and
43
+ models. Their implementations live in `src/pi/`.
39
44
 
40
45
  | Port | Bound in | How |
41
46
  | --- | --- | --- |
42
47
  | `Repositories` | `store.ts` | synchronous `node:sqlite` in WAL mode with `synchronous=FULL`, one transaction per engine command |
43
48
  | `Policy` | `router.ts` (`policyOf`) | admits a trigger only from a person who is not on the bot list |
44
- | `SourceScope` | `extension.ts` | every thread is listened to |
49
+ | `SourceScope` | `router.ts` (`scopeOf`) | filters incoming authors by GitHub association or the configured login list |
45
50
  | `Assessor` | `assessor.ts`, `judge.ts` | candidates go one at a time to a headless pi judge, which answers with `ticket_decide` |
46
51
  | `Executor` | `executor.ts`, `herdr-workers.ts` | one pi session per assignment, in its own herdr tab, reached through files that outlive the router |
47
52
  | `Outbox` | `outbox.ts` | GitHub comments, queued once per id and marked sent only once GitHub accepts them |
48
53
 
49
- Sources are not a port upstream; the engine simply receives Triggers. `source-github.ts` produces them
50
- from issues, comments and reviews, with read positions kept in the same SQLite file as the engine's state.
51
-
52
- Upstream ships its own executor, Feishu and GitHub sources, panel and SQLite store. None of them are
53
- vendored: this repository replaces them with pi sessions in herdr, the GitHub source above, the panel in
54
- `server.ts`, and the store in `store.ts`.
55
-
56
- Two of upstream's rules carry through every binding:
54
+ The engine accepts triggers directly. `source-github.ts` converts issues, comments and reviews
55
+ into triggers and saves its read positions in the engine’s SQLite database. Upstream also ships a
56
+ Feishu source, an executor, a panel and a store. This project supplies its own GitHub integration,
57
+ herdr workers, panel (`server.ts`) and storage adapter (`store.ts`).
57
58
 
58
- - **A report is a tool call, not prose.** A worker's `ticket_report` call sets the state of its
59
- assignment; a question in a *blocked* report becomes the ticket's request for a person.
60
- - **Only the engine writes a ticket.** A worker that could edit its own ticket could mark its own work
61
- done.
59
+ Only the engine writes a ticket. The worker submits its assignment outcome through
60
+ `ticket_report`. A *blocked* report carries the question that the router posts for the requester.
62
61
 
63
62
  ## Tests
64
63
 
65
- `test/core-engine.spec.ts` is upstream's engine suite, unchanged. `test/sqlite-engine.spec.ts` runs the
66
- same 113 cases against the SQLite store, with one line changed, because durability can only be tested
67
- against a store that survives the process.
64
+ `test/core-engine.spec.ts` is the upstream engine suite. `test/sqlite-engine.spec.ts` runs the
65
+ same 113 cases against the local SQLite adapter, exercising the same transitions with persistent storage.
68
66
 
69
67
  ## Taking an upstream change
70
68
 
71
- Copy upstream's `src/core/`, `tests/core-engine.spec.ts` and `docs/` over their counterparts here, update
72
- `UPSTREAM_SHA`, and run `npm run check` and `scripts/check-formal`. If a ticket transition changed,
73
- change `formal/Ticket.tla` to match before trusting the result.
69
+ Copy the files listed in the baseline table to their corresponding local paths and update
70
+ `vendor/dsh-superagent/UPSTREAM_SHA`. If a ticket transition changed, update `formal/Ticket.tla`.
71
+ Run `npm run check` and `scripts/check-formal` against the new baseline.
package/README.md CHANGED
@@ -1,67 +1,21 @@
1
1
  # pi-superagent
2
2
 
3
- **Open a GitHub issue. An agent does the work and answers you there.**
4
-
5
- pi-superagent watches one GitHub repository. When someone opens an issue, comments on one, or reviews a
6
- pull request, a judge reads it and decides whether a person has asked for something concrete. If one has,
7
- a ticket opens and a worker starts: a full [pi](https://github.com/earendil-works/pi) session in its own
8
- tab of herdr, a terminal multiplexer for coding agents, where you can watch it work, type into it, or take
9
- over. The worker finishes by calling a report tool, and the result arrives on the issue as a reply. Work
10
- that changes a repository arrives as a pull request, and the ticket stays open until it is merged.
11
-
12
- There are no labels to learn and no board to tend. The issue is the request, a comment is a follow-up,
13
- and closing the issue is the stop.
14
-
15
- The ticket engine underneath is DeepSeek's
16
- [dsh-superagent-prototype](https://github.com/deepseek-ai/dsh-superagent-prototype), vendored
17
- byte-for-byte. This repository binds it to pi, herdr and GitHub.
18
-
19
- ## How a request travels
20
-
21
- 1. **Trigger.** A new issue is a request; so is a comment on an issue or a pull request, and so is a
22
- submitted review. Only people with write access to the repository are heard: on a public repository
23
- anyone can open an issue, and a request starts a worker with a shell on your machine. On its first
24
- look at a repository the router records what is already there and fires none of it.
25
- 2. **Judgement.** The judge, a headless pi session, reads the request with its link and answers through
26
- a tool: *accept*, *ignore* (chatter, a note to a colleague, a thread that already has a ticket) or
27
- *stop*.
28
- 3. **Work.** An accept opens a ticket and posts the judge's acknowledgement on the issue. A worker starts
29
- in a workspace of its own, briefed with the ticket's mandate. Every later comment a person writes on
30
- the thread goes straight to that worker.
31
- 4. **Report.** The worker ends every run by calling `ticket_report`, and the router posts the report on
32
- the issue. A *blocked* report asks you a question there, and your reply goes straight back to the
33
- worker. A run that ends without a report, a worker that crashes, and a launch that fails are posted
34
- too, each with what you can do next. A crashed worker is replaced once, without anyone asking.
35
- 5. **Pull request.** Work that changes a repository, in any repository, goes out as a pull request the
36
- worker opens and names in its report. The ticket then waits for review: comments and reviews on the
37
- pull request go to the same worker. The merge ends the ticket, and the issue hears it is done; closing
38
- the pull request unmerged ends it too. Work that changes no repository, such as an answer, an
39
- investigation or a deployment, ends with its report.
40
-
41
- Closing the issue stops its ticket and says so on the thread. Reopening the issue starts the request again.
42
-
43
- ## Why it is built this way
44
-
45
- pi-superagent grew out of a setup where agents polled markdown cards, prompts were typed into terminal
46
- panes, and a classifier guessed from prose whether a person had answered. Every failure there was the
47
- same defect in a different hat: **state recorded as text, transitions guessed by readers.** Three rules
48
- answer it:
49
-
50
- - **A worker reports through a tool call, never in prose.** "Done" in a chat message changes nothing.
51
- - **Only the engine writes a ticket.** A worker that could edit its own ticket could mark its own work done.
52
- - **A restart loses nothing and repeats nothing.** A read position commits only once the engine holds
53
- what it produced, every trigger carries an id the engine accepts once, and every outgoing message
54
- carries an id the outbox posts once.
55
-
56
- The ticket lifecycle, the GitHub intake and the worker sweep are specified in TLA+ and checked
57
- exhaustively, 1.5 million distinct states in all, by one command.
3
+ Open a GitHub issue and tell pi-superagent what you’d like to change. A coding agent works on it
4
+ in a checkout on your machine and opens a pull request for you to review. If you ask for a
5
+ revision, the same agent picks it up.
6
+
7
+ You can follow the conversation on GitHub or open the agent’s terminal to see what it’s trying
8
+ and lend a hand.
58
9
 
59
10
  ## Install
60
11
 
61
- Use macOS or Linux with Git, Node 22.19 or later, [pi](https://github.com/earendil-works/pi),
62
- [herdr](https://herdr.dev), and the [GitHub CLI](https://cli.github.com).
63
- Sign into a model provider in pi and confirm your model appears in `pi --list-models`.
64
- Use a GitHub account with write access to the repository you want to watch.
12
+ You’ll need Git, Node 22.19 or later, and three tools on a Mac or Linux machine. Pi runs the coding
13
+ sessions. Herdr gives each session a terminal tab. The GitHub CLI (`gh`) lets the agent read issues
14
+ and open pull requests using your account. [pi](https://github.com/earendil-works/pi) ·
15
+ [herdr](https://herdr.dev) · [GitHub CLI](https://cli.github.com)
16
+
17
+ Sign in to a model provider in pi and check that your model appears in `pi --list-models`. Then
18
+ sign in to GitHub with an account that can write to the repository you want to use.
65
19
 
66
20
  ```sh
67
21
  gh auth login
@@ -70,83 +24,76 @@ pi install npm:pi-superagent
70
24
  npm install -g pi-superagent
71
25
  ```
72
26
 
73
- Pi loads the extension in router and worker sessions. The global npm install puts the
74
- `superagent` command on your PATH. Use the same package version for both.
27
+ The first install gives pi the extension. The second gives you the `superagent` command to start,
28
+ stop and check on it. Keep the two at the same version when you update.
75
29
 
76
- ## Run your first ticket
30
+ ## Try it on one issue
77
31
 
78
- Substitute the GitHub repository you want the worker to change. `init` checks the local tools
79
- and your GitHub access, then saves the repository in `~/.pi/superagent/config.env`.
32
+ Choose a repository and open herdr in your terminal.
80
33
 
81
34
  ```sh
82
35
  superagent init your-org/your-repo
83
- herdr # keep it open, then use another terminal
36
+ herdr
37
+ ```
38
+
39
+ Leave herdr open. In a second terminal, start the **router**, the background session that watches
40
+ your repository and sends work to the right agent.
41
+
42
+ ```sh
84
43
  superagent start
85
44
  superagent status
86
45
  ```
87
46
 
88
- Wait for the first GitHub poll in the **engine log** tab, then open a new issue asking for a small
89
- change. The first poll records existing issues as the starting point. Watch for the acknowledgement
90
- on your issue. The worker clones the watched repository into its own directory, switches to a ticket
91
- branch, and posts the pull request on the issue. Request a change on the PR to send it back to the
92
- worker. Merge when you are satisfied.
93
-
94
- To supply your own workspace setup, set `PI_SUPERAGENT_PREPARE`. A replacement worker keeps the same
95
- ticket directory. To narrow who can start work or give the router its own GitHub identity, see
96
- [`config.example.env`](config.example.env). Stop the router with `superagent stop`.
97
-
98
- ## Watching it
99
-
100
- Everything happens in the herdr workspace `superagent`:
101
-
102
- | Tab | What it shows |
103
- | --- | --- |
104
- | `engine log` | the router's log as it happens: every poll, judgement, launch and receipt |
105
- | `engine` | the router itself, a pi session that stays quiet while its loop runs in the background |
106
- | one per ticket | that ticket's worker, live, labelled `#141 · <issue title>` |
107
-
108
- The panel at <http://127.0.0.1:8788/> answers three questions at a glance: does anything need me, what
109
- is running, and what did the judge decide.
110
-
111
- ## Documentation
112
-
113
- | Read | When you want |
114
- | --- | --- |
115
- | [Operator guide](docs/operator-guide.md) | to ask for work, watch it, and fix what goes wrong |
116
- | [Architecture](docs/architecture.md) | the map: what runs, in what order, and which file owns each rule |
117
- | [Design decisions](docs/design-decisions.md) | the reasons, each with the failure that taught it |
118
- | [Formal verification](docs/formal-verification.md) | what the TLA+ specifications prove, and what they do not |
119
- | [Adaptation ledger](ADAPTATION.md) | how the vendored engine is bound, and how to prove it unmodified |
120
-
121
- ## Repository layout
122
-
123
- | Path | What it holds |
124
- | --- | --- |
125
- | `src/core/` | the vendored engine: tickets, evaluations, assignments, the outbox queue |
126
- | `src/pi/extension.ts` | the router: wires the parts together and runs the loop |
127
- | `src/pi/source-github.ts`, `gh-api.ts` | GitHub in: issues, comments and reviews become triggers |
128
- | `src/pi/pulls.ts` | pull requests: bound to their ticket, followed until merged or closed |
129
- | `src/pi/assessor.ts`, `judge.ts` | the judge: one candidate at a time, answered through `ticket_decide` |
130
- | `src/pi/executor.ts`, `herdr-workers.ts` | workers: pi sessions in herdr tabs, and records that outlive the router |
131
- | `src/pi/worker-role.ts`, `report-tool.ts`, `workspace.ts` | inside a worker: the report tool, the guard, the workspace |
132
- | `src/pi/outbox.ts`, `receipts.ts` | GitHub out: what each ending says, each message posted once |
133
- | `src/pi/store.ts` | the engine's SQLite store |
134
- | `src/pi/server.ts` | the panel and its local API |
135
- | `scripts/superagent` | start, stop, restart and status, with exit codes a health check can read |
136
- | `formal/` | the TLA+ specifications |
47
+ In herdr, find the `superagent` workspace and wait for the first GitHub poll in the **engine log**
48
+ tab. That first look records the issues already open. Now open a new issue with a small request.
49
+ For example, “Show the keyboard shortcut next to Export in the Help menu.”
50
+
51
+ When the router accepts the request, it replies on the issue and opens a **ticket**, its record of
52
+ the work. A **worker** is the pi session assigned to that ticket. It gets its own checkout and a
53
+ tab labeled with the issue number. You can type into the tab, though usually a comment on the
54
+ issue is enough. If the worker needs a decision, it asks there.
55
+
56
+ A code change comes back as a pull request. Review the diff as usual. The ticket stays open while
57
+ you discuss the change and ends when you merge or close the PR. You can also ask a question, such
58
+ as where the shortcut is defined. For that, an answer on the issue can finish the job.
59
+
60
+ ## While the worker runs
61
+
62
+ - **On GitHub**, reply on the issue to add a detail, or on the pull request to request a revision.
63
+ To stop work before there’s a PR, close the issue. Reopening it makes a fresh request.
64
+ - **In herdr**, open the tab with the issue number to see the worker’s commands and output. The
65
+ **engine log** tab shows what the router picked up and which requests it accepted.
66
+ - **In the local panel**, look under *Needs a person* to see who’s waiting for an answer. You can
67
+ also see running workers, queued work and recent decisions. [Open the panel](http://127.0.0.1:8788/)
68
+
69
+ By default, the router listens to authors GitHub identifies as owners, organization members or
70
+ collaborators. You can choose particular logins, give the router its own GitHub account, or supply
71
+ a custom workspace setup. Run `superagent stop` when you want to stop the router.
72
+ [Operator guide](docs/operator-guide.md) · [Configuration examples](config.example.env)
73
+
74
+ ## How it works
75
+
76
+ A separate pi session called the **judge** reads a new request and decides whether there’s work to
77
+ do. Once a ticket is open, follow-up comments go straight to its worker. The worker reports the
78
+ outcome through a tool call, which lets the router distinguish a finished run from a question or
79
+ a crash. The router stores the ticket on disk, so after a restart it can find the worker and pick
80
+ up the conversation. [Architecture](docs/architecture.md) · [Design decisions](docs/design-decisions.md)
81
+
82
+ The ticket engine comes from DeepSeek’s dsh-superagent-prototype. Three TLA+ models check how
83
+ tickets, incoming messages and worker tabs behave when events arrive in different orders.
84
+ [Upstream project](https://github.com/deepseek-ai/dsh-superagent-prototype) ·
85
+ [Adaptation ledger](ADAPTATION.md) · [Formal verification](docs/formal-verification.md)
137
86
 
138
87
  ## Development
139
88
 
140
89
  ```sh
141
90
  npm install
142
- npm run check # typecheck and the full suite: no model calls, no network
143
- npm run check:packed # pack, install globally into a temporary prefix, run both halves from there
144
- scripts/check-formal # model-check all three specifications (about five minutes; needs a JDK)
91
+ npm run check # Type-check and run the test suite
92
+ npm run check:packed # Install the tarball and exercise both the CLI and the pi extension
93
+ scripts/check-formal # Check all three models (about five minutes with a JDK)
145
94
  ```
146
95
 
147
- `npm publish` runs the first two first and stops on a failure.
148
-
149
- The suite clears every `PI_SUPERAGENT_*` variable before it runs (`test/setup.ts`), so no test can reach a
150
- live router.
96
+ The test suite clears `PI_SUPERAGENT_*` settings to isolate its router from yours.
97
+ Publishing runs both npm checks before uploading the package.
151
98
 
152
- MIT licensed. The vendored engine is MIT licensed too; see [NOTICE](NOTICE).
99
+ Both projects use the MIT license. [Upstream attribution](NOTICE)