@sjawhar/opencode-legion-envoy 1.36.0 → 1.37.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 CHANGED
@@ -29,11 +29,12 @@ This package exposes:
29
29
  - `dispatch_read`
30
30
  - `dispatch_search`
31
31
  - `dispatch_issues`
32
+ - `dispatch_architecture_sync`
32
33
  - `dispatch_open_asks`
33
34
  - `dispatch_whoami`
34
35
 
35
- The nineteen native `dispatch_*` tools create and read Dispatch issues, asks, comments,
36
- documents, and artifacts, list a project's issues, or search all of them. They are present when `dispatch.enabled`
36
+ The twenty native `dispatch_*` tools create and read Dispatch issues, asks, comments,
37
+ documents, and artifacts, list a project's issues, sync a project's architecture model, or search all of them. They are present when `dispatch.enabled`
37
38
  resolves a server URL and bearer token from envoy.json (`~/.config/opencode/envoy.json`, merged
38
39
  with `<repo>/.opencode/envoy.json`) or the `DISPATCH_URL` and `DISPATCH_TOKEN` environment
39
40
  variables; `dispatch.enabled: true` without `dispatch.serverUrl` targets `http://localhost:8766`.
@@ -14036,6 +14036,14 @@ var dispatchToolSpecs = [
14036
14036
  limit: z.number({ int: true, min: 1, max: 250 }).describe("Maximum rows, 1-250; default 50.").optional()
14037
14037
  })
14038
14038
  },
14039
+ {
14040
+ name: "dispatch_architecture_sync",
14041
+ description: "Import a project's architecture model from its configured source repository now, instead of " + "waiting for the server's five-minute schedule. Returns the imported commit and component " + "count, or the recorded error when the model was rejected (the previous model stays up). " + "The source itself is configured by a human in Settings; 404 SOURCE_NOT_FOUND without one.",
14042
+ arguments: (z) => ({
14043
+ project: z.string().describe("Project key whose architecture source to sync, such as CORE.")
14044
+ }),
14045
+ strict: true
14046
+ },
14039
14047
  {
14040
14048
  name: "dispatch_open_asks",
14041
14049
  description: "List active unanswered asks, oldest first, with age and whose reply is needed. Omit project to " + "see only this session's own authored asks (call before saying you are waiting for human input); " + "supply project to see every open ask across that project's issues and documents, whoever authored " + "them.",
@@ -14876,6 +14884,9 @@ class DispatchClient {
14876
14884
  async whoami() {
14877
14885
  return this.#json("GET", ["api", "v1", "whoami"]);
14878
14886
  }
14887
+ async syncArchitectureSource(project) {
14888
+ return this.#json("POST", ["api", "v1", "projects", project, "architecture-source", "sync"]);
14889
+ }
14879
14890
  async resolveAsk(id, input) {
14880
14891
  return this.#json("POST", ["api", "v1", "asks", id, "resolve"], input);
14881
14892
  }
@@ -15291,7 +15302,8 @@ var issueFreeTools = {
15291
15302
  dispatch_search: true,
15292
15303
  dispatch_issues: true,
15293
15304
  dispatch_open_asks: true,
15294
- dispatch_whoami: true
15305
+ dispatch_whoami: true,
15306
+ dispatch_architecture_sync: true
15295
15307
  };
15296
15308
  function canonicalExternalIssueRef(value) {
15297
15309
  const match = value.trim().match(externalIssueRefPattern);
@@ -16139,6 +16151,25 @@ async function executeDispatchTool(input) {
16139
16151
  details: { issues: rows }
16140
16152
  };
16141
16153
  }
16154
+ case "dispatch_architecture_sync": {
16155
+ const project = stringArg(args, "project");
16156
+ const source = await client.syncArchitectureSource(project);
16157
+ const at = source.last_sync_at ?? "unknown time";
16158
+ return {
16159
+ text: source.last_error === null ? `Synced ${project} architecture from ${source.repo}@${source.branch}: commit ${source.last_commit ?? "unknown"} (${at}).` : [
16160
+ `Sync failed for ${project} (${source.repo}@${source.branch}): ${source.last_error}`,
16161
+ source.last_commit === null ? "No model has ever imported for this project." : `The previous model stays up (commit ${source.last_commit}).`
16162
+ ].join(`
16163
+ `),
16164
+ details: {
16165
+ project,
16166
+ repo: source.repo,
16167
+ branch: source.branch,
16168
+ commit: source.last_commit,
16169
+ error: source.last_error
16170
+ }
16171
+ };
16172
+ }
16142
16173
  case "dispatch_resolve_ask": {
16143
16174
  const kind = stringArg(args, "kind");
16144
16175
  const ask = await client.resolveAsk(stringArg(args, "ask"), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/opencode-legion-envoy",
3
- "version": "1.36.0",
3
+ "version": "1.37.0",
4
4
  "type": "module",
5
5
  "main": "dist/src/server.js",
6
6
  "exports": {
@@ -248,6 +248,12 @@ that follow from it:
248
248
  the question carries `dispatch://KEY/artifact/<slug>` (or `ref`), never just its filename. Text
249
249
  they must read to decide belongs in the spec in the first place — see [Artifacts](#artifacts).
250
250
 
251
+ Import a project's architecture model from its configured source repository now (a human configures the source in Settings):
252
+ ```ts
253
+ dispatch_architecture_sync({ project: "CORE" })
254
+ ```
255
+ It returns 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`.
256
+
251
257
  Before saying you are waiting for human input, call `dispatch_open_asks`. With no arguments it lists this session's active asks across open issues and project documents, including whether the human or agent owes the next reply. With `dispatch_open_asks({ project })` it lists every open ask in that project — on its issues and on its documents, whoever authored them — which is how you audit what a whole project is waiting on rather than just your own asks.
252
258
 
253
259
  **Anything that needs the human is an ask, or it does not exist.** An approval, a credential,