@sjawhar/opencode-legion-envoy 3.13.0 → 3.15.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.
@@ -0,0 +1,65 @@
1
+ # Answering targeted and direct messages
2
+
3
+ `skill://dispatch` sends you here when a Dispatch frame targets you as BTW, Aside or Steer, or a
4
+ human messages you directly from the Agents page.
5
+
6
+ ## Targeted agent messages
7
+
8
+ A human — or any bearer caller over HTTP, such as a test rig — can target the issue message at a
9
+ live Envoy session or role as **BTW**, **Aside**, or **Steer**. The incoming Dispatch frame names
10
+ the issue and includes a `reply_with` hint (`{ tool, args }`, ready to issue on any host); reply on the same open issue with the existing
11
+ tool, never a new targeted send:
12
+
13
+ ```ts
14
+ dispatch_message({
15
+ issue: "CORE-1",
16
+ in_reply_to: "<targeted-message-id>",
17
+ body: "The requested answer.",
18
+ })
19
+ ```
20
+
21
+ `in_reply_to` correlates the answer under the asker's message in its Conversation card. A BTW
22
+ delivery can post its answer automatically; use this call when the frame asks the primary agent to
23
+ reply. A human may reply to your message in turn — the follow-up arrives as a targeted frame whose
24
+ `in_reply_to` names your message and whose `reply_body` quotes it; answer it the same way,
25
+ `dispatch_message({ issue, in_reply_to: "<their reply id>", body })`, so the exchange reads as one
26
+ thread. `dispatch_message` itself never carries `target` or `delivery`: agent-to-agent traffic goes
27
+ through Envoy or the hub. A bearer that targets over HTTP names its own session in `actor`
28
+ (`{kind: "session", id}`), and the card shows that session as the author. `GET /api/v1/agents`
29
+ (any authenticated caller) lists live sessions with their capabilities (`aside`, `btw`, `steer`);
30
+ target only a session that advertises the mode you want. Sending to a session with no issue
31
+ (`POST /api/v1/agents/{session_id}/messages`) stays human-only.
32
+
33
+ ## Answering a direct message
34
+
35
+ A human can also message you directly from the **Agents** page, with no issue at all. That frame
36
+ names no issue and its `reply_with` hint carries none either; answer it with the message's bare
37
+ id in `in_reply_to`, alone:
38
+
39
+ ```ts
40
+ dispatch_message({
41
+ in_reply_to: "<the direct message's id>",
42
+ body: "The requested answer.",
43
+ })
44
+ ```
45
+
46
+ Leave `issue` out — there is no issue to post into, and naming one would file your answer on
47
+ unrelated work. Dispatch threads the reply under their message in the same conversation, and the
48
+ human sees it in your conversation on the Agents page, where it shows as an unread reply until
49
+ they read it. Every other message still names its issue, so keep the `issue`
50
+ the frame gave you whenever it gave you one; a `dispatch://KEY/message/<id>` reference names the
51
+ issue its message lives on, so that form is a reply on that issue, not a direct message.
52
+
53
+ Have more to say after you answered? Call it again with the same `in_reply_to` and the new text:
54
+ Dispatch threads that follow-up under your first reply, and the tool result names the reply it
55
+ follows. The same text again posts nothing, so a retry is safe. Your host may already have
56
+ answered a **BTW** automatically before you got here; a second call is then your follow-up to
57
+ that answer, so read the result before writing again.
58
+
59
+ Read the whole conversation back — their message and every reply, yours included — with the
60
+ message id alone; it has no issue:
61
+
62
+ ```ts
63
+ dispatch_read({ message: "<the direct message's id, or any reply's>" })
64
+ ```
65
+
@@ -0,0 +1,55 @@
1
+ # Reading Dispatch back, and the reference forms
2
+
3
+ `skill://dispatch` sends you here when you catch up after a restart, read an issue, ask, comment,
4
+ message or document, trace what cites a node, or need the exact `dispatch://` form for a reference.
5
+
6
+ ## What comes back
7
+
8
+ After a restart, catch up with:
9
+
10
+ ```ts
11
+ dispatch_read({ issue?, project?, artifact?, ref? })
12
+ ```
13
+
14
+ With an issue ref, it returns the issue summary, open asks, references, and recent events with `details` `{ issue }`. With a project
15
+ document owner or ref, it returns a document summary with `details` `{ project, document }`. With an ask ref, it returns that ask's
16
+ question, options, state, answer, and its reply thread. With a comment ref, it returns that comment and its quoted reply chain. With a
17
+ message ref, it returns that message and its reply chain. Reads do not subscribe; use `dispatch_doc_read` for document contents.
18
+
19
+ Every read ends with two sections from the reference graph. `Referenced by:` lists what points at the node — every document, ask,
20
+ comment, or message that cites it, plus its structure: child issues, attached documents, anchored and owned asks and comments, replies,
21
+ followers — and `Links:` lists what it cites. Each row is `- <edge kind> <node kind> dispatch://… (<excerpt> · <when>)`; for a
22
+ 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
23
+ one list previews the list's first item. When a document references many issues and each backlink should read right, give each
24
+ issue its own paragraph (or block), not an item of one list. Cross-project, always: a message on another project's issue that
25
+ 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
26
+ document" one read on the document. Cite with `dispatch://` references (below) whenever you name a node in a body — a bare id or
27
+ title is invisible to the graph.
28
+
29
+ ## Reference forms
30
+
31
+ Use these in document, ask, comment, and message bodies. In the dashboard, a reference renders
32
+ as an inline link whose text is the target's title (an issue's title, an ask's question, a
33
+ comment's first line, a document's name) once it resolves; a body that is only a bare reference
34
+ still gets an unfurl card instead. Every `ref` argument below (and `issue`/`project`) accepts
35
+ either form — an issue key or a project key is never ambiguous, since a project key never
36
+ contains a dash:
37
+
38
+ ```text
39
+ dispatch://KEY
40
+ dispatch://KEY/spec
41
+ dispatch://KEY/artifact/<slug>[@vN]
42
+ dispatch://KEY/ask/<id>
43
+ dispatch://KEY/comment/<id>
44
+ dispatch://KEY/message/<id>
45
+ dispatch://PROJECT/artifact/<document-ref>[@vN]
46
+ dispatch://PROJECT/artifact/<document-ref>/ask/<id>
47
+ dispatch://PROJECT/artifact/<document-ref>/comment/<id>
48
+ ```
49
+
50
+ A bare UUID or `KEY#seq` is not a reference; the `dispatch://` form is what Dispatch links and records. `dispatch_read` also
51
+ accepts the dashboard URL of an issue, spec, artifact, ask, comment, or project document on the configured server (it maps to the
52
+ `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
53
+ full uuid. A non-uuid id on `GET /asks/{id}`, `/comments/{id}`, or `/issues/{key}/messages/{id}` is a 400 `ASK_ID_INPUT` /
54
+ `COMMENT_ID_INPUT` / `MESSAGE_ID_INPUT`, never a 500.
55
+
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: dispatch-first
3
+ description: "Use in any session with Dispatch tools, before planning, filing an issue, asking a human, posting a finding, or starting work that someone may already track or have decided."
4
+ ---
5
+
6
+ # Dispatch first
7
+
8
+ Dispatch already holds most of what you are about to plan, file or ask: the open issues, their
9
+ specs, and the answers humans gave. A second issue for tracked work, or a question a human already
10
+ answered, costs that human the time to notice it and splits the history across two places.
11
+
12
+ ## Search before you act
13
+
14
+ Before you plan, file an issue, ask, post a finding or start work, search Dispatch. Every word of
15
+ the query must match, so each word you add can only lose hits: search with two or three words, the
16
+ thing and what is wrong with it, as a user would name them. Never paste a draft.
17
+
18
+ ```ts
19
+ dispatch_search({ query: "broadcast send order" })
20
+ dispatch_search({ query: "reviewer threads OR review comments" })
21
+ ```
22
+
23
+ When a query finds nothing, drop a word before you add one. Try two or three wordings (the
24
+ component's name, the symptom, the fix) before you conclude that nothing exists. Open every hit
25
+ that could be yours with `dispatch_read`, then its parent (the `child_of` row under `Links:`); the
26
+ parent's children and the issue's `Components:` line show where the rest of that work lives.
27
+
28
+ ## What to do with what you find
29
+
30
+ - **The work is already tracked: extend that issue.** Put the finding on it (a comment, a message,
31
+ or an edit to its spec) instead of filing another. File a new issue only when no hit covers the
32
+ work, and cite the nearest one you ruled out (`dispatch://KEY`).
33
+ - **The question is already decided: cite the decision.** An answered ask is the record. Point to
34
+ it where you rely on it (`dispatch://KEY/ask/<id>`) instead of asking again.
35
+ - **You met a duplicate: close it.** Keep the issue that holds the spec and the discussion, carry
36
+ over anything only the duplicate has, then close the duplicate with a reason that names the
37
+ survivor: `dispatch_issue_update({ issue, status: "done", reason: "Duplicate of dispatch://KEY." })`.
38
+ When the duplicate carries the `legion` label, or another session or a human holds its claim,
39
+ comment on it naming the survivor instead of closing it.
40
+ - **Every ask and message stands on its own.** The person who answers sees only that text: put the
41
+ facts, the options and your recommendation in it, and link what you cite (`dispatch://…`)
42
+ instead of writing "see above" or "my earlier message".
43
+
44
+ ## Load the full skill before you write
45
+
46
+ - **Before you write or change a spec, read `skill://dispatch`,** including its "Writing a spec"
47
+ section.
48
+ - Before any other write to Dispatch (an ask, a message, a comment, a document edit, a status
49
+ change, a claim), load `skill://dispatch` unless you already have in this session.
@@ -256,10 +256,10 @@ Preserve this order exactly:
256
256
 
257
257
  What returns the tree to review: a changed diff — a commit above the approved head that
258
258
  touches anything outside `docs/solutions/`, or a conflict-resolution merge whose fingerprint
259
- (`skill://legion-worker`'s unchanged-diff check) differs from the approved head's. What does not: retro's
259
+ (the unchanged-diff check, `skill://legion-worker/references/conflicts-and-rewrites.md`) differs from the approved head's. What does not: retro's
260
260
  `docs/solutions/` commit, and a merge forced by a GitHub-reported conflict whose fingerprint
261
261
  is unchanged. For that merge the order is: the implementer merges the bookmark forward with the
262
- destination (`legion-worker`'s forward-merge procedure — `jj new legion/<KEY> <destination>`,
262
+ destination (the forward-merge procedure in `skill://legion-worker/references/conflicts-and-rewrites.md` — `jj new legion/<KEY> <destination>`,
263
263
  never a rebase, since a rebase rewrites every descendant of the chain's fork point, including
264
264
  another tree's branch stacked on it), pushes it with the ordinary push procedure (a genuine
265
265
  fast-forward), and posts the before/after fingerprints; the tester re-runs the bare gates only;