@adhdev/mesh-shared 1.0.82-rc.4 → 1.0.82-rc.41

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 (65) hide show
  1. package/dist/assistant-protocol.d.ts +161 -6
  2. package/dist/decision-push-relay.d.ts +20 -0
  3. package/dist/index.d.ts +11 -0
  4. package/dist/index.js +1197 -118
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1107 -118
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/launch-defaults.d.ts +196 -0
  9. package/dist/mesh-tool-names.d.ts +2 -2
  10. package/dist/mesh-vocabulary.d.ts +13 -4
  11. package/dist/mission-git-state.d.ts +83 -0
  12. package/dist/mission-items.d.ts +202 -0
  13. package/dist/node-facts.d.ts +75 -1
  14. package/dist/outbound-message.d.ts +9 -2
  15. package/dist/path-ownership.d.ts +1 -1
  16. package/dist/protocol/daemon-server.d.ts +42 -2
  17. package/dist/protocol/dashboard-daemon-p2p.d.ts +1 -1
  18. package/dist/protocol/dashboard-server.d.ts +20 -2
  19. package/dist/provider-approval.d.ts +36 -0
  20. package/dist/provider-question.d.ts +19 -0
  21. package/dist/quota-freshness.d.ts +65 -0
  22. package/dist/relay-reprobe.d.ts +52 -0
  23. package/dist/release.d.ts +90 -0
  24. package/dist/role-launch.d.ts +11 -0
  25. package/dist/session-launch.d.ts +10 -22
  26. package/dist/slot-proposal.d.ts +14 -0
  27. package/dist/task-source-phase.d.ts +75 -0
  28. package/dist/turn-evidence.d.ts +29 -13
  29. package/dist/turn-ipc-mission.d.ts +68 -1
  30. package/dist/turn-ipc-queue.d.ts +19 -0
  31. package/dist/turn-ipc.d.ts +2 -2
  32. package/dist/types.d.ts +1 -0
  33. package/dist/worker-protocol.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/src/assistant-protocol.ts +302 -6
  36. package/src/daemon-normalize.ts +7 -5
  37. package/src/decision-push-relay.ts +23 -0
  38. package/src/index.ts +12 -0
  39. package/src/keyed-doc-delta.ts +9 -1
  40. package/src/launch-defaults.ts +170 -0
  41. package/src/mesh-tool-names.ts +16 -0
  42. package/src/mesh-vocabulary.ts +12 -2
  43. package/src/mission-git-state.ts +112 -0
  44. package/src/mission-items.ts +421 -0
  45. package/src/node-facts.ts +70 -1
  46. package/src/outbound-message.ts +19 -0
  47. package/src/path-ownership.ts +4 -6
  48. package/src/protocol/daemon-server.ts +37 -2
  49. package/src/protocol/dashboard-server.ts +13 -2
  50. package/src/provider-approval.ts +59 -0
  51. package/src/provider-question.ts +31 -0
  52. package/src/quota-freshness.ts +139 -0
  53. package/src/relay-reprobe.ts +117 -0
  54. package/src/release.ts +121 -0
  55. package/src/role-launch.ts +51 -0
  56. package/src/session-launch.ts +17 -1
  57. package/src/slot-proposal.ts +61 -2
  58. package/src/task-source-phase.ts +61 -0
  59. package/src/turn-evidence.ts +27 -20
  60. package/src/turn-ipc-mission.ts +121 -11
  61. package/src/turn-ipc-queue.ts +29 -1
  62. package/src/turn-ipc-turn.ts +1 -1
  63. package/src/turn-ipc.ts +1 -0
  64. package/src/types.ts +1 -0
  65. package/src/worker-protocol.ts +15 -0
@@ -85,9 +85,46 @@ export interface MissionUpsertRequest {
85
85
  * this wire guard only checks SHAPE, not that decision.
86
86
  */
87
87
  brief?: MissionBriefWire | null
88
- }
89
-
90
- export interface MeshMissionRecordWire {
88
+ /**
89
+ * Structured-missions bundle A (design 2026-10-28 §5.1). Every key below is optional
90
+ * and ABSENT on a legacy call. `structured: true` is the caller's capability flag: the
91
+ * daemon only puts the new keys on the response (mission summary/outcome/version,
92
+ * `result`) when it is set, so an older mcp-server that never sends it keeps decoding
93
+ * byte-identical responses (mixed-version fleets, design §13.1).
94
+ */
95
+ structured?: boolean
96
+ summary?: string
97
+ /** One user/operator-visible sentence for the release CHANGELOG draft (design 2026-11-01-release-objects L5). `''` clears. */
98
+ releaseNote?: string
99
+ outcome?: string
100
+ outcomeReason?: string
101
+ /** Mission id open items move to when this call closes the mission (default: the carry-over mission). */
102
+ carryOverTo?: string
103
+ /** Route to the mesh's auto-created carry-over mission instead of `id`/`title` (decision requests without a mission). `title` may then be empty. */
104
+ toCarryOver?: boolean
105
+ itemsAdd?: readonly Record<string, unknown>[]
106
+ itemsUpdate?: readonly Record<string, unknown>[]
107
+ }
108
+
109
+ export interface MeshMissionOpenItemCountsWire {
110
+ remaining: number
111
+ live_check: number
112
+ decision: number
113
+ evidence: number
114
+ }
115
+
116
+ /** Structured-missions fields (only with `structured: true` on the request). */
117
+ export interface MeshMissionStructuredWire {
118
+ summary?: string
119
+ releaseNote?: string
120
+ outcome?: string
121
+ outcomeReason?: string
122
+ version?: number
123
+ carryOver?: boolean
124
+ openItems?: MeshMissionOpenItemCountsWire
125
+ }
126
+
127
+ export interface MeshMissionRecordWire extends MeshMissionStructuredWire {
91
128
  id: string
92
129
  meshId: string
93
130
  title: string
@@ -99,10 +136,30 @@ export interface MeshMissionRecordWire {
99
136
 
100
137
  export interface MissionUpsertResponse {
101
138
  mission: MeshMissionRecordWire
139
+ /** Structured calls only: per-item results, movedItems/movedTo, restoredItems, ownerConfirmationItemId, warnings. */
140
+ result?: Record<string, unknown>
141
+ }
142
+
143
+ const STRUCTURED_MISSION_KEYS = ['summary', 'releaseNote', 'outcome', 'outcomeReason', 'version', 'carryOver', 'openItems'] as const
144
+
145
+ function isOpenItemCountsWire(value: unknown): value is MeshMissionOpenItemCountsWire {
146
+ if (!isRecord(value) || !hasOnlyKeys(value, ['remaining', 'live_check', 'decision', 'evidence'])) return false
147
+ return (['remaining', 'live_check', 'decision', 'evidence'] as const).every((k) => isNonNegativeInt(value[k]))
148
+ }
149
+
150
+ function isStructuredMissionFields(value: Record<string, unknown>): boolean {
151
+ for (const k of ['summary', 'releaseNote', 'outcome', 'outcomeReason'] as const) {
152
+ if (value[k] !== undefined && typeof value[k] !== 'string') return false
153
+ }
154
+ if (value.version !== undefined && !isNonNegativeInt(value.version)) return false
155
+ if (value.carryOver !== undefined && typeof value.carryOver !== 'boolean') return false
156
+ if (value.openItems !== undefined && !isOpenItemCountsWire(value.openItems)) return false
157
+ return true
102
158
  }
103
159
 
104
160
  function isMeshMissionRecordWire(value: unknown): value is MeshMissionRecordWire {
105
- if (!isRecord(value) || !hasOnlyKeys(value, ['id', 'meshId', 'title', 'goal', 'status', 'brief'])) return false
161
+ if (!isRecord(value) || !hasOnlyKeys(value, ['id', 'meshId', 'title', 'goal', 'status', 'brief', ...STRUCTURED_MISSION_KEYS])) return false
162
+ if (!isStructuredMissionFields(value)) return false
106
163
  if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false
107
164
  if (typeof value.title !== 'string' || typeof value.goal !== 'string') return false
108
165
  if (!isMeshMissionStatusValue(value.status)) return false
@@ -111,11 +168,24 @@ function isMeshMissionRecordWire(value: unknown): value is MeshMissionRecordWire
111
168
  }
112
169
 
113
170
  function isMissionUpsertRequest(value: unknown): value is MissionUpsertRequest {
114
- if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'id', 'title', 'goal', 'status', 'brief'])) return false
171
+ if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'id', 'title', 'goal', 'status', 'brief', 'structured', 'summary', 'releaseNote', 'outcome', 'outcomeReason', 'carryOverTo', 'toCarryOver', 'itemsAdd', 'itemsUpdate'])) return false
115
172
  if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false
116
173
  if (!isEvidenceIdentifier(value.meshId)) return false
117
174
  if (value.id !== undefined && !isEvidenceIdentifier(value.id)) return false
118
- if (typeof value.title !== 'string' || value.title.trim().length === 0) return false
175
+ if (typeof value.title !== 'string') return false
176
+ // An empty title is allowed only when the daemon can supply one: an existing mission (id) or the carry-over mission.
177
+ if (value.title.trim().length === 0 && value.toCarryOver !== true && value.id === undefined) return false
178
+ if (value.structured !== undefined && typeof value.structured !== 'boolean') return false
179
+ if (value.toCarryOver !== undefined && typeof value.toCarryOver !== 'boolean') return false
180
+ for (const k of ['summary', 'releaseNote', 'outcome', 'outcomeReason'] as const) {
181
+ if (value[k] !== undefined && typeof value[k] !== 'string') return false
182
+ }
183
+ if (value.carryOverTo !== undefined && !isEvidenceIdentifier(value.carryOverTo)) return false
184
+ for (const k of ['itemsAdd', 'itemsUpdate'] as const) {
185
+ const list = value[k]
186
+ // Bounded only to keep the IPC message sane; per-entry shape/size is clamped (never rejected) by the daemon.
187
+ if (list !== undefined && (!Array.isArray(list) || list.length > 500 || !list.every(isRecord))) return false
188
+ }
119
189
  if (value.goal !== undefined && typeof value.goal !== 'string') return false
120
190
  if (value.status !== undefined && !isMeshMissionStatusValue(value.status)) return false
121
191
  if (value.brief !== undefined && value.brief !== null && !isMissionBriefWire(value.brief)) return false
@@ -127,7 +197,8 @@ export function decodeMissionUpsertRequest(value: unknown): MissionUpsertRequest
127
197
  }
128
198
 
129
199
  export function isMissionUpsertResponse(value: unknown): value is MissionUpsertResponse {
130
- return isRecord(value) && hasOnlyKeys(value, ['mission']) && isMeshMissionRecordWire(value.mission)
200
+ return isRecord(value) && hasOnlyKeys(value, ['mission', 'result']) && isMeshMissionRecordWire(value.mission)
201
+ && (value.result === undefined || isRecord(value.result))
131
202
  }
132
203
 
133
204
  export function decodeMissionUpsertResponse(value: unknown): MissionUpsertResponse | null {
@@ -207,6 +278,12 @@ export interface MissionListQueryRequest {
207
278
  * option except `historyIdLimit` is ignored. An older daemon rejects the key.
208
279
  */
209
280
  meshStatusView?: 'compact' | 'verbose'
281
+ /** Structured-missions capability flag (see MissionUpsertRequest.structured): rows then carry summary/outcome/openItems/carryOver/version. */
282
+ structured?: boolean
283
+ /** Structured only: attach each mission's items. */
284
+ items?: boolean
285
+ /** Structured only: attach each mission's change history (bounded tail). */
286
+ history?: boolean
210
287
  }
211
288
 
212
289
  export interface MeshMissionTaskAggregateWire {
@@ -221,6 +298,8 @@ export interface MeshMissionTaskAggregateWire {
221
298
  }
222
299
 
223
300
  export interface MeshMissionStatsWire {
301
+ /** Present on peers that project proven blocked outcomes separately. */
302
+ blocked?: number
224
303
  missionId: string
225
304
  taskCount: number
226
305
  completed: number
@@ -246,6 +325,16 @@ export interface MissionListSummaryVerboseWire {
246
325
  createdAt?: string
247
326
  updatedAt?: string
248
327
  closeCandidateEmittedAt?: string | null
328
+ /** Structured lists only. */
329
+ summary?: string
330
+ releaseNote?: string
331
+ outcome?: string
332
+ outcomeReason?: string
333
+ version?: number
334
+ carryOver?: boolean
335
+ openItems?: MeshMissionOpenItemCountsWire
336
+ items?: readonly Record<string, unknown>[]
337
+ history?: readonly Record<string, unknown>[]
249
338
  }
250
339
 
251
340
  /** Compact (default) mission row. `goalPreview`/`goalTruncated` present, `goal` absent. */
@@ -264,6 +353,16 @@ export interface MissionListSummarySlimWire {
264
353
  createdAt?: string
265
354
  updatedAt?: string
266
355
  closeCandidateEmittedAt?: string | null
356
+ /** Structured lists only. */
357
+ summary?: string
358
+ releaseNote?: string
359
+ outcome?: string
360
+ outcomeReason?: string
361
+ version?: number
362
+ carryOver?: boolean
363
+ openItems?: MeshMissionOpenItemCountsWire
364
+ items?: readonly Record<string, unknown>[]
365
+ history?: readonly Record<string, unknown>[]
267
366
  }
268
367
 
269
368
  export type MissionListSummaryWire = MissionListSummaryVerboseWire | MissionListSummarySlimWire
@@ -284,7 +383,10 @@ export interface MissionListQueryResponse {
284
383
  }
285
384
 
286
385
  function isMissionListQueryRequest(value: unknown): value is MissionListQueryRequest {
287
- if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'verbose', 'withStats', 'limit', 'historyIdLimit', 'meshStatusView'])) return false
386
+ if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'verbose', 'withStats', 'limit', 'historyIdLimit', 'meshStatusView', 'structured', 'items', 'history'])) return false
387
+ for (const k of ['structured', 'items', 'history'] as const) {
388
+ if (value[k] !== undefined && typeof value[k] !== 'boolean') return false
389
+ }
288
390
  if (value.meshStatusView !== undefined && value.meshStatusView !== 'compact' && value.meshStatusView !== 'verbose') return false
289
391
  if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false
290
392
  if (!isEvidenceIdentifier(value.meshId)) return false
@@ -313,12 +415,13 @@ function isMeshMissionTaskAggregateWire(value: unknown): value is MeshMissionTas
313
415
  }
314
416
 
315
417
  function isMeshMissionStatsWire(value: unknown): value is MeshMissionStatsWire {
316
- const keys = ['missionId', 'taskCount', 'completed', 'failed', 'totalDurationMs', 'wallClockMs', 'retries', 'incompleteTaskIds'] as const
418
+ const keys = ['missionId', 'taskCount', 'completed', 'failed', 'blocked', 'totalDurationMs', 'wallClockMs', 'retries', 'incompleteTaskIds'] as const
317
419
  if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false
318
420
  if (!isEvidenceIdentifier(value.missionId)) return false
319
421
  for (const k of ['taskCount', 'completed', 'failed', 'totalDurationMs', 'retries'] as const) {
320
422
  if (!isNonNegativeInt(value[k])) return false
321
423
  }
424
+ if (value.blocked !== undefined && !isNonNegativeInt(value.blocked)) return false
322
425
  if (value.wallClockMs !== null && !isNonNegativeInt(value.wallClockMs)) return false
323
426
  if (!Array.isArray(value.incompleteTaskIds) || !value.incompleteTaskIds.every(isEvidenceIdentifier)) return false
324
427
  return true
@@ -329,7 +432,7 @@ function isMissionListSummaryWire(value: unknown): value is MissionListSummaryWi
329
432
  const hasGoal = 'goal' in value
330
433
  const hasPreview = 'goalPreview' in value && 'goalTruncated' in value
331
434
  if (hasGoal === hasPreview) return false // exactly one of the two shapes
332
- const baseKeys = ['id', 'meshId', 'title', 'status', 'tasks', 'stats', 'brief', 'createdAt', 'updatedAt', 'closeCandidateEmittedAt'] as const
435
+ const baseKeys = ['id', 'meshId', 'title', 'status', 'tasks', 'stats', 'brief', 'createdAt', 'updatedAt', 'closeCandidateEmittedAt', ...STRUCTURED_MISSION_KEYS, 'items', 'history'] as const
333
436
  const allowed = hasGoal ? [...baseKeys, 'goal'] : [...baseKeys, 'goalPreview', 'goalTruncated']
334
437
  if (!hasOnlyKeys(value, allowed)) return false
335
438
  if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false
@@ -343,6 +446,10 @@ function isMissionListSummaryWire(value: unknown): value is MissionListSummaryWi
343
446
  if (value.createdAt !== undefined && typeof value.createdAt !== 'string') return false
344
447
  if (value.updatedAt !== undefined && typeof value.updatedAt !== 'string') return false
345
448
  if (value.closeCandidateEmittedAt !== undefined && value.closeCandidateEmittedAt !== null && typeof value.closeCandidateEmittedAt !== 'string') return false
449
+ if (!isStructuredMissionFields(value)) return false
450
+ for (const k of ['items', 'history'] as const) {
451
+ if (value[k] !== undefined && (!Array.isArray(value[k]) || !(value[k] as unknown[]).every(isRecord))) return false
452
+ }
346
453
  return true
347
454
  }
348
455
 
@@ -580,6 +687,8 @@ export interface LedgerQueryEntryWire {
580
687
  }
581
688
 
582
689
  export interface LedgerQuerySummaryWire {
690
+ /** Absent on older peers; never folded into failed by the decoder. */
691
+ taskBlocked?: number
583
692
  meshId: string
584
693
  totalEntries: number
585
694
  taskDispatched: number
@@ -625,12 +734,13 @@ function isLedgerQueryEntryWire(value: unknown): value is LedgerQueryEntryWire {
625
734
  }
626
735
 
627
736
  function isLedgerQuerySummaryWire(value: unknown): value is LedgerQuerySummaryWire {
628
- const keys = ['meshId', 'totalEntries', 'taskDispatched', 'taskCompleted', 'taskFailed', 'taskStalled', 'sessionLaunched', 'checkpointCreated', 'lastActivityAt', 'recentFailures'] as const
737
+ const keys = ['meshId', 'totalEntries', 'taskDispatched', 'taskCompleted', 'taskFailed', 'taskBlocked', 'taskStalled', 'sessionLaunched', 'checkpointCreated', 'lastActivityAt', 'recentFailures'] as const
629
738
  if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false
630
739
  if (!isEvidenceIdentifier(value.meshId)) return false
631
740
  for (const k of ['totalEntries', 'taskDispatched', 'taskCompleted', 'taskFailed', 'taskStalled', 'sessionLaunched', 'checkpointCreated', 'recentFailures'] as const) {
632
741
  if (!isNonNegativeInt(value[k])) return false
633
742
  }
743
+ if (value.taskBlocked !== undefined && !isNonNegativeInt(value.taskBlocked)) return false
634
744
  if (value.lastActivityAt !== null && typeof value.lastActivityAt !== 'string') return false
635
745
  return true
636
746
  }
@@ -135,6 +135,8 @@ export interface QueueQueryResponse {
135
135
  counts?: Record<string, number>
136
136
  /** `withCounts` + `historicalOlderThanMs`: terminal rows older than that age. */
137
137
  oldHistoricalCount?: number
138
+ /** Included in counts.blocked, derived from proven worker reports; stored failed rows stay unchanged. */
139
+ legacyReportedBlockedCount?: number
138
140
  /** `withDependencyHeads`. */
139
141
  dependencyHeads?: readonly QueueDependencyHeadWire[]
140
142
  }
@@ -159,9 +161,10 @@ function isQueueDependencyHeadWire(value: unknown): value is QueueDependencyHead
159
161
  }
160
162
 
161
163
  function isQueueQueryResponse(value: unknown): value is QueueQueryResponse {
162
- if (!isRecord(value) || !hasOnlyKeys(value, ['entries', 'counts', 'oldHistoricalCount', 'dependencyHeads'])) return false
164
+ if (!isRecord(value) || !hasOnlyKeys(value, ['entries', 'counts', 'oldHistoricalCount', 'legacyReportedBlockedCount', 'dependencyHeads'])) return false
163
165
  if (!Array.isArray(value.entries) || !value.entries.every(isQueueEntryWire)) return false
164
166
  if (value.counts !== undefined && (!isRecord(value.counts) || !Object.values(value.counts).every(isNonNegativeInt))) return false
167
+ if (value.legacyReportedBlockedCount !== undefined && !isNonNegativeInt(value.legacyReportedBlockedCount)) return false
165
168
  if (value.oldHistoricalCount !== undefined && !isNonNegativeInt(value.oldHistoricalCount)) return false
166
169
  if (value.dependencyHeads !== undefined && (!Array.isArray(value.dependencyHeads) || !value.dependencyHeads.every(isQueueDependencyHeadWire))) return false
167
170
  return true
@@ -491,3 +494,28 @@ function isRecoveryContextQueryResponse(value: unknown): value is RecoveryContex
491
494
  export function decodeRecoveryContextQueryResponse(value: unknown): RecoveryContextQueryResponse | null {
492
495
  return isRecoveryContextQueryResponse(value) ? value : null
493
496
  }
497
+
498
+ // ── queue_revise: host-authenticated pending CAS, never a force requeue ──
499
+ export interface QueueReviseRequest {
500
+ v: typeof TURN_IPC_PROTOCOL_VERSION
501
+ meshId: string
502
+ taskId: string
503
+ expectedRevision: number
504
+ patch: { message?: string; ownedPaths?: string[]; phase?: 'source' | 'integration'; dependsOn?: string[]; routingPreferences?: import('./task-source-phase').MeshRoutingPreferences; review?: import('./task-source-phase').MeshReviewConstraint }
505
+ }
506
+ export type QueueReviseResponse = QueueRequeueResponse
507
+ export function decodeQueueReviseRequest(value: unknown): QueueReviseRequest | null {
508
+ if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'expectedRevision', 'patch'])
509
+ || value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId) || !isEvidenceIdentifier(value.taskId)
510
+ || !Number.isSafeInteger(value.expectedRevision) || (value.expectedRevision as number) < 0
511
+ || !isRecord(value.patch) || !Object.keys(value.patch).length
512
+ || !hasOnlyKeys(value.patch, ['message', 'ownedPaths', 'phase', 'dependsOn', 'routingPreferences', 'review'])) return null
513
+ const p = value.patch
514
+ if (p.message !== undefined && (typeof p.message !== 'string' || !p.message.trim())) return null
515
+ if (p.phase !== undefined && p.phase !== 'source' && p.phase !== 'integration') return null
516
+ for (const key of ['ownedPaths', 'dependsOn']) {
517
+ if (p[key] !== undefined && (!Array.isArray(p[key]) || !(p[key] as unknown[]).every(x => typeof x === 'string' && !!x.trim()))) return null
518
+ }
519
+ return value as unknown as QueueReviseRequest
520
+ }
521
+ export const decodeQueueReviseResponse = decodeQueueRequeueResponse
@@ -66,7 +66,7 @@ function isTurnObserveResponse(value: unknown): value is TurnObserveResponse {
66
66
  && (value.outcome === undefined || isTurnOutcomeValue(value.outcome))
67
67
  }
68
68
 
69
- const TURN_OUTCOMES_LOCAL = ['completed', 'failed', 'cancelled'] as const
69
+ const TURN_OUTCOMES_LOCAL = ['completed', 'blocked', 'failed', 'cancelled'] as const
70
70
  function isTurnOutcomeValue(value: unknown): value is TurnOutcome {
71
71
  return typeof value === 'string' && (TURN_OUTCOMES_LOCAL as readonly string[]).includes(value)
72
72
  }
package/src/turn-ipc.ts CHANGED
@@ -132,6 +132,7 @@ export const TURN_IPC_COMMANDS = [
132
132
  'queue_enqueue_batch',
133
133
  'queue_cancel',
134
134
  'queue_requeue',
135
+ 'queue_revise',
135
136
  'direct_dispatch_record',
136
137
  'active_work_query',
137
138
  'recovery_context_query',
package/src/types.ts CHANGED
@@ -137,6 +137,7 @@ export interface MeshNodeIdentified {
137
137
  }
138
138
 
139
139
  export interface RepoMeshSessionStatus {
140
+ providerApproval?: import('./provider-approval').ProviderApproval | null;
140
141
  sessionId: string
141
142
  providerType?: string
142
143
  state?: string
@@ -40,6 +40,21 @@ export const WORKER_TOOLS = [
40
40
  'git_status',
41
41
  'git_log',
42
42
  'git_diff',
43
+ 'driver_list',
44
+ 'driver_describe',
45
+ 'driver_invoke',
46
+ 'driver_scaffold',
47
+ 'driver_validate',
48
+ 'driver_export',
49
+ 'driver_install',
50
+ 'artifact_register',
51
+ 'artifact_list',
52
+ 'artifact_read',
53
+ // Contract versioning (Cut A): exact pinned-unit reads (E2), the explicit
54
+ // read claim (C1) and the authoritative head/notice pull.
55
+ 'contract_read',
56
+ 'contract_observe',
57
+ 'contract_current',
43
58
  ] as const
44
59
 
45
60
  export type WorkerTool = typeof WORKER_TOOLS[number]