@adhdev/mesh-shared 1.0.82-rc.4 → 1.0.82-rc.40
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 +161 -6
- package/dist/decision-push-relay.d.ts +20 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +1197 -118
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1107 -118
- package/dist/index.mjs.map +1 -1
- package/dist/launch-defaults.d.ts +196 -0
- package/dist/mesh-tool-names.d.ts +2 -2
- package/dist/mesh-vocabulary.d.ts +13 -4
- package/dist/mission-git-state.d.ts +83 -0
- package/dist/mission-items.d.ts +202 -0
- package/dist/node-facts.d.ts +75 -1
- package/dist/outbound-message.d.ts +9 -2
- package/dist/path-ownership.d.ts +1 -1
- package/dist/protocol/daemon-server.d.ts +42 -2
- package/dist/protocol/dashboard-daemon-p2p.d.ts +1 -1
- package/dist/protocol/dashboard-server.d.ts +20 -2
- package/dist/provider-approval.d.ts +36 -0
- package/dist/provider-question.d.ts +19 -0
- package/dist/quota-freshness.d.ts +65 -0
- package/dist/relay-reprobe.d.ts +52 -0
- package/dist/release.d.ts +90 -0
- package/dist/role-launch.d.ts +11 -0
- package/dist/session-launch.d.ts +10 -22
- package/dist/slot-proposal.d.ts +14 -0
- package/dist/task-source-phase.d.ts +75 -0
- package/dist/turn-evidence.d.ts +29 -13
- package/dist/turn-ipc-mission.d.ts +68 -1
- package/dist/turn-ipc-queue.d.ts +19 -0
- package/dist/turn-ipc.d.ts +2 -2
- package/dist/types.d.ts +1 -0
- package/dist/worker-protocol.d.ts +1 -1
- package/package.json +1 -1
- package/src/assistant-protocol.ts +302 -6
- package/src/daemon-normalize.ts +7 -5
- package/src/decision-push-relay.ts +23 -0
- package/src/index.ts +12 -0
- package/src/keyed-doc-delta.ts +9 -1
- package/src/launch-defaults.ts +170 -0
- package/src/mesh-tool-names.ts +16 -0
- package/src/mesh-vocabulary.ts +12 -2
- package/src/mission-git-state.ts +112 -0
- package/src/mission-items.ts +421 -0
- package/src/node-facts.ts +70 -1
- package/src/outbound-message.ts +19 -0
- package/src/path-ownership.ts +4 -6
- package/src/protocol/daemon-server.ts +37 -2
- package/src/protocol/dashboard-server.ts +13 -2
- package/src/provider-approval.ts +59 -0
- package/src/provider-question.ts +31 -0
- package/src/quota-freshness.ts +139 -0
- package/src/relay-reprobe.ts +117 -0
- package/src/release.ts +121 -0
- package/src/role-launch.ts +51 -0
- package/src/session-launch.ts +17 -1
- package/src/slot-proposal.ts +61 -2
- package/src/task-source-phase.ts +61 -0
- package/src/turn-evidence.ts +27 -20
- package/src/turn-ipc-mission.ts +121 -11
- package/src/turn-ipc-queue.ts +29 -1
- package/src/turn-ipc-turn.ts +1 -1
- package/src/turn-ipc.ts +1 -0
- package/src/types.ts +1 -0
- package/src/worker-protocol.ts +15 -0
package/dist/index.mjs
CHANGED
|
@@ -194,15 +194,15 @@ function pickBestTransitGitStatus(node, options) {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
// src/session-normalize.ts
|
|
197
|
-
function deriveSyntheticSessionId(
|
|
197
|
+
function deriveSyntheticSessionId(record2) {
|
|
198
198
|
const parts = [
|
|
199
|
-
readString(
|
|
200
|
-
readString(
|
|
201
|
-
readString(
|
|
202
|
-
readString(
|
|
203
|
-
readString(
|
|
204
|
-
readString(
|
|
205
|
-
readString(
|
|
199
|
+
readString(record2.workspace),
|
|
200
|
+
readString(record2.providerType, record2.provider),
|
|
201
|
+
readString(record2.role),
|
|
202
|
+
readString(record2.state, record2.status),
|
|
203
|
+
readString(record2.title),
|
|
204
|
+
readString(record2.createdAt, record2.created_at),
|
|
205
|
+
readString(record2.startedAt, record2.started_at)
|
|
206
206
|
].filter((part) => Boolean(part));
|
|
207
207
|
if (parts.length === 0) return void 0;
|
|
208
208
|
return `synthetic:${parts.join("|")}`;
|
|
@@ -214,33 +214,33 @@ function sessionIdsEquivalent(a, b) {
|
|
|
214
214
|
return idA === idB;
|
|
215
215
|
}
|
|
216
216
|
function normalizeMeshSessionRecord(entry) {
|
|
217
|
-
const
|
|
218
|
-
const sessionId = readString(
|
|
217
|
+
const record2 = readRecord(entry);
|
|
218
|
+
const sessionId = readString(record2.sessionId, record2.session_id, record2.id) ?? deriveSyntheticSessionId(record2);
|
|
219
219
|
if (!sessionId) return null;
|
|
220
220
|
return {
|
|
221
221
|
sessionId,
|
|
222
|
-
...readString(
|
|
223
|
-
...readString(
|
|
224
|
-
...readString(
|
|
225
|
-
...readString(
|
|
226
|
-
...readString(
|
|
227
|
-
...readString(
|
|
228
|
-
...readString(
|
|
229
|
-
...readString(
|
|
230
|
-
...readString(
|
|
231
|
-
...readBoolean(
|
|
232
|
-
...readString(
|
|
233
|
-
...readString(
|
|
234
|
-
...readString(
|
|
235
|
-
...readString(
|
|
236
|
-
...readBoolean(
|
|
222
|
+
...readString(record2.providerType, record2.provider) ? { providerType: readString(record2.providerType, record2.provider) } : {},
|
|
223
|
+
...readString(record2.state, record2.status) ? { state: readString(record2.state, record2.status) } : {},
|
|
224
|
+
...readString(record2.chatStatus, record2.chat_status) ? { chatStatus: readString(record2.chatStatus, record2.chat_status) } : {},
|
|
225
|
+
...readString(record2.lifecycle) ? { lifecycle: readString(record2.lifecycle) } : {},
|
|
226
|
+
...readString(record2.surfaceKind, record2.surface_kind) ? { surfaceKind: readString(record2.surfaceKind, record2.surface_kind) } : {},
|
|
227
|
+
...readString(record2.recoveryState, record2.recovery_state) ? { recoveryState: readString(record2.recoveryState, record2.recovery_state) } : {},
|
|
228
|
+
...readString(record2.workspace) ? { workspace: readString(record2.workspace) } : {},
|
|
229
|
+
...readString(record2.title) ? { title: readString(record2.title) } : {},
|
|
230
|
+
...readString(record2.role) ? { role: readString(record2.role) } : {},
|
|
231
|
+
...readBoolean(record2.isSelfCoordinator, record2.is_self_coordinator) !== void 0 ? { isSelfCoordinator: readBoolean(record2.isSelfCoordinator, record2.is_self_coordinator) } : {},
|
|
232
|
+
...readString(record2.statusNote, record2.status_note) ? { statusNote: readString(record2.statusNote, record2.status_note) } : {},
|
|
233
|
+
...readString(record2.createdAt, record2.created_at) ? { createdAt: readString(record2.createdAt, record2.created_at) } : {},
|
|
234
|
+
...readString(record2.startedAt, record2.started_at) ? { startedAt: readString(record2.startedAt, record2.started_at) } : {},
|
|
235
|
+
...readString(record2.lastActivityAt, record2.last_activity_at) ? { lastActivityAt: readString(record2.lastActivityAt, record2.last_activity_at) } : {},
|
|
236
|
+
...readBoolean(record2.isCached, record2.is_cached) !== void 0 ? { isCached: readBoolean(record2.isCached, record2.is_cached) } : {}
|
|
237
237
|
};
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
// src/node-normalize.ts
|
|
241
241
|
function normalizeMeshNodeId(node) {
|
|
242
|
-
const
|
|
243
|
-
return readString(
|
|
242
|
+
const record2 = node && typeof node === "object" ? node : {};
|
|
243
|
+
return readString(record2.id, record2.nodeId, record2.node_id);
|
|
244
244
|
}
|
|
245
245
|
function meshNodeIdMatches(node, candidateId) {
|
|
246
246
|
if (!candidateId) return false;
|
|
@@ -252,12 +252,12 @@ function meshNodeIdMatches(node, candidateId) {
|
|
|
252
252
|
// src/node-facts.ts
|
|
253
253
|
function normalizeMeshNodeFacts(raw) {
|
|
254
254
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
255
|
-
const
|
|
256
|
-
const schemaVersion = Number(
|
|
257
|
-
const reportedAt = Number(
|
|
255
|
+
const record2 = raw;
|
|
256
|
+
const schemaVersion = Number(record2.schemaVersion);
|
|
257
|
+
const reportedAt = Number(record2.reportedAt);
|
|
258
258
|
if (!Number.isFinite(schemaVersion) || schemaVersion < 1) return void 0;
|
|
259
259
|
if (!Number.isFinite(reportedAt) || reportedAt <= 0) return void 0;
|
|
260
|
-
return { ...
|
|
260
|
+
return { ...record2, schemaVersion, reportedAt };
|
|
261
261
|
}
|
|
262
262
|
var QUOTA_SUPPORTED_PROVIDERS = [
|
|
263
263
|
"antigravity-cli",
|
|
@@ -300,6 +300,52 @@ function defaultProviderPriorityFromNodeFacts(facts) {
|
|
|
300
300
|
return orderProvidersByBuiltinPreference(detected.length ? detected : enabled);
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
// src/quota-freshness.ts
|
|
304
|
+
var QUOTA_RETRY_INFLIGHT_GRACE_MS = 6e4;
|
|
305
|
+
var QUOTA_BACKFILL_HORIZON_MS = 60 * 60 * 1e3;
|
|
306
|
+
function hasUsableWindow(window) {
|
|
307
|
+
return !!window && typeof window.usedPercent === "number" && Number.isFinite(window.usedPercent);
|
|
308
|
+
}
|
|
309
|
+
function hasReading(quota) {
|
|
310
|
+
if (hasUsableWindow(quota.session) || hasUsableWindow(quota.weekly) || hasUsableWindow(quota.monthly)) return true;
|
|
311
|
+
return Array.isArray(quota.buckets) && quota.buckets.some((b) => !!b && typeof b.usedPercent === "number" && Number.isFinite(b.usedPercent));
|
|
312
|
+
}
|
|
313
|
+
function finiteMs(value) {
|
|
314
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
315
|
+
}
|
|
316
|
+
function backfillCheckAt(quota, now) {
|
|
317
|
+
const dataDue = finiteMs(quota.updatedAt);
|
|
318
|
+
const attempted = finiteMs(quota.metadata?.fetchedAt);
|
|
319
|
+
const dueAt = Math.max(
|
|
320
|
+
dataDue === void 0 ? Number.NEGATIVE_INFINITY : dataDue + QUOTA_BACKFILL_HORIZON_MS,
|
|
321
|
+
attempted === void 0 ? Number.NEGATIVE_INFINITY : attempted + QUOTA_BACKFILL_HORIZON_MS
|
|
322
|
+
);
|
|
323
|
+
return Number.isFinite(dueAt) && dueAt > now ? dueAt : void 0;
|
|
324
|
+
}
|
|
325
|
+
function assessQuotaFreshness(quota, now = Date.now()) {
|
|
326
|
+
const meta = quota.metadata;
|
|
327
|
+
const kind = meta?.failureKind;
|
|
328
|
+
const userMustAct = kind === "no-data" && quota.provider !== "codex-cli";
|
|
329
|
+
const awaitsCliUse = kind === "expired-token" && ["grok-cli", "kimi", "antigravity-cli"].includes(quota.provider);
|
|
330
|
+
if (userMustAct) return hasReading(quota) ? { cue: "stale", userMustAct: true } : { userMustAct: true };
|
|
331
|
+
if (awaitsCliUse) return hasReading(quota) ? { cue: "stale", userMustAct: false } : { userMustAct: false };
|
|
332
|
+
if (meta?.lastGoodWindows !== true) {
|
|
333
|
+
const measuredAt = finiteMs(quota.updatedAt);
|
|
334
|
+
if (hasReading(quota) && (measuredAt === void 0 || now - measuredAt >= QUOTA_BACKFILL_HORIZON_MS)) {
|
|
335
|
+
return { cue: "stale", userMustAct };
|
|
336
|
+
}
|
|
337
|
+
return { userMustAct };
|
|
338
|
+
}
|
|
339
|
+
const retryAtMs = finiteMs(meta?.retryAtMs);
|
|
340
|
+
const retryStopped = meta?.retryExhausted === true || retryAtMs !== void 0 && retryAtMs + QUOTA_RETRY_INFLIGHT_GRACE_MS < now;
|
|
341
|
+
if (kind !== "no-data" && !retryStopped) return { cue: "refreshing", userMustAct: false };
|
|
342
|
+
const nextCheckAt = backfillCheckAt(quota, now);
|
|
343
|
+
return nextCheckAt === void 0 ? { cue: "stale", userMustAct: false } : { cue: "stale", userMustAct: false, nextCheckAt };
|
|
344
|
+
}
|
|
345
|
+
function minutesUntilQuotaCheck(nextCheckAt, now = Date.now()) {
|
|
346
|
+
return Math.max(1, Math.round((nextCheckAt - now) / 6e4));
|
|
347
|
+
}
|
|
348
|
+
|
|
303
349
|
// src/workspace-normalize.ts
|
|
304
350
|
function normalizeMeshWorkspaceForCompare(dir) {
|
|
305
351
|
if (typeof dir !== "string") return "";
|
|
@@ -329,19 +375,21 @@ function isPhantomDaemonEntry(entry) {
|
|
|
329
375
|
function machineCoreFromDaemonId(id2) {
|
|
330
376
|
const trimmed = readString(id2);
|
|
331
377
|
if (!trimmed) return void 0;
|
|
378
|
+
const lower = trimmed.toLowerCase();
|
|
332
379
|
for (const prefix of DAEMON_ID_PREFIXES) {
|
|
333
|
-
if (
|
|
380
|
+
if (lower.startsWith(prefix)) {
|
|
334
381
|
const core = trimmed.slice(prefix.length).trim();
|
|
335
|
-
|
|
382
|
+
if (!core) return void 0;
|
|
383
|
+
return /^mach_/i.test(core) ? `mach_${core.slice(5)}` : core;
|
|
336
384
|
}
|
|
337
385
|
}
|
|
338
|
-
return trimmed;
|
|
386
|
+
return /^mach_/i.test(trimmed) ? `mach_${trimmed.slice(5)}` : trimmed;
|
|
339
387
|
}
|
|
340
388
|
function canonicalDaemonId(id2) {
|
|
341
389
|
const core = machineCoreFromDaemonId(id2);
|
|
342
390
|
if (!core) return void 0;
|
|
343
|
-
if (
|
|
344
|
-
return `
|
|
391
|
+
if (!/^mach_/i.test(core)) return core;
|
|
392
|
+
return `daemon_mach_${core.slice(5)}`;
|
|
345
393
|
}
|
|
346
394
|
function daemonIdsEquivalent(a, b) {
|
|
347
395
|
const coreA = machineCoreFromDaemonId(a);
|
|
@@ -370,9 +418,9 @@ function expandDaemonIdForms(ids) {
|
|
|
370
418
|
|
|
371
419
|
// src/git-summarize.ts
|
|
372
420
|
function summarizeGitShape(status) {
|
|
373
|
-
const
|
|
374
|
-
if (!Object.keys(
|
|
375
|
-
const submodules = Array.isArray(
|
|
421
|
+
const record2 = readRecord(status);
|
|
422
|
+
if (!Object.keys(record2).length) return null;
|
|
423
|
+
const submodules = Array.isArray(record2.submodules) ? record2.submodules.map((entry) => {
|
|
376
424
|
const sub = readRecord(entry);
|
|
377
425
|
return {
|
|
378
426
|
path: readString(sub.path) ?? null,
|
|
@@ -382,23 +430,23 @@ function summarizeGitShape(status) {
|
|
|
382
430
|
};
|
|
383
431
|
}) : [];
|
|
384
432
|
return {
|
|
385
|
-
isGitRepo: readBoolean(
|
|
386
|
-
workspace: readString(
|
|
387
|
-
repoRoot: readString(
|
|
388
|
-
branch: readString(
|
|
389
|
-
upstream: readString(
|
|
390
|
-
upstreamStatus: readString(
|
|
391
|
-
headCommit: readString(
|
|
392
|
-
ahead: readNumber(
|
|
393
|
-
behind: readNumber(
|
|
433
|
+
isGitRepo: readBoolean(record2.isGitRepo),
|
|
434
|
+
workspace: readString(record2.workspace) ?? null,
|
|
435
|
+
repoRoot: readString(record2.repoRoot, record2.repo_root) ?? null,
|
|
436
|
+
branch: readString(record2.branch) ?? null,
|
|
437
|
+
upstream: readString(record2.upstream) ?? null,
|
|
438
|
+
upstreamStatus: readString(record2.upstreamStatus, record2.upstream_status) ?? null,
|
|
439
|
+
headCommit: readString(record2.headCommit, record2.head_commit)?.slice(0, 12) ?? null,
|
|
440
|
+
ahead: readNumber(record2.ahead) ?? null,
|
|
441
|
+
behind: readNumber(record2.behind) ?? null,
|
|
394
442
|
dirtyCounts: {
|
|
395
|
-
staged: readNumber(
|
|
396
|
-
modified: readNumber(
|
|
397
|
-
untracked: readNumber(
|
|
398
|
-
deleted: readNumber(
|
|
399
|
-
renamed: readNumber(
|
|
443
|
+
staged: readNumber(record2.staged) ?? 0,
|
|
444
|
+
modified: readNumber(record2.modified) ?? 0,
|
|
445
|
+
untracked: readNumber(record2.untracked) ?? 0,
|
|
446
|
+
deleted: readNumber(record2.deleted) ?? 0,
|
|
447
|
+
renamed: readNumber(record2.renamed) ?? 0
|
|
400
448
|
},
|
|
401
|
-
lastCheckedAt: readNumber(
|
|
449
|
+
lastCheckedAt: readNumber(record2.lastCheckedAt, record2.last_checked_at) ?? null,
|
|
402
450
|
submoduleCount: submodules.length,
|
|
403
451
|
submodules
|
|
404
452
|
};
|
|
@@ -564,10 +612,25 @@ var CLI_SLOT_RECIPES = Object.freeze({
|
|
|
564
612
|
],
|
|
565
613
|
"antigravity-cli": [
|
|
566
614
|
{
|
|
567
|
-
model: "Gemini 3.
|
|
615
|
+
model: "Gemini 3.8 Flash (High)",
|
|
616
|
+
modelCandidates: ["Gemini 3.8 Flash (High)", "Gemini 4 Argon (Low)", "Gemini 3.7 Flash (High)", "Gemini 3.1 Pro (High)"],
|
|
568
617
|
difficulty: ["easy"],
|
|
569
618
|
maxParallel: 2,
|
|
570
619
|
rationale: "Cheap capacity for easy tasks."
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
model: "Gemini 4 Argon (Medium)",
|
|
623
|
+
modelCandidates: ["Gemini 4 Argon (Medium)", "Gemini 3.8 Flash (High)", "Gemini 3.7 Flash (High)", "Gemini 3.1 Pro (High)"],
|
|
624
|
+
difficulty: ["medium"],
|
|
625
|
+
maxParallel: 2,
|
|
626
|
+
rationale: "Balanced Argon tier for medium tasks."
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
model: "Gemini 4 Argon (High)",
|
|
630
|
+
modelCandidates: ["Gemini 4 Argon (High)", "Gemini 3.8 Flash (High)", "Gemini 3.1 Pro (High)"],
|
|
631
|
+
difficulty: ["difficult"],
|
|
632
|
+
maxParallel: 1,
|
|
633
|
+
rationale: "Reserved for hard tasks; capped at 1 to bound cost."
|
|
571
634
|
}
|
|
572
635
|
],
|
|
573
636
|
"cursor-cli": [
|
|
@@ -606,6 +669,24 @@ function dedupeDetected(detected) {
|
|
|
606
669
|
}
|
|
607
670
|
return out;
|
|
608
671
|
}
|
|
672
|
+
function resolveRecipeModel(recipe, modelOptions) {
|
|
673
|
+
if (!Array.isArray(modelOptions) || modelOptions.length === 0) {
|
|
674
|
+
return recipe.model;
|
|
675
|
+
}
|
|
676
|
+
const available = new Set(
|
|
677
|
+
modelOptions.filter((m) => typeof m === "string" && m.trim().length > 0).map((m) => m.trim())
|
|
678
|
+
);
|
|
679
|
+
if (available.size === 0) return recipe.model;
|
|
680
|
+
const candidates = [
|
|
681
|
+
...recipe.model ? [recipe.model] : [],
|
|
682
|
+
...recipe.modelCandidates ?? []
|
|
683
|
+
];
|
|
684
|
+
for (const candidate of candidates) {
|
|
685
|
+
const trimmed = typeof candidate === "string" ? candidate.trim() : "";
|
|
686
|
+
if (trimmed && available.has(trimmed)) return trimmed;
|
|
687
|
+
}
|
|
688
|
+
return recipe.model;
|
|
689
|
+
}
|
|
609
690
|
function buildSlotProposal(detected, currentSlots = []) {
|
|
610
691
|
const providers = dedupeDetected(detected ?? []);
|
|
611
692
|
const proposedSlots = [];
|
|
@@ -621,7 +702,7 @@ function buildSlotProposal(detected, currentSlots = []) {
|
|
|
621
702
|
for (const recipe of recipes) {
|
|
622
703
|
const slot = normalizeNodeCapabilitySlot({
|
|
623
704
|
provider: provider.type,
|
|
624
|
-
model: recipe.
|
|
705
|
+
model: resolveRecipeModel(recipe, provider.modelOptions),
|
|
625
706
|
thinkingLevel: recipe.thinkingLevel,
|
|
626
707
|
difficulty: recipe.difficulty,
|
|
627
708
|
maxParallel: recipe.maxParallel
|
|
@@ -674,7 +755,9 @@ var CANONICAL_MESH_TOOL_NAMES = [
|
|
|
674
755
|
"mesh_enqueue_task",
|
|
675
756
|
"mesh_view_queue",
|
|
676
757
|
"mesh_queue_cancel",
|
|
758
|
+
"mesh_direct_cancel",
|
|
677
759
|
"mesh_queue_requeue",
|
|
760
|
+
"mesh_queue_revise",
|
|
678
761
|
"mesh_send_task",
|
|
679
762
|
"mesh_read_chat",
|
|
680
763
|
"mesh_read_debug",
|
|
@@ -691,8 +774,11 @@ var CANONICAL_MESH_TOOL_NAMES = [
|
|
|
691
774
|
"mesh_list_pending_approvals",
|
|
692
775
|
"mesh_create",
|
|
693
776
|
"mesh_add_node",
|
|
777
|
+
"mesh_reattach_source_parent",
|
|
778
|
+
"mesh_attach_remote",
|
|
694
779
|
"mesh_clone_node",
|
|
695
780
|
"mesh_remove_node",
|
|
781
|
+
"mesh_retry_node_bootstrap",
|
|
696
782
|
"mesh_cleanup_worktree_nodes",
|
|
697
783
|
"mesh_refine_node",
|
|
698
784
|
"mesh_refine_batch",
|
|
@@ -709,8 +795,19 @@ var CANONICAL_MESH_TOOL_NAMES = [
|
|
|
709
795
|
"mesh_reconcile_ledger",
|
|
710
796
|
"mesh_mission_upsert",
|
|
711
797
|
"mesh_mission_list",
|
|
798
|
+
"mesh_mission_git_eval",
|
|
799
|
+
"mesh_release_upsert",
|
|
800
|
+
"mesh_release_scope",
|
|
801
|
+
"mesh_release_list",
|
|
802
|
+
"mesh_release_record_deploy",
|
|
803
|
+
"mesh_release_changelog_draft",
|
|
712
804
|
"mesh_review_inbox",
|
|
713
|
-
"mesh_node_slots"
|
|
805
|
+
"mesh_node_slots",
|
|
806
|
+
"driver_list",
|
|
807
|
+
"driver_describe",
|
|
808
|
+
"artifact_list",
|
|
809
|
+
"artifact_read",
|
|
810
|
+
"artifact_register"
|
|
714
811
|
];
|
|
715
812
|
var CANONICAL_MESH_TOOL_COUNT = CANONICAL_MESH_TOOL_NAMES.length;
|
|
716
813
|
var RETIRED_MESH_TOOLS = {
|
|
@@ -1020,9 +1117,15 @@ var DAEMON_STATUS_EVENT_NAMES = [
|
|
|
1020
1117
|
"agent:waiting_choice",
|
|
1021
1118
|
"agent:generating_completed",
|
|
1022
1119
|
"agent:stopped",
|
|
1023
|
-
"monitor:no_progress"
|
|
1120
|
+
"monitor:no_progress",
|
|
1121
|
+
// An owner decision (structured missions) needs the owner. Server-bound for the push only;
|
|
1122
|
+
// the dashboard learns about decisions over P2P (`mission_decisions_list`).
|
|
1123
|
+
"agent:decision_needed"
|
|
1024
1124
|
];
|
|
1025
1125
|
var isDaemonStatusEventName = makeTypeGuard(DAEMON_STATUS_EVENT_NAMES);
|
|
1126
|
+
var DECISION_PUSH_QUESTION_MAX = 80;
|
|
1127
|
+
var DECISION_PUSH_OPTION_LABEL_MAX = 24;
|
|
1128
|
+
var DECISION_PUSH_OPTIONS_MAX = 3;
|
|
1026
1129
|
var RELEASE_CHANNELS = ["stable", "preview"];
|
|
1027
1130
|
var NPM_UPDATE_TAGS = ["latest", "next"];
|
|
1028
1131
|
var VERSION_UPDATE_REASONS = ["force_update_below", "major_minor_mismatch", "patch_mismatch", "daemon_ahead"];
|
|
@@ -1385,21 +1488,22 @@ function isTerminalSessionRecordStatus(raw) {
|
|
|
1385
1488
|
return typeof raw === "string" && TERMINAL_SESSION_RECORD_STATUSES.includes(raw.trim().toLowerCase());
|
|
1386
1489
|
}
|
|
1387
1490
|
function isIdleSessionState(state) {
|
|
1388
|
-
const
|
|
1389
|
-
const status = typeof
|
|
1491
|
+
const record2 = state && typeof state === "object" ? state : {};
|
|
1492
|
+
const status = typeof record2.status === "string" ? record2.status.trim().toLowerCase() : "";
|
|
1390
1493
|
if (isTerminalSessionRecordStatus(status) || isDeadStatus(status)) return false;
|
|
1391
|
-
return isReadyStatus(status) ||
|
|
1494
|
+
return isReadyStatus(status) || record2.activeChat?.status === "waiting_input";
|
|
1392
1495
|
}
|
|
1393
1496
|
|
|
1394
1497
|
// src/mesh-vocabulary.ts
|
|
1395
|
-
var MESH_TASK_STATUSES = ["pending", "assigned", "completed", "failed", "cancelled"];
|
|
1396
|
-
var MESH_TERMINAL_TASK_STATUSES = ["completed", "failed", "cancelled"];
|
|
1498
|
+
var MESH_TASK_STATUSES = ["pending", "assigned", "completed", "blocked", "failed", "cancelled"];
|
|
1499
|
+
var MESH_TERMINAL_TASK_STATUSES = ["completed", "blocked", "failed", "cancelled"];
|
|
1397
1500
|
var MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
1398
1501
|
var MESH_TASK_PRIORITIES = ["low", "normal", "high"];
|
|
1399
1502
|
var MESH_THINKING_LEVELS = ["low", "medium", "high"];
|
|
1400
1503
|
var MESH_DELIVERY_MODES = ["when_idle", "interrupt"];
|
|
1401
1504
|
var MESH_SESSION_CLEANUP_MODES = ["preserve", "stop", "delete_stopped", "stop_and_delete"];
|
|
1402
1505
|
var WORKER_REPORT_OUTCOMES = ["completed", "blocked", "failed"];
|
|
1506
|
+
var WORKER_REPORT_SUMMARY_MAX_CHARS = 8e3;
|
|
1403
1507
|
var WORKER_BRANCH_STATES = [
|
|
1404
1508
|
"merged_to_main",
|
|
1405
1509
|
"pushed_feature_branch_needs_merge",
|
|
@@ -1466,6 +1570,7 @@ var SEND_REFUSAL_REASONS = [
|
|
|
1466
1570
|
"no_target",
|
|
1467
1571
|
"bootstrap_pending",
|
|
1468
1572
|
"duplicate_dispatch",
|
|
1573
|
+
"new_work_held",
|
|
1469
1574
|
"internal_error"
|
|
1470
1575
|
];
|
|
1471
1576
|
function isSendRefusal(value) {
|
|
@@ -1497,6 +1602,14 @@ function isOutboundMessage(value) {
|
|
|
1497
1602
|
const candidate = value;
|
|
1498
1603
|
return isMessageId(candidate.messageId) && typeof candidate.sessionId === "string" && candidate.sessionId.length > 0 && isInputEnvelopeWire(candidate.input) && isOutboundMessageOrigin(candidate.origin) && isSendPolicy(candidate.policy) && typeof candidate.createdAt === "number";
|
|
1499
1604
|
}
|
|
1605
|
+
var PASTED_OPEN_RE = /^\s*<pasted_content(?:\s+id="[^"]*")?\s*>\s*$/;
|
|
1606
|
+
var PASTED_CLOSE_RE = /^\s*<\/pasted_content(?:\s+id="[^"]*")?\s*>\s*$/;
|
|
1607
|
+
function unwrapPastedContent(text) {
|
|
1608
|
+
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
1609
|
+
const first = lines.findIndex((line) => line.trim());
|
|
1610
|
+
if (first < 0 || !PASTED_OPEN_RE.test(lines[first])) return text;
|
|
1611
|
+
return lines.filter((line) => !PASTED_OPEN_RE.test(line) && !PASTED_CLOSE_RE.test(line)).join("\n");
|
|
1612
|
+
}
|
|
1500
1613
|
|
|
1501
1614
|
// src/mission-brief.ts
|
|
1502
1615
|
var GOAL_MAX = 500;
|
|
@@ -1582,7 +1695,22 @@ var WORKER_TOOLS = [
|
|
|
1582
1695
|
"peer_context_pull",
|
|
1583
1696
|
"git_status",
|
|
1584
1697
|
"git_log",
|
|
1585
|
-
"git_diff"
|
|
1698
|
+
"git_diff",
|
|
1699
|
+
"driver_list",
|
|
1700
|
+
"driver_describe",
|
|
1701
|
+
"driver_invoke",
|
|
1702
|
+
"driver_scaffold",
|
|
1703
|
+
"driver_validate",
|
|
1704
|
+
"driver_export",
|
|
1705
|
+
"driver_install",
|
|
1706
|
+
"artifact_register",
|
|
1707
|
+
"artifact_list",
|
|
1708
|
+
"artifact_read",
|
|
1709
|
+
// Contract versioning (Cut A): exact pinned-unit reads (E2), the explicit
|
|
1710
|
+
// read claim (C1) and the authoritative head/notice pull.
|
|
1711
|
+
"contract_read",
|
|
1712
|
+
"contract_observe",
|
|
1713
|
+
"contract_current"
|
|
1586
1714
|
];
|
|
1587
1715
|
var WORKER_TOOL_SET = new Set(WORKER_TOOLS);
|
|
1588
1716
|
function isWorkerTool(value) {
|
|
@@ -1667,15 +1795,29 @@ function renderCoordinatorWorkerSection() {
|
|
|
1667
1795
|
// src/assistant-protocol.ts
|
|
1668
1796
|
var ASSISTANT_TOOLS = [
|
|
1669
1797
|
"projects",
|
|
1798
|
+
"environment",
|
|
1799
|
+
"assistant_action",
|
|
1800
|
+
"project_watch",
|
|
1670
1801
|
"project_status",
|
|
1671
1802
|
"project_send",
|
|
1672
1803
|
"project_read",
|
|
1673
1804
|
"project_add",
|
|
1805
|
+
"project_attach_remote",
|
|
1674
1806
|
"discover_repos",
|
|
1675
1807
|
"memory",
|
|
1808
|
+
"memory_search",
|
|
1676
1809
|
"skill_view",
|
|
1677
1810
|
"skill_manage",
|
|
1678
|
-
"project_note"
|
|
1811
|
+
"project_note",
|
|
1812
|
+
"launch_defaults",
|
|
1813
|
+
"launch_defaults_set",
|
|
1814
|
+
"driver_list",
|
|
1815
|
+
"driver_describe",
|
|
1816
|
+
"artifact_list",
|
|
1817
|
+
"artifact_read",
|
|
1818
|
+
"decision_answer",
|
|
1819
|
+
"decision_request",
|
|
1820
|
+
"session_control"
|
|
1679
1821
|
];
|
|
1680
1822
|
var ASSISTANT_TOOL_SET = new Set(ASSISTANT_TOOLS);
|
|
1681
1823
|
function isAssistantTool(value) {
|
|
@@ -1683,50 +1825,167 @@ function isAssistantTool(value) {
|
|
|
1683
1825
|
}
|
|
1684
1826
|
var ASSISTANT_VERB = {
|
|
1685
1827
|
// tool verbs
|
|
1828
|
+
driverList: "driver_list",
|
|
1829
|
+
driverDescribe: "driver_describe",
|
|
1686
1830
|
projects: "assistant_projects",
|
|
1831
|
+
environment: "assistant_environment",
|
|
1832
|
+
action: "assistant_action",
|
|
1833
|
+
watch: "assistant_project_watch",
|
|
1834
|
+
executionState: "assistant_execution_state",
|
|
1835
|
+
executionSettings: "assistant_execution_settings",
|
|
1687
1836
|
projectStatus: "assistant_project_status",
|
|
1688
1837
|
projectSend: "assistant_project_send",
|
|
1689
1838
|
projectRead: "assistant_project_read",
|
|
1690
1839
|
projectAdd: "assistant_project_add",
|
|
1840
|
+
projectAttachRemote: "assistant_project_attach_remote",
|
|
1691
1841
|
discoverRepos: "assistant_discover_repos",
|
|
1692
1842
|
memory: "assistant_memory",
|
|
1843
|
+
/** Pull-only FTS search over the archive tier (memory design 2026-11-01 §3.4). */
|
|
1844
|
+
memorySearch: "assistant_memory_search",
|
|
1693
1845
|
skillView: "assistant_skill_view",
|
|
1694
1846
|
skillManage: "assistant_skill_manage",
|
|
1695
1847
|
projectNote: "assistant_project_note",
|
|
1848
|
+
launchDefaults: "assistant_launch_defaults",
|
|
1849
|
+
launchDefaultsSet: "assistant_launch_defaults_set",
|
|
1850
|
+
artifactList: "assistant_artifact_list",
|
|
1851
|
+
artifactRead: "assistant_artifact_read",
|
|
1852
|
+
/** Owner-decision inbox (structured-missions design 2026-10-28 §6.3): the owner's words recorded as answers. */
|
|
1853
|
+
decisionAnswer: "assistant_decision_answer",
|
|
1854
|
+
/** Register a plain-text question a coordinator put to the owner as a decision item (§5.2). */
|
|
1855
|
+
decisionRequest: "assistant_decision_request",
|
|
1856
|
+
/** Stop / restart / switch the provider of a coordinator, worker or the assistant session (handoff design 2026-11-01 §4). */
|
|
1857
|
+
sessionControl: "assistant_session_control",
|
|
1696
1858
|
// assistant-side daemon verbs without a tool of the same name
|
|
1697
1859
|
launch: "launch_assistant",
|
|
1698
1860
|
pendingRelays: "assistant_pending_relays",
|
|
1699
1861
|
// owner verbs (dashboard only)
|
|
1700
1862
|
stagedResolve: "assistant_staged_resolve",
|
|
1701
1863
|
storeAdmin: "assistant_store_admin",
|
|
1702
|
-
importSkills: "assistant_import_skills"
|
|
1864
|
+
importSkills: "assistant_import_skills",
|
|
1865
|
+
/** Owner skill list (attach/view counts, save proposals, recent skill metrics); reads move no counter. */
|
|
1866
|
+
skillsList: "assistant_skills_list",
|
|
1867
|
+
/** Owner: what the assistant remembered recently, with undo handles (memory design §3.2). */
|
|
1868
|
+
memoryDigest: "assistant_memory_digest",
|
|
1869
|
+
/** Owner: reverse one remembered write or one batch (memory design §3.2). Never an assistant tool. */
|
|
1870
|
+
memoryUndo: "assistant_memory_undo",
|
|
1871
|
+
/** Projects the assistant is following (open relay threads) — list / stop following. */
|
|
1872
|
+
threads: "assistant_threads",
|
|
1873
|
+
threadClose: "assistant_thread_close"
|
|
1703
1874
|
};
|
|
1704
1875
|
var ASSISTANT_TOOL_VERBS = {
|
|
1876
|
+
driver_list: ASSISTANT_VERB.driverList,
|
|
1877
|
+
driver_describe: ASSISTANT_VERB.driverDescribe,
|
|
1705
1878
|
projects: ASSISTANT_VERB.projects,
|
|
1879
|
+
environment: ASSISTANT_VERB.environment,
|
|
1880
|
+
assistant_action: ASSISTANT_VERB.action,
|
|
1881
|
+
project_watch: ASSISTANT_VERB.watch,
|
|
1706
1882
|
project_status: ASSISTANT_VERB.projectStatus,
|
|
1707
1883
|
project_send: ASSISTANT_VERB.projectSend,
|
|
1708
1884
|
project_read: ASSISTANT_VERB.projectRead,
|
|
1709
1885
|
project_add: ASSISTANT_VERB.projectAdd,
|
|
1886
|
+
project_attach_remote: ASSISTANT_VERB.projectAttachRemote,
|
|
1710
1887
|
discover_repos: ASSISTANT_VERB.discoverRepos,
|
|
1711
1888
|
memory: ASSISTANT_VERB.memory,
|
|
1889
|
+
memory_search: ASSISTANT_VERB.memorySearch,
|
|
1712
1890
|
skill_view: ASSISTANT_VERB.skillView,
|
|
1713
1891
|
skill_manage: ASSISTANT_VERB.skillManage,
|
|
1714
|
-
project_note: ASSISTANT_VERB.projectNote
|
|
1892
|
+
project_note: ASSISTANT_VERB.projectNote,
|
|
1893
|
+
launch_defaults: ASSISTANT_VERB.launchDefaults,
|
|
1894
|
+
launch_defaults_set: ASSISTANT_VERB.launchDefaultsSet,
|
|
1895
|
+
artifact_list: ASSISTANT_VERB.artifactList,
|
|
1896
|
+
artifact_read: ASSISTANT_VERB.artifactRead,
|
|
1897
|
+
decision_answer: ASSISTANT_VERB.decisionAnswer,
|
|
1898
|
+
decision_request: ASSISTANT_VERB.decisionRequest,
|
|
1899
|
+
session_control: ASSISTANT_VERB.sessionControl
|
|
1715
1900
|
};
|
|
1716
|
-
var ASSISTANT_WRITE_TOOLS = ["memory", "skill_manage", "project_note", "project_send", "project_add"];
|
|
1901
|
+
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", "session_control"];
|
|
1717
1902
|
var ASSISTANT_OWNER_VERBS = [
|
|
1903
|
+
ASSISTANT_VERB.executionSettings,
|
|
1718
1904
|
ASSISTANT_VERB.stagedResolve,
|
|
1719
1905
|
ASSISTANT_VERB.storeAdmin,
|
|
1720
|
-
ASSISTANT_VERB.importSkills
|
|
1906
|
+
ASSISTANT_VERB.importSkills,
|
|
1907
|
+
ASSISTANT_VERB.skillsList,
|
|
1908
|
+
ASSISTANT_VERB.memoryDigest,
|
|
1909
|
+
ASSISTANT_VERB.memoryUndo,
|
|
1910
|
+
ASSISTANT_VERB.threadClose
|
|
1721
1911
|
];
|
|
1722
1912
|
var ASSISTANT_REVIEW_TURN_VERBS = [
|
|
1723
1913
|
ASSISTANT_VERB.memory,
|
|
1914
|
+
ASSISTANT_VERB.memorySearch,
|
|
1724
1915
|
ASSISTANT_VERB.skillView,
|
|
1725
1916
|
ASSISTANT_VERB.skillManage,
|
|
1726
1917
|
ASSISTANT_VERB.projectNote
|
|
1727
1918
|
];
|
|
1728
1919
|
var ASSISTANT_SESSION_ID_ENV = "ADHDEV_ASSISTANT_SESSION_ID";
|
|
1729
1920
|
var ASSISTANT_SESSION_ID_ARG = "assistantSessionId";
|
|
1921
|
+
var ASSISTANT_ACCOUNT_SLOT = "personal";
|
|
1922
|
+
var ASSISTANT_REMOTE_PROJECT_COMMAND = "assistant_remote_project";
|
|
1923
|
+
var ASSISTANT_REMOTE_PROJECT_CATALOG_COMMAND = "assistant_remote_project_catalog";
|
|
1924
|
+
var ASSISTANT_REMOTE_PROJECT_ACCESS_COMMAND = "assistant_remote_project_access";
|
|
1925
|
+
var ASSISTANT_REMOTE_FOLLOW_COMMAND = "assistant_remote_follow";
|
|
1926
|
+
var ASSISTANT_FOLLOWER_ALLOWED_OPS = ["status", "read", "poll", "report", "send", "artifact_list", "artifact_read", "decision_list", "decision_answer", "decision_request"];
|
|
1927
|
+
var ASSISTANT_FOLLOWER_ALLOWED_OP_SET = new Set(ASSISTANT_FOLLOWER_ALLOWED_OPS);
|
|
1928
|
+
function isAssistantFollowerAllowedOp(value) {
|
|
1929
|
+
return typeof value === "string" && ASSISTANT_FOLLOWER_ALLOWED_OP_SET.has(value);
|
|
1930
|
+
}
|
|
1931
|
+
var DECISION_OP_IMPLIED_BY = {
|
|
1932
|
+
decision_list: "status",
|
|
1933
|
+
decision_answer: "send",
|
|
1934
|
+
decision_request: "send"
|
|
1935
|
+
};
|
|
1936
|
+
function followerOpPermitted(op, allowedOps) {
|
|
1937
|
+
if (!isAssistantFollowerAllowedOp(op)) return false;
|
|
1938
|
+
if (allowedOps.includes(op)) return true;
|
|
1939
|
+
const implied = DECISION_OP_IMPLIED_BY[op];
|
|
1940
|
+
return implied !== void 0 && allowedOps.includes(implied);
|
|
1941
|
+
}
|
|
1942
|
+
function followedRemoteProjectKey(hostDaemonId, meshId) {
|
|
1943
|
+
const canonHost = canonicalDaemonId(hostDaemonId) ?? hostDaemonId.trim();
|
|
1944
|
+
return `${canonHost}::${meshId.trim()}`;
|
|
1945
|
+
}
|
|
1946
|
+
function sanitizeRemoteRepoIdentity(raw) {
|
|
1947
|
+
if (typeof raw !== "string") return null;
|
|
1948
|
+
const trimmed = raw.trim();
|
|
1949
|
+
if (!trimmed) return null;
|
|
1950
|
+
if (trimmed.startsWith("/") || trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed.startsWith("~/") || trimmed.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(trimmed) || /^file:/i.test(trimmed)) {
|
|
1951
|
+
return null;
|
|
1952
|
+
}
|
|
1953
|
+
const withoutQuery = trimmed.replace(/[?#].*$/, "").replace(/\/+$/, "");
|
|
1954
|
+
if (!withoutQuery) return null;
|
|
1955
|
+
let host = "";
|
|
1956
|
+
let repoPath = "";
|
|
1957
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(withoutQuery)) {
|
|
1958
|
+
try {
|
|
1959
|
+
const url = new URL(withoutQuery);
|
|
1960
|
+
if (url.protocol === "file:") return null;
|
|
1961
|
+
host = url.hostname.toLowerCase();
|
|
1962
|
+
repoPath = decodeURIComponent(url.pathname).replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
1963
|
+
} catch {
|
|
1964
|
+
return null;
|
|
1965
|
+
}
|
|
1966
|
+
} else {
|
|
1967
|
+
const scpMatch = withoutQuery.match(/^(?:[^@/:]+@)?(\[[^\]]+\]|[^/:]+):(.+)$/);
|
|
1968
|
+
if (scpMatch) {
|
|
1969
|
+
host = scpMatch[1].replace(/^\[|\]$/g, "").toLowerCase();
|
|
1970
|
+
repoPath = scpMatch[2].replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
1971
|
+
} else {
|
|
1972
|
+
const slash = withoutQuery.indexOf("/");
|
|
1973
|
+
if (slash > 0) {
|
|
1974
|
+
const rawHost = withoutQuery.slice(0, slash);
|
|
1975
|
+
const atIdx = rawHost.lastIndexOf("@");
|
|
1976
|
+
host = (atIdx >= 0 ? rawHost.slice(atIdx + 1) : rawHost).toLowerCase();
|
|
1977
|
+
repoPath = withoutQuery.slice(slash + 1).replace(/^\/+|\/+$/g, "").replace(/\.git$/i, "");
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
if (!host || !repoPath) return null;
|
|
1982
|
+
if (!host.includes(".") && host !== "localhost") return null;
|
|
1983
|
+
if (/[\s@:\\]/.test(host)) return null;
|
|
1984
|
+
const segments = repoPath.split("/").filter(Boolean);
|
|
1985
|
+
if (segments.length === 0) return null;
|
|
1986
|
+
if (segments.some((seg) => seg === "." || seg === ".." || /[\s@:\\]/.test(seg))) return null;
|
|
1987
|
+
return `${host}/${segments.join("/")}`.slice(0, 200);
|
|
1988
|
+
}
|
|
1730
1989
|
|
|
1731
1990
|
// src/turn-evidence.ts
|
|
1732
1991
|
var MESH_TOPIC_PROTOCOL_VERSION = 2;
|
|
@@ -1762,7 +2021,7 @@ var TURN_SCOPES = ["mesh_queue", "mesh_direct", "plain"];
|
|
|
1762
2021
|
var RECLAIMING_SEND_REFUSALS = ["session_exited", "no_target", "unsupported_input"];
|
|
1763
2022
|
var DELIVERY_OUTCOMES = ["delivered", "queued"];
|
|
1764
2023
|
var DELIVERY_VIAS = ["local", "p2p"];
|
|
1765
|
-
var DISPATCH_FAILURE_REASONS = ["worker_absent", "transport_error", "spawn_failed", "rejected_by_worker", "timeout"];
|
|
2024
|
+
var DISPATCH_FAILURE_REASONS = ["worker_absent", "transport_error", "spawn_failed", "rejected_by_worker", "timeout", "submit_unconfirmed"];
|
|
1766
2025
|
function sanitizeRefusalCode(value) {
|
|
1767
2026
|
if (typeof value !== "string") return void 0;
|
|
1768
2027
|
const normalized = value.trim().toLowerCase().replace(/[^a-z_]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
@@ -1772,8 +2031,8 @@ function sanitizeRefusalCode(value) {
|
|
|
1772
2031
|
var CONSUME_PROFILES = ["default", "native_source"];
|
|
1773
2032
|
var SESSION_REBOUND_REASONS = ["restart", "live_holder"];
|
|
1774
2033
|
var SUSPENSION_MODALS = ["approval", "choice"];
|
|
1775
|
-
var SUSPENSION_RESOLUTIONS = ["approved", "rejected", "answered"];
|
|
1776
|
-
var SUSPENSION_RESOLUTION_VIAS = ["modal_button", "auto_approve", "prompt_answer"];
|
|
2034
|
+
var SUSPENSION_RESOLUTIONS = ["approved", "rejected", "answered", "dismissed"];
|
|
2035
|
+
var SUSPENSION_RESOLUTION_VIAS = ["modal_button", "auto_approve", "prompt_answer", "modal_disappeared"];
|
|
1777
2036
|
var TURN_END_STRENGTHS = ["genuine", "weak"];
|
|
1778
2037
|
var TURN_END_BLOCK_REASONS = [
|
|
1779
2038
|
"missing_final_assistant",
|
|
@@ -1781,9 +2040,9 @@ var TURN_END_BLOCK_REASONS = [
|
|
|
1781
2040
|
"terminal_block_hard_cap",
|
|
1782
2041
|
"decoupled_completion"
|
|
1783
2042
|
];
|
|
1784
|
-
var NATIVE_TURN_OUTCOMES = ["completed", "aborted"];
|
|
2043
|
+
var NATIVE_TURN_OUTCOMES = ["completed", "aborted", "failed"];
|
|
1785
2044
|
var LIVENESS_RESULTS = ["alive", "unknown", "read_failed", "dead"];
|
|
1786
|
-
var PROVIDER_FAILURES = ["auth_failed", "billing_failed"];
|
|
2045
|
+
var PROVIDER_FAILURES = ["auth_failed", "billing_failed", "usage_limit_exceeded", "server_overloaded", "provider_error"];
|
|
1787
2046
|
var SESSION_ERROR_REASONS = ["provider_error", "adapter_error", "spawn_failed", "auth_failed", "billing_failed", "unknown", "daemon_restart"];
|
|
1788
2047
|
var CANCEL_REASONS = ["operator_cancel", "intentional_cleanup", "task_removed", "mission_abandoned", "superseded"];
|
|
1789
2048
|
var OPERATOR_STATUSES = ["completed", "failed"];
|
|
@@ -1810,9 +2069,10 @@ var HOLD_REASONS = [
|
|
|
1810
2069
|
// — a turn_end commits the report (R9t), expiry commits it anyway (R13t) so
|
|
1811
2070
|
// a session whose FSM never shows the idle edge again does not wait for
|
|
1812
2071
|
// liveness / hard_ceiling.
|
|
1813
|
-
"await_end"
|
|
2072
|
+
"await_end",
|
|
2073
|
+
"report_correction"
|
|
1814
2074
|
];
|
|
1815
|
-
var TURN_OUTCOMES = ["completed", "failed", "cancelled"];
|
|
2075
|
+
var TURN_OUTCOMES = ["completed", "blocked", "failed", "cancelled"];
|
|
1816
2076
|
var COMMIT_STRENGTHS = ["genuine", "weak", "tool_report", "operator"];
|
|
1817
2077
|
var TURN_REASONS = [
|
|
1818
2078
|
// commits
|
|
@@ -1821,9 +2081,15 @@ var TURN_REASONS = [
|
|
|
1821
2081
|
"transcript_final",
|
|
1822
2082
|
"worker_reported",
|
|
1823
2083
|
"finalization_timeout_no_response",
|
|
2084
|
+
"weak_end_liveness_unconfirmed",
|
|
2085
|
+
"weak_end_probe_unobserved",
|
|
2086
|
+
"report_correction_expired",
|
|
1824
2087
|
"session_error",
|
|
1825
2088
|
"provider_auth_failed",
|
|
1826
2089
|
"provider_billing_failed",
|
|
2090
|
+
"provider_usage_limit_exceeded",
|
|
2091
|
+
"provider_server_overloaded",
|
|
2092
|
+
"provider_error",
|
|
1827
2093
|
"operator_cancel",
|
|
1828
2094
|
"intentional_cleanup",
|
|
1829
2095
|
"task_removed",
|
|
@@ -1851,6 +2117,7 @@ var TURN_REASONS = [
|
|
|
1851
2117
|
];
|
|
1852
2118
|
var NOTIFY_KINDS = [
|
|
1853
2119
|
"completed",
|
|
2120
|
+
"blocked",
|
|
1854
2121
|
"failed",
|
|
1855
2122
|
"cancelled",
|
|
1856
2123
|
"stopped",
|
|
@@ -1900,8 +2167,8 @@ var TURN_EVIDENCE_FIELD_SPECS = {
|
|
|
1900
2167
|
duplicate_dispatch_refusal: { holderSessionId: id, holderAttemptId: idOpt },
|
|
1901
2168
|
session_rebound: { toSessionId: id, reason: en(SESSION_REBOUND_REASONS) },
|
|
1902
2169
|
turn_started: { retro: bool },
|
|
1903
|
-
suspension: { modal: en(SUSPENSION_MODALS), modalKey: idOpt },
|
|
1904
|
-
suspension_resolved: { resolution: en(SUSPENSION_RESOLUTIONS), via: en(SUSPENSION_RESOLUTION_VIAS) },
|
|
2170
|
+
suspension: { modal: en(SUSPENSION_MODALS), modalKey: idOpt, providerSetup: boolOpt, clockUnknown: boolOpt },
|
|
2171
|
+
suspension_resolved: { resolution: en(SUSPENSION_RESOLUTIONS), via: en(SUSPENSION_RESOLUTION_VIAS), modalKey: idOpt },
|
|
1905
2172
|
turn_end: {
|
|
1906
2173
|
strength: en(TURN_END_STRENGTHS),
|
|
1907
2174
|
afterFinalizationTimeout: boolOpt,
|
|
@@ -1911,6 +2178,7 @@ var TURN_EVIDENCE_FIELD_SPECS = {
|
|
|
1911
2178
|
releasedByHardCap: boolOpt,
|
|
1912
2179
|
nativeOutcome: enOpt(NATIVE_TURN_OUTCOMES),
|
|
1913
2180
|
live: { t: "live", optional: true },
|
|
2181
|
+
nativeMarker: { t: "native_marker", optional: true },
|
|
1914
2182
|
reportExpected: boolOpt,
|
|
1915
2183
|
providerFailure: enOpt(PROVIDER_FAILURES)
|
|
1916
2184
|
},
|
|
@@ -1924,7 +2192,7 @@ var TURN_EVIDENCE_FIELD_SPECS = {
|
|
|
1924
2192
|
},
|
|
1925
2193
|
transcript_activity: { newestActivityAt: ms },
|
|
1926
2194
|
no_progress: { stalledMs: ms, observedStatus: en(NO_PROGRESS_OBSERVED_STATUSES), finalAssistantPresent: bool },
|
|
1927
|
-
liveness: { result: en(LIVENESS_RESULTS) },
|
|
2195
|
+
liveness: { result: en(LIVENESS_RESULTS), probeStartedAtMs: msOpt },
|
|
1928
2196
|
process_exit: { exitCode: { t: "int", nullable: true }, providerFailure: enOpt(PROVIDER_FAILURES) },
|
|
1929
2197
|
session_error: { reason: en(SESSION_ERROR_REASONS) },
|
|
1930
2198
|
worker_report: {
|
|
@@ -1934,6 +2202,7 @@ var TURN_EVIDENCE_FIELD_SPECS = {
|
|
|
1934
2202
|
branchState: enOpt(WORKER_BRANCH_STATES),
|
|
1935
2203
|
touchedFileCount: intOpt
|
|
1936
2204
|
},
|
|
2205
|
+
worker_report_correction_requested: { deliveryId: { t: "id", optional: true } },
|
|
1937
2206
|
worker_progress: { note: { t: "summary_ref", optional: true } },
|
|
1938
2207
|
git_side_effect: { dirty: bool, commitsSinceDispatch: { t: "int" }, attributable: bool },
|
|
1939
2208
|
cancel: { reason: en(CANCEL_REASONS) },
|
|
@@ -1981,7 +2250,7 @@ function isLiveTurnPending(value) {
|
|
|
1981
2250
|
return isRecord2(value) && hasOnlyKeys(value, ["modal", "adapterPending", "trailingTool", "newestActivityAt"]) && typeof value.modal === "boolean" && typeof value.adapterPending === "boolean" && typeof value.trailingTool === "boolean" && (value.newestActivityAt === void 0 || isFiniteNumber2(value.newestActivityAt));
|
|
1982
2251
|
}
|
|
1983
2252
|
function isNativeMarkerRef(value) {
|
|
1984
|
-
return isRecord2(value) && hasOnlyKeys(value, ["outcome", "turnId"]) && NATIVE_TURN_OUTCOMES.includes(value.outcome) && (value.turnId === void 0 || isEvidenceIdentifier(value.turnId));
|
|
2253
|
+
return isRecord2(value) && hasOnlyKeys(value, ["outcome", "turnId", "receivedAt", "startedAt", "errorAt"]) && NATIVE_TURN_OUTCOMES.includes(value.outcome) && (value.turnId === void 0 || isEvidenceIdentifier(value.turnId)) && ["receivedAt", "startedAt", "errorAt"].every((key) => value[key] === void 0 || isFiniteNumber2(value[key]));
|
|
1985
2254
|
}
|
|
1986
2255
|
function isCoordinatorIdentity(value) {
|
|
1987
2256
|
return isRecord2(value) && hasOnlyKeys(value, ["daemonId", "coordinatorRunId", "sessionId"]) && isEvidenceIdentifier(value.daemonId) && isEvidenceIdentifier(value.coordinatorRunId) && (value.sessionId === void 0 || isEvidenceIdentifier(value.sessionId));
|
|
@@ -2104,17 +2373,89 @@ function projectTurnEvidenceEntry(evidence, attempt) {
|
|
|
2104
2373
|
};
|
|
2105
2374
|
}
|
|
2106
2375
|
|
|
2376
|
+
// src/launch-defaults.ts
|
|
2377
|
+
var LAUNCH_DEFAULT_ROLES = ["assistant", "coordinator"];
|
|
2378
|
+
var LAUNCH_DEFAULT_SOURCES = ["user", "stored_default", "project_default", "provider_default"];
|
|
2379
|
+
var LAUNCH_DEFAULTS_NEXT_LAUNCH_NOTE = "Applies to the next launch; running sessions are unchanged.";
|
|
2380
|
+
function isLaunchDefaultRole(value) {
|
|
2381
|
+
return typeof value === "string" && LAUNCH_DEFAULT_ROLES.includes(value);
|
|
2382
|
+
}
|
|
2383
|
+
function isLaunchDefaultSource(value) {
|
|
2384
|
+
return typeof value === "string" && LAUNCH_DEFAULT_SOURCES.includes(value);
|
|
2385
|
+
}
|
|
2386
|
+
var LAUNCH_DEFAULT_ERROR_CODES = [
|
|
2387
|
+
"invalid_args",
|
|
2388
|
+
"launch_default_required",
|
|
2389
|
+
"launch_default_unavailable",
|
|
2390
|
+
"launch_selection_invalid",
|
|
2391
|
+
"launch_default_invalid",
|
|
2392
|
+
"revision_conflict",
|
|
2393
|
+
"store_unavailable",
|
|
2394
|
+
"store_busy",
|
|
2395
|
+
"persistence_failed",
|
|
2396
|
+
"project_not_found",
|
|
2397
|
+
"project_ambiguous",
|
|
2398
|
+
"project_not_hosted",
|
|
2399
|
+
"project_storage_unavailable",
|
|
2400
|
+
"staging_unavailable",
|
|
2401
|
+
"staging_failed",
|
|
2402
|
+
"review_turn_tool_denied"
|
|
2403
|
+
];
|
|
2404
|
+
|
|
2405
|
+
// src/role-launch.ts
|
|
2406
|
+
function record(value) {
|
|
2407
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2408
|
+
}
|
|
2409
|
+
function ref(value) {
|
|
2410
|
+
const r = record(value);
|
|
2411
|
+
if (!r || !isLaunchDefaultRole(r.role) || r.scope !== "global" && r.scope !== "project" || !Number.isSafeInteger(r.revision) || r.revision < 1 || r.scope === "project" && (typeof r.projectId !== "string" || !r.projectId)) return void 0;
|
|
2412
|
+
return {
|
|
2413
|
+
role: r.role,
|
|
2414
|
+
scope: r.scope,
|
|
2415
|
+
revision: r.revision,
|
|
2416
|
+
...r.scope === "project" ? { projectId: r.projectId } : {}
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
function axis(value) {
|
|
2420
|
+
const a = record(value);
|
|
2421
|
+
if (!a || !isLaunchDefaultSource(a.source) || a.value !== null && typeof a.value !== "string") return void 0;
|
|
2422
|
+
const defaultRef = ref(a.defaultRef);
|
|
2423
|
+
if (a.source === "stored_default" && defaultRef?.scope !== "global" || a.source === "project_default" && defaultRef?.scope !== "project" || (a.source === "user" || a.source === "provider_default") && a.defaultRef !== void 0) return void 0;
|
|
2424
|
+
return { value: a.value, source: a.source, ...defaultRef ? { defaultRef } : {} };
|
|
2425
|
+
}
|
|
2426
|
+
function parseRoleLaunchSelection(value) {
|
|
2427
|
+
const r = record(value), s = record(r?.selection), a = record(r?.applied);
|
|
2428
|
+
if (!r || !isLaunchDefaultRole(r.role) || !s || typeof s.provider !== "string" || !s.provider || !Number.isSafeInteger(r.documentRevision) || r.documentRevision < 1 || s.model !== void 0 && typeof s.model !== "string" || s.thinkingLevel !== void 0 && typeof s.thinkingLevel !== "string") return void 0;
|
|
2429
|
+
const provider = axis(a?.provider), model = axis(a?.model), thinkingLevel = axis(a?.thinkingLevel);
|
|
2430
|
+
if (!provider || !model || !thinkingLevel || [provider, model, thinkingLevel].some((axis2) => axis2.defaultRef && (axis2.defaultRef.role !== r.role || axis2.defaultRef.scope === "global" && axis2.defaultRef.revision > r.documentRevision)) || provider.value !== s.provider || model.value !== (s.model ?? null) || thinkingLevel.value !== (s.thinkingLevel ?? null)) return void 0;
|
|
2431
|
+
const defaultRef = ref(r.defaultRef);
|
|
2432
|
+
return {
|
|
2433
|
+
role: r.role,
|
|
2434
|
+
selection: {
|
|
2435
|
+
provider: s.provider,
|
|
2436
|
+
...typeof s.model === "string" ? { model: s.model } : {},
|
|
2437
|
+
...typeof s.thinkingLevel === "string" ? { thinkingLevel: s.thinkingLevel } : {}
|
|
2438
|
+
},
|
|
2439
|
+
applied: { provider, model, thinkingLevel },
|
|
2440
|
+
...defaultRef ? { defaultRef } : {},
|
|
2441
|
+
documentRevision: r.documentRevision
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2107
2445
|
// src/session-launch.ts
|
|
2108
2446
|
var MODEL_AXIS_SOURCES = [
|
|
2109
2447
|
/** Picked explicitly for this launch (dashboard dropdown, coordinator dialog). */
|
|
2110
2448
|
"user",
|
|
2111
2449
|
/** The dashboard dialog restored it from the last launch (browser-local memory). */
|
|
2112
2450
|
"remembered",
|
|
2451
|
+
/** The authoritative daemon role default or host project override. */
|
|
2452
|
+
"stored_default",
|
|
2453
|
+
"project_default",
|
|
2113
2454
|
/** A mesh capability slot supplied it (or a difficulty preset the slot outranked). */
|
|
2114
2455
|
"mesh_slot",
|
|
2115
2456
|
/** An explicit per-task model / thinking level on a mesh queue task. */
|
|
2116
2457
|
"task_override",
|
|
2117
|
-
/** Nothing
|
|
2458
|
+
/** Nothing requested: the provider chooses; resolvedDefault records it when known. */
|
|
2118
2459
|
"provider_default",
|
|
2119
2460
|
/** A value was requested without saying where it came from, or nothing is known. */
|
|
2120
2461
|
"unspecified"
|
|
@@ -2158,10 +2499,10 @@ function readFiniteNumber(value) {
|
|
|
2158
2499
|
}
|
|
2159
2500
|
function parseModelSelection(raw) {
|
|
2160
2501
|
if (!raw || typeof raw !== "object") return void 0;
|
|
2161
|
-
const
|
|
2502
|
+
const record2 = raw;
|
|
2162
2503
|
const history = [];
|
|
2163
|
-
if (Array.isArray(
|
|
2164
|
-
for (const entry of
|
|
2504
|
+
if (Array.isArray(record2.history)) {
|
|
2505
|
+
for (const entry of record2.history) {
|
|
2165
2506
|
if (!entry || typeof entry !== "object") continue;
|
|
2166
2507
|
const e = entry;
|
|
2167
2508
|
const value = readString(e.value);
|
|
@@ -2170,41 +2511,45 @@ function parseModelSelection(raw) {
|
|
|
2170
2511
|
if (value && at !== void 0 && via) history.push({ at, value, via });
|
|
2171
2512
|
}
|
|
2172
2513
|
}
|
|
2173
|
-
const requested = readString(
|
|
2174
|
-
const launchValue = readString(
|
|
2175
|
-
const resolvedDefault = readString(
|
|
2176
|
-
const current = readString(
|
|
2177
|
-
const observed = readString(
|
|
2178
|
-
const observedAt = readFiniteNumber(
|
|
2514
|
+
const requested = readString(record2.requested);
|
|
2515
|
+
const launchValue = readString(record2.launchValue);
|
|
2516
|
+
const resolvedDefault = readString(record2.resolvedDefault);
|
|
2517
|
+
const current = readString(record2.current);
|
|
2518
|
+
const observed = readString(record2.observed);
|
|
2519
|
+
const observedAt = readFiniteNumber(record2.observedAt);
|
|
2520
|
+
const fallback = record2.fallback === true;
|
|
2179
2521
|
return {
|
|
2180
|
-
source: isModelAxisSource(
|
|
2522
|
+
source: isModelAxisSource(record2.source) ? record2.source : "unspecified",
|
|
2181
2523
|
...requested ? { requested } : {},
|
|
2182
2524
|
...launchValue ? { launchValue } : {},
|
|
2183
2525
|
...resolvedDefault ? { resolvedDefault } : {},
|
|
2184
2526
|
...current ? { current } : {},
|
|
2185
2527
|
...observed ? { observed } : {},
|
|
2186
2528
|
...observedAt !== void 0 ? { observedAt } : {},
|
|
2529
|
+
...fallback ? { fallback } : {},
|
|
2187
2530
|
history: history.slice(-MODEL_SELECTION_HISTORY_LIMIT)
|
|
2188
2531
|
};
|
|
2189
2532
|
}
|
|
2190
2533
|
function parseSessionLaunchRecord(raw) {
|
|
2191
2534
|
if (!raw || typeof raw !== "object") return void 0;
|
|
2192
|
-
const
|
|
2193
|
-
const sessionId = readString(
|
|
2194
|
-
const providerType = readString(
|
|
2195
|
-
const launchedAt = readFiniteNumber(
|
|
2196
|
-
const model = parseModelSelection(
|
|
2197
|
-
const thinkingLevel = parseModelSelection(
|
|
2535
|
+
const record2 = raw;
|
|
2536
|
+
const sessionId = readString(record2.sessionId);
|
|
2537
|
+
const providerType = readString(record2.providerType);
|
|
2538
|
+
const launchedAt = readFiniteNumber(record2.launchedAt);
|
|
2539
|
+
const model = parseModelSelection(record2.model);
|
|
2540
|
+
const thinkingLevel = parseModelSelection(record2.thinkingLevel);
|
|
2198
2541
|
if (!sessionId || !providerType || launchedAt === void 0 || !model || !thinkingLevel) return void 0;
|
|
2199
|
-
const providerVersion = readString(
|
|
2200
|
-
const workspace = readString(
|
|
2201
|
-
const autoApproveModeId = readString(
|
|
2542
|
+
const providerVersion = readString(record2.providerVersion);
|
|
2543
|
+
const workspace = readString(record2.workspace);
|
|
2544
|
+
const autoApproveModeId = readString(record2.autoApproveModeId);
|
|
2545
|
+
const roleLaunch = parseRoleLaunchSelection(record2.roleLaunch);
|
|
2202
2546
|
return {
|
|
2547
|
+
...roleLaunch ? { roleLaunch } : {},
|
|
2203
2548
|
sessionId,
|
|
2204
2549
|
providerType,
|
|
2205
2550
|
...providerVersion ? { providerVersion } : {},
|
|
2206
|
-
...
|
|
2207
|
-
launchedBy: isSessionLaunchedBy(
|
|
2551
|
+
...record2.providerChannel === "stable" || record2.providerChannel === "preview" ? { providerChannel: record2.providerChannel } : {},
|
|
2552
|
+
launchedBy: isSessionLaunchedBy(record2.launchedBy) ? record2.launchedBy : "api",
|
|
2208
2553
|
launchedAt,
|
|
2209
2554
|
...workspace ? { workspace } : {},
|
|
2210
2555
|
model,
|
|
@@ -2268,7 +2613,7 @@ function isTurnAttemptRefValue(value) {
|
|
|
2268
2613
|
function isTurnObserveResponse(value) {
|
|
2269
2614
|
return isRecord(value) && hasOnlyKeys2(value, ["verdict", "attemptRef", "outcome"]) && isTurnObserveVerdict(value.verdict) && isTurnAttemptRefValue(value.attemptRef) && (value.outcome === void 0 || isTurnOutcomeValue(value.outcome));
|
|
2270
2615
|
}
|
|
2271
|
-
var TURN_OUTCOMES_LOCAL = ["completed", "failed", "cancelled"];
|
|
2616
|
+
var TURN_OUTCOMES_LOCAL = ["completed", "blocked", "failed", "cancelled"];
|
|
2272
2617
|
function isTurnOutcomeValue(value) {
|
|
2273
2618
|
return typeof value === "string" && TURN_OUTCOMES_LOCAL.includes(value);
|
|
2274
2619
|
}
|
|
@@ -2494,8 +2839,23 @@ function isMissionBriefWire(value) {
|
|
|
2494
2839
|
}
|
|
2495
2840
|
return true;
|
|
2496
2841
|
}
|
|
2842
|
+
var STRUCTURED_MISSION_KEYS = ["summary", "releaseNote", "outcome", "outcomeReason", "version", "carryOver", "openItems"];
|
|
2843
|
+
function isOpenItemCountsWire(value) {
|
|
2844
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["remaining", "live_check", "decision", "evidence"])) return false;
|
|
2845
|
+
return ["remaining", "live_check", "decision", "evidence"].every((k) => isNonNegativeInt(value[k]));
|
|
2846
|
+
}
|
|
2847
|
+
function isStructuredMissionFields(value) {
|
|
2848
|
+
for (const k of ["summary", "releaseNote", "outcome", "outcomeReason"]) {
|
|
2849
|
+
if (value[k] !== void 0 && typeof value[k] !== "string") return false;
|
|
2850
|
+
}
|
|
2851
|
+
if (value.version !== void 0 && !isNonNegativeInt(value.version)) return false;
|
|
2852
|
+
if (value.carryOver !== void 0 && typeof value.carryOver !== "boolean") return false;
|
|
2853
|
+
if (value.openItems !== void 0 && !isOpenItemCountsWire(value.openItems)) return false;
|
|
2854
|
+
return true;
|
|
2855
|
+
}
|
|
2497
2856
|
function isMeshMissionRecordWire(value) {
|
|
2498
|
-
if (!isRecord(value) || !hasOnlyKeys2(value, ["id", "meshId", "title", "goal", "status", "brief"])) return false;
|
|
2857
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["id", "meshId", "title", "goal", "status", "brief", ...STRUCTURED_MISSION_KEYS])) return false;
|
|
2858
|
+
if (!isStructuredMissionFields(value)) return false;
|
|
2499
2859
|
if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false;
|
|
2500
2860
|
if (typeof value.title !== "string" || typeof value.goal !== "string") return false;
|
|
2501
2861
|
if (!isMeshMissionStatusValue(value.status)) return false;
|
|
@@ -2503,11 +2863,22 @@ function isMeshMissionRecordWire(value) {
|
|
|
2503
2863
|
return true;
|
|
2504
2864
|
}
|
|
2505
2865
|
function isMissionUpsertRequest(value) {
|
|
2506
|
-
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "id", "title", "goal", "status", "brief"])) return false;
|
|
2866
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "id", "title", "goal", "status", "brief", "structured", "summary", "releaseNote", "outcome", "outcomeReason", "carryOverTo", "toCarryOver", "itemsAdd", "itemsUpdate"])) return false;
|
|
2507
2867
|
if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false;
|
|
2508
2868
|
if (!isEvidenceIdentifier(value.meshId)) return false;
|
|
2509
2869
|
if (value.id !== void 0 && !isEvidenceIdentifier(value.id)) return false;
|
|
2510
|
-
if (typeof value.title !== "string"
|
|
2870
|
+
if (typeof value.title !== "string") return false;
|
|
2871
|
+
if (value.title.trim().length === 0 && value.toCarryOver !== true && value.id === void 0) return false;
|
|
2872
|
+
if (value.structured !== void 0 && typeof value.structured !== "boolean") return false;
|
|
2873
|
+
if (value.toCarryOver !== void 0 && typeof value.toCarryOver !== "boolean") return false;
|
|
2874
|
+
for (const k of ["summary", "releaseNote", "outcome", "outcomeReason"]) {
|
|
2875
|
+
if (value[k] !== void 0 && typeof value[k] !== "string") return false;
|
|
2876
|
+
}
|
|
2877
|
+
if (value.carryOverTo !== void 0 && !isEvidenceIdentifier(value.carryOverTo)) return false;
|
|
2878
|
+
for (const k of ["itemsAdd", "itemsUpdate"]) {
|
|
2879
|
+
const list = value[k];
|
|
2880
|
+
if (list !== void 0 && (!Array.isArray(list) || list.length > 500 || !list.every(isRecord))) return false;
|
|
2881
|
+
}
|
|
2511
2882
|
if (value.goal !== void 0 && typeof value.goal !== "string") return false;
|
|
2512
2883
|
if (value.status !== void 0 && !isMeshMissionStatusValue(value.status)) return false;
|
|
2513
2884
|
if (value.brief !== void 0 && value.brief !== null && !isMissionBriefWire(value.brief)) return false;
|
|
@@ -2517,7 +2888,7 @@ function decodeMissionUpsertRequest(value) {
|
|
|
2517
2888
|
return isMissionUpsertRequest(value) ? value : null;
|
|
2518
2889
|
}
|
|
2519
2890
|
function isMissionUpsertResponse(value) {
|
|
2520
|
-
return isRecord(value) && hasOnlyKeys2(value, ["mission"]) && isMeshMissionRecordWire(value.mission);
|
|
2891
|
+
return isRecord(value) && hasOnlyKeys2(value, ["mission", "result"]) && isMeshMissionRecordWire(value.mission) && (value.result === void 0 || isRecord(value.result));
|
|
2521
2892
|
}
|
|
2522
2893
|
function decodeMissionUpsertResponse(value) {
|
|
2523
2894
|
return isMissionUpsertResponse(value) ? value : null;
|
|
@@ -2543,7 +2914,10 @@ function decodeMissionQueryResponse(value) {
|
|
|
2543
2914
|
return isMissionQueryResponse(value) ? value : null;
|
|
2544
2915
|
}
|
|
2545
2916
|
function isMissionListQueryRequest(value) {
|
|
2546
|
-
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "statuses", "verbose", "withStats", "limit", "historyIdLimit", "meshStatusView"])) return false;
|
|
2917
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "statuses", "verbose", "withStats", "limit", "historyIdLimit", "meshStatusView", "structured", "items", "history"])) return false;
|
|
2918
|
+
for (const k of ["structured", "items", "history"]) {
|
|
2919
|
+
if (value[k] !== void 0 && typeof value[k] !== "boolean") return false;
|
|
2920
|
+
}
|
|
2547
2921
|
if (value.meshStatusView !== void 0 && value.meshStatusView !== "compact" && value.meshStatusView !== "verbose") return false;
|
|
2548
2922
|
if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false;
|
|
2549
2923
|
if (!isEvidenceIdentifier(value.meshId)) return false;
|
|
@@ -2569,12 +2943,13 @@ function isMeshMissionTaskAggregateWire(value) {
|
|
|
2569
2943
|
return value.lastActivityAt === null || typeof value.lastActivityAt === "string";
|
|
2570
2944
|
}
|
|
2571
2945
|
function isMeshMissionStatsWire(value) {
|
|
2572
|
-
const keys = ["missionId", "taskCount", "completed", "failed", "totalDurationMs", "wallClockMs", "retries", "incompleteTaskIds"];
|
|
2946
|
+
const keys = ["missionId", "taskCount", "completed", "failed", "blocked", "totalDurationMs", "wallClockMs", "retries", "incompleteTaskIds"];
|
|
2573
2947
|
if (!isRecord(value) || !hasOnlyKeys2(value, keys)) return false;
|
|
2574
2948
|
if (!isEvidenceIdentifier(value.missionId)) return false;
|
|
2575
2949
|
for (const k of ["taskCount", "completed", "failed", "totalDurationMs", "retries"]) {
|
|
2576
2950
|
if (!isNonNegativeInt(value[k])) return false;
|
|
2577
2951
|
}
|
|
2952
|
+
if (value.blocked !== void 0 && !isNonNegativeInt(value.blocked)) return false;
|
|
2578
2953
|
if (value.wallClockMs !== null && !isNonNegativeInt(value.wallClockMs)) return false;
|
|
2579
2954
|
if (!Array.isArray(value.incompleteTaskIds) || !value.incompleteTaskIds.every(isEvidenceIdentifier)) return false;
|
|
2580
2955
|
return true;
|
|
@@ -2584,7 +2959,7 @@ function isMissionListSummaryWire(value) {
|
|
|
2584
2959
|
const hasGoal = "goal" in value;
|
|
2585
2960
|
const hasPreview = "goalPreview" in value && "goalTruncated" in value;
|
|
2586
2961
|
if (hasGoal === hasPreview) return false;
|
|
2587
|
-
const baseKeys = ["id", "meshId", "title", "status", "tasks", "stats", "brief", "createdAt", "updatedAt", "closeCandidateEmittedAt"];
|
|
2962
|
+
const baseKeys = ["id", "meshId", "title", "status", "tasks", "stats", "brief", "createdAt", "updatedAt", "closeCandidateEmittedAt", ...STRUCTURED_MISSION_KEYS, "items", "history"];
|
|
2588
2963
|
const allowed = hasGoal ? [...baseKeys, "goal"] : [...baseKeys, "goalPreview", "goalTruncated"];
|
|
2589
2964
|
if (!hasOnlyKeys2(value, allowed)) return false;
|
|
2590
2965
|
if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false;
|
|
@@ -2598,6 +2973,10 @@ function isMissionListSummaryWire(value) {
|
|
|
2598
2973
|
if (value.createdAt !== void 0 && typeof value.createdAt !== "string") return false;
|
|
2599
2974
|
if (value.updatedAt !== void 0 && typeof value.updatedAt !== "string") return false;
|
|
2600
2975
|
if (value.closeCandidateEmittedAt !== void 0 && value.closeCandidateEmittedAt !== null && typeof value.closeCandidateEmittedAt !== "string") return false;
|
|
2976
|
+
if (!isStructuredMissionFields(value)) return false;
|
|
2977
|
+
for (const k of ["items", "history"]) {
|
|
2978
|
+
if (value[k] !== void 0 && (!Array.isArray(value[k]) || !value[k].every(isRecord))) return false;
|
|
2979
|
+
}
|
|
2601
2980
|
return true;
|
|
2602
2981
|
}
|
|
2603
2982
|
function isMeshMissionHistoryFoldWire(value) {
|
|
@@ -2696,12 +3075,13 @@ function isLedgerQueryEntryWire(value) {
|
|
|
2696
3075
|
return true;
|
|
2697
3076
|
}
|
|
2698
3077
|
function isLedgerQuerySummaryWire(value) {
|
|
2699
|
-
const keys = ["meshId", "totalEntries", "taskDispatched", "taskCompleted", "taskFailed", "taskStalled", "sessionLaunched", "checkpointCreated", "lastActivityAt", "recentFailures"];
|
|
3078
|
+
const keys = ["meshId", "totalEntries", "taskDispatched", "taskCompleted", "taskFailed", "taskBlocked", "taskStalled", "sessionLaunched", "checkpointCreated", "lastActivityAt", "recentFailures"];
|
|
2700
3079
|
if (!isRecord(value) || !hasOnlyKeys2(value, keys)) return false;
|
|
2701
3080
|
if (!isEvidenceIdentifier(value.meshId)) return false;
|
|
2702
3081
|
for (const k of ["totalEntries", "taskDispatched", "taskCompleted", "taskFailed", "taskStalled", "sessionLaunched", "checkpointCreated", "recentFailures"]) {
|
|
2703
3082
|
if (!isNonNegativeInt(value[k])) return false;
|
|
2704
3083
|
}
|
|
3084
|
+
if (value.taskBlocked !== void 0 && !isNonNegativeInt(value.taskBlocked)) return false;
|
|
2705
3085
|
if (value.lastActivityAt !== null && typeof value.lastActivityAt !== "string") return false;
|
|
2706
3086
|
return true;
|
|
2707
3087
|
}
|
|
@@ -2745,9 +3125,10 @@ function isQueueDependencyHeadWire(value) {
|
|
|
2745
3125
|
return isRecord(value) && hasOnlyKeys2(value, ["id", "status", "cancelReason"]) && typeof value.id === "string" && typeof value.status === "string" && (value.cancelReason === void 0 || typeof value.cancelReason === "string");
|
|
2746
3126
|
}
|
|
2747
3127
|
function isQueueQueryResponse(value) {
|
|
2748
|
-
if (!isRecord(value) || !hasOnlyKeys2(value, ["entries", "counts", "oldHistoricalCount", "dependencyHeads"])) return false;
|
|
3128
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["entries", "counts", "oldHistoricalCount", "legacyReportedBlockedCount", "dependencyHeads"])) return false;
|
|
2749
3129
|
if (!Array.isArray(value.entries) || !value.entries.every(isQueueEntryWire)) return false;
|
|
2750
3130
|
if (value.counts !== void 0 && (!isRecord(value.counts) || !Object.values(value.counts).every(isNonNegativeInt))) return false;
|
|
3131
|
+
if (value.legacyReportedBlockedCount !== void 0 && !isNonNegativeInt(value.legacyReportedBlockedCount)) return false;
|
|
2751
3132
|
if (value.oldHistoricalCount !== void 0 && !isNonNegativeInt(value.oldHistoricalCount)) return false;
|
|
2752
3133
|
if (value.dependencyHeads !== void 0 && (!Array.isArray(value.dependencyHeads) || !value.dependencyHeads.every(isQueueDependencyHeadWire))) return false;
|
|
2753
3134
|
return true;
|
|
@@ -2869,6 +3250,17 @@ function isRecoveryContextQueryResponse(value) {
|
|
|
2869
3250
|
function decodeRecoveryContextQueryResponse(value) {
|
|
2870
3251
|
return isRecoveryContextQueryResponse(value) ? value : null;
|
|
2871
3252
|
}
|
|
3253
|
+
function decodeQueueReviseRequest(value) {
|
|
3254
|
+
if (!isRecord(value) || !hasOnlyKeys2(value, ["v", "meshId", "taskId", "expectedRevision", "patch"]) || value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId) || !isEvidenceIdentifier(value.taskId) || !Number.isSafeInteger(value.expectedRevision) || value.expectedRevision < 0 || !isRecord(value.patch) || !Object.keys(value.patch).length || !hasOnlyKeys2(value.patch, ["message", "ownedPaths", "phase", "dependsOn", "routingPreferences", "review"])) return null;
|
|
3255
|
+
const p = value.patch;
|
|
3256
|
+
if (p.message !== void 0 && (typeof p.message !== "string" || !p.message.trim())) return null;
|
|
3257
|
+
if (p.phase !== void 0 && p.phase !== "source" && p.phase !== "integration") return null;
|
|
3258
|
+
for (const key of ["ownedPaths", "dependsOn"]) {
|
|
3259
|
+
if (p[key] !== void 0 && (!Array.isArray(p[key]) || !p[key].every((x) => typeof x === "string" && !!x.trim()))) return null;
|
|
3260
|
+
}
|
|
3261
|
+
return value;
|
|
3262
|
+
}
|
|
3263
|
+
var decodeQueueReviseResponse = decodeQueueRequeueResponse;
|
|
2872
3264
|
|
|
2873
3265
|
// src/turn-ipc-stats.ts
|
|
2874
3266
|
function isTaskStatsQueryRequest(value) {
|
|
@@ -2967,6 +3359,7 @@ var TURN_IPC_COMMANDS = [
|
|
|
2967
3359
|
"queue_enqueue_batch",
|
|
2968
3360
|
"queue_cancel",
|
|
2969
3361
|
"queue_requeue",
|
|
3362
|
+
"queue_revise",
|
|
2970
3363
|
"direct_dispatch_record",
|
|
2971
3364
|
"active_work_query",
|
|
2972
3365
|
"recovery_context_query",
|
|
@@ -3050,14 +3443,11 @@ function normalizeOwnedPaths(input) {
|
|
|
3050
3443
|
}
|
|
3051
3444
|
function entryContains(base, path) {
|
|
3052
3445
|
if (path === base.path) return true;
|
|
3053
|
-
if (base.subtree && (path ===
|
|
3446
|
+
if (base.subtree && (base.path === "" || path.startsWith(`${base.path}/`))) return true;
|
|
3054
3447
|
return false;
|
|
3055
3448
|
}
|
|
3056
3449
|
function entriesOverlap(a, b) {
|
|
3057
|
-
|
|
3058
|
-
if (a.subtree && (b.path === a.path || b.path.startsWith(`${a.path}/`))) return true;
|
|
3059
|
-
if (b.subtree && (a.path === b.path || a.path.startsWith(`${b.path}/`))) return true;
|
|
3060
|
-
return false;
|
|
3450
|
+
return entryContains(a, b.path) || entryContains(b, a.path);
|
|
3061
3451
|
}
|
|
3062
3452
|
function pathsOverlap(a, b) {
|
|
3063
3453
|
if (a.paths.length === 0 || b.paths.length === 0) return false;
|
|
@@ -3109,6 +3499,357 @@ function touchedFilesOutsideOwnership(touched, owned) {
|
|
|
3109
3499
|
return { undeclaredTouched, unusedDeclarations };
|
|
3110
3500
|
}
|
|
3111
3501
|
|
|
3502
|
+
// src/mission-items.ts
|
|
3503
|
+
var MISSION_ITEM_KINDS = ["remaining", "live_check", "decision", "evidence"];
|
|
3504
|
+
var MISSION_ITEM_STATES = ["open", "done", "failed", "dropped", "moved", "answered", "expired", "withdrawn", "superseded"];
|
|
3505
|
+
var COORDINATOR_SETTABLE_ITEM_STATES = {
|
|
3506
|
+
remaining: ["open", "done", "dropped"],
|
|
3507
|
+
live_check: ["open", "done", "dropped"],
|
|
3508
|
+
evidence: ["open", "done", "dropped"],
|
|
3509
|
+
decision: ["open", "withdrawn", "superseded"]
|
|
3510
|
+
};
|
|
3511
|
+
var MISSION_OUTCOMES = ["merged", "verified_live", "superseded", "not_needed", "owner_abandoned", "unspecified"];
|
|
3512
|
+
function isMissionOutcome(value) {
|
|
3513
|
+
return typeof value === "string" && MISSION_OUTCOMES.includes(value);
|
|
3514
|
+
}
|
|
3515
|
+
var MISSION_REF_KINDS = ["commit", "branch", "pr", "task", "artifact", "mission", "url"];
|
|
3516
|
+
var MISSION_LIMITS = {
|
|
3517
|
+
summary: 300,
|
|
3518
|
+
outcomeReason: 500,
|
|
3519
|
+
itemText: 300,
|
|
3520
|
+
machine: 80,
|
|
3521
|
+
refs: 8,
|
|
3522
|
+
refValue: 300,
|
|
3523
|
+
refRepo: 120,
|
|
3524
|
+
refNote: 200,
|
|
3525
|
+
dedupeKey: 400,
|
|
3526
|
+
question: 300,
|
|
3527
|
+
context: 600,
|
|
3528
|
+
options: 5,
|
|
3529
|
+
optionLabel: 60,
|
|
3530
|
+
optionDetail: 200,
|
|
3531
|
+
/** Open items per mission before the oldest `remaining` fold into a "N more" summary item. */
|
|
3532
|
+
openItemsPerMission: 200,
|
|
3533
|
+
/** One event payload (serialized). */
|
|
3534
|
+
eventPayloadBytes: 16 * 1024,
|
|
3535
|
+
/** items_add / items_update entries honoured per call (extra entries are reported, not applied). */
|
|
3536
|
+
itemsPerCall: 50
|
|
3537
|
+
};
|
|
3538
|
+
var MISSION_DECISION_OPTION_IDS = ["a", "b", "c", "d", "e"];
|
|
3539
|
+
var MISSION_DECISION_URGENCIES = ["normal", "blocking"];
|
|
3540
|
+
var MISSION_DECISION_ON_DUE = ["remind", "apply_recommended"];
|
|
3541
|
+
function truncateMissionText(value, max) {
|
|
3542
|
+
if (value.length <= max) return value;
|
|
3543
|
+
return `${value.slice(0, max - 1).trimEnd()}\u2026`;
|
|
3544
|
+
}
|
|
3545
|
+
function str(value) {
|
|
3546
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3547
|
+
}
|
|
3548
|
+
function collapse(value) {
|
|
3549
|
+
return value.replace(/\s+/g, " ").trim();
|
|
3550
|
+
}
|
|
3551
|
+
function normalizeMissionSummary(value) {
|
|
3552
|
+
if (typeof value !== "string") return null;
|
|
3553
|
+
const text = collapse(value);
|
|
3554
|
+
return { value: truncateMissionText(text, MISSION_LIMITS.summary), truncated: text.length > MISSION_LIMITS.summary };
|
|
3555
|
+
}
|
|
3556
|
+
function normalizeOutcomeReason(value) {
|
|
3557
|
+
if (typeof value !== "string") return null;
|
|
3558
|
+
const text = value.trim();
|
|
3559
|
+
return { value: truncateMissionText(text, MISSION_LIMITS.outcomeReason), truncated: text.length > MISSION_LIMITS.outcomeReason };
|
|
3560
|
+
}
|
|
3561
|
+
function normalizeMissionRefs(value) {
|
|
3562
|
+
if (!Array.isArray(value)) return { refs: [], truncated: false };
|
|
3563
|
+
const refs = [];
|
|
3564
|
+
let truncated = false;
|
|
3565
|
+
for (const raw of value) {
|
|
3566
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
3567
|
+
const r = raw;
|
|
3568
|
+
const kind = str(r.kind);
|
|
3569
|
+
const refValue = str(r.value);
|
|
3570
|
+
if (!MISSION_REF_KINDS.includes(kind) || !refValue) continue;
|
|
3571
|
+
if (refs.length >= MISSION_LIMITS.refs) {
|
|
3572
|
+
truncated = true;
|
|
3573
|
+
break;
|
|
3574
|
+
}
|
|
3575
|
+
const repo = str(r.repo);
|
|
3576
|
+
const note = str(r.note);
|
|
3577
|
+
refs.push({
|
|
3578
|
+
kind,
|
|
3579
|
+
...repo ? { repo: truncateMissionText(repo, MISSION_LIMITS.refRepo) } : {},
|
|
3580
|
+
value: truncateMissionText(refValue, MISSION_LIMITS.refValue),
|
|
3581
|
+
...note ? { note: truncateMissionText(note, MISSION_LIMITS.refNote) } : {}
|
|
3582
|
+
});
|
|
3583
|
+
}
|
|
3584
|
+
return { refs, truncated };
|
|
3585
|
+
}
|
|
3586
|
+
function normalizeOptions(value, truncated) {
|
|
3587
|
+
if (!Array.isArray(value)) return [];
|
|
3588
|
+
const out = [];
|
|
3589
|
+
for (const raw of value) {
|
|
3590
|
+
if (typeof raw === "string" && raw.trim()) {
|
|
3591
|
+
if (out.length >= MISSION_LIMITS.options) {
|
|
3592
|
+
truncated.push("options");
|
|
3593
|
+
break;
|
|
3594
|
+
}
|
|
3595
|
+
out.push({ id: MISSION_DECISION_OPTION_IDS[out.length], label: truncateMissionText(raw.trim(), MISSION_LIMITS.optionLabel) });
|
|
3596
|
+
continue;
|
|
3597
|
+
}
|
|
3598
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
3599
|
+
const o = raw;
|
|
3600
|
+
const label = collapse(str(o.label));
|
|
3601
|
+
if (!label) continue;
|
|
3602
|
+
if (out.length >= MISSION_LIMITS.options) {
|
|
3603
|
+
truncated.push("options");
|
|
3604
|
+
break;
|
|
3605
|
+
}
|
|
3606
|
+
const detail = str(o.detail);
|
|
3607
|
+
out.push({
|
|
3608
|
+
id: MISSION_DECISION_OPTION_IDS[out.length],
|
|
3609
|
+
label: truncateMissionText(label, MISSION_LIMITS.optionLabel),
|
|
3610
|
+
...detail ? { detail: truncateMissionText(detail, MISSION_LIMITS.optionDetail) } : {}
|
|
3611
|
+
});
|
|
3612
|
+
}
|
|
3613
|
+
return out;
|
|
3614
|
+
}
|
|
3615
|
+
function normalizeDueAt(value) {
|
|
3616
|
+
if (typeof value !== "string" || !value.trim()) return void 0;
|
|
3617
|
+
const ms2 = Date.parse(value);
|
|
3618
|
+
return Number.isNaN(ms2) ? void 0 : new Date(ms2).toISOString();
|
|
3619
|
+
}
|
|
3620
|
+
function normalizeDecisionInput(raw, truncated) {
|
|
3621
|
+
const questionSource = collapse(str(raw.question) || str(raw.text));
|
|
3622
|
+
if (!questionSource) return null;
|
|
3623
|
+
if (questionSource.length > MISSION_LIMITS.question) truncated.push("question");
|
|
3624
|
+
const question = truncateMissionText(questionSource, MISSION_LIMITS.question);
|
|
3625
|
+
const contextSource = str(raw.context);
|
|
3626
|
+
if (contextSource.length > MISSION_LIMITS.context) truncated.push("context");
|
|
3627
|
+
const options = normalizeOptions(raw.options, truncated);
|
|
3628
|
+
const recommendedRaw = str(raw.recommended);
|
|
3629
|
+
const recommended = recommendedRaw && options.some((o) => o.id === recommendedRaw) ? recommendedRaw : options.find((o) => recommendedRaw && o.label.toLowerCase() === recommendedRaw.toLowerCase())?.id;
|
|
3630
|
+
const dueAt = normalizeDueAt(raw.dueAt ?? raw.due_at);
|
|
3631
|
+
const onDueRaw = str(raw.onDue ?? raw.on_due);
|
|
3632
|
+
const urgencyRaw = str(raw.urgency);
|
|
3633
|
+
const allowFreeTextRaw = raw.allowFreeText ?? raw.allow_free_text;
|
|
3634
|
+
return {
|
|
3635
|
+
question,
|
|
3636
|
+
...contextSource ? { context: truncateMissionText(contextSource, MISSION_LIMITS.context) } : {},
|
|
3637
|
+
options,
|
|
3638
|
+
...recommended ? { recommended } : {},
|
|
3639
|
+
allowFreeText: typeof allowFreeTextRaw === "boolean" ? allowFreeTextRaw : true,
|
|
3640
|
+
...dueAt ? { dueAt } : {},
|
|
3641
|
+
// apply_recommended without a recommended option has nothing to apply — fall back to remind.
|
|
3642
|
+
onDue: onDueRaw === "apply_recommended" && recommended ? "apply_recommended" : "remind",
|
|
3643
|
+
urgency: urgencyRaw === "blocking" ? "blocking" : "normal"
|
|
3644
|
+
};
|
|
3645
|
+
}
|
|
3646
|
+
function normalizeForDedupe(text) {
|
|
3647
|
+
return collapse(text).toLowerCase().replace(/[\s.!?。]+$/u, "");
|
|
3648
|
+
}
|
|
3649
|
+
function deriveItemDedupeKey(kind, parts) {
|
|
3650
|
+
const explicit = str(parts.explicit);
|
|
3651
|
+
if (explicit) return truncateMissionText(`k:${explicit}`, MISSION_LIMITS.dedupeKey);
|
|
3652
|
+
if (kind === "decision") return truncateMissionText(`decision:${normalizeForDedupe(parts.question ?? parts.text ?? "")}`, MISSION_LIMITS.dedupeKey);
|
|
3653
|
+
if (kind === "evidence") {
|
|
3654
|
+
const ref2 = parts.refs?.[0];
|
|
3655
|
+
if (ref2) return truncateMissionText(`evidence:${ref2.kind}:${ref2.repo ?? ""}:${ref2.value}`, MISSION_LIMITS.dedupeKey);
|
|
3656
|
+
}
|
|
3657
|
+
const machine = parts.machine ? `@${normalizeForDedupe(parts.machine)}` : "";
|
|
3658
|
+
return truncateMissionText(`${kind}${machine}:${normalizeForDedupe(parts.text ?? "")}`, MISSION_LIMITS.dedupeKey);
|
|
3659
|
+
}
|
|
3660
|
+
function normalizeMissionItemInput(raw) {
|
|
3661
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "item must be an object" };
|
|
3662
|
+
const r = raw;
|
|
3663
|
+
const kind = str(r.kind) || "remaining";
|
|
3664
|
+
if (!MISSION_ITEM_KINDS.includes(kind)) {
|
|
3665
|
+
return { error: `invalid kind '${kind}' (valid: ${MISSION_ITEM_KINDS.join(", ")})` };
|
|
3666
|
+
}
|
|
3667
|
+
const truncated = [];
|
|
3668
|
+
const { refs, truncated: refsTruncated } = normalizeMissionRefs(r.refs);
|
|
3669
|
+
if (refsTruncated) truncated.push("refs");
|
|
3670
|
+
const machineRaw = collapse(str(r.machine));
|
|
3671
|
+
const machine = machineRaw ? truncateMissionText(machineRaw, MISSION_LIMITS.machine) : void 0;
|
|
3672
|
+
const explicitKey = str(r.dedupe_key ?? r.dedupeKey);
|
|
3673
|
+
if (kind === "decision") {
|
|
3674
|
+
const decisionRaw = r.decision && typeof r.decision === "object" && !Array.isArray(r.decision) ? r.decision : r;
|
|
3675
|
+
const decision = normalizeDecisionInput({ ...decisionRaw, question: decisionRaw.question ?? r.question ?? r.text }, truncated);
|
|
3676
|
+
if (!decision) return { error: "decision item needs a question" };
|
|
3677
|
+
return {
|
|
3678
|
+
item: {
|
|
3679
|
+
kind,
|
|
3680
|
+
text: decision.question,
|
|
3681
|
+
...machine ? { machine } : {},
|
|
3682
|
+
refs,
|
|
3683
|
+
decision,
|
|
3684
|
+
dedupeKey: deriveItemDedupeKey("decision", { question: decision.question, explicit: explicitKey }),
|
|
3685
|
+
truncated
|
|
3686
|
+
}
|
|
3687
|
+
};
|
|
3688
|
+
}
|
|
3689
|
+
const textSource = collapse(str(r.text));
|
|
3690
|
+
if (!textSource && !(kind === "evidence" && refs.length > 0)) return { error: `${kind} item needs text` };
|
|
3691
|
+
if (textSource.length > MISSION_LIMITS.itemText) truncated.push("text");
|
|
3692
|
+
const text = truncateMissionText(textSource || `${refs[0].kind}: ${refs[0].value}`, MISSION_LIMITS.itemText);
|
|
3693
|
+
return {
|
|
3694
|
+
item: {
|
|
3695
|
+
kind,
|
|
3696
|
+
text,
|
|
3697
|
+
...machine ? { machine } : {},
|
|
3698
|
+
refs,
|
|
3699
|
+
dedupeKey: deriveItemDedupeKey(kind, { text, machine, refs, explicit: explicitKey }),
|
|
3700
|
+
truncated
|
|
3701
|
+
}
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
function normalizeMissionItemUpdate(raw) {
|
|
3705
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "update must be an object" };
|
|
3706
|
+
const r = raw;
|
|
3707
|
+
const id2 = str(r.id ?? r.item_id ?? r.itemId);
|
|
3708
|
+
if (!id2) return { error: "update needs an item id" };
|
|
3709
|
+
const truncated = [];
|
|
3710
|
+
const update = { id: id2 };
|
|
3711
|
+
if (r.state !== void 0) {
|
|
3712
|
+
const state = str(r.state);
|
|
3713
|
+
if (!MISSION_ITEM_STATES.includes(state)) return { error: `invalid state '${state}'` };
|
|
3714
|
+
update.state = state;
|
|
3715
|
+
}
|
|
3716
|
+
if (typeof r.text === "string") {
|
|
3717
|
+
const text = collapse(r.text);
|
|
3718
|
+
if (text.length > MISSION_LIMITS.itemText) truncated.push("text");
|
|
3719
|
+
if (text) update.text = truncateMissionText(text, MISSION_LIMITS.itemText);
|
|
3720
|
+
}
|
|
3721
|
+
if (r.machine === null) update.machine = null;
|
|
3722
|
+
else if (typeof r.machine === "string") {
|
|
3723
|
+
const machine = collapse(r.machine);
|
|
3724
|
+
update.machine = machine ? truncateMissionText(machine, MISSION_LIMITS.machine) : null;
|
|
3725
|
+
}
|
|
3726
|
+
if (r.refs !== void 0) {
|
|
3727
|
+
const { refs, truncated: t } = normalizeMissionRefs(r.refs);
|
|
3728
|
+
if (t) truncated.push("refs");
|
|
3729
|
+
update.refs = refs;
|
|
3730
|
+
}
|
|
3731
|
+
return { update, truncated };
|
|
3732
|
+
}
|
|
3733
|
+
function boundEventPayload(payload) {
|
|
3734
|
+
let json = JSON.stringify(payload);
|
|
3735
|
+
if (json.length <= MISSION_LIMITS.eventPayloadBytes) return json;
|
|
3736
|
+
const shrunk = {};
|
|
3737
|
+
for (const [k, v] of Object.entries(payload)) {
|
|
3738
|
+
shrunk[k] = typeof v === "string" && v.length > 4e3 ? `${v.slice(0, 4e3)}\u2026` : v;
|
|
3739
|
+
}
|
|
3740
|
+
shrunk.payloadTruncated = true;
|
|
3741
|
+
json = JSON.stringify(shrunk);
|
|
3742
|
+
if (json.length <= MISSION_LIMITS.eventPayloadBytes) return json;
|
|
3743
|
+
return JSON.stringify({ payloadTruncated: true, keys: Object.keys(payload).slice(0, 20) });
|
|
3744
|
+
}
|
|
3745
|
+
var CARRY_OVER_MISSION_TITLE = "Carry-over \u2014 open items from closed missions";
|
|
3746
|
+
var LEGACY_CARRY_OVER_MISSION_TITLE = "\uC774\uC6D4 \u2014 \uB2EB\uD78C \uBBF8\uC158\uC5D0\uC11C \uB118\uC5B4\uC628 \uD56D\uBAA9";
|
|
3747
|
+
var CARRY_OVER_MISSION_GOAL = "Open items carried over from closed missions, and decisions requested without a mission. Managed automatically \u2014 do not close.";
|
|
3748
|
+
function isCarryOverMissionRecord(m) {
|
|
3749
|
+
return !!m && (m.isCarryOver === true || isCarryOverMissionTitle(m.title));
|
|
3750
|
+
}
|
|
3751
|
+
function isCarryOverMissionTitle(title) {
|
|
3752
|
+
if (typeof title !== "string") return false;
|
|
3753
|
+
const t = title.trim();
|
|
3754
|
+
return t === CARRY_OVER_MISSION_TITLE || t === LEGACY_CARRY_OVER_MISSION_TITLE;
|
|
3755
|
+
}
|
|
3756
|
+
var OWNER_ABANDON_CONFIRM_KEY_PREFIX = "owner-abandon-confirm:";
|
|
3757
|
+
var OWNER_ABANDON_CONFIRM_QUESTION = "The coordinator closed this as 'owner abandoned' \u2014 correct?";
|
|
3758
|
+
var OWNER_ABANDON_CONFIRM_OPTIONS = ["Correct", "Reopen"];
|
|
3759
|
+
var WORKER_DECISIONS_NEEDED_MAX = 3;
|
|
3760
|
+
var WORKER_COMMITS_MAX = 20;
|
|
3761
|
+
var SHA_RE = /^[0-9a-f]{7,64}$/i;
|
|
3762
|
+
function normalizeReportCommits(value) {
|
|
3763
|
+
if (!Array.isArray(value)) return null;
|
|
3764
|
+
const out = [];
|
|
3765
|
+
for (const v of value) {
|
|
3766
|
+
if (typeof v !== "string") return null;
|
|
3767
|
+
const sha = v.trim();
|
|
3768
|
+
if (!SHA_RE.test(sha)) return null;
|
|
3769
|
+
if (!out.includes(sha.toLowerCase())) out.push(sha.toLowerCase());
|
|
3770
|
+
}
|
|
3771
|
+
return out;
|
|
3772
|
+
}
|
|
3773
|
+
|
|
3774
|
+
// src/mission-git-state.ts
|
|
3775
|
+
var MISSION_REF_GIT_STATUSES = ["contained_ancestor", "contained_patch_equivalent", "not_contained", "unknown"];
|
|
3776
|
+
var MISSION_REF_GIT_METHODS = ["ancestry", "cherry", "residual_patch"];
|
|
3777
|
+
var MISSION_GIT_STATES = ["no_refs", "landed", "partial", "not_landed", "unknown"];
|
|
3778
|
+
function isMissionRefContained(status) {
|
|
3779
|
+
return status === "contained_ancestor" || status === "contained_patch_equivalent";
|
|
3780
|
+
}
|
|
3781
|
+
function aggregateMissionGitState(statuses) {
|
|
3782
|
+
const total = statuses.length;
|
|
3783
|
+
const contained = statuses.filter(isMissionRefContained).length;
|
|
3784
|
+
const notContained = statuses.filter((s) => s === "not_contained").length;
|
|
3785
|
+
const unknown = statuses.filter((s) => s === "unknown").length;
|
|
3786
|
+
const counts = { total, contained, notContained, unknown };
|
|
3787
|
+
if (total === 0) return { state: "no_refs", partialUnknown: false, counts };
|
|
3788
|
+
if (contained === total) return { state: "landed", partialUnknown: false, counts };
|
|
3789
|
+
if (contained > 0) return { state: "partial", partialUnknown: unknown > 0, counts };
|
|
3790
|
+
if (notContained === total) return { state: "not_landed", partialUnknown: false, counts };
|
|
3791
|
+
return { state: "unknown", partialUnknown: false, counts };
|
|
3792
|
+
}
|
|
3793
|
+
|
|
3794
|
+
// src/release.ts
|
|
3795
|
+
var MESH_RELEASE_CHANNELS = ["preview", "stable"];
|
|
3796
|
+
function isMeshReleaseChannel(value) {
|
|
3797
|
+
return typeof value === "string" && MESH_RELEASE_CHANNELS.includes(value);
|
|
3798
|
+
}
|
|
3799
|
+
var MESH_RELEASE_STATUSES = ["planned", "frozen", "deployed", "verified", "superseded", "cancelled"];
|
|
3800
|
+
function isReleaseStatus(value) {
|
|
3801
|
+
return typeof value === "string" && MESH_RELEASE_STATUSES.includes(value);
|
|
3802
|
+
}
|
|
3803
|
+
var RELEASE_MEMBER_STATES = ["member", "moved_out", "removed"];
|
|
3804
|
+
var RELEASE_ACTORS = ["coordinator", "owner", "assistant", "script"];
|
|
3805
|
+
var RELEASE_EVENT_TYPES = [
|
|
3806
|
+
"created",
|
|
3807
|
+
"status_changed",
|
|
3808
|
+
"scope_added",
|
|
3809
|
+
"scope_moved",
|
|
3810
|
+
"scope_removed",
|
|
3811
|
+
"deploy_recorded",
|
|
3812
|
+
"changelog_drafted",
|
|
3813
|
+
"changelog_applied"
|
|
3814
|
+
];
|
|
3815
|
+
var MISSION_RELEASE_EVENT_TYPES = ["release_attached", "release_moved", "release_detached"];
|
|
3816
|
+
var RELEASE_LIMITS = {
|
|
3817
|
+
name: 80,
|
|
3818
|
+
note: 500,
|
|
3819
|
+
/** `mesh_missions.release_note`: one user/operator-visible sentence. */
|
|
3820
|
+
releaseNote: 400,
|
|
3821
|
+
missionsPerCall: 100,
|
|
3822
|
+
changelogEntries: 300
|
|
3823
|
+
};
|
|
3824
|
+
var CHANGELOG_SECTIONS = ["Added", "Fixed", "Changed"];
|
|
3825
|
+
var NEEDS_WORDING_MARKER = "[needs user-facing wording]";
|
|
3826
|
+
function changelogMissionMarker(missionId) {
|
|
3827
|
+
return `<!-- m:${missionId.slice(0, 8)} -->`;
|
|
3828
|
+
}
|
|
3829
|
+
function classifyChangelogSection(text, hint) {
|
|
3830
|
+
const m = /^\s*\[(added|fixed|changed)\]\s*/i.exec(text);
|
|
3831
|
+
if (m) {
|
|
3832
|
+
const key = m[1].toLowerCase();
|
|
3833
|
+
return { section: key === "added" ? "Added" : key === "fixed" ? "Fixed" : "Changed", text: text.slice(m[0].length).trim() };
|
|
3834
|
+
}
|
|
3835
|
+
const probe = `${hint ?? ""} ${text}`.toLowerCase();
|
|
3836
|
+
if (/\b(fix|fixes|fixed|bug|regression|crash|error)\b|오류|결함|버그|수정/.test(probe)) return { section: "Fixed", text };
|
|
3837
|
+
if (/\b(add|adds|added|new|introduc\w*|support\w*)\b|신규|추가/.test(probe)) return { section: "Added", text };
|
|
3838
|
+
return { section: "Changed", text };
|
|
3839
|
+
}
|
|
3840
|
+
function lintChangelogText(text) {
|
|
3841
|
+
const out = [];
|
|
3842
|
+
if (/\bwave[\s-]*\d+/i.test(text) || /웨이브\s*\d+/.test(text)) out.push("mentions an internal wave number");
|
|
3843
|
+
if (/\brc[.\s-]?\d+\b/i.test(text)) out.push("mentions an internal rc number");
|
|
3844
|
+
if (/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i.test(text) || /\bmi_[0-9a-f]{12}\b/.test(text) || /\brel_[0-9a-f]{12}\b/.test(text)) out.push("contains an internal id");
|
|
3845
|
+
if (/\bmission\b/i.test(text)) out.push('mentions "mission" (internal vocabulary)');
|
|
3846
|
+
return out;
|
|
3847
|
+
}
|
|
3848
|
+
|
|
3849
|
+
// src/decision-push-relay.ts
|
|
3850
|
+
var DECISION_PUSH_RELAY_COMMAND = "mission_decision_push_relay_answer";
|
|
3851
|
+
var DECISION_PUSH_RELAY_SOURCE = "push_relay";
|
|
3852
|
+
|
|
3112
3853
|
// src/keyed-doc-delta.ts
|
|
3113
3854
|
function sig(value) {
|
|
3114
3855
|
if (value === void 0) return void 0;
|
|
@@ -3329,7 +4070,15 @@ function foldKeyedDoc(held, delta, spec) {
|
|
|
3329
4070
|
const heldList = heldCollections.get(path);
|
|
3330
4071
|
if (change?.absent) {
|
|
3331
4072
|
const [head2, tail2] = splitPath(path);
|
|
3332
|
-
if (!tail2)
|
|
4073
|
+
if (!tail2) {
|
|
4074
|
+
delete next[head2];
|
|
4075
|
+
continue;
|
|
4076
|
+
}
|
|
4077
|
+
const parent2 = next[head2];
|
|
4078
|
+
if (!isRecord3(parent2) || !(tail2 in parent2)) continue;
|
|
4079
|
+
const copy = { ...parent2 };
|
|
4080
|
+
delete copy[tail2];
|
|
4081
|
+
next[head2] = copy;
|
|
3333
4082
|
continue;
|
|
3334
4083
|
}
|
|
3335
4084
|
if (!change && heldList === void 0) continue;
|
|
@@ -3393,8 +4142,164 @@ function stableMeshNodeRow(row) {
|
|
|
3393
4142
|
}
|
|
3394
4143
|
return out;
|
|
3395
4144
|
}
|
|
4145
|
+
|
|
4146
|
+
// src/provider-approval.ts
|
|
4147
|
+
function isActionableProviderApproval(approval) {
|
|
4148
|
+
return !!approval && approval.source === "provider_modal" && approval.type === "tool_permission" && approval.lifecycle === "pending" && approval.evidence === "live" && approval.actionable && !!approval.modalKey && Array.isArray(approval.buttons) && approval.buttons.some((button) => typeof button === "string" && !!button.trim());
|
|
4149
|
+
}
|
|
4150
|
+
function readProviderDecision(approval, waiting, hasModal = false) {
|
|
4151
|
+
if (approval !== void 0) return approval && ["provider_modal", "legacy_provider", "status_only", "ledger_approval"].includes(approval.source) ? approval : null;
|
|
4152
|
+
if (!waiting) return null;
|
|
4153
|
+
return {
|
|
4154
|
+
source: hasModal ? "legacy_provider" : "status_only",
|
|
4155
|
+
type: "unknown",
|
|
4156
|
+
compatibility: hasModal ? "session_only" : "unknown",
|
|
4157
|
+
evidence: "unavailable",
|
|
4158
|
+
lifecycle: "pending",
|
|
4159
|
+
modalKey: null,
|
|
4160
|
+
createdAt: null,
|
|
4161
|
+
resolvedAt: null,
|
|
4162
|
+
description: "",
|
|
4163
|
+
buttons: [],
|
|
4164
|
+
actionable: false
|
|
4165
|
+
};
|
|
4166
|
+
}
|
|
4167
|
+
function providerApprovalSnapshot(approval) {
|
|
4168
|
+
if (!approval) return null;
|
|
4169
|
+
const {
|
|
4170
|
+
source,
|
|
4171
|
+
type,
|
|
4172
|
+
lifecycle,
|
|
4173
|
+
modalKey,
|
|
4174
|
+
createdAt,
|
|
4175
|
+
resolvedAt,
|
|
4176
|
+
providerType,
|
|
4177
|
+
sessionId,
|
|
4178
|
+
nodeId,
|
|
4179
|
+
meshId,
|
|
4180
|
+
taskId,
|
|
4181
|
+
attemptId,
|
|
4182
|
+
generation
|
|
4183
|
+
} = approval;
|
|
4184
|
+
return {
|
|
4185
|
+
source,
|
|
4186
|
+
type,
|
|
4187
|
+
lifecycle,
|
|
4188
|
+
modalKey,
|
|
4189
|
+
createdAt,
|
|
4190
|
+
resolvedAt,
|
|
4191
|
+
providerType,
|
|
4192
|
+
sessionId,
|
|
4193
|
+
nodeId,
|
|
4194
|
+
meshId,
|
|
4195
|
+
taskId,
|
|
4196
|
+
attemptId,
|
|
4197
|
+
generation,
|
|
4198
|
+
evidence: "cached",
|
|
4199
|
+
actionable: false,
|
|
4200
|
+
description: "",
|
|
4201
|
+
buttons: []
|
|
4202
|
+
};
|
|
4203
|
+
}
|
|
4204
|
+
|
|
4205
|
+
// src/provider-question.ts
|
|
4206
|
+
function isProviderQuestionBinding(value) {
|
|
4207
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
4208
|
+
const b = value;
|
|
4209
|
+
if (b.transport !== "codex_rpc" && b.transport !== "codex_async") return false;
|
|
4210
|
+
const keys = ["transport", "sessionId", "generation", "threadId", "turnId", "itemId", ...b.transport === "codex_rpc" ? ["requestId"] : []];
|
|
4211
|
+
if (Reflect.ownKeys(b).some((key) => typeof key !== "string" || !keys.includes(key))) return false;
|
|
4212
|
+
if (["sessionId", "generation", "threadId", "turnId", "itemId"].some((key) => typeof b[key] !== "string" || !b[key].trim())) return false;
|
|
4213
|
+
return b.transport === "codex_async" ? b.requestId === void 0 : typeof b.requestId === "string" && !!b.requestId.trim() || typeof b.requestId === "number" && Number.isFinite(b.requestId);
|
|
4214
|
+
}
|
|
4215
|
+
|
|
4216
|
+
// src/relay-reprobe.ts
|
|
4217
|
+
var RELAY_REPROBE_BASE_DELAY_MS = 6e4;
|
|
4218
|
+
var RELAY_REPROBE_MAX_DELAY_MS = 5 * 6e4;
|
|
4219
|
+
var RELAY_REPROBE_JITTER_RATIO = 0.2;
|
|
4220
|
+
function computeRelayReprobeDelay(failures, random, timing = {}) {
|
|
4221
|
+
const base = timing.baseDelayMs ?? RELAY_REPROBE_BASE_DELAY_MS;
|
|
4222
|
+
const max = timing.maxDelayMs ?? RELAY_REPROBE_MAX_DELAY_MS;
|
|
4223
|
+
const jitter = timing.jitterRatio ?? RELAY_REPROBE_JITTER_RATIO;
|
|
4224
|
+
const grown = Math.min(max, base * 2 ** Math.max(0, failures));
|
|
4225
|
+
const factor = 1 + jitter * (Math.min(1, Math.max(0, random())) * 2 - 1);
|
|
4226
|
+
return Math.round(grown * factor);
|
|
4227
|
+
}
|
|
4228
|
+
var RelayReprobeScheduler = class {
|
|
4229
|
+
constructor(options) {
|
|
4230
|
+
this.options = options;
|
|
4231
|
+
}
|
|
4232
|
+
handle = null;
|
|
4233
|
+
running = false;
|
|
4234
|
+
inFlight = false;
|
|
4235
|
+
failureCount = 0;
|
|
4236
|
+
generation = 0;
|
|
4237
|
+
get isRunning() {
|
|
4238
|
+
return this.running;
|
|
4239
|
+
}
|
|
4240
|
+
get failures() {
|
|
4241
|
+
return this.failureCount;
|
|
4242
|
+
}
|
|
4243
|
+
get probing() {
|
|
4244
|
+
return this.inFlight;
|
|
4245
|
+
}
|
|
4246
|
+
/** Begin probing (idempotent). Call when a connection is selected as relay. */
|
|
4247
|
+
start() {
|
|
4248
|
+
if (this.running) return;
|
|
4249
|
+
this.running = true;
|
|
4250
|
+
this.failureCount = 0;
|
|
4251
|
+
this.generation++;
|
|
4252
|
+
this.schedule();
|
|
4253
|
+
}
|
|
4254
|
+
/** Stop for good (direct path found, connection closed, auth epoch changed). */
|
|
4255
|
+
stop() {
|
|
4256
|
+
this.running = false;
|
|
4257
|
+
this.generation++;
|
|
4258
|
+
if (this.handle !== null) {
|
|
4259
|
+
this.options.clearTimer(this.handle);
|
|
4260
|
+
this.handle = null;
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
schedule() {
|
|
4264
|
+
if (!this.running) return;
|
|
4265
|
+
const generation = this.generation;
|
|
4266
|
+
const delay = computeRelayReprobeDelay(this.failureCount, this.options.random, this.options);
|
|
4267
|
+
this.handle = this.options.setTimer(() => {
|
|
4268
|
+
this.handle = null;
|
|
4269
|
+
void this.tick(generation);
|
|
4270
|
+
}, delay);
|
|
4271
|
+
}
|
|
4272
|
+
async tick(generation) {
|
|
4273
|
+
if (!this.running || generation !== this.generation) return;
|
|
4274
|
+
if (this.inFlight || !this.options.shouldProbe()) {
|
|
4275
|
+
this.schedule();
|
|
4276
|
+
return;
|
|
4277
|
+
}
|
|
4278
|
+
this.inFlight = true;
|
|
4279
|
+
let outcome;
|
|
4280
|
+
try {
|
|
4281
|
+
outcome = await this.options.probe();
|
|
4282
|
+
} catch {
|
|
4283
|
+
outcome = "failed";
|
|
4284
|
+
}
|
|
4285
|
+
this.inFlight = false;
|
|
4286
|
+
if (!this.running || generation !== this.generation) return;
|
|
4287
|
+
if (outcome === "direct") {
|
|
4288
|
+
this.stop();
|
|
4289
|
+
return;
|
|
4290
|
+
}
|
|
4291
|
+
if (outcome !== "skipped") this.failureCount++;
|
|
4292
|
+
this.schedule();
|
|
4293
|
+
}
|
|
4294
|
+
};
|
|
3396
4295
|
export {
|
|
4296
|
+
ASSISTANT_ACCOUNT_SLOT,
|
|
4297
|
+
ASSISTANT_FOLLOWER_ALLOWED_OPS,
|
|
3397
4298
|
ASSISTANT_OWNER_VERBS,
|
|
4299
|
+
ASSISTANT_REMOTE_FOLLOW_COMMAND,
|
|
4300
|
+
ASSISTANT_REMOTE_PROJECT_ACCESS_COMMAND,
|
|
4301
|
+
ASSISTANT_REMOTE_PROJECT_CATALOG_COMMAND,
|
|
4302
|
+
ASSISTANT_REMOTE_PROJECT_COMMAND,
|
|
3398
4303
|
ASSISTANT_REVIEW_TURN_VERBS,
|
|
3399
4304
|
ASSISTANT_SESSION_ID_ARG,
|
|
3400
4305
|
ASSISTANT_SESSION_ID_ENV,
|
|
@@ -3406,12 +4311,16 @@ export {
|
|
|
3406
4311
|
CANCEL_REASONS,
|
|
3407
4312
|
CANONICAL_MESH_TOOL_COUNT,
|
|
3408
4313
|
CANONICAL_MESH_TOOL_NAMES,
|
|
4314
|
+
CARRY_OVER_MISSION_GOAL,
|
|
4315
|
+
CARRY_OVER_MISSION_TITLE,
|
|
4316
|
+
CHANGELOG_SECTIONS,
|
|
3409
4317
|
CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX,
|
|
3410
4318
|
CLAUDE_TUI_REVIEW_UNCONFIRMED_PREFIX,
|
|
3411
4319
|
CLI_SLOT_RECIPES,
|
|
3412
4320
|
COMMIT_STRENGTHS,
|
|
3413
4321
|
CONSUME_PROFILES,
|
|
3414
4322
|
COORDINATOR_ACK_OUTCOMES,
|
|
4323
|
+
COORDINATOR_SETTABLE_ITEM_STATES,
|
|
3415
4324
|
DAEMON_METADATA_DOC_SPEC,
|
|
3416
4325
|
DAEMON_P2P_SIGNAL_TYPES,
|
|
3417
4326
|
DAEMON_STATUS_EVENT_NAMES,
|
|
@@ -3424,6 +4333,11 @@ export {
|
|
|
3424
4333
|
DASHBOARD_TO_DAEMON_P2P_TYPES,
|
|
3425
4334
|
DASHBOARD_TO_USER_SESSION_TYPES,
|
|
3426
4335
|
DASHBOARD_WIRE_VERSION,
|
|
4336
|
+
DECISION_PUSH_OPTIONS_MAX,
|
|
4337
|
+
DECISION_PUSH_OPTION_LABEL_MAX,
|
|
4338
|
+
DECISION_PUSH_QUESTION_MAX,
|
|
4339
|
+
DECISION_PUSH_RELAY_COMMAND,
|
|
4340
|
+
DECISION_PUSH_RELAY_SOURCE,
|
|
3427
4341
|
DEFAULT_DIFFICULTY_BRAINS,
|
|
3428
4342
|
DELIVERY_OUTCOMES,
|
|
3429
4343
|
DELIVERY_VIAS,
|
|
@@ -3431,6 +4345,11 @@ export {
|
|
|
3431
4345
|
EVIDENCE_ENVELOPE_FIELD_SPECS,
|
|
3432
4346
|
EVIDENCE_SOURCE_IDS,
|
|
3433
4347
|
HOLD_REASONS,
|
|
4348
|
+
LAUNCH_DEFAULTS_NEXT_LAUNCH_NOTE,
|
|
4349
|
+
LAUNCH_DEFAULT_ERROR_CODES,
|
|
4350
|
+
LAUNCH_DEFAULT_ROLES,
|
|
4351
|
+
LAUNCH_DEFAULT_SOURCES,
|
|
4352
|
+
LEGACY_CARRY_OVER_MISSION_TITLE,
|
|
3434
4353
|
LIVENESS_RESULTS,
|
|
3435
4354
|
MAX_MESH_RECORD_STRING,
|
|
3436
4355
|
MAX_OWNED_PATHS,
|
|
@@ -3445,6 +4364,8 @@ export {
|
|
|
3445
4364
|
MESH_MISSION_STATUSES,
|
|
3446
4365
|
MESH_P2P_SIGNAL_TYPES,
|
|
3447
4366
|
MESH_RECORD_PAYLOAD_KEYS,
|
|
4367
|
+
MESH_RELEASE_CHANNELS,
|
|
4368
|
+
MESH_RELEASE_STATUSES,
|
|
3448
4369
|
MESH_SESSION_CLEANUP_MODES,
|
|
3449
4370
|
MESH_STATUS_DOC_SPEC,
|
|
3450
4371
|
MESH_TASK_DIFFICULTIES,
|
|
@@ -3456,10 +4377,23 @@ export {
|
|
|
3456
4377
|
MESH_TOPIC_ENTRY_KINDS,
|
|
3457
4378
|
MESH_TOPIC_PROTOCOL_VERSION,
|
|
3458
4379
|
MISSION_BRIEF_RENDER_MAX_CHARS,
|
|
4380
|
+
MISSION_DECISION_ON_DUE,
|
|
4381
|
+
MISSION_DECISION_OPTION_IDS,
|
|
4382
|
+
MISSION_DECISION_URGENCIES,
|
|
4383
|
+
MISSION_GIT_STATES,
|
|
4384
|
+
MISSION_ITEM_KINDS,
|
|
4385
|
+
MISSION_ITEM_STATES,
|
|
4386
|
+
MISSION_LIMITS,
|
|
4387
|
+
MISSION_OUTCOMES,
|
|
4388
|
+
MISSION_REF_GIT_METHODS,
|
|
4389
|
+
MISSION_REF_GIT_STATUSES,
|
|
4390
|
+
MISSION_REF_KINDS,
|
|
4391
|
+
MISSION_RELEASE_EVENT_TYPES,
|
|
3459
4392
|
MODEL_AXIS_SOURCES,
|
|
3460
4393
|
MODEL_SELECTION_HISTORY_LIMIT,
|
|
3461
4394
|
MeshChunkAssembler,
|
|
3462
4395
|
NATIVE_TURN_OUTCOMES,
|
|
4396
|
+
NEEDS_WORDING_MARKER,
|
|
3463
4397
|
NOTIFY_KINDS,
|
|
3464
4398
|
NO_PROGRESS_OBSERVED_STATUSES,
|
|
3465
4399
|
NPM_UPDATE_TAGS,
|
|
@@ -3469,14 +4403,27 @@ export {
|
|
|
3469
4403
|
OPERATOR_STATUS_REASON_VALUES,
|
|
3470
4404
|
OPERATOR_STATUS_VALUES,
|
|
3471
4405
|
OUTBOUND_MESSAGE_ORIGINS,
|
|
4406
|
+
OWNER_ABANDON_CONFIRM_KEY_PREFIX,
|
|
4407
|
+
OWNER_ABANDON_CONFIRM_OPTIONS,
|
|
4408
|
+
OWNER_ABANDON_CONFIRM_QUESTION,
|
|
3472
4409
|
P2P_SIGNAL_TYPES,
|
|
3473
4410
|
PROVIDER_FAILURES,
|
|
4411
|
+
QUOTA_BACKFILL_HORIZON_MS,
|
|
4412
|
+
QUOTA_RETRY_INFLIGHT_GRACE_MS,
|
|
3474
4413
|
QUOTA_SUPPORTED_PROVIDERS,
|
|
3475
4414
|
RECENT_SESSION_BUCKETS,
|
|
3476
4415
|
RECLAIMING_SEND_REFUSALS,
|
|
4416
|
+
RELAY_REPROBE_BASE_DELAY_MS,
|
|
4417
|
+
RELAY_REPROBE_JITTER_RATIO,
|
|
4418
|
+
RELAY_REPROBE_MAX_DELAY_MS,
|
|
4419
|
+
RELEASE_ACTORS,
|
|
3477
4420
|
RELEASE_CHANNELS,
|
|
4421
|
+
RELEASE_EVENT_TYPES,
|
|
4422
|
+
RELEASE_LIMITS,
|
|
4423
|
+
RELEASE_MEMBER_STATES,
|
|
3478
4424
|
REMOVED_MESH_TOOLS,
|
|
3479
4425
|
RETIRED_MESH_TOOLS,
|
|
4426
|
+
RelayReprobeScheduler,
|
|
3480
4427
|
SEND_POLICY_MODES,
|
|
3481
4428
|
SEND_REFUSAL_REASONS,
|
|
3482
4429
|
SERVER_STATUS_EVENT_NAMES,
|
|
@@ -3514,16 +4461,25 @@ export {
|
|
|
3514
4461
|
VERSION_UPDATE_REASONS,
|
|
3515
4462
|
VIEWER_TO_SHARED_SESSION_TYPES,
|
|
3516
4463
|
WORKER_BRANCH_STATES,
|
|
4464
|
+
WORKER_COMMITS_MAX,
|
|
4465
|
+
WORKER_DECISIONS_NEEDED_MAX,
|
|
3517
4466
|
WORKER_PROTOCOL_FOOTER_MARKER,
|
|
3518
4467
|
WORKER_REPORT_OUTCOMES,
|
|
4468
|
+
WORKER_REPORT_SUMMARY_MAX_CHARS,
|
|
3519
4469
|
WORKER_TOOLS,
|
|
4470
|
+
aggregateMissionGitState,
|
|
3520
4471
|
appendWorkerProtocolFooter,
|
|
3521
4472
|
argsCarryStatusProbeMarker,
|
|
4473
|
+
assessQuotaFreshness,
|
|
4474
|
+
boundEventPayload,
|
|
3522
4475
|
buildSlotProposal,
|
|
3523
4476
|
canonicalDaemonId,
|
|
4477
|
+
changelogMissionMarker,
|
|
4478
|
+
classifyChangelogSection,
|
|
3524
4479
|
classifySessionStatus,
|
|
3525
4480
|
compareDashboardWireVersion,
|
|
3526
4481
|
compareSemver,
|
|
4482
|
+
computeRelayReprobeDelay,
|
|
3527
4483
|
daemonIdsEquivalent,
|
|
3528
4484
|
decodeActiveWorkQueryRequest,
|
|
3529
4485
|
decodeActiveWorkQueryResponse,
|
|
@@ -3566,6 +4522,8 @@ export {
|
|
|
3566
4522
|
decodeQueueQueryResponse,
|
|
3567
4523
|
decodeQueueRequeueRequest,
|
|
3568
4524
|
decodeQueueRequeueResponse,
|
|
4525
|
+
decodeQueueReviseRequest,
|
|
4526
|
+
decodeQueueReviseResponse,
|
|
3569
4527
|
decodeRecordLocalRequest,
|
|
3570
4528
|
decodeRecordLocalResponse,
|
|
3571
4529
|
decodeRecoveryContextQueryRequest,
|
|
@@ -3585,6 +4543,7 @@ export {
|
|
|
3585
4543
|
decodeUserSessionToDashboard,
|
|
3586
4544
|
decodeViewerToSharedSession,
|
|
3587
4545
|
defaultProviderPriorityFromNodeFacts,
|
|
4546
|
+
deriveItemDedupeKey,
|
|
3588
4547
|
deriveProviderPriorityFromSlots,
|
|
3589
4548
|
deriveSlotsFromLegacy,
|
|
3590
4549
|
describeModelSelection,
|
|
@@ -3595,13 +4554,19 @@ export {
|
|
|
3595
4554
|
expandDaemonIdForms,
|
|
3596
4555
|
findOwnershipConflicts,
|
|
3597
4556
|
foldKeyedDoc,
|
|
4557
|
+
followedRemoteProjectKey,
|
|
4558
|
+
followerOpPermitted,
|
|
3598
4559
|
formatQuotaAccount,
|
|
3599
4560
|
hasGitStatusEvidence,
|
|
3600
4561
|
hasWorkerProtocolFooter,
|
|
3601
4562
|
interpolateString,
|
|
4563
|
+
isActionableProviderApproval,
|
|
4564
|
+
isAssistantFollowerAllowedOp,
|
|
3602
4565
|
isAssistantTool,
|
|
3603
4566
|
isBlockedStatus,
|
|
3604
4567
|
isBusyStatus,
|
|
4568
|
+
isCarryOverMissionRecord,
|
|
4569
|
+
isCarryOverMissionTitle,
|
|
3605
4570
|
isChunkType,
|
|
3606
4571
|
isCommitStrength,
|
|
3607
4572
|
isDaemonDirectCommandType,
|
|
@@ -3620,11 +4585,14 @@ export {
|
|
|
3620
4585
|
isFiniteNumber,
|
|
3621
4586
|
isIdleSessionState,
|
|
3622
4587
|
isInputEnvelopeWire,
|
|
4588
|
+
isLaunchDefaultRole,
|
|
4589
|
+
isLaunchDefaultSource,
|
|
3623
4590
|
isMeshDeliveryMode,
|
|
3624
4591
|
isMeshIndexQueryResponse,
|
|
3625
4592
|
isMeshMissionStatusValue,
|
|
3626
4593
|
isMeshP2PSignalType,
|
|
3627
4594
|
isMeshRecordPayload,
|
|
4595
|
+
isMeshReleaseChannel,
|
|
3628
4596
|
isMeshTaskDifficulty,
|
|
3629
4597
|
isMeshTaskMode,
|
|
3630
4598
|
isMeshTaskPriority,
|
|
@@ -3632,17 +4600,22 @@ export {
|
|
|
3632
4600
|
isMeshTerminalTaskStatus,
|
|
3633
4601
|
isMeshTopicEntry,
|
|
3634
4602
|
isMessageId,
|
|
4603
|
+
isMissionOutcome,
|
|
4604
|
+
isMissionRefContained,
|
|
3635
4605
|
isMissionUpsertResponse,
|
|
3636
4606
|
isModelAxisSource,
|
|
4607
|
+
isNativeMarkerRef,
|
|
3637
4608
|
isNonEmptyString,
|
|
3638
4609
|
isNotifyKind,
|
|
3639
4610
|
isOutboundMessage,
|
|
3640
4611
|
isOutboundMessageOrigin,
|
|
3641
4612
|
isP2PSignalType,
|
|
3642
4613
|
isPhantomDaemonEntry,
|
|
4614
|
+
isProviderQuestionBinding,
|
|
3643
4615
|
isRawDaemonDoId,
|
|
3644
4616
|
isReadyStatus,
|
|
3645
4617
|
isRecord,
|
|
4618
|
+
isReleaseStatus,
|
|
3646
4619
|
isSendPolicy,
|
|
3647
4620
|
isSendPolicyMode,
|
|
3648
4621
|
isSendRefusal,
|
|
@@ -3669,6 +4642,7 @@ export {
|
|
|
3669
4642
|
isWorkingStatus,
|
|
3670
4643
|
joinRepoPath,
|
|
3671
4644
|
launchModelSelectionValue,
|
|
4645
|
+
lintChangelogText,
|
|
3672
4646
|
machineCoreFromDaemonId,
|
|
3673
4647
|
makeTypeGuard,
|
|
3674
4648
|
measureWorstCaseChunkEnvelopeBytes,
|
|
@@ -3677,33 +4651,45 @@ export {
|
|
|
3677
4651
|
meshUtf8ByteLength,
|
|
3678
4652
|
meshWorkspacesEquivalent,
|
|
3679
4653
|
mintMessageId,
|
|
4654
|
+
minutesUntilQuotaCheck,
|
|
3680
4655
|
normalizeAuthOkLimits,
|
|
3681
4656
|
normalizeBrainSlot,
|
|
4657
|
+
normalizeDecisionInput,
|
|
3682
4658
|
normalizeDifficultyBrainMap,
|
|
4659
|
+
normalizeForDedupe,
|
|
3683
4660
|
normalizeGitStatus,
|
|
3684
4661
|
normalizeMeshNodeFacts,
|
|
3685
4662
|
normalizeMeshNodeId,
|
|
3686
4663
|
normalizeMeshSessionRecord,
|
|
3687
4664
|
normalizeMeshWorkspaceForCompare,
|
|
3688
4665
|
normalizeMissionBrief,
|
|
4666
|
+
normalizeMissionItemInput,
|
|
4667
|
+
normalizeMissionItemUpdate,
|
|
4668
|
+
normalizeMissionRefs,
|
|
4669
|
+
normalizeMissionSummary,
|
|
3689
4670
|
normalizeNodeCapabilitySlot,
|
|
3690
4671
|
normalizeNodeCapabilitySlots,
|
|
4672
|
+
normalizeOutcomeReason,
|
|
3691
4673
|
normalizeOwnedPaths,
|
|
4674
|
+
normalizeReportCommits,
|
|
3692
4675
|
normalizeSessionStatus,
|
|
3693
4676
|
normalizeThinkingLevel,
|
|
3694
4677
|
orderProvidersByBuiltinPreference,
|
|
3695
4678
|
parseJsonRecord,
|
|
4679
|
+
parseRoleLaunchSelection,
|
|
3696
4680
|
parseSemver,
|
|
3697
4681
|
parseSessionLaunchRecord,
|
|
3698
4682
|
pathsOverlap,
|
|
3699
4683
|
pickBestTransitGitStatus,
|
|
3700
4684
|
projectFileDiffRow,
|
|
3701
4685
|
projectTurnEvidenceEntry,
|
|
4686
|
+
providerApprovalSnapshot,
|
|
3702
4687
|
readBoolean,
|
|
3703
4688
|
readEnvelopeFields,
|
|
3704
4689
|
readGitSubmodules,
|
|
3705
4690
|
readNumber,
|
|
3706
4691
|
readOptionalRecord,
|
|
4692
|
+
readProviderDecision,
|
|
3707
4693
|
readRecord,
|
|
3708
4694
|
readString,
|
|
3709
4695
|
readStringArray,
|
|
@@ -3714,6 +4700,7 @@ export {
|
|
|
3714
4700
|
retiredMeshToolError,
|
|
3715
4701
|
sanitizeModelIdentifier,
|
|
3716
4702
|
sanitizeRefusalCode,
|
|
4703
|
+
sanitizeRemoteRepoIdentity,
|
|
3717
4704
|
scoreGitStatusCandidate,
|
|
3718
4705
|
scoreGitUpstreamFreshness,
|
|
3719
4706
|
sessionIdsEquivalent,
|
|
@@ -3724,6 +4711,8 @@ export {
|
|
|
3724
4711
|
summarizeGitShape,
|
|
3725
4712
|
supportsQuota,
|
|
3726
4713
|
touchedFilesOutsideOwnership,
|
|
4714
|
+
truncateMissionText,
|
|
4715
|
+
unwrapPastedContent,
|
|
3727
4716
|
withStatusProbeMarker
|
|
3728
4717
|
};
|
|
3729
4718
|
//# sourceMappingURL=index.mjs.map
|