@sema-agent/client-core 0.77.1 → 0.78.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 +42 -1
- package/README.md +6 -5
- package/dist/abortableSleep.d.ts +0 -28
- package/dist/abortableSleep.js +0 -28
- package/dist/adapt/arms.d.ts +0 -46
- package/dist/adapt/arms.js +9 -544
- package/dist/adapt/ids.d.ts +0 -58
- package/dist/adapt/ids.js +0 -63
- package/dist/adapt/instanceLedger.d.ts +0 -25
- package/dist/adapt/instanceLedger.js +0 -20
- package/dist/adapt/panelTasks.d.ts +0 -69
- package/dist/adapt/panelTasks.js +0 -95
- package/dist/adapt/textSegmentAuthority.d.ts +1 -137
- package/dist/adapt/textSegmentAuthority.js +0 -54
- package/dist/adapt/textStream.d.ts +0 -252
- package/dist/adapt/textStream.js +2 -281
- package/dist/adapt/toolCards.d.ts +0 -46
- package/dist/adapt/toolCards.js +0 -23
- package/dist/adapt/turnFlags.d.ts +0 -54
- package/dist/adapt/turnFlags.js +1 -17
- package/dist/adapt/wireShapes.d.ts +0 -92
- package/dist/adapt/wireShapes.js +0 -83
- package/dist/adapt.d.ts +0 -55
- package/dist/adapt.js +1 -120
- package/dist/adapter/activeRunSelfHeal.d.ts +22 -515
- package/dist/adapter/activeRunSelfHeal.js +10 -625
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -305
- package/dist/adapter/downstream/eventToSdkMessage.js +2 -867
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -314
- package/dist/adapter/downstream/terminalToSdkResult.js +13 -560
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +0 -95
- package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -31
- package/dist/adapter/runStream.d.ts +0 -206
- package/dist/adapter/runStream.js +6 -596
- package/dist/adapter/types.d.ts +0 -111
- package/dist/adapter/types.js +0 -29
- package/dist/agentSession/backgroundView.d.ts +0 -106
- package/dist/agentSession/backgroundView.js +3 -49
- package/dist/agentSession/contract.d.ts +0 -98
- package/dist/agentSession/contract.js +0 -12
- package/dist/agentsWireCaps.d.ts +0 -72
- package/dist/agentsWireCaps.js +4 -72
- package/dist/approvalsStreamLiveCapability.d.ts +0 -25
- package/dist/approvalsStreamLiveCapability.js +0 -31
- package/dist/argvFlagValue.d.ts +0 -33
- package/dist/argvFlagValue.js +3 -35
- package/dist/attachmentsWireCaps.d.ts +0 -127
- package/dist/attachmentsWireCaps.js +0 -144
- package/dist/autoModeUnavailable.d.ts +0 -120
- package/dist/autoModeUnavailable.js +0 -144
- package/dist/classifierStatus.d.ts +0 -72
- package/dist/classifierStatus.js +0 -167
- package/dist/classifierVerdictWire.d.ts +0 -54
- package/dist/classifierVerdictWire.js +0 -133
- package/dist/clientContextWireCaps.d.ts +0 -37
- package/dist/clientContextWireCaps.js +0 -36
- package/dist/clientSlice.d.ts +0 -63
- package/dist/clientSlice.js +0 -45
- package/dist/cloudConfigWireCaps.d.ts +0 -86
- package/dist/cloudConfigWireCaps.js +2 -65
- package/dist/compensations.d.ts +0 -52
- package/dist/compensations.js +2 -63
- package/dist/controlRouter.d.ts +2 -208
- package/dist/controlRouter.js +1 -129
- package/dist/coreValuePorts.d.ts +0 -84
- package/dist/coreValuePorts.js +0 -29
- package/dist/decideReceipt.d.ts +0 -110
- package/dist/decideReceipt.js +0 -84
- package/dist/detachWire.d.ts +0 -130
- package/dist/detachWire.js +1 -130
- package/dist/deviceExecutorManagementCapability.d.ts +2 -35
- package/dist/deviceExecutorManagementCapability.js +1 -37
- package/dist/diagnostics.d.ts +0 -8
- package/dist/diagnostics.js +0 -8
- package/dist/diff/patch.d.ts +0 -17
- package/dist/diff/patch.js +0 -19
- package/dist/effectiveFacts.d.ts +0 -40
- package/dist/effectiveFacts.js +0 -22
- package/dist/effortWire.d.ts +0 -11
- package/dist/effortWire.js +0 -12
- package/dist/engineAgentPanelStore.d.ts +0 -169
- package/dist/engineAgentPanelStore.js +13 -293
- package/dist/engineCapReader.d.ts +0 -62
- package/dist/engineCapReader.js +1 -43
- package/dist/engineCapsCache.d.ts +0 -177
- package/dist/engineCapsCache.js +0 -199
- package/dist/engineCapsGenerationGuard.d.ts +0 -2
- package/dist/engineCapsGenerationGuard.js +0 -11
- package/dist/engineErrorCodes.d.ts +1 -316
- package/dist/engineErrorCodes.js +0 -427
- package/dist/engineHttpTools.d.ts +0 -29
- package/dist/engineHttpTools.js +0 -29
- package/dist/engineIdentity.d.ts +0 -83
- package/dist/engineIdentity.js +0 -88
- package/dist/engineInlineTaskStats.d.ts +0 -57
- package/dist/engineInlineTaskStats.js +1 -42
- package/dist/engineNoticeCodes.d.ts +0 -190
- package/dist/engineNoticeCodes.js +0 -182
- package/dist/engineSessionParam.d.ts +0 -30
- package/dist/engineSessionParam.js +0 -52
- package/dist/engineToolLabelStore.d.ts +0 -29
- package/dist/engineToolLabelStore.js +0 -31
- package/dist/engineWireSdk.d.ts +0 -90
- package/dist/engineWireSdk.js +0 -74
- package/dist/engineWireTarget.d.ts +0 -14
- package/dist/engineWireTarget.js +0 -39
- package/dist/env/localeGeo.d.ts +0 -12
- package/dist/env/localeGeo.js +2 -77
- package/dist/env/localeTag.d.ts +0 -34
- package/dist/env/localeTag.js +0 -32
- package/dist/env/uiLanguage.d.ts +0 -13
- package/dist/env/uiLanguage.js +0 -25
- package/dist/envFlag.d.ts +0 -37
- package/dist/envFlag.js +0 -40
- package/dist/executionLaneCapability.d.ts +0 -48
- package/dist/executionLaneCapability.js +0 -54
- package/dist/finalVerifyWire.d.ts +0 -67
- package/dist/finalVerifyWire.js +3 -43
- package/dist/fleet/fleetLedger.d.ts +0 -308
- package/dist/fleet/fleetLedger.js +10 -429
- package/dist/fleet/fleetProjection.d.ts +0 -240
- package/dist/fleet/fleetProjection.js +0 -189
- package/dist/fleet/fleetRowAgentType.d.ts +0 -6
- package/dist/fleet/fleetRowAgentType.js +1 -32
- package/dist/fleet/workflowSizeWarning.d.ts +0 -47
- package/dist/fleet/workflowSizeWarning.js +1 -46
- package/dist/fleetAgentPanelProjection.d.ts +0 -48
- package/dist/fleetAgentPanelProjection.js +8 -173
- package/dist/fleetTaskDesc.d.ts +0 -39
- package/dist/fleetTaskDesc.js +0 -69
- package/dist/forkWireCaps.d.ts +0 -23
- package/dist/forkWireCaps.js +1 -24
- package/dist/gateOutcome.d.ts +0 -140
- package/dist/gateOutcome.js +0 -85
- package/dist/gateVocabulary.d.ts +0 -114
- package/dist/gateVocabulary.js +3 -161
- package/dist/goalStopHook.d.ts +0 -127
- package/dist/goalStopHook.js +0 -178
- package/dist/headlessPermissionModeWire.d.ts +0 -76
- package/dist/headlessPermissionModeWire.js +1 -155
- package/dist/headlessReconnectWire.d.ts +0 -84
- package/dist/headlessReconnectWire.js +13 -67
- package/dist/hitl/approvalDecisionNoteAudit.d.ts +0 -49
- package/dist/hitl/approvalDecisionNoteAudit.js +0 -56
- package/dist/hitl/approvalOutcomeNote.d.ts +0 -2
- package/dist/hitl/approvalOutcomeNote.js +0 -20
- package/dist/hitl/approvalResolution.d.ts +0 -113
- package/dist/hitl/approvalResolution.js +0 -66
- package/dist/hitl/approvalsFeed.d.ts +0 -183
- package/dist/hitl/approvalsFeed.js +12 -243
- package/dist/hitl/armedGateRegistry.d.ts +0 -55
- package/dist/hitl/armedGateRegistry.js +0 -146
- package/dist/hitl/askGateWire.d.ts +0 -86
- package/dist/hitl/askGateWire.js +1 -95
- package/dist/hitl/askParkRowRouting.d.ts +0 -123
- package/dist/hitl/askParkRowRouting.js +1 -89
- package/dist/hitl/crashConverged.d.ts +0 -148
- package/dist/hitl/crashConverged.js +0 -214
- package/dist/hitl/editedRuleTextPrecheck.d.ts +0 -109
- package/dist/hitl/editedRuleTextPrecheck.js +0 -71
- package/dist/hitl/frameRouter.d.ts +0 -134
- package/dist/hitl/frameRouter.js +6 -378
- package/dist/hitl/gateIdentity.d.ts +0 -39
- package/dist/hitl/gateIdentity.js +0 -41
- package/dist/hitl/gateLedger.d.ts +0 -267
- package/dist/hitl/gateLedger.js +0 -121
- package/dist/hitl/hitlBridge.d.ts +7 -431
- package/dist/hitl/hitlBridge.js +7 -476
- package/dist/hitl/hitlHostSurface.d.ts +0 -150
- package/dist/hitl/hitlHostSurface.js +0 -169
- package/dist/hitl/livePendingAsk.d.ts +0 -91
- package/dist/hitl/livePendingAsk.js +0 -74
- package/dist/hitl/localAllowRule.d.ts +0 -62
- package/dist/hitl/localAllowRule.js +1 -33
- package/dist/hitl/parkOwnership.d.ts +0 -56
- package/dist/hitl/parkOwnership.js +0 -22
- package/dist/hitl/parkResolver.d.ts +3 -88
- package/dist/hitl/parkResolver.js +8 -349
- package/dist/hitl/parkRowBirthWait.d.ts +2 -26
- package/dist/hitl/parkRowBirthWait.js +3 -93
- package/dist/hitl/persistedRulesWire.d.ts +23 -371
- package/dist/hitl/persistedRulesWire.js +62 -329
- package/dist/hitl/planReviewWire.d.ts +4 -176
- package/dist/hitl/planReviewWire.js +9 -312
- package/dist/hitl/resumeRunningCard.d.ts +0 -105
- package/dist/hitl/resumeRunningCard.js +0 -105
- package/dist/hitl/sessionPolicyWire.d.ts +11 -191
- package/dist/hitl/sessionPolicyWire.js +0 -149
- package/dist/hitl/suspendedReopen.d.ts +3 -24
- package/dist/hitl/suspendedReopen.js +0 -14
- package/dist/hitl/toolApprovalWire.d.ts +5 -1308
- package/dist/hitl/toolApprovalWire.js +5 -945
- package/dist/hooksWireCaps.d.ts +0 -38
- package/dist/hooksWireCaps.js +0 -190
- package/dist/host.d.ts +0 -105
- package/dist/host.js +0 -33
- package/dist/hostEnv.d.ts +0 -14
- package/dist/hostEnv.js +0 -13
- package/dist/imagesWireCaps.d.ts +0 -21
- package/dist/imagesWireCaps.js +0 -22
- package/dist/index.d.ts +0 -134
- package/dist/index.js +0 -476
- package/dist/interactiveHalt.d.ts +5 -153
- package/dist/interactiveHalt.js +0 -111
- package/dist/interactiveToolsWire.d.ts +0 -62
- package/dist/interactiveToolsWire.js +1 -67
- package/dist/leaderConflict.d.ts +0 -59
- package/dist/leaderConflict.js +0 -48
- package/dist/limitsWire.d.ts +0 -125
- package/dist/limitsWire.js +2 -120
- package/dist/liveInitToolFace.d.ts +0 -77
- package/dist/liveInitToolFace.js +1 -109
- package/dist/liveModelCatalog.d.ts +0 -52
- package/dist/liveModelCatalog.js +0 -48
- package/dist/liveQuestionStore.d.ts +0 -87
- package/dist/liveQuestionStore.js +1 -56
- package/dist/mcpLiveness.d.ts +0 -151
- package/dist/mcpLiveness.js +0 -122
- package/dist/mcpPanel.d.ts +0 -104
- package/dist/mcpPanel.js +0 -49
- package/dist/mcpReconnect.d.ts +0 -58
- package/dist/mcpReconnect.js +0 -69
- package/dist/mcpWireCaps.d.ts +0 -55
- package/dist/mcpWireCaps.js +1 -13
- package/dist/memoryComplianceCapability.d.ts +3 -57
- package/dist/memoryComplianceCapability.js +0 -57
- package/dist/memoryEntriesWire.d.ts +6 -198
- package/dist/memoryEntriesWire.js +0 -144
- package/dist/memoryOriginCapability.d.ts +3 -53
- package/dist/memoryOriginCapability.js +0 -50
- package/dist/memorySpecWire.d.ts +0 -116
- package/dist/memorySpecWire.js +0 -150
- package/dist/model/catalog.d.ts +0 -111
- package/dist/model/catalog.js +0 -87
- package/dist/model/catalogLoader.d.ts +0 -114
- package/dist/model/catalogLoader.js +2 -139
- package/dist/model/modelSupplyRules.d.ts +1 -55
- package/dist/model/modelSupplyRules.js +0 -62
- package/dist/model/providerAuth.d.ts +0 -103
- package/dist/model/providerAuth.js +2 -38
- package/dist/model/providerCatalog.d.ts +0 -45
- package/dist/model/providerCatalog.js +0 -37
- package/dist/model/providerPresets.d.ts +0 -33
- package/dist/model/providerPresets.js +2 -91
- package/dist/model/tierVocabulary.d.ts +0 -31
- package/dist/model/tierVocabulary.js +0 -27
- package/dist/modelBudgetRule.d.ts +0 -39
- package/dist/modelBudgetRule.js +0 -39
- package/dist/modelCapabilityProbe.d.ts +0 -175
- package/dist/modelCapabilityProbe.js +0 -147
- package/dist/modelWireCaps.d.ts +0 -13
- package/dist/modelWireCaps.js +0 -13
- package/dist/notifications.d.ts +0 -233
- package/dist/notifications.js +14 -492
- package/dist/oneShotWireCaps.d.ts +0 -34
- package/dist/oneShotWireCaps.js +0 -35
- package/dist/ownKey.d.ts +0 -33
- package/dist/ownKey.js +0 -33
- package/dist/panelRunningHistory.d.ts +0 -28
- package/dist/panelRunningHistory.js +0 -43
- package/dist/peerFrames.d.ts +0 -71
- package/dist/peerFrames.js +0 -168
- package/dist/peerLaneCapability.d.ts +0 -44
- package/dist/peerLaneCapability.js +0 -52
- package/dist/permissionRuleIssue.d.ts +0 -30
- package/dist/permissionRuleIssue.js +0 -78
- package/dist/permissionRulesWriteCapability.d.ts +0 -46
- package/dist/permissionRulesWriteCapability.js +0 -54
- package/dist/permissionWireCaps.d.ts +0 -37
- package/dist/permissionWireCaps.js +0 -37
- package/dist/postureKnob.d.ts +0 -71
- package/dist/postureKnob.js +0 -86
- package/dist/principalWire.d.ts +0 -17
- package/dist/principalWire.js +0 -17
- package/dist/printToolResultFrame.d.ts +0 -100
- package/dist/printToolResultFrame.js +0 -33
- package/dist/promptProfileWireCaps.d.ts +0 -13
- package/dist/promptProfileWireCaps.js +0 -13
- package/dist/readFacePosture.d.ts +0 -43
- package/dist/readFacePosture.js +0 -46
- package/dist/request/printNotification.d.ts +0 -20
- package/dist/request/printNotification.js +0 -55
- package/dist/request/taskRequest.d.ts +1 -249
- package/dist/request/taskRequest.js +20 -498
- package/dist/resumeRefusalCopy.d.ts +0 -136
- package/dist/resumeRefusalCopy.js +1 -117
- package/dist/retainBackgroundWireCaps.d.ts +0 -48
- package/dist/retainBackgroundWireCaps.js +0 -48
- package/dist/retryStatus.d.ts +2 -221
- package/dist/retryStatus.js +0 -107
- package/dist/rewindWireCaps.d.ts +0 -27
- package/dist/rewindWireCaps.js +0 -24
- package/dist/runCancelContext.d.ts +1 -20
- package/dist/runCancelContext.js +0 -34
- package/dist/runTerminal.d.ts +0 -273
- package/dist/runTerminal.js +0 -177
- package/dist/sandboxWire.d.ts +0 -38
- package/dist/sandboxWire.js +0 -82
- package/dist/scenarioWire.d.ts +0 -60
- package/dist/scenarioWire.js +0 -68
- package/dist/scratchpadWireCaps.d.ts +0 -11
- package/dist/scratchpadWireCaps.js +0 -32
- package/dist/sdkWireTransit.d.ts +0 -38
- package/dist/sdkWireTransit.js +0 -30
- package/dist/seam.d.ts +18 -853
- package/dist/seam.js +0 -52
- package/dist/seatContract.d.ts +0 -555
- package/dist/seatContract.js +5 -304
- package/dist/selfOrchestrationDenial.d.ts +0 -189
- package/dist/selfOrchestrationDenial.js +0 -162
- package/dist/selfOrchestrationWireCaps.d.ts +0 -38
- package/dist/selfOrchestrationWireCaps.js +0 -38
- package/dist/sessionMap.d.ts +0 -60
- package/dist/sessionMap.js +0 -37
- package/dist/sessionMemoryStatus.d.ts +11 -114
- package/dist/sessionMemoryStatus.js +0 -112
- package/dist/sessionModelLatch.d.ts +0 -29
- package/dist/sessionModelLatch.js +0 -40
- package/dist/sessionPolicyCapability.d.ts +3 -53
- package/dist/sessionPolicyCapability.js +0 -52
- package/dist/sessionSlot.d.ts +0 -26
- package/dist/sessionSlot.js +0 -17
- package/dist/skillsWireCaps.d.ts +0 -87
- package/dist/skillsWireCaps.js +0 -38
- package/dist/sqlEngineCapability.d.ts +0 -118
- package/dist/sqlEngineCapability.js +0 -134
- package/dist/sseIdleTriage.d.ts +0 -79
- package/dist/sseIdleTriage.js +1 -80
- package/dist/steering.d.ts +0 -54
- package/dist/steering.js +0 -63
- package/dist/subagent/engineCompactWire.d.ts +0 -34
- package/dist/subagent/engineCompactWire.js +4 -134
- package/dist/subagent/engineDelegatedPrompt.d.ts +0 -31
- package/dist/subagent/engineDelegatedPrompt.js +1 -103
- package/dist/subagent/engineRowStopGate.d.ts +0 -20
- package/dist/subagent/engineRowStopGate.js +0 -49
- package/dist/subagent/engineSubagentOutput.d.ts +0 -7
- package/dist/subagent/engineSubagentOutput.js +1 -51
- package/dist/subagent/engineSubagentResume.d.ts +2 -279
- package/dist/subagent/engineSubagentResume.js +2 -129
- package/dist/subagent/engineSubagentSteer.d.ts +0 -26
- package/dist/subagent/engineSubagentSteer.js +0 -63
- package/dist/subagent/engineSubagentTail.d.ts +0 -38
- package/dist/subagent/engineSubagentTail.js +2 -110
- package/dist/subagent/engineTaskHandleWire.d.ts +6 -67
- package/dist/subagent/engineTaskHandleWire.js +0 -126
- package/dist/subagent/subagentOwnerAbsence.d.ts +0 -2
- package/dist/subagent/subagentOwnerAbsence.js +0 -25
- package/dist/subagentContentStore.d.ts +3 -260
- package/dist/subagentContentStore.js +7 -540
- package/dist/systemReminderTag.d.ts +0 -49
- package/dist/systemReminderTag.js +0 -61
- package/dist/toolResult.d.ts +1 -211
- package/dist/toolResult.js +1 -358
- package/dist/toolRoster.d.ts +0 -140
- package/dist/toolRoster.js +0 -66
- package/dist/typePins.d.ts +0 -46
- package/dist/types/engineState.d.ts +0 -71
- package/dist/types/engineState.js +0 -16
- package/dist/ultracodeWireCaps.d.ts +0 -75
- package/dist/ultracodeWireCaps.js +0 -92
- package/dist/unrefTimer.d.ts +0 -27
- package/dist/webSearchBackendCapability.d.ts +0 -72
- package/dist/webSearchBackendCapability.js +0 -79
- package/dist/webSearchWireCaps.d.ts +0 -37
- package/dist/webSearchWireCaps.js +0 -34
- package/dist/websearch/searchProviderPresets.d.ts +0 -81
- package/dist/websearch/searchProviderPresets.js +0 -27
- package/dist/wireErrorTriage.d.ts +4 -160
- package/dist/wireErrorTriage.js +0 -171
- package/dist/wireRefusalCopy.d.ts +0 -28
- package/dist/wireRefusalCopy.js +0 -28
- package/dist/workflow.d.ts +0 -40
- package/dist/workflow.js +0 -52
- package/dist/workflowClient.d.ts +0 -122
- package/dist/workflowClient.js +8 -360
- package/dist/workflowMonitor.d.ts +2 -72
- package/dist/workflowMonitor.js +0 -26
- package/dist/writeProtectionCapability.d.ts +0 -112
- package/dist/writeProtectionCapability.js +0 -109
- package/docs/INTEGRATION-CLIENTS.md +78 -5
- package/package.json +3 -3
package/dist/engineWireSdk.js
CHANGED
|
@@ -1,29 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ⇄ B2 批搬迁(2026-07-27,多端改造设计稿 §3 B2):cli src/sema/engineWireSdk.ts 逐字搬入(纯半场 client 工厂;agentsWireCaps 的静态依赖,故同批过来)。
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* engineWireSdk — SDK 宪法迁移批(0.0.52)的纯半场 client 工厂:壳内各 wire 子模块(compact/steer/
|
|
6
|
-
* plan-review/auto-title/recap/caps 探测)从手抄 raw fetch 改接 @sema-agent/sdk AgentClient 的共用
|
|
7
|
-
* 构造点。ZERO 产品依赖(只 import 外部零依赖 SDK)——agentsWireCaps/liveInitToolFace 等「纯半场/
|
|
8
|
-
* 零产品图」模块可安全 import,不拖 engineTarget 的 fs 图,亦无循环依赖。
|
|
9
|
-
*
|
|
10
|
-
* 凭证解析 = engineTarget.resolveLiveAuthToken 的逐字镜像(#118 三态;那边是产品半场真源,这里为
|
|
11
|
-
* 纯半场复刻,两处语义必须一致):
|
|
12
|
-
* · token 有 → 原样 Bearer;
|
|
13
|
-
* · 无 token ∧ loopback → { mode: 'loopback-unauthed' }(出站零 Authorization 头,绝不伪造);
|
|
14
|
-
* · 无 token ∧ 非 loopback → 'anon'(fail-closed worker 换来诚实 401;与主车道 replEntry 同姿势)。
|
|
15
|
-
* ⚠️ 迁移差分记账:旧 raw fetch 在「无 token ∧ 非 loopback」时不带任何 Authorization 头;SDK 恒需
|
|
16
|
-
* 合法 authToken 形,这里按主车道姿势出 'anon'——该态本就是残破配置(connect 未登录),两种姿势对
|
|
17
|
-
* fail-closed worker 都是 401,对 owner-gated 路由都是 owner 不匹配,行为面等价。
|
|
18
|
-
*
|
|
19
|
-
* 缺省 maxRetries=0:raw fetch 原语义是单发不重试(探针有自己的预算窗;fire-and-forget 不该静默
|
|
20
|
-
* 翻倍打点)。要 SDK 缺省重试的调用方显式传。principal 缺席=不发头(F-011 停发,replEntry live 车道
|
|
21
|
-
* 同款)——SDK Transport 恒 stamp x-agent-principal(principal-first 宪法);旧 raw fetch 在缺
|
|
22
|
-
* principal 时省略该头,迁移后恒出示,对 requirePrincipal 部署是 fail-open 改善,已记账。
|
|
23
|
-
*/
|
|
24
1
|
import { AgentClient } from '@sema-agent/sdk';
|
|
25
2
|
import { normalizeWirePrincipal } from './principalWire.js';
|
|
26
|
-
/** loopback 判定(engineTarget.isLoopbackEngineUrl 逐字镜像;解析失败=非 loopback)。 */
|
|
27
3
|
export function isLoopbackWireUrl(url) {
|
|
28
4
|
try {
|
|
29
5
|
const h = new URL(url).hostname;
|
|
@@ -33,24 +9,6 @@ export function isLoopbackWireUrl(url) {
|
|
|
33
9
|
return false;
|
|
34
10
|
}
|
|
35
11
|
}
|
|
36
|
-
/**
|
|
37
|
-
* §8-2 定谳的**唯一**凭证解析口(B4 收编)—— 11 处构造点的公共分母。
|
|
38
|
-
*
|
|
39
|
-
* 背景(设计稿 §8-2 + B4 实测):壳里今天是 **2 份三态解析**(`engineTarget.resolveLiveAuthToken`
|
|
40
|
-
* 产品半场 + 本包 `wireAuthTokenFor` 纯半场,后者头注自述是前者的「逐字镜像」⇒ 两份必然漂移)
|
|
41
|
-
* 外加 **11 处 `new AgentClient` 直造**,其中 7 处根本不走任何解析口,直接手写
|
|
42
|
-
* `token ?? { mode:'loopback-unauthed' }` —— 那一形**丢了 'anon' 那一态**:非 loopback 且无 token
|
|
43
|
-
* 时它给的是 loopback-unauthed(出站零 Authorization 头),而三态解析给 'anon'。对 fail-closed
|
|
44
|
-
* worker 两者都是 401,但对 **owner-gated 路由**不是同一回事,所以这是真分歧不是等价写法。
|
|
45
|
-
*
|
|
46
|
-
* 🔴 **env 缺省留在端上**:`resolveLiveAuthToken` 的第二参缺省是 `process.env.SEMA_LIVE_TOKEN`,
|
|
47
|
-
* 那一半**绝不进包**(本包零 `process.env` —— portability 门盯着)。壳侧 shim 保留缺省参即可:
|
|
48
|
-
* `resolveLiveAuthToken(u, t = process.env.SEMA_LIVE_TOKEN) => resolveWireAuth(u, t)`。
|
|
49
|
-
*
|
|
50
|
-
* 三态(#118):token 有 ⇒ 原样 Bearer;无 token ∧ loopback ⇒ `{mode:'loopback-unauthed'}`
|
|
51
|
-
* (出站零 Authorization 头,绝不伪造);无 token ∧ 非 loopback ⇒ `'anon'`(fail-closed 换诚实 401)。
|
|
52
|
-
* `baseUrl` 允许 undefined(= `resolveLiveAuthToken` 的签名超集,本地自 spawn 态)⇒ 'anon'。
|
|
53
|
-
*/
|
|
54
12
|
export function resolveWireAuth(baseUrl, token) {
|
|
55
13
|
if (token)
|
|
56
14
|
return token;
|
|
@@ -58,16 +16,9 @@ export function resolveWireAuth(baseUrl, token) {
|
|
|
58
16
|
return { mode: 'loopback-unauthed' };
|
|
59
17
|
return 'anon';
|
|
60
18
|
}
|
|
61
|
-
/**
|
|
62
|
-
* #118 三态凭证解析(旧名,B2 引入)。
|
|
63
|
-
* B4 起是 `resolveWireAuth` 的**别名**(baseUrl 必填的窄签名);两者行为逐字相同,保留是为了
|
|
64
|
-
* 壳侧既有 import 零改动 —— 不设代际让位([clean-cut-no-legacy-compat] 只约束**行为面**硬切,
|
|
65
|
-
* 同一函数的两个名字不是两套行为)。新代码一律用 `resolveWireAuth`。
|
|
66
|
-
*/
|
|
67
19
|
export function wireAuthTokenFor(baseUrl, token) {
|
|
68
20
|
return resolveWireAuth(baseUrl, token);
|
|
69
21
|
}
|
|
70
|
-
/** 出站头的**归一读写**(SDK 的传输层给的是普通对象,但入参形状是 `HeadersInit` 三形之一)。 */
|
|
71
22
|
function headersToRecord(init) {
|
|
72
23
|
const out = {};
|
|
73
24
|
if (init === undefined)
|
|
@@ -89,16 +40,6 @@ function headersToRecord(init) {
|
|
|
89
40
|
out[String(k).toLowerCase()] = String(v);
|
|
90
41
|
return out;
|
|
91
42
|
}
|
|
92
|
-
/**
|
|
93
|
-
* 把一个 `fetch` 包一层:**每一发出站请求**重读凭证并就地改写 Authorization 头。
|
|
94
|
-
*
|
|
95
|
-
* 🔴 为什么是包 `fetch` 而不是「构造时解析一次」:底层客户端把凭证捕获进构造期闭包,构造时解析
|
|
96
|
-
* 等于把快照换了个位置放 —— 换代之后照样发旧凭证。请求那一刻才是**决定结果的时刻**。
|
|
97
|
-
* 🔴 三态在这一层逐格重演(与 {@link resolveWireAuth} 同一只):串 ⇒ `Bearer <串>`;
|
|
98
|
-
* `{mode:'loopback-unauthed'}` ⇒ **删**掉 Authorization 头(绝不伪造一个)。
|
|
99
|
-
* 🔴 取值函数抛错 ⇒ 当「这一刻没有凭证」处置(fail-soft):一个坏掉的取值口不该让整条 wire 不可用,
|
|
100
|
-
* 而且异常里可能夹带凭证材料,原样上抛就是又一条外溢面。
|
|
101
|
-
*/
|
|
102
43
|
function withPerRequestAuth(baseUrl, read, inner) {
|
|
103
44
|
return async (input, init) => {
|
|
104
45
|
let token;
|
|
@@ -106,7 +47,6 @@ function withPerRequestAuth(baseUrl, read, inner) {
|
|
|
106
47
|
token = read();
|
|
107
48
|
}
|
|
108
49
|
catch {
|
|
109
|
-
// fail-soft:取不到就按无 token 走三态(理由见本函数头注第三条)。
|
|
110
50
|
token = undefined;
|
|
111
51
|
}
|
|
112
52
|
const resolved = resolveWireAuth(baseUrl, token);
|
|
@@ -118,20 +58,13 @@ function withPerRequestAuth(baseUrl, read, inner) {
|
|
|
118
58
|
return inner(input, { ...init, headers });
|
|
119
59
|
};
|
|
120
60
|
}
|
|
121
|
-
/**
|
|
122
|
-
* 构造一个引擎 wire 用 AgentClient。null = 构造失败(SDK fail-closed 拒绝——不该发生:
|
|
123
|
-
* wireAuthTokenFor 恒给合法形;防御性 fail-soft,调用方按各自离线/探测失败路径处理)。
|
|
124
|
-
*/
|
|
125
61
|
export function makeEngineWireClient(cfg) {
|
|
126
62
|
try {
|
|
127
63
|
const principal = normalizeWirePrincipal(cfg.principal);
|
|
128
|
-
// 取值函数形:出站腿包一层「每发一次读一次」;构造期**一次都不读**(读一次就是一次快照)。
|
|
129
64
|
const source = typeof cfg.token === 'function' ? cfg.token : null;
|
|
130
65
|
const innerFetch = cfg.fetchImpl ?? fetch;
|
|
131
66
|
const base = {
|
|
132
67
|
baseUrl: cfg.baseUrl,
|
|
133
|
-
// F-011 停发:缺席/空串=不给键(SDK 6.11 缺席=不发 x-agent-principal 头,owner-null)。
|
|
134
|
-
// A-028.10(0.30.3):空串判升级为 trim 判(principalWire 同尺)——全空白值同罪,归缺席。
|
|
135
68
|
...(principal !== undefined ? { principal } : {}),
|
|
136
69
|
...(cfg.timeoutMs !== undefined ? { timeoutMs: cfg.timeoutMs } : {}),
|
|
137
70
|
maxRetries: cfg.maxRetries ?? 0,
|
|
@@ -141,18 +74,11 @@ export function makeEngineWireClient(cfg) {
|
|
|
141
74
|
? { fetch: cfg.fetchImpl }
|
|
142
75
|
: {}),
|
|
143
76
|
};
|
|
144
|
-
// relay 形直传(显式声明,不过三态解析);串/缺席走 resolveWireAuth 三态,语义与 0.28.x 字节
|
|
145
|
-
// 不变。分支构造而非三元合流:SDK AgentClientConfig 按 authToken 判别联合,联合值不可直赋。
|
|
146
77
|
if (typeof cfg.token === 'object')
|
|
147
78
|
return new AgentClient({ ...base, authToken: cfg.token });
|
|
148
79
|
if (source !== null) {
|
|
149
|
-
// 🔴 构造期给的是**不读取值函数**的三态形(回环 ⇒ loopback-unauthed;非回环 ⇒ 匿名身份)。
|
|
150
|
-
// 它只用来过 SDK 的构造期形校验与浏览器守卫 —— 真正上 wire 的那一份由上面那层每发重写,
|
|
151
|
-
// 所以这里绝不能顺手调一次取值函数:调了就多一次「与任何请求都不对应」的读取,
|
|
152
|
-
// 而「读取次数 = 请求次数」正是本形的可验证承诺(见 run-wire-auth-source-test.mjs G2)。
|
|
153
80
|
return new AgentClient({ ...base, authToken: resolveWireAuth(cfg.baseUrl, undefined) });
|
|
154
81
|
}
|
|
155
|
-
// 到这里 `cfg.token` 只可能是串或缺席(对象形与函数形都已在上面分流),类型面收窄靠一次显式判。
|
|
156
82
|
const literal = typeof cfg.token === 'string' ? cfg.token : undefined;
|
|
157
83
|
return new AgentClient({ ...base, authToken: resolveWireAuth(cfg.baseUrl, literal) });
|
|
158
84
|
}
|
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
export interface EngineWireTarget {
|
|
2
2
|
baseUrl: string;
|
|
3
3
|
token?: string;
|
|
4
|
-
/** 缺席=不发 x-agent-principal 头(owner-null,F-011 停发);显式装配/env 值恒赢。
|
|
5
|
-
* A-028.10(0.30.3):在场性按 trim 判(principalWire 原语)——全空白值在**读出口**归缺席,
|
|
6
|
-
* 绝不发全空白头(裁定=壳 livePrincipal trim 语义为正)。 */
|
|
7
4
|
principal?: string;
|
|
8
5
|
}
|
|
9
|
-
/** 装/卸引擎 wire 目标。传 null 卸回 env 派生。返回还原函数。 */
|
|
10
6
|
export declare function installEngineWireTarget(t: EngineWireTarget | null): () => void;
|
|
11
|
-
/** W1 带 key 变体:装/卸某会话的引擎 wire 目标(多会话宿主每会话一键,互不顶盖)。 */
|
|
12
7
|
export declare function installEngineWireTargetFor(sessionKey: string, t: EngineWireTarget | null): () => void;
|
|
13
|
-
/**
|
|
14
|
-
* 当前引擎 wire 目标。null = 无 wire(离线/mock/浏览器未装)—— 调用方走各自的回落路径,
|
|
15
|
-
* **不是**错误态。
|
|
16
|
-
*/
|
|
17
8
|
export declare function engineWireTarget(): EngineWireTarget | null;
|
|
18
|
-
/**
|
|
19
|
-
* W1 带 key 变体。env 派生回落是**进程级**(键无关):该键未显式装过 ⇒ 与零参同一条 env
|
|
20
|
-
* 回落路径(Node 壳单会话语义不变;浏览器宿主 env 恒空 ⇒ null)。
|
|
21
|
-
*/
|
|
22
9
|
export declare function engineWireTargetFor(sessionKey: string): EngineWireTarget | null;
|
|
23
|
-
/** 诊断开关(壳侧 `process.env.SEMA_DEBUG` 的等价读;本包零 process)。 */
|
|
24
10
|
export declare function engineWireDebugEnabled(): boolean;
|
package/dist/engineWireTarget.js
CHANGED
|
@@ -1,33 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ⇄ B6 批搬迁(2026-07-27,设计稿 §3 B6):子代 wire 族里**逐字重复**的 `wireConfig()`
|
|
3
|
-
* (SEMA_LIVE_BASEURL / SEMA_LIVE_TOKEN / SEMA_LIVE_PRINCIPAL 三读;principal 缺席=不发头,F-011 停发)
|
|
4
|
-
* 收成一份。
|
|
5
|
-
*
|
|
6
|
-
* 🔴 收编前的事实(壳 HEAD 2aa1d3e 实测,`grep -rln 'function wireConfig' src/sema/`):
|
|
7
|
-
* **七**份而不是六份 —— `engineSubagentOutput.ts:30` · `engineSubagentSteer.ts:26` ·
|
|
8
|
-
* `engineTaskHandleWire.ts:40` · `engineCompactWire.ts:77` · `engineSubagentTail.ts:40` ·
|
|
9
|
-
* `engineDelegatedPrompt.ts:80` · **`planReviewWire.ts:36`**。
|
|
10
|
-
* ⚠️ 本批搬入的是前六份(子代/fleet 族);**第七份 `planReviewWire` 不在 B6 范围**,仍留壳内
|
|
11
|
-
* —— 它是下一批的收编候选,别以为已经收干净了(这条更正即为「按名字数数会数漏」的实例)。
|
|
12
|
-
* 七份漂移不是假想:`engineCompactWire` 那份已经多了一行 principal 注释,`engineSubagentSteer`
|
|
13
|
-
* 那份 token 读法与其它几份的 `...(cfg.token ? …)` spread 姿势不同步。
|
|
14
|
-
*
|
|
15
|
-
* 🔴 env 读取走 `hostEnv()`(本包零 `process` —— portability 门盯着)。Node 下 `hostEnv()` 返回的
|
|
16
|
-
* 就是 `process.env` 那个同一对象 ⇒ 壳侧行为一字节不变;浏览器宿主返回 `{}` ⇒ `baseUrl`
|
|
17
|
-
* 缺席 ⇒ 每个 verb 走自己既有的「无 wire」回落路径(不是报错)。
|
|
18
|
-
* ⚠️ web/桌面宿主要用这条 wire,**不能靠 env** —— 用 `installEngineWireTarget()` 显式装。
|
|
19
|
-
*/
|
|
20
1
|
import { hostEnv } from './hostEnv.js';
|
|
21
2
|
import { createSessionSlot, DEFAULT_SESSION_KEY } from './sessionSlot.js';
|
|
22
3
|
import { normalizeWirePrincipal } from './principalWire.js';
|
|
23
|
-
/** 显式装配(非 Node 宿主唯一的入口;装了就**优先于** env,便于桌面/web 一页多引擎)。
|
|
24
|
-
* W1(design/161):sessionKey → 注册表;零参 API = DEFAULT_SESSION_KEY 兼容层。 */
|
|
25
4
|
const installedByKey = createSessionSlot();
|
|
26
|
-
/** 装/卸引擎 wire 目标。传 null 卸回 env 派生。返回还原函数。 */
|
|
27
5
|
export function installEngineWireTarget(t) {
|
|
28
6
|
return installEngineWireTargetFor(DEFAULT_SESSION_KEY, t);
|
|
29
7
|
}
|
|
30
|
-
/** W1 带 key 变体:装/卸某会话的引擎 wire 目标(多会话宿主每会话一键,互不顶盖)。 */
|
|
31
8
|
export function installEngineWireTargetFor(sessionKey, t) {
|
|
32
9
|
const prev = installedByKey.get(sessionKey);
|
|
33
10
|
installedByKey.set(sessionKey, t);
|
|
@@ -35,21 +12,11 @@ export function installEngineWireTargetFor(sessionKey, t) {
|
|
|
35
12
|
installedByKey.set(sessionKey, prev);
|
|
36
13
|
};
|
|
37
14
|
}
|
|
38
|
-
/**
|
|
39
|
-
* 当前引擎 wire 目标。null = 无 wire(离线/mock/浏览器未装)—— 调用方走各自的回落路径,
|
|
40
|
-
* **不是**错误态。
|
|
41
|
-
*/
|
|
42
15
|
export function engineWireTarget() {
|
|
43
16
|
return engineWireTargetFor(DEFAULT_SESSION_KEY);
|
|
44
17
|
}
|
|
45
|
-
/**
|
|
46
|
-
* W1 带 key 变体。env 派生回落是**进程级**(键无关):该键未显式装过 ⇒ 与零参同一条 env
|
|
47
|
-
* 回落路径(Node 壳单会话语义不变;浏览器宿主 env 恒空 ⇒ null)。
|
|
48
|
-
*/
|
|
49
18
|
export function engineWireTargetFor(sessionKey) {
|
|
50
19
|
const installed = installedByKey.get(sessionKey) ?? null;
|
|
51
|
-
// A-028.10 显式装配臂(0.30.3 BEHAVIOR CHANGE):装配值里全空白 principal 在读出口归缺席
|
|
52
|
-
// (键不出现)——与 env 臂同一把 trim 尺;其余键原样。非空白值(含带空白包围的实值)一字不动。
|
|
53
20
|
if (installed !== null) {
|
|
54
21
|
const p = normalizeWirePrincipal(installed.principal);
|
|
55
22
|
if (p === installed.principal)
|
|
@@ -61,11 +28,6 @@ export function engineWireTargetFor(sessionKey) {
|
|
|
61
28
|
const baseUrl = env.SEMA_LIVE_BASEURL;
|
|
62
29
|
if (!baseUrl)
|
|
63
30
|
return null;
|
|
64
|
-
// principal must match the run's owner (stamped by the live stream) — the owner-gated routes answer
|
|
65
|
-
// 404 for non-owners (no existence oracle). F-011 停发([3279]):缺席=不发头,owner-null 两侧
|
|
66
|
-
// 对齐(server 7.8.1 读写面窄互认盖存量);显式 SEMA_LIVE_PRINCIPAL 恒赢,绝不铸哨兵值。
|
|
67
|
-
// A-028.10(0.30.3 BEHAVIOR CHANGE):裸 truthy → trim 判定 —— 全空白 env 值此前会发出
|
|
68
|
-
// 全空白 x-agent-principal 头(垃圾值伪装在场),现归缺席(键不出现),与壳 livePrincipal 同尺。
|
|
69
31
|
const envPrincipal = normalizeWirePrincipal(env.SEMA_LIVE_PRINCIPAL);
|
|
70
32
|
return {
|
|
71
33
|
baseUrl,
|
|
@@ -73,7 +35,6 @@ export function engineWireTargetFor(sessionKey) {
|
|
|
73
35
|
...(envPrincipal !== undefined ? { principal: envPrincipal } : {}),
|
|
74
36
|
};
|
|
75
37
|
}
|
|
76
|
-
/** 诊断开关(壳侧 `process.env.SEMA_DEBUG` 的等价读;本包零 process)。 */
|
|
77
38
|
export function engineWireDebugEnabled() {
|
|
78
39
|
return Boolean(hostEnv().SEMA_DEBUG);
|
|
79
40
|
}
|
package/dist/env/localeGeo.d.ts
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
/** 三档。🔴 `unknown` ≠ `intl`:前者是没有判据,后者是有判据且指向境外。 */
|
|
2
1
|
export type RegionHint = 'cn' | 'intl' | 'unknown';
|
|
3
|
-
/** 全部输入由调用方注入(Node 侧传 `env.LANG`/`env.LC_ALL` 与 `Intl.DateTimeFormat().resolvedOptions().timeZone`)。 */
|
|
4
2
|
export interface RegionHintInput {
|
|
5
|
-
/** `LANG`,如 `zh_CN.UTF-8`。 */
|
|
6
3
|
lang?: string;
|
|
7
|
-
/** `LC_ALL`。POSIX 下它压过 `LANG`(见 localeTag)。 */
|
|
8
4
|
lcAll?: string;
|
|
9
|
-
/** IANA 时区名,如 `Asia/Shanghai`。 */
|
|
10
5
|
timeZone?: string;
|
|
11
6
|
}
|
|
12
7
|
export interface RegionHintResult {
|
|
13
8
|
region: RegionHint;
|
|
14
|
-
/** 给端直接显示的诚实说明(英文,与本包其它面向宿主的文案同口径)。 */
|
|
15
9
|
reason: string;
|
|
16
10
|
}
|
|
17
|
-
/**
|
|
18
|
-
* 地域预选提示(纯函数,零网络、零环境读取)。
|
|
19
|
-
*
|
|
20
|
-
* 结果**永远只是默认值**:端必须让用户能当场改掉,并把 `reason` 显示出来(「已按你的系统区域
|
|
21
|
-
* 预选,可随时改」)。见文件头零耦合约束 —— 它不得被用于对模型 provider 目录做任何排序/过滤。
|
|
22
|
-
*/
|
|
23
11
|
export declare function resolveRegionHint(input?: RegionHintInput): RegionHintResult;
|
package/dist/env/localeGeo.js
CHANGED
|
@@ -1,55 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* localeGeo.ts — **地域预选 v1(零网络)**:只看系统 locale 与 IANA 时区,给出一个「默认选哪个
|
|
3
|
-
* 地址更可达」的提示。三端复用(CLI / web / 桌面)。
|
|
4
|
-
*
|
|
5
|
-
* ## 🔴 零耦合约束:模型 provider 目录不吃地域信号(clay 令 2026-07-31)
|
|
6
|
-
*
|
|
7
|
-
* 模型 provider **不分国内国外,完全用户选择,走全表** —— 模型 provider 表恒**全表呈现、顺序
|
|
8
|
-
* 不随地域变**,选哪家 100% 是用户的事。因此本模块与模型目录之间是**设计上的零耦合**,不是巧合:
|
|
9
|
-
* · 本模块**不导出**任何 `sortProvidersByRegion` / `filterProvidersFor(region)` 形状的函数;
|
|
10
|
-
* · `src/model/**` **不许** import 本模块(pure 门 GEO 段有机械断言把这条钉住,不靠自觉);
|
|
11
|
-
* · 唯一合法用途:**搜索 provider / 镜像源 / SearXNG 镜像地址**这类「取哪个地址更可达」的
|
|
12
|
-
* **默认预选**,而且**永远只是默认值,用户可改**。
|
|
13
|
-
*
|
|
14
|
-
* ## 为什么 v1 零网络
|
|
15
|
-
*
|
|
16
|
-
* 拨号探测(测 RTT / 查出口 IP)会在**用户还没同意任何事**之前就产生一次出站请求,而它换来的
|
|
17
|
-
* 只是一个初始默认值。locale 与时区是宿主已经知道的事实,不需要问任何人。⇒ 本模块是纯函数,
|
|
18
|
-
* 输入由调用方注入(不读宿主的环境变量,与本包 hostEnv 纪律一致:环境是宿主资产)。
|
|
19
|
-
* 门里那条「零环境读取」断言查的是**整份源文件**(注释也算),所以本文里刻意不出现那个成员
|
|
20
|
-
* 表达式的字面写法 —— 判据不必先长出一个词法器,代价只是这一行说明。
|
|
21
|
-
*
|
|
22
|
-
* ## 三档,`unknown` 不是 `intl`
|
|
23
|
-
*
|
|
24
|
-
* 两个信号都没有 ⇒ `unknown`,**绝不猜 `intl`**。「不知道」和「知道它在境外」是两件事:端拿到
|
|
25
|
-
* `unknown` 应当**不预选**(让用户自己挑),拿到 `intl` 才是预选国际地址。把不知道渲染成一个
|
|
26
|
-
* 具体答案,就是[honest-absence-not-fabricated-zero]里那条「编造零值」的同族错误。
|
|
27
|
-
*
|
|
28
|
-
* ## 冲突时**时区赢**(locale 说 zh 但时区是 America/New_York)
|
|
29
|
-
*
|
|
30
|
-
* 理由锚在本模块的用途上 —— 判的是「**哪个地址更可达**」,那是**机器在哪张网上**决定的:
|
|
31
|
-
* · **时区** = 系统对自己**所在位置**的记录(装机/NTP 时按位置设),与网络出口高度相关;
|
|
32
|
-
* · **locale** = 用户偏好**哪种语言**,与机器在哪张网上无关(在纽约用中文界面的人很多)。
|
|
33
|
-
* ⇒ 时区是位置的更强证据,冲突时它赢。两个信号一致时 `reason` 同时点名两者(证据更足)。
|
|
34
|
-
*
|
|
35
|
-
* ## `reason` 是「我看到了什么」,不是「你在哪」
|
|
36
|
-
*
|
|
37
|
-
* 端会把它渲成「已按你的系统区域预选,可随时改」。所以 reason 只陈述观测到的事实
|
|
38
|
-
* (`system time zone Asia/Shanghai`),不做身份断言(不写 "you are in China")—— 用户看到的
|
|
39
|
-
* 是判据本身,于是「这判据不对」是他能当场看出来并改掉的。
|
|
40
|
-
*
|
|
41
|
-
* ## tag 手术委托 `./localeTag.js`(F4 族D A-028.20,双出口成文)
|
|
42
|
-
*
|
|
43
|
-
* 剥 codeset/modifier、中性 locale 认定、子标签切分这台**手术**与 `env/uiLanguage.ts` 共用
|
|
44
|
-
* 同一份实现;但两件各答各的题(本件答「哪个地址更可达」,那件答「界面用哪种文字」),
|
|
45
|
-
* 输出域语义不同,刻意不收敛 —— 理由成文在 localeTag.ts 文件头。
|
|
46
|
-
*/
|
|
47
1
|
import { parseLocaleTag } from './localeTag.js';
|
|
48
|
-
/**
|
|
49
|
-
* 判为「内地」的 IANA 时区(含 backward 链接别名与老 `PRC` 形)。
|
|
50
|
-
* 🔴 `Asia/Hong_Kong` / `Asia/Macau` / `Asia/Taipei` **不在**表内:本模块判的是「哪个镜像地址
|
|
51
|
-
* 更可达」,这三处的网络出口与内地不同,按内地预选反而会给出更慢的默认值。
|
|
52
|
-
*/
|
|
53
2
|
const CN_TIME_ZONES = new Set([
|
|
54
3
|
'asia/shanghai',
|
|
55
4
|
'asia/chongqing',
|
|
@@ -59,37 +8,21 @@ const CN_TIME_ZONES = new Set([
|
|
|
59
8
|
'asia/kashgar',
|
|
60
9
|
'prc',
|
|
61
10
|
]);
|
|
62
|
-
/** IANA 时区名的形(`Area/Location`,允许多级如 `America/Argentina/Salta`)。 */
|
|
63
11
|
const IANA_SHAPE = /^[a-z]+(?:\/[a-z0-9_+-]+)+$/i;
|
|
64
|
-
/** 不含地理信息的时区(UTC 家族):有值,但不构成判据。 */
|
|
65
12
|
const GEOLESS_ZONES = new Set(['utc', 'gmt', 'z', 'universal', 'zulu']);
|
|
66
|
-
/** reason 里回显观测值的长度上限 —— 输入来自宿主环境变量,不该由它决定一行 UI 有多长。 */
|
|
67
13
|
const ECHO_MAX = 64;
|
|
68
14
|
const echo = (v) => (v.length > ECHO_MAX ? `${v.slice(0, ECHO_MAX)}…` : v);
|
|
69
|
-
/**
|
|
70
|
-
* 取生效的 locale 标签(已剥 codeset 与 modifier:`zh_CN.UTF-8@pinyin` → `zh_CN`)。
|
|
71
|
-
*
|
|
72
|
-
* 🔴 `LC_ALL` 非空时**独赢,不回落 `LANG`** —— POSIX 就是这个覆盖语义,而 reason 必须说的是
|
|
73
|
-
* **真正生效**的那个 locale。`LC_ALL=C` 时回落去报 `LANG` 的值,等于在 reason 里陈述一件
|
|
74
|
-
* 当前并不成立的事。
|
|
75
|
-
*/
|
|
76
15
|
function localeTag(input) {
|
|
77
16
|
const pick = (v) => (typeof v === 'string' ? v.trim() : '');
|
|
78
17
|
const raw = pick(input.lcAll) || pick(input.lang);
|
|
79
|
-
// tag 手术(剥 codeset/modifier、中性 locale、认形)单源在 localeTag.ts —— 本件只保留
|
|
80
|
-
// 「LC_ALL 独赢」这半句 POSIX 语义,手术本身不再自持第二份。
|
|
81
18
|
return parseLocaleTag(raw).tag;
|
|
82
19
|
}
|
|
83
|
-
/**
|
|
84
|
-
* locale → 信号。`zh` 系按**地区码优先、脚本次之**读(地区码比脚本更接近地理事实:
|
|
85
|
-
* `zh-Hans-TW` 用的是简体,但机器在台北那张网上)。
|
|
86
|
-
*/
|
|
87
20
|
function localeSignal(tag) {
|
|
88
21
|
if (!tag)
|
|
89
22
|
return 'unknown';
|
|
90
23
|
const parts = parseLocaleTag(tag).subtags;
|
|
91
24
|
if (parts[0] !== 'zh')
|
|
92
|
-
return 'intl';
|
|
25
|
+
return 'intl';
|
|
93
26
|
const rest = parts.slice(1);
|
|
94
27
|
if (rest.includes('cn'))
|
|
95
28
|
return 'cn';
|
|
@@ -99,9 +32,8 @@ function localeSignal(tag) {
|
|
|
99
32
|
return 'cn';
|
|
100
33
|
if (rest.includes('hant'))
|
|
101
34
|
return 'intl';
|
|
102
|
-
return 'cn';
|
|
35
|
+
return 'cn';
|
|
103
36
|
}
|
|
104
|
-
/** 时区 → 信号。形不对/UTC 家族 ⇒ 没信号(不是 `intl`)。 */
|
|
105
37
|
function timeZoneSignal(zone) {
|
|
106
38
|
const z = zone.toLowerCase();
|
|
107
39
|
if (!z)
|
|
@@ -112,12 +44,6 @@ function timeZoneSignal(zone) {
|
|
|
112
44
|
return 'unknown';
|
|
113
45
|
return IANA_SHAPE.test(z) ? 'intl' : 'unknown';
|
|
114
46
|
}
|
|
115
|
-
/**
|
|
116
|
-
* 地域预选提示(纯函数,零网络、零环境读取)。
|
|
117
|
-
*
|
|
118
|
-
* 结果**永远只是默认值**:端必须让用户能当场改掉,并把 `reason` 显示出来(「已按你的系统区域
|
|
119
|
-
* 预选,可随时改」)。见文件头零耦合约束 —— 它不得被用于对模型 provider 目录做任何排序/过滤。
|
|
120
|
-
*/
|
|
121
47
|
export function resolveRegionHint(input = {}) {
|
|
122
48
|
const zone = typeof input.timeZone === 'string' ? input.timeZone.trim() : '';
|
|
123
49
|
const tag = localeTag(input);
|
|
@@ -130,7 +56,6 @@ export function resolveRegionHint(input = {}) {
|
|
|
130
56
|
if (localeHint === zoneHint) {
|
|
131
57
|
return { region: zoneHint, reason: `system time zone ${echo(zone)} and locale ${echo(tag)}` };
|
|
132
58
|
}
|
|
133
|
-
// 冲突:两个观测都说出来,并说明用了哪一个(见文件头「冲突时时区赢」)。
|
|
134
59
|
return {
|
|
135
60
|
region: zoneHint,
|
|
136
61
|
reason: `system time zone ${echo(zone)} (locale ${echo(tag)} differs; time zone wins)`,
|
package/dist/env/localeTag.d.ts
CHANGED
|
@@ -1,40 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* localeTag.ts — F4 族D(A-028.20,2026-08-15):locale 标签的**纯 tag 手术**单源。
|
|
3
|
-
*
|
|
4
|
-
* ## 为什么要有这一件
|
|
5
|
-
*
|
|
6
|
-
* 「把一个 locale 标签剥成语言子标签」这台手术此前被做了三次:cli `i18n/core/uiLanguage.ts`
|
|
7
|
-
* (剥 codeset/modifier → 取语言子标签 → 判 UI 语言)、本包 `env/localeGeo.ts`(同一台手术 →
|
|
8
|
-
* 判地域预选)、web 侧第二份(答案还不一致)。手术步骤漂了(比如谁剥 `@modifier` 谁不剥),
|
|
9
|
-
* 同一个 `zh_CN.UTF-8@pinyin` 会在不同端得出不同判定。手术进包单源后,两个**输出域不同**的
|
|
10
|
-
* 判定(见下)共用这一台手术,步骤从结构上不可能再漂。
|
|
11
|
-
*
|
|
12
|
-
* ## 🔴 双出口成文:tag 手术单源 ≠ 答案单源
|
|
13
|
-
*
|
|
14
|
-
* 本件只做**手术**(剥、切、认形),不做**判定**。判定有两个,输出域**语义不同**,刻意不收敛:
|
|
15
|
-
* · `env/uiLanguage.ts` `pickUiLanguage` → `'en' | 'zh'`:**用户读哪种界面文字**(语言偏好域;
|
|
16
|
-
* 未知回落 en = 回落到可读的 fallback 目录);
|
|
17
|
-
* · `env/localeGeo.ts` `resolveRegionHint` → `'cn' | 'intl' | 'unknown'`:**机器在哪张网上**
|
|
18
|
-
* (地址可达域;未知就是 unknown,绝不猜 —— 端应当不预选)。
|
|
19
|
-
* 两域对同一输入给不同答案是**设计**,不是漂移:`zh-Hant` 的界面语言是中文(zh),而它的网络
|
|
20
|
-
* 预选是境外(intl)。谁要「收敛成一个函数」谁就把这两件事重新搅在一起。
|
|
21
|
-
*
|
|
22
|
-
* ## 手术步骤(POSIX `zh_CN.UTF-8@pinyin` → `zh_CN`)
|
|
23
|
-
*
|
|
24
|
-
* ① trim;② 剥 codeset(`.` 后);③ 剥 modifier(`@` 后)再 trim;
|
|
25
|
-
* ④ 中性 locale(`C`/`POSIX`)与不合语言标签形的串(头段非 2–3 位字母)⇒ **无信号**
|
|
26
|
-
* (`tag: ''`)——「没有 locale」和「locale 指向某语言」必须分得开;
|
|
27
|
-
* ⑤ 子标签统一小写、`_`→`-` 后切开(`tag` 保留原大小写 —— 端要拿它回显观测值)。
|
|
28
|
-
*/
|
|
29
|
-
/** 手术产物。`tag === ''` = 无信号(空/中性/形不对),此时 language/subtags 也为空。 */
|
|
30
1
|
export interface ParsedLocaleTag {
|
|
31
|
-
/** 剥 codeset/modifier 后的标签**原样**(保留大小写,供端回显观测值);'' = 无信号。 */
|
|
32
2
|
tag: string;
|
|
33
|
-
/** 语言子标签(小写);无信号时 ''。 */
|
|
34
3
|
language: string;
|
|
35
|
-
/** 全部子标签(小写,[-_] 切);无信号时 []。 */
|
|
36
4
|
subtags: string[];
|
|
37
5
|
}
|
|
38
|
-
/** 纯 tag 手术(见文件头步骤表)。任何宿主形态的标签都吃:POSIX `LANG`、BCP 47、
|
|
39
|
-
* `navigator.language`、Electron `app.getLocale()`。 */
|
|
40
6
|
export declare function parseLocaleTag(raw: string | undefined): ParsedLocaleTag;
|
package/dist/env/localeTag.js
CHANGED
|
@@ -1,37 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* localeTag.ts — F4 族D(A-028.20,2026-08-15):locale 标签的**纯 tag 手术**单源。
|
|
3
|
-
*
|
|
4
|
-
* ## 为什么要有这一件
|
|
5
|
-
*
|
|
6
|
-
* 「把一个 locale 标签剥成语言子标签」这台手术此前被做了三次:cli `i18n/core/uiLanguage.ts`
|
|
7
|
-
* (剥 codeset/modifier → 取语言子标签 → 判 UI 语言)、本包 `env/localeGeo.ts`(同一台手术 →
|
|
8
|
-
* 判地域预选)、web 侧第二份(答案还不一致)。手术步骤漂了(比如谁剥 `@modifier` 谁不剥),
|
|
9
|
-
* 同一个 `zh_CN.UTF-8@pinyin` 会在不同端得出不同判定。手术进包单源后,两个**输出域不同**的
|
|
10
|
-
* 判定(见下)共用这一台手术,步骤从结构上不可能再漂。
|
|
11
|
-
*
|
|
12
|
-
* ## 🔴 双出口成文:tag 手术单源 ≠ 答案单源
|
|
13
|
-
*
|
|
14
|
-
* 本件只做**手术**(剥、切、认形),不做**判定**。判定有两个,输出域**语义不同**,刻意不收敛:
|
|
15
|
-
* · `env/uiLanguage.ts` `pickUiLanguage` → `'en' | 'zh'`:**用户读哪种界面文字**(语言偏好域;
|
|
16
|
-
* 未知回落 en = 回落到可读的 fallback 目录);
|
|
17
|
-
* · `env/localeGeo.ts` `resolveRegionHint` → `'cn' | 'intl' | 'unknown'`:**机器在哪张网上**
|
|
18
|
-
* (地址可达域;未知就是 unknown,绝不猜 —— 端应当不预选)。
|
|
19
|
-
* 两域对同一输入给不同答案是**设计**,不是漂移:`zh-Hant` 的界面语言是中文(zh),而它的网络
|
|
20
|
-
* 预选是境外(intl)。谁要「收敛成一个函数」谁就把这两件事重新搅在一起。
|
|
21
|
-
*
|
|
22
|
-
* ## 手术步骤(POSIX `zh_CN.UTF-8@pinyin` → `zh_CN`)
|
|
23
|
-
*
|
|
24
|
-
* ① trim;② 剥 codeset(`.` 后);③ 剥 modifier(`@` 后)再 trim;
|
|
25
|
-
* ④ 中性 locale(`C`/`POSIX`)与不合语言标签形的串(头段非 2–3 位字母)⇒ **无信号**
|
|
26
|
-
* (`tag: ''`)——「没有 locale」和「locale 指向某语言」必须分得开;
|
|
27
|
-
* ⑤ 子标签统一小写、`_`→`-` 后切开(`tag` 保留原大小写 —— 端要拿它回显观测值)。
|
|
28
|
-
*/
|
|
29
|
-
/** 显式「无 locale」的 POSIX 值 —— 它们不携带任何语言/地域信息。 */
|
|
30
1
|
const NEUTRAL_LOCALES = new Set(['c', 'posix']);
|
|
31
|
-
/** 语言标签的形:头一段是 2–3 位字母的语言码。不合形的串(`1234` / 空串)当没信号。 */
|
|
32
2
|
const LANGUAGE_TAG_SHAPE = /^[a-z]{2,3}(?:[-_]|$)/i;
|
|
33
|
-
/** 纯 tag 手术(见文件头步骤表)。任何宿主形态的标签都吃:POSIX `LANG`、BCP 47、
|
|
34
|
-
* `navigator.language`、Electron `app.getLocale()`。 */
|
|
35
3
|
export function parseLocaleTag(raw) {
|
|
36
4
|
const trimmed = typeof raw === 'string' ? raw.trim() : '';
|
|
37
5
|
const noCodeset = trimmed.split('.')[0] ?? '';
|
package/dist/env/uiLanguage.d.ts
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
/** The languages sema's own screens are available in. */
|
|
2
1
|
export type UiLanguage = 'en' | 'zh';
|
|
3
|
-
/** Menu order: the detected language is pre-focused, so this order is presentation only. */
|
|
4
2
|
export declare const UI_LANGUAGES: readonly UiLanguage[];
|
|
5
|
-
/**
|
|
6
|
-
* Language names in the language itself (endonyms). NEVER translated and never routed through the
|
|
7
|
-
* message catalog: a language picker has to be readable by someone who cannot read the current UI
|
|
8
|
-
* language — that is the whole point of the screen.
|
|
9
|
-
*/
|
|
10
3
|
export declare const UI_LANGUAGE_ENDONYMS: Record<UiLanguage, string>;
|
|
11
4
|
export declare function isUiLanguage(v: unknown): v is UiLanguage;
|
|
12
|
-
/**
|
|
13
|
-
* Decide the UI language from ONE locale tag, whatever the host got it from — a POSIX `LANG`
|
|
14
|
-
* (`zh_CN.UTF-8`), a BCP 47 tag (`zh-Hant`), `navigator.language`, an Electron `app.getLocale()`.
|
|
15
|
-
* Anything whose language subtag is `zh` ⇒ 中文; everything else — including empty, `C` and
|
|
16
|
-
* `POSIX` — ⇒ English (which is also the fallback catalog, so "unknown" degrades to "readable").
|
|
17
|
-
*/
|
|
18
5
|
export declare function pickUiLanguage(localeTag: string | undefined): UiLanguage;
|
package/dist/env/uiLanguage.js
CHANGED
|
@@ -1,24 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* uiLanguage.ts — F4 族D(A-028.20,2026-08-15;整体自 cli `src/sema/i18n/core/uiLanguage.ts`
|
|
3
|
-
* 搬迁):UI 语言的**词表 + 判定**——类型、两种受支持语言、各自的 endonym、以及
|
|
4
|
-
* 「一个 locale 标签 → UI 语言」的纯判定。三端(CLI / web / 桌面)共用这一份。
|
|
5
|
-
*
|
|
6
|
-
* tag 手术(剥 codeset/modifier、切子标签)委托 `./localeTag.js` —— 与 `./localeGeo.js` 共用
|
|
7
|
-
* **同一台手术**但**各答各的题**(双出口成文,理由见 localeTag.ts 文件头:语言偏好域 ≠ 地址
|
|
8
|
-
* 可达域,`zh-Hant` 在前者是 zh、在后者是 intl)。
|
|
9
|
-
*
|
|
10
|
-
* 标签从哪来是宿主的事,本件不读环境:CLI 读 POSIX env(LC_ALL > LC_MESSAGES > LANG),
|
|
11
|
-
* 浏览器读 `navigator.language`,Electron 读 `app.getLocale()` —— 各宿主的三行 adapter 都
|
|
12
|
-
* 调同一个 `pickUiLanguage`。
|
|
13
|
-
*/
|
|
14
1
|
import { parseLocaleTag } from './localeTag.js';
|
|
15
|
-
/** Menu order: the detected language is pre-focused, so this order is presentation only. */
|
|
16
2
|
export const UI_LANGUAGES = ['en', 'zh'];
|
|
17
|
-
/**
|
|
18
|
-
* Language names in the language itself (endonyms). NEVER translated and never routed through the
|
|
19
|
-
* message catalog: a language picker has to be readable by someone who cannot read the current UI
|
|
20
|
-
* language — that is the whole point of the screen.
|
|
21
|
-
*/
|
|
22
3
|
export const UI_LANGUAGE_ENDONYMS = {
|
|
23
4
|
en: 'English',
|
|
24
5
|
zh: '中文',
|
|
@@ -26,12 +7,6 @@ export const UI_LANGUAGE_ENDONYMS = {
|
|
|
26
7
|
export function isUiLanguage(v) {
|
|
27
8
|
return v === 'en' || v === 'zh';
|
|
28
9
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Decide the UI language from ONE locale tag, whatever the host got it from — a POSIX `LANG`
|
|
31
|
-
* (`zh_CN.UTF-8`), a BCP 47 tag (`zh-Hant`), `navigator.language`, an Electron `app.getLocale()`.
|
|
32
|
-
* Anything whose language subtag is `zh` ⇒ 中文; everything else — including empty, `C` and
|
|
33
|
-
* `POSIX` — ⇒ English (which is also the fallback catalog, so "unknown" degrades to "readable").
|
|
34
|
-
*/
|
|
35
10
|
export function pickUiLanguage(localeTag) {
|
|
36
11
|
return parseLocaleTag(localeTag).language === 'zh' ? 'zh' : 'en';
|
|
37
12
|
}
|
package/dist/envFlag.d.ts
CHANGED
|
@@ -1,39 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* envFlag.ts — single spelling-set source for boolean-shaped `SEMA_*` env knobs (REF-CC-141, P2
|
|
3
|
-
* 台账 dup-02,wave1 卡B,2026-08-01).
|
|
4
|
-
*
|
|
5
|
-
* WHY: ten call sites across nine `*Wire*`/`*WireCaps*` modules each hand-rolled their own
|
|
6
|
-
* off/on-spelling check for a `SEMA_*` boolean env knob, and the four variants DISAGREED:
|
|
7
|
-
* ① 4-word off-set `'0'|'false'|'no'|'off'` (6 copies: forkWireCaps.ts isFalsy,
|
|
8
|
-
* selfOrchestrationWireCaps.ts isFalsy, retainBackgroundWireCaps.ts isFalsy,
|
|
9
|
-
* ultracodeWireCaps.ts deferOptedOut + lowFreqOptedOut, hooksWireCaps.ts isGoalStopHookWireArmed);
|
|
10
|
-
* ② 2-word off-set `'false'|'0'` (2 copies: detachWire.ts headlessDetachDisabledByEnv,
|
|
11
|
-
* finalVerifyWire.ts headlessFinalVerifyDisabledByEnv) — `=off` / `=no` silently did nothing;
|
|
12
|
-
* ③ 4-word off-set but a DIFFERENT fourth word `'off'|'0'|'false'|'none'`
|
|
13
|
-
* (attachmentsWireCaps.ts attachmentsForRequest — accepted "none", not "no");
|
|
14
|
-
* ④ 2-word set WITHOUT lowercasing `raw==='true'||raw==='1'` / `raw==='false'||raw==='0'`
|
|
15
|
-
* (interactiveToolsWire.ts resolveHeadlessInteractiveTools — `SEMA_HEADLESS_INTERACTIVE_TOOLS=False`
|
|
16
|
-
* fell through to the "not a boolean" warn-and-default path instead of being recognized).
|
|
17
|
-
*
|
|
18
|
-
* User-visible consequence (dup-02 evidence): the SAME settings.json could have
|
|
19
|
-
* `SEMA_HEADLESS_DETACH=off` silently ignored (falls back to default-ON) sitting right next to
|
|
20
|
-
* `SEMA_RETAIN_BACKGROUND=off` which worked — no way for a user to know which spelling their knob
|
|
21
|
-
* actually honors.
|
|
22
|
-
*
|
|
23
|
-
* FIX: one leaf module, one spelling set PER POLARITY, each the UNION across all four prior
|
|
24
|
-
* variants (only-tightens-never-loosens direction inverted here on purpose — widen everywhere,
|
|
25
|
-
* never narrow a caller's existing accepted set). Zero dependencies (no `hostEnv`/`EnvLike` import —
|
|
26
|
-
* operates on the already-extracted string, so it stays trivially portable and unit-testable).
|
|
27
|
-
*/
|
|
28
|
-
/**
|
|
29
|
-
* True iff `v` is an explicit OFF spelling ({@link OFF_SPELLINGS}: `0`/`false`/`no`/`off`/`none`,
|
|
30
|
-
* case-insensitive, trimmed). Unset/empty/unrecognized ⇒ `false` — the caller decides what "not
|
|
31
|
-
* explicitly off" defaults to (many of these knobs are default-ON escape hatches).
|
|
32
|
-
*/
|
|
33
1
|
export declare function envFlagOff(v: string | undefined): boolean;
|
|
34
|
-
/**
|
|
35
|
-
* True iff `v` is an explicit ON spelling ({@link ON_SPELLINGS}: `1`/`true`/`yes`/`on`,
|
|
36
|
-
* case-insensitive, trimmed). Unset/empty/unrecognized ⇒ `false` — the caller decides what "not
|
|
37
|
-
* explicitly on" defaults to.
|
|
38
|
-
*/
|
|
39
2
|
export declare function envFlagOn(v: string | undefined): boolean;
|
package/dist/envFlag.js
CHANGED
|
@@ -1,51 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* envFlag.ts — single spelling-set source for boolean-shaped `SEMA_*` env knobs (REF-CC-141, P2
|
|
3
|
-
* 台账 dup-02,wave1 卡B,2026-08-01).
|
|
4
|
-
*
|
|
5
|
-
* WHY: ten call sites across nine `*Wire*`/`*WireCaps*` modules each hand-rolled their own
|
|
6
|
-
* off/on-spelling check for a `SEMA_*` boolean env knob, and the four variants DISAGREED:
|
|
7
|
-
* ① 4-word off-set `'0'|'false'|'no'|'off'` (6 copies: forkWireCaps.ts isFalsy,
|
|
8
|
-
* selfOrchestrationWireCaps.ts isFalsy, retainBackgroundWireCaps.ts isFalsy,
|
|
9
|
-
* ultracodeWireCaps.ts deferOptedOut + lowFreqOptedOut, hooksWireCaps.ts isGoalStopHookWireArmed);
|
|
10
|
-
* ② 2-word off-set `'false'|'0'` (2 copies: detachWire.ts headlessDetachDisabledByEnv,
|
|
11
|
-
* finalVerifyWire.ts headlessFinalVerifyDisabledByEnv) — `=off` / `=no` silently did nothing;
|
|
12
|
-
* ③ 4-word off-set but a DIFFERENT fourth word `'off'|'0'|'false'|'none'`
|
|
13
|
-
* (attachmentsWireCaps.ts attachmentsForRequest — accepted "none", not "no");
|
|
14
|
-
* ④ 2-word set WITHOUT lowercasing `raw==='true'||raw==='1'` / `raw==='false'||raw==='0'`
|
|
15
|
-
* (interactiveToolsWire.ts resolveHeadlessInteractiveTools — `SEMA_HEADLESS_INTERACTIVE_TOOLS=False`
|
|
16
|
-
* fell through to the "not a boolean" warn-and-default path instead of being recognized).
|
|
17
|
-
*
|
|
18
|
-
* User-visible consequence (dup-02 evidence): the SAME settings.json could have
|
|
19
|
-
* `SEMA_HEADLESS_DETACH=off` silently ignored (falls back to default-ON) sitting right next to
|
|
20
|
-
* `SEMA_RETAIN_BACKGROUND=off` which worked — no way for a user to know which spelling their knob
|
|
21
|
-
* actually honors.
|
|
22
|
-
*
|
|
23
|
-
* FIX: one leaf module, one spelling set PER POLARITY, each the UNION across all four prior
|
|
24
|
-
* variants (only-tightens-never-loosens direction inverted here on purpose — widen everywhere,
|
|
25
|
-
* never narrow a caller's existing accepted set). Zero dependencies (no `hostEnv`/`EnvLike` import —
|
|
26
|
-
* operates on the already-extracted string, so it stays trivially portable and unit-testable).
|
|
27
|
-
*/
|
|
28
|
-
/** OFF spellings — union of all four prior variants (see file header). Case-insensitive, trimmed. */
|
|
29
1
|
const OFF_SPELLINGS = new Set(['0', 'false', 'no', 'off', 'none']);
|
|
30
|
-
/** ON spellings — union of all prior variants that had an explicit truthy branch (forkWireCaps
|
|
31
|
-
* isTruthy `1/true/yes/on`; interactiveToolsWire's narrower `true/1`). Case-insensitive, trimmed. */
|
|
32
2
|
const ON_SPELLINGS = new Set(['1', 'true', 'yes', 'on']);
|
|
33
3
|
function normalize(v) {
|
|
34
4
|
return typeof v === 'string' ? v.trim().toLowerCase() : '';
|
|
35
5
|
}
|
|
36
|
-
/**
|
|
37
|
-
* True iff `v` is an explicit OFF spelling ({@link OFF_SPELLINGS}: `0`/`false`/`no`/`off`/`none`,
|
|
38
|
-
* case-insensitive, trimmed). Unset/empty/unrecognized ⇒ `false` — the caller decides what "not
|
|
39
|
-
* explicitly off" defaults to (many of these knobs are default-ON escape hatches).
|
|
40
|
-
*/
|
|
41
6
|
export function envFlagOff(v) {
|
|
42
7
|
return OFF_SPELLINGS.has(normalize(v));
|
|
43
8
|
}
|
|
44
|
-
/**
|
|
45
|
-
* True iff `v` is an explicit ON spelling ({@link ON_SPELLINGS}: `1`/`true`/`yes`/`on`,
|
|
46
|
-
* case-insensitive, trimmed). Unset/empty/unrecognized ⇒ `false` — the caller decides what "not
|
|
47
|
-
* explicitly on" defaults to.
|
|
48
|
-
*/
|
|
49
9
|
export function envFlagOn(v) {
|
|
50
10
|
return ON_SPELLINGS.has(normalize(v));
|
|
51
11
|
}
|