@sema-agent/client-core 0.108.0 → 0.110.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 (179) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +77 -40
  3. package/dist/adapt/arms.js +41 -13
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +37 -16
  6. package/dist/adapter/activeRunSelfHeal.js +1 -1
  7. package/dist/adapter/downstream/eventToSdkMessage.js +11 -5
  8. package/dist/agentSession/engineAgentRegistryRead.js +2 -0
  9. package/dist/bashExitReading.d.ts +12 -0
  10. package/dist/bashExitReading.js +44 -0
  11. package/dist/checkpointRowVerdict.d.ts +1 -1
  12. package/dist/checkpointRowVerdict.js +4 -2
  13. package/dist/compensations.js +1 -1
  14. package/dist/declared/supportFloorDeclared.js +1 -1
  15. package/dist/displayUntrusted.js +132 -14
  16. package/dist/engineAgentAbsence.d.ts +2 -0
  17. package/dist/engineAgentAbsence.js +28 -0
  18. package/dist/engineErrorCodes.d.ts +7 -0
  19. package/dist/engineErrorCodes.js +7 -0
  20. package/dist/engineHealthFacts.d.ts +26 -0
  21. package/dist/engineHealthFacts.js +63 -4
  22. package/dist/engineInlineTaskStats.d.ts +4 -3
  23. package/dist/engineInlineTaskStats.js +18 -2
  24. package/dist/engineNoticeCodes.d.ts +138 -0
  25. package/dist/engineNoticeCodes.js +662 -55
  26. package/dist/engineRepoint.d.ts +140 -0
  27. package/dist/engineRepoint.js +285 -0
  28. package/dist/engineRowRef.js +2 -0
  29. package/dist/engineSessionMessages.d.ts +2 -1
  30. package/dist/engineSessionMessages.js +5 -0
  31. package/dist/errorSupplementRoles.js +5 -1
  32. package/dist/fleet/fleetProjection.js +3 -2
  33. package/dist/fleetTaskDesc.js +3 -3
  34. package/dist/generated/engineFactTables.d.ts +3 -0
  35. package/dist/generated/engineFactTables.js +18 -0
  36. package/dist/generated/engineNoticeTables.js +3 -0
  37. package/dist/generated/sdkFactTables.d.ts +1 -0
  38. package/dist/generated/sdkFactTables.js +4 -0
  39. package/dist/hitl/approvalAskers.d.ts +6 -0
  40. package/dist/hitl/approvalAskers.js +30 -0
  41. package/dist/hitl/approvalCardReasons.js +25 -4
  42. package/dist/hitl/approvalRequestFrameReading.d.ts +21 -0
  43. package/dist/hitl/approvalRequestFrameReading.js +90 -0
  44. package/dist/hitl/approvalResolution.d.ts +8 -1
  45. package/dist/hitl/approvalResolution.js +4 -0
  46. package/dist/hitl/approvalsFeed.js +1 -1
  47. package/dist/hitl/askGateWire.js +0 -2
  48. package/dist/hitl/askParkRowRouting.js +5 -2
  49. package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
  50. package/dist/hitl/automaticAnswerVerdict.js +18 -4
  51. package/dist/hitl/decisionConflict.d.ts +2 -1
  52. package/dist/hitl/decisionConflict.js +10 -4
  53. package/dist/hitl/decisionRefusal.js +1 -0
  54. package/dist/hitl/decisionSend.d.ts +3 -0
  55. package/dist/hitl/decisionSend.js +29 -11
  56. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  57. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  58. package/dist/hitl/frameRouter.js +13 -19
  59. package/dist/hitl/gateLedger.d.ts +0 -4
  60. package/dist/hitl/gateLedger.js +0 -19
  61. package/dist/hitl/hitlBridge.d.ts +5 -0
  62. package/dist/hitl/hitlBridge.js +13 -9
  63. package/dist/hitl/hitlHostSurface.d.ts +1 -0
  64. package/dist/hitl/hitlHostSurface.js +7 -2
  65. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  66. package/dist/hitl/hostWithdrawal.js +38 -0
  67. package/dist/hitl/livePendingAsk.js +17 -16
  68. package/dist/hitl/localAllowRule.js +2 -1
  69. package/dist/hitl/noAllowCause.d.ts +1 -1
  70. package/dist/hitl/noAllowCause.js +4 -2
  71. package/dist/hitl/parkExpiryJudgements.js +26 -1
  72. package/dist/hitl/parkOwnership.d.ts +2 -0
  73. package/dist/hitl/parkOwnership.js +48 -8
  74. package/dist/hitl/parkResolver.js +32 -16
  75. package/dist/hitl/parkedUnresumable.d.ts +13 -0
  76. package/dist/hitl/parkedUnresumable.js +80 -0
  77. package/dist/hitl/permissionRuleScope.d.ts +4 -0
  78. package/dist/hitl/permissionRuleScope.js +31 -0
  79. package/dist/hitl/persistedRulesWire.d.ts +2 -0
  80. package/dist/hitl/persistedRulesWire.js +13 -12
  81. package/dist/hitl/planReviewWire.js +14 -4
  82. package/dist/hitl/sessionAllowRoute.js +5 -4
  83. package/dist/hitl/sessionPolicyWire.js +6 -4
  84. package/dist/hitl/standingRows.d.ts +2 -5
  85. package/dist/hitl/standingRows.js +30 -15
  86. package/dist/hitl/toolApprovalWire.d.ts +42 -9
  87. package/dist/hitl/toolApprovalWire.js +267 -44
  88. package/dist/hooksWireCaps.js +35 -4
  89. package/dist/hostSettingsSource.js +2 -0
  90. package/dist/hostTurnSettings.d.ts +10 -4
  91. package/dist/hostTurnSettings.js +112 -5
  92. package/dist/i18n/messages.en.d.ts +251 -0
  93. package/dist/i18n/messages.en.js +254 -2
  94. package/dist/i18n/messages.zh.js +264 -2
  95. package/dist/index.d.ts +48 -12
  96. package/dist/index.js +29 -7
  97. package/dist/inheritEnvCapability.js +2 -0
  98. package/dist/inputAuthor.d.ts +16 -0
  99. package/dist/inputAuthor.js +44 -0
  100. package/dist/interruptRefusalNote.d.ts +2 -0
  101. package/dist/interruptRefusalNote.js +17 -0
  102. package/dist/liveModelCatalog.d.ts +2 -0
  103. package/dist/liveModelCatalog.js +21 -7
  104. package/dist/liveQuestionStore.d.ts +4 -1
  105. package/dist/liveQuestionStore.js +12 -3
  106. package/dist/localEngineJudge.d.ts +75 -0
  107. package/dist/localEngineJudge.js +242 -0
  108. package/dist/localEngineOccupancy.d.ts +88 -0
  109. package/dist/localEngineOccupancy.js +269 -0
  110. package/dist/localEngineSeatReading.d.ts +29 -0
  111. package/dist/localEngineSeatReading.js +294 -0
  112. package/dist/localEngineSpawn.d.ts +113 -0
  113. package/dist/localEngineSpawn.js +486 -0
  114. package/dist/localEngineStep.d.ts +286 -0
  115. package/dist/localEngineStep.js +1086 -0
  116. package/dist/localEngineStopLadder.d.ts +29 -0
  117. package/dist/localEngineStopLadder.js +139 -0
  118. package/dist/localEngineSwapCard.d.ts +43 -0
  119. package/dist/localEngineSwapCard.js +205 -0
  120. package/dist/localEngineTiming.d.ts +8 -0
  121. package/dist/localEngineTiming.js +8 -0
  122. package/dist/mcpEngineLeg.d.ts +3 -0
  123. package/dist/mcpEngineLeg.js +38 -1
  124. package/dist/mcpPanel.js +2 -0
  125. package/dist/mcpReconnect.d.ts +9 -1
  126. package/dist/mcpReconnect.js +132 -20
  127. package/dist/mcpWireCaps.js +2 -2
  128. package/dist/memoryEntriesWire.d.ts +1 -1
  129. package/dist/memoryEntriesWire.js +5 -0
  130. package/dist/modelCapabilityProbe.js +4 -3
  131. package/dist/modsFace.d.ts +8 -1
  132. package/dist/modsFace.js +27 -0
  133. package/dist/noticePresentation.d.ts +2 -0
  134. package/dist/noticePresentation.js +79 -1
  135. package/dist/notifications.d.ts +17 -6
  136. package/dist/notifications.js +67 -19
  137. package/dist/ownKey.d.ts +5 -0
  138. package/dist/ownKey.js +8 -1
  139. package/dist/peerFrames.d.ts +40 -2
  140. package/dist/peerFrames.js +158 -3
  141. package/dist/pluginHooksWire.d.ts +2 -1
  142. package/dist/pluginHooksWire.js +56 -1
  143. package/dist/replayBody.js +10 -2
  144. package/dist/request/taskRequest.d.ts +5 -0
  145. package/dist/request/taskRequest.js +138 -21
  146. package/dist/resumeRefusalCopy.d.ts +1 -3
  147. package/dist/resumeRefusalCopy.js +2 -1
  148. package/dist/retryStatus.d.ts +2 -2
  149. package/dist/retryStatus.js +2 -0
  150. package/dist/ruleReadings.js +1 -1
  151. package/dist/seam.d.ts +24 -2
  152. package/dist/seam.js +15 -2
  153. package/dist/seatContract.d.ts +125 -10
  154. package/dist/seatContract.js +373 -7
  155. package/dist/sessionBackground.js +4 -1
  156. package/dist/sessionBackgroundHandoff.js +2 -1
  157. package/dist/sessionEngine.d.ts +2 -0
  158. package/dist/sessionEngine.js +111 -0
  159. package/dist/sessionMemoryStatus.d.ts +2 -1
  160. package/dist/sessionSyncFileHistory.d.ts +4 -0
  161. package/dist/sessionSyncFileHistory.js +28 -0
  162. package/dist/sseIdleTriage.d.ts +13 -1
  163. package/dist/sseIdleTriage.js +24 -6
  164. package/dist/subagent/engineSubagentTail.js +6 -0
  165. package/dist/subagentContentStore.d.ts +12 -0
  166. package/dist/subagentContentStore.js +72 -11
  167. package/dist/terminalStatuses.d.ts +1 -0
  168. package/dist/terminalStatuses.js +4 -1
  169. package/dist/toolResult.js +18 -5
  170. package/dist/turnFailurePresentation.js +9 -2
  171. package/dist/typePins.d.ts +11 -0
  172. package/dist/usageAnalytics.d.ts +17 -0
  173. package/dist/usageAnalytics.js +44 -2
  174. package/dist/wireFailureShape.d.ts +22 -5
  175. package/dist/wireFailureShape.js +47 -26
  176. package/dist/wireRefusalCopy.d.ts +31 -1
  177. package/dist/wireRefusalCopy.js +167 -2
  178. package/docs/INTEGRATION-CLIENTS.md +3269 -21
  179. package/package.json +5 -5
@@ -1,7 +1,7 @@
1
1
  import { engineCapNestedTrue, engineCapState, engineCapString, engineCapValue } from './engineCapsCache.js';
2
2
  import { hooksReaderNotReadKeys } from './hooksReaderGenerations.js';
3
3
  import { msg, renderMessage } from './i18n/translate.js';
4
- import { capForDisplay, collapseLabel } from './fleetTaskDesc.js';
4
+ import { capForDisplay } from './fleetTaskDesc.js';
5
5
  import { hostLog } from './host.js';
6
6
  import { faultText } from './hostCallbackGuard.js';
7
7
  import { HostSettingsSourceShapeError, MANAGED_READING_DISPOSITIONS, mergedBooleanOf, nonManagedLayerDown, readHostSettingsOnce } from './hostSettingsSource.js';
@@ -9,7 +9,7 @@ import { admittedLayers, layerAdmissionWord } from './settingsLayerAdmission.js'
9
9
  import { guardedRead, readOwnDataValue } from './ownKey.js';
10
10
  import { HOOK_SETTINGS_SOURCE_TEXT, hooksSalvageMaskOf, salvageSettingsHooksEntries, settingsHooksSalvageNotice } from './settingsHooksSalvage.js';
11
11
  import { submissionOriginOf } from './request/submissionIdentity.js';
12
- import { createSettingsHookJudge, decidePluginHooks, decideSessionHooks, dedupeSettingsHookGroups, filterSettingsHookGroups, hooksWirePlanShapeOf, occupancyOf, } from './pluginHooksWire.js';
12
+ import { createSettingsHookJudge, decidePluginHooks, decideSessionHooks, dedupeSettingsHookGroups, filterSettingsHookGroups, hooksWirePlanShapeOf, isEngineFiredHookEvent, occupancyOf, } from './pluginHooksWire.js';
13
13
  import { MAX_HOOK_NOTICE_TEXT_CHARS } from './notifications.js';
14
14
  import { applyHttpHookPolicy, httpHookAdmittedSources, readHttpHookPolicy, wireHasHttpEntry } from './httpHookPolicy.js';
15
15
  import { goalStopHookMatcher, __resetGoalStopHookForTests } from './goalStopHook.js';
@@ -300,6 +300,32 @@ function withheldRowsOf(candidates, trust, layers) {
300
300
  }
301
301
  return rows;
302
302
  }
303
+ function closedDropRowsOf(source, doc, reason) {
304
+ const rows = [];
305
+ try {
306
+ const hooks = readOwnDataValue(doc, 'hooks');
307
+ if (typeof hooks !== 'object' || hooks === null || Array.isArray(hooks))
308
+ return rows;
309
+ for (const event of Object.keys(hooks)) {
310
+ const groups = readOwnDataValue(hooks, event);
311
+ if (!Array.isArray(groups))
312
+ continue;
313
+ groups.forEach((group, groupIndex) => {
314
+ if (typeof group !== 'object' || group === null)
315
+ return;
316
+ const entries = readOwnDataValue(group, 'hooks');
317
+ if (!Array.isArray(entries))
318
+ return;
319
+ entries.forEach((_entry, hookIndex) => {
320
+ rows.push({ source, event, groupIndex, hookIndex, reason, notRun: true });
321
+ });
322
+ });
323
+ }
324
+ }
325
+ catch {
326
+ }
327
+ return rows;
328
+ }
303
329
  function buildHooksWirePlan(read, engine, shellRuns, promptAuthoredByUser, suppressedLocally, readerNotRead, compactionOnShell = false) {
304
330
  const settingsDropped = [];
305
331
  const settingsVerdicts = [];
@@ -333,6 +359,8 @@ function buildHooksWirePlan(read, engine, shellRuns, promptAuthoredByUser, suppr
333
359
  });
334
360
  const closedPlan = (reason) => {
335
361
  closedBy = reason;
362
+ for (const source of ALL_HOOK_SOURCES)
363
+ settingsDropped.push(...closedDropRowsOf(source, read.layers[source].doc, reason));
336
364
  sessionReader = read.sessionHooks.state;
337
365
  const pr = read.plugins;
338
366
  if (pr.reading === undefined)
@@ -472,6 +500,8 @@ function buildHooksWirePlan(read, engine, shellRuns, promptAuthoredByUser, suppr
472
500
  settingsDropped.push(...kept.drops);
473
501
  settingsVerdicts.push(...kept.verdicts);
474
502
  settingsExcluded.push(...kept.excluded);
503
+ if (!isEngineFiredHookEvent(event))
504
+ continue;
475
505
  settingsStripped += kept.stripped;
476
506
  if (kept.groups.length === 0)
477
507
  continue;
@@ -555,8 +585,9 @@ export function fleetHookFailureNoticeCapable(baseUrl) {
555
585
  export const HOOK_FAILURE_WARN_PREFIX = 'Hook error';
556
586
  export function hookFailureNoticeText(n) {
557
587
  const code = n.exitCode !== undefined ? `exit ${n.exitCode}` : n.reason;
558
- const name = collapseLabel(n.hookName);
559
- const tail = n.stderr !== undefined ? `: ${collapseLabel(n.stderr)}` : '';
588
+ const fold = (s) => s.replace(/\s+/g, ' ').trim();
589
+ const name = fold(n.hookName);
590
+ const tail = n.stderr !== undefined ? `: ${fold(n.stderr)}` : '';
560
591
  const line = `${HOOK_FAILURE_WARN_PREFIX}: ${name} (${code})${tail}`;
561
592
  return capForDisplay(line, MAX_HOOK_NOTICE_TEXT_CHARS);
562
593
  }
@@ -550,6 +550,8 @@ export function adoptHostSettingsRead(read, session, allowAdmitted = () => true,
550
550
  return true;
551
551
  if (LOADED.has(c.status))
552
552
  return false;
553
+ if (c.status === 'absent')
554
+ return false;
553
555
  return !(c.status === 'empty' && c.emptyKind === 'empty-object');
554
556
  });
555
557
  trusted = !newIssue && !lost && !anyMalformed;
@@ -1,22 +1,22 @@
1
- import type { TaskRequest } from '@sema-agent/sdk';
1
+ import type { SemaSettings, TaskRequest } from '@sema-agent/sdk';
2
2
  import type { WireHooksConfig } from './finalVerifyWire.js';
3
3
  import type { memoryOffDeclared as MemoryOffDeclared } from './request/taskRequest.js';
4
4
  import type { EnvLike } from './hostEnv.js';
5
5
  import { type SettingsDocument } from './host.js';
6
- import type { HooksWirePlan, HooksWirePlanOptions } from './pluginHooksWire.js';
6
+ import { type HooksWirePlan, type HooksWirePlanOptions } from './pluginHooksWire.js';
7
7
  import { type HostSettingsLayer, type HostSettingsSession, type HostSettingsSource } from './hostSettingsSource.js';
8
8
  import { type SubmissionIdentity } from './request/submissionIdentity.js';
9
9
  import { type WebSearchApiKeyFor } from './webSearchWireCaps.js';
10
10
  import { type FileHistoryCaptureReading } from './fileHistoryCaptureCapability.js';
11
11
  import { type PermissionsAllowGrantReading } from './permissionsAllowGrantCapability.js';
12
- export declare const HOST_SUPPLIED_KEYS: readonly ["settings.hooks", "settings.resolved", "settings.webSearch", "settings.outputStyle", "memory", "fileHistory"];
12
+ export declare const HOST_SUPPLIED_KEYS: readonly ["settings.hooks", "settings.resolved", "settings.webSearch", "settings.outputStyle", "memory", "fileHistory", "settings.env"];
13
13
  export type HostSuppliedKey = (typeof HOST_SUPPLIED_KEYS)[number];
14
14
  export declare const HOST_SETTING_CAUSES: readonly ["carried", "entries_dropped", "source_rejected", "projection_failed", "source_unreadable", "empty", "no_source", "host_port_missing", "value_malformed", "held_previous", "policy_withheld"];
15
15
  export type HostSettingCause = (typeof HOST_SETTING_CAUSES)[number];
16
16
  export declare const HOST_SETTING_DISPOSITIONS: readonly ["carry", "carry_partial", "withhold_notice", "withhold_by_policy", "hold_for_consent", "refuse_turn", "unwired", "nothing_to_carry"];
17
17
  export type HostSettingDisposition = (typeof HOST_SETTING_DISPOSITIONS)[number];
18
18
  export type HostSettingPlane = 'turn' | 'session' | 'diagnostic';
19
- export type HostSettingNoticeId = 'HS-UNWIRED' | 'HS-MANAGED-REJECTED' | 'HS-PROJECTION' | 'HS-SOURCE-UNREADABLE' | 'HS-WEBSEARCH-MALFORMED' | 'HS-SWITCH-MALFORMED' | 'HS-FILEHISTORY-UNJUDGED' | 'HS-FILEHISTORY-RESTORE' | 'HS-MANAGED-UNREADABLE' | 'HS-LAYER-NOT-LOADED' | 'HS-HELD-PREVIOUS' | 'HS-STYLE-MISSING' | 'HS-STYLE-SAFE' | 'HS-LAYER-PARTS-UNREAD';
19
+ export type HostSettingNoticeId = 'HS-UNWIRED' | 'HS-MANAGED-REJECTED' | 'HS-PROJECTION' | 'HS-SOURCE-UNREADABLE' | 'HS-WEBSEARCH-MALFORMED' | 'HS-SWITCH-MALFORMED' | 'HS-FILEHISTORY-UNJUDGED' | 'HS-FILEHISTORY-RESTORE' | 'HS-MANAGED-UNREADABLE' | 'HS-LAYER-NOT-LOADED' | 'HS-HELD-PREVIOUS' | 'HS-STYLE-MISSING' | 'HS-STYLE-SAFE' | 'HS-LAYER-PARTS-UNREAD' | 'HS-STYLE-OVERSIZE' | 'HS-STYLE-UNREADABLE';
20
20
  export interface HostSettingRow {
21
21
  readonly key: HostSuppliedKey;
22
22
  readonly cause: HostSettingCause;
@@ -61,6 +61,9 @@ export interface HostTurnSettingsSources {
61
61
  readonly reading: FileHistoryCaptureReading;
62
62
  readonly captureOff: boolean;
63
63
  } | 'none';
64
+ readonly env: {
65
+ readonly env: EnvLike;
66
+ } | 'none';
64
67
  }
65
68
  export interface HostWebSearchSource {
66
69
  readonly env: EnvLike;
@@ -83,6 +86,7 @@ export interface HostSettingsCarried {
83
86
  readonly outputStyle?: string;
84
87
  readonly memory?: TaskRequest['memory'];
85
88
  readonly fileHistory?: TaskRequest['fileHistory'];
89
+ readonly env?: NonNullable<SemaSettings['env']>;
86
90
  }
87
91
  export interface HostOutputStyleFacts {
88
92
  readonly name: string;
@@ -108,6 +112,7 @@ export interface HostSettingsHeld {
108
112
  };
109
113
  readonly version: string;
110
114
  }
115
+ export declare function hookEnvNamesOf(hooks: unknown): readonly string[];
111
116
  export interface HostTurnSettingsJudges {
112
117
  readonly materialize: HostResolvedMaterializer;
113
118
  readonly memoryOffDeclared: typeof MemoryOffDeclared;
@@ -137,6 +142,7 @@ export declare function hostSettingsAcceptCurrent(product: HostTurnSettings, con
137
142
  export declare function hostSettingsSelfCheck(product: HostTurnSettings): readonly HostSuppliedKey[];
138
143
  export declare const hostProjectionNotice: () => HostSettingNotice;
139
144
  export declare const hostFileHistoryRestoreNotice: () => HostSettingNotice;
145
+ export declare const hostStyleNotAppliedNotice: (cause: "oversize" | "unreadable", limit: number) => HostSettingNotice;
140
146
  export declare class HostSettingsRefused extends Error {
141
147
  readonly notice: HostSettingNotice;
142
148
  constructor(n: HostSettingNotice);
@@ -1,5 +1,6 @@
1
1
  import { SETTINGS_CLASSIFY_HOOKS_CONFIG } from './generated/settingsSchemaFns.js';
2
2
  import { hostLog } from './host.js';
3
+ import { isEngineFiredHookEvent } from './pluginHooksWire.js';
3
4
  import { layerNotAppliedRefusesTurn, salvageSettingsHooksEntries } from './settingsHooksSalvage.js';
4
5
  import { ADOPTED_LAYERS, HOST_SETTINGS_LAYERS, HostSettingsSourceShapeError, TIGHTEN_ONLY_HOST_SETTINGS_LAYERS, permissionBucketOf, permissionRulesOf, MANAGED_READING_DISPOSITIONS, adoptHostSettingsRead, mintHostSettingsSession, readHostSettingsOnce, remintSameContent, sessionSnapshotOf, settingsValueOf, sourceOfRead, } from './hostSettingsSource.js';
5
6
  import { hooksWirePlan } from './hooksWireCaps.js';
@@ -13,8 +14,8 @@ import { assemblyRefusalOf } from './wireFailureShape.js';
13
14
  import { permissionRuleLayersOn } from './permissionsAllowGrantCapability.js';
14
15
  import { layerAdmissionReading, layerAdmitted } from './settingsLayerAdmission.js';
15
16
  import { SETTINGS_BUILD_LAYER_PARTS_UNREAD_NOTICE } from './generated/settingsSchemaFns.js';
16
- import { appendOwnElement, ownDataField } from './ownKey.js';
17
- export const HOST_SUPPLIED_KEYS = Object.freeze(['settings.hooks', 'settings.resolved', 'settings.webSearch', 'settings.outputStyle', 'memory', 'fileHistory']);
17
+ import { appendOwnElement, ownDataField, readOwnDataValue } from './ownKey.js';
18
+ export const HOST_SUPPLIED_KEYS = Object.freeze(['settings.hooks', 'settings.resolved', 'settings.webSearch', 'settings.outputStyle', 'memory', 'fileHistory', 'settings.env']);
18
19
  export const HOST_SETTING_CAUSES = Object.freeze([
19
20
  'carried',
20
21
  'entries_dropped',
@@ -44,6 +45,8 @@ const HOST_SETTING_NOTICE_TEXT = {
44
45
  'HS-STYLE-MISSING': (what) => renderMessage(msg('session.hostSettings.styleMissing', { name: what })),
45
46
  'HS-STYLE-SAFE': () => renderMessage(msg('session.hostSettings.styleSafeMode')),
46
47
  'HS-LAYER-PARTS-UNREAD': (line) => line,
48
+ 'HS-STYLE-OVERSIZE': (what) => renderMessage(msg('session.hostSettings.styleOversize', { limit: what })),
49
+ 'HS-STYLE-UNREADABLE': () => renderMessage(msg('session.hostSettings.styleUnreadable')),
47
50
  };
48
51
  const KEY_NOUN = {
49
52
  'settings.hooks': 'the hooks',
@@ -52,6 +55,7 @@ const KEY_NOUN = {
52
55
  'settings.outputStyle': 'the output style',
53
56
  memory: 'auto-memory',
54
57
  fileHistory: 'file checkpoints',
58
+ 'settings.env': 'the environment variables your HTTP hooks read',
55
59
  };
56
60
  const BASE_DISPOSITION = {
57
61
  carried: 'carry',
@@ -204,6 +208,98 @@ function webSearchArm(src, side) {
204
208
  notices: [notice('HS-WEBSEARCH-MALFORMED', 'turn', webSearchVerdictMessage(verdict, 'submit') ?? '')],
205
209
  };
206
210
  }
211
+ function ownElementsOf(v) {
212
+ if (!Array.isArray(v))
213
+ return [];
214
+ const len = readOwnDataValue(v, 'length');
215
+ if (typeof len !== 'number' || !Number.isSafeInteger(len) || len < 0)
216
+ return [];
217
+ const out = [];
218
+ for (let i = 0; i < len; i++)
219
+ appendOwnElement(out, readOwnDataValue(v, String(i)));
220
+ return out;
221
+ }
222
+ export function hookEnvNamesOf(hooks) {
223
+ const out = [];
224
+ if (!isRecordShape(hooks))
225
+ return out;
226
+ for (const event of Object.keys(hooks)) {
227
+ if (!isEngineFiredHookEvent(event))
228
+ continue;
229
+ for (const group of ownElementsOf(readOwnDataValue(hooks, event))) {
230
+ if (!isRecordShape(group))
231
+ continue;
232
+ for (const entry of ownElementsOf(readOwnDataValue(group, 'hooks'))) {
233
+ if (!isRecordShape(entry) || readOwnDataValue(entry, 'type') !== 'http')
234
+ continue;
235
+ for (const name of ownElementsOf(readOwnDataValue(entry, 'allowedEnvVars'))) {
236
+ if (typeof name === 'string' && !out.includes(name))
237
+ appendOwnElement(out, name);
238
+ }
239
+ }
240
+ }
241
+ }
242
+ return out;
243
+ }
244
+ function hookEnvLayerOf(names, env) {
245
+ const layer = {};
246
+ let n = 0;
247
+ for (const name of names) {
248
+ const v = readOwnDataValue(env, name);
249
+ if (typeof v !== 'string')
250
+ continue;
251
+ Object.defineProperty(layer, name, { value: v, enumerable: true, writable: true, configurable: true });
252
+ n++;
253
+ }
254
+ return n > 0 ? freeze(layer) : undefined;
255
+ }
256
+ function hookEnvConsistent(env, hooks) {
257
+ if (env === undefined)
258
+ return true;
259
+ try {
260
+ if (!isRecordShape(env))
261
+ return false;
262
+ const keys = Reflect.ownKeys(env);
263
+ if (keys.length === 0)
264
+ return false;
265
+ const names = hookEnvNamesOf(hooks);
266
+ return keys.every((k) => typeof k === 'string' && names.includes(k) && typeof readOwnDataValue(env, k) === 'string');
267
+ }
268
+ catch {
269
+ return false;
270
+ }
271
+ }
272
+ function envArm(src, hooksCarried) {
273
+ const key = 'settings.env';
274
+ if (src.kind === 'missing')
275
+ return missingArm(key);
276
+ if (src.kind === 'threw')
277
+ return unreadableArm(key);
278
+ const v = src.value;
279
+ if (v === 'none')
280
+ return noSourceArm(key);
281
+ let env;
282
+ try {
283
+ if (!isRecordShape(v) || !Object.hasOwn(v, 'env'))
284
+ throw badSource(key, "{ env } with the host environment (pass 'none' where there is none)");
285
+ env = v.env;
286
+ }
287
+ catch (e) {
288
+ if (e instanceof HostSourceShapeError)
289
+ throw e;
290
+ return unreadableArm(key);
291
+ }
292
+ if (!isRecordShape(env))
293
+ throw badSource(key, '{ env } where env is the environment record');
294
+ let layer;
295
+ try {
296
+ layer = hookEnvLayerOf(hookEnvNamesOf(hooksCarried), env);
297
+ }
298
+ catch {
299
+ return unreadableArm(key);
300
+ }
301
+ return layer === undefined ? emptyArm(key) : carriedArm(key, layer);
302
+ }
207
303
  function memoryArm(src, side, judge) {
208
304
  const key = 'memory';
209
305
  if (src.kind === 'missing')
@@ -336,7 +432,7 @@ function outputStyleArm(src, side) {
336
432
  const reminder = state.ok && state.value === 'present' ? ownDataOf(body, 'turnReminder') : undefined;
337
433
  if (text !== undefined && text.ok && typeof text.value === 'string' && reminder !== undefined && reminder.ok && (reminder.value === undefined || typeof reminder.value === 'string')) {
338
434
  const facts = freeze({ name, body: text.value, ...(reminder.value !== undefined ? { turnReminder: reminder.value } : {}) });
339
- return { ...carriedArm(key, name), facts };
435
+ return text.value.trim() === '' ? { ...emptyArm(key), facts } : { ...carriedArm(key, text.value), facts };
340
436
  }
341
437
  return {
342
438
  row: freeze({ key, cause: 'source_unreadable', disposition: 'withhold_notice' }),
@@ -709,6 +805,7 @@ export function buildHostTurnSettings(input, judges) {
709
805
  const outputStyle = outputStyleArm(read('outputStyle'), side);
710
806
  const memory = memoryArm(read('memory'), side, judges.memoryOffDeclared);
711
807
  const fileHistory = fileHistoryArm(read('fileHistory'));
808
+ const envSource = read('env');
712
809
  let resolved = resolvedArm;
713
810
  let armsByKey = [hooks, resolved, webSearch, outputStyle, memory, fileHistory];
714
811
  if (side.kind === 'read' && MANAGED_READING_DISPOSITIONS[side.read.managed].commit === 'refuse') {
@@ -765,7 +862,10 @@ export function buildHostTurnSettings(input, judges) {
765
862
  armsByKey = [{ ...mark(armsByKey[0]), ...(hooks.plan !== undefined ? { plan: hooks.plan } : {}) }, mark(armsByKey[1]), armsByKey[2], armsByKey[3], armsByKey[4], armsByKey[5]];
766
863
  appendOwnElement(heldNotices, notice('HS-HELD-PREVIOUS', 'diagnostic'));
767
864
  }
768
- const arms = armsByKey;
865
+ const hooksFinal = armsByKey[0];
866
+ const hooksToCarry = hooksFinal.row.disposition === 'carry' || hooksFinal.row.disposition === 'carry_partial' || hooksFinal.row.disposition === 'hold_for_consent' ? hooksFinal.carried : undefined;
867
+ const env = envArm(envSource, hooksToCarry);
868
+ const arms = [...armsByKey, env];
769
869
  const rows = freeze(arms.map((a) => a.row));
770
870
  const resolvedOut = arms[1]?.row.disposition === 'carry' || arms[1]?.row.disposition === 'carry_partial' || arms[1]?.row.disposition === 'hold_for_consent' ? resolvedCarried : undefined;
771
871
  const permissionsRow = arms[1]?.row;
@@ -790,8 +890,10 @@ export function buildHostTurnSettings(input, judges) {
790
890
  ...(carriedOf(3) !== undefined ? { outputStyle: carriedOf(3) } : {}),
791
891
  ...(carriedOf(4) !== undefined ? { memory: 'off' } : {}),
792
892
  ...(carriedOf(5) !== undefined ? { fileHistory: 'disabled' } : {}),
893
+ ...(carriedOf(6) !== undefined ? { env: carriedOf(6) } : {}),
793
894
  });
794
- const styleFacts = arms[3]?.row.disposition === 'carry' ? outputStyle.facts : undefined;
895
+ const styleDisposition = arms[3]?.row.disposition;
896
+ const styleFacts = styleDisposition === 'carry' || styleDisposition === 'nothing_to_carry' ? outputStyle.facts : undefined;
795
897
  const product = { verdict, rows, notices, hooks: hooks.plan, carried, session: nextSession, outputStyle: styleFacts, held };
796
898
  if (resolvedError !== undefined && resolvedOut !== undefined)
797
899
  Object.defineProperty(product, RESOLVED_DEFERRED_ERROR, { value: resolvedError, enumerable: false });
@@ -910,6 +1012,7 @@ export function hostSettingsSelfCheck(product) {
910
1012
  }
911
1013
  export const hostProjectionNotice = () => notice('HS-PROJECTION', 'turn');
912
1014
  export const hostFileHistoryRestoreNotice = () => notice('HS-FILEHISTORY-RESTORE', 'turn');
1015
+ export const hostStyleNotAppliedNotice = (cause, limit) => cause === 'oversize' ? notice('HS-STYLE-OVERSIZE', 'turn', String(limit)) : notice('HS-STYLE-UNREADABLE', 'turn');
913
1016
  export class HostSettingsRefused extends Error {
914
1017
  notice;
915
1018
  constructor(n) {
@@ -985,6 +1088,8 @@ export function hostTurnSettingsOf(v, depth = 'full') {
985
1088
  return undefined;
986
1089
  if (Object.hasOwn(carried, 'hooks') && carried.hooks !== undefined && !hooksPassJudge(carried.hooks))
987
1090
  return undefined;
1091
+ if (!hookEnvConsistent(Object.hasOwn(carried, 'env') ? carried.env : undefined, Object.hasOwn(carried, 'hooks') ? carried.hooks : undefined))
1092
+ return undefined;
988
1093
  return shaped;
989
1094
  }
990
1095
  catch {
@@ -1225,6 +1330,8 @@ function intakeSnapshotUnguarded(product, onResolved) {
1225
1330
  return undefined;
1226
1331
  if (values.hooks !== undefined && !hooksPassJudge(values.hooks))
1227
1332
  return undefined;
1333
+ if (!hookEnvConsistent(values.env, values.hooks))
1334
+ return undefined;
1228
1335
  const v = ownDataOf(product, 'verdict');
1229
1336
  if (!v.ok)
1230
1337
  return undefined;