@sema-agent/client-core 0.112.0 → 0.113.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 (182) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/README.md +37 -24
  3. package/dist/adapt/arms.js +7 -1
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +27 -1
  6. package/dist/adapter/activeRunSelfHeal.d.ts +7 -5
  7. package/dist/adapter/activeRunSelfHeal.js +38 -66
  8. package/dist/adapter/downstream/eventToSdkMessage.js +4 -0
  9. package/dist/adapter/downstream/terminalToSdkResult.d.ts +8 -0
  10. package/dist/adapter/downstream/terminalToSdkResult.js +36 -1
  11. package/dist/adapter/runStream.d.ts +2 -12
  12. package/dist/adapter/runStream.js +46 -19
  13. package/dist/agentSession/engineAgentRegistryRead.js +2 -1
  14. package/dist/agentSession/engineSessionBackgroundStop.js +2 -2
  15. package/dist/attachmentOutcome.d.ts +35 -0
  16. package/dist/attachmentOutcome.js +192 -0
  17. package/dist/attachmentPathPlan.d.ts +67 -0
  18. package/dist/attachmentPathPlan.js +203 -0
  19. package/dist/attachmentRoute.d.ts +9 -1
  20. package/dist/attachmentRoute.js +23 -2
  21. package/dist/declared/supportFloorDeclared.d.ts +1 -1
  22. package/dist/declared/supportFloorDeclared.js +1 -0
  23. package/dist/deviceRebind.js +2 -3
  24. package/dist/displayUntrusted.js +126 -19
  25. package/dist/engineAddress.d.ts +1 -1
  26. package/dist/engineAddress.js +9 -6
  27. package/dist/engineErrorCodes.d.ts +3 -0
  28. package/dist/engineErrorCodes.js +4 -0
  29. package/dist/engineNoticeCodes.d.ts +34 -4
  30. package/dist/engineNoticeCodes.js +133 -6
  31. package/dist/engineUnavailable.d.ts +4 -2
  32. package/dist/engineUnavailable.js +99 -17
  33. package/dist/fleet/fleetLedger.d.ts +9 -3
  34. package/dist/fleet/fleetLedger.js +112 -16
  35. package/dist/fleet/fleetProjection.d.ts +5 -0
  36. package/dist/fleet/fleetProjection.js +9 -1
  37. package/dist/gateVocabulary.d.ts +7 -0
  38. package/dist/gateVocabulary.js +40 -14
  39. package/dist/generated/engineFactTables.d.ts +4 -2
  40. package/dist/generated/engineFactTables.js +198 -2
  41. package/dist/generated/engineNoticeTables.js +56 -8
  42. package/dist/generated/settingsSchemaFns.d.ts +7 -0
  43. package/dist/generated/settingsSchemaFns.js +11 -0
  44. package/dist/generated/settingsSchemaHash.d.ts +1 -0
  45. package/dist/generated/settingsSchemaHash.js +58 -0
  46. package/dist/generated/settingsSchemaOwnKeyRead.js +6 -1
  47. package/dist/generated/settingsSchemaTables.d.ts +3 -2
  48. package/dist/generated/settingsSchemaTables.js +14 -0
  49. package/dist/generated/settingsSchemaTightenVerdict.d.ts +1 -0
  50. package/dist/generated/settingsSchemaTightenVerdict.js +125 -0
  51. package/dist/headlessPermissionModeWire.d.ts +7 -2
  52. package/dist/headlessPermissionModeWire.js +77 -8
  53. package/dist/hitl/approvalDecisionDoor.d.ts +24 -0
  54. package/dist/hitl/approvalDecisionDoor.js +77 -0
  55. package/dist/hitl/approvalDelivery.d.ts +6 -0
  56. package/dist/hitl/approvalDelivery.js +57 -7
  57. package/dist/hitl/approvalResolution.d.ts +6 -3
  58. package/dist/hitl/approvalResolution.js +24 -2
  59. package/dist/hitl/approvalsFeed.js +1 -1
  60. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  61. package/dist/hitl/decisionSend.d.ts +7 -4
  62. package/dist/hitl/decisionSend.js +90 -41
  63. package/dist/hitl/frameRouter.d.ts +3 -3
  64. package/dist/hitl/frameRouter.js +5 -0
  65. package/dist/hitl/hitlBridge.d.ts +1 -0
  66. package/dist/hitl/hitlBridge.js +17 -4
  67. package/dist/hitl/hitlHostSurface.d.ts +3 -2
  68. package/dist/hitl/hitlHostSurface.js +5 -3
  69. package/dist/hitl/legacyApprovalShapes.d.ts +142 -0
  70. package/dist/hitl/legacyApprovalShapes.js +1 -0
  71. package/dist/hitl/livePendingAsk.d.ts +4 -4
  72. package/dist/hitl/livePendingAsk.js +5 -3
  73. package/dist/hitl/parkResolver.js +1 -1
  74. package/dist/hitl/persistedRulesWire.js +2 -2
  75. package/dist/hitl/planReviewCard.d.ts +4 -2
  76. package/dist/hitl/planReviewCard.js +66 -1
  77. package/dist/hitl/planReviewWire.d.ts +34 -2
  78. package/dist/hitl/planReviewWire.js +326 -150
  79. package/dist/hitl/sessionPolicyWire.js +16 -7
  80. package/dist/hitl/subagentSource.d.ts +1 -0
  81. package/dist/hitl/subagentSource.js +11 -0
  82. package/dist/hitl/toolApprovalWire.d.ts +34 -10
  83. package/dist/hitl/toolApprovalWire.js +182 -33
  84. package/dist/hookMatcherVerdict.d.ts +2 -1
  85. package/dist/hookMatcherVerdict.js +3 -2
  86. package/dist/hooksReaderGenerations.d.ts +8 -0
  87. package/dist/hooksReaderGenerations.js +49 -0
  88. package/dist/hooksWireCaps.js +43 -18
  89. package/dist/hostSettingsSource.d.ts +1 -1
  90. package/dist/hostSettingsSource.js +2 -2
  91. package/dist/hostTurnSettings.d.ts +2 -2
  92. package/dist/hostTurnSettings.js +87 -47
  93. package/dist/humanTurn.d.ts +2 -1
  94. package/dist/humanTurn.js +44 -13
  95. package/dist/humanTurnRead.d.ts +7 -0
  96. package/dist/humanTurnRead.js +23 -14
  97. package/dist/humanTurnSentences.js +3 -0
  98. package/dist/i18n/messages.en.d.ts +93 -5
  99. package/dist/i18n/messages.en.js +100 -12
  100. package/dist/i18n/messages.zh.js +110 -15
  101. package/dist/index.d.ts +29 -15
  102. package/dist/index.js +17 -9
  103. package/dist/liveModelCatalog.js +1 -0
  104. package/dist/liveQuestionStore.d.ts +2 -0
  105. package/dist/liveQuestionStore.js +7 -2
  106. package/dist/localConfig/kernel.d.ts +2 -1
  107. package/dist/localConfig/kernel.js +12 -18
  108. package/dist/localConfig/mcp/edit.js +25 -27
  109. package/dist/localConfig/mcp/servers.js +5 -8
  110. package/dist/localConfig/modelPool.d.ts +6 -1
  111. package/dist/localConfig/modelPool.js +104 -27
  112. package/dist/localConfig/modelPoolWords.d.ts +2 -0
  113. package/dist/localConfig/modelPoolWords.js +1 -0
  114. package/dist/localConfig/settingsWrite.js +1 -14
  115. package/dist/localConfig/skills.js +9 -16
  116. package/dist/localEngineSpawn.d.ts +29 -1
  117. package/dist/localEngineSpawn.js +62 -1
  118. package/dist/mcpLiveness.d.ts +1 -1
  119. package/dist/mcpProbeWire.js +2 -2
  120. package/dist/mcpReconnect.js +2 -2
  121. package/dist/model/catalogLoader.js +3 -17
  122. package/dist/model/onboardJudgement.d.ts +8 -0
  123. package/dist/model/onboardJudgement.js +8 -3
  124. package/dist/model/onboardSteps.d.ts +19 -0
  125. package/dist/model/onboardSteps.js +76 -0
  126. package/dist/notifications.js +20 -12
  127. package/dist/ownKey.d.ts +4 -0
  128. package/dist/ownKey.js +61 -0
  129. package/dist/pathShape.d.ts +14 -0
  130. package/dist/pathShape.js +44 -0
  131. package/dist/planReviewCardFacts.d.ts +3 -0
  132. package/dist/planReviewCardFacts.js +20 -3
  133. package/dist/planReviewOutcomeCause.d.ts +2 -0
  134. package/dist/planReviewOutcomeCause.js +12 -0
  135. package/dist/pluginHooksWire.d.ts +20 -8
  136. package/dist/pluginHooksWire.js +204 -86
  137. package/dist/prepareRefusal.d.ts +2 -0
  138. package/dist/prepareRefusal.js +11 -1
  139. package/dist/request/taskRequest.js +3 -1
  140. package/dist/resultFrameKeys.d.ts +1 -0
  141. package/dist/resultFrameKeys.js +3 -0
  142. package/dist/resumeRefusalCopy.js +3 -1
  143. package/dist/retryStatus.d.ts +11 -1
  144. package/dist/retryStatus.js +15 -4
  145. package/dist/runTerminal.d.ts +1 -0
  146. package/dist/runTerminal.js +15 -1
  147. package/dist/sdkWireTransit.d.ts +1 -1
  148. package/dist/seatContract.d.ts +12 -3
  149. package/dist/seatContract.js +24 -13
  150. package/dist/sessionEngine.js +1 -1
  151. package/dist/sessionHooksRoster.js +8 -6
  152. package/dist/sessionIdSegment.d.ts +0 -1
  153. package/dist/sessionIdSegment.js +1 -3
  154. package/dist/sessionMemoryErase.js +2 -2
  155. package/dist/sessionMemoryStatus.js +2 -1
  156. package/dist/sessionOccupant.d.ts +29 -0
  157. package/dist/sessionOccupant.js +78 -0
  158. package/dist/settingsHooksSalvage.d.ts +4 -1
  159. package/dist/settingsHooksSalvage.js +22 -9
  160. package/dist/skillOverrideChain.d.ts +3 -0
  161. package/dist/skillOverrideChain.js +31 -4
  162. package/dist/skillsWireCaps.d.ts +16 -2
  163. package/dist/skillsWireCaps.js +47 -20
  164. package/dist/subagent/agentStateDetail.js +32 -8
  165. package/dist/subagent/engineCompactWire.js +48 -36
  166. package/dist/subagent/engineDelegatedPrompt.d.ts +3 -2
  167. package/dist/subagent/engineDelegatedPrompt.js +65 -28
  168. package/dist/subagentEditOutcomes.d.ts +9 -0
  169. package/dist/subagentEditOutcomes.js +43 -0
  170. package/dist/supportFloor.d.ts +2 -1
  171. package/dist/supportFloor.js +1 -1
  172. package/dist/toolResult.js +4 -2
  173. package/dist/toolRoster.d.ts +1 -0
  174. package/dist/toolRoster.js +1 -0
  175. package/dist/usageAnalytics.js +2 -1
  176. package/dist/userAttachmentEnvelope.d.ts +11 -0
  177. package/dist/userAttachmentEnvelope.js +7 -2
  178. package/dist/userAttachmentSeat.d.ts +7 -1
  179. package/dist/userAttachmentSeat.js +44 -7
  180. package/dist/wiringInstructionsAttribution.js +8 -2
  181. package/docs/INTEGRATION-CLIENTS.md +1654 -16
  182. package/package.json +5 -5
@@ -0,0 +1,19 @@
1
+ import type { EngineTargetState, ModelPoolListResult } from '../seatContract.js';
2
+ import type { ModelPoolView } from '../localConfig/modelPool.js';
3
+ export declare const ONBOARD_STEPS: readonly ["model", "tiers", "optional", "ready"];
4
+ export type OnboardStep = (typeof ONBOARD_STEPS)[number];
5
+ export declare const ONBOARD_STEP_STATES: readonly ["required", "skippable", "skipped"];
6
+ export type OnboardStepState = (typeof ONBOARD_STEP_STATES)[number];
7
+ export declare const ONBOARD_STEP_REASONS: readonly ["already_configured", "pool_empty", "target_not_local"];
8
+ export type OnboardStepReason = (typeof ONBOARD_STEP_REASONS)[number];
9
+ export interface OnboardStepRow {
10
+ readonly step: OnboardStep;
11
+ readonly state: OnboardStepState;
12
+ readonly reason?: OnboardStepReason;
13
+ }
14
+ export type OnboardStepPlan = readonly [OnboardStepRow, OnboardStepRow, OnboardStepRow, OnboardStepRow];
15
+ export interface OnboardStepPlanInput {
16
+ readonly target?: Pick<EngineTargetState, 'mode'> | undefined;
17
+ readonly view?: ModelPoolView | ModelPoolListResult | undefined;
18
+ }
19
+ export declare function onboardStepPlanOf(input?: OnboardStepPlanInput): OnboardStepPlan;
@@ -0,0 +1,76 @@
1
+ import { modelPoolEnvReadingOf } from '../localConfig/modelPool.js';
2
+ import { ownDataField, ownSnapshotRecordFaithful } from '../ownKey.js';
3
+ export const ONBOARD_STEPS = Object.freeze(['model', 'tiers', 'optional', 'ready']);
4
+ export const ONBOARD_STEP_STATES = Object.freeze(['required', 'skippable', 'skipped']);
5
+ export const ONBOARD_STEP_REASONS = Object.freeze(['already_configured', 'pool_empty', 'target_not_local']);
6
+ function slotOf(carrier, key) {
7
+ try {
8
+ return typeof carrier === 'object' && carrier !== null ? ownDataField(carrier, key) : undefined;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ const arrayOf = (v) => (Array.isArray(v) ? v : undefined);
15
+ const recordOf = (v) => (typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined);
16
+ function poolFactsOf(view) {
17
+ const v = ownSnapshotRecordFaithful(view);
18
+ if (v === undefined || v['kind'] === 'unavailable')
19
+ return undefined;
20
+ const catalog = v['catalog'];
21
+ if (catalog !== 'read' && catalog !== 'absent' && catalog !== 'unreadable')
22
+ return undefined;
23
+ if (catalog === 'unreadable')
24
+ return undefined;
25
+ const entries = arrayOf(v['entries']);
26
+ if (entries === undefined)
27
+ return undefined;
28
+ let enabled = 0;
29
+ for (let i = 0; i < entries.length; i++) {
30
+ if (!(i in entries))
31
+ return undefined;
32
+ const entry = recordOf(entries[i]);
33
+ const on = entry === undefined ? undefined : entry['enabled'];
34
+ if (typeof on !== 'boolean')
35
+ return undefined;
36
+ if (on)
37
+ enabled++;
38
+ }
39
+ if (catalog === 'absent' && entries.length > 0)
40
+ return undefined;
41
+ const certainlyEmpty = catalog === 'absent' || (catalog === 'read' && v['completeness'] === 'complete' && enabled === 0);
42
+ return { enabled, certainlyEmpty, env: modelPoolEnvReadingOf(v), envModels: envModelsOf(v['envModels']) };
43
+ }
44
+ function envModelsOf(raw) {
45
+ const models = arrayOf(raw);
46
+ if (models === undefined)
47
+ return 'unknown';
48
+ for (let i = 0; i < models.length; i++) {
49
+ if (!(i in models) || typeof models[i] !== 'string')
50
+ return 'unknown';
51
+ }
52
+ return models.length === 0 ? 'empty' : 'some';
53
+ }
54
+ const row = (step, state, reason) => Object.freeze(reason === undefined ? { step, state } : { step, state, reason });
55
+ function planOf(mode, pool) {
56
+ let model = row('model', 'skippable');
57
+ if (mode === 'cloud')
58
+ model = row('model', 'skippable', 'target_not_local');
59
+ else if (mode === 'local' && pool !== undefined) {
60
+ if (pool.certainlyEmpty && pool.env === 'read' && pool.envModels === 'empty')
61
+ model = row('model', 'required');
62
+ else if (pool.enabled > 0 || (pool.env === 'read' && pool.envModels === 'some'))
63
+ model = row('model', 'skippable', 'already_configured');
64
+ }
65
+ const tiers = pool !== undefined && pool.certainlyEmpty ? row('tiers', 'skipped', 'pool_empty') : row('tiers', 'skippable');
66
+ return Object.freeze([model, tiers, row('optional', 'skippable'), row('ready', 'required')]);
67
+ }
68
+ export function onboardStepPlanOf(input) {
69
+ try {
70
+ const mode = slotOf(slotOf(input, 'target'), 'mode');
71
+ return planOf(typeof mode === 'string' ? mode : undefined, poolFactsOf(slotOf(input, 'view')));
72
+ }
73
+ catch {
74
+ return planOf(undefined, undefined);
75
+ }
76
+ }
@@ -1,4 +1,5 @@
1
1
  import { hostEnv } from './hostEnv.js';
2
+ import { planReviewOutcomeCauseOf } from './planReviewOutcomeCause.js';
2
3
  import { unrefTimer } from './unrefTimer.js';
3
4
  import { clearEnginePanelTaskResidentByWire, publishEngineAgentPanelEvent, } from './engineAgentPanelStore.js';
4
5
  import { panelEndFact } from './panelReduce.js';
@@ -432,21 +433,28 @@ export function enqueuePlanReviewOutcome(value, meta) {
432
433
  priority: 'later',
433
434
  isMeta: true,
434
435
  workload: 'plan-review',
435
- ...(meta !== undefined
436
- ? {
437
- _sema_planReviewOutcome: Object.freeze({
438
- taskId: meta.taskId,
439
- dispatchNo: meta.dispatchNo,
440
- decision: meta.decision,
441
- effect: meta.effect,
442
- ...(meta.effect === 'still_parked' && meta.cause === 'stored_form_unsupported' ? { cause: meta.cause } : {}),
443
- ...(questionId !== undefined ? { questionId } : {}),
444
- }),
445
- }
446
- : {}),
436
+ ...(meta !== undefined ? { _sema_planReviewOutcome: planReviewOutcomeRefrozen(meta, questionId) } : {}),
447
437
  });
448
438
  return true;
449
439
  }
440
+ function planReviewOutcomeRefrozen(meta, questionId) {
441
+ const effect = meta.effect;
442
+ const cause = planReviewOutcomeCauseOf(effect, meta.cause);
443
+ const delivery = guardedRead(() => readOwnDataValue(meta, 'delivery'));
444
+ const gateIdOmitted = guardedRead(() => readOwnDataValue(meta, 'gateIdOmitted'));
445
+ const wayOut = guardedRead(() => readOwnDataNonEmptyString(meta, 'wayOut'));
446
+ return Object.freeze({
447
+ taskId: meta.taskId,
448
+ dispatchNo: meta.dispatchNo,
449
+ decision: meta.decision,
450
+ effect,
451
+ ...(cause !== undefined ? { cause } : {}),
452
+ ...(questionId !== undefined ? { questionId } : {}),
453
+ ...(delivery === 'submit' || delivery === 'follow' ? { delivery } : {}),
454
+ ...(gateIdOmitted === true ? { gateIdOmitted: true } : {}),
455
+ ...(wayOut !== undefined ? { wayOut } : {}),
456
+ });
457
+ }
450
458
  export function resupplyTruncatedSentence(facts, lang) {
451
459
  try {
452
460
  const f = resupplyTruncatedFactsOf(facts);
package/dist/ownKey.d.ts CHANGED
@@ -5,13 +5,17 @@ export declare function readOwnDataNonEmptyString(v: object | null | undefined,
5
5
  export declare function readOwnDataFiniteNumber(v: object | null | undefined, key: string): number | undefined;
6
6
  export declare function readOwnDataValue<T>(v: object | null | undefined, key: string): T | undefined;
7
7
  export declare function carriesAnswerText(text: string): boolean;
8
+ export declare function sameJson(a: {} | null | undefined, b: {} | null | undefined): boolean;
8
9
  export declare function appendOwnElement<T>(list: T[], value: T): void;
9
10
  export declare function toolResultBlockOf(record: object): object | undefined;
10
11
  export declare function guardedRead<T>(read: () => T | undefined): T | undefined;
12
+ export type HostPresence = 'here' | 'left' | 'unconfirmed';
13
+ export declare function hostPresenceOf(host: object | null | undefined, call?: (ask: () => boolean | undefined) => boolean | undefined): HostPresence;
11
14
  export declare function ownDataField(v: object, key: string): unknown;
12
15
  export declare function ownSendableField(v: object, key: string): unknown;
13
16
  export declare function ownDataRefusalKeyOf(e: unknown): string | undefined;
14
17
  export declare function readFrameStringKey(frame: unknown, key: string): string | undefined;
18
+ export declare function readFrameEntryIdList(frame: object | null | undefined, key: string): readonly string[] | undefined;
15
19
  export declare function readFrameTrueMark(frame: object | null | undefined, key: string): boolean;
16
20
  export type FrameTrueMarkReading = 'marked' | 'absent' | 'unreadable';
17
21
  export declare function readFrameTrueMarkReading(frame: object | null | undefined, key: string): FrameTrueMarkReading;
package/dist/ownKey.js CHANGED
@@ -37,6 +37,21 @@ export function readOwnDataValue(v, key) {
37
37
  export function carriesAnswerText(text) {
38
38
  return text.trim().length > 0;
39
39
  }
40
+ export function sameJson(a, b) {
41
+ if (a === b)
42
+ return true;
43
+ if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null)
44
+ return false;
45
+ if (Array.isArray(a) !== Array.isArray(b))
46
+ return false;
47
+ if (Array.isArray(a) && Array.isArray(b))
48
+ return a.length === b.length && a.every((x, i) => sameJson(x, b[i]));
49
+ const ka = Object.keys(a);
50
+ const kb = Object.keys(b);
51
+ if (ka.length !== kb.length)
52
+ return false;
53
+ return ka.every((k) => Object.hasOwn(b, k) && sameJson(a[k], b[k]));
54
+ }
40
55
  export function appendOwnElement(list, value) {
41
56
  Object.defineProperty(list, list.length, { value, writable: true, enumerable: true, configurable: true });
42
57
  }
@@ -63,6 +78,29 @@ export function guardedRead(read) {
63
78
  return undefined;
64
79
  }
65
80
  }
81
+ export function hostPresenceOf(host, call) {
82
+ if (typeof host !== 'object' || host === null)
83
+ return 'here';
84
+ let port;
85
+ try {
86
+ port = host.stillHere;
87
+ }
88
+ catch {
89
+ return 'unconfirmed';
90
+ }
91
+ if (port === undefined)
92
+ return 'here';
93
+ if (typeof port !== 'function')
94
+ return 'unconfirmed';
95
+ try {
96
+ const ask = () => port.call(host);
97
+ const answer = call === undefined ? ask() : call(ask);
98
+ return answer === true ? 'here' : answer === false ? 'left' : 'unconfirmed';
99
+ }
100
+ catch {
101
+ return 'unconfirmed';
102
+ }
103
+ }
66
104
  export function ownDataField(v, key) {
67
105
  return ownField(v, key, false);
68
106
  }
@@ -94,6 +132,29 @@ export function readFrameStringKey(frame, key) {
94
132
  return undefined;
95
133
  }
96
134
  }
135
+ export function readFrameEntryIdList(frame, key) {
136
+ try {
137
+ if (frame === null || typeof frame !== 'object' || Array.isArray(frame))
138
+ return undefined;
139
+ const list = readOwnDataValue(frame, key);
140
+ if (!Array.isArray(list))
141
+ return undefined;
142
+ const len = readOwnDataValue(list, 'length');
143
+ if (typeof len !== 'number' || !Number.isInteger(len) || len < 0 || len > 1024)
144
+ return undefined;
145
+ const out = [];
146
+ for (let i = 0; i < len; i++) {
147
+ const id = readOwnDataNonEmptyString(list, String(i));
148
+ if (id === undefined)
149
+ return undefined;
150
+ appendOwnElement(out, id);
151
+ }
152
+ return out;
153
+ }
154
+ catch {
155
+ return undefined;
156
+ }
157
+ }
97
158
  export function readFrameTrueMark(frame, key) {
98
159
  return readFrameTrueMarkReading(frame, key) === 'marked';
99
160
  }
@@ -0,0 +1,14 @@
1
+ export declare const PATH_LENGTH_LIMIT = 4096;
2
+ export type PathRootKind = 'posix' | 'drive' | 'unc' | 'relative';
3
+ export type PathCut = 'both' | '/' | '\\';
4
+ export interface PathShape {
5
+ readonly kind: PathRootKind;
6
+ readonly root: string;
7
+ readonly names: readonly string[];
8
+ readonly hasEmptySegment: boolean;
9
+ readonly hasTrailingSeparator: boolean;
10
+ readonly hasDotSegment: boolean;
11
+ readonly hasParentSegment: boolean;
12
+ }
13
+ export declare function isDotSegment(seg: string): boolean;
14
+ export declare function pathShapeOf(raw: string, cut?: PathCut): PathShape | undefined;
@@ -0,0 +1,44 @@
1
+ export const PATH_LENGTH_LIMIT = 4096;
2
+ export function isDotSegment(seg) {
3
+ return seg === '.' || seg === '..';
4
+ }
5
+ export function pathShapeOf(raw, cut = 'both') {
6
+ if (typeof raw !== 'string' || raw === '' || raw.includes('\u0000'))
7
+ return undefined;
8
+ let kind = 'relative';
9
+ let root = '';
10
+ if (raw.charAt(0) === '/') {
11
+ kind = 'posix';
12
+ root = '/';
13
+ }
14
+ else if (/^[A-Za-z]:[\\/]/.test(raw)) {
15
+ kind = 'drive';
16
+ root = raw.slice(0, 3);
17
+ }
18
+ else {
19
+ const unc = /^\\\\[^\\/]+[\\/][^\\/]+/.exec(raw);
20
+ if (unc !== null) {
21
+ kind = 'unc';
22
+ root = unc[0];
23
+ }
24
+ }
25
+ let from = root.length;
26
+ if (kind === 'unc' && (raw.charAt(from) === '/' || raw.charAt(from) === '\\'))
27
+ from += 1;
28
+ const tail = raw.slice(from);
29
+ const pieces = tail === '' ? [] : tail.split(cut === 'both' ? /[\\/]/ : cut);
30
+ let end = pieces.length;
31
+ while (end > 0 && pieces[end - 1] === '')
32
+ end -= 1;
33
+ const body = pieces.slice(0, end);
34
+ const all = raw.split(/[\\/]/);
35
+ return Object.freeze({
36
+ kind,
37
+ root,
38
+ names: Object.freeze(body.filter((p) => p !== '')),
39
+ hasEmptySegment: body.some((p) => p === ''),
40
+ hasTrailingSeparator: end < pieces.length,
41
+ hasDotSegment: all.some(isDotSegment),
42
+ hasParentSegment: all.some((p) => p === '..'),
43
+ });
44
+ }
@@ -64,6 +64,7 @@ interface PlanReviewRunRecord {
64
64
  gate?: PlanReviewGateEntry;
65
65
  generation: number;
66
66
  cardIssued: boolean;
67
+ lastCardGate?: string;
67
68
  }
68
69
  export declare function _resetPlanReviewRunsForTest(): void;
69
70
  export interface PlanReviewFactsTicket {
@@ -83,6 +84,8 @@ export interface PlanReviewCurrentGate {
83
84
  export declare function currentPlanReviewGateOf(sessionKey: string, taskId: string): PlanReviewCurrentGate | undefined;
84
85
  export declare function planReviewRunGeneration(sessionKey: string, taskId: string): number;
85
86
  export declare function notePlanReviewCardIssued(sessionKey: string, taskId: string): boolean;
87
+ export declare function noteCardGateHandedOver(sessionKey: string, taskId: string, checkpointId: string | undefined): void;
88
+ export declare function planReviewCardReplacesEarlier(sessionKey: string, facts: PlanReviewCardFacts): boolean;
86
89
  export declare function planReviewGateHighWaterOf(sessionKey: string, taskId: string, checkpointId: string): string | undefined;
87
90
  export interface PlanBodyClaimLeg {
88
91
  taskId?: string;
@@ -134,7 +134,13 @@ export function pausedCheckpointIdOf(carrier) {
134
134
  }
135
135
  const SETTLED_CALLS_MAX = 10_000;
136
136
  const PLAN_REVIEW_RUNS_MAX = 64;
137
- const planReviewRuns = new Map();
137
+ class PlanReviewRunTable extends Map {
138
+ generationSeq = 0;
139
+ }
140
+ function nextRunGeneration() {
141
+ return ++planReviewRuns.generationSeq;
142
+ }
143
+ const planReviewRuns = new PlanReviewRunTable();
138
144
  const runKey = (sessionKey, taskId) => `${sessionKey}\u0000${taskId}`;
139
145
  function emptyWindow() {
140
146
  return { presented: [], malformed: false, ambiguous: false, unreadable: false };
@@ -146,7 +152,7 @@ function recordFor(sessionKey, taskId) {
146
152
  planReviewRuns.delete(key);
147
153
  }
148
154
  else {
149
- rec = { open: new Set(), settled: new Set(), window: emptyWindow(), sawPlanFrame: false, dirty: false, generation: 0, cardIssued: false };
155
+ rec = { open: new Set(), settled: new Set(), window: emptyWindow(), sawPlanFrame: false, dirty: false, generation: nextRunGeneration(), cardIssued: false };
150
156
  }
151
157
  planReviewRuns.set(key, rec);
152
158
  while (planReviewRuns.size > PLAN_REVIEW_RUNS_MAX) {
@@ -162,7 +168,7 @@ export function _resetPlanReviewRunsForTest() {
162
168
  }
163
169
  export function beginPlanReviewFactsRead(sessionKey, taskId) {
164
170
  const rec = recordFor(sessionKey, taskId);
165
- rec.generation += 1;
171
+ rec.generation = nextRunGeneration();
166
172
  return { sessionKey, taskId, generation: rec.generation };
167
173
  }
168
174
  export function commitPlanReviewFacts(ticket, facts, claim, highWater) {
@@ -216,6 +222,17 @@ export function notePlanReviewCardIssued(sessionKey, taskId) {
216
222
  rec.cardIssued = true;
217
223
  return before;
218
224
  }
225
+ export function noteCardGateHandedOver(sessionKey, taskId, checkpointId) {
226
+ const rec = recordFor(sessionKey, taskId);
227
+ if (checkpointId === undefined)
228
+ delete rec.lastCardGate;
229
+ else
230
+ rec.lastCardGate = checkpointId;
231
+ }
232
+ export function planReviewCardReplacesEarlier(sessionKey, facts) {
233
+ const last = planReviewRuns.get(runKey(sessionKey, facts.taskId))?.lastCardGate;
234
+ return last !== undefined && facts.checkpointId !== undefined && last !== facts.checkpointId;
235
+ }
219
236
  export function planReviewGateHighWaterOf(sessionKey, taskId, checkpointId) {
220
237
  const gate = planReviewRuns.get(runKey(sessionKey, taskId))?.gate;
221
238
  return gate !== undefined && gate.checkpointId === checkpointId ? gate.highWater : undefined;
@@ -0,0 +1,2 @@
1
+ export type PlanReviewOutcomeCause = 'stored_form_unsupported' | 'card_missing' | 'card_withholds' | 'gate_moved' | 'gate_untrusted';
2
+ export declare function planReviewOutcomeCauseOf(effect: {} | null | undefined, cause: {} | null | undefined): PlanReviewOutcomeCause | undefined;
@@ -0,0 +1,12 @@
1
+ export function planReviewOutcomeCauseOf(effect, cause) {
2
+ switch (effect) {
3
+ case 'still_parked':
4
+ return cause === 'stored_form_unsupported' ? 'stored_form_unsupported' : undefined;
5
+ case 'not_sent':
6
+ return cause === 'card_missing' ? 'card_missing' : cause === 'card_withholds' ? 'card_withholds' : undefined;
7
+ case 'not_applied':
8
+ return cause === 'gate_moved' ? 'gate_moved' : cause === 'gate_untrusted' ? 'gate_untrusted' : undefined;
9
+ default:
10
+ return undefined;
11
+ }
12
+ }
@@ -1,18 +1,27 @@
1
1
  import type { HostSettingsSource } from './hostSettingsSource.js';
2
2
  import type { WireHooksConfig } from './finalVerifyWire.js';
3
- import type { PluginHookSource, SessionHookOrigin, SessionHookSource } from './host.js';
3
+ import { SETTINGS_ENGINE_OWNED_HOOK_EVENTS } from './generated/settingsSchemaTables.js';
4
+ import { type PluginHookSource, type SessionHookOrigin, type SessionHookSource } from './host.js';
4
5
  import type { HttpPolicyDropRow } from './httpHookPolicy.js';
5
6
  import type { SubmissionIdentity } from './request/submissionIdentity.js';
7
+ import type { HooksEntryKeyReader } from './hooksReaderGenerations.js';
6
8
  import { type HooksSalvageDrop, type HooksSalvageMask, type HooksSalvageRejection } from './settingsHooksSalvage.js';
7
- export declare const ENGINE_FIRED_HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "PreCompact", "PostCompact", "Stop", "StopFailure", "UserPromptSubmit"];
8
- export type EngineFiredHookEvent = (typeof ENGINE_FIRED_HOOK_EVENTS)[number];
9
+ export type EngineFiredHookEvent = (typeof SETTINGS_ENGINE_OWNED_HOOK_EVENTS)[number];
10
+ export interface HooksWireSettingsContract {
11
+ readonly version: string;
12
+ readonly basis: 'reported' | 'absent' | 'unreadable';
13
+ }
14
+ export declare const SUPPORT_FLOOR_SETTINGS_CONTRACT: HooksWireSettingsContract;
15
+ export declare function contractOwnsHookEventAt(event: string, contractVersion: string): boolean | undefined;
16
+ export declare function engineLaneOf(reading: HooksWireSettingsContract | undefined): (event: string) => boolean;
17
+ export declare function planSettingsContractOf(plan: object | undefined): HooksWireSettingsContract | undefined;
9
18
  export declare const PLUGIN_HOOK_DISPOSITIONS: readonly ["engine", "shell", "not_run"];
10
19
  export type PluginHookDisposition = (typeof PLUGIN_HOOK_DISPOSITIONS)[number];
11
20
  export declare const PLUGIN_HOOK_REASONS: readonly ["projected", "shell_event", "no_executor", "engine_not_local", "engine_locality_unknown", "engine_capability_absent", "engine_capability_unknown", "not_command", "sensitive_options", "engine_limit", "shell_form_user_config", "user_config_unset", "malformed_entry", "engine_hooks_off", "engine_hooks_unknown", "engine_type_skipped", "engine_llm_limit", "engine_unconfirmed", "engine_elsewhere", "hooks_module", "scope_unsupported", "source_incomplete", "compaction_local_fallback", "key_not_read", "source_not_authored"];
12
21
  export type PluginHookReason = (typeof PLUGIN_HOOK_REASONS)[number];
13
22
  export declare const PLUGIN_HOOK_EXCLUSION_REASONS: readonly ["workspace_untrusted", "governance_unreadable", "policy_disable_all", "startup_mode", "managed_plugins_only", "prompt_not_user_authored"];
14
23
  export type PluginHookExclusionReason = (typeof PLUGIN_HOOK_EXCLUSION_REASONS)[number];
15
- export declare const SETTINGS_HOOK_DROP_REASONS: readonly ["exec_form_unsupported", "mcp_tool_unsupported", "key_not_read", "source_not_authored", "workspace_untrusted", "governance_unreadable", "policy_disable_all", "no_executor"];
24
+ export declare const SETTINGS_HOOK_DROP_REASONS: readonly ["exec_form_unsupported", "mcp_tool_unsupported", "key_not_read", "source_not_authored", "workspace_untrusted", "governance_unreadable", "policy_disable_all", "no_executor", "layer_degraded"];
16
25
  export type SettingsHookDropReason = (typeof SETTINGS_HOOK_DROP_REASONS)[number];
17
26
  export type HookEntryTypeWord = 'command' | 'prompt' | 'agent' | 'http' | 'mcp_tool';
18
27
  export declare const HOOK_ENTRY_TYPE_WORDS: readonly ["command", "prompt", "agent", "http", "mcp_tool"];
@@ -39,6 +48,7 @@ export interface SettingsHookDrop {
39
48
  readonly type?: HookEntryTypeWord;
40
49
  readonly reason: SettingsHookDropReason;
41
50
  readonly notRun: boolean;
51
+ readonly guard: boolean;
42
52
  readonly unreadKeys?: readonly (readonly (string | number)[])[];
43
53
  }
44
54
  export interface SettingsHookVerdict {
@@ -67,7 +77,7 @@ export interface SettingsHooksSalvageRow {
67
77
  }
68
78
  export interface SettingsLayerWithheldRow {
69
79
  readonly source: HookSettingsSource;
70
- readonly cause: 'trust_withheld';
80
+ readonly cause: 'trust_withheld' | 'layer_degraded';
71
81
  readonly notice: string;
72
82
  }
73
83
  export interface PluginHookModuleVerdict {
@@ -89,6 +99,8 @@ export interface HooksWireEngineFacts {
89
99
  readonly ownedByThisShell: boolean | null;
90
100
  readonly pluginHooksCapable: boolean | null;
91
101
  readonly hooksCapable: boolean | null;
102
+ readonly settingsContract: HooksWireSettingsContract;
103
+ readonly hookEntryFields?: 'reported' | 'not_reported' | 'unreadable' | null;
92
104
  }
93
105
  export type PluginHookReaderState = 'present' | 'absent' | 'failed';
94
106
  export interface HooksWirePlan {
@@ -138,7 +150,7 @@ type HookExecutor = {
138
150
  };
139
151
  type WireHookGroup = NonNullable<WireHooksConfig[string]>[number];
140
152
  type WireHookEntry = WireHookGroup['hooks'][number];
141
- export declare function isEngineFiredHookEvent(event: string): boolean;
153
+ export declare function isEngineFiredHookEvent(event: string, contract: HooksWireSettingsContract): boolean;
142
154
  export interface EventOccupancy {
143
155
  readonly groups: number;
144
156
  readonly entries: number;
@@ -153,7 +165,7 @@ export interface PluginHookDecisionInput {
153
165
  readonly promptAuthoredByUser: boolean;
154
166
  readonly occupied: ReadonlyMap<string, EventOccupancy>;
155
167
  readonly suppressedLocally?: ReadonlySet<string>;
156
- readonly readerNotRead: readonly string[];
168
+ readonly reader: HooksEntryKeyReader;
157
169
  }
158
170
  export interface PluginHookDecision {
159
171
  readonly verdicts: readonly PluginHookVerdict[];
@@ -173,7 +185,7 @@ export declare function decideSessionHooks(input: SessionHookDecisionInput): {
173
185
  readonly verdicts: readonly SessionHookVerdict[];
174
186
  readonly unreadable: number;
175
187
  };
176
- export declare function filterSettingsHookGroups(source: HookSettingsSource, event: string, groups: readonly WireHookGroup[], execFormCapable: boolean, shellRunsType: (type: string | undefined) => boolean, judge: SettingsHookJudge, readerNotRead: readonly string[], mask?: HooksSalvageMask): SettingsHookFilterResult;
188
+ export declare function filterSettingsHookGroups(source: HookSettingsSource, event: string, groups: readonly WireHookGroup[], execFormCapable: boolean, shellRunsType: (type: string | undefined) => boolean, judge: SettingsHookJudge, reader: HooksEntryKeyReader, contract: HooksWireSettingsContract, mask?: HooksSalvageMask): SettingsHookFilterResult;
177
189
  export declare function hookEntryTypeWordOf(entry: {} | null | undefined): {
178
190
  readonly type?: HookEntryTypeWord;
179
191
  };