@sema-agent/client-core 0.100.0 → 0.102.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 +452 -0
- package/README.md +172 -120
- package/dist/adapt/arms.js +51 -16
- package/dist/adapt/textStream.js +7 -4
- package/dist/adapt/toolCards.d.ts +2 -1
- package/dist/adapt/toolCards.js +28 -13
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +8 -2
- package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
- package/dist/adapter/activeRunSelfHeal.js +108 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +38 -79
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
- package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
- package/dist/adapter/downstream/wiringManifestView.d.ts +1 -0
- package/dist/adapter/downstream/wiringManifestView.js +138 -0
- 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/compensations.js +1 -1
- 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 +9 -4
- package/dist/displayUntrusted.js +834 -104
- 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 +4 -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 +16 -3
- 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 +222 -2
- package/dist/i18n/messages.en.js +225 -5
- package/dist/i18n/messages.zh.js +237 -5
- package/dist/i18n/translate.js +3 -3
- package/dist/index.d.ts +77 -15
- package/dist/index.js +50 -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/interactiveHalt.d.ts +3 -1
- package/dist/interactiveHalt.js +2 -0
- package/dist/interactiveInterrupt.d.ts +2 -0
- package/dist/interactiveInterrupt.js +15 -0
- 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/modsFace.d.ts +8 -0
- package/dist/modsFace.js +59 -0
- 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 +12 -0
- package/dist/ownKey.js +179 -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/printToolResultFrame.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 +6 -2
- package/dist/request/submissionIdentity.d.ts +37 -0
- package/dist/request/submissionIdentity.js +65 -0
- package/dist/request/taskRequest.d.ts +33 -4
- package/dist/request/taskRequest.js +341 -156
- 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 +3 -3
- package/dist/seatContract.d.ts +68 -7
- package/dist/seatContract.js +84 -25
- package/dist/selfOrchestrationDenial.js +1 -1
- package/dist/sessionBackground.d.ts +165 -0
- package/dist/sessionBackground.js +781 -0
- package/dist/sessionBackgroundHandoff.d.ts +54 -0
- package/dist/sessionBackgroundHandoff.js +321 -0
- package/dist/sessionMap.js +4 -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 +55 -15
- 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/thinkingLatch.d.ts +69 -0
- package/dist/thinkingLatch.js +255 -0
- package/dist/thinkingLatchWords.d.ts +7 -0
- package/dist/thinkingLatchWords.js +4 -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 +159 -32
- 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 +907 -182
- package/package.json +14 -3
- package/dist/argvFlagValue.d.ts +0 -8
- package/dist/argvFlagValue.js +0 -37
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { AgentEvent } from '@sema-agent/sdk';
|
|
2
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
3
|
+
import { type BackgroundHandoffVerdict, type InteractiveEngineWire } from './sessionBackground.js';
|
|
4
|
+
export declare const BACKGROUND_HANDOFF_ABORT_REASON = "background";
|
|
5
|
+
export interface BackgroundHandoffRequest {
|
|
6
|
+
readonly wire: InteractiveEngineWire | undefined;
|
|
7
|
+
readonly sessionKey: string;
|
|
8
|
+
readonly onHandedOff: (reason: typeof BACKGROUND_HANDOFF_ABORT_REASON) => void;
|
|
9
|
+
readonly lang?: UiLanguage;
|
|
10
|
+
}
|
|
11
|
+
export type BackgroundHandoffOutcome = {
|
|
12
|
+
readonly kind: 'kept';
|
|
13
|
+
readonly verdict: Exclude<BackgroundHandoffVerdict, {
|
|
14
|
+
verdict: 'eligible';
|
|
15
|
+
}>;
|
|
16
|
+
readonly sentence: string;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: 'handed-off';
|
|
19
|
+
readonly run: BackgroundRun;
|
|
20
|
+
readonly hostNotified: boolean;
|
|
21
|
+
readonly sentence: string;
|
|
22
|
+
};
|
|
23
|
+
export interface BackgroundRun {
|
|
24
|
+
readonly taskId: string;
|
|
25
|
+
openFrames(signal?: AbortSignal): AsyncGenerator<AgentEvent>;
|
|
26
|
+
readonly settled: Promise<BackgroundRunSettlement>;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
}
|
|
29
|
+
export type BackgroundRunSettlement = {
|
|
30
|
+
readonly runEnded: true;
|
|
31
|
+
readonly kind: 'completed' | 'failed' | 'cancelled' | 'parked';
|
|
32
|
+
readonly status: string;
|
|
33
|
+
readonly errorCode?: string;
|
|
34
|
+
readonly sentence: string;
|
|
35
|
+
} | {
|
|
36
|
+
readonly runEnded: false;
|
|
37
|
+
readonly kind: 'observation-stopped';
|
|
38
|
+
readonly cause: 'window-exhausted' | 'disposed' | 'engine-ended';
|
|
39
|
+
readonly sentence: string;
|
|
40
|
+
};
|
|
41
|
+
export interface HandedOffRunRow {
|
|
42
|
+
readonly taskId: string;
|
|
43
|
+
readonly sessionKey: string;
|
|
44
|
+
readonly state: 'running' | 'ended' | 'unconfirmed';
|
|
45
|
+
}
|
|
46
|
+
export type HandedOffRunsReading = {
|
|
47
|
+
readonly kind: 'read';
|
|
48
|
+
readonly runs: readonly HandedOffRunRow[];
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: 'unrecognized-wire';
|
|
51
|
+
};
|
|
52
|
+
export declare function handoffInteractiveRun(req: BackgroundHandoffRequest): BackgroundHandoffOutcome;
|
|
53
|
+
export declare function handedOffRunsOf(wire: InteractiveEngineWire): HandedOffRunsReading;
|
|
54
|
+
export declare function forgetHandedOffRun(wire: InteractiveEngineWire, taskId: string): boolean;
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
2
|
+
import { abortableSleep } from './abortableSleep.js';
|
|
3
|
+
import { REATTACH_WINDOW_MS, reattachBackoffMs } from './reattachWindow.js';
|
|
4
|
+
import { terminalEventFromRunRow } from './headlessReconnectWire.js';
|
|
5
|
+
import { RUN_CANCELLED_CODE } from './runCancelContext.js';
|
|
6
|
+
import { readRunTerminal } from './runTerminal.js';
|
|
7
|
+
import { readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
|
|
8
|
+
import { backgroundHandoffSentence, judgeHandoff, ownSlotOf, wireStateOf, } from './sessionBackground.js';
|
|
9
|
+
export const BACKGROUND_HANDOFF_ABORT_REASON = 'background';
|
|
10
|
+
const HANDED_OFF_ENDED_CAP = 256;
|
|
11
|
+
const isObj = (v) => (typeof v === 'object' && v !== null) || typeof v === 'function';
|
|
12
|
+
function slot(o, key) {
|
|
13
|
+
try {
|
|
14
|
+
return readOwnDataValue(o, key);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function slotString(o, key) {
|
|
21
|
+
try {
|
|
22
|
+
return readOwnDataNonEmptyString(o, key);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function executionSettlementOf(ev) {
|
|
29
|
+
try {
|
|
30
|
+
const type = slot(ev, 'type');
|
|
31
|
+
if (type === 'failed') {
|
|
32
|
+
const code = slotString(ev, 'errorCode');
|
|
33
|
+
if (code === RUN_CANCELLED_CODE)
|
|
34
|
+
return { runEnded: true, kind: 'cancelled', status: 'failed' };
|
|
35
|
+
return { runEnded: true, kind: 'failed', status: 'failed', ...(code !== undefined ? { errorCode: code } : {}) };
|
|
36
|
+
}
|
|
37
|
+
if (type !== 'done' || slot(ev, 'replay') === true)
|
|
38
|
+
return undefined;
|
|
39
|
+
const read = readRunTerminal(slot(ev, 'result'));
|
|
40
|
+
if (read === null)
|
|
41
|
+
return { runEnded: true, kind: 'completed', status: 'completed' };
|
|
42
|
+
switch (read.kind) {
|
|
43
|
+
case 'completed':
|
|
44
|
+
return { runEnded: true, kind: 'completed', status: 'completed' };
|
|
45
|
+
case 'paused':
|
|
46
|
+
return { runEnded: true, kind: 'parked', status: read.flatStatus ?? 'paused' };
|
|
47
|
+
case 'failed':
|
|
48
|
+
if (read.code === RUN_CANCELLED_CODE)
|
|
49
|
+
return { runEnded: true, kind: 'cancelled', status: 'failed' };
|
|
50
|
+
return { runEnded: true, kind: 'failed', status: 'failed', ...(read.code !== undefined ? { errorCode: read.code } : {}) };
|
|
51
|
+
case 'blocked':
|
|
52
|
+
return { runEnded: true, kind: 'failed', status: 'blocked', ...(read.code !== undefined ? { errorCode: read.code } : {}) };
|
|
53
|
+
case 'unknown':
|
|
54
|
+
return { runEnded: true, kind: 'failed', status: read.word ?? 'unknown', ...(read.code !== undefined ? { errorCode: read.code } : {}) };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function settlementSentence(s, lang) {
|
|
62
|
+
if (!s.runEnded)
|
|
63
|
+
return renderMessage(msg('session.background.settled.observationStopped'), lang);
|
|
64
|
+
switch (s.kind) {
|
|
65
|
+
case 'completed':
|
|
66
|
+
return renderMessage(msg('session.background.settled.completed'), lang);
|
|
67
|
+
case 'cancelled':
|
|
68
|
+
return renderMessage(msg('session.background.settled.cancelled'), lang);
|
|
69
|
+
case 'parked':
|
|
70
|
+
return renderMessage(msg('session.background.settled.parked'), lang);
|
|
71
|
+
case 'failed':
|
|
72
|
+
return renderMessage(msg('session.background.settled.failed', { code: s.errorCode ?? s.status }), lang);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function runRowOf(row) {
|
|
76
|
+
if (!isObj(row))
|
|
77
|
+
return null;
|
|
78
|
+
const status = slotString(row, 'status');
|
|
79
|
+
if (status === undefined)
|
|
80
|
+
return null;
|
|
81
|
+
const result = slot(row, 'result');
|
|
82
|
+
const errorCode = slotString(row, 'errorCode');
|
|
83
|
+
const error = slotString(row, 'error');
|
|
84
|
+
return {
|
|
85
|
+
status,
|
|
86
|
+
...(result !== undefined ? { result } : {}),
|
|
87
|
+
...(errorCode !== undefined ? { errorCode } : {}),
|
|
88
|
+
...(error !== undefined ? { error } : {}),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async function readRunRow(state, taskId, sessionId, signal) {
|
|
92
|
+
try {
|
|
93
|
+
const row = await state.get(taskId, signal !== undefined ? { session: sessionId, signal } : { session: sessionId });
|
|
94
|
+
return runRowOf(row);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function* framesEndedWith(error) {
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
function trimHandedOff(state) {
|
|
104
|
+
let ended = 0;
|
|
105
|
+
for (const e of state.handedOff.values())
|
|
106
|
+
if (e.state === 'ended')
|
|
107
|
+
ended++;
|
|
108
|
+
if (ended <= HANDED_OFF_ENDED_CAP)
|
|
109
|
+
return;
|
|
110
|
+
for (const [taskId, e] of [...state.handedOff]) {
|
|
111
|
+
if (ended <= HANDED_OFF_ENDED_CAP)
|
|
112
|
+
break;
|
|
113
|
+
if (e.state !== 'ended')
|
|
114
|
+
continue;
|
|
115
|
+
state.handedOff.delete(taskId);
|
|
116
|
+
ended--;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function ledgerSeqOf(ev) {
|
|
120
|
+
const id = slotString(ev, 'id');
|
|
121
|
+
return id !== undefined && /^\d+$/.test(id) ? Number(id) : undefined;
|
|
122
|
+
}
|
|
123
|
+
async function pump(state, taskId, sessionId, signal, finish) {
|
|
124
|
+
let deadline = Date.now() + REATTACH_WINDOW_MS;
|
|
125
|
+
let attempt = 0;
|
|
126
|
+
let farthest = -1;
|
|
127
|
+
for (;;) {
|
|
128
|
+
if (signal.aborted)
|
|
129
|
+
return;
|
|
130
|
+
let progressed = false;
|
|
131
|
+
try {
|
|
132
|
+
const frames = state.events(taskId, { session: sessionId, signal });
|
|
133
|
+
for await (const ev of frames) {
|
|
134
|
+
if (signal.aborted)
|
|
135
|
+
return;
|
|
136
|
+
const seq = ledgerSeqOf(ev);
|
|
137
|
+
if (seq !== undefined && seq > farthest) {
|
|
138
|
+
farthest = seq;
|
|
139
|
+
progressed = true;
|
|
140
|
+
}
|
|
141
|
+
const s = executionSettlementOf(ev);
|
|
142
|
+
if (s !== undefined) {
|
|
143
|
+
finish(s);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
}
|
|
150
|
+
if (signal.aborted)
|
|
151
|
+
return;
|
|
152
|
+
const row = await readRunRow(state, taskId, sessionId, signal);
|
|
153
|
+
if (signal.aborted)
|
|
154
|
+
return;
|
|
155
|
+
const synthesized = terminalEventFromRunRow(row);
|
|
156
|
+
const s = synthesized === null ? undefined : executionSettlementOf(synthesized);
|
|
157
|
+
if (s !== undefined) {
|
|
158
|
+
finish(s);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (progressed) {
|
|
162
|
+
deadline = Date.now() + REATTACH_WINDOW_MS;
|
|
163
|
+
attempt = 0;
|
|
164
|
+
}
|
|
165
|
+
if (Date.now() >= deadline) {
|
|
166
|
+
finish({ runEnded: false, kind: 'observation-stopped', cause: 'window-exhausted' });
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
attempt++;
|
|
170
|
+
await abortableSleep(reattachBackoffMs(attempt), signal);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function startBackground(state, taskId, sessionKey, sessionId, lang) {
|
|
174
|
+
const controller = new AbortController();
|
|
175
|
+
let resolveSettled = () => { };
|
|
176
|
+
const settled = new Promise((resolve) => {
|
|
177
|
+
resolveSettled = resolve;
|
|
178
|
+
});
|
|
179
|
+
let done = false;
|
|
180
|
+
let reconciling = false;
|
|
181
|
+
const finish = (s) => {
|
|
182
|
+
if (done)
|
|
183
|
+
return;
|
|
184
|
+
done = true;
|
|
185
|
+
entry.state = s.runEnded ? 'ended' : 'unconfirmed';
|
|
186
|
+
controller.abort();
|
|
187
|
+
resolveSettled(Object.freeze({ ...s, sentence: settlementSentence(s, lang) }));
|
|
188
|
+
if (s.runEnded)
|
|
189
|
+
trimHandedOff(state);
|
|
190
|
+
};
|
|
191
|
+
const entry = {
|
|
192
|
+
taskId,
|
|
193
|
+
sessionKey,
|
|
194
|
+
state: 'running',
|
|
195
|
+
stop: (cause) => finish({ runEnded: false, kind: 'observation-stopped', cause }),
|
|
196
|
+
reconcile: () => {
|
|
197
|
+
if (entry.state !== 'unconfirmed' || reconciling || state.retired)
|
|
198
|
+
return;
|
|
199
|
+
reconciling = true;
|
|
200
|
+
void readRunRow(state, taskId, sessionId, undefined)
|
|
201
|
+
.then((row) => {
|
|
202
|
+
const synthesized = terminalEventFromRunRow(row);
|
|
203
|
+
const s = synthesized === null ? undefined : executionSettlementOf(synthesized);
|
|
204
|
+
if (s !== undefined && s.runEnded && entry.state === 'unconfirmed') {
|
|
205
|
+
entry.state = 'ended';
|
|
206
|
+
trimHandedOff(state);
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
.finally(() => {
|
|
210
|
+
reconciling = false;
|
|
211
|
+
});
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
state.handedOff.set(taskId, entry);
|
|
215
|
+
void pump(state, taskId, sessionId, controller.signal, finish).catch(() => finish({ runEnded: false, kind: 'observation-stopped', cause: 'window-exhausted' }));
|
|
216
|
+
const run = Object.freeze({
|
|
217
|
+
taskId,
|
|
218
|
+
openFrames(signal) {
|
|
219
|
+
try {
|
|
220
|
+
return state.events(taskId, signal !== undefined ? { session: sessionId, signal } : { session: sessionId });
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
return framesEndedWith(e);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
settled,
|
|
227
|
+
dispose() {
|
|
228
|
+
finish({ runEnded: false, kind: 'observation-stopped', cause: 'disposed' });
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
return run;
|
|
232
|
+
}
|
|
233
|
+
function snapshotHandoffRequest(req) {
|
|
234
|
+
if (!isObj(req))
|
|
235
|
+
return { readable: false, wire: undefined, sessionKey: undefined, onHandedOff: undefined, lang: undefined };
|
|
236
|
+
const wireSlot = ownSlotOf(req, 'wire');
|
|
237
|
+
const sessionKey = slotString(req, 'sessionKey');
|
|
238
|
+
const onHandedOff = slot(req, 'onHandedOff');
|
|
239
|
+
const lang = slot(req, 'lang');
|
|
240
|
+
return {
|
|
241
|
+
readable: sessionKey !== undefined && typeof onHandedOff === 'function',
|
|
242
|
+
wire: wireSlot.state === 'unreadable' ? {} : wireSlot.state === 'data' ? wireSlot.value : undefined,
|
|
243
|
+
sessionKey,
|
|
244
|
+
onHandedOff: typeof onHandedOff === 'function' ? onHandedOff : undefined,
|
|
245
|
+
lang: typeof lang === 'string' ? lang : undefined,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function keptOf(verdict, lang) {
|
|
249
|
+
const v = verdict.verdict === 'eligible' ? Object.freeze({ verdict: 'unknown', reason: 'unreadable-input' }) : verdict;
|
|
250
|
+
const sentence = backgroundHandoffSentence(v, lang) ?? renderMessage(msg('session.background.unknown'), lang);
|
|
251
|
+
return Object.freeze({ kind: 'kept', verdict: v, sentence });
|
|
252
|
+
}
|
|
253
|
+
export function handoffInteractiveRun(req) {
|
|
254
|
+
let snap;
|
|
255
|
+
try {
|
|
256
|
+
snap = snapshotHandoffRequest(req);
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return keptOf(Object.freeze({ verdict: 'unknown', reason: 'unreadable-input' }), undefined);
|
|
260
|
+
}
|
|
261
|
+
const lang = snap.lang;
|
|
262
|
+
if (!snap.readable || snap.sessionKey === undefined || snap.onHandedOff === undefined) {
|
|
263
|
+
return keptOf(Object.freeze({ verdict: 'unknown', reason: 'unreadable-input' }), lang);
|
|
264
|
+
}
|
|
265
|
+
const judged = judgeHandoff({ wire: snap.wire, sessionKey: snap.sessionKey });
|
|
266
|
+
const { verdict, rec, state } = judged;
|
|
267
|
+
if (verdict.verdict !== 'eligible' || rec === undefined || state === undefined || rec.sessionId === undefined)
|
|
268
|
+
return keptOf(verdict, lang);
|
|
269
|
+
const taskId = verdict.taskId;
|
|
270
|
+
const sessionId = rec.sessionId;
|
|
271
|
+
rec.phase = 'handing-off';
|
|
272
|
+
try {
|
|
273
|
+
rec.tear(BACKGROUND_HANDOFF_ABORT_REASON);
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
}
|
|
277
|
+
rec.phase = 'handed-off';
|
|
278
|
+
const run = startBackground(state, taskId, snap.sessionKey, sessionId, lang);
|
|
279
|
+
let hostNotified = true;
|
|
280
|
+
try {
|
|
281
|
+
snap.onHandedOff(BACKGROUND_HANDOFF_ABORT_REASON);
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
hostNotified = false;
|
|
285
|
+
}
|
|
286
|
+
const sentence = renderMessage(msg(hostNotified ? 'session.background.handedOff' : 'session.background.hostNotNotified'), lang);
|
|
287
|
+
return Object.freeze({ kind: 'handed-off', run, hostNotified, sentence });
|
|
288
|
+
}
|
|
289
|
+
export function handedOffRunsOf(wire) {
|
|
290
|
+
try {
|
|
291
|
+
const state = wireStateOf(wire);
|
|
292
|
+
if (state === undefined)
|
|
293
|
+
return Object.freeze({ kind: 'unrecognized-wire' });
|
|
294
|
+
const runs = [];
|
|
295
|
+
for (const e of state.handedOff.values()) {
|
|
296
|
+
if (e.state === 'unconfirmed')
|
|
297
|
+
e.reconcile();
|
|
298
|
+
runs.push(Object.freeze({ taskId: e.taskId, sessionKey: e.sessionKey, state: e.state }));
|
|
299
|
+
}
|
|
300
|
+
return Object.freeze({ kind: 'read', runs: Object.freeze(runs) });
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
return Object.freeze({ kind: 'unrecognized-wire' });
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
export function forgetHandedOffRun(wire, taskId) {
|
|
307
|
+
try {
|
|
308
|
+
const state = wireStateOf(wire);
|
|
309
|
+
if (state === undefined || typeof taskId !== 'string')
|
|
310
|
+
return false;
|
|
311
|
+
const entry = state.handedOff.get(taskId);
|
|
312
|
+
if (entry === undefined)
|
|
313
|
+
return false;
|
|
314
|
+
entry.stop('disposed');
|
|
315
|
+
state.handedOff.delete(taskId);
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
}
|
package/dist/sessionMap.js
CHANGED
|
@@ -2,7 +2,10 @@ export function engineNamespaceKeyFor(baseUrl) {
|
|
|
2
2
|
if (!baseUrl)
|
|
3
3
|
return 'local';
|
|
4
4
|
try {
|
|
5
|
-
|
|
5
|
+
const u = new URL(baseUrl);
|
|
6
|
+
if (!/^(?:https?|wss?|ftp):$/.test(u.protocol))
|
|
7
|
+
return baseUrl.toLowerCase();
|
|
8
|
+
return u.origin.toLowerCase() + u.pathname.replace(/\/+$/, '');
|
|
6
9
|
}
|
|
7
10
|
catch {
|
|
8
11
|
return baseUrl.toLowerCase();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { engineWireTargetBaseUrl } from './engineWireTarget.js';
|
|
2
2
|
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
3
3
|
import { msg, renderMessage } from './i18n/translate.js';
|
|
4
4
|
import { ownDataField } from './ownKey.js';
|
|
@@ -22,7 +22,7 @@ const reader = createEngineCapReader({
|
|
|
22
22
|
name: 'sessionPolicy',
|
|
23
23
|
project: projectSessionPolicyCapability,
|
|
24
24
|
});
|
|
25
|
-
export function observedSessionPolicy(baseUrl =
|
|
25
|
+
export function observedSessionPolicy(baseUrl = engineWireTargetBaseUrl()) {
|
|
26
26
|
return reader.observed(baseUrl);
|
|
27
27
|
}
|
|
28
28
|
export function sessionPolicyFaceAvailable(reading) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { guardedRead, readOwnDataValue } from './ownKey.js';
|
|
2
|
+
export function sessionRulesChildrenReadLiveOf(manifest) {
|
|
3
|
+
const raw = guardedRead(() => readOwnDataValue(readOwnDataValue(manifest, 'sessionRules'), 'childrenReadLive'));
|
|
4
|
+
return typeof raw === 'boolean' ? raw : undefined;
|
|
5
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SessionRulesNamespaceFormsReading = {
|
|
2
|
+
readonly kind: 'confirmed';
|
|
3
|
+
} | {
|
|
4
|
+
readonly kind: 'absent';
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: 'declined';
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: 'unreadable';
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'unobserved';
|
|
11
|
+
};
|
|
12
|
+
export declare function observedSessionRulesNamespaceForms(baseUrl?: string | undefined): SessionRulesNamespaceFormsReading;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { engineCapValue } from './engineCapsCache.js';
|
|
2
|
+
import { engineWireTargetBaseUrl } from './engineWireTarget.js';
|
|
3
|
+
const SESSION_RULES_NAMESPACE_FORMS_KEY = 'sessionRulesNamespaceForms';
|
|
4
|
+
const CONFIRMED = Object.freeze({ kind: 'confirmed' });
|
|
5
|
+
const ABSENT = Object.freeze({ kind: 'absent' });
|
|
6
|
+
const DECLINED = Object.freeze({ kind: 'declined' });
|
|
7
|
+
const UNREADABLE = Object.freeze({ kind: 'unreadable' });
|
|
8
|
+
const UNOBSERVED = Object.freeze({ kind: 'unobserved' });
|
|
9
|
+
export function observedSessionRulesNamespaceForms(baseUrl) {
|
|
10
|
+
try {
|
|
11
|
+
const base = baseUrl === undefined ? engineWireTargetBaseUrl() : baseUrl;
|
|
12
|
+
const slot = engineCapValue(typeof base === 'string' ? base : undefined, SESSION_RULES_NAMESPACE_FORMS_KEY);
|
|
13
|
+
switch (slot.kind) {
|
|
14
|
+
case 'unobserved':
|
|
15
|
+
return UNOBSERVED;
|
|
16
|
+
case 'not_reported':
|
|
17
|
+
return ABSENT;
|
|
18
|
+
case 'unreadable':
|
|
19
|
+
return UNREADABLE;
|
|
20
|
+
case 'null':
|
|
21
|
+
return DECLINED;
|
|
22
|
+
case 'value':
|
|
23
|
+
return slot.value === true ? CONFIRMED : DECLINED;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return UNOBSERVED;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { engineWireTargetBaseUrl } from './engineWireTarget.js';
|
|
2
2
|
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
3
3
|
import { ownDataField } from './ownKey.js';
|
|
4
4
|
export function projectSessionSyncFileHistoryCapability(caps) {
|
|
@@ -20,7 +20,7 @@ const reader = createEngineCapReader({
|
|
|
20
20
|
name: 'sessionSyncFileHistory',
|
|
21
21
|
project: projectSessionSyncFileHistoryCapability,
|
|
22
22
|
});
|
|
23
|
-
export function observedSessionSyncFileHistory(baseUrl =
|
|
23
|
+
export function observedSessionSyncFileHistory(baseUrl = engineWireTargetBaseUrl()) {
|
|
24
24
|
return reader.observed(baseUrl);
|
|
25
25
|
}
|
|
26
26
|
export function sessionSyncFileHistoryAvailable(reading) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { looksLikeKnownSecret,
|
|
1
|
+
import { configuredValueCarriesCredential, looksLikeKnownSecret, percentBoundaryReadingOf } from './displayUntrusted.js';
|
|
2
2
|
const CREDENTIAL_WORDS = new Set([
|
|
3
3
|
'key', 'keys', 'apikey', 'token', 'tokens', 'secret', 'secrets', 'password', 'passwd', 'pass', 'pwd', 'pin', 'otp',
|
|
4
4
|
'auth', 'authorization', 'credential', 'credentials', 'cookie', 'cookies', 'session', 'private', 'cert', 'signature', 'salt',
|
|
@@ -6,6 +6,9 @@ const CREDENTIAL_WORDS = new Set([
|
|
|
6
6
|
const CREDENTIAL_STEMS = ['PASSWORD', 'PASSWD', 'SECRET', 'TOKEN', 'APIKEY', 'CREDENTIAL', 'COOKIE', 'PRIVATE'];
|
|
7
7
|
const CREDENTIAL_SUFFIXES = ['PASS', 'PWD', 'KEY', 'AUTH'];
|
|
8
8
|
const SECRET_CONFIG_NAME = /(?:^|[-_.])(?:token|key|secret|password|authorization|credential|cookie)s?$/i;
|
|
9
|
+
const FLATTENED_CREDENTIAL_TAILS = [
|
|
10
|
+
'apikey', 'token', 'tokens', 'secret', 'secrets', 'password', 'passwd', 'credential', 'credentials', 'cookie', 'cookies', 'authorization',
|
|
11
|
+
];
|
|
9
12
|
export function credentialNameWords(name) {
|
|
10
13
|
if (typeof name !== 'string')
|
|
11
14
|
return [];
|
|
@@ -24,30 +27,67 @@ export function isCredentialEnvName(name) {
|
|
|
24
27
|
const upper = name.toUpperCase();
|
|
25
28
|
return CREDENTIAL_STEMS.some((stem) => upper.includes(stem)) || CREDENTIAL_SUFFIXES.some((suffix) => upper.endsWith(suffix));
|
|
26
29
|
}
|
|
30
|
+
function legacyNameWords(name) {
|
|
31
|
+
return name
|
|
32
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
33
|
+
.split(/[_\-.\s]+/)
|
|
34
|
+
.filter((w) => w.length > 0)
|
|
35
|
+
.map((w) => w.toLowerCase());
|
|
36
|
+
}
|
|
27
37
|
export function isCredentialConfigKey(name) {
|
|
28
38
|
if (typeof name !== 'string')
|
|
29
39
|
return false;
|
|
30
40
|
const words = credentialNameWords(name);
|
|
31
41
|
const last = words[words.length - 1];
|
|
32
|
-
|
|
42
|
+
if (SECRET_CONFIG_NAME.test(name) || (last !== undefined && CREDENTIAL_WORDS.has(last)))
|
|
43
|
+
return true;
|
|
44
|
+
const legacy = legacyNameWords(name);
|
|
45
|
+
const legacyLast = legacy[legacy.length - 1];
|
|
46
|
+
if (legacyLast !== undefined && CREDENTIAL_WORDS.has(legacyLast))
|
|
47
|
+
return true;
|
|
48
|
+
const flattened = name.replace(/[_\-.\s]+/g, '').toLowerCase();
|
|
49
|
+
return FLATTENED_CREDENTIAL_TAILS.some((tail) => flattened.endsWith(tail));
|
|
33
50
|
}
|
|
34
51
|
const DECIMAL_INTEGER_RE = /^\s*\d+\s*$/;
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
url = new URL(text);
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
52
|
+
function percentDecodeOnce(s) {
|
|
53
|
+
return s.indexOf('%') === -1 ? s : s.replace(/%([0-7][0-9A-Fa-f])/g, (_m, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
|
|
54
|
+
}
|
|
55
|
+
const SCHEME_THEN_ENCODED_SPACE = /(?:^|[^A-Za-z0-9])(?:bearer|basic)(?:\+|%20)[^\s+%]{1,4096}/i;
|
|
56
|
+
const FORM_READING_MAX_LAYERS = 3;
|
|
57
|
+
function formEncodedCarriesCredential(value) {
|
|
58
|
+
if (value.indexOf('+') === -1 && value.indexOf('%') === -1)
|
|
46
59
|
return false;
|
|
60
|
+
let layer = value;
|
|
61
|
+
for (let depth = 0;; depth++) {
|
|
62
|
+
const boundary = percentBoundaryReadingOf(layer);
|
|
63
|
+
for (const reading of boundary === layer ? [layer] : [layer, boundary]) {
|
|
64
|
+
if (SCHEME_THEN_ENCODED_SPACE.test(reading))
|
|
65
|
+
return true;
|
|
66
|
+
if (reading.indexOf('+') !== -1 && looksLikeKnownSecret(reading.replace(/\+/g, ' ')))
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
const next = percentDecodeOnce(layer);
|
|
70
|
+
if (next === layer)
|
|
71
|
+
return false;
|
|
72
|
+
if (depth === FORM_READING_MAX_LAYERS)
|
|
73
|
+
return true;
|
|
74
|
+
layer = next;
|
|
47
75
|
}
|
|
48
|
-
|
|
76
|
+
}
|
|
77
|
+
function stringCarriesCredential(value) {
|
|
78
|
+
if (looksLikeKnownSecret(value) || formEncodedCarriesCredential(value))
|
|
49
79
|
return true;
|
|
50
|
-
|
|
80
|
+
let layer = value;
|
|
81
|
+
for (let depth = 0;; depth++) {
|
|
82
|
+
if (configuredValueCarriesCredential(layer))
|
|
83
|
+
return true;
|
|
84
|
+
if (depth === FORM_READING_MAX_LAYERS)
|
|
85
|
+
return false;
|
|
86
|
+
const next = percentDecodeOnce(layer);
|
|
87
|
+
if (next === layer)
|
|
88
|
+
return false;
|
|
89
|
+
layer = next;
|
|
90
|
+
}
|
|
51
91
|
}
|
|
52
92
|
const ENV_ASSIGNMENT_RE = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/s;
|
|
53
93
|
const LONG_OPTION_RE = /^--?([A-Za-z][A-Za-z0-9_-]*)(?:=(.*))?$/s;
|
|
@@ -41,4 +41,5 @@ export declare function hooksSalvageMaskOf(dropped: readonly {
|
|
|
41
41
|
}[]): HooksSalvageMask;
|
|
42
42
|
export declare function salvageSettingsHooksEntries(doc: SettingsDocument | null | undefined): HooksSalvage;
|
|
43
43
|
export declare const HOOK_SETTINGS_SOURCE_TEXT: Readonly<Record<HookSettingsSource, string>>;
|
|
44
|
+
export declare function layerNotAppliedRefusesTurn(source: HookSettingsSource): boolean;
|
|
44
45
|
export declare function settingsHooksSalvageNotice(salvage: HooksSalvage, source: HookSettingsSource, doc?: SettingsDocument | null): string | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { displayUntrusted } from './displayUntrusted.js';
|
|
2
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
2
3
|
import { SETTINGS_CLASSIFY_HOOKS_CONFIG, } from './generated/settingsSchemaFns.js';
|
|
3
4
|
const _tuplePins = [true, true, true, true, true, true];
|
|
4
5
|
void _tuplePins;
|
|
@@ -116,6 +117,9 @@ export const HOOK_SETTINGS_SOURCE_TEXT = Object.freeze({
|
|
|
116
117
|
localSettings: 'Local settings',
|
|
117
118
|
flagSettings: 'Flag settings',
|
|
118
119
|
});
|
|
120
|
+
export function layerNotAppliedRefusesTurn(source) {
|
|
121
|
+
return source === 'policySettings';
|
|
122
|
+
}
|
|
119
123
|
const SALVAGE_LABEL_MAX = 80;
|
|
120
124
|
const SALVAGE_PIECES_SHOWN = 3;
|
|
121
125
|
const labelOf = (s) => (typeof s === 'number' ? String(s) : displayUntrusted(s, { max: SALVAGE_LABEL_MAX }));
|
|
@@ -194,11 +198,13 @@ export function settingsHooksSalvageNotice(salvage, source, doc) {
|
|
|
194
198
|
try {
|
|
195
199
|
if (salvage.outcome === 'loaded-partial') {
|
|
196
200
|
const what = joinPhrases(salvage.dropped.map((d) => ({ key: d.path.join('\u0000'), text: dropPhrase(d, doc) })));
|
|
201
|
+
if (layerNotAppliedRefusesTurn(source))
|
|
202
|
+
return renderMessage(msg('config.hooks.salvage.managedPartial', { layer, what }));
|
|
197
203
|
return `${layer}: ${what}. The rest of this file's hooks are applied.`;
|
|
198
204
|
}
|
|
199
205
|
if (salvage.outcome === 'rejected') {
|
|
200
206
|
const why = joinPhrases(salvage.rejections.map((r) => ({ key: r.path.join('\u0000'), text: rejectionPhrase(r) })));
|
|
201
|
-
if (source
|
|
207
|
+
if (layerNotAppliedRefusesTurn(source)) {
|
|
202
208
|
return `${layer}: hooks could not be loaded — ${why}. Requests are not sent while the managed hooks cannot be applied; ask your administrator to fix the managed settings.`;
|
|
203
209
|
}
|
|
204
210
|
return `${layer}: hooks were not loaded — ${why}; ${GUARD_RISK_TAIL}.`;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HostSettingsLayer, WorkspaceTrustState } from './hostSettingsSource.js';
|
|
2
|
+
export declare function layerAdmissionWord(layer: HostSettingsLayer, trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): string;
|
|
3
|
+
export declare function layerAdmitted(layer: HostSettingsLayer, trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): boolean;
|
|
4
|
+
export declare function admittedLayers<L extends HostSettingsLayer>(layers: readonly L[], trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): readonly L[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SETTINGS_LAYER_ADMISSION } from './generated/settingsSchemaFns.js';
|
|
2
|
+
const TRUST_UNREADABLE_READING = 'declined';
|
|
3
|
+
const ADMITTED = 'admitted';
|
|
4
|
+
function layerAdmissionOf(layer, trust, category, member) {
|
|
5
|
+
const reading = trust === 'unreadable' ? TRUST_UNREADABLE_READING : trust;
|
|
6
|
+
return member === undefined ? SETTINGS_LAYER_ADMISSION(layer, reading, category) : SETTINGS_LAYER_ADMISSION(layer, reading, category, member);
|
|
7
|
+
}
|
|
8
|
+
export function layerAdmissionWord(layer, trust, category, member) {
|
|
9
|
+
return layerAdmissionOf(layer, trust, category, member);
|
|
10
|
+
}
|
|
11
|
+
export function layerAdmitted(layer, trust, category, member) {
|
|
12
|
+
return layerAdmissionOf(layer, trust, category, member) === ADMITTED;
|
|
13
|
+
}
|
|
14
|
+
export function admittedLayers(layers, trust, category, member) {
|
|
15
|
+
return layers.filter((layer) => layerAdmitted(layer, trust, category, member));
|
|
16
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { engineWireTargetBaseUrl } from './engineWireTarget.js';
|
|
2
2
|
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
3
3
|
import { msg, renderMessage } from './i18n/translate.js';
|
|
4
|
-
import { ownDataField } from './ownKey.js';
|
|
4
|
+
import { guardedRead, ownDataField, readOwnDataValue } from './ownKey.js';
|
|
5
5
|
export function projectSkillToolListsCapability(caps) {
|
|
6
6
|
try {
|
|
7
7
|
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
@@ -21,13 +21,14 @@ const reader = createEngineCapReader({
|
|
|
21
21
|
name: 'skillToolLists',
|
|
22
22
|
project: projectSkillToolListsCapability,
|
|
23
23
|
});
|
|
24
|
-
export function observedSkillToolLists(baseUrl =
|
|
24
|
+
export function observedSkillToolLists(baseUrl = engineWireTargetBaseUrl()) {
|
|
25
25
|
return reader.observed(baseUrl);
|
|
26
26
|
}
|
|
27
27
|
export function skillToolListsAvailable(reading) {
|
|
28
|
-
|
|
28
|
+
const kind = guardedRead(() => readOwnDataValue(reading, 'kind'));
|
|
29
|
+
if (kind === 'present')
|
|
29
30
|
return 'yes';
|
|
30
|
-
if (
|
|
31
|
+
if (kind === 'absent' || kind === 'not_reported')
|
|
31
32
|
return 'no';
|
|
32
33
|
return 'unknown';
|
|
33
34
|
}
|