@openscout/protocol 0.2.98 → 0.2.104

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.
Files changed (63) hide show
  1. package/dist/actors.d.ts +2 -2
  2. package/dist/actors.d.ts.map +1 -1
  3. package/dist/actors.js +1 -0
  4. package/dist/broker-routes.d.ts +8 -0
  5. package/dist/broker-routes.d.ts.map +1 -1
  6. package/dist/broker-routes.js +15 -0
  7. package/dist/channel-identity.d.ts +77 -0
  8. package/dist/channel-identity.d.ts.map +1 -1
  9. package/dist/channel-identity.js +134 -0
  10. package/dist/channel-invites.d.ts +179 -0
  11. package/dist/channel-invites.d.ts.map +1 -0
  12. package/dist/channel-invites.js +166 -0
  13. package/dist/channel-reception.d.ts +78 -0
  14. package/dist/channel-reception.d.ts.map +1 -0
  15. package/dist/channel-reception.js +219 -0
  16. package/dist/common.d.ts +1 -1
  17. package/dist/common.d.ts.map +1 -1
  18. package/dist/conversation-projection.d.ts +1 -1
  19. package/dist/conversation-projection.js +1 -1
  20. package/dist/herdr-workspace-digest.d.ts +151 -0
  21. package/dist/herdr-workspace-digest.d.ts.map +1 -0
  22. package/dist/herdr-workspace-digest.js +343 -0
  23. package/dist/index.d.ts +4 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +4 -0
  26. package/dist/machines.d.ts +233 -0
  27. package/dist/machines.d.ts.map +1 -0
  28. package/dist/machines.js +550 -0
  29. package/dist/mesh.d.ts +8 -0
  30. package/dist/mesh.d.ts.map +1 -1
  31. package/dist/runtime-catalog-contract.d.ts +1 -1
  32. package/dist/runtime-catalog-contract.d.ts.map +1 -1
  33. package/dist/runtime-catalog-contract.js +1 -1
  34. package/dist/runtime-catalog.generated.d.ts +34 -15
  35. package/dist/runtime-catalog.generated.d.ts.map +1 -1
  36. package/dist/runtime-catalog.generated.js +46 -19
  37. package/dist/runtime-execution.d.ts +1 -1
  38. package/dist/runtime-execution.d.ts.map +1 -1
  39. package/dist/scout-delivery.d.ts +1 -0
  40. package/dist/scout-delivery.d.ts.map +1 -1
  41. package/dist/terminal-host-topology.d.ts +20 -1
  42. package/dist/terminal-host-topology.d.ts.map +1 -1
  43. package/dist/terminal-host-topology.js +8 -2
  44. package/dist/transports.d.ts +39 -1
  45. package/dist/transports.d.ts.map +1 -1
  46. package/package.json +2 -2
  47. package/src/actors.ts +2 -0
  48. package/src/broker-routes.ts +17 -0
  49. package/src/channel-identity.ts +151 -0
  50. package/src/channel-invites.ts +343 -0
  51. package/src/channel-reception.ts +308 -0
  52. package/src/common.ts +1 -0
  53. package/src/conversation-projection.ts +1 -1
  54. package/src/herdr-workspace-digest.ts +458 -0
  55. package/src/index.ts +4 -0
  56. package/src/machines.ts +743 -0
  57. package/src/mesh.ts +8 -0
  58. package/src/runtime-catalog-contract.ts +1 -1
  59. package/src/runtime-catalog.generated.ts +46 -19
  60. package/src/runtime-catalog.v1.json +18 -8
  61. package/src/scout-delivery.ts +1 -0
  62. package/src/terminal-host-topology.ts +32 -2
  63. package/src/transports.ts +48 -0
package/src/mesh.ts CHANGED
@@ -89,6 +89,14 @@ export interface NodeDefinition {
89
89
  advertiseScope: AdvertiseScope;
90
90
  brokerUrl?: string;
91
91
  webUrl?: string;
92
+ /**
93
+ * The node's named web doorway (e.g. `m1.scout.local`), matching the edge's
94
+ * advertisedHost. `*.scout.local` names resolve to 127.0.0.1 on every LAN
95
+ * machine; the local edge recognizes them as peer doorways and proxies to
96
+ * this node's reachable route, so the name is a stable way to open a peer's
97
+ * Scout regardless of its current address.
98
+ */
99
+ webHost?: string;
92
100
  meshEntrypoints?: NodeMeshEntrypoint[];
93
101
  tailnetName?: string;
94
102
  capabilities?: string[];
@@ -2,7 +2,7 @@ import type { AgentHarness } from "./actors.js";
2
2
 
3
3
  /** Harness ids Scout can select for a new execution session. */
4
4
  export const SCOUT_LAUNCHABLE_HARNESSES = [
5
- "claude", "codex", "grok", "grok-acp", "kimi", "flue", "cursor", "opencode", "pi",
5
+ "claude", "codex", "grok", "grok-acp", "kimi", "flue", "cursor", "opencode", "pi", "devin",
6
6
  ] as const satisfies readonly AgentHarness[];
7
7
 
8
8
  export type ScoutLaunchableHarness = typeof SCOUT_LAUNCHABLE_HARNESSES[number];
@@ -2,7 +2,7 @@
2
2
 
3
3
  export const SCOUT_RUNTIME_CATALOG_DATA = {
4
4
  "schemaVersion": "openscout.runtime-catalog.v1",
5
- "revision": "2026-09-05.1",
5
+ "revision": "2026-09-14.1",
6
6
  "harnesses": [
7
7
  {
8
8
  "id": "claude",
@@ -161,7 +161,7 @@ export const SCOUT_RUNTIME_CATALOG_DATA = {
161
161
  "high",
162
162
  "xhigh"
163
163
  ],
164
- "defaultReasoningEffort": "medium",
164
+ "defaultReasoningEffort": "high",
165
165
  "models": [
166
166
  {
167
167
  "id": "grok-4.6",
@@ -177,14 +177,8 @@ export const SCOUT_RUNTIME_CATALOG_DATA = {
177
177
  "label": "Grok 4.5",
178
178
  "enabled": true,
179
179
  "family": "Grok",
180
- "version": "4.5"
181
- },
182
- {
183
- "id": "grok-4.3",
184
- "label": "Grok 4.3",
185
- "enabled": true,
186
- "family": "Grok",
187
- "version": "4.3"
180
+ "version": "4.5",
181
+ "contextWindowTokens": 500000
188
182
  }
189
183
  ]
190
184
  },
@@ -192,7 +186,13 @@ export const SCOUT_RUNTIME_CATALOG_DATA = {
192
186
  "id": "grok-acp",
193
187
  "label": "Grok",
194
188
  "enabled": true,
195
- "reasoningEfforts": null,
189
+ "reasoningEfforts": [
190
+ "low",
191
+ "medium",
192
+ "high",
193
+ "xhigh"
194
+ ],
195
+ "defaultReasoningEffort": "high",
196
196
  "models": [
197
197
  {
198
198
  "id": "grok-4.6",
@@ -208,14 +208,8 @@ export const SCOUT_RUNTIME_CATALOG_DATA = {
208
208
  "label": "Grok 4.5",
209
209
  "enabled": true,
210
210
  "family": "Grok",
211
- "version": "4.5"
212
- },
213
- {
214
- "id": "grok-4.3",
215
- "label": "Grok 4.3",
216
- "enabled": true,
217
- "family": "Grok",
218
- "version": "4.3"
211
+ "version": "4.5",
212
+ "contextWindowTokens": 500000
219
213
  }
220
214
  ]
221
215
  },
@@ -318,6 +312,39 @@ export const SCOUT_RUNTIME_CATALOG_DATA = {
318
312
  "enabled": true,
319
313
  "reasoningEfforts": null,
320
314
  "models": []
315
+ },
316
+ {
317
+ "id": "devin",
318
+ "label": "Devin",
319
+ "enabled": true,
320
+ "reasoningEfforts": null,
321
+ "models": [
322
+ {
323
+ "id": "swe-2-high",
324
+ "label": "SWE-2 High",
325
+ "enabled": true,
326
+ "default": true,
327
+ "family": "SWE",
328
+ "version": "2 High",
329
+ "contextWindowTokens": 262000
330
+ },
331
+ {
332
+ "id": "swe-2-medium",
333
+ "label": "SWE-2 Medium",
334
+ "enabled": true,
335
+ "family": "SWE",
336
+ "version": "2 Medium",
337
+ "contextWindowTokens": 262000
338
+ },
339
+ {
340
+ "id": "swe-2-max",
341
+ "label": "SWE-2 Max",
342
+ "enabled": true,
343
+ "family": "SWE",
344
+ "version": "2 Max",
345
+ "contextWindowTokens": 262000
346
+ }
347
+ ]
321
348
  }
322
349
  ]
323
350
  } as const;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": "openscout.runtime-catalog.v1",
3
- "revision": "2026-09-05.1",
3
+ "revision": "2026-09-14.1",
4
4
  "harnesses": [
5
5
  {
6
6
  "id": "claude",
@@ -40,22 +40,21 @@
40
40
  "enabled": true,
41
41
  "listed": false,
42
42
  "reasoningEfforts": ["low", "medium", "high", "xhigh"],
43
- "defaultReasoningEffort": "medium",
43
+ "defaultReasoningEffort": "high",
44
44
  "models": [
45
45
  { "id": "grok-4.6", "label": "Grok 4.6", "enabled": true, "default": true, "family": "Grok", "version": "4.6", "contextWindowTokens": 500000 },
46
- { "id": "grok-4.5", "label": "Grok 4.5", "enabled": true, "family": "Grok", "version": "4.5" },
47
- { "id": "grok-4.3", "label": "Grok 4.3", "enabled": true, "family": "Grok", "version": "4.3" }
46
+ { "id": "grok-4.5", "label": "Grok 4.5", "enabled": true, "family": "Grok", "version": "4.5", "contextWindowTokens": 500000 }
48
47
  ]
49
48
  },
50
49
  {
51
50
  "id": "grok-acp",
52
51
  "label": "Grok",
53
52
  "enabled": true,
54
- "reasoningEfforts": null,
53
+ "reasoningEfforts": ["low", "medium", "high", "xhigh"],
54
+ "defaultReasoningEffort": "high",
55
55
  "models": [
56
56
  { "id": "grok-4.6", "label": "Grok 4.6", "enabled": true, "default": true, "family": "Grok", "version": "4.6", "contextWindowTokens": 500000 },
57
- { "id": "grok-4.5", "label": "Grok 4.5", "enabled": true, "family": "Grok", "version": "4.5" },
58
- { "id": "grok-4.3", "label": "Grok 4.3", "enabled": true, "family": "Grok", "version": "4.3" }
57
+ { "id": "grok-4.5", "label": "Grok 4.5", "enabled": true, "family": "Grok", "version": "4.5", "contextWindowTokens": 500000 }
59
58
  ]
60
59
  },
61
60
  { "id": "kimi", "label": "Kimi Code", "enabled": true, "reasoningEfforts": null, "models": [] },
@@ -78,6 +77,17 @@
78
77
  { "id": "opencode/laguna-s-2.1-free", "label": "Laguna S 2.1 (free)", "enabled": true, "family": "Laguna", "version": "S 2.1 Free" }
79
78
  ]
80
79
  },
81
- { "id": "pi", "label": "Pi", "enabled": true, "reasoningEfforts": null, "models": [] }
80
+ { "id": "pi", "label": "Pi", "enabled": true, "reasoningEfforts": null, "models": [] },
81
+ {
82
+ "id": "devin",
83
+ "label": "Devin",
84
+ "enabled": true,
85
+ "reasoningEfforts": null,
86
+ "models": [
87
+ { "id": "swe-2-high", "label": "SWE-2 High", "enabled": true, "default": true, "family": "SWE", "version": "2 High", "contextWindowTokens": 262000 },
88
+ { "id": "swe-2-medium", "label": "SWE-2 Medium", "enabled": true, "family": "SWE", "version": "2 Medium", "contextWindowTokens": 262000 },
89
+ { "id": "swe-2-max", "label": "SWE-2 Max", "enabled": true, "family": "SWE", "version": "2 Max", "contextWindowTokens": 262000 }
90
+ ]
91
+ }
82
92
  ]
83
93
  }
@@ -63,6 +63,7 @@ export type ScoutOperatorSignal =
63
63
  replyExpectation: "required";
64
64
  /** What the agent is asking for. Never empty — that is the whole point. */
65
65
  question: string;
66
+ requestKind?: "permission";
66
67
  /** Optional discrete choices, when the answer is a selection. */
67
68
  options?: string[];
68
69
  /** Why the agent cannot continue without it. */
@@ -120,6 +120,21 @@ export type HerdrWorkspaceProjection = {
120
120
  tabs: HerdrTabProjection[];
121
121
  };
122
122
 
123
+ /**
124
+ * Why a projection is not live.
125
+ *
126
+ * `not_running` is the ordinary case: no herdr server answers for this session,
127
+ * so its persisted layout is the honest thing to show.
128
+ *
129
+ * `unreadable` is the case worth naming. A herdr server for this session IS
130
+ * running, but it did not answer the topology commands — a protocol skew
131
+ * between the installed client and a long-lived server is the common cause,
132
+ * and a busy server or a timeout look the same from here. Collapsing that into
133
+ * `not_running` would state, of live work, that it is not running. The
134
+ * projection says which it is so a reader never has to guess.
135
+ */
136
+ export type HerdrTopologyUnavailableReason = "not_running" | "unreadable";
137
+
123
138
  export type HerdrSessionTopology = {
124
139
  /** Herdr session name, e.g. "openscout". */
125
140
  session: string;
@@ -134,8 +149,23 @@ export type HerdrSessionTopology = {
134
149
  * projection is live.
135
150
  */
136
151
  savedAt?: number | null;
152
+ /**
153
+ * Why this projection is not live. Set only when `running` is false; absent
154
+ * on a live read. See {@link HerdrTopologyUnavailableReason}.
155
+ */
156
+ unavailable?: HerdrTopologyUnavailableReason | null;
137
157
  };
138
158
 
139
- export function emptyHerdrSessionTopology(session: string, running: boolean): HerdrSessionTopology {
140
- return { session, running, workspaces: [], observedAt: Date.now() };
159
+ export function emptyHerdrSessionTopology(
160
+ session: string,
161
+ running: boolean,
162
+ unavailable?: HerdrTopologyUnavailableReason | null,
163
+ ): HerdrSessionTopology {
164
+ return {
165
+ session,
166
+ running,
167
+ workspaces: [],
168
+ observedAt: Date.now(),
169
+ ...(running ? {} : { unavailable: unavailable ?? "not_running" }),
170
+ };
141
171
  }
package/src/transports.ts CHANGED
@@ -5,6 +5,11 @@ import type { InvocationRequest } from "./invocations.js";
5
5
  import type { NodeDefinition } from "./mesh.js";
6
6
  import type { MessageRecord } from "./messages.js";
7
7
  import type { CollaborationEvent, CollaborationRecord } from "./collaboration.js";
8
+ import type {
9
+ ChannelInviteRedemptionRequest,
10
+ ChannelInviteRoute,
11
+ ChannelInviteInvitee,
12
+ } from "./channel-invites.js";
8
13
 
9
14
  export interface SubscriptionRequest {
10
15
  actorId: ScoutId;
@@ -77,6 +82,46 @@ export interface CollaborationEventAppendCommand {
77
82
  event: CollaborationEvent;
78
83
  }
79
84
 
85
+ /**
86
+ * Invitation writes are broker commands rather than conversation upserts so
87
+ * the read-modify-write of a channel's invitation set happens inside the
88
+ * broker's serialized command queue. Two operators minting an invitation at
89
+ * the same instant must not clobber each other's record.
90
+ */
91
+ export interface ChannelInviteCreateCommand {
92
+ kind: "channel.invite.create";
93
+ channelId: ScoutId;
94
+ inviteId: ScoutId;
95
+ /** Digest only. The raw token never crosses this boundary. */
96
+ tokenHash: string;
97
+ tokenHint: string;
98
+ createdByActorId: ScoutId;
99
+ createdAt: number;
100
+ expiresAt: number | null;
101
+ maxRedemptions: number | null;
102
+ route: ChannelInviteRoute;
103
+ invitee?: ChannelInviteInvitee;
104
+ metadata?: MetadataMap;
105
+ }
106
+
107
+ export interface ChannelInviteRevokeCommand {
108
+ kind: "channel.invite.revoke";
109
+ channelId: ScoutId;
110
+ inviteId: ScoutId;
111
+ revokedByActorId: ScoutId;
112
+ revokedAt: number;
113
+ }
114
+
115
+ export interface ChannelInviteRedeemCommand {
116
+ kind: "channel.invite.redeem";
117
+ channelId: ScoutId;
118
+ /** Digest of the presented token; the broker matches, never the caller. */
119
+ tokenHash: string;
120
+ redemptionId: ScoutId;
121
+ redeemedAt: number;
122
+ request: ChannelInviteRedemptionRequest;
123
+ }
124
+
80
125
  export type ControlCommand =
81
126
  | NodeUpsertCommand
82
127
  | ActorUpsertCommand
@@ -86,6 +131,9 @@ export type ControlCommand =
86
131
  | BindingUpsertCommand
87
132
  | CollaborationUpsertCommand
88
133
  | CollaborationEventAppendCommand
134
+ | ChannelInviteCreateCommand
135
+ | ChannelInviteRevokeCommand
136
+ | ChannelInviteRedeemCommand
89
137
  | PostMessageCommand
90
138
  | InvokeAgentCommand
91
139
  | EnsureAwakeCommand