@sema-agent/client-core 0.100.0 → 0.101.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.
- package/CHANGELOG.md +395 -0
- package/README.md +164 -117
- package/dist/adapt/arms.js +51 -16
- package/dist/adapt/textStream.js +7 -4
- package/dist/adapt/toolCards.js +9 -8
- package/dist/adapt.js +7 -1
- package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
- package/dist/adapter/activeRunSelfHeal.js +108 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +33 -12
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
- package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
- package/dist/adapter/runStream.d.ts +4 -4
- package/dist/adapter/runStream.js +158 -43
- package/dist/agentsWireCaps.d.ts +2 -7
- package/dist/agentsWireCaps.js +1 -2
- package/dist/approvalDecidedByCapability.js +2 -2
- package/dist/approvalFrameFamilies.d.ts +33 -0
- package/dist/approvalFrameFamilies.js +120 -0
- package/dist/approvalsStreamLiveCapability.js +2 -2
- package/dist/attachmentsWireCaps.js +41 -13
- package/dist/callerCwdCapability.js +2 -2
- package/dist/centerWiringCapability.js +2 -2
- package/dist/clockReading.d.ts +2 -0
- package/dist/clockReading.js +4 -0
- package/dist/cloudConfigWireCaps.d.ts +19 -5
- package/dist/cloudConfigWireCaps.js +193 -56
- package/dist/coreValuePorts.d.ts +12 -2
- package/dist/coreValuePorts.js +9 -0
- package/dist/decideFailureNote.js +5 -3
- package/dist/decideReceipt.js +2 -2
- package/dist/deviceExecutorManagementCapability.js +2 -2
- package/dist/deviceFlowPolling.js +1 -1
- package/dist/disableSkillsWire.d.ts +1 -1
- package/dist/disableSkillsWire.js +4 -3
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +65 -8
- package/dist/engineCapReader.js +1 -1
- package/dist/engineConfigDrift.js +1 -1
- package/dist/engineErrorCodes.d.ts +14 -5
- package/dist/engineErrorCodes.js +27 -6
- package/dist/engineGenerationConvergence.d.ts +39 -0
- package/dist/engineGenerationConvergence.js +95 -0
- package/dist/engineGenerationPort.d.ts +61 -0
- package/dist/engineGenerationPort.js +144 -0
- package/dist/engineHealthFacts.d.ts +23 -0
- package/dist/engineHealthFacts.js +92 -0
- package/dist/engineIdentity.d.ts +4 -0
- package/dist/engineIdentity.js +11 -0
- package/dist/engineNoticeCodes.d.ts +2 -5
- package/dist/engineRowRef.js +3 -0
- package/dist/engineSessionMessages.js +2 -2
- package/dist/engineToolDirectory.js +2 -2
- package/dist/engineWireFor.d.ts +99 -0
- package/dist/engineWireFor.js +248 -6
- package/dist/engineWireTarget.d.ts +1 -0
- package/dist/engineWireTarget.js +8 -0
- package/dist/env/uiLanguage.js +1 -1
- package/dist/errorSupplementRoles.d.ts +3 -0
- package/dist/errorSupplementRoles.js +37 -0
- package/dist/executionLaneCapability.js +2 -2
- package/dist/fileHistoryCaptureCapability.js +3 -3
- package/dist/finalVerifyWire.d.ts +6 -3
- package/dist/finalVerifyWire.js +6 -23
- package/dist/flagInput.d.ts +4 -0
- package/dist/flagInput.js +24 -0
- package/dist/fleet/fleetLedger.js +5 -2
- package/dist/fleet/fleetProjection.d.ts +1 -0
- package/dist/fleet/fleetProjection.js +15 -2
- package/dist/gateVocabulary.js +3 -0
- package/dist/generated/engineFactTables.d.ts +7 -3
- package/dist/generated/engineFactTables.js +52 -0
- package/dist/generated/engineNoticeTables.js +12 -0
- package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
- package/dist/generated/settingsSchemaActiveTiers.js +14 -0
- package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
- package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
- package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
- package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
- package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
- package/dist/generated/settingsSchemaDefaultModel.js +25 -0
- package/dist/generated/settingsSchemaFns.d.ts +54 -0
- package/dist/generated/settingsSchemaFns.js +26 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
- package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
- package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
- package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
- package/dist/generated/settingsSchemaSettingsSources.js +58 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +13 -0
- package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlPattern.js +183 -0
- package/dist/headlessPermissionModeWire.d.ts +18 -2
- package/dist/headlessPermissionModeWire.js +30 -19
- package/dist/hitl/allowRuleShadow.js +7 -5
- package/dist/hitl/approvalCardReading.d.ts +3 -0
- package/dist/hitl/approvalCardReading.js +17 -0
- package/dist/hitl/approvalCompleteParked.js +1 -1
- package/dist/hitl/approvalDelivery.d.ts +87 -0
- package/dist/hitl/approvalDelivery.js +193 -0
- package/dist/hitl/approvalResolution.d.ts +11 -0
- package/dist/hitl/approvalResolution.js +50 -11
- package/dist/hitl/askClassPair.d.ts +6 -0
- package/dist/hitl/askClassPair.js +30 -3
- package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
- package/dist/hitl/askParkAutoReopenBlock.js +117 -0
- package/dist/hitl/askParkRowRouting.js +4 -1
- package/dist/hitl/attributionLadder.d.ts +42 -3
- package/dist/hitl/attributionLadder.js +79 -8
- package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
- package/dist/hitl/automaticAnswerVerdict.js +46 -11
- package/dist/hitl/crashConverged.js +2 -2
- package/dist/hitl/decisionConflict.d.ts +6 -2
- package/dist/hitl/decisionConflict.js +24 -9
- package/dist/hitl/decisionRefusal.d.ts +20 -10
- package/dist/hitl/decisionRefusal.js +99 -54
- package/dist/hitl/decisionSend.d.ts +3 -0
- package/dist/hitl/decisionSend.js +87 -103
- package/dist/hitl/frameRouter.d.ts +1 -0
- package/dist/hitl/frameRouter.js +9 -2
- package/dist/hitl/hitlBridge.d.ts +18 -6
- package/dist/hitl/hitlBridge.js +41 -37
- package/dist/hitl/livePendingAsk.js +4 -3
- package/dist/hitl/noAllowCause.js +1 -1
- package/dist/hitl/parkResolver.js +3 -2
- package/dist/hitl/persistedRulesWire.js +1 -0
- package/dist/hitl/planReviewWire.d.ts +4 -0
- package/dist/hitl/planReviewWire.js +59 -30
- package/dist/hitl/resumeRunningCard.d.ts +3 -2
- package/dist/hitl/resumeRunningCard.js +17 -11
- package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
- package/dist/hitl/sessionPolicyDeliverable.js +62 -29
- package/dist/hitl/sessionPolicyWire.d.ts +13 -3
- package/dist/hitl/sessionPolicyWire.js +81 -16
- package/dist/hitl/standingRows.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +9 -10
- package/dist/hitl/toolApprovalWire.js +72 -54
- package/dist/hookMatcherVerdict.d.ts +2 -0
- package/dist/hookMatcherVerdict.js +12 -0
- package/dist/hooksCompactTransition.d.ts +19 -0
- package/dist/hooksCompactTransition.js +41 -0
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +202 -203
- package/dist/host.d.ts +1 -14
- package/dist/host.js +0 -8
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +1 -1
- package/dist/hostSettingsSource.d.ts +172 -0
- package/dist/hostSettingsSource.js +675 -0
- package/dist/hostTurnSettings.d.ts +73 -17
- package/dist/hostTurnSettings.js +594 -97
- package/dist/httpHookPolicy.d.ts +37 -0
- package/dist/httpHookPolicy.js +176 -0
- package/dist/humanTurn.d.ts +2 -1
- package/dist/humanTurn.js +37 -7
- package/dist/humanTurnRead.js +4 -3
- package/dist/humanTurnSentences.d.ts +10 -0
- package/dist/humanTurnSentences.js +74 -0
- package/dist/i18n/messages.en.d.ts +184 -2
- package/dist/i18n/messages.en.js +187 -5
- package/dist/i18n/messages.zh.js +197 -5
- package/dist/i18n/translate.js +3 -3
- package/dist/index.d.ts +69 -15
- package/dist/index.js +45 -13
- package/dist/inheritEnvCapability.d.ts +3 -1
- package/dist/inheritEnvCapability.js +31 -17
- package/dist/inheritEnvWire.d.ts +2 -1
- package/dist/inheritEnvWire.js +11 -5
- package/dist/interactiveToolsWire.d.ts +4 -2
- package/dist/interactiveToolsWire.js +5 -5
- package/dist/jsonFaithful.d.ts +20 -0
- package/dist/jsonFaithful.js +152 -0
- package/dist/limitsWire.d.ts +7 -2
- package/dist/limitsWire.js +19 -13
- package/dist/liveInitToolFace.d.ts +6 -1
- package/dist/liveInitToolFace.js +5 -3
- package/dist/liveModelCatalog.d.ts +22 -0
- package/dist/liveModelCatalog.js +132 -18
- package/dist/mcpPanel.js +1 -1
- package/dist/mcpProbeCapability.js +2 -2
- package/dist/mcpStatusSupersetKeys.d.ts +24 -0
- package/dist/mcpStatusSupersetKeys.js +45 -0
- package/dist/mcpToolToggles.js +2 -1
- package/dist/mcpWireCaps.d.ts +39 -1
- package/dist/mcpWireCaps.js +254 -50
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/model/catalogDefault.d.ts +24 -0
- package/dist/model/catalogDefault.js +4 -0
- package/dist/model/liveCatalogShape.js +5 -4
- package/dist/model/modelsPolicy.js +4 -3
- package/dist/model/onboardJudgement.d.ts +1 -0
- package/dist/model/onboardJudgement.js +1 -1
- package/dist/model/subagentModelWord.js +2 -2
- package/dist/modelCapabilityProbe.js +6 -6
- package/dist/modelIdentityResolvability.d.ts +10 -1
- package/dist/modelIdentityResolvability.js +62 -39
- package/dist/modsKernelIdentity.d.ts +10 -0
- package/dist/modsKernelIdentity.js +103 -0
- package/dist/modsKernelTransit.d.ts +8 -0
- package/dist/modsKernelTransit.js +6 -0
- package/dist/notifications.d.ts +30 -12
- package/dist/notifications.js +241 -53
- package/dist/outputStyleSeatCapability.js +2 -2
- package/dist/ownKey.d.ts +11 -0
- package/dist/ownKey.js +164 -3
- package/dist/panelReduce.js +1 -1
- package/dist/peerFrames.d.ts +1 -1
- package/dist/peerFrames.js +6 -2
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.js +4 -4
- package/dist/permissionRuleIssue.js +2 -0
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionsAllowGrantCapability.js +2 -2
- package/dist/permissionsDeclaration.d.ts +43 -4
- package/dist/permissionsDeclaration.js +102 -35
- package/dist/pluginHooksWire.d.ts +20 -4
- package/dist/pluginHooksWire.js +92 -53
- package/dist/prepareRefusal.d.ts +3 -2
- package/dist/prepareRefusal.js +27 -9
- package/dist/printInitToolFace.js +2 -2
- package/dist/printModelStatus.js +1 -1
- package/dist/projectMemory.d.ts +32 -0
- package/dist/projectMemory.js +70 -0
- package/dist/promptBlockedCopy.d.ts +2 -1
- package/dist/promptBlockedCopy.js +2 -1
- package/dist/promptDelivery.d.ts +23 -3
- package/dist/promptDelivery.js +169 -30
- package/dist/providerRejection.d.ts +19 -1
- package/dist/providerRejection.js +75 -4
- package/dist/queuedDelivery.d.ts +48 -0
- package/dist/queuedDelivery.js +233 -0
- package/dist/reattachWindow.d.ts +94 -0
- package/dist/reattachWindow.js +127 -0
- package/dist/request/printNotification.d.ts +1 -1
- package/dist/request/printNotification.js +5 -1
- package/dist/request/submissionIdentity.d.ts +37 -0
- package/dist/request/submissionIdentity.js +65 -0
- package/dist/request/taskRequest.d.ts +12 -4
- package/dist/request/taskRequest.js +221 -152
- package/dist/resultFrameKeys.d.ts +1 -0
- package/dist/resultFrameKeys.js +4 -1
- package/dist/retryStatus.d.ts +8 -0
- package/dist/retryStatus.js +57 -9
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/rewindEngineAction.d.ts +2 -0
- package/dist/rewindEngineAction.js +23 -1
- package/dist/rowKind.d.ts +36 -0
- package/dist/rowKind.js +97 -0
- package/dist/ruleCompileVerdict.d.ts +18 -0
- package/dist/ruleCompileVerdict.js +67 -2
- package/dist/ruleReadings.d.ts +58 -0
- package/dist/ruleReadings.js +132 -0
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +9 -3
- package/dist/runCancelContext.d.ts +0 -1
- package/dist/runCancelContext.js +1 -2
- package/dist/runTerminal.d.ts +5 -0
- package/dist/runTerminal.js +52 -17
- package/dist/sandboxWire.d.ts +1 -1
- package/dist/sandboxWire.js +4 -6
- package/dist/scenarioRefusal.js +1 -1
- package/dist/scenarioSkills.d.ts +20 -0
- package/dist/scenarioSkills.js +72 -0
- package/dist/scenarioWire.d.ts +5 -2
- package/dist/scenarioWire.js +9 -9
- package/dist/sealedKeyCapability.js +2 -2
- package/dist/seam.d.ts +2 -0
- package/dist/seam.js +2 -2
- package/dist/seatContract.d.ts +46 -1
- package/dist/seatContract.js +49 -19
- package/dist/selfOrchestrationDenial.js +1 -1
- package/dist/sessionPolicyCapability.js +2 -2
- package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
- package/dist/sessionRulesChildrenReadLive.js +5 -0
- package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
- package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
- package/dist/sessionSyncFileHistoryCapability.js +2 -2
- package/dist/settingsCredentialKeyPaths.js +60 -5
- package/dist/settingsHooksSalvage.d.ts +1 -0
- package/dist/settingsHooksSalvage.js +7 -1
- package/dist/settingsLayerAdmission.d.ts +4 -0
- package/dist/settingsLayerAdmission.js +16 -0
- package/dist/skillToolListsCapability.js +6 -5
- package/dist/skillsWireCaps.d.ts +14 -0
- package/dist/skillsWireCaps.js +47 -16
- package/dist/slashCommandGate.d.ts +24 -0
- package/dist/slashCommandGate.js +74 -0
- package/dist/slashCommandTable.d.ts +14 -0
- package/dist/slashCommandTable.js +99 -0
- package/dist/sqlEngineCapability.js +2 -2
- package/dist/steerPriorityCapability.js +2 -2
- package/dist/storePostureCapability.js +2 -2
- package/dist/subagent/agentStateDetail.js +1 -1
- package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
- package/dist/subagent/engineDelegatedPrompt.js +38 -7
- package/dist/subagent/engineRowStopGate.js +2 -2
- package/dist/subagent/engineSubagentResume.js +3 -3
- package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
- package/dist/subagent/engineTaskHandleWire.js +10 -0
- package/dist/submitFailure.d.ts +8 -0
- package/dist/submitFailure.js +17 -0
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +7 -0
- package/dist/terminationIntent.d.ts +55 -0
- package/dist/terminationIntent.js +352 -0
- package/dist/toolHistoryMismatch.d.ts +8 -0
- package/dist/toolHistoryMismatch.js +37 -6
- package/dist/toolResult.d.ts +13 -3
- package/dist/toolResult.js +158 -9
- package/dist/toolResultContent.d.ts +13 -0
- package/dist/toolResultContent.js +82 -7
- package/dist/toolRoster.d.ts +18 -0
- package/dist/toolRoster.js +64 -0
- package/dist/turnFailurePresentation.js +27 -90
- package/dist/usageLimitAutoResume.d.ts +74 -0
- package/dist/usageLimitAutoResume.js +227 -0
- package/dist/userAttachmentEnvelope.js +1 -1
- package/dist/userAttachmentSeat.js +5 -5
- package/dist/userInvokedSkillsCapability.js +2 -2
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/wireErrorTriage.js +99 -50
- package/dist/wireFailureShape.d.ts +25 -1
- package/dist/wireFailureShape.js +92 -5
- package/dist/wireRefusalCopy.d.ts +24 -1
- package/dist/wireRefusalCopy.js +253 -32
- package/dist/wiringFleetDoctor.d.ts +3 -0
- package/dist/wiringFleetDoctor.js +21 -0
- package/dist/workflow.d.ts +2 -1
- package/dist/workflow.js +38 -1
- package/dist/workflowClient.d.ts +2 -7
- package/dist/workflowsJournalCapability.js +2 -2
- package/dist/writeProtectionCapability.js +2 -2
- package/docs/INTEGRATION-CLIENTS.md +607 -181
- package/package.json +14 -3
package/dist/hooksWireCaps.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { engineCapNestedTrue, engineCapState, engineCapValue } from './engineCapsCache.js';
|
|
2
2
|
import { msg, renderMessage } from './i18n/translate.js';
|
|
3
3
|
import { capForDisplay, collapseLabel } from './fleetTaskDesc.js';
|
|
4
|
-
import { hostLog
|
|
5
|
-
import {
|
|
4
|
+
import { hostLog } from './host.js';
|
|
5
|
+
import { faultText } from './hostCallbackGuard.js';
|
|
6
|
+
import { HostSettingsSourceShapeError, MANAGED_READING_DISPOSITIONS, mergedBooleanOf, nonManagedLayerDown, readHostSettingsOnce } from './hostSettingsSource.js';
|
|
7
|
+
import { admittedLayers, layerAdmissionWord } from './settingsLayerAdmission.js';
|
|
8
|
+
import { guardedRead, readOwnDataValue } from './ownKey.js';
|
|
9
|
+
import { HOOK_SETTINGS_SOURCE_TEXT, hooksSalvageMaskOf, salvageSettingsHooksEntries, settingsHooksSalvageNotice } from './settingsHooksSalvage.js';
|
|
10
|
+
import { submissionOriginOf } from './request/submissionIdentity.js';
|
|
6
11
|
import { createSettingsHookJudge, decidePluginHooks, decideSessionHooks, dedupeSettingsHookGroups, filterSettingsHookGroups, hooksWirePlanShapeOf, occupancyOf, } from './pluginHooksWire.js';
|
|
7
12
|
import { MAX_HOOK_NOTICE_TEXT_CHARS } from './notifications.js';
|
|
13
|
+
import { applyHttpHookPolicy, httpHookAdmittedSources, readHttpHookPolicy, wireHasHttpEntry } from './httpHookPolicy.js';
|
|
8
14
|
import { goalStopHookMatcher, __resetGoalStopHookForTests } from './goalStopHook.js';
|
|
9
15
|
export { GOAL_STOP_HOOK_WIRE_ENV, isGoalStopHookWireArmed, setWireSessionStopHook, getWireSessionStopHook, } from './goalStopHook.js';
|
|
10
16
|
const EDITABLE_HOOK_SOURCES = ['userSettings', 'projectSettings', 'localSettings'];
|
|
@@ -18,96 +24,13 @@ function hooksLockedToPluginOnly(policyValue) {
|
|
|
18
24
|
return policyValue.includes('hooks');
|
|
19
25
|
return false;
|
|
20
26
|
}
|
|
21
|
-
let warnedNoMergedReader = new WeakSet();
|
|
22
|
-
const NO_MERGED_READER_WARNING = 'client-core: the installed settings port does not implement mergedDisableAllHooks() — ' +
|
|
23
|
-
'a disableAllHooks set in user, project, local or flag settings is not applied to hooks sent to the engine ' +
|
|
24
|
-
'(only a managed-settings disableAllHooks is). Implement SettingsPort.mergedDisableAllHooks() to return ' +
|
|
25
|
-
'the effective merged value.';
|
|
26
|
-
function nonManagedDisableAllHooks(settings) {
|
|
27
|
-
try {
|
|
28
|
-
if (typeof settings.mergedDisableAllHooks === 'function')
|
|
29
|
-
return settings.mergedDisableAllHooks() === true;
|
|
30
|
-
}
|
|
31
|
-
catch (err) {
|
|
32
|
-
hostLog('debug', `hooksWireCaps: merged disableAllHooks read threw — fail-closed (only policySettings hooks projected to the engine): ${String(err)}`);
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
if (!warnedNoMergedReader.has(settings)) {
|
|
36
|
-
warnedNoMergedReader.add(settings);
|
|
37
|
-
hostLog('warn', NO_MERGED_READER_WARNING);
|
|
38
|
-
}
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
const HOOKS_STARTUP_MODES = ['safe', 'bare'];
|
|
42
|
-
const _startupModesPin = [true, true];
|
|
43
|
-
void _startupModesPin;
|
|
44
|
-
function describeStartupModeValue(v) {
|
|
45
|
-
if (v === null)
|
|
46
|
-
return 'null';
|
|
47
|
-
if (typeof v === 'string')
|
|
48
|
-
return JSON.stringify(v.length > 40 ? `${v.slice(0, 40)}…` : v);
|
|
49
|
-
return typeof v;
|
|
50
|
-
}
|
|
51
|
-
function startupModeWord(settings) {
|
|
52
|
-
let v;
|
|
53
|
-
try {
|
|
54
|
-
const member = settings.hooksStartupMode;
|
|
55
|
-
if (member === undefined)
|
|
56
|
-
return undefined;
|
|
57
|
-
if (typeof member !== 'function') {
|
|
58
|
-
hostLog('debug', `hooksWireCaps: hooksStartupMode is ${describeStartupModeValue(member)}, not a method — treated as neither safe nor bare mode (settings hooks not narrowed)`);
|
|
59
|
-
return undefined;
|
|
60
|
-
}
|
|
61
|
-
v = member.call(settings);
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
hostLog('debug', `hooksWireCaps: hooksStartupMode() threw — treated as neither safe nor bare mode (settings hooks not narrowed): ${String(err)}`);
|
|
65
|
-
return undefined;
|
|
66
|
-
}
|
|
67
|
-
if (v === undefined)
|
|
68
|
-
return undefined;
|
|
69
|
-
const word = HOOKS_STARTUP_MODES.find((w) => w === v);
|
|
70
|
-
if (word !== undefined)
|
|
71
|
-
return word;
|
|
72
|
-
hostLog('debug', `hooksWireCaps: hooksStartupMode() returned ${describeStartupModeValue(v)}, which is neither 'safe' nor 'bare' — treated as neither mode (settings hooks not narrowed)`);
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
75
|
-
const MANAGED_POLICY_STATES = ['absent', 'in-effect', 'unreadable'];
|
|
76
|
-
const _managedPolicyStatesPin = [true, true];
|
|
77
|
-
void _managedPolicyStatesPin;
|
|
78
|
-
function managedPolicyUnreadable(settings) {
|
|
79
|
-
try {
|
|
80
|
-
const member = settings.managedPolicyReading;
|
|
81
|
-
if (member === undefined)
|
|
82
|
-
return false;
|
|
83
|
-
if (typeof member !== 'function') {
|
|
84
|
-
hostLog('debug', `hooksWireCaps: managedPolicyReading is ${describeStartupModeValue(member)}, not a method — fail-closed (no hooks projected to the engine)`);
|
|
85
|
-
return true;
|
|
86
|
-
}
|
|
87
|
-
const r = member.call(settings);
|
|
88
|
-
const state = typeof r === 'object' && r !== null && !Array.isArray(r) ? r.state : undefined;
|
|
89
|
-
const word = MANAGED_POLICY_STATES.find((w) => w === state);
|
|
90
|
-
if (word === 'absent' || word === 'in-effect')
|
|
91
|
-
return false;
|
|
92
|
-
if (word === 'unreadable') {
|
|
93
|
-
hostLog('debug', 'hooksWireCaps: managed policy layer reported unreadable — fail-closed (no hooks projected to the engine)');
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
hostLog('debug', `hooksWireCaps: managedPolicyReading() returned ${describeStartupModeValue(state)} as its state, which is none of 'absent' / 'in-effect' / 'unreadable' — fail-closed (no hooks projected to the engine)`);
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
hostLog('debug', `hooksWireCaps: managedPolicyReading() threw — fail-closed (no hooks projected to the engine): ${String(err)}`);
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
27
|
const NO_LAYER = Object.freeze({ hooks: null, mask: undefined });
|
|
105
28
|
function layerOfDoc(source, doc) {
|
|
106
29
|
try {
|
|
107
30
|
return classifyLayer(source, doc);
|
|
108
31
|
}
|
|
109
32
|
catch (err) {
|
|
110
|
-
hostLog('debug', `hooksWireCaps: ${source} settings could not be read by the hooks reader — treated as no hooks from this source: ${
|
|
33
|
+
hostLog('debug', `hooksWireCaps: ${source} settings could not be read by the hooks reader — treated as no hooks from this source: ${faultText(err)}`);
|
|
111
34
|
return NO_LAYER;
|
|
112
35
|
}
|
|
113
36
|
}
|
|
@@ -123,71 +46,47 @@ function classifyLayer(source, doc) {
|
|
|
123
46
|
return { hooks: null, mask: undefined, row };
|
|
124
47
|
return { hooks: original, mask: hooksSalvageMaskOf(salvage.dropped), row };
|
|
125
48
|
}
|
|
126
|
-
function layerOfSource(source) {
|
|
49
|
+
function layerOfSource(source, docOf) {
|
|
127
50
|
let doc;
|
|
128
51
|
try {
|
|
129
|
-
doc =
|
|
52
|
+
doc = docOf(source);
|
|
130
53
|
}
|
|
131
54
|
catch (err) {
|
|
132
|
-
hostLog('debug', `hooksWireCaps: ${source} settings read
|
|
55
|
+
hostLog('debug', `hooksWireCaps: ${source} settings could not be read — treated as no hooks from this source: ${faultText(err)}`);
|
|
133
56
|
return NO_LAYER;
|
|
134
57
|
}
|
|
135
58
|
return layerOfDoc(source, doc);
|
|
136
59
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
60
|
+
class LayerUnreadable extends Error {
|
|
61
|
+
layer;
|
|
62
|
+
constructor(layer) {
|
|
63
|
+
super(`${layer} settings unreadable`);
|
|
64
|
+
this.layer = layer;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
141
67
|
function guardPluginTraversal(run) {
|
|
142
68
|
try {
|
|
143
69
|
return run();
|
|
144
70
|
}
|
|
145
71
|
catch (err) {
|
|
146
|
-
hostLog('debug', `hooksWireCaps: plugin hook data threw while being read — no plugin hooks projected this turn: ${
|
|
72
|
+
hostLog('debug', `hooksWireCaps: plugin hook data threw while being read — no plugin hooks projected this turn: ${faultText(err)}`);
|
|
147
73
|
return undefined;
|
|
148
74
|
}
|
|
149
75
|
}
|
|
150
|
-
function
|
|
151
|
-
|
|
152
|
-
if (typeof settings.enabledPluginHooks === 'function') {
|
|
153
|
-
const r = settings.enabledPluginHooks();
|
|
154
|
-
if (typeof r === 'object' && r !== null && Array.isArray(r.plugins)) {
|
|
155
|
-
return { state: 'present', reading: r };
|
|
156
|
-
}
|
|
157
|
-
hostLog('debug', 'hooksWireCaps: enabledPluginHooks() returned a malformed reading — no plugin hooks projected this turn');
|
|
158
|
-
return { state: 'failed' };
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
catch (err) {
|
|
162
|
-
hostLog('debug', `hooksWireCaps: enabledPluginHooks() threw — no plugin hooks projected this turn: ${String(err)}`);
|
|
163
|
-
return { state: 'failed' };
|
|
164
|
-
}
|
|
165
|
-
if (warnIfAbsent && !warnedNoPluginReader.has(settings)) {
|
|
166
|
-
warnedNoPluginReader.add(settings);
|
|
167
|
-
hostLog('warn', NO_PLUGIN_READER_WARNING);
|
|
168
|
-
}
|
|
169
|
-
return { state: 'absent' };
|
|
170
|
-
}
|
|
171
|
-
function readSessionHooks(settings) {
|
|
76
|
+
function compactionOnShellOf(o) {
|
|
77
|
+
let raw;
|
|
172
78
|
try {
|
|
173
|
-
|
|
174
|
-
if (member === undefined)
|
|
175
|
-
return { state: 'absent' };
|
|
176
|
-
if (typeof member !== 'function') {
|
|
177
|
-
hostLog('debug', 'hooksWireCaps: sessionHooks is not a method — no session hooks judged this turn');
|
|
178
|
-
return { state: 'failed' };
|
|
179
|
-
}
|
|
180
|
-
const r = member.call(settings);
|
|
181
|
-
const sources = typeof r === 'object' && r !== null ? r.sources : undefined;
|
|
182
|
-
if (Array.isArray(sources))
|
|
183
|
-
return { state: 'present', sources };
|
|
184
|
-
hostLog('debug', 'hooksWireCaps: sessionHooks() returned a malformed reading — no session hooks judged this turn');
|
|
185
|
-
return { state: 'failed' };
|
|
79
|
+
raw = o.compactionOnShell;
|
|
186
80
|
}
|
|
187
|
-
catch
|
|
188
|
-
hostLog('debug',
|
|
189
|
-
return
|
|
81
|
+
catch {
|
|
82
|
+
hostLog('debug', 'hooksWirePlan: compactionOnShell threw while being read — treated as absent (compaction hooks judged as before)');
|
|
83
|
+
return false;
|
|
190
84
|
}
|
|
85
|
+
if (raw === undefined || raw === false)
|
|
86
|
+
return false;
|
|
87
|
+
if (raw !== true)
|
|
88
|
+
hostLog('debug', 'hooksWirePlan: compactionOnShell is not the boolean true — treated as absent (compaction hooks judged as before)');
|
|
89
|
+
return raw === true;
|
|
191
90
|
}
|
|
192
91
|
function suppressedLocallyOf(o) {
|
|
193
92
|
let raw;
|
|
@@ -249,8 +148,20 @@ export function hooksForWire(opts) {
|
|
|
249
148
|
throw usageError(given === undefined ? msg('config.hooks.forWire.planMissing') : msg('config.hooks.forWire.planNotPlan', { shape: hostValueShape(given) }));
|
|
250
149
|
}
|
|
251
150
|
const planShapeOf = hooksWirePlanShapeOf;
|
|
252
|
-
export function hooksWirePlan(opts
|
|
253
|
-
|
|
151
|
+
export function hooksWirePlan(opts) {
|
|
152
|
+
if (typeof opts !== 'object' || opts === null)
|
|
153
|
+
throw new HostSettingsSourceShapeError('hooksWirePlan: pass { settings, ... } where settings is the HostSettingsSource for this turn.');
|
|
154
|
+
const o = opts;
|
|
155
|
+
let given;
|
|
156
|
+
try {
|
|
157
|
+
given = o.settings;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
throw new HostSettingsSourceShapeError('hooksWirePlan: reading opts.settings threw — pass { settings, ... } where settings is the HostSettingsSource for this turn.');
|
|
161
|
+
}
|
|
162
|
+
const read = readHostSettingsOnce(given, 'hooksWirePlan');
|
|
163
|
+
for (const line of read.debug)
|
|
164
|
+
hostLog('debug', line);
|
|
254
165
|
const owned = o.engineOwnedByThisShell;
|
|
255
166
|
const engine = {
|
|
256
167
|
ownedByThisShell: owned === true ? true : owned === false ? false : null,
|
|
@@ -274,7 +185,7 @@ export function hooksWirePlan(opts = {}) {
|
|
|
274
185
|
const types = typesByEvent.get(event);
|
|
275
186
|
return types === undefined || (typeof type === 'string' && types.has(type));
|
|
276
187
|
};
|
|
277
|
-
return buildHooksWirePlan(engine, shellRuns, promptAuthoredByUserOf(o), suppressedLocallyOf(o));
|
|
188
|
+
return buildHooksWirePlan(read, engine, shellRuns, promptAuthoredByUserOf(o), suppressedLocallyOf(o), compactionOnShellOf(o));
|
|
278
189
|
}
|
|
279
190
|
function taskHooksCapability(baseUrl) {
|
|
280
191
|
const v = engineCapValue(baseUrl, 'taskSettings');
|
|
@@ -305,17 +216,53 @@ function shellHookTypesOf(o) {
|
|
|
305
216
|
return out;
|
|
306
217
|
}
|
|
307
218
|
catch (err) {
|
|
308
|
-
hostLog('debug', `hooksWirePlan: shellHookTypesByEvent is malformed — treated as absent (command and http hooks count as running on every reported event; prompt and agent hooks are not counted as running locally): ${
|
|
219
|
+
hostLog('debug', `hooksWirePlan: shellHookTypesByEvent is malformed — treated as absent (command and http hooks count as running on every reported event; prompt and agent hooks are not counted as running locally): ${faultText(err)}`);
|
|
309
220
|
return undefined;
|
|
310
221
|
}
|
|
311
222
|
}
|
|
312
223
|
function promptAuthoredByUserOf(o) {
|
|
224
|
+
const origin = identityOriginOf(o);
|
|
225
|
+
if (origin === undefined)
|
|
226
|
+
return legacyPromptAuthoredByUserOf(o);
|
|
227
|
+
const derived = origin === 'user';
|
|
228
|
+
let v;
|
|
229
|
+
try {
|
|
230
|
+
v = o.promptAuthoredByUser;
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
hostLog('debug', 'hooksWirePlan: promptAuthoredByUser threw while being read — ignored, the submission identity decides');
|
|
234
|
+
return derived;
|
|
235
|
+
}
|
|
236
|
+
if (v === undefined || v === derived)
|
|
237
|
+
return derived;
|
|
238
|
+
hostLog('debug', v === true || v === false
|
|
239
|
+
? `hooksWirePlan: promptAuthoredByUser (${String(v)}) conflicts with the submission identity (origin ${origin}) — the identity decides`
|
|
240
|
+
: 'hooksWirePlan: promptAuthoredByUser is not a boolean — ignored, the submission identity decides');
|
|
241
|
+
return derived;
|
|
242
|
+
}
|
|
243
|
+
function identityOriginOf(o) {
|
|
244
|
+
let raw;
|
|
245
|
+
try {
|
|
246
|
+
raw = o.identity;
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
hostLog('debug', 'hooksWirePlan: identity threw while being read — treated as absent (the promptAuthoredByUser slot decides, as before)');
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
if (raw === undefined || raw === null)
|
|
253
|
+
return undefined;
|
|
254
|
+
const origin = typeof raw === 'object' ? submissionOriginOf(raw) : undefined;
|
|
255
|
+
if (origin === undefined)
|
|
256
|
+
hostLog('debug', 'hooksWirePlan: identity is not a submission identity — treated as absent (the promptAuthoredByUser slot decides, as before)');
|
|
257
|
+
return origin;
|
|
258
|
+
}
|
|
259
|
+
function legacyPromptAuthoredByUserOf(o) {
|
|
313
260
|
let v;
|
|
314
261
|
try {
|
|
315
262
|
v = o.promptAuthoredByUser;
|
|
316
263
|
}
|
|
317
264
|
catch (err) {
|
|
318
|
-
hostLog('debug', `hooksWirePlan: promptAuthoredByUser threw while being read — treated as written by the user: ${
|
|
265
|
+
hostLog('debug', `hooksWirePlan: promptAuthoredByUser threw while being read — treated as written by the user: ${faultText(err)}`);
|
|
319
266
|
return true;
|
|
320
267
|
}
|
|
321
268
|
if (v === false)
|
|
@@ -325,15 +272,44 @@ function promptAuthoredByUserOf(o) {
|
|
|
325
272
|
}
|
|
326
273
|
return true;
|
|
327
274
|
}
|
|
328
|
-
function
|
|
275
|
+
function layerWritesHooks(doc) {
|
|
276
|
+
const hooks = guardedRead(() => readOwnDataValue(doc, 'hooks'));
|
|
277
|
+
if (typeof hooks !== 'object' || hooks === null || Array.isArray(hooks))
|
|
278
|
+
return false;
|
|
279
|
+
try {
|
|
280
|
+
return Object.keys(hooks).length > 0;
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function withheldRowsOf(candidates, trust, layers) {
|
|
287
|
+
const rows = [];
|
|
288
|
+
for (const source of candidates) {
|
|
289
|
+
if (!layerWritesHooks(layers[source].doc))
|
|
290
|
+
continue;
|
|
291
|
+
if (layerAdmissionWord(source, trust, 'hooks') !== 'trust_withheld')
|
|
292
|
+
continue;
|
|
293
|
+
rows.push(Object.freeze({
|
|
294
|
+
source,
|
|
295
|
+
cause: 'trust_withheld',
|
|
296
|
+
notice: renderMessage(msg('config.hooks.layerWithheld.trust', { layer: HOOK_SETTINGS_SOURCE_TEXT[source] })),
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
return rows;
|
|
300
|
+
}
|
|
301
|
+
function buildHooksWirePlan(read, engine, shellRuns, promptAuthoredByUser, suppressedLocally, compactionOnShell = false) {
|
|
329
302
|
const settingsDropped = [];
|
|
330
303
|
const settingsVerdicts = [];
|
|
331
304
|
const settingsExcluded = [];
|
|
332
305
|
const settingsSalvage = [];
|
|
306
|
+
const httpPolicyDrops = [];
|
|
333
307
|
let sessionVerdicts = [];
|
|
334
308
|
let sessionReader = 'absent';
|
|
335
309
|
let closedBy = null;
|
|
336
|
-
|
|
310
|
+
let settingsSourcesNow = [];
|
|
311
|
+
let settingsWithheldNow = [];
|
|
312
|
+
const judge = createSettingsHookJudge(engine, shellRuns, promptAuthoredByUser, compactionOnShell);
|
|
337
313
|
let settingsStripped = 0;
|
|
338
314
|
const planOf = (pluginReader, wire, verdicts = [], excluded = [], moduleVerdicts = []) => ({
|
|
339
315
|
engine,
|
|
@@ -344,19 +320,22 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser, suppressedL
|
|
|
344
320
|
settingsVerdicts,
|
|
345
321
|
settingsExcluded,
|
|
346
322
|
settingsSalvage,
|
|
323
|
+
httpPolicyDrops: [...httpPolicyDrops],
|
|
347
324
|
moduleVerdicts,
|
|
348
325
|
sessionVerdicts,
|
|
349
326
|
sessionReader,
|
|
350
327
|
closedBy,
|
|
328
|
+
settingsSources: closedBy === null ? settingsSourcesNow : [],
|
|
329
|
+
settingsWithheld: closedBy === null ? settingsWithheldNow : [],
|
|
351
330
|
wire,
|
|
352
331
|
});
|
|
353
|
-
const closedPlan = (
|
|
332
|
+
const closedPlan = (reason) => {
|
|
354
333
|
closedBy = reason;
|
|
355
|
-
sessionReader =
|
|
356
|
-
const
|
|
357
|
-
if (
|
|
358
|
-
return planOf(
|
|
359
|
-
const reading =
|
|
334
|
+
sessionReader = read.sessionHooks.state;
|
|
335
|
+
const pr = read.plugins;
|
|
336
|
+
if (pr.reading === undefined)
|
|
337
|
+
return planOf(pr.state, undefined);
|
|
338
|
+
const reading = pr.reading;
|
|
360
339
|
const d = guardPluginTraversal(() => decidePluginHooks({
|
|
361
340
|
plugins: reading.plugins,
|
|
362
341
|
exclusion: reason,
|
|
@@ -368,64 +347,82 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser, suppressedL
|
|
|
368
347
|
}));
|
|
369
348
|
if (d === undefined)
|
|
370
349
|
return planOf('failed', undefined);
|
|
371
|
-
return planOf(
|
|
350
|
+
return planOf(pr.state, undefined, d.verdicts, d.excluded);
|
|
372
351
|
};
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
if (
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
policy = policyDoc;
|
|
393
|
-
}
|
|
394
|
-
catch (err) {
|
|
395
|
-
hostLog('debug', `hooksWireCaps: policySettings read threw — fail-closed (no hooks projected to the engine): ${String(err)}`);
|
|
396
|
-
return closedPlan(settings, 'governance_unreadable');
|
|
397
|
-
}
|
|
352
|
+
if (read.trust === 'unreadable')
|
|
353
|
+
return closedPlan('governance_unreadable');
|
|
354
|
+
if (read.trust === 'declined') {
|
|
355
|
+
hostLog('debug', 'hooksWireCaps: workspace not trusted — no hooks projected to the engine');
|
|
356
|
+
return closedPlan('workspace_untrusted');
|
|
357
|
+
}
|
|
358
|
+
const managedReading = MANAGED_READING_DISPOSITIONS[read.managed];
|
|
359
|
+
if (managedReading.commit === 'refuse') {
|
|
360
|
+
hostLog('debug', `hooksWireCaps: managed policy layer reported ${read.managed} — fail-closed (no hooks projected to the engine)`);
|
|
361
|
+
return closedPlan('governance_unreadable');
|
|
362
|
+
}
|
|
363
|
+
const policySnap = read.layers.policySettings;
|
|
364
|
+
const policyCarrierDown = policySnap.outcome === 'unreadable' || policySnap.outcome === 'not-loaded';
|
|
365
|
+
if (policySnap.malformed || (policyCarrierDown && (read.managed === 'absent' || read.managed === 'in-effect'))) {
|
|
366
|
+
hostLog('debug', 'hooksWireCaps: policySettings could not be read — fail-closed (no hooks projected to the engine)');
|
|
367
|
+
return closedPlan('governance_unreadable');
|
|
368
|
+
}
|
|
369
|
+
const policyDoc = policySnap.doc;
|
|
370
|
+
const policy = policyDoc;
|
|
398
371
|
let policyLayer;
|
|
399
372
|
try {
|
|
400
373
|
policyLayer = classifyLayer('policySettings', policyDoc);
|
|
401
374
|
}
|
|
402
375
|
catch (err) {
|
|
403
|
-
hostLog('debug', `hooksWireCaps: managed settings could not be read by the hooks reader — fail-closed (no hooks projected to the engine): ${
|
|
404
|
-
return closedPlan(
|
|
376
|
+
hostLog('debug', `hooksWireCaps: managed settings could not be read by the hooks reader — fail-closed (no hooks projected to the engine): ${faultText(err)}`);
|
|
377
|
+
return closedPlan('governance_unreadable');
|
|
405
378
|
}
|
|
406
379
|
if (policyLayer.row?.outcome === 'rejected') {
|
|
407
380
|
settingsSalvage.push(policyLayer.row);
|
|
408
381
|
hostLog('debug', 'hooksWireCaps: managed settings hooks rejected by the hooks reader — fail-closed (no hooks projected to the engine)');
|
|
409
|
-
return closedPlan(
|
|
410
|
-
}
|
|
382
|
+
return closedPlan('governance_unreadable');
|
|
383
|
+
}
|
|
384
|
+
const docOnce = (source) => read.layers[source].doc;
|
|
385
|
+
const listDocOf = (source) => {
|
|
386
|
+
const snap = read.layers[source];
|
|
387
|
+
if (snap.malformed || snap.outcome === 'unreadable' || snap.outcome === 'not-loaded')
|
|
388
|
+
throw new LayerUnreadable(source);
|
|
389
|
+
return snap.doc;
|
|
390
|
+
};
|
|
391
|
+
const policyListDoc = () => {
|
|
392
|
+
if (managedReading.httpList === 'withhold')
|
|
393
|
+
throw new LayerUnreadable('policySettings');
|
|
394
|
+
return policyDoc;
|
|
395
|
+
};
|
|
411
396
|
if (policy?.disableAllHooks === true) {
|
|
412
397
|
hostLog('debug', 'hooksWireCaps: disableAllHooks (managed) — no hooks projected to the engine');
|
|
413
|
-
return closedPlan(
|
|
398
|
+
return closedPlan('policy_disable_all');
|
|
414
399
|
}
|
|
415
400
|
const pluginOnlyHooks = hooksLockedToPluginOnly(policy?.strictPluginOnlyCustomization);
|
|
416
401
|
if (pluginOnlyHooks) {
|
|
417
402
|
hostLog('debug', 'hooksWireCaps: strictPluginOnlyCustomization locks the hooks surface (managed) — only policySettings hooks projected to the engine');
|
|
418
403
|
}
|
|
419
|
-
const managedByPolicy = policy?.allowManagedHooksOnly === true || pluginOnlyHooks;
|
|
420
|
-
|
|
421
|
-
|
|
404
|
+
const managedByPolicy = policy?.allowManagedHooksOnly === true || pluginOnlyHooks || managedReading.hooksRestriction === 'withhold';
|
|
405
|
+
if (managedReading.hooksRestriction === 'withhold') {
|
|
406
|
+
hostLog('debug', `hooksWireCaps: managed policy layer reported ${read.managed} — only policySettings hooks projected to the engine`);
|
|
407
|
+
}
|
|
408
|
+
const mergedDisable = () => mergedBooleanOf(read, 'disableAllHooks') === true || (read.current !== undefined && mergedBooleanOf(read.current, 'disableAllHooks') === true) || nonManagedLayerDown(read);
|
|
422
409
|
const disabledByNonManaged = !managedByPolicy && mergedDisable();
|
|
423
410
|
if (disabledByNonManaged) {
|
|
424
411
|
hostLog('debug', 'hooksWireCaps: disableAllHooks (merged, non-managed) — only policySettings hooks projected to the engine');
|
|
425
412
|
}
|
|
426
413
|
const managedOnly = managedByPolicy || disabledByNonManaged;
|
|
414
|
+
let httpAdmitted;
|
|
415
|
+
let hookAdmitted;
|
|
416
|
+
try {
|
|
417
|
+
httpAdmitted = httpHookAdmittedSources(ALL_HOOK_SOURCES, read.trust);
|
|
418
|
+
hookAdmitted = admittedLayers(ALL_HOOK_SOURCES, read.trust, 'hooks');
|
|
419
|
+
}
|
|
420
|
+
catch (err) {
|
|
421
|
+
hostLog('debug', `http-hook-lists-admission-threw: ${faultText(err)}`);
|
|
422
|
+
return closedPlan('governance_unreadable');
|
|
423
|
+
}
|
|
427
424
|
{
|
|
428
|
-
const sr =
|
|
425
|
+
const sr = read.sessionHooks;
|
|
429
426
|
sessionReader = sr.state;
|
|
430
427
|
if (sr.sources !== undefined && !managedOnly) {
|
|
431
428
|
const sources = sr.sources;
|
|
@@ -439,29 +436,25 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser, suppressedL
|
|
|
439
436
|
}
|
|
440
437
|
}
|
|
441
438
|
}
|
|
442
|
-
const
|
|
443
|
-
let oldStartupBit;
|
|
444
|
-
let pluginDataThrew = false;
|
|
445
|
-
if (read.reading !== undefined) {
|
|
446
|
-
const reading = read.reading;
|
|
447
|
-
const bit = guardPluginTraversal(() => reading.suppressedByStartupMode === true);
|
|
448
|
-
if (bit === undefined)
|
|
449
|
-
pluginDataThrew = true;
|
|
450
|
-
else
|
|
451
|
-
oldStartupBit = bit;
|
|
452
|
-
}
|
|
453
|
-
const startupMode = startupModeWord(settings) ?? (oldStartupBit === true ? 'safe' : undefined);
|
|
439
|
+
const startupMode = read.startup === 'none' ? undefined : read.startup;
|
|
454
440
|
if (startupMode === 'bare') {
|
|
455
441
|
hostLog('debug', 'hooksWireCaps: bare mode reported by the host — only policySettings hooks projected to the engine (same as safe mode)');
|
|
456
442
|
}
|
|
457
443
|
else if (startupMode === 'safe') {
|
|
458
444
|
hostLog('debug', 'hooksWireCaps: safe mode reported by the host — only policySettings hooks projected to the engine');
|
|
459
445
|
}
|
|
460
|
-
const sources = managedOnly || startupMode !== undefined ? ['policySettings'] :
|
|
446
|
+
const sources = managedOnly || startupMode !== undefined ? ['policySettings'] : hookAdmitted;
|
|
447
|
+
settingsSourcesNow = Object.freeze([...sources]);
|
|
448
|
+
const notAdmitted = ALL_HOOK_SOURCES.filter((s) => !hookAdmitted.includes(s) && read.layers[s].doc !== null);
|
|
449
|
+
if (sources === hookAdmitted)
|
|
450
|
+
settingsWithheldNow = Object.freeze(withheldRowsOf(notAdmitted, read.trust, read.layers));
|
|
451
|
+
if (sources !== hookAdmitted ? false : notAdmitted.length > 0) {
|
|
452
|
+
hostLog('debug', `hooksWireCaps: workspace trust reading ${read.trust} — hooks from ${notAdmitted.join(', ')} are not admitted (repository-controlled layers need an accepted workspace)`);
|
|
453
|
+
}
|
|
461
454
|
const merged = {};
|
|
462
455
|
const sourced = new Map();
|
|
463
456
|
for (const source of sources) {
|
|
464
|
-
const layer = source === 'policySettings' ? policyLayer : layerOfSource(source);
|
|
457
|
+
const layer = source === 'policySettings' ? policyLayer : layerOfSource(source, docOnce);
|
|
465
458
|
if (layer.row !== undefined)
|
|
466
459
|
settingsSalvage.push(layer.row);
|
|
467
460
|
const hooks = layer.hooks;
|
|
@@ -510,17 +503,25 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser, suppressedL
|
|
|
510
503
|
hostLog('debug', `hooksWireCaps: ${settingsStripped} settings hook entr${settingsStripped === 1 ? 'y' : 'ies'} carried a plugin key — ` +
|
|
511
504
|
'stripped before sending (plugin context is only minted for entries from the plugin reader)');
|
|
512
505
|
}
|
|
513
|
-
const wireOf = () =>
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
506
|
+
const wireOf = () => {
|
|
507
|
+
if (Object.keys(merged).length === 0)
|
|
508
|
+
return undefined;
|
|
509
|
+
const applied = wireHasHttpEntry(merged)
|
|
510
|
+
? applyHttpHookPolicy(merged, readHttpHookPolicy(httpAdmitted, (layer) => (layer === 'policySettings' ? policyListDoc() : listDocOf(layer))))
|
|
511
|
+
: { wire: merged, rows: [] };
|
|
512
|
+
httpPolicyDrops.length = 0;
|
|
513
|
+
httpPolicyDrops.push(...applied.rows);
|
|
514
|
+
return applied.wire;
|
|
515
|
+
};
|
|
516
|
+
const pluginRead = read.plugins;
|
|
517
|
+
if (pluginRead.reading === undefined)
|
|
518
|
+
return planOf(pluginRead.state, wireOf());
|
|
519
|
+
const reading = pluginRead.reading;
|
|
519
520
|
const occupied = occupancyOf(merged);
|
|
520
521
|
const d = guardPluginTraversal(() => {
|
|
521
522
|
const plugins = reading.plugins;
|
|
522
523
|
const startup = startupMode !== undefined;
|
|
523
|
-
const managedOnlyPlugins = !startup && plugins.length > 0 && (policy?.allowManagedHooksOnly === true || mergedDisable());
|
|
524
|
+
const managedOnlyPlugins = !startup && plugins.length > 0 && (policy?.allowManagedHooksOnly === true || managedReading.hooksRestriction === 'withhold' || mergedDisable());
|
|
524
525
|
return decidePluginHooks({
|
|
525
526
|
plugins,
|
|
526
527
|
exclusion: startup ? 'startup_mode' : undefined,
|
|
@@ -543,8 +544,6 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser, suppressedL
|
|
|
543
544
|
}
|
|
544
545
|
export function __resetHooksWireCapsForTests() {
|
|
545
546
|
__resetGoalStopHookForTests();
|
|
546
|
-
warnedNoMergedReader = new WeakSet();
|
|
547
|
-
warnedNoPluginReader = new WeakSet();
|
|
548
547
|
}
|
|
549
548
|
export function fleetHookFailureNoticeCapable(baseUrl) {
|
|
550
549
|
return engineCapNestedTrue(baseUrl, 'fleet', 'hookFailureNotice');
|
package/dist/host.d.ts
CHANGED
|
@@ -2,16 +2,7 @@ import type { AdapterLogLevel, TimerHandle } from './seam.js';
|
|
|
2
2
|
import type { WireHooksConfig } from './finalVerifyWire.js';
|
|
3
3
|
import { type NotificationQueuePort } from './notifications.js';
|
|
4
4
|
export type SettingsDocument = Record<string, unknown>;
|
|
5
|
-
export
|
|
6
|
-
getSettingsForSource(source: string): SettingsDocument | null;
|
|
7
|
-
shouldSkipHookDueToTrust(hook?: unknown): boolean;
|
|
8
|
-
mergedDisableAllHooks?(): boolean | undefined;
|
|
9
|
-
enabledPluginHooks?(): PluginHooksReading;
|
|
10
|
-
hooksStartupMode?(): HooksStartupMode | undefined;
|
|
11
|
-
managedPolicyReading?(): ManagedPolicyReading;
|
|
12
|
-
sessionHooks?(): SessionHooksReading;
|
|
13
|
-
}
|
|
14
|
-
export type ManagedPolicyState = 'absent' | 'in-effect' | 'unreadable';
|
|
5
|
+
export type ManagedPolicyState = 'absent' | 'in-effect' | 'in-effect-pieces' | 'unreadable-covered' | 'unreadable-uncovered' | 'remote-unknown';
|
|
15
6
|
export interface ManagedPolicyReading {
|
|
16
7
|
readonly state: ManagedPolicyState;
|
|
17
8
|
}
|
|
@@ -56,7 +47,6 @@ export interface SessionHooksReading {
|
|
|
56
47
|
}
|
|
57
48
|
export interface PluginHooksReading {
|
|
58
49
|
readonly plugins: readonly PluginHookSource[];
|
|
59
|
-
readonly suppressedByStartupMode?: boolean;
|
|
60
50
|
}
|
|
61
51
|
export interface FsPort {
|
|
62
52
|
getScratchpadDir(): string | undefined;
|
|
@@ -76,7 +66,6 @@ export interface HostPorts {
|
|
|
76
66
|
probe?(channel: string, line: string): void;
|
|
77
67
|
queue?: NotificationQueuePort | null;
|
|
78
68
|
timers?: TimersPort;
|
|
79
|
-
settings?: SettingsPort;
|
|
80
69
|
fs?: FsPort;
|
|
81
70
|
session?: SessionPort;
|
|
82
71
|
}
|
|
@@ -84,8 +73,6 @@ export declare function installHost(ports: HostPorts): () => void;
|
|
|
84
73
|
export declare function installHostFor(sessionKey: string, ports: Omit<HostPorts, 'queue'>): () => void;
|
|
85
74
|
export declare function hostLog(level: AdapterLogLevel, msg: string, data?: unknown): boolean;
|
|
86
75
|
export declare function hostProbe(channel: string, line: string): void;
|
|
87
|
-
export declare function hostSettings(): SettingsPort | undefined;
|
|
88
|
-
export declare function hostSettingsFor(sessionKey: string): SettingsPort | undefined;
|
|
89
76
|
export declare function hostFs(): FsPort | undefined;
|
|
90
77
|
export declare function hostFsFor(sessionKey: string): FsPort | undefined;
|
|
91
78
|
export declare function hostTimers(): TimersPort | undefined;
|
package/dist/host.js
CHANGED
|
@@ -36,8 +36,6 @@ export function installHostFor(sessionKey, ports) {
|
|
|
36
36
|
slot.state.probe = ports.probe;
|
|
37
37
|
if ('timers' in ports)
|
|
38
38
|
slot.state.timers = ports.timers;
|
|
39
|
-
if ('settings' in ports)
|
|
40
|
-
slot.state.settings = ports.settings;
|
|
41
39
|
if ('fs' in ports)
|
|
42
40
|
slot.state.fs = ports.fs;
|
|
43
41
|
if ('session' in ports)
|
|
@@ -63,12 +61,6 @@ export function hostLog(level, msg, data) {
|
|
|
63
61
|
export function hostProbe(channel, line) {
|
|
64
62
|
callDiagnosticPort(() => hostSlot(DEFAULT_SESSION_KEY).state.probe?.(channel, line));
|
|
65
63
|
}
|
|
66
|
-
export function hostSettings() {
|
|
67
|
-
return hostSettingsFor(DEFAULT_SESSION_KEY);
|
|
68
|
-
}
|
|
69
|
-
export function hostSettingsFor(sessionKey) {
|
|
70
|
-
return hostSlot(sessionKey).state.settings ?? miss(sessionKey, 'settings');
|
|
71
|
-
}
|
|
72
64
|
export function hostFs() {
|
|
73
65
|
return hostFsFor(DEFAULT_SESSION_KEY);
|
|
74
66
|
}
|