@adhdev/mesh-shared 1.0.82-rc.33 → 1.0.82-rc.35

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/dist/index.js CHANGED
@@ -38,12 +38,15 @@ __export(index_exports, {
38
38
  CANCEL_REASONS: () => CANCEL_REASONS,
39
39
  CANONICAL_MESH_TOOL_COUNT: () => CANONICAL_MESH_TOOL_COUNT,
40
40
  CANONICAL_MESH_TOOL_NAMES: () => CANONICAL_MESH_TOOL_NAMES,
41
+ CARRY_OVER_MISSION_GOAL: () => CARRY_OVER_MISSION_GOAL,
42
+ CARRY_OVER_MISSION_TITLE: () => CARRY_OVER_MISSION_TITLE,
41
43
  CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX: () => CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX,
42
44
  CLAUDE_TUI_REVIEW_UNCONFIRMED_PREFIX: () => CLAUDE_TUI_REVIEW_UNCONFIRMED_PREFIX,
43
45
  CLI_SLOT_RECIPES: () => CLI_SLOT_RECIPES,
44
46
  COMMIT_STRENGTHS: () => COMMIT_STRENGTHS,
45
47
  CONSUME_PROFILES: () => CONSUME_PROFILES,
46
48
  COORDINATOR_ACK_OUTCOMES: () => COORDINATOR_ACK_OUTCOMES,
49
+ COORDINATOR_SETTABLE_ITEM_STATES: () => COORDINATOR_SETTABLE_ITEM_STATES,
47
50
  DAEMON_METADATA_DOC_SPEC: () => DAEMON_METADATA_DOC_SPEC,
48
51
  DAEMON_P2P_SIGNAL_TYPES: () => DAEMON_P2P_SIGNAL_TYPES,
49
52
  DAEMON_STATUS_EVENT_NAMES: () => DAEMON_STATUS_EVENT_NAMES,
@@ -56,6 +59,11 @@ __export(index_exports, {
56
59
  DASHBOARD_TO_DAEMON_P2P_TYPES: () => DASHBOARD_TO_DAEMON_P2P_TYPES,
57
60
  DASHBOARD_TO_USER_SESSION_TYPES: () => DASHBOARD_TO_USER_SESSION_TYPES,
58
61
  DASHBOARD_WIRE_VERSION: () => DASHBOARD_WIRE_VERSION,
62
+ DECISION_PUSH_OPTIONS_MAX: () => DECISION_PUSH_OPTIONS_MAX,
63
+ DECISION_PUSH_OPTION_LABEL_MAX: () => DECISION_PUSH_OPTION_LABEL_MAX,
64
+ DECISION_PUSH_QUESTION_MAX: () => DECISION_PUSH_QUESTION_MAX,
65
+ DECISION_PUSH_RELAY_COMMAND: () => DECISION_PUSH_RELAY_COMMAND,
66
+ DECISION_PUSH_RELAY_SOURCE: () => DECISION_PUSH_RELAY_SOURCE,
59
67
  DEFAULT_DIFFICULTY_BRAINS: () => DEFAULT_DIFFICULTY_BRAINS,
60
68
  DELIVERY_OUTCOMES: () => DELIVERY_OUTCOMES,
61
69
  DELIVERY_VIAS: () => DELIVERY_VIAS,
@@ -67,6 +75,7 @@ __export(index_exports, {
67
75
  LAUNCH_DEFAULT_ERROR_CODES: () => LAUNCH_DEFAULT_ERROR_CODES,
68
76
  LAUNCH_DEFAULT_ROLES: () => LAUNCH_DEFAULT_ROLES,
69
77
  LAUNCH_DEFAULT_SOURCES: () => LAUNCH_DEFAULT_SOURCES,
78
+ LEGACY_CARRY_OVER_MISSION_TITLE: () => LEGACY_CARRY_OVER_MISSION_TITLE,
70
79
  LIVENESS_RESULTS: () => LIVENESS_RESULTS,
71
80
  MAX_MESH_RECORD_STRING: () => MAX_MESH_RECORD_STRING,
72
81
  MAX_OWNED_PATHS: () => MAX_OWNED_PATHS,
@@ -92,6 +101,14 @@ __export(index_exports, {
92
101
  MESH_TOPIC_ENTRY_KINDS: () => MESH_TOPIC_ENTRY_KINDS,
93
102
  MESH_TOPIC_PROTOCOL_VERSION: () => MESH_TOPIC_PROTOCOL_VERSION,
94
103
  MISSION_BRIEF_RENDER_MAX_CHARS: () => MISSION_BRIEF_RENDER_MAX_CHARS,
104
+ MISSION_DECISION_ON_DUE: () => MISSION_DECISION_ON_DUE,
105
+ MISSION_DECISION_OPTION_IDS: () => MISSION_DECISION_OPTION_IDS,
106
+ MISSION_DECISION_URGENCIES: () => MISSION_DECISION_URGENCIES,
107
+ MISSION_ITEM_KINDS: () => MISSION_ITEM_KINDS,
108
+ MISSION_ITEM_STATES: () => MISSION_ITEM_STATES,
109
+ MISSION_LIMITS: () => MISSION_LIMITS,
110
+ MISSION_OUTCOMES: () => MISSION_OUTCOMES,
111
+ MISSION_REF_KINDS: () => MISSION_REF_KINDS,
95
112
  MODEL_AXIS_SOURCES: () => MODEL_AXIS_SOURCES,
96
113
  MODEL_SELECTION_HISTORY_LIMIT: () => MODEL_SELECTION_HISTORY_LIMIT,
97
114
  MeshChunkAssembler: () => MeshChunkAssembler,
@@ -105,6 +122,9 @@ __export(index_exports, {
105
122
  OPERATOR_STATUS_REASON_VALUES: () => OPERATOR_STATUS_REASON_VALUES,
106
123
  OPERATOR_STATUS_VALUES: () => OPERATOR_STATUS_VALUES,
107
124
  OUTBOUND_MESSAGE_ORIGINS: () => OUTBOUND_MESSAGE_ORIGINS,
125
+ OWNER_ABANDON_CONFIRM_KEY_PREFIX: () => OWNER_ABANDON_CONFIRM_KEY_PREFIX,
126
+ OWNER_ABANDON_CONFIRM_OPTIONS: () => OWNER_ABANDON_CONFIRM_OPTIONS,
127
+ OWNER_ABANDON_CONFIRM_QUESTION: () => OWNER_ABANDON_CONFIRM_QUESTION,
108
128
  P2P_SIGNAL_TYPES: () => P2P_SIGNAL_TYPES,
109
129
  PROVIDER_FAILURES: () => PROVIDER_FAILURES,
110
130
  QUOTA_BACKFILL_HORIZON_MS: () => QUOTA_BACKFILL_HORIZON_MS,
@@ -112,9 +132,13 @@ __export(index_exports, {
112
132
  QUOTA_SUPPORTED_PROVIDERS: () => QUOTA_SUPPORTED_PROVIDERS,
113
133
  RECENT_SESSION_BUCKETS: () => RECENT_SESSION_BUCKETS,
114
134
  RECLAIMING_SEND_REFUSALS: () => RECLAIMING_SEND_REFUSALS,
135
+ RELAY_REPROBE_BASE_DELAY_MS: () => RELAY_REPROBE_BASE_DELAY_MS,
136
+ RELAY_REPROBE_JITTER_RATIO: () => RELAY_REPROBE_JITTER_RATIO,
137
+ RELAY_REPROBE_MAX_DELAY_MS: () => RELAY_REPROBE_MAX_DELAY_MS,
115
138
  RELEASE_CHANNELS: () => RELEASE_CHANNELS,
116
139
  REMOVED_MESH_TOOLS: () => REMOVED_MESH_TOOLS,
117
140
  RETIRED_MESH_TOOLS: () => RETIRED_MESH_TOOLS,
141
+ RelayReprobeScheduler: () => RelayReprobeScheduler,
118
142
  SEND_POLICY_MODES: () => SEND_POLICY_MODES,
119
143
  SEND_REFUSAL_REASONS: () => SEND_REFUSAL_REASONS,
120
144
  SERVER_STATUS_EVENT_NAMES: () => SERVER_STATUS_EVENT_NAMES,
@@ -152,6 +176,8 @@ __export(index_exports, {
152
176
  VERSION_UPDATE_REASONS: () => VERSION_UPDATE_REASONS,
153
177
  VIEWER_TO_SHARED_SESSION_TYPES: () => VIEWER_TO_SHARED_SESSION_TYPES,
154
178
  WORKER_BRANCH_STATES: () => WORKER_BRANCH_STATES,
179
+ WORKER_COMMITS_MAX: () => WORKER_COMMITS_MAX,
180
+ WORKER_DECISIONS_NEEDED_MAX: () => WORKER_DECISIONS_NEEDED_MAX,
155
181
  WORKER_PROTOCOL_FOOTER_MARKER: () => WORKER_PROTOCOL_FOOTER_MARKER,
156
182
  WORKER_REPORT_OUTCOMES: () => WORKER_REPORT_OUTCOMES,
157
183
  WORKER_REPORT_SUMMARY_MAX_CHARS: () => WORKER_REPORT_SUMMARY_MAX_CHARS,
@@ -159,11 +185,13 @@ __export(index_exports, {
159
185
  appendWorkerProtocolFooter: () => appendWorkerProtocolFooter,
160
186
  argsCarryStatusProbeMarker: () => argsCarryStatusProbeMarker,
161
187
  assessQuotaFreshness: () => assessQuotaFreshness,
188
+ boundEventPayload: () => boundEventPayload,
162
189
  buildSlotProposal: () => buildSlotProposal,
163
190
  canonicalDaemonId: () => canonicalDaemonId,
164
191
  classifySessionStatus: () => classifySessionStatus,
165
192
  compareDashboardWireVersion: () => compareDashboardWireVersion,
166
193
  compareSemver: () => compareSemver,
194
+ computeRelayReprobeDelay: () => computeRelayReprobeDelay,
167
195
  daemonIdsEquivalent: () => daemonIdsEquivalent,
168
196
  decodeActiveWorkQueryRequest: () => decodeActiveWorkQueryRequest,
169
197
  decodeActiveWorkQueryResponse: () => decodeActiveWorkQueryResponse,
@@ -227,6 +255,7 @@ __export(index_exports, {
227
255
  decodeUserSessionToDashboard: () => decodeUserSessionToDashboard,
228
256
  decodeViewerToSharedSession: () => decodeViewerToSharedSession,
229
257
  defaultProviderPriorityFromNodeFacts: () => defaultProviderPriorityFromNodeFacts,
258
+ deriveItemDedupeKey: () => deriveItemDedupeKey,
230
259
  deriveProviderPriorityFromSlots: () => deriveProviderPriorityFromSlots,
231
260
  deriveSlotsFromLegacy: () => deriveSlotsFromLegacy,
232
261
  describeModelSelection: () => describeModelSelection,
@@ -238,6 +267,7 @@ __export(index_exports, {
238
267
  findOwnershipConflicts: () => findOwnershipConflicts,
239
268
  foldKeyedDoc: () => foldKeyedDoc,
240
269
  followedRemoteProjectKey: () => followedRemoteProjectKey,
270
+ followerOpPermitted: () => followerOpPermitted,
241
271
  formatQuotaAccount: () => formatQuotaAccount,
242
272
  hasGitStatusEvidence: () => hasGitStatusEvidence,
243
273
  hasWorkerProtocolFooter: () => hasWorkerProtocolFooter,
@@ -247,6 +277,8 @@ __export(index_exports, {
247
277
  isAssistantTool: () => isAssistantTool,
248
278
  isBlockedStatus: () => isBlockedStatus,
249
279
  isBusyStatus: () => isBusyStatus,
280
+ isCarryOverMissionRecord: () => isCarryOverMissionRecord,
281
+ isCarryOverMissionTitle: () => isCarryOverMissionTitle,
250
282
  isChunkType: () => isChunkType,
251
283
  isCommitStrength: () => isCommitStrength,
252
284
  isDaemonDirectCommandType: () => isDaemonDirectCommandType,
@@ -279,6 +311,7 @@ __export(index_exports, {
279
311
  isMeshTerminalTaskStatus: () => isMeshTerminalTaskStatus,
280
312
  isMeshTopicEntry: () => isMeshTopicEntry,
281
313
  isMessageId: () => isMessageId,
314
+ isMissionOutcome: () => isMissionOutcome,
282
315
  isMissionUpsertResponse: () => isMissionUpsertResponse,
283
316
  isModelAxisSource: () => isModelAxisSource,
284
317
  isNativeMarkerRef: () => isNativeMarkerRef,
@@ -329,16 +362,24 @@ __export(index_exports, {
329
362
  minutesUntilQuotaCheck: () => minutesUntilQuotaCheck,
330
363
  normalizeAuthOkLimits: () => normalizeAuthOkLimits,
331
364
  normalizeBrainSlot: () => normalizeBrainSlot,
365
+ normalizeDecisionInput: () => normalizeDecisionInput,
332
366
  normalizeDifficultyBrainMap: () => normalizeDifficultyBrainMap,
367
+ normalizeForDedupe: () => normalizeForDedupe,
333
368
  normalizeGitStatus: () => normalizeGitStatus,
334
369
  normalizeMeshNodeFacts: () => normalizeMeshNodeFacts,
335
370
  normalizeMeshNodeId: () => normalizeMeshNodeId,
336
371
  normalizeMeshSessionRecord: () => normalizeMeshSessionRecord,
337
372
  normalizeMeshWorkspaceForCompare: () => normalizeMeshWorkspaceForCompare,
338
373
  normalizeMissionBrief: () => normalizeMissionBrief,
374
+ normalizeMissionItemInput: () => normalizeMissionItemInput,
375
+ normalizeMissionItemUpdate: () => normalizeMissionItemUpdate,
376
+ normalizeMissionRefs: () => normalizeMissionRefs,
377
+ normalizeMissionSummary: () => normalizeMissionSummary,
339
378
  normalizeNodeCapabilitySlot: () => normalizeNodeCapabilitySlot,
340
379
  normalizeNodeCapabilitySlots: () => normalizeNodeCapabilitySlots,
380
+ normalizeOutcomeReason: () => normalizeOutcomeReason,
341
381
  normalizeOwnedPaths: () => normalizeOwnedPaths,
382
+ normalizeReportCommits: () => normalizeReportCommits,
342
383
  normalizeSessionStatus: () => normalizeSessionStatus,
343
384
  normalizeThinkingLevel: () => normalizeThinkingLevel,
344
385
  orderProvidersByBuiltinPreference: () => orderProvidersByBuiltinPreference,
@@ -378,6 +419,7 @@ __export(index_exports, {
378
419
  summarizeGitShape: () => summarizeGitShape,
379
420
  supportsQuota: () => supportsQuota,
380
421
  touchedFilesOutsideOwnership: () => touchedFilesOutsideOwnership,
422
+ truncateMissionText: () => truncateMissionText,
381
423
  unwrapPastedContent: () => unwrapPastedContent,
382
424
  withStatusProbeMarker: () => withStatusProbeMarker
383
425
  });
@@ -1158,6 +1200,7 @@ var CANONICAL_MESH_TOOL_NAMES = [
1158
1200
  "mesh_list_pending_approvals",
1159
1201
  "mesh_create",
1160
1202
  "mesh_add_node",
1203
+ "mesh_reattach_source_parent",
1161
1204
  "mesh_attach_remote",
1162
1205
  "mesh_clone_node",
1163
1206
  "mesh_remove_node",
@@ -1181,7 +1224,9 @@ var CANONICAL_MESH_TOOL_NAMES = [
1181
1224
  "mesh_node_slots",
1182
1225
  "driver_list",
1183
1226
  "driver_describe",
1184
- "artifact_list"
1227
+ "artifact_list",
1228
+ "artifact_read",
1229
+ "artifact_register"
1185
1230
  ];
1186
1231
  var CANONICAL_MESH_TOOL_COUNT = CANONICAL_MESH_TOOL_NAMES.length;
1187
1232
  var RETIRED_MESH_TOOLS = {
@@ -1491,9 +1536,15 @@ var DAEMON_STATUS_EVENT_NAMES = [
1491
1536
  "agent:waiting_choice",
1492
1537
  "agent:generating_completed",
1493
1538
  "agent:stopped",
1494
- "monitor:no_progress"
1539
+ "monitor:no_progress",
1540
+ // An owner decision (structured missions) needs the owner. Server-bound for the push only;
1541
+ // the dashboard learns about decisions over P2P (`mission_decisions_list`).
1542
+ "agent:decision_needed"
1495
1543
  ];
1496
1544
  var isDaemonStatusEventName = makeTypeGuard(DAEMON_STATUS_EVENT_NAMES);
1545
+ var DECISION_PUSH_QUESTION_MAX = 80;
1546
+ var DECISION_PUSH_OPTION_LABEL_MAX = 24;
1547
+ var DECISION_PUSH_OPTIONS_MAX = 3;
1497
1548
  var RELEASE_CHANNELS = ["stable", "preview"];
1498
1549
  var NPM_UPDATE_TAGS = ["latest", "next"];
1499
1550
  var VERSION_UPDATE_REASONS = ["force_update_below", "major_minor_mismatch", "patch_mismatch", "daemon_ahead"];
@@ -2067,7 +2118,18 @@ var WORKER_TOOLS = [
2067
2118
  "driver_list",
2068
2119
  "driver_describe",
2069
2120
  "driver_invoke",
2070
- "artifact_register"
2121
+ "driver_scaffold",
2122
+ "driver_validate",
2123
+ "driver_export",
2124
+ "driver_install",
2125
+ "artifact_register",
2126
+ "artifact_list",
2127
+ "artifact_read",
2128
+ // Contract versioning (Cut A): exact pinned-unit reads (E2), the explicit
2129
+ // read claim (C1) and the authoritative head/notice pull.
2130
+ "contract_read",
2131
+ "contract_observe",
2132
+ "contract_current"
2071
2133
  ];
2072
2134
  var WORKER_TOOL_SET = new Set(WORKER_TOOLS);
2073
2135
  function isWorkerTool(value) {
@@ -2168,7 +2230,11 @@ var ASSISTANT_TOOLS = [
2168
2230
  "launch_defaults",
2169
2231
  "launch_defaults_set",
2170
2232
  "driver_list",
2171
- "driver_describe"
2233
+ "driver_describe",
2234
+ "artifact_list",
2235
+ "artifact_read",
2236
+ "decision_answer",
2237
+ "decision_request"
2172
2238
  ];
2173
2239
  var ASSISTANT_TOOL_SET = new Set(ASSISTANT_TOOLS);
2174
2240
  function isAssistantTool(value) {
@@ -2196,6 +2262,12 @@ var ASSISTANT_VERB = {
2196
2262
  projectNote: "assistant_project_note",
2197
2263
  launchDefaults: "assistant_launch_defaults",
2198
2264
  launchDefaultsSet: "assistant_launch_defaults_set",
2265
+ artifactList: "assistant_artifact_list",
2266
+ artifactRead: "assistant_artifact_read",
2267
+ /** Owner-decision inbox (structured-missions design 2026-10-28 §6.3): the owner's words recorded as answers. */
2268
+ decisionAnswer: "assistant_decision_answer",
2269
+ /** Register a plain-text question a coordinator put to the owner as a decision item (§5.2). */
2270
+ decisionRequest: "assistant_decision_request",
2199
2271
  // assistant-side daemon verbs without a tool of the same name
2200
2272
  launch: "launch_assistant",
2201
2273
  pendingRelays: "assistant_pending_relays",
@@ -2225,9 +2297,13 @@ var ASSISTANT_TOOL_VERBS = {
2225
2297
  skill_manage: ASSISTANT_VERB.skillManage,
2226
2298
  project_note: ASSISTANT_VERB.projectNote,
2227
2299
  launch_defaults: ASSISTANT_VERB.launchDefaults,
2228
- launch_defaults_set: ASSISTANT_VERB.launchDefaultsSet
2300
+ launch_defaults_set: ASSISTANT_VERB.launchDefaultsSet,
2301
+ artifact_list: ASSISTANT_VERB.artifactList,
2302
+ artifact_read: ASSISTANT_VERB.artifactRead,
2303
+ decision_answer: ASSISTANT_VERB.decisionAnswer,
2304
+ decision_request: ASSISTANT_VERB.decisionRequest
2229
2305
  };
2230
- var ASSISTANT_WRITE_TOOLS = ["project_watch", "assistant_action", "memory", "skill_manage", "project_note", "project_send", "project_add", "project_attach_remote", "launch_defaults_set"];
2306
+ var ASSISTANT_WRITE_TOOLS = ["project_watch", "assistant_action", "memory", "skill_manage", "project_note", "project_send", "project_add", "project_attach_remote", "launch_defaults_set", "decision_answer", "decision_request"];
2231
2307
  var ASSISTANT_OWNER_VERBS = [
2232
2308
  ASSISTANT_VERB.executionSettings,
2233
2309
  ASSISTANT_VERB.stagedResolve,
@@ -2248,11 +2324,22 @@ var ASSISTANT_REMOTE_PROJECT_COMMAND = "assistant_remote_project";
2248
2324
  var ASSISTANT_REMOTE_PROJECT_CATALOG_COMMAND = "assistant_remote_project_catalog";
2249
2325
  var ASSISTANT_REMOTE_PROJECT_ACCESS_COMMAND = "assistant_remote_project_access";
2250
2326
  var ASSISTANT_REMOTE_FOLLOW_COMMAND = "assistant_remote_follow";
2251
- var ASSISTANT_FOLLOWER_ALLOWED_OPS = ["status", "read", "poll", "report", "send"];
2327
+ var ASSISTANT_FOLLOWER_ALLOWED_OPS = ["status", "read", "poll", "report", "send", "artifact_list", "artifact_read", "decision_list", "decision_answer", "decision_request"];
2252
2328
  var ASSISTANT_FOLLOWER_ALLOWED_OP_SET = new Set(ASSISTANT_FOLLOWER_ALLOWED_OPS);
2253
2329
  function isAssistantFollowerAllowedOp(value) {
2254
2330
  return typeof value === "string" && ASSISTANT_FOLLOWER_ALLOWED_OP_SET.has(value);
2255
2331
  }
2332
+ var DECISION_OP_IMPLIED_BY = {
2333
+ decision_list: "status",
2334
+ decision_answer: "send",
2335
+ decision_request: "send"
2336
+ };
2337
+ function followerOpPermitted(op, allowedOps) {
2338
+ if (!isAssistantFollowerAllowedOp(op)) return false;
2339
+ if (allowedOps.includes(op)) return true;
2340
+ const implied = DECISION_OP_IMPLIED_BY[op];
2341
+ return implied !== void 0 && allowedOps.includes(implied);
2342
+ }
2256
2343
  function followedRemoteProjectKey(hostDaemonId, meshId) {
2257
2344
  const canonHost = canonicalDaemonId(hostDaemonId) ?? hostDaemonId.trim();
2258
2345
  return `${canonHost}::${meshId.trim()}`;
@@ -3151,8 +3238,23 @@ function isMissionBriefWire(value) {
3151
3238
  }
3152
3239
  return true;
3153
3240
  }
3241
+ var STRUCTURED_MISSION_KEYS = ["summary", "outcome", "outcomeReason", "version", "carryOver", "openItems"];
3242
+ function isOpenItemCountsWire(value) {
3243
+ if (!isRecord(value) || !hasOnlyKeys2(value, ["remaining", "live_check", "decision", "evidence"])) return false;
3244
+ return ["remaining", "live_check", "decision", "evidence"].every((k) => isNonNegativeInt(value[k]));
3245
+ }
3246
+ function isStructuredMissionFields(value) {
3247
+ for (const k of ["summary", "outcome", "outcomeReason"]) {
3248
+ if (value[k] !== void 0 && typeof value[k] !== "string") return false;
3249
+ }
3250
+ if (value.version !== void 0 && !isNonNegativeInt(value.version)) return false;
3251
+ if (value.carryOver !== void 0 && typeof value.carryOver !== "boolean") return false;
3252
+ if (value.openItems !== void 0 && !isOpenItemCountsWire(value.openItems)) return false;
3253
+ return true;
3254
+ }
3154
3255
  function isMeshMissionRecordWire(value) {
3155
- if (!isRecord(value) || !hasOnlyKeys2(value, ["id", "meshId", "title", "goal", "status", "brief"])) return false;
3256
+ if (!isRecord(value) || !hasOnlyKeys2(value, ["id", "meshId", "title", "goal", "status", "brief", ...STRUCTURED_MISSION_KEYS])) return false;
3257
+ if (!isStructuredMissionFields(value)) return false;
3156
3258
  if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false;
3157
3259
  if (typeof value.title !== "string" || typeof value.goal !== "string") return false;
3158
3260
  if (!isMeshMissionStatusValue(value.status)) return false;
@@ -3160,11 +3262,22 @@ function isMeshMissionRecordWire(value) {
3160
3262
  return true;
3161
3263
  }
3162
3264
  function isMissionUpsertRequest(value) {
3163
- if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "id", "title", "goal", "status", "brief"])) return false;
3265
+ if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "id", "title", "goal", "status", "brief", "structured", "summary", "outcome", "outcomeReason", "carryOverTo", "toCarryOver", "itemsAdd", "itemsUpdate"])) return false;
3164
3266
  if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false;
3165
3267
  if (!isEvidenceIdentifier(value.meshId)) return false;
3166
3268
  if (value.id !== void 0 && !isEvidenceIdentifier(value.id)) return false;
3167
- if (typeof value.title !== "string" || value.title.trim().length === 0) return false;
3269
+ if (typeof value.title !== "string") return false;
3270
+ if (value.title.trim().length === 0 && value.toCarryOver !== true && value.id === void 0) return false;
3271
+ if (value.structured !== void 0 && typeof value.structured !== "boolean") return false;
3272
+ if (value.toCarryOver !== void 0 && typeof value.toCarryOver !== "boolean") return false;
3273
+ for (const k of ["summary", "outcome", "outcomeReason"]) {
3274
+ if (value[k] !== void 0 && typeof value[k] !== "string") return false;
3275
+ }
3276
+ if (value.carryOverTo !== void 0 && !isEvidenceIdentifier(value.carryOverTo)) return false;
3277
+ for (const k of ["itemsAdd", "itemsUpdate"]) {
3278
+ const list = value[k];
3279
+ if (list !== void 0 && (!Array.isArray(list) || list.length > 500 || !list.every(isRecord))) return false;
3280
+ }
3168
3281
  if (value.goal !== void 0 && typeof value.goal !== "string") return false;
3169
3282
  if (value.status !== void 0 && !isMeshMissionStatusValue(value.status)) return false;
3170
3283
  if (value.brief !== void 0 && value.brief !== null && !isMissionBriefWire(value.brief)) return false;
@@ -3174,7 +3287,7 @@ function decodeMissionUpsertRequest(value) {
3174
3287
  return isMissionUpsertRequest(value) ? value : null;
3175
3288
  }
3176
3289
  function isMissionUpsertResponse(value) {
3177
- return isRecord(value) && hasOnlyKeys2(value, ["mission"]) && isMeshMissionRecordWire(value.mission);
3290
+ return isRecord(value) && hasOnlyKeys2(value, ["mission", "result"]) && isMeshMissionRecordWire(value.mission) && (value.result === void 0 || isRecord(value.result));
3178
3291
  }
3179
3292
  function decodeMissionUpsertResponse(value) {
3180
3293
  return isMissionUpsertResponse(value) ? value : null;
@@ -3200,7 +3313,10 @@ function decodeMissionQueryResponse(value) {
3200
3313
  return isMissionQueryResponse(value) ? value : null;
3201
3314
  }
3202
3315
  function isMissionListQueryRequest(value) {
3203
- if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "statuses", "verbose", "withStats", "limit", "historyIdLimit", "meshStatusView"])) return false;
3316
+ if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "statuses", "verbose", "withStats", "limit", "historyIdLimit", "meshStatusView", "structured", "items", "history"])) return false;
3317
+ for (const k of ["structured", "items", "history"]) {
3318
+ if (value[k] !== void 0 && typeof value[k] !== "boolean") return false;
3319
+ }
3204
3320
  if (value.meshStatusView !== void 0 && value.meshStatusView !== "compact" && value.meshStatusView !== "verbose") return false;
3205
3321
  if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false;
3206
3322
  if (!isEvidenceIdentifier(value.meshId)) return false;
@@ -3242,7 +3358,7 @@ function isMissionListSummaryWire(value) {
3242
3358
  const hasGoal = "goal" in value;
3243
3359
  const hasPreview = "goalPreview" in value && "goalTruncated" in value;
3244
3360
  if (hasGoal === hasPreview) return false;
3245
- const baseKeys = ["id", "meshId", "title", "status", "tasks", "stats", "brief", "createdAt", "updatedAt", "closeCandidateEmittedAt"];
3361
+ const baseKeys = ["id", "meshId", "title", "status", "tasks", "stats", "brief", "createdAt", "updatedAt", "closeCandidateEmittedAt", ...STRUCTURED_MISSION_KEYS, "items", "history"];
3246
3362
  const allowed = hasGoal ? [...baseKeys, "goal"] : [...baseKeys, "goalPreview", "goalTruncated"];
3247
3363
  if (!hasOnlyKeys2(value, allowed)) return false;
3248
3364
  if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false;
@@ -3256,6 +3372,10 @@ function isMissionListSummaryWire(value) {
3256
3372
  if (value.createdAt !== void 0 && typeof value.createdAt !== "string") return false;
3257
3373
  if (value.updatedAt !== void 0 && typeof value.updatedAt !== "string") return false;
3258
3374
  if (value.closeCandidateEmittedAt !== void 0 && value.closeCandidateEmittedAt !== null && typeof value.closeCandidateEmittedAt !== "string") return false;
3375
+ if (!isStructuredMissionFields(value)) return false;
3376
+ for (const k of ["items", "history"]) {
3377
+ if (value[k] !== void 0 && (!Array.isArray(value[k]) || !value[k].every(isRecord))) return false;
3378
+ }
3259
3379
  return true;
3260
3380
  }
3261
3381
  function isMeshMissionHistoryFoldWire(value) {
@@ -3778,6 +3898,282 @@ function touchedFilesOutsideOwnership(touched, owned) {
3778
3898
  return { undeclaredTouched, unusedDeclarations };
3779
3899
  }
3780
3900
 
3901
+ // src/mission-items.ts
3902
+ var MISSION_ITEM_KINDS = ["remaining", "live_check", "decision", "evidence"];
3903
+ var MISSION_ITEM_STATES = ["open", "done", "dropped", "moved", "answered", "expired", "withdrawn", "superseded"];
3904
+ var COORDINATOR_SETTABLE_ITEM_STATES = {
3905
+ remaining: ["open", "done", "dropped"],
3906
+ live_check: ["open", "done", "dropped"],
3907
+ evidence: ["open", "done", "dropped"],
3908
+ decision: ["open", "withdrawn", "superseded"]
3909
+ };
3910
+ var MISSION_OUTCOMES = ["merged", "verified_live", "superseded", "not_needed", "owner_abandoned", "unspecified"];
3911
+ function isMissionOutcome(value) {
3912
+ return typeof value === "string" && MISSION_OUTCOMES.includes(value);
3913
+ }
3914
+ var MISSION_REF_KINDS = ["commit", "branch", "pr", "task", "artifact", "mission", "url"];
3915
+ var MISSION_LIMITS = {
3916
+ summary: 300,
3917
+ outcomeReason: 500,
3918
+ itemText: 300,
3919
+ machine: 80,
3920
+ refs: 8,
3921
+ refValue: 300,
3922
+ refRepo: 120,
3923
+ refNote: 200,
3924
+ dedupeKey: 400,
3925
+ question: 300,
3926
+ context: 600,
3927
+ options: 5,
3928
+ optionLabel: 60,
3929
+ optionDetail: 200,
3930
+ /** Open items per mission before the oldest `remaining` fold into a "N more" summary item. */
3931
+ openItemsPerMission: 200,
3932
+ /** One event payload (serialized). */
3933
+ eventPayloadBytes: 16 * 1024,
3934
+ /** items_add / items_update entries honoured per call (extra entries are reported, not applied). */
3935
+ itemsPerCall: 50
3936
+ };
3937
+ var MISSION_DECISION_OPTION_IDS = ["a", "b", "c", "d", "e"];
3938
+ var MISSION_DECISION_URGENCIES = ["normal", "blocking"];
3939
+ var MISSION_DECISION_ON_DUE = ["remind", "apply_recommended"];
3940
+ function truncateMissionText(value, max) {
3941
+ if (value.length <= max) return value;
3942
+ return `${value.slice(0, max - 1).trimEnd()}\u2026`;
3943
+ }
3944
+ function str(value) {
3945
+ return typeof value === "string" ? value.trim() : "";
3946
+ }
3947
+ function collapse(value) {
3948
+ return value.replace(/\s+/g, " ").trim();
3949
+ }
3950
+ function normalizeMissionSummary(value) {
3951
+ if (typeof value !== "string") return null;
3952
+ const text = collapse(value);
3953
+ return { value: truncateMissionText(text, MISSION_LIMITS.summary), truncated: text.length > MISSION_LIMITS.summary };
3954
+ }
3955
+ function normalizeOutcomeReason(value) {
3956
+ if (typeof value !== "string") return null;
3957
+ const text = value.trim();
3958
+ return { value: truncateMissionText(text, MISSION_LIMITS.outcomeReason), truncated: text.length > MISSION_LIMITS.outcomeReason };
3959
+ }
3960
+ function normalizeMissionRefs(value) {
3961
+ if (!Array.isArray(value)) return { refs: [], truncated: false };
3962
+ const refs = [];
3963
+ let truncated = false;
3964
+ for (const raw of value) {
3965
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
3966
+ const r = raw;
3967
+ const kind = str(r.kind);
3968
+ const refValue = str(r.value);
3969
+ if (!MISSION_REF_KINDS.includes(kind) || !refValue) continue;
3970
+ if (refs.length >= MISSION_LIMITS.refs) {
3971
+ truncated = true;
3972
+ break;
3973
+ }
3974
+ const repo = str(r.repo);
3975
+ const note = str(r.note);
3976
+ refs.push({
3977
+ kind,
3978
+ ...repo ? { repo: truncateMissionText(repo, MISSION_LIMITS.refRepo) } : {},
3979
+ value: truncateMissionText(refValue, MISSION_LIMITS.refValue),
3980
+ ...note ? { note: truncateMissionText(note, MISSION_LIMITS.refNote) } : {}
3981
+ });
3982
+ }
3983
+ return { refs, truncated };
3984
+ }
3985
+ function normalizeOptions(value, truncated) {
3986
+ if (!Array.isArray(value)) return [];
3987
+ const out = [];
3988
+ for (const raw of value) {
3989
+ if (typeof raw === "string" && raw.trim()) {
3990
+ if (out.length >= MISSION_LIMITS.options) {
3991
+ truncated.push("options");
3992
+ break;
3993
+ }
3994
+ out.push({ id: MISSION_DECISION_OPTION_IDS[out.length], label: truncateMissionText(raw.trim(), MISSION_LIMITS.optionLabel) });
3995
+ continue;
3996
+ }
3997
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
3998
+ const o = raw;
3999
+ const label = collapse(str(o.label));
4000
+ if (!label) continue;
4001
+ if (out.length >= MISSION_LIMITS.options) {
4002
+ truncated.push("options");
4003
+ break;
4004
+ }
4005
+ const detail = str(o.detail);
4006
+ out.push({
4007
+ id: MISSION_DECISION_OPTION_IDS[out.length],
4008
+ label: truncateMissionText(label, MISSION_LIMITS.optionLabel),
4009
+ ...detail ? { detail: truncateMissionText(detail, MISSION_LIMITS.optionDetail) } : {}
4010
+ });
4011
+ }
4012
+ return out;
4013
+ }
4014
+ function normalizeDueAt(value) {
4015
+ if (typeof value !== "string" || !value.trim()) return void 0;
4016
+ const ms2 = Date.parse(value);
4017
+ return Number.isNaN(ms2) ? void 0 : new Date(ms2).toISOString();
4018
+ }
4019
+ function normalizeDecisionInput(raw, truncated) {
4020
+ const questionSource = collapse(str(raw.question) || str(raw.text));
4021
+ if (!questionSource) return null;
4022
+ if (questionSource.length > MISSION_LIMITS.question) truncated.push("question");
4023
+ const question = truncateMissionText(questionSource, MISSION_LIMITS.question);
4024
+ const contextSource = str(raw.context);
4025
+ if (contextSource.length > MISSION_LIMITS.context) truncated.push("context");
4026
+ const options = normalizeOptions(raw.options, truncated);
4027
+ const recommendedRaw = str(raw.recommended);
4028
+ const recommended = recommendedRaw && options.some((o) => o.id === recommendedRaw) ? recommendedRaw : options.find((o) => recommendedRaw && o.label.toLowerCase() === recommendedRaw.toLowerCase())?.id;
4029
+ const dueAt = normalizeDueAt(raw.dueAt ?? raw.due_at);
4030
+ const onDueRaw = str(raw.onDue ?? raw.on_due);
4031
+ const urgencyRaw = str(raw.urgency);
4032
+ const allowFreeTextRaw = raw.allowFreeText ?? raw.allow_free_text;
4033
+ return {
4034
+ question,
4035
+ ...contextSource ? { context: truncateMissionText(contextSource, MISSION_LIMITS.context) } : {},
4036
+ options,
4037
+ ...recommended ? { recommended } : {},
4038
+ allowFreeText: typeof allowFreeTextRaw === "boolean" ? allowFreeTextRaw : true,
4039
+ ...dueAt ? { dueAt } : {},
4040
+ // apply_recommended without a recommended option has nothing to apply — fall back to remind.
4041
+ onDue: onDueRaw === "apply_recommended" && recommended ? "apply_recommended" : "remind",
4042
+ urgency: urgencyRaw === "blocking" ? "blocking" : "normal"
4043
+ };
4044
+ }
4045
+ function normalizeForDedupe(text) {
4046
+ return collapse(text).toLowerCase().replace(/[\s.!?。]+$/u, "");
4047
+ }
4048
+ function deriveItemDedupeKey(kind, parts) {
4049
+ const explicit = str(parts.explicit);
4050
+ if (explicit) return truncateMissionText(`k:${explicit}`, MISSION_LIMITS.dedupeKey);
4051
+ if (kind === "decision") return truncateMissionText(`decision:${normalizeForDedupe(parts.question ?? parts.text ?? "")}`, MISSION_LIMITS.dedupeKey);
4052
+ if (kind === "evidence") {
4053
+ const ref2 = parts.refs?.[0];
4054
+ if (ref2) return truncateMissionText(`evidence:${ref2.kind}:${ref2.repo ?? ""}:${ref2.value}`, MISSION_LIMITS.dedupeKey);
4055
+ }
4056
+ const machine = parts.machine ? `@${normalizeForDedupe(parts.machine)}` : "";
4057
+ return truncateMissionText(`${kind}${machine}:${normalizeForDedupe(parts.text ?? "")}`, MISSION_LIMITS.dedupeKey);
4058
+ }
4059
+ function normalizeMissionItemInput(raw) {
4060
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "item must be an object" };
4061
+ const r = raw;
4062
+ const kind = str(r.kind) || "remaining";
4063
+ if (!MISSION_ITEM_KINDS.includes(kind)) {
4064
+ return { error: `invalid kind '${kind}' (valid: ${MISSION_ITEM_KINDS.join(", ")})` };
4065
+ }
4066
+ const truncated = [];
4067
+ const { refs, truncated: refsTruncated } = normalizeMissionRefs(r.refs);
4068
+ if (refsTruncated) truncated.push("refs");
4069
+ const machineRaw = collapse(str(r.machine));
4070
+ const machine = machineRaw ? truncateMissionText(machineRaw, MISSION_LIMITS.machine) : void 0;
4071
+ const explicitKey = str(r.dedupe_key ?? r.dedupeKey);
4072
+ if (kind === "decision") {
4073
+ const decisionRaw = r.decision && typeof r.decision === "object" && !Array.isArray(r.decision) ? r.decision : r;
4074
+ const decision = normalizeDecisionInput({ ...decisionRaw, question: decisionRaw.question ?? r.question ?? r.text }, truncated);
4075
+ if (!decision) return { error: "decision item needs a question" };
4076
+ return {
4077
+ item: {
4078
+ kind,
4079
+ text: decision.question,
4080
+ ...machine ? { machine } : {},
4081
+ refs,
4082
+ decision,
4083
+ dedupeKey: deriveItemDedupeKey("decision", { question: decision.question, explicit: explicitKey }),
4084
+ truncated
4085
+ }
4086
+ };
4087
+ }
4088
+ const textSource = collapse(str(r.text));
4089
+ if (!textSource && !(kind === "evidence" && refs.length > 0)) return { error: `${kind} item needs text` };
4090
+ if (textSource.length > MISSION_LIMITS.itemText) truncated.push("text");
4091
+ const text = truncateMissionText(textSource || `${refs[0].kind}: ${refs[0].value}`, MISSION_LIMITS.itemText);
4092
+ return {
4093
+ item: {
4094
+ kind,
4095
+ text,
4096
+ ...machine ? { machine } : {},
4097
+ refs,
4098
+ dedupeKey: deriveItemDedupeKey(kind, { text, machine, refs, explicit: explicitKey }),
4099
+ truncated
4100
+ }
4101
+ };
4102
+ }
4103
+ function normalizeMissionItemUpdate(raw) {
4104
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "update must be an object" };
4105
+ const r = raw;
4106
+ const id2 = str(r.id ?? r.item_id ?? r.itemId);
4107
+ if (!id2) return { error: "update needs an item id" };
4108
+ const truncated = [];
4109
+ const update = { id: id2 };
4110
+ if (r.state !== void 0) {
4111
+ const state = str(r.state);
4112
+ if (!MISSION_ITEM_STATES.includes(state)) return { error: `invalid state '${state}'` };
4113
+ update.state = state;
4114
+ }
4115
+ if (typeof r.text === "string") {
4116
+ const text = collapse(r.text);
4117
+ if (text.length > MISSION_LIMITS.itemText) truncated.push("text");
4118
+ if (text) update.text = truncateMissionText(text, MISSION_LIMITS.itemText);
4119
+ }
4120
+ if (r.machine === null) update.machine = null;
4121
+ else if (typeof r.machine === "string") {
4122
+ const machine = collapse(r.machine);
4123
+ update.machine = machine ? truncateMissionText(machine, MISSION_LIMITS.machine) : null;
4124
+ }
4125
+ if (r.refs !== void 0) {
4126
+ const { refs, truncated: t } = normalizeMissionRefs(r.refs);
4127
+ if (t) truncated.push("refs");
4128
+ update.refs = refs;
4129
+ }
4130
+ return { update, truncated };
4131
+ }
4132
+ function boundEventPayload(payload) {
4133
+ let json = JSON.stringify(payload);
4134
+ if (json.length <= MISSION_LIMITS.eventPayloadBytes) return json;
4135
+ const shrunk = {};
4136
+ for (const [k, v] of Object.entries(payload)) {
4137
+ shrunk[k] = typeof v === "string" && v.length > 4e3 ? `${v.slice(0, 4e3)}\u2026` : v;
4138
+ }
4139
+ shrunk.payloadTruncated = true;
4140
+ json = JSON.stringify(shrunk);
4141
+ if (json.length <= MISSION_LIMITS.eventPayloadBytes) return json;
4142
+ return JSON.stringify({ payloadTruncated: true, keys: Object.keys(payload).slice(0, 20) });
4143
+ }
4144
+ var CARRY_OVER_MISSION_TITLE = "Carry-over \u2014 open items from closed missions";
4145
+ var LEGACY_CARRY_OVER_MISSION_TITLE = "\uC774\uC6D4 \u2014 \uB2EB\uD78C \uBBF8\uC158\uC5D0\uC11C \uB118\uC5B4\uC628 \uD56D\uBAA9";
4146
+ var CARRY_OVER_MISSION_GOAL = "Open items carried over from closed missions, and decisions requested without a mission. Managed automatically \u2014 do not close.";
4147
+ function isCarryOverMissionRecord(m) {
4148
+ return !!m && (m.isCarryOver === true || isCarryOverMissionTitle(m.title));
4149
+ }
4150
+ function isCarryOverMissionTitle(title) {
4151
+ if (typeof title !== "string") return false;
4152
+ const t = title.trim();
4153
+ return t === CARRY_OVER_MISSION_TITLE || t === LEGACY_CARRY_OVER_MISSION_TITLE;
4154
+ }
4155
+ var OWNER_ABANDON_CONFIRM_KEY_PREFIX = "owner-abandon-confirm:";
4156
+ var OWNER_ABANDON_CONFIRM_QUESTION = "The coordinator closed this as 'owner abandoned' \u2014 correct?";
4157
+ var OWNER_ABANDON_CONFIRM_OPTIONS = ["Correct", "Reopen"];
4158
+ var WORKER_DECISIONS_NEEDED_MAX = 3;
4159
+ var WORKER_COMMITS_MAX = 20;
4160
+ var SHA_RE = /^[0-9a-f]{7,64}$/i;
4161
+ function normalizeReportCommits(value) {
4162
+ if (!Array.isArray(value)) return null;
4163
+ const out = [];
4164
+ for (const v of value) {
4165
+ if (typeof v !== "string") return null;
4166
+ const sha = v.trim();
4167
+ if (!SHA_RE.test(sha)) return null;
4168
+ if (!out.includes(sha.toLowerCase())) out.push(sha.toLowerCase());
4169
+ }
4170
+ return out;
4171
+ }
4172
+
4173
+ // src/decision-push-relay.ts
4174
+ var DECISION_PUSH_RELAY_COMMAND = "mission_decision_push_relay_answer";
4175
+ var DECISION_PUSH_RELAY_SOURCE = "push_relay";
4176
+
3781
4177
  // src/keyed-doc-delta.ts
3782
4178
  function sig(value) {
3783
4179
  if (value === void 0) return void 0;
@@ -4140,6 +4536,86 @@ function isProviderQuestionBinding(value) {
4140
4536
  if (["sessionId", "generation", "threadId", "turnId", "itemId"].some((key) => typeof b[key] !== "string" || !b[key].trim())) return false;
4141
4537
  return b.transport === "codex_async" ? b.requestId === void 0 : typeof b.requestId === "string" && !!b.requestId.trim() || typeof b.requestId === "number" && Number.isFinite(b.requestId);
4142
4538
  }
4539
+
4540
+ // src/relay-reprobe.ts
4541
+ var RELAY_REPROBE_BASE_DELAY_MS = 6e4;
4542
+ var RELAY_REPROBE_MAX_DELAY_MS = 5 * 6e4;
4543
+ var RELAY_REPROBE_JITTER_RATIO = 0.2;
4544
+ function computeRelayReprobeDelay(failures, random, timing = {}) {
4545
+ const base = timing.baseDelayMs ?? RELAY_REPROBE_BASE_DELAY_MS;
4546
+ const max = timing.maxDelayMs ?? RELAY_REPROBE_MAX_DELAY_MS;
4547
+ const jitter = timing.jitterRatio ?? RELAY_REPROBE_JITTER_RATIO;
4548
+ const grown = Math.min(max, base * 2 ** Math.max(0, failures));
4549
+ const factor = 1 + jitter * (Math.min(1, Math.max(0, random())) * 2 - 1);
4550
+ return Math.round(grown * factor);
4551
+ }
4552
+ var RelayReprobeScheduler = class {
4553
+ constructor(options) {
4554
+ this.options = options;
4555
+ }
4556
+ handle = null;
4557
+ running = false;
4558
+ inFlight = false;
4559
+ failureCount = 0;
4560
+ generation = 0;
4561
+ get isRunning() {
4562
+ return this.running;
4563
+ }
4564
+ get failures() {
4565
+ return this.failureCount;
4566
+ }
4567
+ get probing() {
4568
+ return this.inFlight;
4569
+ }
4570
+ /** Begin probing (idempotent). Call when a connection is selected as relay. */
4571
+ start() {
4572
+ if (this.running) return;
4573
+ this.running = true;
4574
+ this.failureCount = 0;
4575
+ this.generation++;
4576
+ this.schedule();
4577
+ }
4578
+ /** Stop for good (direct path found, connection closed, auth epoch changed). */
4579
+ stop() {
4580
+ this.running = false;
4581
+ this.generation++;
4582
+ if (this.handle !== null) {
4583
+ this.options.clearTimer(this.handle);
4584
+ this.handle = null;
4585
+ }
4586
+ }
4587
+ schedule() {
4588
+ if (!this.running) return;
4589
+ const generation = this.generation;
4590
+ const delay = computeRelayReprobeDelay(this.failureCount, this.options.random, this.options);
4591
+ this.handle = this.options.setTimer(() => {
4592
+ this.handle = null;
4593
+ void this.tick(generation);
4594
+ }, delay);
4595
+ }
4596
+ async tick(generation) {
4597
+ if (!this.running || generation !== this.generation) return;
4598
+ if (this.inFlight || !this.options.shouldProbe()) {
4599
+ this.schedule();
4600
+ return;
4601
+ }
4602
+ this.inFlight = true;
4603
+ let outcome;
4604
+ try {
4605
+ outcome = await this.options.probe();
4606
+ } catch {
4607
+ outcome = "failed";
4608
+ }
4609
+ this.inFlight = false;
4610
+ if (!this.running || generation !== this.generation) return;
4611
+ if (outcome === "direct") {
4612
+ this.stop();
4613
+ return;
4614
+ }
4615
+ if (outcome !== "skipped") this.failureCount++;
4616
+ this.schedule();
4617
+ }
4618
+ };
4143
4619
  // Annotate the CommonJS export names for ESM import in node:
4144
4620
  0 && (module.exports = {
4145
4621
  ASSISTANT_ACCOUNT_SLOT,
@@ -4160,12 +4636,15 @@ function isProviderQuestionBinding(value) {
4160
4636
  CANCEL_REASONS,
4161
4637
  CANONICAL_MESH_TOOL_COUNT,
4162
4638
  CANONICAL_MESH_TOOL_NAMES,
4639
+ CARRY_OVER_MISSION_GOAL,
4640
+ CARRY_OVER_MISSION_TITLE,
4163
4641
  CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX,
4164
4642
  CLAUDE_TUI_REVIEW_UNCONFIRMED_PREFIX,
4165
4643
  CLI_SLOT_RECIPES,
4166
4644
  COMMIT_STRENGTHS,
4167
4645
  CONSUME_PROFILES,
4168
4646
  COORDINATOR_ACK_OUTCOMES,
4647
+ COORDINATOR_SETTABLE_ITEM_STATES,
4169
4648
  DAEMON_METADATA_DOC_SPEC,
4170
4649
  DAEMON_P2P_SIGNAL_TYPES,
4171
4650
  DAEMON_STATUS_EVENT_NAMES,
@@ -4178,6 +4657,11 @@ function isProviderQuestionBinding(value) {
4178
4657
  DASHBOARD_TO_DAEMON_P2P_TYPES,
4179
4658
  DASHBOARD_TO_USER_SESSION_TYPES,
4180
4659
  DASHBOARD_WIRE_VERSION,
4660
+ DECISION_PUSH_OPTIONS_MAX,
4661
+ DECISION_PUSH_OPTION_LABEL_MAX,
4662
+ DECISION_PUSH_QUESTION_MAX,
4663
+ DECISION_PUSH_RELAY_COMMAND,
4664
+ DECISION_PUSH_RELAY_SOURCE,
4181
4665
  DEFAULT_DIFFICULTY_BRAINS,
4182
4666
  DELIVERY_OUTCOMES,
4183
4667
  DELIVERY_VIAS,
@@ -4189,6 +4673,7 @@ function isProviderQuestionBinding(value) {
4189
4673
  LAUNCH_DEFAULT_ERROR_CODES,
4190
4674
  LAUNCH_DEFAULT_ROLES,
4191
4675
  LAUNCH_DEFAULT_SOURCES,
4676
+ LEGACY_CARRY_OVER_MISSION_TITLE,
4192
4677
  LIVENESS_RESULTS,
4193
4678
  MAX_MESH_RECORD_STRING,
4194
4679
  MAX_OWNED_PATHS,
@@ -4214,6 +4699,14 @@ function isProviderQuestionBinding(value) {
4214
4699
  MESH_TOPIC_ENTRY_KINDS,
4215
4700
  MESH_TOPIC_PROTOCOL_VERSION,
4216
4701
  MISSION_BRIEF_RENDER_MAX_CHARS,
4702
+ MISSION_DECISION_ON_DUE,
4703
+ MISSION_DECISION_OPTION_IDS,
4704
+ MISSION_DECISION_URGENCIES,
4705
+ MISSION_ITEM_KINDS,
4706
+ MISSION_ITEM_STATES,
4707
+ MISSION_LIMITS,
4708
+ MISSION_OUTCOMES,
4709
+ MISSION_REF_KINDS,
4217
4710
  MODEL_AXIS_SOURCES,
4218
4711
  MODEL_SELECTION_HISTORY_LIMIT,
4219
4712
  MeshChunkAssembler,
@@ -4227,6 +4720,9 @@ function isProviderQuestionBinding(value) {
4227
4720
  OPERATOR_STATUS_REASON_VALUES,
4228
4721
  OPERATOR_STATUS_VALUES,
4229
4722
  OUTBOUND_MESSAGE_ORIGINS,
4723
+ OWNER_ABANDON_CONFIRM_KEY_PREFIX,
4724
+ OWNER_ABANDON_CONFIRM_OPTIONS,
4725
+ OWNER_ABANDON_CONFIRM_QUESTION,
4230
4726
  P2P_SIGNAL_TYPES,
4231
4727
  PROVIDER_FAILURES,
4232
4728
  QUOTA_BACKFILL_HORIZON_MS,
@@ -4234,9 +4730,13 @@ function isProviderQuestionBinding(value) {
4234
4730
  QUOTA_SUPPORTED_PROVIDERS,
4235
4731
  RECENT_SESSION_BUCKETS,
4236
4732
  RECLAIMING_SEND_REFUSALS,
4733
+ RELAY_REPROBE_BASE_DELAY_MS,
4734
+ RELAY_REPROBE_JITTER_RATIO,
4735
+ RELAY_REPROBE_MAX_DELAY_MS,
4237
4736
  RELEASE_CHANNELS,
4238
4737
  REMOVED_MESH_TOOLS,
4239
4738
  RETIRED_MESH_TOOLS,
4739
+ RelayReprobeScheduler,
4240
4740
  SEND_POLICY_MODES,
4241
4741
  SEND_REFUSAL_REASONS,
4242
4742
  SERVER_STATUS_EVENT_NAMES,
@@ -4274,6 +4774,8 @@ function isProviderQuestionBinding(value) {
4274
4774
  VERSION_UPDATE_REASONS,
4275
4775
  VIEWER_TO_SHARED_SESSION_TYPES,
4276
4776
  WORKER_BRANCH_STATES,
4777
+ WORKER_COMMITS_MAX,
4778
+ WORKER_DECISIONS_NEEDED_MAX,
4277
4779
  WORKER_PROTOCOL_FOOTER_MARKER,
4278
4780
  WORKER_REPORT_OUTCOMES,
4279
4781
  WORKER_REPORT_SUMMARY_MAX_CHARS,
@@ -4281,11 +4783,13 @@ function isProviderQuestionBinding(value) {
4281
4783
  appendWorkerProtocolFooter,
4282
4784
  argsCarryStatusProbeMarker,
4283
4785
  assessQuotaFreshness,
4786
+ boundEventPayload,
4284
4787
  buildSlotProposal,
4285
4788
  canonicalDaemonId,
4286
4789
  classifySessionStatus,
4287
4790
  compareDashboardWireVersion,
4288
4791
  compareSemver,
4792
+ computeRelayReprobeDelay,
4289
4793
  daemonIdsEquivalent,
4290
4794
  decodeActiveWorkQueryRequest,
4291
4795
  decodeActiveWorkQueryResponse,
@@ -4349,6 +4853,7 @@ function isProviderQuestionBinding(value) {
4349
4853
  decodeUserSessionToDashboard,
4350
4854
  decodeViewerToSharedSession,
4351
4855
  defaultProviderPriorityFromNodeFacts,
4856
+ deriveItemDedupeKey,
4352
4857
  deriveProviderPriorityFromSlots,
4353
4858
  deriveSlotsFromLegacy,
4354
4859
  describeModelSelection,
@@ -4360,6 +4865,7 @@ function isProviderQuestionBinding(value) {
4360
4865
  findOwnershipConflicts,
4361
4866
  foldKeyedDoc,
4362
4867
  followedRemoteProjectKey,
4868
+ followerOpPermitted,
4363
4869
  formatQuotaAccount,
4364
4870
  hasGitStatusEvidence,
4365
4871
  hasWorkerProtocolFooter,
@@ -4369,6 +4875,8 @@ function isProviderQuestionBinding(value) {
4369
4875
  isAssistantTool,
4370
4876
  isBlockedStatus,
4371
4877
  isBusyStatus,
4878
+ isCarryOverMissionRecord,
4879
+ isCarryOverMissionTitle,
4372
4880
  isChunkType,
4373
4881
  isCommitStrength,
4374
4882
  isDaemonDirectCommandType,
@@ -4401,6 +4909,7 @@ function isProviderQuestionBinding(value) {
4401
4909
  isMeshTerminalTaskStatus,
4402
4910
  isMeshTopicEntry,
4403
4911
  isMessageId,
4912
+ isMissionOutcome,
4404
4913
  isMissionUpsertResponse,
4405
4914
  isModelAxisSource,
4406
4915
  isNativeMarkerRef,
@@ -4451,16 +4960,24 @@ function isProviderQuestionBinding(value) {
4451
4960
  minutesUntilQuotaCheck,
4452
4961
  normalizeAuthOkLimits,
4453
4962
  normalizeBrainSlot,
4963
+ normalizeDecisionInput,
4454
4964
  normalizeDifficultyBrainMap,
4965
+ normalizeForDedupe,
4455
4966
  normalizeGitStatus,
4456
4967
  normalizeMeshNodeFacts,
4457
4968
  normalizeMeshNodeId,
4458
4969
  normalizeMeshSessionRecord,
4459
4970
  normalizeMeshWorkspaceForCompare,
4460
4971
  normalizeMissionBrief,
4972
+ normalizeMissionItemInput,
4973
+ normalizeMissionItemUpdate,
4974
+ normalizeMissionRefs,
4975
+ normalizeMissionSummary,
4461
4976
  normalizeNodeCapabilitySlot,
4462
4977
  normalizeNodeCapabilitySlots,
4978
+ normalizeOutcomeReason,
4463
4979
  normalizeOwnedPaths,
4980
+ normalizeReportCommits,
4464
4981
  normalizeSessionStatus,
4465
4982
  normalizeThinkingLevel,
4466
4983
  orderProvidersByBuiltinPreference,
@@ -4500,6 +5017,7 @@ function isProviderQuestionBinding(value) {
4500
5017
  summarizeGitShape,
4501
5018
  supportsQuota,
4502
5019
  touchedFilesOutsideOwnership,
5020
+ truncateMissionText,
4503
5021
  unwrapPastedContent,
4504
5022
  withStatusProbeMarker
4505
5023
  });