@sjawhar/pi-envoy 8.4.0 → 8.6.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/README.md +38 -31
- package/bin/dispatch +6 -0
- package/dist/dispatch.js +18648 -0
- package/dist/envoy.js +580 -2656
- package/dist/skills/dispatch/SKILL.md +85 -97
- package/dist/skills/dispatch/references/api.md +4 -4
- package/dist/skills/dispatch/references/asks.md +34 -54
- package/dist/skills/dispatch/references/document-edits.md +24 -21
- package/dist/skills/dispatch/references/documents.md +75 -72
- package/dist/skills/dispatch/references/examples.md +37 -67
- package/dist/skills/dispatch/references/issues.md +48 -48
- package/dist/skills/dispatch/references/messages.md +18 -25
- package/dist/skills/dispatch/references/reading.md +10 -10
- package/dist/skills/dispatch-brainstorming/SKILL.md +19 -15
- package/dist/skills/dispatch-first/SKILL.md +7 -7
- package/dist/skills/envoy/SKILL.md +3 -2
- package/package.json +6 -5
|
@@ -37,17 +37,17 @@ reordering the board yourself.
|
|
|
37
37
|
|
|
38
38
|
Before you start implementing an issue, claim it:
|
|
39
39
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
```bash
|
|
41
|
+
dispatch claim --issue LEGION-234 # I am implementing this
|
|
42
|
+
dispatch claim --issue LEGION-234 --release # I have stopped; it is free
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
A claim records **your** session — the one making the call, never another — and shows on every
|
|
46
|
-
read of the issue: the dashboard header, the issue list and board, `
|
|
47
|
-
`Claimed by:` line) and `
|
|
46
|
+
read of the issue: the dashboard header, the issue list and board, `dispatch read` (a
|
|
47
|
+
`Claimed by:` line) and `dispatch issues` (a claim on the row). A session's claim there ends
|
|
48
48
|
`· not running` when the live agent registry does not list that session, as the dashboard's chip
|
|
49
49
|
does — that claim is free to take — and `· liveness unknown` when the registry could not be read,
|
|
50
|
-
which says nothing either way. `
|
|
50
|
+
which says nothing either way. `dispatch issues` plus the dashboard's **Unclaimed** filter is how
|
|
51
51
|
you find work nobody is on.
|
|
52
52
|
|
|
53
53
|
- **`409 ISSUE_CLAIMED` means someone else holds this issue.** When it is another session, the
|
|
@@ -55,7 +55,7 @@ you find work nobody is on.
|
|
|
55
55
|
that session (its id is in the message; `envoy_send` reaches it) or pick up something else,
|
|
56
56
|
and tell the human if you believe the work should be yours. When a **human** holds it, the
|
|
57
57
|
refusal names the person and says nothing about a session running, because there is none to
|
|
58
|
-
message: ask them with `
|
|
58
|
+
message: ask them with `dispatch ask` instead, so the open ask appears in their Inbox, and
|
|
59
59
|
never assume their claim has lapsed — only a human releases or forces a human's claim.
|
|
60
60
|
- **`409 CLAIM_CONTENDED` means the issue changed hands twice while your call ran**, so nothing
|
|
61
61
|
was applied and nobody's liveness was checked. Read the issue and decide again; it is not a
|
|
@@ -71,8 +71,8 @@ you find work nobody is on.
|
|
|
71
71
|
|
|
72
72
|
**Claiming and moving the status are two separate actions, and you do both.** A claim says which
|
|
73
73
|
session is on the work; the status says where the work has got to, and humans use it to track
|
|
74
|
-
that too. So when you start: `
|
|
75
|
-
`
|
|
74
|
+
that too. So when you start: `dispatch claim --issue <KEY>` **and**
|
|
75
|
+
`dispatch issue-update --issue <KEY> --status in_progress`.
|
|
76
76
|
|
|
77
77
|
## Issue status is yours to move
|
|
78
78
|
|
|
@@ -84,29 +84,29 @@ queue, `done` when the change has been driven in production (a merge is not `don
|
|
|
84
84
|
issues you own as well as the root. An issue left at `triage` while work is underway is a defect.
|
|
85
85
|
Waiting for the deploy lane is not a status and is never announced.
|
|
86
86
|
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
```bash
|
|
88
|
+
# PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL), route, parent
|
|
89
|
+
dispatch issue-update --issue PROJ-175 --status testing
|
|
90
|
+
dispatch issue-update --issue PROJ-175 --status done --reason 'Shipped in owner/repo#7; verified on the production dashboard.'
|
|
91
|
+
dispatch issue-update --issue PROJ-175 --priority 1 # 0–3; see Priority is yours to set
|
|
92
|
+
dispatch issue-update --issue PROJ-175 --external-link https://github.com/owner/repo/pull/7
|
|
93
|
+
dispatch issue-update --issue PROJ-175 --parent PROJ-170 # same-project key; --parent '' clears it
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
Closing takes a
|
|
96
|
+
Closing takes a `--reason`, and the command refuses `--status done` without one: it posts the reason on
|
|
97
97
|
the issue as a message, then closes it, because a closed issue refuses messages, comments, and
|
|
98
98
|
artifacts, so a reason left for later has nowhere to go. When the close fails after the post, the
|
|
99
99
|
error names the posted message; after a timeout or a server error it also says the close may have
|
|
100
100
|
landed, so read the issue's status first. A retry points its reason at the posted message rather
|
|
101
101
|
than repeating it.
|
|
102
102
|
|
|
103
|
-
The two clears differ:
|
|
104
|
-
Guessing the other one is a refusal either way.
|
|
103
|
+
The two clears differ: `--clear-priority` sends null, while `--parent ''` and `--route ''` clear with an
|
|
104
|
+
empty string. Guessing the other one is a refusal either way.
|
|
105
105
|
|
|
106
|
-
Link the pull request that delivers the issue
|
|
107
|
-
renders its state and checks from that link, and `
|
|
108
|
-
The
|
|
109
|
-
other `
|
|
106
|
+
Link the pull request that delivers the issue with `--external-link` when you open it; the issue page
|
|
107
|
+
renders its state and checks from that link, and `dispatch read` lists it under `External links:`.
|
|
108
|
+
The command is authenticated with the same bearer as every
|
|
109
|
+
other `dispatch` command: a Legion pane reads it from the `DISPATCH_TOKEN_FILE` path the daemon sets on
|
|
110
110
|
the pane; an OMP session outside Legion reads `dispatch.token` from `~/.config/opencode/envoy.json`.
|
|
111
111
|
|
|
112
112
|
A write to an issue still in `triage` answers once with `… is still in triage …`; move the status
|
|
@@ -120,39 +120,39 @@ lowest, and `null` clears it. Agents set it (`dispatch://LEGION/artifact/issue-s
|
|
|
120
120
|
the human overrides anything they disagree with from the dashboard. A closed
|
|
121
121
|
issue takes only `rank`, `components`, and a reopening `status` (any status but `done`);
|
|
122
122
|
everything else, `priority` included, waits for the reopen (`409 ISSUE_CLOSED`). So reopen it
|
|
123
|
-
first, then set the priority — the two cannot go in one
|
|
123
|
+
first, then set the priority — the two cannot go in one command. `rank` itself is not a flag:
|
|
124
124
|
reorder it the way [Issue reads](#board-rank-priority-and-assignee-on-a-read) describes, through `PATCH /api/v1/issues/{key}`.
|
|
125
125
|
|
|
126
126
|
## Board rank, priority, and assignee on a read
|
|
127
127
|
|
|
128
|
-
Issue reads include `rank`, the server-owned ordering key used by project boards; reorder through `PATCH /api/v1/issues/{key}` with `{"rank": {"before": "<key>", "after": "<key>"}}`, either neighbor optional and both in the issue's project. A bearer caller also names its own session in that body, `"actor": {"kind": "session", "id": "<your session id>"}`, or the server refuses with `ACTOR_KIND`. They also include nullable coarse priority (`P0` highest through `P3` lowest) and `assignee`: the lowercase email of the person who answers the issue's asks, or `null` when nobody holds it. `
|
|
128
|
+
Issue reads include `rank`, the server-owned ordering key used by project boards; reorder through `PATCH /api/v1/issues/{key}` with `{"rank": {"before": "<key>", "after": "<key>"}}`, either neighbor optional and both in the issue's project. A bearer caller also names its own session in that body, `"actor": {"kind": "session", "id": "<your session id>"}`, or the server refuses with `ACTOR_KIND`. They also include nullable coarse priority (`P0` highest through `P3` lowest) and `assignee`: the lowercase email of the person who answers the issue's asks, or `null` when nobody holds it. `dispatch read` of an issue prints it as `Assignee: <email>` or `Assignee: unassigned`.
|
|
129
129
|
|
|
130
130
|
## Reading a project's backlog
|
|
131
131
|
|
|
132
132
|
To see the shape of a project rather than find a phrase, list its issues:
|
|
133
|
-
```
|
|
134
|
-
|
|
133
|
+
```bash
|
|
134
|
+
dispatch issues --project <KEY>
|
|
135
135
|
```
|
|
136
136
|
Each row carries the issue key, title, status, priority, parent, labels, its open-ask count, and
|
|
137
|
-
when it last changed — a roadmap or backlog pass without opening every issue. Filter with
|
|
138
|
-
(a lifecycle status),
|
|
139
|
-
`
|
|
140
|
-
`
|
|
141
|
-
default and 250 at most, and
|
|
137
|
+
when it last changed — a roadmap or backlog pass without opening every issue. Filter with `--status`
|
|
138
|
+
(a lifecycle status), `--parent` (one issue's children), `--label`, `--priority` (repeated, `0`–`3`, with
|
|
139
|
+
`none` for an issue with no priority: `--priority 0 --priority 1` is every P0 and P1), `--route-status` (below), or
|
|
140
|
+
`--updated-since` (an RFC3339 timestamp, for "what moved this week"). `--limit` is the page size, 50 by
|
|
141
|
+
default and 250 at most, and `--offset` is where the page starts; the output says how many issues
|
|
142
142
|
match. Repeating with the next offset walks every matching issue only while the list does not
|
|
143
143
|
change: an issue that enters or leaves what your filters match, or whose status or rank changes,
|
|
144
144
|
between two pages shifts rows across a page boundary, and the walk then shows one issue twice and
|
|
145
145
|
misses another.
|
|
146
146
|
|
|
147
|
-
This is not search: it matches no text. Use `
|
|
148
|
-
`
|
|
147
|
+
This is not search: it matches no text. Use `dispatch search` for a keyword or phrase, and
|
|
148
|
+
`dispatch issues` when you want every issue in a project and its current state.
|
|
149
149
|
|
|
150
150
|
### The owner audit
|
|
151
151
|
|
|
152
152
|
As the owner of a surface, list the project's P0 and P1 issues and staff or close each one nobody
|
|
153
153
|
has started:
|
|
154
|
-
```
|
|
155
|
-
|
|
154
|
+
```bash
|
|
155
|
+
dispatch issues --project <KEY> --priority 0 --priority 1 --limit 250
|
|
156
156
|
```
|
|
157
157
|
Every unclaimed row in `triage`, `icebox`, `backlog` or `todo` is a decision: someone takes it and
|
|
158
158
|
builds it, or it closes. A row in `in_progress`, `testing`, `needs_review` or `retro`, or one that
|
|
@@ -175,8 +175,8 @@ The audit finds four shapes:
|
|
|
175
175
|
- **Unreachable route.** An open issue whose route names a role nobody holds, or a session that is
|
|
176
176
|
not running, reaches nobody, whatever its priority, and the priority filter above never finds
|
|
177
177
|
it. List it on its own:
|
|
178
|
-
```
|
|
179
|
-
|
|
178
|
+
```bash
|
|
179
|
+
dispatch issues --project <KEY> --route-status no_holder --limit 250
|
|
180
180
|
```
|
|
181
181
|
Each row reads `route role:sre (nobody holds it right now)` or `route session:<id> (that session
|
|
182
182
|
is not running right now)`. That is one read of the listener, and one read cannot tell a
|
|
@@ -184,9 +184,9 @@ The audit finds four shapes:
|
|
|
184
184
|
session is absent from the listener for minutes, and its role with it.
|
|
185
185
|
So a route is unowned only when it is `no_holder` on two reads at least ten minutes apart: list
|
|
186
186
|
again after ten minutes and act on the issues both lists name. Confirm with the second
|
|
187
|
-
`
|
|
187
|
+
`dispatch issues` read, not `envoy_role_get`: a role lookup releases the claim of a holder whose
|
|
188
188
|
session is absent from the registry as it answers. Then staff the role, re-route the
|
|
189
|
-
issue to a live holder, or clear the route and assign it.
|
|
189
|
+
issue to a live holder, or clear the route and assign it. `--route-status unknown` means the
|
|
190
190
|
listener did not answer, so a route could not be judged; a `no_holder` filter refuses rather
|
|
191
191
|
than answer an empty list then.
|
|
192
192
|
|
|
@@ -195,19 +195,19 @@ are found by running the check, not by noticing them.
|
|
|
195
195
|
|
|
196
196
|
## Search paging
|
|
197
197
|
|
|
198
|
-
`skill://dispatch` sends you here when a `
|
|
198
|
+
`skill://dispatch` sends you here when a `dispatch search` page is not enough: more hits remain,
|
|
199
199
|
or a kind runs out before the page does.
|
|
200
200
|
|
|
201
|
-
A page holds
|
|
202
|
-
(`showing 1-20 of 312`), and, while more can be reached, the last line names the next
|
|
203
|
-
Each kind lists at most its best 100, so when the
|
|
204
|
-
the query or name a
|
|
201
|
+
A page holds `--limit` hits (20 by default, 50 at most); the first line names how many match
|
|
202
|
+
(`showing 1-20 of 312`), and, while more can be reached, the last line names the next `--offset`.
|
|
203
|
+
Each kind lists at most its best 100, so when the output says the rest cannot be paged to, narrow
|
|
204
|
+
the query or name a `--project`.
|
|
205
205
|
|
|
206
206
|
## Syncing a project's architecture model
|
|
207
207
|
|
|
208
208
|
Import a project's architecture model from its configured source repository now (a human configures the source in Settings):
|
|
209
|
-
```
|
|
210
|
-
|
|
209
|
+
```bash
|
|
210
|
+
dispatch architecture-sync --project CORE
|
|
211
211
|
```
|
|
212
|
-
It
|
|
212
|
+
It prints the imported commit, or the recorded error when the model was rejected — the previous model stays up. Without a configured source it answers 404 `SOURCE_NOT_FOUND`.
|
|
213
213
|
|
|
@@ -8,23 +8,19 @@ human messages you directly from the Agents page.
|
|
|
8
8
|
A human — or any bearer caller over HTTP, such as a test rig — can target the issue message at a
|
|
9
9
|
live Envoy session or role as **BTW**, **Aside**, or **Steer** (the dashboard calls a steer
|
|
10
10
|
**Send**). The incoming Dispatch frame names
|
|
11
|
-
the issue and includes a `reply_with` hint (`{
|
|
12
|
-
|
|
11
|
+
the issue and includes a `reply_with` hint (`{ command }`, the `dispatch` command line that answers it, with `...` for
|
|
12
|
+
the body); reply on the same open issue with that command, never a new targeted send:
|
|
13
13
|
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
issue: "CORE-1",
|
|
17
|
-
in_reply_to: "<targeted-message-id>",
|
|
18
|
-
body: "The requested answer.",
|
|
19
|
-
})
|
|
14
|
+
```bash
|
|
15
|
+
dispatch message --issue CORE-1 --in-reply-to <targeted-message-id> --body 'The requested answer.'
|
|
20
16
|
```
|
|
21
17
|
|
|
22
|
-
`
|
|
18
|
+
`--in-reply-to` correlates the answer under the asker's message in its Conversation card. A BTW
|
|
23
19
|
delivery can post its answer automatically; use this call when the frame asks the primary agent to
|
|
24
20
|
reply. A human may reply to your message in turn — the follow-up arrives as a targeted frame whose
|
|
25
21
|
`in_reply_to` names your message and whose `reply_body` quotes it; answer it the same way,
|
|
26
|
-
`
|
|
27
|
-
thread. `
|
|
22
|
+
`dispatch message --issue <KEY> --in-reply-to <their reply id> --body-file -`, so the exchange reads as one
|
|
23
|
+
thread. `dispatch message` itself never carries `target` or `delivery`: agent-to-agent traffic goes
|
|
28
24
|
through Envoy or Oh My Pi's `agent://` messages. A bearer that targets over HTTP names its own
|
|
29
25
|
session in `actor` (`{kind: "session", id}`), and the card shows that session as the author.
|
|
30
26
|
`GET /api/v1/agents` (any authenticated caller) lists live sessions with their capabilities
|
|
@@ -37,38 +33,35 @@ A human can also message you directly from the **Agents** page, with no issue at
|
|
|
37
33
|
Pi, a person's **Send** or **Aside** arrives as their own user message, exactly as if they had
|
|
38
34
|
typed it at your terminal: your Envoy plugin takes it only once Dispatch accepts it as a person's
|
|
39
35
|
own fresh message to you, and injects the text Dispatch stored. Answer it in the conversation as
|
|
40
|
-
you would anything typed, with no `
|
|
36
|
+
you would anything typed, with no `dispatch message`; the Agents page shows your conversation
|
|
41
37
|
live, so they read your answer there.
|
|
42
38
|
|
|
43
39
|
Everything else still arrives as a Dispatch frame: a **BTW**, a broadcast, a direct message on a
|
|
44
40
|
host that takes no user turn from its plugin (Claude Code), and one Dispatch did not accept.
|
|
45
41
|
That frame names no issue and its `reply_with` hint carries none either; answer it with the
|
|
46
|
-
message's bare id in
|
|
42
|
+
message's bare id in `--in-reply-to`, alone:
|
|
47
43
|
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
in_reply_to: "<the direct message's id>",
|
|
51
|
-
body: "The requested answer.",
|
|
52
|
-
})
|
|
44
|
+
```bash
|
|
45
|
+
dispatch message --in-reply-to <the direct message's id> --body 'The requested answer.'
|
|
53
46
|
```
|
|
54
47
|
|
|
55
|
-
Leave
|
|
48
|
+
Leave `--issue` out — there is no issue to post into, and naming one would file your answer on
|
|
56
49
|
unrelated work. Dispatch threads the reply under their message in the same conversation, and the
|
|
57
50
|
human sees it in your conversation on the Agents page, where it shows as an unread reply until
|
|
58
|
-
they read it. Every other message still names its issue, so keep the
|
|
51
|
+
they read it. Every other message still names its issue, so keep the `--issue`
|
|
59
52
|
the frame gave you whenever it gave you one; a `dispatch://KEY/message/<id>` reference names the
|
|
60
53
|
issue its message lives on, so that form is a reply on that issue, not a direct message.
|
|
61
54
|
|
|
62
|
-
Have more to say after you answered?
|
|
63
|
-
Dispatch threads that follow-up under your first reply, and the
|
|
55
|
+
Have more to say after you answered? Run it again with the same `--in-reply-to` and the new text:
|
|
56
|
+
Dispatch threads that follow-up under your first reply, and the output names the reply it
|
|
64
57
|
follows. The same text again posts nothing, so a retry is safe. Your host may already have
|
|
65
58
|
answered a **BTW** automatically before you got here; a second call is then your follow-up to
|
|
66
|
-
that answer, so read the
|
|
59
|
+
that answer, so read the output before writing again.
|
|
67
60
|
|
|
68
61
|
Read the whole conversation back — their message and every reply, yours included — with the
|
|
69
62
|
message id alone; it has no issue:
|
|
70
63
|
|
|
71
|
-
```
|
|
72
|
-
|
|
64
|
+
```bash
|
|
65
|
+
dispatch read --message <the direct message's id, or any reply's>
|
|
73
66
|
```
|
|
74
67
|
|
|
@@ -5,16 +5,16 @@ message or document, trace what cites a node, or need the exact `dispatch://` fo
|
|
|
5
5
|
|
|
6
6
|
## What comes back
|
|
7
7
|
|
|
8
|
-
After a restart, catch up with:
|
|
8
|
+
After a restart, catch up with `dispatch read` (`--issue`, or `--project` and `--artifact`, or `--ref`):
|
|
9
9
|
|
|
10
|
-
```
|
|
11
|
-
|
|
10
|
+
```bash
|
|
11
|
+
dispatch read --issue <KEY>
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
With an issue ref, it
|
|
15
|
-
document owner or ref, it
|
|
16
|
-
question, options, state, answer, and its reply thread. With a comment ref, it
|
|
17
|
-
message ref, it
|
|
14
|
+
With an issue ref, it prints the issue summary, open asks, references, and recent events. With a project
|
|
15
|
+
document owner or ref, it prints a document summary. With an ask ref, it prints that ask's
|
|
16
|
+
question, options, state, answer, and its reply thread. With a comment ref, it prints that comment and its quoted reply chain. With a
|
|
17
|
+
message ref, it prints that message and its reply chain. Reads do not subscribe; use `dispatch doc-read` for document contents.
|
|
18
18
|
|
|
19
19
|
An anchored comment or ask also prints `Position:`, where its quote's block stands — `table[3] › row 5 (Red-teamer loop), column Due`
|
|
20
20
|
is the fourth top-level block, a table, its row 5 (row 0 is the header; the index `delete_row` takes), labelled by the row's cells
|
|
@@ -31,7 +31,7 @@ followers — and `Links:` lists what it cites. Each row is `- <edge kind> <node
|
|
|
31
31
|
document source the excerpt is the start of the block holding the mention, and a whole list is one block, so every issue named in
|
|
32
32
|
one list previews the list's first item. When a document references many issues and each backlink should read right, give each
|
|
33
33
|
issue its own paragraph (or block), not an item of one list. Cross-project, always: a message on another project's issue that
|
|
34
|
-
cites an ask shows up under that ask. So "what led to this decision" is one `
|
|
34
|
+
cites an ask shows up under that ask. So "what led to this decision" is one `dispatch read` on the ask, and "who relies on this
|
|
35
35
|
document" one read on the document. Cite with `dispatch://` references (below) whenever you name a node in a body — a bare id or
|
|
36
36
|
title is invisible to the graph.
|
|
37
37
|
|
|
@@ -40,7 +40,7 @@ title is invisible to the graph.
|
|
|
40
40
|
Use these in document, ask, comment, and message bodies. In the dashboard, a reference renders
|
|
41
41
|
as an inline link whose text is the target's title (an issue's title, an ask's question, a
|
|
42
42
|
comment's first line, a document's name) once it resolves; a body that is only a bare reference
|
|
43
|
-
still gets an unfurl card instead. Every
|
|
43
|
+
still gets an unfurl card instead. Every `--ref` flag below (and `--issue`/`--project`) accepts
|
|
44
44
|
either form — an issue key or a project key is never ambiguous, since a project key never
|
|
45
45
|
contains a dash:
|
|
46
46
|
|
|
@@ -56,7 +56,7 @@ dispatch://PROJECT/artifact/<document-ref>/ask/<id>
|
|
|
56
56
|
dispatch://PROJECT/artifact/<document-ref>/comment/<id>
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
A bare UUID or `KEY#seq` is not a reference; the `dispatch://` form is what Dispatch links and records. `
|
|
59
|
+
A bare UUID or `KEY#seq` is not a reference; the `dispatch://` form is what Dispatch links and records. `dispatch read` also
|
|
60
60
|
accepts the dashboard URL of an issue, spec, artifact, ask, comment, or project document on the configured server (it maps to the
|
|
61
61
|
`dispatch://` form above), and an ask or comment id may be a unique prefix of at least 8 hex characters; a message id is always the
|
|
62
62
|
full uuid. A non-uuid id on `GET /asks/{id}`, `/comments/{id}`, or `/issues/{key}/messages/{id}` is a 400 `ASK_ID_INPUT` /
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dispatch-brainstorming
|
|
3
|
-
description: "Use in a session with Dispatch
|
|
3
|
+
description: "Use in a session with Dispatch whenever a design conversation with a person starts: brainstorming or /brainstorming, \"let's design\", writing or changing a spec, writing an implementation plan, or a feature request or change that needs a person's choices. In a session with Dispatch it replaces superpowers' brainstorming and writing-plans; a Legion architect's own spec follows skill://legion-architect instead."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Brainstorming in Dispatch
|
|
@@ -34,19 +34,21 @@ decision to its architect (`skill://legion-worker`).
|
|
|
34
34
|
## Where the spec lives
|
|
35
35
|
|
|
36
36
|
Search Dispatch first, as `skill://dispatch-first` says. When an issue already tracks the work, its
|
|
37
|
-
primary document is the spec: extend it in place with `
|
|
37
|
+
primary document is the spec: extend it in place with `dispatch doc-edit`, keeping the human's own
|
|
38
38
|
text. Otherwise create the issue with its first version as `spec`, in the project a search hit
|
|
39
39
|
already named or, when none does, the project the human names:
|
|
40
40
|
|
|
41
|
-
```
|
|
42
|
-
|
|
41
|
+
```bash
|
|
42
|
+
dispatch issue --project <KEY> --title '<title>' --spec-file - <<'EOF'
|
|
43
|
+
<the spec's first version>
|
|
44
|
+
EOF
|
|
43
45
|
```
|
|
44
46
|
|
|
45
|
-
No
|
|
47
|
+
No command lists every project, so when nothing you found names one, ask the human in chat which
|
|
46
48
|
project the issue belongs in before you create it — a filing question with nowhere else to land
|
|
47
49
|
yet, not a design question, so it does not change "your reply in chat links the issue and asks
|
|
48
50
|
nothing" for the design itself. Never read the project from the environment, a configuration file,
|
|
49
|
-
or the Dispatch HTTP API: every read and write goes through a `
|
|
51
|
+
or the Dispatch HTTP API: every read and write goes through a `dispatch` command.
|
|
50
52
|
|
|
51
53
|
Before the first version, read the code and documents the design touches, so the facts you write
|
|
52
54
|
are ones you checked.
|
|
@@ -65,11 +67,11 @@ are ones you checked.
|
|
|
65
67
|
nothing is settled until the human has seen it, so even a flagged inference waits for its own
|
|
66
68
|
decision block.
|
|
67
69
|
2. **The human answers or comments.** Reply to each human comment in its thread
|
|
68
|
-
(`
|
|
69
|
-
Under an open ask whose next move is yours, such as the approval request you must
|
|
70
|
-
hand back, reply with
|
|
71
|
-
default turn, which hands the request back to the human unchanged, and a call
|
|
72
|
-
|
|
70
|
+
(`dispatch comment --reply-to <comment id>`), then rewrite the passage the answer or the comment
|
|
71
|
+
changes. Under an open ask whose next move is yours, such as the approval request you must
|
|
72
|
+
revise or hand back, reply with `--reply-to-ask <ask id> --turn agent` instead: a `--reply-to`
|
|
73
|
+
reply takes the default turn, which hands the request back to the human unchanged, and a call
|
|
74
|
+
with a corrected `--summary` is refused while it waits on them.
|
|
73
75
|
3. **Each next version folds the answers in and adds what they open.** Keep each answered
|
|
74
76
|
decision block where it is, fold its answer into the surrounding text in the human's words with
|
|
75
77
|
the date, recording the person as `skill://dispatch`'s "Writing a spec" says for a settled
|
|
@@ -77,7 +79,7 @@ are ones you checked.
|
|
|
77
79
|
at once, each as a decision block at the end of the section that sets it up; a question waits
|
|
78
80
|
only when it depends on an answer still open.
|
|
79
81
|
4. **A comment that answers a question settles it** as surely as the block does. Fold it into the
|
|
80
|
-
text at once, and close the block with `
|
|
82
|
+
text at once, and close the block with `dispatch resolve-ask` if the human has not.
|
|
81
83
|
5. **Request approval at the end, not after each section.** Once nothing in the spec is new to the
|
|
82
84
|
human, request it exactly when "Approval of a spec" in `skill://dispatch` says: every decision
|
|
83
85
|
block settled and folded in, the human has agreed to every point in the spec, and the current
|
|
@@ -97,8 +99,10 @@ Once the spec is approved — or, when the issue needed no spec at all (a bug fi
|
|
|
97
99
|
decision), once you have enough to plan from — the implementation plan is the issue's `plan.md`
|
|
98
100
|
document, never its spec and never a repository file:
|
|
99
101
|
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
+
```bash
|
|
103
|
+
dispatch artifact --issue <KEY> --name plan.md --content-file - <<'EOF'
|
|
104
|
+
<the plan>
|
|
105
|
+
EOF
|
|
102
106
|
```
|
|
103
107
|
|
|
104
108
|
Uploading `plan.md` again writes its next version. `writing-plans`'s content rules still apply in
|
|
@@ -108,6 +112,6 @@ Technical choices inside the approved design are made in the plan and need no qu
|
|
|
108
112
|
never changes a decision the human made in the spec: a change to one goes back to the spec as a
|
|
109
113
|
decision block, with the evidence for it.
|
|
110
114
|
|
|
111
|
-
Execution reads the plan the same way: `
|
|
115
|
+
Execution reads the plan the same way: `dispatch doc-read --issue <KEY> --artifact plan.md` in place
|
|
112
116
|
of opening a plan file, then follows `executing-plans` or `subagent-driven-development` as it would
|
|
113
117
|
for a file on disk.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dispatch-first
|
|
3
|
-
description: "Use in any session with
|
|
3
|
+
description: "Use in any session with the dispatch command, before planning, filing an issue, asking a human, posting a finding, or starting work that someone may already track or have decided."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Dispatch first
|
|
@@ -11,18 +11,18 @@ answered, costs that human the time to notice it and splits the history across t
|
|
|
11
11
|
|
|
12
12
|
## Search before you act
|
|
13
13
|
|
|
14
|
-
Before you plan, file an issue, ask, post a finding or start work, search Dispatch. Every word of
|
|
14
|
+
Before you plan, file an issue, ask, post a finding or start work, search Dispatch with the `dispatch` command in your shell (`dispatch --help` lists every command). Every word of
|
|
15
15
|
the query must match, so each word you add can only lose hits: search with two or three words, the
|
|
16
16
|
thing and what is wrong with it, as a user would name them. Never paste a draft.
|
|
17
17
|
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
```bash
|
|
19
|
+
dispatch search --query 'broadcast send order'
|
|
20
|
+
dispatch search --query 'reviewer threads OR review comments'
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
When a query finds nothing, drop a word before you add one. Try two or three wordings (the
|
|
24
24
|
component's name, the symptom, the fix) before you conclude that nothing exists. Open every hit
|
|
25
|
-
that could be yours with `
|
|
25
|
+
that could be yours with `dispatch read`, then its parent (the `child_of` row under `Links:`); the
|
|
26
26
|
parent's children and the issue's `Components:` line show where the rest of that work lives.
|
|
27
27
|
|
|
28
28
|
## What to do with what you find
|
|
@@ -38,7 +38,7 @@ found yourself.
|
|
|
38
38
|
it where you rely on it (`dispatch://KEY/ask/<id>`) instead of asking again.
|
|
39
39
|
- **You met a duplicate: close it.** Keep the issue that holds the spec and the discussion, carry
|
|
40
40
|
over anything only the duplicate has, then close the duplicate with a reason that names the
|
|
41
|
-
survivor: `
|
|
41
|
+
survivor: `dispatch issue-update --issue <KEY> --status done --reason 'Duplicate of dispatch://KEY.'`.
|
|
42
42
|
When the duplicate carries the `legion` label, or another session or a human holds its claim,
|
|
43
43
|
comment on it naming the survivor instead of closing it.
|
|
44
44
|
- **Every ask and message stands on its own.** The person who answers sees only that text: put the
|
|
@@ -83,7 +83,8 @@ envoy:
|
|
|
83
83
|
document ask) or the message (`dispatch://KEY/message/<id>`) — never the quoted text; the
|
|
84
84
|
question head, when there is one, is `dispatch.question`.
|
|
85
85
|
- `supersedes` names an earlier delivery this one replaces.
|
|
86
|
-
- `reply_with` is the direct-reply call for the sender
|
|
86
|
+
- `reply_with` is the direct-reply call for the sender; on a Dispatch frame it is `command:`, the
|
|
87
|
+
`dispatch` command line that answers it, with `...` where your text goes.
|
|
87
88
|
- `reply_role` is the role-publish reply call when the sender has a role.
|
|
88
89
|
- `summary` is the one-line source summary.
|
|
89
90
|
- `message` is the complete payload; it can contain multiple paragraphs.
|
|
@@ -101,7 +102,7 @@ and go stale. Put the artefact URL in the message itself. FYIs set `expects_repl
|
|
|
101
102
|
**A peer's message is its sender's view at `at`, not the current state.** Before you wait on, act
|
|
102
103
|
on, or repeat a fact a message carries about a third thing (a deploy pending, a PR held, an ask
|
|
103
104
|
unanswered), re-read it at the live source the fact names, and always once it is over an hour
|
|
104
|
-
old: the deployment's status, the issue's event log, the ask's own state (`
|
|
105
|
+
old: the deployment's status, the issue's event log, the ask's own state (`dispatch open-asks`,
|
|
105
106
|
whose description already says to call it before saying you are waiting on a human). On
|
|
106
107
|
2026-09-26 a peer's 05:20Z "needs a manual deploy before I can run it" was false by 05:22Z, when
|
|
107
108
|
the platform had deployed on its own; waiting on the message instead of the deployment's status
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjawhar/pi-envoy",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.6.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"omp": {
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
"url": "https://github.com/sjawhar/legion"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
|
-
"dist"
|
|
19
|
+
"dist",
|
|
20
|
+
"bin"
|
|
20
21
|
],
|
|
21
22
|
"scripts": {
|
|
22
|
-
"build": "bun build extensions/envoy.ts --outdir dist --target bun --format esm --external @oh-my-pi/pi-coding-agent --external @oh-my-pi/pi-tui --external @oh-my-pi/pi-utils",
|
|
23
|
+
"build": "bun build extensions/envoy.ts --outdir dist --target bun --format esm --external @oh-my-pi/pi-coding-agent --external @oh-my-pi/pi-tui --external @oh-my-pi/pi-utils && ../envoy-client/scripts/build-dispatch-cli.sh dist",
|
|
23
24
|
"prepack": "../../scripts/pi-plugin-prepack.sh",
|
|
24
25
|
"postpack": "rm -rf dist/skills",
|
|
25
26
|
"typecheck": "bunx tsc --noEmit",
|
|
@@ -31,8 +32,8 @@
|
|
|
31
32
|
"@legion/contracts": "0.10.0",
|
|
32
33
|
"@legion/envoy-client": "0.1.0",
|
|
33
34
|
"@legion/pi-shared": "0.1.0",
|
|
34
|
-
"@oh-my-pi/pi-tui": "^18.
|
|
35
|
-
"@oh-my-pi/pi-utils": "^18.
|
|
35
|
+
"@oh-my-pi/pi-tui": "^18.6.0",
|
|
36
|
+
"@oh-my-pi/pi-utils": "^18.6.0",
|
|
36
37
|
"@toon-format/toon": "^4.1.1",
|
|
37
38
|
"@types/bun": "latest",
|
|
38
39
|
"nats": "^2.29.2",
|