@adhdev/mesh-shared 1.0.82-rc.34 → 1.0.82-rc.36
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/assistant-protocol.d.ts +7 -2
- package/dist/decision-push-relay.d.ts +20 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +425 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +388 -11
- package/dist/index.mjs.map +1 -1
- package/dist/mission-items.d.ts +202 -0
- package/dist/protocol/daemon-server.d.ts +27 -2
- package/dist/protocol/dashboard-server.d.ts +2 -2
- package/dist/session-launch.d.ts +7 -0
- package/dist/turn-ipc-mission.d.ts +59 -1
- package/dist/worker-protocol.d.ts +1 -1
- package/package.json +1 -1
- package/src/assistant-protocol.ts +29 -2
- package/src/decision-push-relay.ts +23 -0
- package/src/index.ts +2 -0
- package/src/mission-items.ts +421 -0
- package/src/protocol/daemon-server.ts +26 -0
- package/src/session-launch.ts +9 -0
- package/src/turn-ipc-mission.ts +108 -9
- package/src/worker-protocol.ts +4 -0
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,
|
|
@@ -156,6 +176,8 @@ __export(index_exports, {
|
|
|
156
176
|
VERSION_UPDATE_REASONS: () => VERSION_UPDATE_REASONS,
|
|
157
177
|
VIEWER_TO_SHARED_SESSION_TYPES: () => VIEWER_TO_SHARED_SESSION_TYPES,
|
|
158
178
|
WORKER_BRANCH_STATES: () => WORKER_BRANCH_STATES,
|
|
179
|
+
WORKER_COMMITS_MAX: () => WORKER_COMMITS_MAX,
|
|
180
|
+
WORKER_DECISIONS_NEEDED_MAX: () => WORKER_DECISIONS_NEEDED_MAX,
|
|
159
181
|
WORKER_PROTOCOL_FOOTER_MARKER: () => WORKER_PROTOCOL_FOOTER_MARKER,
|
|
160
182
|
WORKER_REPORT_OUTCOMES: () => WORKER_REPORT_OUTCOMES,
|
|
161
183
|
WORKER_REPORT_SUMMARY_MAX_CHARS: () => WORKER_REPORT_SUMMARY_MAX_CHARS,
|
|
@@ -163,6 +185,7 @@ __export(index_exports, {
|
|
|
163
185
|
appendWorkerProtocolFooter: () => appendWorkerProtocolFooter,
|
|
164
186
|
argsCarryStatusProbeMarker: () => argsCarryStatusProbeMarker,
|
|
165
187
|
assessQuotaFreshness: () => assessQuotaFreshness,
|
|
188
|
+
boundEventPayload: () => boundEventPayload,
|
|
166
189
|
buildSlotProposal: () => buildSlotProposal,
|
|
167
190
|
canonicalDaemonId: () => canonicalDaemonId,
|
|
168
191
|
classifySessionStatus: () => classifySessionStatus,
|
|
@@ -232,6 +255,7 @@ __export(index_exports, {
|
|
|
232
255
|
decodeUserSessionToDashboard: () => decodeUserSessionToDashboard,
|
|
233
256
|
decodeViewerToSharedSession: () => decodeViewerToSharedSession,
|
|
234
257
|
defaultProviderPriorityFromNodeFacts: () => defaultProviderPriorityFromNodeFacts,
|
|
258
|
+
deriveItemDedupeKey: () => deriveItemDedupeKey,
|
|
235
259
|
deriveProviderPriorityFromSlots: () => deriveProviderPriorityFromSlots,
|
|
236
260
|
deriveSlotsFromLegacy: () => deriveSlotsFromLegacy,
|
|
237
261
|
describeModelSelection: () => describeModelSelection,
|
|
@@ -243,6 +267,7 @@ __export(index_exports, {
|
|
|
243
267
|
findOwnershipConflicts: () => findOwnershipConflicts,
|
|
244
268
|
foldKeyedDoc: () => foldKeyedDoc,
|
|
245
269
|
followedRemoteProjectKey: () => followedRemoteProjectKey,
|
|
270
|
+
followerOpPermitted: () => followerOpPermitted,
|
|
246
271
|
formatQuotaAccount: () => formatQuotaAccount,
|
|
247
272
|
hasGitStatusEvidence: () => hasGitStatusEvidence,
|
|
248
273
|
hasWorkerProtocolFooter: () => hasWorkerProtocolFooter,
|
|
@@ -252,6 +277,8 @@ __export(index_exports, {
|
|
|
252
277
|
isAssistantTool: () => isAssistantTool,
|
|
253
278
|
isBlockedStatus: () => isBlockedStatus,
|
|
254
279
|
isBusyStatus: () => isBusyStatus,
|
|
280
|
+
isCarryOverMissionRecord: () => isCarryOverMissionRecord,
|
|
281
|
+
isCarryOverMissionTitle: () => isCarryOverMissionTitle,
|
|
255
282
|
isChunkType: () => isChunkType,
|
|
256
283
|
isCommitStrength: () => isCommitStrength,
|
|
257
284
|
isDaemonDirectCommandType: () => isDaemonDirectCommandType,
|
|
@@ -284,6 +311,7 @@ __export(index_exports, {
|
|
|
284
311
|
isMeshTerminalTaskStatus: () => isMeshTerminalTaskStatus,
|
|
285
312
|
isMeshTopicEntry: () => isMeshTopicEntry,
|
|
286
313
|
isMessageId: () => isMessageId,
|
|
314
|
+
isMissionOutcome: () => isMissionOutcome,
|
|
287
315
|
isMissionUpsertResponse: () => isMissionUpsertResponse,
|
|
288
316
|
isModelAxisSource: () => isModelAxisSource,
|
|
289
317
|
isNativeMarkerRef: () => isNativeMarkerRef,
|
|
@@ -334,16 +362,24 @@ __export(index_exports, {
|
|
|
334
362
|
minutesUntilQuotaCheck: () => minutesUntilQuotaCheck,
|
|
335
363
|
normalizeAuthOkLimits: () => normalizeAuthOkLimits,
|
|
336
364
|
normalizeBrainSlot: () => normalizeBrainSlot,
|
|
365
|
+
normalizeDecisionInput: () => normalizeDecisionInput,
|
|
337
366
|
normalizeDifficultyBrainMap: () => normalizeDifficultyBrainMap,
|
|
367
|
+
normalizeForDedupe: () => normalizeForDedupe,
|
|
338
368
|
normalizeGitStatus: () => normalizeGitStatus,
|
|
339
369
|
normalizeMeshNodeFacts: () => normalizeMeshNodeFacts,
|
|
340
370
|
normalizeMeshNodeId: () => normalizeMeshNodeId,
|
|
341
371
|
normalizeMeshSessionRecord: () => normalizeMeshSessionRecord,
|
|
342
372
|
normalizeMeshWorkspaceForCompare: () => normalizeMeshWorkspaceForCompare,
|
|
343
373
|
normalizeMissionBrief: () => normalizeMissionBrief,
|
|
374
|
+
normalizeMissionItemInput: () => normalizeMissionItemInput,
|
|
375
|
+
normalizeMissionItemUpdate: () => normalizeMissionItemUpdate,
|
|
376
|
+
normalizeMissionRefs: () => normalizeMissionRefs,
|
|
377
|
+
normalizeMissionSummary: () => normalizeMissionSummary,
|
|
344
378
|
normalizeNodeCapabilitySlot: () => normalizeNodeCapabilitySlot,
|
|
345
379
|
normalizeNodeCapabilitySlots: () => normalizeNodeCapabilitySlots,
|
|
380
|
+
normalizeOutcomeReason: () => normalizeOutcomeReason,
|
|
346
381
|
normalizeOwnedPaths: () => normalizeOwnedPaths,
|
|
382
|
+
normalizeReportCommits: () => normalizeReportCommits,
|
|
347
383
|
normalizeSessionStatus: () => normalizeSessionStatus,
|
|
348
384
|
normalizeThinkingLevel: () => normalizeThinkingLevel,
|
|
349
385
|
orderProvidersByBuiltinPreference: () => orderProvidersByBuiltinPreference,
|
|
@@ -383,6 +419,7 @@ __export(index_exports, {
|
|
|
383
419
|
summarizeGitShape: () => summarizeGitShape,
|
|
384
420
|
supportsQuota: () => supportsQuota,
|
|
385
421
|
touchedFilesOutsideOwnership: () => touchedFilesOutsideOwnership,
|
|
422
|
+
truncateMissionText: () => truncateMissionText,
|
|
386
423
|
unwrapPastedContent: () => unwrapPastedContent,
|
|
387
424
|
withStatusProbeMarker: () => withStatusProbeMarker
|
|
388
425
|
});
|
|
@@ -1499,9 +1536,15 @@ var DAEMON_STATUS_EVENT_NAMES = [
|
|
|
1499
1536
|
"agent:waiting_choice",
|
|
1500
1537
|
"agent:generating_completed",
|
|
1501
1538
|
"agent:stopped",
|
|
1502
|
-
"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"
|
|
1503
1543
|
];
|
|
1504
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;
|
|
1505
1548
|
var RELEASE_CHANNELS = ["stable", "preview"];
|
|
1506
1549
|
var NPM_UPDATE_TAGS = ["latest", "next"];
|
|
1507
1550
|
var VERSION_UPDATE_REASONS = ["force_update_below", "major_minor_mismatch", "patch_mismatch", "daemon_ahead"];
|
|
@@ -2075,6 +2118,10 @@ var WORKER_TOOLS = [
|
|
|
2075
2118
|
"driver_list",
|
|
2076
2119
|
"driver_describe",
|
|
2077
2120
|
"driver_invoke",
|
|
2121
|
+
"driver_scaffold",
|
|
2122
|
+
"driver_validate",
|
|
2123
|
+
"driver_export",
|
|
2124
|
+
"driver_install",
|
|
2078
2125
|
"artifact_register",
|
|
2079
2126
|
"artifact_list",
|
|
2080
2127
|
"artifact_read",
|
|
@@ -2185,7 +2232,9 @@ var ASSISTANT_TOOLS = [
|
|
|
2185
2232
|
"driver_list",
|
|
2186
2233
|
"driver_describe",
|
|
2187
2234
|
"artifact_list",
|
|
2188
|
-
"artifact_read"
|
|
2235
|
+
"artifact_read",
|
|
2236
|
+
"decision_answer",
|
|
2237
|
+
"decision_request"
|
|
2189
2238
|
];
|
|
2190
2239
|
var ASSISTANT_TOOL_SET = new Set(ASSISTANT_TOOLS);
|
|
2191
2240
|
function isAssistantTool(value) {
|
|
@@ -2215,6 +2264,10 @@ var ASSISTANT_VERB = {
|
|
|
2215
2264
|
launchDefaultsSet: "assistant_launch_defaults_set",
|
|
2216
2265
|
artifactList: "assistant_artifact_list",
|
|
2217
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",
|
|
2218
2271
|
// assistant-side daemon verbs without a tool of the same name
|
|
2219
2272
|
launch: "launch_assistant",
|
|
2220
2273
|
pendingRelays: "assistant_pending_relays",
|
|
@@ -2246,9 +2299,11 @@ var ASSISTANT_TOOL_VERBS = {
|
|
|
2246
2299
|
launch_defaults: ASSISTANT_VERB.launchDefaults,
|
|
2247
2300
|
launch_defaults_set: ASSISTANT_VERB.launchDefaultsSet,
|
|
2248
2301
|
artifact_list: ASSISTANT_VERB.artifactList,
|
|
2249
|
-
artifact_read: ASSISTANT_VERB.artifactRead
|
|
2302
|
+
artifact_read: ASSISTANT_VERB.artifactRead,
|
|
2303
|
+
decision_answer: ASSISTANT_VERB.decisionAnswer,
|
|
2304
|
+
decision_request: ASSISTANT_VERB.decisionRequest
|
|
2250
2305
|
};
|
|
2251
|
-
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"];
|
|
2252
2307
|
var ASSISTANT_OWNER_VERBS = [
|
|
2253
2308
|
ASSISTANT_VERB.executionSettings,
|
|
2254
2309
|
ASSISTANT_VERB.stagedResolve,
|
|
@@ -2269,11 +2324,22 @@ var ASSISTANT_REMOTE_PROJECT_COMMAND = "assistant_remote_project";
|
|
|
2269
2324
|
var ASSISTANT_REMOTE_PROJECT_CATALOG_COMMAND = "assistant_remote_project_catalog";
|
|
2270
2325
|
var ASSISTANT_REMOTE_PROJECT_ACCESS_COMMAND = "assistant_remote_project_access";
|
|
2271
2326
|
var ASSISTANT_REMOTE_FOLLOW_COMMAND = "assistant_remote_follow";
|
|
2272
|
-
var ASSISTANT_FOLLOWER_ALLOWED_OPS = ["status", "read", "poll", "report", "send", "artifact_list", "artifact_read"];
|
|
2327
|
+
var ASSISTANT_FOLLOWER_ALLOWED_OPS = ["status", "read", "poll", "report", "send", "artifact_list", "artifact_read", "decision_list", "decision_answer", "decision_request"];
|
|
2273
2328
|
var ASSISTANT_FOLLOWER_ALLOWED_OP_SET = new Set(ASSISTANT_FOLLOWER_ALLOWED_OPS);
|
|
2274
2329
|
function isAssistantFollowerAllowedOp(value) {
|
|
2275
2330
|
return typeof value === "string" && ASSISTANT_FOLLOWER_ALLOWED_OP_SET.has(value);
|
|
2276
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
|
+
}
|
|
2277
2343
|
function followedRemoteProjectKey(hostDaemonId, meshId) {
|
|
2278
2344
|
const canonHost = canonicalDaemonId(hostDaemonId) ?? hostDaemonId.trim();
|
|
2279
2345
|
return `${canonHost}::${meshId.trim()}`;
|
|
@@ -2852,6 +2918,7 @@ function parseModelSelection(raw) {
|
|
|
2852
2918
|
const current = readString(record2.current);
|
|
2853
2919
|
const observed = readString(record2.observed);
|
|
2854
2920
|
const observedAt = readFiniteNumber(record2.observedAt);
|
|
2921
|
+
const fallback = record2.fallback === true;
|
|
2855
2922
|
return {
|
|
2856
2923
|
source: isModelAxisSource(record2.source) ? record2.source : "unspecified",
|
|
2857
2924
|
...requested ? { requested } : {},
|
|
@@ -2860,6 +2927,7 @@ function parseModelSelection(raw) {
|
|
|
2860
2927
|
...current ? { current } : {},
|
|
2861
2928
|
...observed ? { observed } : {},
|
|
2862
2929
|
...observedAt !== void 0 ? { observedAt } : {},
|
|
2930
|
+
...fallback ? { fallback } : {},
|
|
2863
2931
|
history: history.slice(-MODEL_SELECTION_HISTORY_LIMIT)
|
|
2864
2932
|
};
|
|
2865
2933
|
}
|
|
@@ -3172,8 +3240,23 @@ function isMissionBriefWire(value) {
|
|
|
3172
3240
|
}
|
|
3173
3241
|
return true;
|
|
3174
3242
|
}
|
|
3243
|
+
var STRUCTURED_MISSION_KEYS = ["summary", "outcome", "outcomeReason", "version", "carryOver", "openItems"];
|
|
3244
|
+
function isOpenItemCountsWire(value) {
|
|
3245
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["remaining", "live_check", "decision", "evidence"])) return false;
|
|
3246
|
+
return ["remaining", "live_check", "decision", "evidence"].every((k) => isNonNegativeInt(value[k]));
|
|
3247
|
+
}
|
|
3248
|
+
function isStructuredMissionFields(value) {
|
|
3249
|
+
for (const k of ["summary", "outcome", "outcomeReason"]) {
|
|
3250
|
+
if (value[k] !== void 0 && typeof value[k] !== "string") return false;
|
|
3251
|
+
}
|
|
3252
|
+
if (value.version !== void 0 && !isNonNegativeInt(value.version)) return false;
|
|
3253
|
+
if (value.carryOver !== void 0 && typeof value.carryOver !== "boolean") return false;
|
|
3254
|
+
if (value.openItems !== void 0 && !isOpenItemCountsWire(value.openItems)) return false;
|
|
3255
|
+
return true;
|
|
3256
|
+
}
|
|
3175
3257
|
function isMeshMissionRecordWire(value) {
|
|
3176
|
-
if (!isRecord(value) || !hasOnlyKeys2(value, ["id", "meshId", "title", "goal", "status", "brief"])) return false;
|
|
3258
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["id", "meshId", "title", "goal", "status", "brief", ...STRUCTURED_MISSION_KEYS])) return false;
|
|
3259
|
+
if (!isStructuredMissionFields(value)) return false;
|
|
3177
3260
|
if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false;
|
|
3178
3261
|
if (typeof value.title !== "string" || typeof value.goal !== "string") return false;
|
|
3179
3262
|
if (!isMeshMissionStatusValue(value.status)) return false;
|
|
@@ -3181,11 +3264,22 @@ function isMeshMissionRecordWire(value) {
|
|
|
3181
3264
|
return true;
|
|
3182
3265
|
}
|
|
3183
3266
|
function isMissionUpsertRequest(value) {
|
|
3184
|
-
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "id", "title", "goal", "status", "brief"])) return false;
|
|
3267
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "id", "title", "goal", "status", "brief", "structured", "summary", "outcome", "outcomeReason", "carryOverTo", "toCarryOver", "itemsAdd", "itemsUpdate"])) return false;
|
|
3185
3268
|
if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false;
|
|
3186
3269
|
if (!isEvidenceIdentifier(value.meshId)) return false;
|
|
3187
3270
|
if (value.id !== void 0 && !isEvidenceIdentifier(value.id)) return false;
|
|
3188
|
-
if (typeof value.title !== "string"
|
|
3271
|
+
if (typeof value.title !== "string") return false;
|
|
3272
|
+
if (value.title.trim().length === 0 && value.toCarryOver !== true && value.id === void 0) return false;
|
|
3273
|
+
if (value.structured !== void 0 && typeof value.structured !== "boolean") return false;
|
|
3274
|
+
if (value.toCarryOver !== void 0 && typeof value.toCarryOver !== "boolean") return false;
|
|
3275
|
+
for (const k of ["summary", "outcome", "outcomeReason"]) {
|
|
3276
|
+
if (value[k] !== void 0 && typeof value[k] !== "string") return false;
|
|
3277
|
+
}
|
|
3278
|
+
if (value.carryOverTo !== void 0 && !isEvidenceIdentifier(value.carryOverTo)) return false;
|
|
3279
|
+
for (const k of ["itemsAdd", "itemsUpdate"]) {
|
|
3280
|
+
const list = value[k];
|
|
3281
|
+
if (list !== void 0 && (!Array.isArray(list) || list.length > 500 || !list.every(isRecord))) return false;
|
|
3282
|
+
}
|
|
3189
3283
|
if (value.goal !== void 0 && typeof value.goal !== "string") return false;
|
|
3190
3284
|
if (value.status !== void 0 && !isMeshMissionStatusValue(value.status)) return false;
|
|
3191
3285
|
if (value.brief !== void 0 && value.brief !== null && !isMissionBriefWire(value.brief)) return false;
|
|
@@ -3195,7 +3289,7 @@ function decodeMissionUpsertRequest(value) {
|
|
|
3195
3289
|
return isMissionUpsertRequest(value) ? value : null;
|
|
3196
3290
|
}
|
|
3197
3291
|
function isMissionUpsertResponse(value) {
|
|
3198
|
-
return isRecord(value) && hasOnlyKeys2(value, ["mission"]) && isMeshMissionRecordWire(value.mission);
|
|
3292
|
+
return isRecord(value) && hasOnlyKeys2(value, ["mission", "result"]) && isMeshMissionRecordWire(value.mission) && (value.result === void 0 || isRecord(value.result));
|
|
3199
3293
|
}
|
|
3200
3294
|
function decodeMissionUpsertResponse(value) {
|
|
3201
3295
|
return isMissionUpsertResponse(value) ? value : null;
|
|
@@ -3221,7 +3315,10 @@ function decodeMissionQueryResponse(value) {
|
|
|
3221
3315
|
return isMissionQueryResponse(value) ? value : null;
|
|
3222
3316
|
}
|
|
3223
3317
|
function isMissionListQueryRequest(value) {
|
|
3224
|
-
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "statuses", "verbose", "withStats", "limit", "historyIdLimit", "meshStatusView"])) return false;
|
|
3318
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "statuses", "verbose", "withStats", "limit", "historyIdLimit", "meshStatusView", "structured", "items", "history"])) return false;
|
|
3319
|
+
for (const k of ["structured", "items", "history"]) {
|
|
3320
|
+
if (value[k] !== void 0 && typeof value[k] !== "boolean") return false;
|
|
3321
|
+
}
|
|
3225
3322
|
if (value.meshStatusView !== void 0 && value.meshStatusView !== "compact" && value.meshStatusView !== "verbose") return false;
|
|
3226
3323
|
if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false;
|
|
3227
3324
|
if (!isEvidenceIdentifier(value.meshId)) return false;
|
|
@@ -3263,7 +3360,7 @@ function isMissionListSummaryWire(value) {
|
|
|
3263
3360
|
const hasGoal = "goal" in value;
|
|
3264
3361
|
const hasPreview = "goalPreview" in value && "goalTruncated" in value;
|
|
3265
3362
|
if (hasGoal === hasPreview) return false;
|
|
3266
|
-
const baseKeys = ["id", "meshId", "title", "status", "tasks", "stats", "brief", "createdAt", "updatedAt", "closeCandidateEmittedAt"];
|
|
3363
|
+
const baseKeys = ["id", "meshId", "title", "status", "tasks", "stats", "brief", "createdAt", "updatedAt", "closeCandidateEmittedAt", ...STRUCTURED_MISSION_KEYS, "items", "history"];
|
|
3267
3364
|
const allowed = hasGoal ? [...baseKeys, "goal"] : [...baseKeys, "goalPreview", "goalTruncated"];
|
|
3268
3365
|
if (!hasOnlyKeys2(value, allowed)) return false;
|
|
3269
3366
|
if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false;
|
|
@@ -3277,6 +3374,10 @@ function isMissionListSummaryWire(value) {
|
|
|
3277
3374
|
if (value.createdAt !== void 0 && typeof value.createdAt !== "string") return false;
|
|
3278
3375
|
if (value.updatedAt !== void 0 && typeof value.updatedAt !== "string") return false;
|
|
3279
3376
|
if (value.closeCandidateEmittedAt !== void 0 && value.closeCandidateEmittedAt !== null && typeof value.closeCandidateEmittedAt !== "string") return false;
|
|
3377
|
+
if (!isStructuredMissionFields(value)) return false;
|
|
3378
|
+
for (const k of ["items", "history"]) {
|
|
3379
|
+
if (value[k] !== void 0 && (!Array.isArray(value[k]) || !value[k].every(isRecord))) return false;
|
|
3380
|
+
}
|
|
3280
3381
|
return true;
|
|
3281
3382
|
}
|
|
3282
3383
|
function isMeshMissionHistoryFoldWire(value) {
|
|
@@ -3799,6 +3900,282 @@ function touchedFilesOutsideOwnership(touched, owned) {
|
|
|
3799
3900
|
return { undeclaredTouched, unusedDeclarations };
|
|
3800
3901
|
}
|
|
3801
3902
|
|
|
3903
|
+
// src/mission-items.ts
|
|
3904
|
+
var MISSION_ITEM_KINDS = ["remaining", "live_check", "decision", "evidence"];
|
|
3905
|
+
var MISSION_ITEM_STATES = ["open", "done", "dropped", "moved", "answered", "expired", "withdrawn", "superseded"];
|
|
3906
|
+
var COORDINATOR_SETTABLE_ITEM_STATES = {
|
|
3907
|
+
remaining: ["open", "done", "dropped"],
|
|
3908
|
+
live_check: ["open", "done", "dropped"],
|
|
3909
|
+
evidence: ["open", "done", "dropped"],
|
|
3910
|
+
decision: ["open", "withdrawn", "superseded"]
|
|
3911
|
+
};
|
|
3912
|
+
var MISSION_OUTCOMES = ["merged", "verified_live", "superseded", "not_needed", "owner_abandoned", "unspecified"];
|
|
3913
|
+
function isMissionOutcome(value) {
|
|
3914
|
+
return typeof value === "string" && MISSION_OUTCOMES.includes(value);
|
|
3915
|
+
}
|
|
3916
|
+
var MISSION_REF_KINDS = ["commit", "branch", "pr", "task", "artifact", "mission", "url"];
|
|
3917
|
+
var MISSION_LIMITS = {
|
|
3918
|
+
summary: 300,
|
|
3919
|
+
outcomeReason: 500,
|
|
3920
|
+
itemText: 300,
|
|
3921
|
+
machine: 80,
|
|
3922
|
+
refs: 8,
|
|
3923
|
+
refValue: 300,
|
|
3924
|
+
refRepo: 120,
|
|
3925
|
+
refNote: 200,
|
|
3926
|
+
dedupeKey: 400,
|
|
3927
|
+
question: 300,
|
|
3928
|
+
context: 600,
|
|
3929
|
+
options: 5,
|
|
3930
|
+
optionLabel: 60,
|
|
3931
|
+
optionDetail: 200,
|
|
3932
|
+
/** Open items per mission before the oldest `remaining` fold into a "N more" summary item. */
|
|
3933
|
+
openItemsPerMission: 200,
|
|
3934
|
+
/** One event payload (serialized). */
|
|
3935
|
+
eventPayloadBytes: 16 * 1024,
|
|
3936
|
+
/** items_add / items_update entries honoured per call (extra entries are reported, not applied). */
|
|
3937
|
+
itemsPerCall: 50
|
|
3938
|
+
};
|
|
3939
|
+
var MISSION_DECISION_OPTION_IDS = ["a", "b", "c", "d", "e"];
|
|
3940
|
+
var MISSION_DECISION_URGENCIES = ["normal", "blocking"];
|
|
3941
|
+
var MISSION_DECISION_ON_DUE = ["remind", "apply_recommended"];
|
|
3942
|
+
function truncateMissionText(value, max) {
|
|
3943
|
+
if (value.length <= max) return value;
|
|
3944
|
+
return `${value.slice(0, max - 1).trimEnd()}\u2026`;
|
|
3945
|
+
}
|
|
3946
|
+
function str(value) {
|
|
3947
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3948
|
+
}
|
|
3949
|
+
function collapse(value) {
|
|
3950
|
+
return value.replace(/\s+/g, " ").trim();
|
|
3951
|
+
}
|
|
3952
|
+
function normalizeMissionSummary(value) {
|
|
3953
|
+
if (typeof value !== "string") return null;
|
|
3954
|
+
const text = collapse(value);
|
|
3955
|
+
return { value: truncateMissionText(text, MISSION_LIMITS.summary), truncated: text.length > MISSION_LIMITS.summary };
|
|
3956
|
+
}
|
|
3957
|
+
function normalizeOutcomeReason(value) {
|
|
3958
|
+
if (typeof value !== "string") return null;
|
|
3959
|
+
const text = value.trim();
|
|
3960
|
+
return { value: truncateMissionText(text, MISSION_LIMITS.outcomeReason), truncated: text.length > MISSION_LIMITS.outcomeReason };
|
|
3961
|
+
}
|
|
3962
|
+
function normalizeMissionRefs(value) {
|
|
3963
|
+
if (!Array.isArray(value)) return { refs: [], truncated: false };
|
|
3964
|
+
const refs = [];
|
|
3965
|
+
let truncated = false;
|
|
3966
|
+
for (const raw of value) {
|
|
3967
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
3968
|
+
const r = raw;
|
|
3969
|
+
const kind = str(r.kind);
|
|
3970
|
+
const refValue = str(r.value);
|
|
3971
|
+
if (!MISSION_REF_KINDS.includes(kind) || !refValue) continue;
|
|
3972
|
+
if (refs.length >= MISSION_LIMITS.refs) {
|
|
3973
|
+
truncated = true;
|
|
3974
|
+
break;
|
|
3975
|
+
}
|
|
3976
|
+
const repo = str(r.repo);
|
|
3977
|
+
const note = str(r.note);
|
|
3978
|
+
refs.push({
|
|
3979
|
+
kind,
|
|
3980
|
+
...repo ? { repo: truncateMissionText(repo, MISSION_LIMITS.refRepo) } : {},
|
|
3981
|
+
value: truncateMissionText(refValue, MISSION_LIMITS.refValue),
|
|
3982
|
+
...note ? { note: truncateMissionText(note, MISSION_LIMITS.refNote) } : {}
|
|
3983
|
+
});
|
|
3984
|
+
}
|
|
3985
|
+
return { refs, truncated };
|
|
3986
|
+
}
|
|
3987
|
+
function normalizeOptions(value, truncated) {
|
|
3988
|
+
if (!Array.isArray(value)) return [];
|
|
3989
|
+
const out = [];
|
|
3990
|
+
for (const raw of value) {
|
|
3991
|
+
if (typeof raw === "string" && raw.trim()) {
|
|
3992
|
+
if (out.length >= MISSION_LIMITS.options) {
|
|
3993
|
+
truncated.push("options");
|
|
3994
|
+
break;
|
|
3995
|
+
}
|
|
3996
|
+
out.push({ id: MISSION_DECISION_OPTION_IDS[out.length], label: truncateMissionText(raw.trim(), MISSION_LIMITS.optionLabel) });
|
|
3997
|
+
continue;
|
|
3998
|
+
}
|
|
3999
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
4000
|
+
const o = raw;
|
|
4001
|
+
const label = collapse(str(o.label));
|
|
4002
|
+
if (!label) continue;
|
|
4003
|
+
if (out.length >= MISSION_LIMITS.options) {
|
|
4004
|
+
truncated.push("options");
|
|
4005
|
+
break;
|
|
4006
|
+
}
|
|
4007
|
+
const detail = str(o.detail);
|
|
4008
|
+
out.push({
|
|
4009
|
+
id: MISSION_DECISION_OPTION_IDS[out.length],
|
|
4010
|
+
label: truncateMissionText(label, MISSION_LIMITS.optionLabel),
|
|
4011
|
+
...detail ? { detail: truncateMissionText(detail, MISSION_LIMITS.optionDetail) } : {}
|
|
4012
|
+
});
|
|
4013
|
+
}
|
|
4014
|
+
return out;
|
|
4015
|
+
}
|
|
4016
|
+
function normalizeDueAt(value) {
|
|
4017
|
+
if (typeof value !== "string" || !value.trim()) return void 0;
|
|
4018
|
+
const ms2 = Date.parse(value);
|
|
4019
|
+
return Number.isNaN(ms2) ? void 0 : new Date(ms2).toISOString();
|
|
4020
|
+
}
|
|
4021
|
+
function normalizeDecisionInput(raw, truncated) {
|
|
4022
|
+
const questionSource = collapse(str(raw.question) || str(raw.text));
|
|
4023
|
+
if (!questionSource) return null;
|
|
4024
|
+
if (questionSource.length > MISSION_LIMITS.question) truncated.push("question");
|
|
4025
|
+
const question = truncateMissionText(questionSource, MISSION_LIMITS.question);
|
|
4026
|
+
const contextSource = str(raw.context);
|
|
4027
|
+
if (contextSource.length > MISSION_LIMITS.context) truncated.push("context");
|
|
4028
|
+
const options = normalizeOptions(raw.options, truncated);
|
|
4029
|
+
const recommendedRaw = str(raw.recommended);
|
|
4030
|
+
const recommended = recommendedRaw && options.some((o) => o.id === recommendedRaw) ? recommendedRaw : options.find((o) => recommendedRaw && o.label.toLowerCase() === recommendedRaw.toLowerCase())?.id;
|
|
4031
|
+
const dueAt = normalizeDueAt(raw.dueAt ?? raw.due_at);
|
|
4032
|
+
const onDueRaw = str(raw.onDue ?? raw.on_due);
|
|
4033
|
+
const urgencyRaw = str(raw.urgency);
|
|
4034
|
+
const allowFreeTextRaw = raw.allowFreeText ?? raw.allow_free_text;
|
|
4035
|
+
return {
|
|
4036
|
+
question,
|
|
4037
|
+
...contextSource ? { context: truncateMissionText(contextSource, MISSION_LIMITS.context) } : {},
|
|
4038
|
+
options,
|
|
4039
|
+
...recommended ? { recommended } : {},
|
|
4040
|
+
allowFreeText: typeof allowFreeTextRaw === "boolean" ? allowFreeTextRaw : true,
|
|
4041
|
+
...dueAt ? { dueAt } : {},
|
|
4042
|
+
// apply_recommended without a recommended option has nothing to apply — fall back to remind.
|
|
4043
|
+
onDue: onDueRaw === "apply_recommended" && recommended ? "apply_recommended" : "remind",
|
|
4044
|
+
urgency: urgencyRaw === "blocking" ? "blocking" : "normal"
|
|
4045
|
+
};
|
|
4046
|
+
}
|
|
4047
|
+
function normalizeForDedupe(text) {
|
|
4048
|
+
return collapse(text).toLowerCase().replace(/[\s.!?。]+$/u, "");
|
|
4049
|
+
}
|
|
4050
|
+
function deriveItemDedupeKey(kind, parts) {
|
|
4051
|
+
const explicit = str(parts.explicit);
|
|
4052
|
+
if (explicit) return truncateMissionText(`k:${explicit}`, MISSION_LIMITS.dedupeKey);
|
|
4053
|
+
if (kind === "decision") return truncateMissionText(`decision:${normalizeForDedupe(parts.question ?? parts.text ?? "")}`, MISSION_LIMITS.dedupeKey);
|
|
4054
|
+
if (kind === "evidence") {
|
|
4055
|
+
const ref2 = parts.refs?.[0];
|
|
4056
|
+
if (ref2) return truncateMissionText(`evidence:${ref2.kind}:${ref2.repo ?? ""}:${ref2.value}`, MISSION_LIMITS.dedupeKey);
|
|
4057
|
+
}
|
|
4058
|
+
const machine = parts.machine ? `@${normalizeForDedupe(parts.machine)}` : "";
|
|
4059
|
+
return truncateMissionText(`${kind}${machine}:${normalizeForDedupe(parts.text ?? "")}`, MISSION_LIMITS.dedupeKey);
|
|
4060
|
+
}
|
|
4061
|
+
function normalizeMissionItemInput(raw) {
|
|
4062
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "item must be an object" };
|
|
4063
|
+
const r = raw;
|
|
4064
|
+
const kind = str(r.kind) || "remaining";
|
|
4065
|
+
if (!MISSION_ITEM_KINDS.includes(kind)) {
|
|
4066
|
+
return { error: `invalid kind '${kind}' (valid: ${MISSION_ITEM_KINDS.join(", ")})` };
|
|
4067
|
+
}
|
|
4068
|
+
const truncated = [];
|
|
4069
|
+
const { refs, truncated: refsTruncated } = normalizeMissionRefs(r.refs);
|
|
4070
|
+
if (refsTruncated) truncated.push("refs");
|
|
4071
|
+
const machineRaw = collapse(str(r.machine));
|
|
4072
|
+
const machine = machineRaw ? truncateMissionText(machineRaw, MISSION_LIMITS.machine) : void 0;
|
|
4073
|
+
const explicitKey = str(r.dedupe_key ?? r.dedupeKey);
|
|
4074
|
+
if (kind === "decision") {
|
|
4075
|
+
const decisionRaw = r.decision && typeof r.decision === "object" && !Array.isArray(r.decision) ? r.decision : r;
|
|
4076
|
+
const decision = normalizeDecisionInput({ ...decisionRaw, question: decisionRaw.question ?? r.question ?? r.text }, truncated);
|
|
4077
|
+
if (!decision) return { error: "decision item needs a question" };
|
|
4078
|
+
return {
|
|
4079
|
+
item: {
|
|
4080
|
+
kind,
|
|
4081
|
+
text: decision.question,
|
|
4082
|
+
...machine ? { machine } : {},
|
|
4083
|
+
refs,
|
|
4084
|
+
decision,
|
|
4085
|
+
dedupeKey: deriveItemDedupeKey("decision", { question: decision.question, explicit: explicitKey }),
|
|
4086
|
+
truncated
|
|
4087
|
+
}
|
|
4088
|
+
};
|
|
4089
|
+
}
|
|
4090
|
+
const textSource = collapse(str(r.text));
|
|
4091
|
+
if (!textSource && !(kind === "evidence" && refs.length > 0)) return { error: `${kind} item needs text` };
|
|
4092
|
+
if (textSource.length > MISSION_LIMITS.itemText) truncated.push("text");
|
|
4093
|
+
const text = truncateMissionText(textSource || `${refs[0].kind}: ${refs[0].value}`, MISSION_LIMITS.itemText);
|
|
4094
|
+
return {
|
|
4095
|
+
item: {
|
|
4096
|
+
kind,
|
|
4097
|
+
text,
|
|
4098
|
+
...machine ? { machine } : {},
|
|
4099
|
+
refs,
|
|
4100
|
+
dedupeKey: deriveItemDedupeKey(kind, { text, machine, refs, explicit: explicitKey }),
|
|
4101
|
+
truncated
|
|
4102
|
+
}
|
|
4103
|
+
};
|
|
4104
|
+
}
|
|
4105
|
+
function normalizeMissionItemUpdate(raw) {
|
|
4106
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "update must be an object" };
|
|
4107
|
+
const r = raw;
|
|
4108
|
+
const id2 = str(r.id ?? r.item_id ?? r.itemId);
|
|
4109
|
+
if (!id2) return { error: "update needs an item id" };
|
|
4110
|
+
const truncated = [];
|
|
4111
|
+
const update = { id: id2 };
|
|
4112
|
+
if (r.state !== void 0) {
|
|
4113
|
+
const state = str(r.state);
|
|
4114
|
+
if (!MISSION_ITEM_STATES.includes(state)) return { error: `invalid state '${state}'` };
|
|
4115
|
+
update.state = state;
|
|
4116
|
+
}
|
|
4117
|
+
if (typeof r.text === "string") {
|
|
4118
|
+
const text = collapse(r.text);
|
|
4119
|
+
if (text.length > MISSION_LIMITS.itemText) truncated.push("text");
|
|
4120
|
+
if (text) update.text = truncateMissionText(text, MISSION_LIMITS.itemText);
|
|
4121
|
+
}
|
|
4122
|
+
if (r.machine === null) update.machine = null;
|
|
4123
|
+
else if (typeof r.machine === "string") {
|
|
4124
|
+
const machine = collapse(r.machine);
|
|
4125
|
+
update.machine = machine ? truncateMissionText(machine, MISSION_LIMITS.machine) : null;
|
|
4126
|
+
}
|
|
4127
|
+
if (r.refs !== void 0) {
|
|
4128
|
+
const { refs, truncated: t } = normalizeMissionRefs(r.refs);
|
|
4129
|
+
if (t) truncated.push("refs");
|
|
4130
|
+
update.refs = refs;
|
|
4131
|
+
}
|
|
4132
|
+
return { update, truncated };
|
|
4133
|
+
}
|
|
4134
|
+
function boundEventPayload(payload) {
|
|
4135
|
+
let json = JSON.stringify(payload);
|
|
4136
|
+
if (json.length <= MISSION_LIMITS.eventPayloadBytes) return json;
|
|
4137
|
+
const shrunk = {};
|
|
4138
|
+
for (const [k, v] of Object.entries(payload)) {
|
|
4139
|
+
shrunk[k] = typeof v === "string" && v.length > 4e3 ? `${v.slice(0, 4e3)}\u2026` : v;
|
|
4140
|
+
}
|
|
4141
|
+
shrunk.payloadTruncated = true;
|
|
4142
|
+
json = JSON.stringify(shrunk);
|
|
4143
|
+
if (json.length <= MISSION_LIMITS.eventPayloadBytes) return json;
|
|
4144
|
+
return JSON.stringify({ payloadTruncated: true, keys: Object.keys(payload).slice(0, 20) });
|
|
4145
|
+
}
|
|
4146
|
+
var CARRY_OVER_MISSION_TITLE = "Carry-over \u2014 open items from closed missions";
|
|
4147
|
+
var LEGACY_CARRY_OVER_MISSION_TITLE = "\uC774\uC6D4 \u2014 \uB2EB\uD78C \uBBF8\uC158\uC5D0\uC11C \uB118\uC5B4\uC628 \uD56D\uBAA9";
|
|
4148
|
+
var CARRY_OVER_MISSION_GOAL = "Open items carried over from closed missions, and decisions requested without a mission. Managed automatically \u2014 do not close.";
|
|
4149
|
+
function isCarryOverMissionRecord(m) {
|
|
4150
|
+
return !!m && (m.isCarryOver === true || isCarryOverMissionTitle(m.title));
|
|
4151
|
+
}
|
|
4152
|
+
function isCarryOverMissionTitle(title) {
|
|
4153
|
+
if (typeof title !== "string") return false;
|
|
4154
|
+
const t = title.trim();
|
|
4155
|
+
return t === CARRY_OVER_MISSION_TITLE || t === LEGACY_CARRY_OVER_MISSION_TITLE;
|
|
4156
|
+
}
|
|
4157
|
+
var OWNER_ABANDON_CONFIRM_KEY_PREFIX = "owner-abandon-confirm:";
|
|
4158
|
+
var OWNER_ABANDON_CONFIRM_QUESTION = "The coordinator closed this as 'owner abandoned' \u2014 correct?";
|
|
4159
|
+
var OWNER_ABANDON_CONFIRM_OPTIONS = ["Correct", "Reopen"];
|
|
4160
|
+
var WORKER_DECISIONS_NEEDED_MAX = 3;
|
|
4161
|
+
var WORKER_COMMITS_MAX = 20;
|
|
4162
|
+
var SHA_RE = /^[0-9a-f]{7,64}$/i;
|
|
4163
|
+
function normalizeReportCommits(value) {
|
|
4164
|
+
if (!Array.isArray(value)) return null;
|
|
4165
|
+
const out = [];
|
|
4166
|
+
for (const v of value) {
|
|
4167
|
+
if (typeof v !== "string") return null;
|
|
4168
|
+
const sha = v.trim();
|
|
4169
|
+
if (!SHA_RE.test(sha)) return null;
|
|
4170
|
+
if (!out.includes(sha.toLowerCase())) out.push(sha.toLowerCase());
|
|
4171
|
+
}
|
|
4172
|
+
return out;
|
|
4173
|
+
}
|
|
4174
|
+
|
|
4175
|
+
// src/decision-push-relay.ts
|
|
4176
|
+
var DECISION_PUSH_RELAY_COMMAND = "mission_decision_push_relay_answer";
|
|
4177
|
+
var DECISION_PUSH_RELAY_SOURCE = "push_relay";
|
|
4178
|
+
|
|
3802
4179
|
// src/keyed-doc-delta.ts
|
|
3803
4180
|
function sig(value) {
|
|
3804
4181
|
if (value === void 0) return void 0;
|
|
@@ -4261,12 +4638,15 @@ var RelayReprobeScheduler = class {
|
|
|
4261
4638
|
CANCEL_REASONS,
|
|
4262
4639
|
CANONICAL_MESH_TOOL_COUNT,
|
|
4263
4640
|
CANONICAL_MESH_TOOL_NAMES,
|
|
4641
|
+
CARRY_OVER_MISSION_GOAL,
|
|
4642
|
+
CARRY_OVER_MISSION_TITLE,
|
|
4264
4643
|
CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX,
|
|
4265
4644
|
CLAUDE_TUI_REVIEW_UNCONFIRMED_PREFIX,
|
|
4266
4645
|
CLI_SLOT_RECIPES,
|
|
4267
4646
|
COMMIT_STRENGTHS,
|
|
4268
4647
|
CONSUME_PROFILES,
|
|
4269
4648
|
COORDINATOR_ACK_OUTCOMES,
|
|
4649
|
+
COORDINATOR_SETTABLE_ITEM_STATES,
|
|
4270
4650
|
DAEMON_METADATA_DOC_SPEC,
|
|
4271
4651
|
DAEMON_P2P_SIGNAL_TYPES,
|
|
4272
4652
|
DAEMON_STATUS_EVENT_NAMES,
|
|
@@ -4279,6 +4659,11 @@ var RelayReprobeScheduler = class {
|
|
|
4279
4659
|
DASHBOARD_TO_DAEMON_P2P_TYPES,
|
|
4280
4660
|
DASHBOARD_TO_USER_SESSION_TYPES,
|
|
4281
4661
|
DASHBOARD_WIRE_VERSION,
|
|
4662
|
+
DECISION_PUSH_OPTIONS_MAX,
|
|
4663
|
+
DECISION_PUSH_OPTION_LABEL_MAX,
|
|
4664
|
+
DECISION_PUSH_QUESTION_MAX,
|
|
4665
|
+
DECISION_PUSH_RELAY_COMMAND,
|
|
4666
|
+
DECISION_PUSH_RELAY_SOURCE,
|
|
4282
4667
|
DEFAULT_DIFFICULTY_BRAINS,
|
|
4283
4668
|
DELIVERY_OUTCOMES,
|
|
4284
4669
|
DELIVERY_VIAS,
|
|
@@ -4290,6 +4675,7 @@ var RelayReprobeScheduler = class {
|
|
|
4290
4675
|
LAUNCH_DEFAULT_ERROR_CODES,
|
|
4291
4676
|
LAUNCH_DEFAULT_ROLES,
|
|
4292
4677
|
LAUNCH_DEFAULT_SOURCES,
|
|
4678
|
+
LEGACY_CARRY_OVER_MISSION_TITLE,
|
|
4293
4679
|
LIVENESS_RESULTS,
|
|
4294
4680
|
MAX_MESH_RECORD_STRING,
|
|
4295
4681
|
MAX_OWNED_PATHS,
|
|
@@ -4315,6 +4701,14 @@ var RelayReprobeScheduler = class {
|
|
|
4315
4701
|
MESH_TOPIC_ENTRY_KINDS,
|
|
4316
4702
|
MESH_TOPIC_PROTOCOL_VERSION,
|
|
4317
4703
|
MISSION_BRIEF_RENDER_MAX_CHARS,
|
|
4704
|
+
MISSION_DECISION_ON_DUE,
|
|
4705
|
+
MISSION_DECISION_OPTION_IDS,
|
|
4706
|
+
MISSION_DECISION_URGENCIES,
|
|
4707
|
+
MISSION_ITEM_KINDS,
|
|
4708
|
+
MISSION_ITEM_STATES,
|
|
4709
|
+
MISSION_LIMITS,
|
|
4710
|
+
MISSION_OUTCOMES,
|
|
4711
|
+
MISSION_REF_KINDS,
|
|
4318
4712
|
MODEL_AXIS_SOURCES,
|
|
4319
4713
|
MODEL_SELECTION_HISTORY_LIMIT,
|
|
4320
4714
|
MeshChunkAssembler,
|
|
@@ -4328,6 +4722,9 @@ var RelayReprobeScheduler = class {
|
|
|
4328
4722
|
OPERATOR_STATUS_REASON_VALUES,
|
|
4329
4723
|
OPERATOR_STATUS_VALUES,
|
|
4330
4724
|
OUTBOUND_MESSAGE_ORIGINS,
|
|
4725
|
+
OWNER_ABANDON_CONFIRM_KEY_PREFIX,
|
|
4726
|
+
OWNER_ABANDON_CONFIRM_OPTIONS,
|
|
4727
|
+
OWNER_ABANDON_CONFIRM_QUESTION,
|
|
4331
4728
|
P2P_SIGNAL_TYPES,
|
|
4332
4729
|
PROVIDER_FAILURES,
|
|
4333
4730
|
QUOTA_BACKFILL_HORIZON_MS,
|
|
@@ -4379,6 +4776,8 @@ var RelayReprobeScheduler = class {
|
|
|
4379
4776
|
VERSION_UPDATE_REASONS,
|
|
4380
4777
|
VIEWER_TO_SHARED_SESSION_TYPES,
|
|
4381
4778
|
WORKER_BRANCH_STATES,
|
|
4779
|
+
WORKER_COMMITS_MAX,
|
|
4780
|
+
WORKER_DECISIONS_NEEDED_MAX,
|
|
4382
4781
|
WORKER_PROTOCOL_FOOTER_MARKER,
|
|
4383
4782
|
WORKER_REPORT_OUTCOMES,
|
|
4384
4783
|
WORKER_REPORT_SUMMARY_MAX_CHARS,
|
|
@@ -4386,6 +4785,7 @@ var RelayReprobeScheduler = class {
|
|
|
4386
4785
|
appendWorkerProtocolFooter,
|
|
4387
4786
|
argsCarryStatusProbeMarker,
|
|
4388
4787
|
assessQuotaFreshness,
|
|
4788
|
+
boundEventPayload,
|
|
4389
4789
|
buildSlotProposal,
|
|
4390
4790
|
canonicalDaemonId,
|
|
4391
4791
|
classifySessionStatus,
|
|
@@ -4455,6 +4855,7 @@ var RelayReprobeScheduler = class {
|
|
|
4455
4855
|
decodeUserSessionToDashboard,
|
|
4456
4856
|
decodeViewerToSharedSession,
|
|
4457
4857
|
defaultProviderPriorityFromNodeFacts,
|
|
4858
|
+
deriveItemDedupeKey,
|
|
4458
4859
|
deriveProviderPriorityFromSlots,
|
|
4459
4860
|
deriveSlotsFromLegacy,
|
|
4460
4861
|
describeModelSelection,
|
|
@@ -4466,6 +4867,7 @@ var RelayReprobeScheduler = class {
|
|
|
4466
4867
|
findOwnershipConflicts,
|
|
4467
4868
|
foldKeyedDoc,
|
|
4468
4869
|
followedRemoteProjectKey,
|
|
4870
|
+
followerOpPermitted,
|
|
4469
4871
|
formatQuotaAccount,
|
|
4470
4872
|
hasGitStatusEvidence,
|
|
4471
4873
|
hasWorkerProtocolFooter,
|
|
@@ -4475,6 +4877,8 @@ var RelayReprobeScheduler = class {
|
|
|
4475
4877
|
isAssistantTool,
|
|
4476
4878
|
isBlockedStatus,
|
|
4477
4879
|
isBusyStatus,
|
|
4880
|
+
isCarryOverMissionRecord,
|
|
4881
|
+
isCarryOverMissionTitle,
|
|
4478
4882
|
isChunkType,
|
|
4479
4883
|
isCommitStrength,
|
|
4480
4884
|
isDaemonDirectCommandType,
|
|
@@ -4507,6 +4911,7 @@ var RelayReprobeScheduler = class {
|
|
|
4507
4911
|
isMeshTerminalTaskStatus,
|
|
4508
4912
|
isMeshTopicEntry,
|
|
4509
4913
|
isMessageId,
|
|
4914
|
+
isMissionOutcome,
|
|
4510
4915
|
isMissionUpsertResponse,
|
|
4511
4916
|
isModelAxisSource,
|
|
4512
4917
|
isNativeMarkerRef,
|
|
@@ -4557,16 +4962,24 @@ var RelayReprobeScheduler = class {
|
|
|
4557
4962
|
minutesUntilQuotaCheck,
|
|
4558
4963
|
normalizeAuthOkLimits,
|
|
4559
4964
|
normalizeBrainSlot,
|
|
4965
|
+
normalizeDecisionInput,
|
|
4560
4966
|
normalizeDifficultyBrainMap,
|
|
4967
|
+
normalizeForDedupe,
|
|
4561
4968
|
normalizeGitStatus,
|
|
4562
4969
|
normalizeMeshNodeFacts,
|
|
4563
4970
|
normalizeMeshNodeId,
|
|
4564
4971
|
normalizeMeshSessionRecord,
|
|
4565
4972
|
normalizeMeshWorkspaceForCompare,
|
|
4566
4973
|
normalizeMissionBrief,
|
|
4974
|
+
normalizeMissionItemInput,
|
|
4975
|
+
normalizeMissionItemUpdate,
|
|
4976
|
+
normalizeMissionRefs,
|
|
4977
|
+
normalizeMissionSummary,
|
|
4567
4978
|
normalizeNodeCapabilitySlot,
|
|
4568
4979
|
normalizeNodeCapabilitySlots,
|
|
4980
|
+
normalizeOutcomeReason,
|
|
4569
4981
|
normalizeOwnedPaths,
|
|
4982
|
+
normalizeReportCommits,
|
|
4570
4983
|
normalizeSessionStatus,
|
|
4571
4984
|
normalizeThinkingLevel,
|
|
4572
4985
|
orderProvidersByBuiltinPreference,
|
|
@@ -4606,6 +5019,7 @@ var RelayReprobeScheduler = class {
|
|
|
4606
5019
|
summarizeGitShape,
|
|
4607
5020
|
supportsQuota,
|
|
4608
5021
|
touchedFilesOutsideOwnership,
|
|
5022
|
+
truncateMissionText,
|
|
4609
5023
|
unwrapPastedContent,
|
|
4610
5024
|
withStatusProbeMarker
|
|
4611
5025
|
});
|