@sema-agent/client-core 0.105.0 → 0.106.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +220 -0
  2. package/README.md +26 -11
  3. package/dist/adapt/arms.js +10 -1
  4. package/dist/adapter/activeRunSelfHeal.d.ts +13 -2
  5. package/dist/adapter/activeRunSelfHeal.js +80 -7
  6. package/dist/adapter/downstream/eventToSdkMessage.d.ts +0 -5
  7. package/dist/adapter/downstream/eventToSdkMessage.js +20 -19
  8. package/dist/adapter/downstream/terminalToSdkResult.js +2 -3
  9. package/dist/adapter/downstream/wiringManifestView.d.ts +1 -3
  10. package/dist/adapter/downstream/wiringManifestView.js +0 -1
  11. package/dist/adapter/runStream.js +3 -4
  12. package/dist/approvalReachWire.d.ts +1 -0
  13. package/dist/approvalReachWire.js +4 -1
  14. package/dist/approvalSeat.d.ts +21 -0
  15. package/dist/approvalSeat.js +73 -0
  16. package/dist/assistantInbox.d.ts +2 -0
  17. package/dist/assistantInbox.js +3 -0
  18. package/dist/checkpointRowVerdict.d.ts +23 -0
  19. package/dist/checkpointRowVerdict.js +89 -0
  20. package/dist/coreValuePorts.d.ts +12 -1
  21. package/dist/coreValuePorts.js +10 -0
  22. package/dist/decideFailureNote.js +3 -1
  23. package/dist/decideReceipt.d.ts +9 -0
  24. package/dist/decideReceipt.js +29 -1
  25. package/dist/declared/supportFloorDeclared.js +2 -2
  26. package/dist/deviceRebind.d.ts +7 -0
  27. package/dist/deviceRebind.js +39 -5
  28. package/dist/engineAddress.d.ts +3 -0
  29. package/dist/engineAddress.js +25 -0
  30. package/dist/engineDirectory.js +9 -17
  31. package/dist/engineErrorCodes.d.ts +8 -0
  32. package/dist/engineErrorCodes.js +8 -0
  33. package/dist/engineNoticeCodes.d.ts +26 -3
  34. package/dist/engineNoticeCodes.js +52 -7
  35. package/dist/engineRowRef.js +1 -1
  36. package/dist/errorSupplementRoles.js +2 -0
  37. package/dist/eventLeg.d.ts +2 -2
  38. package/dist/eventLeg.js +2 -1
  39. package/dist/fleet/fleetProjection.js +26 -5
  40. package/dist/generated/engineFactTables.d.ts +2 -1
  41. package/dist/generated/engineFactTables.js +3 -1
  42. package/dist/generated/engineNoticeTables.js +19 -4
  43. package/dist/generated/sdkFactTables.d.ts +3 -0
  44. package/dist/generated/sdkFactTables.js +15 -0
  45. package/dist/generated/settingsSchemaFns.d.ts +11 -0
  46. package/dist/generated/settingsSchemaFns.js +2 -1
  47. package/dist/generated/settingsSchemaSafetyMergeSpec.js +1 -1
  48. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -1
  49. package/dist/generated/settingsSchemaSettingsSources.js +22 -2
  50. package/dist/hitl/approvalLiveFace.d.ts +17 -0
  51. package/dist/hitl/approvalLiveFace.js +35 -0
  52. package/dist/hitl/approvalQueueRow.d.ts +21 -0
  53. package/dist/hitl/approvalQueueRow.js +69 -0
  54. package/dist/hitl/approvalsFeed.d.ts +5 -4
  55. package/dist/hitl/approvalsFeed.js +38 -6
  56. package/dist/hitl/askParkRowRouting.d.ts +4 -3
  57. package/dist/hitl/askParkRowRouting.js +15 -3
  58. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  59. package/dist/hitl/crashConverged.d.ts +5 -1
  60. package/dist/hitl/decisionConflict.js +2 -1
  61. package/dist/hitl/decisionRefusal.js +1 -1
  62. package/dist/hitl/decisionSend.d.ts +1 -0
  63. package/dist/hitl/decisionSend.js +14 -2
  64. package/dist/hitl/frameRouter.js +4 -5
  65. package/dist/hitl/hitlBridge.d.ts +1 -1
  66. package/dist/hitl/hitlBridge.js +26 -5
  67. package/dist/hitl/livePendingAsk.d.ts +5 -0
  68. package/dist/hitl/livePendingAsk.js +6 -1
  69. package/dist/hitl/planReviewCard.d.ts +2 -0
  70. package/dist/hitl/planReviewCard.js +21 -0
  71. package/dist/hitl/planReviewWire.d.ts +2 -2
  72. package/dist/hitl/planReviewWire.js +101 -36
  73. package/dist/hitl/sessionAllowRoute.d.ts +2 -0
  74. package/dist/hitl/sessionAllowRoute.js +7 -0
  75. package/dist/hitl/sessionPolicyWire.d.ts +1 -7
  76. package/dist/hitl/sessionPolicyWire.js +3 -43
  77. package/dist/hitl/subagentSource.d.ts +1 -0
  78. package/dist/hitl/subagentSource.js +13 -0
  79. package/dist/hitl/toolApprovalWire.d.ts +3 -2
  80. package/dist/hitl/toolApprovalWire.js +79 -37
  81. package/dist/hostSettingsSource.d.ts +4 -1
  82. package/dist/hostSettingsSource.js +11 -6
  83. package/dist/hostTurnSettings.d.ts +4 -5
  84. package/dist/hostTurnSettings.js +80 -19
  85. package/dist/i18n/messages.en.d.ts +35 -12
  86. package/dist/i18n/messages.en.js +36 -13
  87. package/dist/i18n/messages.zh.js +38 -13
  88. package/dist/index.d.ts +21 -2
  89. package/dist/index.js +11 -2
  90. package/dist/liveInitToolFace.js +0 -1
  91. package/dist/liveModelCatalog.d.ts +15 -0
  92. package/dist/liveModelCatalog.js +40 -0
  93. package/dist/mcpWireCaps.js +1 -1
  94. package/dist/modelCapabilityProbe.js +66 -33
  95. package/dist/ownKey.d.ts +0 -1
  96. package/dist/ownKey.js +0 -2
  97. package/dist/permissionsDeclaration.d.ts +2 -2
  98. package/dist/permissionsDeclaration.js +12 -14
  99. package/dist/projectSeed.d.ts +39 -0
  100. package/dist/projectSeed.js +80 -0
  101. package/dist/promptDelivery.js +1 -1
  102. package/dist/replayBody.d.ts +7 -6
  103. package/dist/replayBody.js +62 -7
  104. package/dist/request/taskRequest.js +3 -4
  105. package/dist/ruleCompileVerdict.d.ts +0 -2
  106. package/dist/ruleCompileVerdict.js +0 -31
  107. package/dist/ruleRefusalSentence.js +0 -3
  108. package/dist/runReattachPolicy.d.ts +3 -0
  109. package/dist/runReattachPolicy.js +15 -2
  110. package/dist/runTerminal.js +30 -8
  111. package/dist/sandboxWire.d.ts +0 -3
  112. package/dist/sandboxWire.js +0 -9
  113. package/dist/seam.d.ts +14 -7
  114. package/dist/seam.js +12 -0
  115. package/dist/seatContract.d.ts +57 -7
  116. package/dist/seatContract.js +132 -3
  117. package/dist/serverSupportRange.d.ts +18 -0
  118. package/dist/serverSupportRange.js +25 -0
  119. package/dist/sessionEngine.d.ts +156 -0
  120. package/dist/sessionEngine.js +464 -0
  121. package/dist/sessionMap.d.ts +11 -1
  122. package/dist/sessionMap.js +35 -9
  123. package/dist/sessionMemorySync.d.ts +31 -0
  124. package/dist/sessionMemorySync.js +95 -0
  125. package/dist/sessionRowTag.d.ts +4 -0
  126. package/dist/sessionRowTag.js +18 -0
  127. package/dist/settingsLayerAdmission.d.ts +1 -0
  128. package/dist/settingsLayerAdmission.js +4 -1
  129. package/dist/toolResult.js +1 -1
  130. package/dist/wireRefusalCopy.js +2 -6
  131. package/docs/INTEGRATION-CLIENTS.md +1022 -16
  132. package/package.json +5 -5
@@ -40,7 +40,6 @@ export const ENGINE_RUNNER_FACE = [
40
40
  'SendMessage',
41
41
  'ListAgents',
42
42
  'Skill',
43
- 'TaskOutput',
44
43
  'TaskStop',
45
44
  'ToolSearch',
46
45
  'Workflow',
@@ -22,6 +22,7 @@ export interface LiveModelCatalog {
22
22
  };
23
23
  droppedEntries?: readonly LiveModelDroppedEntry[];
24
24
  candidateRejected?: unknown;
25
+ modelPlane?: {} | null;
25
26
  }
26
27
  export declare function setLiveModelCatalog(next: LiveModelCatalog | null): void;
27
28
  export declare function setLiveModelCatalogRefresher(fn: (() => Promise<LiveModelCatalog | null>) | null): void;
@@ -103,6 +104,20 @@ export type ModelCandidateRejectedReading = {
103
104
  readonly kind: 'unreadable';
104
105
  };
105
106
  export declare function modelCandidateRejectedOf(catalog?: LiveModelCatalog | null): ModelCandidateRejectedReading;
107
+ export declare const MODEL_PLANE_SERVED_TABLES: readonly ["env", "catalog"];
108
+ export type ModelPlaneServedTable = (typeof MODEL_PLANE_SERVED_TABLES)[number];
109
+ export declare const MODEL_PLANE_CATALOG_STANCES: readonly ["absent", "adopted", "refused"];
110
+ export type ModelPlaneCatalogStance = (typeof MODEL_PLANE_CATALOG_STANCES)[number];
111
+ export type ModelPlaneReading = {
112
+ readonly kind: 'not_reported';
113
+ } | {
114
+ readonly kind: 'read';
115
+ readonly servedTable?: ModelPlaneServedTable;
116
+ readonly catalog?: ModelPlaneCatalogStance;
117
+ } | {
118
+ readonly kind: 'unreadable';
119
+ };
120
+ export declare function modelPlaneOf(catalog?: LiveModelCatalog | null): ModelPlaneReading;
106
121
  export declare function modelCandidateRejectedContent(reading: ModelCandidateRejectedReading, lang?: UiLanguage): string | undefined;
107
122
  export interface RoutePairingVerdict {
108
123
  verdict: 'ok' | 'broken' | 'unknown';
@@ -383,6 +383,43 @@ export function modelCandidateRejectedOf(catalog = getLiveModelCatalog()) {
383
383
  return unreadable;
384
384
  }
385
385
  }
386
+ export const MODEL_PLANE_SERVED_TABLES = Object.freeze(['env', 'catalog']);
387
+ export const MODEL_PLANE_CATALOG_STANCES = Object.freeze(['absent', 'adopted', 'refused']);
388
+ const inWords = (words, v) => typeof v === 'string' && words.includes(v);
389
+ export function modelPlaneOf(catalog = getLiveModelCatalog()) {
390
+ const unreadable = Object.freeze({ kind: 'unreadable' });
391
+ try {
392
+ if (catalog === null || typeof catalog !== 'object' || Array.isArray(catalog))
393
+ return Object.freeze({ kind: 'not_reported' });
394
+ if (!Object.hasOwn(catalog, 'modelPlane'))
395
+ return Object.freeze({ kind: 'not_reported' });
396
+ const d = Object.getOwnPropertyDescriptor(catalog, 'modelPlane');
397
+ if (d === undefined || !(Object.hasOwn(d, 'value')))
398
+ return unreadable;
399
+ const v = d.value;
400
+ if (v === undefined)
401
+ return Object.freeze({ kind: 'not_reported' });
402
+ if (v === null || typeof v !== 'object' || Array.isArray(v))
403
+ return unreadable;
404
+ const proto = Object.getPrototypeOf(v);
405
+ if (proto !== Object.prototype && proto !== null)
406
+ return unreadable;
407
+ const dServed = Object.getOwnPropertyDescriptor(v, 'servedTable');
408
+ const dStance = Object.getOwnPropertyDescriptor(v, 'catalog');
409
+ if ((dServed !== undefined && !Object.hasOwn(dServed, 'value')) || (dStance !== undefined && !Object.hasOwn(dStance, 'value')))
410
+ return unreadable;
411
+ const servedTable = dServed?.value;
412
+ const stance = dStance?.value;
413
+ return Object.freeze({
414
+ kind: 'read',
415
+ ...(inWords(MODEL_PLANE_SERVED_TABLES, servedTable) ? { servedTable } : {}),
416
+ ...(inWords(MODEL_PLANE_CATALOG_STANCES, stance) ? { catalog: stance } : {}),
417
+ });
418
+ }
419
+ catch {
420
+ return unreadable;
421
+ }
422
+ }
386
423
  const CONFIG_DOMAIN_WORD = /^[a-z][a-z0-9_.-]{0,63}$/;
387
424
  export function modelCandidateRejectedContent(reading, lang) {
388
425
  try {
@@ -429,6 +466,7 @@ export function readLiveModelCatalog(body) {
429
466
  const defaultModelKey = envelopeKey(body, 'defaultModel');
430
467
  const droppedKey = envelopeKey(body, 'droppedEntries');
431
468
  const candidateKey = envelopeKey(body, 'candidateRejected');
469
+ const planeKey = envelopeKey(body, 'modelPlane');
432
470
  const raw = modelsKey.present ? modelsKey.value : undefined;
433
471
  if (!Array.isArray(raw))
434
472
  return unreadableCatalog('models_not_array');
@@ -464,6 +502,8 @@ export function readLiveModelCatalog(body) {
464
502
  }
465
503
  if (candidateKey.present && candidateKey.value !== undefined)
466
504
  out.candidateRejected = frozenJsonCopyOf(candidateKey.value) ?? null;
505
+ if (planeKey.present && planeKey.value !== undefined)
506
+ out.modelPlane = frozenJsonCopyOf(planeKey.value) ?? null;
467
507
  return Object.freeze({ kind: 'read', catalog: Object.freeze(out), unreadableRows, ...(defaultModelMalformed ? { defaultModelMalformed: true } : {}) });
468
508
  }
469
509
  catch {
@@ -448,6 +448,6 @@ export function mcpAssertionHeaderNotSentNotice(specs) {
448
448
  const parts = distinct.slice(0, ASSERTION_NOTICE_NAMES_SHOWN).map((x) => `"${x}"`);
449
449
  if (distinct.length > ASSERTION_NOTICE_NAMES_SHOWN)
450
450
  parts.push(`+${distinct.length - ASSERTION_NOTICE_NAMES_SHOWN} more`);
451
- return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.139.0 accept this setting but do not send the header, ` +
451
+ return (`MCP servers that declare an assertion header (assertionHeader): ${parts.join(', ')} — server versions up to 7.144.0 accept this setting but do not send the header, ` +
452
452
  'and this client cannot tell whether the engine it uses sends it; a connector that requires the header will refuse requests from these servers');
453
453
  }
@@ -155,15 +155,48 @@ function isBusyStatus(status) {
155
155
  function looksBusyError(apiError) {
156
156
  return apiError !== undefined && /overload|rate.?limit|too many requests|too busy|server busy|capacity/i.test(apiError);
157
157
  }
158
- function apiErrorOf(parsed) {
159
- const e = parsed?.error;
160
- if (!e || typeof e !== 'object')
158
+ function wordOf(v) {
159
+ if (typeof v === 'string')
160
+ return v.trim() === '' ? undefined : v;
161
+ return typeof v === 'number' && Number.isFinite(v) && v !== 0 ? String(v) : undefined;
162
+ }
163
+ function hasContent(v, depth = 0) {
164
+ if (typeof v === 'string')
165
+ return v.trim() !== '';
166
+ if (typeof v === 'number')
167
+ return Number.isFinite(v) && v !== 0;
168
+ if (v === true)
169
+ return true;
170
+ if (v === null || typeof v !== 'object')
171
+ return false;
172
+ if (depth >= 2)
173
+ return true;
174
+ return (Array.isArray(v) ? v : Object.values(v)).some((x) => hasContent(x, depth + 1));
175
+ }
176
+ function errorBodyOf(parsed) {
177
+ if (parsed === null || typeof parsed !== 'object')
161
178
  return undefined;
162
- return [e.code ?? e.type, e.message].filter(Boolean).join(': ') || undefined;
179
+ const e = parsed.error;
180
+ const o = e;
181
+ if (o !== null && o !== undefined && typeof o === 'object' && !Array.isArray(o)) {
182
+ const legacy = [o.code ?? o.type, o.message].filter(Boolean).join(': ');
183
+ if (legacy !== '')
184
+ return { words: legacy, standard: true };
185
+ }
186
+ if (!hasContent(e))
187
+ return undefined;
188
+ if (typeof e !== 'object' || e === null) {
189
+ const words = wordOf(e);
190
+ return words === undefined ? { standard: false } : { words, standard: false };
191
+ }
192
+ if (Array.isArray(e))
193
+ return { standard: false };
194
+ const words = [wordOf(o?.code) ?? wordOf(o?.type) ?? wordOf(o?.status), wordOf(o?.message) ?? wordOf(o?.detail)].filter((x) => x !== undefined).join(': ');
195
+ return { ...(words !== '' ? { words } : {}), standard: false };
163
196
  }
164
- function extractApiError(body) {
197
+ function extractErrorBody(body) {
165
198
  try {
166
- return apiErrorOf(JSON.parse(body));
199
+ return errorBodyOf(JSON.parse(body));
167
200
  }
168
201
  catch {
169
202
  return undefined;
@@ -189,12 +222,10 @@ function shownApiError(raw, redact) {
189
222
  const shown = displayUntrusted(masked, { max: 200 });
190
223
  return shown.trim() === '' ? undefined : shown;
191
224
  }
192
- function looksLikeModelError(status, apiError) {
225
+ function namesModel(status, apiError) {
193
226
  if (status !== 400 && status !== 404 && status !== 422)
194
227
  return false;
195
- if (!apiError)
196
- return status === 404;
197
- return /model/i.test(apiError);
228
+ return apiError !== undefined && /model/i.test(apiError);
198
229
  }
199
230
  const MESSAGES_PATH = '/v1/messages';
200
231
  const COMPLETIONS_PATH = '/chat/completions';
@@ -204,33 +235,33 @@ function verdictRequestBody(modelId) {
204
235
  return JSON.stringify({ model: modelId ?? '', max_tokens: 1, messages: [{ role: 'user', content: 'hi' }], stream: true });
205
236
  }
206
237
  function judgeMessagesFailure(status, body, hasModelId, near, redact) {
207
- if (status === 401 || status === 403)
208
- return { verdict: 'auth', httpStatus: status, path: MESSAGES_PATH };
209
- const apiError = extractApiError(body);
238
+ const eb = extractErrorBody(body);
239
+ const apiError = eb?.words;
240
+ const standard = eb?.standard === true;
210
241
  const shown = shownApiError(apiError, redact);
211
242
  const ev = { httpStatus: status, path: MESSAGES_PATH, ...(shown !== undefined ? { apiError: shown } : {}) };
243
+ if (status === 401 || status === 403)
244
+ return { verdict: 'auth', ...ev };
212
245
  if (isBusyStatus(status) || looksBusyError(apiError))
213
246
  return { verdict: 'busy', ...ev };
214
- if (status === 404 && !apiError)
215
- return { verdict: 'shape', httpStatus: status, path: MESSAGES_PATH };
216
- if (looksLikeModelError(status, apiError)) {
217
- if (!hasModelId)
218
- return { verdict: 'ok', httpStatus: status, path: MESSAGES_PATH };
219
- return { verdict: 'model', ...ev, ...(near !== undefined ? { nearModelId: near } : {}) };
220
- }
221
- if (!hasModelId && status >= 400 && status < 500 && apiError)
247
+ if (!hasModelId && standard && status >= 400 && status < 500)
222
248
  return { verdict: 'ok', httpStatus: status, path: MESSAGES_PATH };
249
+ if (hasModelId && namesModel(status, apiError))
250
+ return { verdict: 'model', ...ev, ...(near !== undefined ? { nearModelId: near } : {}) };
251
+ if (status === 404 && !standard)
252
+ return { verdict: 'shape', ...ev };
223
253
  return { verdict: 'other', ...ev };
224
254
  }
225
255
  function judgeCompletionsFailure(status, body, near, redact) {
226
- if (status === 401 || status === 403)
227
- return { verdict: 'auth', httpStatus: status, path: COMPLETIONS_PATH };
228
- const apiError = extractApiError(body);
256
+ const eb = extractErrorBody(body);
257
+ const apiError = eb?.words;
229
258
  const shown = shownApiError(apiError, redact);
230
259
  const ev = { httpStatus: status, path: COMPLETIONS_PATH, ...(shown !== undefined ? { apiError: shown } : {}) };
260
+ if (status === 401 || status === 403)
261
+ return { verdict: 'auth', ...ev };
231
262
  if (isBusyStatus(status) || looksBusyError(apiError))
232
263
  return { verdict: 'busy', ...ev };
233
- if (looksLikeModelError(status, apiError))
264
+ if (namesModel(status, apiError) || (status === 404 && eb?.standard !== true))
234
265
  return { verdict: 'model', ...ev, ...(near !== undefined ? { nearModelId: near } : {}) };
235
266
  return { verdict: 'other', ...ev };
236
267
  }
@@ -318,9 +349,9 @@ function judgeJsonBody(text, contentType, api) {
318
349
  if (obj === null || typeof obj !== 'object')
319
350
  return { kind: 'not_model', contentType };
320
351
  const o = obj;
321
- const apiError = apiErrorOf(o);
322
- if (apiError !== undefined || o.type === 'error')
323
- return { kind: 'error', ...(apiError !== undefined ? { apiError } : {}) };
352
+ const eb = errorBodyOf(o);
353
+ if (eb !== undefined || o.type === 'error')
354
+ return { kind: 'error', ...(eb?.words !== undefined ? { apiError: eb.words } : {}) };
324
355
  const usage = (o.usage ?? null);
325
356
  if (api === 'anthropic-messages') {
326
357
  if (o.type !== 'message' && !Array.isArray(o.content))
@@ -365,9 +396,9 @@ function createAnswerScanner(contentType, api) {
365
396
  if (obj === null || typeof obj !== 'object')
366
397
  return;
367
398
  const o = obj;
368
- const apiError = apiErrorOf(o);
369
- if (ev === 'error' || o.type === 'error' || apiError !== undefined) {
370
- settled = { kind: 'error', ...(apiError !== undefined ? { apiError } : {}) };
399
+ const eb = errorBodyOf(o);
400
+ if (ev === 'error' || o.type === 'error' || eb !== undefined) {
401
+ settled = { kind: 'error', ...(eb?.words !== undefined ? { apiError: eb.words } : {}) };
371
402
  return;
372
403
  }
373
404
  if (isTokenFrame(o, api))
@@ -667,8 +698,10 @@ async function livenessOf(input) {
667
698
  }
668
699
  }
669
700
  const gate = await getCatalogText(fetchIt, urlOf(MODELS_PATH_OPENAI), getHeaders, catalogBudget, input.signal);
670
- if (gate.status === 401 || gate.status === 403)
671
- return { verdict: 'auth', httpStatus: gate.status, path: '/models' };
701
+ if (gate.status === 401 || gate.status === 403) {
702
+ const shown = shownApiError(extractErrorBody(gate.text)?.words, redact);
703
+ return { verdict: 'auth', httpStatus: gate.status, path: '/models', ...(shown !== undefined ? { apiError: shown } : {}) };
704
+ }
672
705
  if (isBusyStatus(gate.status))
673
706
  return { verdict: 'busy', httpStatus: gate.status, path: '/models' };
674
707
  if (gate.status < 200 || gate.status >= 300)
package/dist/ownKey.d.ts CHANGED
@@ -43,7 +43,6 @@ export interface PromptManifestSectionRow {
43
43
  locale?: string;
44
44
  variant?: string;
45
45
  contentHash?: string;
46
- slot?: string;
47
46
  }
48
47
  export interface PromptManifestIdentityRow {
49
48
  readonly artifact: string;
package/dist/ownKey.js CHANGED
@@ -221,7 +221,6 @@ export function promptManifestSectionViewOf(row) {
221
221
  const locale = str(o.locale);
222
222
  const variant = str(o.variant);
223
223
  const contentHash = band !== undefined ? str(o.contentHash) : undefined;
224
- const slot = str(o.slot);
225
224
  return {
226
225
  id,
227
226
  chars,
@@ -229,7 +228,6 @@ export function promptManifestSectionViewOf(row) {
229
228
  ...(locale !== undefined ? { locale } : {}),
230
229
  ...(variant !== undefined ? { variant } : {}),
231
230
  ...(contentHash !== undefined ? { contentHash } : {}),
232
- ...(slot !== undefined ? { slot } : {}),
233
231
  };
234
232
  }
235
233
  export function promptManifestIdentityOfFrame(frame) {
@@ -6,6 +6,7 @@ declare const SETTINGS_SOURCE_TIERS: Readonly<{
6
6
  readonly userSettings: "global";
7
7
  readonly localSettings: "project";
8
8
  readonly projectSettings: "project";
9
+ readonly foreignProjectSettings: "project";
9
10
  }>;
10
11
  declare const OFF_LADDER_ROWS: readonly [{
11
12
  readonly origin: "cliArg";
@@ -29,7 +30,6 @@ export interface PermissionsDeclarationInput {
29
30
  readonly cliDeny?: readonly string[];
30
31
  readonly settingsRead: 'clean' | 'partial' | 'unreadable';
31
32
  readonly clientOwnedServers?: readonly string[];
32
- readonly serverVersion?: string;
33
33
  }
34
34
  export interface PermissionsDeclarationBuckets {
35
35
  deny?: string[];
@@ -57,7 +57,7 @@ export interface HostPermissionsBuckets {
57
57
  export interface HostPermissionsDeclaration {
58
58
  permissions?: HostPermissionsBuckets;
59
59
  }
60
- export declare const PERMISSIONS_KEPT_REASONS: readonly ["allow_capability_off", "settings_read_not_clean", "empty_rule", "paren_in_tool_name", "retired_tool_name", "unprefixed_namespaced_name", "incomplete_protocol_name", "unminted_protocol_segment", "home_relative_path", "compile_refused", "content_form_not_grantable", "content_form_never_matches", "judge_failed", "duplicate", "voids_allow_list"];
60
+ export declare const PERMISSIONS_KEPT_REASONS: readonly ["allow_capability_off", "settings_read_not_clean", "empty_rule", "paren_in_tool_name", "retired_tool_name", "unprefixed_namespaced_name", "incomplete_protocol_name", "unminted_protocol_segment", "home_relative_path", "compile_refused", "content_form_not_grantable", "judge_failed", "duplicate", "voids_allow_list"];
61
61
  export type PermissionsKeptReason = (typeof PERMISSIONS_KEPT_REASONS)[number];
62
62
  export interface PermissionsKeptRule {
63
63
  rule: string;
@@ -1,6 +1,6 @@
1
1
  import { compileAllowList, hasCoreValuePort, protocolOf, ruleToolGrammarOf } from './coreValuePorts.js';
2
2
  import { clientOwnedServerPrefix, ruleToolNameVerdictOf } from './protocolSegment.js';
3
- import { ruleCompileVerdict, tightenEntryNeverMatches } from './ruleCompileVerdict.js';
3
+ import { ruleCompileVerdict } from './ruleCompileVerdict.js';
4
4
  import { allowRulesGate, allowWireForm } from './permissionsAllowGrantCapability.js';
5
5
  import { SETTINGS_IS_AT_LEAST } from './generated/settingsSchemaFns.js';
6
6
  import { THROWN_SLOT_UNREADABLE, asAssemblyRefusal, assemblyRefusalOf, isSlotCarrier, readThrownSlot, withAssemblyRefusal } from './wireFailureShape.js';
@@ -11,8 +11,9 @@ const SETTINGS_SOURCE_TIERS = Object.freeze({
11
11
  userSettings: 'global',
12
12
  localSettings: 'project',
13
13
  projectSettings: 'project',
14
+ foreignProjectSettings: 'project',
14
15
  });
15
- const SAME_TIER_ORDER = ['flagSettings', 'userSettings', 'localSettings', 'projectSettings'];
16
+ const SAME_TIER_ORDER = ['flagSettings', 'userSettings', 'localSettings', 'projectSettings', 'foreignProjectSettings'];
16
17
  const OFF_LADDER_ROWS = Object.freeze([
17
18
  { origin: 'cliArg', after: 'policySettings' },
18
19
  { origin: 'session', after: 'flagSettings' },
@@ -47,7 +48,6 @@ export const PERMISSIONS_KEPT_REASONS = Object.freeze([
47
48
  'home_relative_path',
48
49
  'compile_refused',
49
50
  'content_form_not_grantable',
50
- 'content_form_never_matches',
51
51
  'judge_failed',
52
52
  'duplicate',
53
53
  'voids_allow_list',
@@ -154,7 +154,7 @@ function tighteningWholeName(name, check) {
154
154
  const next = nameCheck(successor);
155
155
  return 'retired' in next || 'issue' in next ? name : successor;
156
156
  }
157
- function judgeList(rules, behavior, allowForm = 'grant', serverVersion) {
157
+ function judgeList(rules, behavior, allowForm = 'grant') {
158
158
  let portsChecked = false;
159
159
  return rules.map((rule) => {
160
160
  if (rule === '')
@@ -184,7 +184,7 @@ function judgeList(rules, behavior, allowForm = 'grant', serverVersion) {
184
184
  }
185
185
  const check = nameCheck(parsed.toolName);
186
186
  if (behavior !== 'allow')
187
- return tightenEntryNeverMatches(rule, serverVersion) ? kept('content_form_never_matches') : { sent: true, wire: rule };
187
+ return { sent: true, wire: rule };
188
188
  if ('retired' in check)
189
189
  return kept('retired_tool_name');
190
190
  if ('issue' in check)
@@ -244,7 +244,7 @@ function allowListVoiders(sent) {
244
244
  return 'unknown';
245
245
  }
246
246
  }
247
- function judgeBucket(raw, behavior, originOf, cli, settingsGate, allowForm = 'grant', dropWire, owned = [], serverVersion, layeredFrom) {
247
+ function judgeBucket(raw, behavior, originOf, cli, settingsGate, allowForm = 'grant', dropWire, owned = [], layeredFrom) {
248
248
  const firstSlot = new Map();
249
249
  for (const s of raw)
250
250
  if (!firstSlot.has(s.rule))
@@ -288,7 +288,7 @@ function judgeBucket(raw, behavior, originOf, cli, settingsGate, allowForm = 'gr
288
288
  };
289
289
  const appendGroup = (group, origin) => {
290
290
  const held = settingsGate !== undefined && !outsideSettingsFiles(origin);
291
- const fates = held ? group.map(() => kept(settingsGate)) : judgeList(group, behavior, allowForm, serverVersion);
291
+ const fates = held ? group.map(() => kept(settingsGate)) : judgeList(group, behavior, allowForm);
292
292
  group.forEach((r, k) => {
293
293
  const f = place(firstSlot.get(r), fates[k], origin);
294
294
  if (!fateOfRule.has(r))
@@ -412,19 +412,17 @@ function readAssemblyInput(input, caps) {
412
412
  origins = { ...(od ? { deny: od } : {}), ...(oa ? { ask: oa } : {}), ...(ol ? { allow: ol } : {}) };
413
413
  }
414
414
  const gate = allowRulesGate(caps, ownField(input, 'settingsRead', ''));
415
- const versionRaw = ownField(input, 'serverVersion', '');
416
- const serverVersion = typeof versionRaw === 'string' ? versionRaw : undefined;
417
- return { deny, ask, allow, cliDeny, ownedServers, origins, gate, serverVersion };
415
+ return { deny, ask, allow, cliDeny, ownedServers, origins, gate };
418
416
  }
419
417
  function judgeAssembly(read, caps, layered) {
420
- const { deny, ask, allow, cliDeny, ownedServers, origins, gate, serverVersion } = read;
418
+ const { deny, ask, allow, cliDeny, ownedServers, origins, gate } = read;
421
419
  const cliSlots = slotsOf(cliDeny, 'cliDeny');
422
- const cli = cliDeny === undefined ? undefined : { slots: cliSlots, fates: judgeList(cliDeny, 'deny', 'grant', serverVersion) };
420
+ const cli = cliDeny === undefined ? undefined : { slots: cliSlots, fates: judgeList(cliDeny, 'deny', 'grant') };
423
421
  const denySlots = slotsOf(deny, 'deny');
424
422
  const askSlots = slotsOf(ask, 'ask');
425
423
  const allowSlots = slotsOf(allow, 'allow');
426
- const denyJ = judgeBucket(denySlots, 'deny', origins.deny, cli, undefined, 'grant', undefined, [], serverVersion, layered?.deny);
427
- const askJ = judgeBucket(askSlots, 'ask', origins.ask, undefined, undefined, 'grant', undefined, [], serverVersion, layered?.ask);
424
+ const denyJ = judgeBucket(denySlots, 'deny', origins.deny, cli, undefined, 'grant', undefined, [], layered?.deny);
425
+ const askJ = judgeBucket(askSlots, 'ask', origins.ask, undefined, undefined, 'grant', undefined, [], layered?.ask);
428
426
  const allowForm = allowWireForm(caps) === 'layer' ? 'layer' : 'grant';
429
427
  const settingsGate = gate === 'settings_read_not_clean' ? 'settings_read_not_clean' : undefined;
430
428
  let allowJ = gate === 'capability_off'
@@ -0,0 +1,39 @@
1
+ import { ATTACHMENT_BOUND_ELSEWHERE, ATTACHMENT_BUNDLE_INVALID, ATTACHMENT_BUNDLE_LANE_NOT_ISOLATED, ATTACHMENT_BUNDLE_SEED_FIXED } from './engineErrorCodes.js';
2
+ import type { UiLanguage } from './env/uiLanguage.js';
3
+ export type ProjectSeedArm = 'handoff' | 'mirror' | 'sidecar';
4
+ export type ProjectSeedGate = {
5
+ readonly kind: 'ready';
6
+ readonly attachmentIds: readonly [string];
7
+ } | {
8
+ readonly kind: 'not_carried';
9
+ } | {
10
+ readonly kind: 'lane_not_isolated';
11
+ } | {
12
+ readonly kind: 'lane_unknown';
13
+ } | {
14
+ readonly kind: 'seed_missing';
15
+ };
16
+ export interface ProjectSeedGateInput {
17
+ readonly arm: ProjectSeedArm;
18
+ readonly caps: {} | null | undefined;
19
+ readonly attachmentId?: string | null;
20
+ }
21
+ export declare function projectSeedGateOf(input: ProjectSeedGateInput): ProjectSeedGate;
22
+ export type ProjectSeedRefusal = {
23
+ readonly code: typeof ATTACHMENT_BUNDLE_INVALID;
24
+ readonly reason?: string;
25
+ readonly path?: string;
26
+ } | {
27
+ readonly code: typeof ATTACHMENT_BUNDLE_LANE_NOT_ISOLATED;
28
+ readonly id?: string;
29
+ readonly lane?: string;
30
+ } | {
31
+ readonly code: typeof ATTACHMENT_BUNDLE_SEED_FIXED;
32
+ readonly id?: string;
33
+ } | {
34
+ readonly code: typeof ATTACHMENT_BOUND_ELSEWHERE;
35
+ readonly id?: string;
36
+ };
37
+ export declare function projectSeedRefusalOf(err: {} | null | undefined): ProjectSeedRefusal | null;
38
+ export declare function projectSeedRefusalContent(refusal: ProjectSeedRefusal, lang?: UiLanguage): string;
39
+ export declare function projectSeedGateContent(gate: ProjectSeedGate, lang?: UiLanguage): string | undefined;
@@ -0,0 +1,80 @@
1
+ import { ATTACHMENT_BOUND_ELSEWHERE, ATTACHMENT_BUNDLE_INVALID, ATTACHMENT_BUNDLE_LANE_NOT_ISOLATED, ATTACHMENT_BUNDLE_SEED_FIXED } from './engineErrorCodes.js';
2
+ import { projectExecutionLaneCapability } from './executionLaneCapability.js';
3
+ import { capForDisplay } from './fleetTaskDesc.js';
4
+ import { ownDataField } from './ownKey.js';
5
+ import { isSlotCarrier, readErrorString } from './wireFailureShape.js';
6
+ import { effectiveWireErrorCode } from './wireErrorTriage.js';
7
+ import { msg, renderMessage } from './i18n/translate.js';
8
+ export function projectSeedGateOf(input) {
9
+ try {
10
+ if (ownDataField(input, 'arm') !== 'handoff')
11
+ return Object.freeze({ kind: 'not_carried' });
12
+ const reading = projectExecutionLaneCapability(ownDataField(input, 'caps'));
13
+ const isolated = reading?.kind === 'present' ? reading.view.isolated : undefined;
14
+ if (isolated === false)
15
+ return Object.freeze({ kind: 'lane_not_isolated' });
16
+ if (isolated !== true)
17
+ return Object.freeze({ kind: 'lane_unknown' });
18
+ const id = ownDataField(input, 'attachmentId');
19
+ if (typeof id !== 'string' || id.length === 0)
20
+ return Object.freeze({ kind: 'seed_missing' });
21
+ return Object.freeze({ kind: 'ready', attachmentIds: Object.freeze([id]) });
22
+ }
23
+ catch {
24
+ return Object.freeze({ kind: 'not_carried' });
25
+ }
26
+ }
27
+ const nonEmpty = (v) => (typeof v === 'string' && v.length > 0 ? v : undefined);
28
+ export function projectSeedRefusalOf(err) {
29
+ try {
30
+ if (!isSlotCarrier(err))
31
+ return null;
32
+ const code = effectiveWireErrorCode(err);
33
+ const o = err;
34
+ if (code === ATTACHMENT_BUNDLE_INVALID) {
35
+ const reason = nonEmpty(readErrorString(o, 'reason'));
36
+ const path = nonEmpty(readErrorString(o, 'path'));
37
+ return Object.freeze({ code, ...(reason !== undefined ? { reason } : {}), ...(path !== undefined ? { path } : {}) });
38
+ }
39
+ if (code === ATTACHMENT_BUNDLE_LANE_NOT_ISOLATED) {
40
+ const id = nonEmpty(readErrorString(o, 'id'));
41
+ const lane = nonEmpty(readErrorString(o, 'lane'));
42
+ return Object.freeze({ code, ...(id !== undefined ? { id } : {}), ...(lane !== undefined ? { lane } : {}) });
43
+ }
44
+ if (code === ATTACHMENT_BUNDLE_SEED_FIXED || code === ATTACHMENT_BOUND_ELSEWHERE) {
45
+ const id = nonEmpty(readErrorString(o, 'id'));
46
+ return Object.freeze({ code, ...(id !== undefined ? { id } : {}) });
47
+ }
48
+ return null;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ const SEED_PATH_DISPLAY_MAX = 200;
55
+ export function projectSeedRefusalContent(refusal, lang) {
56
+ switch (refusal.code) {
57
+ case ATTACHMENT_BUNDLE_INVALID: {
58
+ const sentence = renderMessage(msg('session.projectSeed.invalid'), lang);
59
+ return refusal.path === undefined ? sentence : renderMessage(msg('session.projectSeed.invalidAt', { sentence, path: capForDisplay(refusal.path, SEED_PATH_DISPLAY_MAX) }), lang);
60
+ }
61
+ case ATTACHMENT_BUNDLE_LANE_NOT_ISOLATED:
62
+ return renderMessage(msg('session.projectSeed.laneNotIsolated'), lang);
63
+ case ATTACHMENT_BUNDLE_SEED_FIXED:
64
+ return renderMessage(msg('session.projectSeed.seedFixed'), lang);
65
+ case ATTACHMENT_BOUND_ELSEWHERE:
66
+ return renderMessage(msg('session.projectSeed.boundElsewhere'), lang);
67
+ }
68
+ }
69
+ export function projectSeedGateContent(gate, lang) {
70
+ switch (gate.kind) {
71
+ case 'lane_not_isolated':
72
+ return renderMessage(msg('session.projectSeed.laneNotIsolated'), lang);
73
+ case 'lane_unknown':
74
+ return renderMessage(msg('session.projectSeed.laneUnknown'), lang);
75
+ case 'seed_missing':
76
+ return renderMessage(msg('session.projectSeed.missing'), lang);
77
+ default:
78
+ return undefined;
79
+ }
80
+ }
@@ -149,7 +149,7 @@ function batchTiers(batch) {
149
149
  const inFull = new Set(full);
150
150
  return { full, partial: partial.filter((u) => !inFull.has(u)) };
151
151
  }
152
- const PRE_RUN_FRAME_TYPES = new Set(['meta', 'approval_request', 'approval_revoke']);
152
+ const PRE_RUN_FRAME_TYPES = new Set(['meta', 'approval_request', 'approval_revoke', 'approval_complete']);
153
153
  export function frameProvesDelivery(event) {
154
154
  if (typeof event !== 'object' || event === null)
155
155
  return false;
@@ -1,14 +1,15 @@
1
- export interface ReplayRowView {
2
- readonly status?: string;
3
- readonly errorCode?: string;
4
- readonly error?: string;
1
+ export interface RunReceiptView {
2
+ readonly taskId?: string;
5
3
  readonly sessionId?: string;
4
+ readonly status?: string;
6
5
  }
7
6
  export interface DoneResultView {
8
7
  readonly replay: boolean;
9
- readonly engine: unknown;
10
- readonly row?: ReplayRowView;
8
+ readonly receipt: boolean;
9
+ readonly body: unknown;
11
10
  }
11
+ export declare function terminalLayerOf<T>(carrier: T): T | object;
12
+ export declare function runRowSentenceOf<T>(carrier: T): string | undefined;
12
13
  export declare function doneResultView(result: unknown): DoneResultView;
13
14
  export declare function isReplayedTerminal(frame: object | null | undefined): boolean;
14
15
  export declare function isReplayMarked(message: object | null | undefined): boolean;
@@ -11,18 +11,73 @@ function guardedString(o, k) {
11
11
  const v = guarded(o, k);
12
12
  return typeof v === 'string' && v.length > 0 ? v : undefined;
13
13
  }
14
+ function guardedIn(o, k) {
15
+ try {
16
+ return k in o;
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ }
22
+ function carriesEngineResult(o) {
23
+ const stats = guardedIn(o, 'stats');
24
+ const terminal = guardedIn(o, 'terminal');
25
+ if (stats === true || terminal === true)
26
+ return true;
27
+ return stats === false && terminal === false ? false : undefined;
28
+ }
29
+ function engineResultLayerOf(carrier) {
30
+ try {
31
+ if (typeof carrier !== 'object' || carrier === null || Array.isArray(carrier))
32
+ return undefined;
33
+ const own = carriesEngineResult(carrier);
34
+ if (own !== false)
35
+ return own === true ? carrier : undefined;
36
+ const nested = guarded(carrier, 'result');
37
+ if (typeof nested !== 'object' || nested === null || Array.isArray(nested))
38
+ return undefined;
39
+ return carriesEngineResult(nested) === true ? nested : undefined;
40
+ }
41
+ catch {
42
+ return undefined;
43
+ }
44
+ }
45
+ function isRunReceiptShape(o) {
46
+ return guardedIn(o, 'activeTaskId') === false && guardedIn(o, 'taskId') === true;
47
+ }
48
+ export function terminalLayerOf(carrier) {
49
+ return engineResultLayerOf(carrier) ?? carrier;
50
+ }
51
+ export function runRowSentenceOf(carrier) {
52
+ try {
53
+ if (typeof carrier !== 'object' || carrier === null || Array.isArray(carrier))
54
+ return undefined;
55
+ if (engineResultLayerOf(carrier) !== undefined)
56
+ return undefined;
57
+ if (!isRunReceiptShape(carrier))
58
+ return undefined;
59
+ return guardedString(carrier, 'error');
60
+ }
61
+ catch {
62
+ return undefined;
63
+ }
64
+ }
14
65
  export function doneResultView(result) {
15
66
  if (typeof result !== 'object' || result === null || Array.isArray(result))
16
- return { replay: false, engine: result };
17
- if (guarded(result, 'replay') !== true)
18
- return { replay: false, engine: result };
19
- const row = {};
20
- for (const k of ['status', 'errorCode', 'error', 'sessionId']) {
67
+ return { replay: false, receipt: false, body: result };
68
+ const replay = guarded(result, 'replay') === true;
69
+ const engine = engineResultLayerOf(result);
70
+ if (engine !== undefined)
71
+ return { replay, receipt: false, body: engine };
72
+ if (!isRunReceiptShape(result))
73
+ return { replay, receipt: false, body: result };
74
+ const view = {};
75
+ for (const k of ['taskId', 'sessionId', 'status']) {
21
76
  const v = guardedString(result, k);
22
77
  if (v !== undefined)
23
- row[k] = v;
78
+ view[k] = v;
24
79
  }
25
- return { replay: true, engine: guarded(result, 'result'), row };
80
+ return { replay, receipt: true, body: Object.freeze(view) };
26
81
  }
27
82
  export function isReplayedTerminal(frame) {
28
83
  if (frame === null || typeof frame !== 'object' || Array.isArray(frame))