@sema-agent/client-core 0.97.1 → 0.99.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 +607 -0
- package/README.md +96 -46
- package/dist/adapt/arms.d.ts +1 -0
- package/dist/adapt/arms.js +188 -53
- package/dist/adapt/ids.d.ts +12 -1
- package/dist/adapt/ids.js +59 -8
- package/dist/adapt/instanceLedger.d.ts +50 -0
- package/dist/adapt/instanceLedger.js +147 -0
- package/dist/adapt/panelTasks.d.ts +1 -1
- package/dist/adapt/panelTasks.js +2 -2
- package/dist/adapt/textStream.d.ts +1 -0
- package/dist/adapt/textStream.js +24 -7
- package/dist/adapt/toolCards.d.ts +27 -5
- package/dist/adapt/toolCards.js +39 -6
- package/dist/adapt/wireShapes.js +6 -2
- package/dist/adapt.d.ts +2 -0
- package/dist/adapt.js +8 -3
- package/dist/adapter/activeRunSelfHeal.d.ts +9 -3
- package/dist/adapter/activeRunSelfHeal.js +205 -313
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
- package/dist/adapter/downstream/eventToSdkMessage.js +77 -36
- package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
- package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
- package/dist/adapter/runStream.js +79 -48
- package/dist/adapter/types.d.ts +4 -4
- package/dist/adapter/types.js +2 -1
- package/dist/agentSession/backgroundView.js +2 -1
- package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
- package/dist/agentSession/engineAgentRegistryRead.js +12 -13
- package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
- package/dist/agentsWireCaps.d.ts +8 -11
- package/dist/agentsWireCaps.js +196 -194
- package/dist/approvalDecidedByCapability.d.ts +0 -4
- package/dist/approvalDecidedByCapability.js +0 -6
- package/dist/approvalsStreamLiveCapability.d.ts +0 -4
- package/dist/approvalsStreamLiveCapability.js +0 -6
- package/dist/assistantInbox.d.ts +34 -0
- package/dist/assistantInbox.js +118 -0
- package/dist/centerWiringCapability.js +9 -1
- package/dist/clientSlice.d.ts +0 -9
- package/dist/clientSlice.js +0 -3
- package/dist/cloudConfigWireCaps.d.ts +5 -3
- package/dist/cloudConfigWireCaps.js +106 -64
- package/dist/compensations.js +1 -1
- package/dist/connectorStatus.d.ts +21 -0
- package/dist/connectorStatus.js +112 -0
- package/dist/controlRouter.d.ts +18 -3
- package/dist/controlRouter.js +106 -67
- package/dist/coreValuePorts.d.ts +29 -4
- package/dist/coreValuePorts.js +10 -0
- package/dist/corruptSessionCopy.d.ts +2 -1
- package/dist/corruptSessionCopy.js +3 -3
- package/dist/decideReceipt.d.ts +2 -2
- package/dist/decideReceipt.js +5 -2
- package/dist/declared/supportFloorDeclared.js +3 -3
- package/dist/detachWire.js +3 -2
- package/dist/deviceExecutorManagementCapability.d.ts +0 -4
- package/dist/deviceExecutorManagementCapability.js +0 -6
- package/dist/deviceRebind.d.ts +49 -1
- package/dist/deviceRebind.js +221 -3
- package/dist/devicesFace.d.ts +34 -0
- package/dist/devicesFace.js +90 -0
- package/dist/displayUntrusted.d.ts +2 -0
- package/dist/displayUntrusted.js +253 -76
- package/dist/engineAgentAbsence.d.ts +1 -1
- package/dist/engineAgentPanelStore.d.ts +12 -4
- package/dist/engineAgentPanelStore.js +16 -11
- package/dist/engineCapReader.d.ts +2 -5
- package/dist/engineCapReader.js +8 -10
- package/dist/engineCapsCache.d.ts +12 -0
- package/dist/engineCapsCache.js +76 -18
- package/dist/engineCapsChange.d.ts +2 -0
- package/dist/engineCapsChange.js +9 -0
- package/dist/engineClosedSets.d.ts +1 -0
- package/dist/engineClosedSets.js +4 -1
- package/dist/engineErrorCodes.d.ts +11 -3
- package/dist/engineErrorCodes.js +11 -8
- package/dist/engineIdentity.d.ts +1 -0
- package/dist/engineIdentity.js +8 -0
- package/dist/engineRowRef.d.ts +28 -0
- package/dist/engineRowRef.js +114 -0
- package/dist/engineSessionMessages.d.ts +68 -0
- package/dist/engineSessionMessages.js +370 -0
- package/dist/engineTargetSeat.d.ts +27 -0
- package/dist/engineTargetSeat.js +199 -0
- package/dist/engineToolDirectory.d.ts +0 -9
- package/dist/engineToolDirectory.js +1 -94
- package/dist/engineUrl.d.ts +18 -0
- package/dist/engineUrl.js +52 -0
- package/dist/engineWireFor.js +3 -8
- package/dist/env/uiLanguage.d.ts +11 -1
- package/dist/env/uiLanguage.js +38 -2
- package/dist/eventLeg.d.ts +100 -0
- package/dist/eventLeg.js +305 -0
- package/dist/executionLaneCapability.d.ts +0 -4
- package/dist/executionLaneCapability.js +3 -16
- package/dist/fileHistoryCaptureCapability.d.ts +2 -5
- package/dist/fileHistoryCaptureCapability.js +13 -21
- package/dist/fileHistoryLegNotice.d.ts +2 -1
- package/dist/fileHistoryLegNotice.js +3 -3
- package/dist/fleet/fleetLedger.d.ts +0 -3
- package/dist/fleet/fleetLedger.js +21 -36
- package/dist/fleet/fleetProjection.d.ts +2 -2
- package/dist/fleet/fleetProjection.js +10 -8
- package/dist/frameBinding.d.ts +8 -0
- package/dist/frameBinding.js +35 -0
- package/dist/gateFailureCodes.d.ts +2 -0
- package/dist/gateFailureCodes.js +15 -0
- package/dist/gateOutcome.d.ts +3 -1
- package/dist/gateOutcome.js +41 -8
- package/dist/gateVocabulary.d.ts +10 -4
- package/dist/gateVocabulary.js +107 -47
- package/dist/generated/engineAskFaceTables.js +2 -2
- package/dist/generated/engineFactTables.d.ts +22 -3
- package/dist/generated/engineFactTables.js +51 -4
- package/dist/generated/engineNoticeTables.js +18 -3
- package/dist/generated/settingsSchemaFns.d.ts +6 -0
- package/dist/generated/settingsSchemaFns.js +57 -0
- package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
- package/dist/generated/settingsSchemaTables.d.ts +1 -0
- package/dist/generated/settingsSchemaTables.js +4 -0
- package/dist/generated/settingsSchemaTypes.d.ts +105 -0
- package/dist/generated/settingsSchemaTypes.js +1 -0
- package/dist/generated/toolNameTables.d.ts +1 -0
- package/dist/generated/toolNameTables.js +1 -0
- package/dist/hitl/allowRuleShadow.d.ts +8 -2
- package/dist/hitl/allowRuleShadow.js +36 -29
- package/dist/hitl/approvalCardReading.d.ts +15 -0
- package/dist/hitl/approvalCardReading.js +154 -0
- package/dist/hitl/approvalCardReasons.d.ts +14 -0
- package/dist/hitl/approvalCardReasons.js +119 -0
- package/dist/hitl/approvalHolds.d.ts +50 -15
- package/dist/hitl/approvalHolds.js +177 -27
- package/dist/hitl/approvalResolution.d.ts +51 -26
- package/dist/hitl/approvalResolution.js +86 -122
- package/dist/hitl/approvalsFeed.js +6 -18
- package/dist/hitl/askClassPair.d.ts +2 -0
- package/dist/hitl/askClassPair.js +17 -0
- package/dist/hitl/askGateWire.d.ts +20 -2
- package/dist/hitl/askGateWire.js +50 -1
- package/dist/hitl/askParkRowRouting.d.ts +5 -0
- package/dist/hitl/askParkRowRouting.js +32 -1
- package/dist/hitl/askSettlementLine.d.ts +28 -0
- package/dist/hitl/askSettlementLine.js +99 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +3 -2
- package/dist/hitl/automaticAnswerVerdict.js +29 -13
- package/dist/hitl/crashConverged.d.ts +11 -20
- package/dist/hitl/crashConverged.js +56 -0
- package/dist/hitl/crashConvergedNotice.d.ts +6 -3
- package/dist/hitl/crashConvergedNotice.js +48 -24
- package/dist/hitl/decisionConflict.js +3 -10
- package/dist/hitl/decisionRefusal.d.ts +40 -1
- package/dist/hitl/decisionRefusal.js +199 -42
- package/dist/hitl/frameRouter.d.ts +5 -2
- package/dist/hitl/frameRouter.js +27 -24
- package/dist/hitl/gateLedger.d.ts +2 -0
- package/dist/hitl/gateLedger.js +50 -13
- package/dist/hitl/hitlBridge.d.ts +2 -2
- package/dist/hitl/hitlBridge.js +13 -10
- package/dist/hitl/livePendingAsk.d.ts +3 -3
- package/dist/hitl/livePendingAsk.js +7 -18
- package/dist/hitl/parkResolver.d.ts +2 -24
- package/dist/hitl/parkResolver.js +61 -97
- package/dist/hitl/persistedRulesWire.d.ts +25 -0
- package/dist/hitl/persistedRulesWire.js +104 -2
- package/dist/hitl/planReviewWire.d.ts +31 -13
- package/dist/hitl/planReviewWire.js +120 -78
- package/dist/hitl/refusedToolNameProse.d.ts +0 -1
- package/dist/hitl/refusedToolNameProse.js +0 -3
- package/dist/hitl/replayedApproval.d.ts +4 -3
- package/dist/hitl/replayedApproval.js +7 -4
- package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
- package/dist/hitl/sessionPolicyDeliverable.js +48 -7
- package/dist/hitl/sessionPolicyWire.d.ts +34 -21
- package/dist/hitl/sessionPolicyWire.js +179 -70
- package/dist/hitl/standingRows.d.ts +20 -2
- package/dist/hitl/standingRows.js +69 -8
- package/dist/hitl/suspendedReopen.d.ts +2 -1
- package/dist/hitl/suspendedReopen.js +7 -10
- package/dist/hitl/toolApprovalWire.d.ts +103 -156
- package/dist/hitl/toolApprovalWire.js +661 -411
- package/dist/hookMatcherVerdict.d.ts +6 -1
- package/dist/hookMatcherVerdict.js +14 -7
- package/dist/hooksWireCaps.d.ts +2 -2
- package/dist/hooksWireCaps.js +174 -81
- package/dist/host.d.ts +21 -0
- package/dist/hostTurnSettings.d.ts +71 -0
- package/dist/hostTurnSettings.js +291 -0
- package/dist/humanTurn.d.ts +14 -1
- package/dist/humanTurn.js +100 -12
- package/dist/humanTurnRead.d.ts +2 -0
- package/dist/humanTurnRead.js +22 -1
- package/dist/i18n/messages.en.d.ts +703 -0
- package/dist/i18n/messages.en.js +701 -0
- package/dist/i18n/messages.zh.d.ts +3 -0
- package/dist/i18n/messages.zh.js +837 -0
- package/dist/i18n/translate.d.ts +25 -0
- package/dist/i18n/translate.js +127 -0
- package/dist/index.d.ts +78 -29
- package/dist/index.js +54 -18
- package/dist/inheritEnvCapability.d.ts +32 -0
- package/dist/inheritEnvCapability.js +104 -0
- package/dist/inheritEnvWire.d.ts +3 -2
- package/dist/inheritEnvWire.js +12 -14
- package/dist/interactiveHalt.js +17 -6
- package/dist/liveModelCatalog.d.ts +3 -3
- package/dist/liveModelCatalog.js +15 -13
- package/dist/liveQuestionStore.d.ts +2 -21
- package/dist/mcpLiveness.d.ts +2 -1
- package/dist/mcpPanel.d.ts +10 -1
- package/dist/mcpPanel.js +40 -13
- package/dist/mcpProbeCapability.d.ts +2 -1
- package/dist/mcpProbeCapability.js +7 -11
- package/dist/mcpProbeWire.d.ts +9 -2
- package/dist/mcpProbeWire.js +6 -1
- package/dist/mcpWireCaps.d.ts +47 -2
- package/dist/mcpWireCaps.js +164 -16
- package/dist/memoryEntriesWire.d.ts +4 -9
- package/dist/memoryEntriesWire.js +5 -10
- package/dist/model/modelSupplyRules.d.ts +0 -2
- package/dist/model/modelSupplyRules.js +3 -12
- package/dist/model/modelsPolicy.d.ts +0 -5
- package/dist/model/modelsPolicy.js +6 -36
- package/dist/model/onboardJudgement.d.ts +93 -0
- package/dist/model/onboardJudgement.js +415 -0
- package/dist/model/subagentModelWord.d.ts +31 -0
- package/dist/model/subagentModelWord.js +261 -0
- package/dist/model/tierVocabulary.d.ts +2 -0
- package/dist/model/tierVocabulary.js +17 -5
- package/dist/modelCapabilityProbe.d.ts +64 -0
- package/dist/modelCapabilityProbe.js +600 -0
- package/dist/modelIdentityResolvability.d.ts +3 -0
- package/dist/modelIdentityResolvability.js +26 -17
- package/dist/notifications.d.ts +6 -0
- package/dist/notifications.js +71 -23
- package/dist/outputStyleSeatCapability.d.ts +0 -3
- package/dist/outputStyleSeatCapability.js +0 -3
- package/dist/ownKey.d.ts +22 -0
- package/dist/ownKey.js +94 -3
- package/dist/panelReduce.d.ts +21 -10
- package/dist/panelReduce.js +728 -550
- package/dist/panelStateHolder.d.ts +3 -7
- package/dist/panelStateHolder.js +14 -130
- package/dist/peerLaneCapability.d.ts +0 -4
- package/dist/peerLaneCapability.js +0 -6
- package/dist/permissionRuleIssue.js +2 -0
- package/dist/permissionRulesWriteCapability.d.ts +2 -5
- package/dist/permissionRulesWriteCapability.js +8 -12
- package/dist/permissionWireCaps.d.ts +2 -2
- package/dist/permissionWireCaps.js +2 -0
- package/dist/permissionsAllowGrantCapability.d.ts +0 -4
- package/dist/permissionsAllowGrantCapability.js +0 -6
- package/dist/permissionsDeclaration.d.ts +0 -11
- package/dist/permissionsDeclaration.js +60 -53
- package/dist/pluginHooksWire.d.ts +46 -3
- package/dist/pluginHooksWire.js +219 -16
- package/dist/preemptWire.d.ts +44 -0
- package/dist/preemptWire.js +83 -0
- package/dist/printModelStatus.d.ts +63 -0
- package/dist/printModelStatus.js +155 -0
- package/dist/printToolResultFrame.js +15 -4
- package/dist/replayBody.d.ts +3 -0
- package/dist/replayBody.js +14 -0
- package/dist/request/taskRequest.d.ts +11 -6
- package/dist/request/taskRequest.js +112 -19
- package/dist/resumeRefusalCopy.d.ts +13 -9
- package/dist/resumeRefusalCopy.js +81 -118
- package/dist/retryStatus.d.ts +45 -0
- package/dist/retryStatus.js +185 -1
- package/dist/rewindArchiveCapability.d.ts +0 -4
- package/dist/rewindArchiveCapability.js +2 -10
- package/dist/rewindArchiveReading.d.ts +0 -1
- package/dist/rewindArchiveReading.js +0 -3
- package/dist/runCancelContext.d.ts +2 -1
- package/dist/runCancelContext.js +4 -2
- package/dist/runReattachPolicy.d.ts +31 -0
- package/dist/runReattachPolicy.js +46 -0
- package/dist/runTerminal.d.ts +3 -6
- package/dist/runTerminal.js +8 -9
- package/dist/sandboxWire.d.ts +3 -1
- package/dist/sandboxWire.js +76 -27
- package/dist/scenarioRefusal.d.ts +9 -0
- package/dist/scenarioRefusal.js +111 -0
- package/dist/scenarioWire.js +1 -1
- package/dist/seam.d.ts +48 -2
- package/dist/seam.js +25 -4
- package/dist/seatContract.d.ts +311 -18
- package/dist/seatContract.js +824 -100
- package/dist/selfOrchestrationDenial.js +7 -19
- package/dist/sessionIdSegment.d.ts +6 -0
- package/dist/sessionIdSegment.js +24 -0
- package/dist/sessionMemoryStatus.js +6 -11
- package/dist/sessionPolicyCapability.d.ts +2 -5
- package/dist/sessionPolicyCapability.js +8 -12
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
- package/dist/sessionSyncFileHistoryCapability.js +0 -3
- package/dist/settingsHooksSalvage.d.ts +44 -0
- package/dist/settingsHooksSalvage.js +211 -0
- package/dist/skillToolListsCapability.d.ts +2 -4
- package/dist/skillToolListsCapability.js +8 -9
- package/dist/sqlEngineCapability.d.ts +0 -4
- package/dist/sqlEngineCapability.js +0 -6
- package/dist/sseIdleTriage.js +3 -2
- package/dist/steerPriorityCapability.d.ts +0 -3
- package/dist/steerPriorityCapability.js +0 -3
- package/dist/streamDrainingLegs.d.ts +4 -0
- package/dist/streamDrainingLegs.js +6 -1
- package/dist/subagent/engineCompactWire.d.ts +0 -1
- package/dist/subagent/engineCompactWire.js +7 -5
- package/dist/subagent/engineSubagentResume.js +15 -9
- package/dist/subagent/engineTaskHandleWire.js +4 -7
- package/dist/subagentContentStore.d.ts +3 -0
- package/dist/subagentContentStore.js +22 -10
- package/dist/submitReopen.d.ts +24 -0
- package/dist/submitReopen.js +75 -0
- package/dist/terminalStatuses.d.ts +3 -0
- package/dist/terminalStatuses.js +10 -2
- package/dist/toolHistoryMismatch.js +3 -2
- package/dist/toolResult.d.ts +10 -1
- package/dist/toolResult.js +34 -6
- package/dist/toolRoster.d.ts +3 -4
- package/dist/toolRoster.js +21 -22
- package/dist/turnFailurePresentation.d.ts +39 -0
- package/dist/turnFailurePresentation.js +402 -0
- package/dist/usageAnalytics.js +6 -11
- package/dist/userAttachmentEnvelope.d.ts +1 -0
- package/dist/userAttachmentEnvelope.js +37 -7
- package/dist/userAttachmentSeat.d.ts +21 -0
- package/dist/userAttachmentSeat.js +75 -0
- package/dist/userInvokedSkillsCapability.d.ts +11 -4
- package/dist/userInvokedSkillsCapability.js +31 -10
- package/dist/webSearchBackendCapability.d.ts +0 -4
- package/dist/webSearchBackendCapability.js +0 -6
- package/dist/wireErrorTriage.d.ts +7 -0
- package/dist/wireErrorTriage.js +26 -23
- package/dist/wireFailureShape.d.ts +62 -5
- package/dist/wireFailureShape.js +106 -5
- package/dist/wireRefusalCopy.d.ts +25 -3
- package/dist/wireRefusalCopy.js +74 -80
- package/dist/workflowsJournalCapability.d.ts +2 -5
- package/dist/workflowsJournalCapability.js +8 -12
- package/dist/writeProtectionCapability.d.ts +0 -4
- package/dist/writeProtectionCapability.js +0 -6
- package/docs/INTEGRATION-CLIENTS.md +1775 -56
- package/package.json +6 -5
- package/dist/attachmentSeatCapability.d.ts +0 -12
- package/dist/attachmentSeatCapability.js +0 -23
- package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
- package/dist/hitl/approvalOutcomeNote.js +0 -29
- package/dist/sessionReadRedactionCapability.d.ts +0 -13
- package/dist/sessionReadRedactionCapability.js +0 -35
package/dist/deviceRebind.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { atMostOnceVerdictOf } from './atMostOnce.js';
|
|
2
2
|
import { readOwnDataValue } from './ownKey.js';
|
|
3
|
+
import { isDisplayableWireCode, readErrorString, readThrownSlot, wireFailureShapeOf } from './wireFailureShape.js';
|
|
3
4
|
const LANE_ABSENT = 'capability.device_lane_required';
|
|
4
5
|
const RUN_STORE_ABSENT = 'capability.run_store_required';
|
|
5
6
|
const NOT_FOUND = 'not_found.device';
|
|
@@ -40,9 +41,13 @@ function isArraySafely(v) {
|
|
|
40
41
|
return false;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
function scrubbed(redact, v) {
|
|
45
|
+
return v !== undefined && redact !== undefined && v.includes(redact) ? undefined : v;
|
|
46
|
+
}
|
|
47
|
+
function refusedOf(status, code, e, redact) {
|
|
48
|
+
const message = scrubbed(redact, nonEmpty(slot(e, 'message')));
|
|
49
|
+
const errorCode = scrubbed(redact, code);
|
|
50
|
+
return { kind: 'refused', status, ...(errorCode !== undefined ? { errorCode } : {}), ...(message !== undefined ? { message } : {}) };
|
|
46
51
|
}
|
|
47
52
|
function transportOf(v) {
|
|
48
53
|
return { kind: 'transport', ...(v.name !== undefined ? { detail: v.name } : {}) };
|
|
@@ -240,3 +245,216 @@ export function rebindProvesRequestNotApplied(outcome) {
|
|
|
240
245
|
return false;
|
|
241
246
|
}
|
|
242
247
|
}
|
|
248
|
+
const RATE_LIMITED = 'limit.rate_exceeded';
|
|
249
|
+
const ENROLLMENT_INVALID = 'device.enrollment_invalid';
|
|
250
|
+
function rateLimitedOf(e) {
|
|
251
|
+
const sec = wireFailureShapeOf(e).retryAfterSec;
|
|
252
|
+
return { kind: 'rate-limited', ...(sec !== undefined ? { retryAfterSec: sec } : {}) };
|
|
253
|
+
}
|
|
254
|
+
function unconfirmedOf(v, redact) {
|
|
255
|
+
const name = scrubbed(redact, v.name);
|
|
256
|
+
return v.status !== undefined
|
|
257
|
+
? { kind: 'unconfirmed', why: 'server-error', detail: String(v.status), mayStillBeRunning: true }
|
|
258
|
+
: { kind: 'unconfirmed', why: 'transport', ...(name !== undefined ? { detail: name } : {}), mayStillBeRunning: true };
|
|
259
|
+
}
|
|
260
|
+
const acceptedUnreadable = () => ({ kind: 'unconfirmed', why: 'accepted-unreadable', mayStillBeRunning: false });
|
|
261
|
+
function localRefusal(message) {
|
|
262
|
+
return { kind: 'refused', status: 0, errorCode: 'request.field_invalid', message };
|
|
263
|
+
}
|
|
264
|
+
function issueFailureOf(e) {
|
|
265
|
+
const v = atMostOnceVerdictOf(e);
|
|
266
|
+
const common = commonOf(v.status, v.code);
|
|
267
|
+
if (common !== null)
|
|
268
|
+
return common.kind === 'not-found' ? refusedOf(404, NOT_FOUND, e) : common;
|
|
269
|
+
if (v.status === 429 && v.code === RATE_LIMITED)
|
|
270
|
+
return rateLimitedOf(e);
|
|
271
|
+
return v.status !== undefined ? refusedOf(v.status, v.code, e) : transportOf(v);
|
|
272
|
+
}
|
|
273
|
+
export async function issueEnrollToken(devices, opts) {
|
|
274
|
+
const verb = verbOf(devices, 'issueEnrollToken');
|
|
275
|
+
if (verb === undefined)
|
|
276
|
+
return { kind: 'unarmed' };
|
|
277
|
+
let body;
|
|
278
|
+
try {
|
|
279
|
+
body = await verb.call(devices, signalOpts(opts));
|
|
280
|
+
}
|
|
281
|
+
catch (e) {
|
|
282
|
+
return issueFailureOf(e);
|
|
283
|
+
}
|
|
284
|
+
const token = nonEmpty(own(body, 'token'));
|
|
285
|
+
if (token === undefined)
|
|
286
|
+
return { kind: 'unreadable', why: 'the enrollment token response carries no token — refusing to treat it as a token' };
|
|
287
|
+
const expiresAt = nonEmpty(own(body, 'expiresAt'));
|
|
288
|
+
const ttl = own(body, 'ttlSec');
|
|
289
|
+
const ttlSec = typeof ttl === 'number' && Number.isInteger(ttl) && ttl > 0 ? ttl : undefined;
|
|
290
|
+
return { kind: 'ok', token, ...(expiresAt !== undefined ? { expiresAt } : {}), ...(ttlSec !== undefined ? { ttlSec } : {}) };
|
|
291
|
+
}
|
|
292
|
+
function enrollFailureOf(e, token) {
|
|
293
|
+
const v = atMostOnceVerdictOf(e);
|
|
294
|
+
const common = commonOf(v.status, v.code);
|
|
295
|
+
if (common !== null)
|
|
296
|
+
return common.kind === 'not-found' ? refusedOf(404, NOT_FOUND, e, token) : common;
|
|
297
|
+
if (v.status === 403 && v.code === ENROLLMENT_INVALID)
|
|
298
|
+
return { kind: 'enrollment-invalid' };
|
|
299
|
+
if (v.status === 429 && v.code === RATE_LIMITED)
|
|
300
|
+
return rateLimitedOf(e);
|
|
301
|
+
if (v.status === 503 && v.code === SERVICE_TOKEN_REQUIRED)
|
|
302
|
+
return refusedOf(v.status, v.code, e, token);
|
|
303
|
+
if (v.delivery === 'rejected' && v.status !== undefined)
|
|
304
|
+
return refusedOf(v.status, v.code, e, token);
|
|
305
|
+
return unconfirmedOf(v, token);
|
|
306
|
+
}
|
|
307
|
+
export async function enrollDevice(devices, req, opts) {
|
|
308
|
+
const token = nonEmpty(own(req, 'token'));
|
|
309
|
+
const pubkey = nonEmpty(own(req, 'pubkey'));
|
|
310
|
+
const platformOs = nonEmpty(own(req, 'platformOs'));
|
|
311
|
+
const workspaceRoot = nonEmpty(own(req, 'workspaceRoot'));
|
|
312
|
+
if (token === undefined || pubkey === undefined || platformOs === undefined || workspaceRoot === undefined) {
|
|
313
|
+
return localRefusal('the enrollment request is missing a required detail (token, public key, platform or workspace root), so nothing was sent');
|
|
314
|
+
}
|
|
315
|
+
const platformArch = nonEmpty(own(req, 'platformArch'));
|
|
316
|
+
const displayName = nonEmpty(own(req, 'displayName'));
|
|
317
|
+
const verb = verbOf(devices, 'enroll');
|
|
318
|
+
if (verb === undefined)
|
|
319
|
+
return { kind: 'unarmed' };
|
|
320
|
+
const wire = {
|
|
321
|
+
token,
|
|
322
|
+
pubkey,
|
|
323
|
+
platformOs,
|
|
324
|
+
...(platformArch !== undefined ? { platformArch } : {}),
|
|
325
|
+
...(displayName !== undefined ? { displayName } : {}),
|
|
326
|
+
workspaceRoot,
|
|
327
|
+
};
|
|
328
|
+
let body;
|
|
329
|
+
try {
|
|
330
|
+
body = await verb.call(devices, wire, signalOpts(opts));
|
|
331
|
+
}
|
|
332
|
+
catch (e) {
|
|
333
|
+
return enrollFailureOf(e, token);
|
|
334
|
+
}
|
|
335
|
+
const deviceId = nonEmpty(own(body, 'deviceId'));
|
|
336
|
+
if (deviceId === undefined || scrubbed(token, deviceId) === undefined)
|
|
337
|
+
return acceptedUnreadable();
|
|
338
|
+
const accept = opts === undefined || opts === null ? undefined : own(opts, 'acceptDeviceId');
|
|
339
|
+
if (typeof accept === 'function') {
|
|
340
|
+
let verdict;
|
|
341
|
+
try {
|
|
342
|
+
verdict = accept(deviceId);
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
verdict = false;
|
|
346
|
+
}
|
|
347
|
+
if (verdict !== true)
|
|
348
|
+
return acceptedUnreadable();
|
|
349
|
+
}
|
|
350
|
+
return { kind: 'ok', deviceId };
|
|
351
|
+
}
|
|
352
|
+
function revokeFailureOf(e) {
|
|
353
|
+
const v = atMostOnceVerdictOf(e);
|
|
354
|
+
const common = commonOf(v.status, v.code);
|
|
355
|
+
if (common !== null)
|
|
356
|
+
return common;
|
|
357
|
+
if (v.status === 503 && v.code === SERVICE_TOKEN_REQUIRED)
|
|
358
|
+
return refusedOf(v.status, v.code, e);
|
|
359
|
+
if (v.delivery === 'rejected' && v.status !== undefined)
|
|
360
|
+
return refusedOf(v.status, v.code, e);
|
|
361
|
+
return unconfirmedOf(v);
|
|
362
|
+
}
|
|
363
|
+
export async function revokeDevice(devices, deviceId, opts) {
|
|
364
|
+
const id = nonEmpty(deviceId);
|
|
365
|
+
if (id === undefined)
|
|
366
|
+
return localRefusal('the device id is missing, so nothing was sent');
|
|
367
|
+
const verb = verbOf(devices, 'revoke');
|
|
368
|
+
if (verb === undefined)
|
|
369
|
+
return { kind: 'unarmed' };
|
|
370
|
+
const reason = nonEmpty(own(opts, 'reason'));
|
|
371
|
+
let body;
|
|
372
|
+
try {
|
|
373
|
+
body = await verb.call(devices, id, reason !== undefined ? { reason } : {}, signalOpts(opts));
|
|
374
|
+
}
|
|
375
|
+
catch (e) {
|
|
376
|
+
return revokeFailureOf(e);
|
|
377
|
+
}
|
|
378
|
+
if (own(body, 'deviceId') !== id || own(body, 'status') !== 'revoked')
|
|
379
|
+
return acceptedUnreadable();
|
|
380
|
+
const revokedAt = nonEmpty(own(body, 'revokedAt'));
|
|
381
|
+
return { kind: 'ok', deviceId: id, ...(revokedAt !== undefined ? { revokedAt } : {}) };
|
|
382
|
+
}
|
|
383
|
+
const IDENTITY_MISMATCH = 'device.identity_mismatch';
|
|
384
|
+
const IDENTITY_MISMATCH_TEXT_PREFIX = `[${IDENTITY_MISMATCH}] `;
|
|
385
|
+
export function deviceIdentityMismatchOf(err) {
|
|
386
|
+
if (err === null || err === undefined)
|
|
387
|
+
return null;
|
|
388
|
+
if (typeof err === 'string')
|
|
389
|
+
return err.startsWith(IDENTITY_MISMATCH_TEXT_PREFIX) ? { code: IDENTITY_MISMATCH } : null;
|
|
390
|
+
if (typeof err !== 'object' && typeof err !== 'function')
|
|
391
|
+
return null;
|
|
392
|
+
const code = readThrownSlot(err, 'errorCode', 'data');
|
|
393
|
+
const message = readThrownSlot(err, 'message');
|
|
394
|
+
if (code !== IDENTITY_MISMATCH && !(typeof message === 'string' && message.startsWith(IDENTITY_MISMATCH_TEXT_PREFIX)))
|
|
395
|
+
return null;
|
|
396
|
+
const bound = readErrorString(err, 'boundDeviceId');
|
|
397
|
+
return Object.freeze({ code: IDENTITY_MISMATCH, ...(bound !== undefined && bound !== '' ? { boundDeviceId: bound } : {}) });
|
|
398
|
+
}
|
|
399
|
+
export function deviceIdentityMismatchLine(detail) {
|
|
400
|
+
const bound = nonEmpty(own(detail, 'boundDeviceId'));
|
|
401
|
+
return [
|
|
402
|
+
'This session was rebound to a different device after that work was minted',
|
|
403
|
+
bound !== undefined && isDisplayableWireCode(bound) ? `It now runs on ${bound}` : 'The engine line above names the device it now runs on',
|
|
404
|
+
'The engine refuses to silently re-target it — the new device has a different workspace',
|
|
405
|
+
"Re-initiate the work on the currently bound device (the session's device binding shows which one that is)",
|
|
406
|
+
].join(' · ');
|
|
407
|
+
}
|
|
408
|
+
export function deviceRegistrationOutcomeLine(verb, outcome) {
|
|
409
|
+
if (verb !== 'issue' && verb !== 'enroll' && verb !== 'revoke')
|
|
410
|
+
return undefined;
|
|
411
|
+
const kind = own(outcome, 'kind');
|
|
412
|
+
switch (kind) {
|
|
413
|
+
case 'rate-limited': {
|
|
414
|
+
const sec = own(outcome, 'retryAfterSec');
|
|
415
|
+
return typeof sec === 'number' && Number.isFinite(sec) && sec > 0
|
|
416
|
+
? `Too many device requests were sent in a short time — wait ${sec} second${sec === 1 ? '' : 's'} and try again.`
|
|
417
|
+
: 'Too many device requests were sent in a short time — wait a moment and try again.';
|
|
418
|
+
}
|
|
419
|
+
case 'enrollment-invalid':
|
|
420
|
+
return 'Enrollment was refused. The token may have expired, may already have been used by another device, or may have been issued to a different account. Ask for a new enrollment token and try again.';
|
|
421
|
+
case 'not-found':
|
|
422
|
+
return 'No such device is visible to you — it may not exist, may belong to someone else, or may already be revoked; the engine deliberately does not say which.';
|
|
423
|
+
case 'lane-absent':
|
|
424
|
+
return own(outcome, 'runStoreOnly') === true
|
|
425
|
+
? 'Device lane not enabled — this engine has the device lane but no run store.'
|
|
426
|
+
: 'Device lane not enabled on this engine.';
|
|
427
|
+
case 'refused': {
|
|
428
|
+
const status = own(outcome, 'status');
|
|
429
|
+
if (status === 0)
|
|
430
|
+
return 'The request is incomplete, so nothing was sent.';
|
|
431
|
+
const code = own(outcome, 'errorCode');
|
|
432
|
+
const shown = typeof code === 'string' && isDisplayableWireCode(code) ? ` ${code}` : '';
|
|
433
|
+
return `The engine refused this request (${typeof status === 'number' ? String(status) : 'no status'}${shown}).`;
|
|
434
|
+
}
|
|
435
|
+
case 'unconfirmed': {
|
|
436
|
+
const accepted = own(outcome, 'why') === 'accepted-unreadable';
|
|
437
|
+
if (verb === 'enroll') {
|
|
438
|
+
return accepted
|
|
439
|
+
? 'The engine accepted the enrollment but did not report the resulting device — it may be enrolled. Sending the same token and public key again is safe: it returns the same device.'
|
|
440
|
+
: 'The enrollment request went out but no confirmation came back — the device may or may not be enrolled. Sending the same token and public key again is safe: it returns the same device.';
|
|
441
|
+
}
|
|
442
|
+
if (verb === 'revoke') {
|
|
443
|
+
return accepted
|
|
444
|
+
? 'The engine accepted the revocation but did not confirm it — the device may be revoked. Revoking again is safe: a second revocation succeeds without changing anything.'
|
|
445
|
+
: 'The revocation request went out but no confirmation came back — the device may or may not be revoked. Revoking again is safe: a second revocation succeeds without changing anything.';
|
|
446
|
+
}
|
|
447
|
+
return accepted
|
|
448
|
+
? 'The engine accepted the request but did not confirm it — it may or may not have taken effect.'
|
|
449
|
+
: 'The request went out but no confirmation came back — it may or may not have taken effect.';
|
|
450
|
+
}
|
|
451
|
+
case 'transport':
|
|
452
|
+
return 'The request did not reach the engine, or no answer came back — nothing was confirmed.';
|
|
453
|
+
case 'unreadable':
|
|
454
|
+
return 'The engine answered, but the answer could not be read.';
|
|
455
|
+
case 'unarmed':
|
|
456
|
+
return 'No device-management connection is set up here, so nothing was sent.';
|
|
457
|
+
default:
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type SeatCapabilityReading } from './seatContract.js';
|
|
2
|
+
import { type DeviceExecutorManagementReading } from './deviceExecutorManagementCapability.js';
|
|
3
|
+
import type { DeviceListOutcome } from './deviceRebind.js';
|
|
4
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
5
|
+
export type DevicesFaceUnavailableWhy = 'host_not_wired' | 'host_not_reported' | 'host_report_unreadable' | 'lane_absent' | 'lane_unreported';
|
|
6
|
+
export type DevicesFace = {
|
|
7
|
+
readonly kind: 'unavailable';
|
|
8
|
+
readonly why: DevicesFaceUnavailableWhy;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'probe_pending';
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'probe_failed';
|
|
13
|
+
readonly retryable: true;
|
|
14
|
+
readonly cause: 'transport' | 'refused' | 'unreadable';
|
|
15
|
+
} | {
|
|
16
|
+
readonly kind: 'verbs_off';
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: 'manage';
|
|
19
|
+
readonly probe: boolean;
|
|
20
|
+
};
|
|
21
|
+
export interface DevicesFaceInput {
|
|
22
|
+
readonly host: {
|
|
23
|
+
readonly kind: 'seat';
|
|
24
|
+
readonly capability: SeatCapabilityReading;
|
|
25
|
+
} | {
|
|
26
|
+
readonly kind: 'direct';
|
|
27
|
+
readonly sliceArmed: boolean;
|
|
28
|
+
};
|
|
29
|
+
readonly engine?: DeviceExecutorManagementReading | undefined;
|
|
30
|
+
readonly lastList?: DeviceListOutcome | undefined;
|
|
31
|
+
}
|
|
32
|
+
export declare function devicesFaceOf(input: DevicesFaceInput): DevicesFace;
|
|
33
|
+
export declare function devicesWritesAllowed(face: DevicesFace): boolean;
|
|
34
|
+
export declare function devicesFaceDetail(face: DevicesFace, lang?: UiLanguage): string | undefined;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { seatCapabilityUnavailableDetail } from './seatContract.js';
|
|
2
|
+
import { deviceLaneOpen, deviceManagementVerbsAvailable } from './deviceExecutorManagementCapability.js';
|
|
3
|
+
import { ownDataField } from './ownKey.js';
|
|
4
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
5
|
+
const freeze = (v) => Object.freeze(v);
|
|
6
|
+
const field = (v, key) => {
|
|
7
|
+
if (v === null || typeof v !== 'object')
|
|
8
|
+
return undefined;
|
|
9
|
+
try {
|
|
10
|
+
return ownDataField(v, key);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function hostProblem(host) {
|
|
17
|
+
const kind = field(host, 'kind');
|
|
18
|
+
if (kind === 'direct')
|
|
19
|
+
return field(host, 'sliceArmed') === true ? undefined : 'host_not_wired';
|
|
20
|
+
if (kind !== 'seat')
|
|
21
|
+
return 'host_report_unreadable';
|
|
22
|
+
const reading = field(host, 'capability');
|
|
23
|
+
const rk = field(reading, 'kind');
|
|
24
|
+
if (rk === 'reported')
|
|
25
|
+
return field(reading, 'available') === true ? undefined : 'host_not_wired';
|
|
26
|
+
if (rk === 'not_reported')
|
|
27
|
+
return 'host_not_reported';
|
|
28
|
+
return 'host_report_unreadable';
|
|
29
|
+
}
|
|
30
|
+
export function devicesFaceOf(input) {
|
|
31
|
+
const engineRaw = field(input, 'engine');
|
|
32
|
+
const engine = { kind: field(engineRaw, 'kind'), management: field(engineRaw, 'management') };
|
|
33
|
+
const lane = deviceLaneOpen(engine);
|
|
34
|
+
const listKind = field(field(input, 'lastList'), 'kind');
|
|
35
|
+
if (lane === 'no' || listKind === 'lane-absent')
|
|
36
|
+
return freeze({ kind: 'unavailable', why: 'lane_absent' });
|
|
37
|
+
const host = field(input, 'host');
|
|
38
|
+
const hostWhy = hostProblem(host);
|
|
39
|
+
if (hostWhy !== undefined)
|
|
40
|
+
return freeze({ kind: 'unavailable', why: hostWhy });
|
|
41
|
+
if (listKind === 'unarmed')
|
|
42
|
+
return freeze({ kind: 'unavailable', why: 'host_not_wired' });
|
|
43
|
+
if (lane === 'unknown') {
|
|
44
|
+
if (field(host, 'kind') === 'direct')
|
|
45
|
+
return freeze({ kind: 'unavailable', why: 'lane_unreported' });
|
|
46
|
+
if (listKind === undefined)
|
|
47
|
+
return freeze({ kind: 'probe_pending' });
|
|
48
|
+
if (listKind === 'ok')
|
|
49
|
+
return freeze({ kind: 'manage', probe: true });
|
|
50
|
+
const cause = listKind === 'transport' || listKind === 'refused' ? listKind : 'unreadable';
|
|
51
|
+
return freeze({ kind: 'probe_failed', retryable: true, cause });
|
|
52
|
+
}
|
|
53
|
+
const verbs = deviceManagementVerbsAvailable(engine);
|
|
54
|
+
if (verbs === 'no')
|
|
55
|
+
return freeze({ kind: 'verbs_off' });
|
|
56
|
+
return freeze({ kind: 'manage', probe: verbs === 'unknown' });
|
|
57
|
+
}
|
|
58
|
+
export function devicesWritesAllowed(face) {
|
|
59
|
+
return field(face, 'kind') === 'manage';
|
|
60
|
+
}
|
|
61
|
+
const UNWIRED = freeze({ kind: 'reported', available: false });
|
|
62
|
+
const NOT_REPORTED = freeze({ kind: 'not_reported' });
|
|
63
|
+
const MALFORMED = freeze({ kind: 'malformed' });
|
|
64
|
+
export function devicesFaceDetail(face, lang) {
|
|
65
|
+
const kind = field(face, 'kind');
|
|
66
|
+
if (kind === 'manage')
|
|
67
|
+
return undefined;
|
|
68
|
+
if (kind === 'probe_pending')
|
|
69
|
+
return renderMessage(msg('session.devices.probePending'), lang);
|
|
70
|
+
if (kind === 'verbs_off')
|
|
71
|
+
return renderMessage(msg('session.devices.verbsOff'), lang);
|
|
72
|
+
if (kind === 'probe_failed') {
|
|
73
|
+
const cause = field(face, 'cause');
|
|
74
|
+
if (cause === 'transport')
|
|
75
|
+
return renderMessage(msg('session.devices.probeFailedTransport'), lang);
|
|
76
|
+
if (cause === 'refused')
|
|
77
|
+
return renderMessage(msg('session.devices.probeFailedRefused'), lang);
|
|
78
|
+
return renderMessage(msg('session.devices.probeFailedUnreadable'), lang);
|
|
79
|
+
}
|
|
80
|
+
const why = kind === 'unavailable' ? field(face, 'why') : undefined;
|
|
81
|
+
if (why === 'lane_absent')
|
|
82
|
+
return renderMessage(msg('session.devices.laneAbsent'), lang);
|
|
83
|
+
if (why === 'lane_unreported')
|
|
84
|
+
return renderMessage(msg('session.devices.laneUnreported'), lang);
|
|
85
|
+
if (why === 'host_not_wired')
|
|
86
|
+
return seatCapabilityUnavailableDetail('devices', UNWIRED);
|
|
87
|
+
if (why === 'host_not_reported')
|
|
88
|
+
return seatCapabilityUnavailableDetail('devices', NOT_REPORTED);
|
|
89
|
+
return seatCapabilityUnavailableDetail('devices', MALFORMED);
|
|
90
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const REDACTION_MARKER_PREFIX = "\u00ABredacted";
|
|
2
2
|
export declare function looksLikeKnownSecret(s: string): boolean;
|
|
3
|
+
export declare function isDiagnosticValueWord(value: string): boolean;
|
|
3
4
|
export declare function washCredentials(text: string): string;
|
|
4
5
|
export type DisplayMark = 'escape' | 'dot' | 'space';
|
|
5
6
|
export interface DisplayFace {
|
|
@@ -43,6 +44,7 @@ export declare function credentialWashPasses(text: string, opts?: DisplayUntrust
|
|
|
43
44
|
capped: boolean;
|
|
44
45
|
};
|
|
45
46
|
export declare function displayUntrusted(text: string, opts?: DisplayUntrustedOptions): string;
|
|
47
|
+
export declare function cleanUntrustedScalar(v: string | number | bigint | boolean | null | undefined): string;
|
|
46
48
|
export declare function queryCarriesCredential(query: string): boolean;
|
|
47
49
|
export declare function displayConfiguredUrl(url: string, opts?: DisplayUntrustedOptions): string;
|
|
48
50
|
export declare function quoteUntrustedForSentence(text: string, max: number): string | undefined;
|