@sema-agent/client-core 0.110.0 → 0.112.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 +244 -0
- package/README.md +59 -18
- package/dist/abortableSleep.d.ts +7 -0
- package/dist/abortableSleep.js +37 -0
- package/dist/adapt/arms.js +25 -4
- package/dist/adapt/toolCards.d.ts +3 -1
- package/dist/adapt/toolCards.js +4 -2
- package/dist/adapter/activeRunSelfHeal.d.ts +39 -0
- package/dist/adapter/activeRunSelfHeal.js +171 -3
- package/dist/adapter/downstream/eventToSdkMessage.js +10 -10
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
- package/dist/adapter/downstream/terminalToSdkResult.js +11 -0
- package/dist/adapter/runStream.d.ts +5 -0
- package/dist/adapter/runStream.js +15 -3
- package/dist/agentSession/engineSessionBackgroundStop.js +2 -2
- package/dist/attachmentRoute.d.ts +20 -0
- package/dist/attachmentRoute.js +39 -0
- package/dist/attachmentsWireCaps.js +1 -1
- package/dist/builtinOutputStyles.d.ts +12 -0
- package/dist/builtinOutputStyles.js +147 -0
- package/dist/checkpointRowVerdict.d.ts +3 -0
- package/dist/checkpointRowVerdict.js +14 -1
- package/dist/compactionStatus.d.ts +9 -0
- package/dist/compactionStatus.js +29 -5
- package/dist/consoleCaPin.d.ts +136 -0
- package/dist/consoleCaPin.js +827 -0
- package/dist/controlRouter.js +2 -1
- package/dist/coreValuePorts.d.ts +39 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/decideReceipt.d.ts +2 -1
- package/dist/deviceRebind.js +3 -3
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +6 -0
- package/dist/effectiveFacts.d.ts +9 -0
- package/dist/effectiveFacts.js +33 -0
- package/dist/engineAddress.d.ts +1 -0
- package/dist/engineAddress.js +4 -1
- package/dist/engineCredentialRelease.d.ts +54 -0
- package/dist/engineCredentialRelease.js +146 -0
- package/dist/engineErrorCodes.d.ts +1 -0
- package/dist/engineErrorCodes.js +1 -0
- package/dist/engineHealthProbeVerdict.d.ts +24 -0
- package/dist/engineHealthProbeVerdict.js +123 -0
- package/dist/engineNoticeCodes.js +5 -7
- package/dist/engineRepoint.d.ts +12 -5
- package/dist/engineRepoint.js +44 -19
- package/dist/engineRowRef.d.ts +3 -0
- package/dist/engineRowRef.js +11 -1
- package/dist/engineSwapCrossing.d.ts +57 -0
- package/dist/engineSwapCrossing.js +297 -0
- package/dist/engineUnavailable.d.ts +45 -0
- package/dist/engineUnavailable.js +496 -0
- package/dist/engineUrl.js +4 -2
- package/dist/eventLeg.js +3 -3
- package/dist/gateFailureCodes.js +2 -2
- package/dist/generated/sdkFactTables.d.ts +2 -1
- package/dist/generated/sdkFactTables.js +14 -0
- package/dist/generated/settingsSchemaFns.d.ts +1 -0
- package/dist/generated/settingsSchemaFns.js +3 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +38 -9
- package/dist/generated/settingsSchemaTables.d.ts +56 -0
- package/dist/generated/settingsSchemaTables.js +19 -0
- package/dist/generated/settingsSchemaTypes.d.ts +23 -13
- package/dist/generated/settingsSchemaUrlShape.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlShape.js +17 -0
- package/dist/hitl/approvalDelivery.d.ts +1 -0
- package/dist/hitl/approvalDelivery.js +1 -1
- package/dist/hitl/approvalResolution.d.ts +1 -1
- package/dist/hitl/approvalResolution.js +2 -1
- package/dist/hitl/askGateWire.js +5 -6
- package/dist/hitl/decisionRefusal.d.ts +6 -0
- package/dist/hitl/decisionRefusal.js +19 -10
- package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
- package/dist/hitl/decisionRefusalCarrier.js +348 -0
- package/dist/hitl/decisionSend.d.ts +7 -0
- package/dist/hitl/decisionSend.js +34 -12
- package/dist/hitl/editedApprovalAcceptance.js +1 -1
- package/dist/hitl/elicitationRefusal.d.ts +4 -0
- package/dist/hitl/elicitationRefusal.js +23 -0
- package/dist/hitl/frameRouter.d.ts +2 -2
- package/dist/hitl/frameRouter.js +8 -15
- package/dist/hitl/gateIdentity.d.ts +5 -0
- package/dist/hitl/gateIdentity.js +23 -0
- package/dist/hitl/hitlBridge.d.ts +6 -0
- package/dist/hitl/hitlBridge.js +10 -4
- package/dist/hitl/hitlHostSurface.d.ts +2 -1
- package/dist/hitl/hitlHostSurface.js +7 -2
- package/dist/hitl/localAllowRedemption.d.ts +70 -0
- package/dist/hitl/localAllowRedemption.js +276 -0
- package/dist/hitl/parkOwnership.js +2 -1
- package/dist/hitl/parkResolver.js +14 -4
- package/dist/hitl/persistedRulesWire.d.ts +16 -0
- package/dist/hitl/persistedRulesWire.js +70 -0
- package/dist/hitl/planReviewWire.d.ts +3 -0
- package/dist/hitl/planReviewWire.js +23 -6
- package/dist/hitl/policyDenyCause.d.ts +1 -1
- package/dist/hitl/policyDenyCause.js +1 -1
- package/dist/hitl/resumeRunningCard.d.ts +1 -0
- package/dist/hitl/resumeRunningCard.js +1 -0
- package/dist/hitl/screenCardCarriers.d.ts +15 -0
- package/dist/hitl/screenCardCarriers.js +41 -0
- package/dist/hitl/screenDecisionCards.d.ts +98 -0
- package/dist/hitl/screenDecisionCards.js +363 -0
- package/dist/hitl/sessionPolicyWire.js +2 -2
- package/dist/hitl/standingRows.d.ts +6 -2
- package/dist/hitl/standingRows.js +27 -2
- package/dist/hitl/toolApprovalWire.d.ts +30 -8
- package/dist/hitl/toolApprovalWire.js +264 -121
- package/dist/hooksReaderGenerations.js +1 -1
- package/dist/hooksWireCaps.js +3 -3
- package/dist/hostSettingNoticeArm.d.ts +3 -0
- package/dist/hostSettingNoticeArm.js +12 -0
- package/dist/hostTurnSettings.d.ts +3 -0
- package/dist/hostTurnSettings.js +38 -5
- package/dist/humanTurnRead.js +11 -1
- package/dist/i18n/messages.en.d.ts +292 -0
- package/dist/i18n/messages.en.js +298 -7
- package/dist/i18n/messages.zh.js +316 -6
- package/dist/i18n/translate.d.ts +3 -0
- package/dist/i18n/translate.js +78 -10
- package/dist/i18n/zh.d.ts +1 -0
- package/dist/i18n/zh.js +1 -0
- package/dist/index.d.ts +71 -20
- package/dist/index.js +44 -13
- package/dist/interactiveHalt.js +2 -1
- package/dist/interactiveInterrupt.js +20 -2
- package/dist/liveModelCatalog.d.ts +4 -0
- package/dist/liveModelCatalog.js +12 -3
- package/dist/localConfig/documents.d.ts +61 -0
- package/dist/localConfig/documents.js +51 -0
- package/dist/localConfig/kernel.d.ts +149 -0
- package/dist/localConfig/kernel.js +597 -0
- package/dist/localConfig/mcp/edit.d.ts +161 -0
- package/dist/localConfig/mcp/edit.js +846 -0
- package/dist/localConfig/mcp/servers.d.ts +165 -0
- package/dist/localConfig/mcp/servers.js +776 -0
- package/dist/localConfig/mcp/views.d.ts +170 -0
- package/dist/localConfig/mcp/views.js +429 -0
- package/dist/localConfig/modelPool.d.ts +262 -0
- package/dist/localConfig/modelPool.js +1489 -0
- package/dist/localConfig/modelPoolWords.d.ts +13 -0
- package/dist/localConfig/modelPoolWords.js +20 -0
- package/dist/localConfig/receiptShape.d.ts +7 -0
- package/dist/localConfig/receiptShape.js +135 -0
- package/dist/localConfig/settingsWrite.d.ts +127 -0
- package/dist/localConfig/settingsWrite.js +237 -0
- package/dist/localConfig/skills.d.ts +124 -0
- package/dist/localConfig/skills.js +397 -0
- package/dist/localConfig/skillsWords.d.ts +10 -0
- package/dist/localConfig/skillsWords.js +5 -0
- package/dist/localEngineSeatReading.d.ts +2 -2
- package/dist/localEngineSeatReading.js +5 -3
- package/dist/localEngineSpawn.d.ts +0 -7
- package/dist/localEngineSpawn.js +0 -92
- package/dist/localEngineStep.d.ts +2 -2
- package/dist/localEngineStep.js +2 -0
- package/dist/mcpProbeWire.js +2 -1
- package/dist/mcpReconnect.js +3 -3
- package/dist/mcpWireCaps.js +1 -1
- package/dist/memoryVerbsWire.js +3 -2
- package/dist/model/engineModelWords.d.ts +3 -0
- package/dist/model/engineModelWords.js +13 -0
- package/dist/model/onboardJudgement.d.ts +14 -4
- package/dist/model/onboardJudgement.js +91 -139
- package/dist/model/subagentModelWord.d.ts +21 -2
- package/dist/model/subagentModelWord.js +100 -29
- package/dist/modelCapabilityProbe.js +3 -40
- package/dist/modelConfigGapNotice.d.ts +20 -0
- package/dist/modelConfigGapNotice.js +102 -0
- package/dist/modsKernelIdentity.js +2 -47
- package/dist/notifications.d.ts +19 -0
- package/dist/notifications.js +114 -12
- package/dist/ownKey.d.ts +7 -0
- package/dist/ownKey.js +71 -8
- package/dist/pendingUserRow.d.ts +4 -0
- package/dist/pendingUserRow.js +16 -0
- package/dist/permissionsDeclaration.d.ts +3 -1
- package/dist/permissionsDeclaration.js +33 -9
- package/dist/planReviewCardFacts.d.ts +3 -0
- package/dist/planReviewCardFacts.js +52 -2
- package/dist/pluginHooksWire.d.ts +9 -1
- package/dist/pluginHooksWire.js +40 -6
- package/dist/printToolResultFrame.js +4 -2
- package/dist/promptBlockedCopy.js +12 -7
- package/dist/promptSuggestionBatch.d.ts +7 -0
- package/dist/promptSuggestionBatch.js +9 -0
- package/dist/promptSuggestionsTail.d.ts +39 -0
- package/dist/promptSuggestionsTail.js +116 -0
- package/dist/request/taskRequest.js +10 -6
- package/dist/requestCoordinate.d.ts +1 -0
- package/dist/requestCoordinate.js +13 -0
- package/dist/resumeRefusalCopy.d.ts +3 -1
- package/dist/resumeRefusalCopy.js +12 -4
- package/dist/rewindArchiveReading.js +4 -4
- package/dist/runCancelContext.d.ts +2 -1
- package/dist/runCancelContext.js +1 -0
- package/dist/runLedgerSnapshot.js +3 -3
- package/dist/runPermissionModeSwitch.js +3 -4
- package/dist/scenarioRefusal.js +11 -13
- package/dist/scenarioSkills.js +11 -6
- package/dist/seam.d.ts +16 -2
- package/dist/seam.js +10 -0
- package/dist/seatContract.d.ts +259 -9
- package/dist/seatContract.js +444 -15
- package/dist/sessionCostReading.d.ts +70 -0
- package/dist/sessionCostReading.js +150 -0
- package/dist/sessionHooksRoster.d.ts +4 -0
- package/dist/sessionHooksRoster.js +158 -0
- package/dist/sessionIdSegment.d.ts +1 -0
- package/dist/sessionIdSegment.js +4 -1
- package/dist/sessionMemoryErase.js +2 -1
- package/dist/sessionMemoryStatus.js +2 -2
- package/dist/sessionReadRedaction.d.ts +7 -0
- package/dist/sessionReadRedaction.js +26 -0
- package/dist/sessionSyncFileHistory.js +8 -9
- package/dist/settingsHooksSalvage.js +2 -1
- package/dist/sha256Bytes.d.ts +1 -0
- package/dist/sha256Bytes.js +46 -0
- package/dist/skillOverrideChain.d.ts +83 -0
- package/dist/skillOverrideChain.js +378 -0
- package/dist/skillsWireCaps.d.ts +3 -0
- package/dist/skillsWireCaps.js +16 -1
- package/dist/sseIdleTriage.js +2 -1
- package/dist/storeDurabilityWord.d.ts +15 -0
- package/dist/storeDurabilityWord.js +18 -0
- package/dist/storePostureCapability.d.ts +7 -3
- package/dist/storePostureCapability.js +69 -39
- package/dist/subagent/engineSubagentResume.js +2 -2
- package/dist/subagent/engineSubagentTail.js +2 -1
- package/dist/subagentContentStore.d.ts +11 -0
- package/dist/subagentContentStore.js +28 -2
- package/dist/toolResult.d.ts +1 -0
- package/dist/toolResult.js +2 -0
- package/dist/turnFailurePresentation.js +4 -10
- package/dist/userAttachmentEnvelope.d.ts +2 -1
- package/dist/userAttachmentEnvelope.js +10 -0
- package/dist/wireErrorTriage.js +2 -1
- package/dist/wireFailureShape.d.ts +4 -0
- package/dist/wireFailureShape.js +141 -19
- package/dist/wireRefusalCopy.d.ts +6 -5
- package/dist/wireRefusalCopy.js +49 -92
- package/docs/INTEGRATION-CLIENTS.md +2718 -17
- package/package.json +7 -3
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { SETTINGS_IS_RESERVED_MEMBER_NAME } from './generated/settingsSchemaFns.js';
|
|
2
|
+
import { readOwnDataValue } from './ownKey.js';
|
|
3
|
+
export const SKILL_OVERRIDE_STATES = Object.freeze(['on', 'name-only', 'user-invocable-only', 'off']);
|
|
4
|
+
export const SKILL_ORIGINS = Object.freeze(['skills', 'synced', 'commands', 'mcp', 'plugin', 'builtin', 'bundled']);
|
|
5
|
+
export const SKILL_OVERRIDE_LAYERS = Object.freeze(['policySettings', 'flagSettings', 'localSettings', 'projectSettings', 'userSettings']);
|
|
6
|
+
export const SKILL_OVERRIDE_DECIDERS = Object.freeze([...SKILL_OVERRIDE_LAYERS, 'session', 'default', 'plugin', 'builtin_clamp', 'hidden_behind_plugin']);
|
|
7
|
+
export const SKILL_OVERRIDE_LOCK_SOURCES = Object.freeze(['policy', 'flag', 'plugin', 'skill-author', 'reserved-name']);
|
|
8
|
+
const MANAGED = ['policySettings', 'flagSettings'];
|
|
9
|
+
const PLAIN = ['localSettings', 'projectSettings', 'userSettings'];
|
|
10
|
+
const MERGED = ['policySettings', 'flagSettings', 'localSettings', 'projectSettings', 'userSettings'];
|
|
11
|
+
const RANK = { on: 0, 'name-only': 1, 'user-invocable-only': 2, off: 3 };
|
|
12
|
+
const LIST_BUDGET = 4096;
|
|
13
|
+
function own(v, key) {
|
|
14
|
+
if (typeof v !== 'object' || v === null)
|
|
15
|
+
return undefined;
|
|
16
|
+
try {
|
|
17
|
+
return readOwnDataValue(v, key);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const isState = (v) => typeof v === 'string' && SKILL_OVERRIDE_STATES.some((w) => w === v);
|
|
24
|
+
const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
25
|
+
function stringsOf(v) {
|
|
26
|
+
const out = [];
|
|
27
|
+
if (!Array.isArray(v))
|
|
28
|
+
return out;
|
|
29
|
+
let n;
|
|
30
|
+
try {
|
|
31
|
+
n = own(v, 'length');
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
if (typeof n !== 'number' || !Number.isSafeInteger(n) || n < 0 || n > LIST_BUDGET)
|
|
37
|
+
return out;
|
|
38
|
+
for (let i = 0; i < n; i++) {
|
|
39
|
+
const s = own(v, String(i));
|
|
40
|
+
if (typeof s === 'string' && s !== '')
|
|
41
|
+
out.push(s);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
export function shapeSkillSubject(v) {
|
|
46
|
+
if (!isRecord(v))
|
|
47
|
+
return undefined;
|
|
48
|
+
const name = own(v, 'name');
|
|
49
|
+
const originRaw = own(v, 'origin');
|
|
50
|
+
const origin = SKILL_ORIGINS.find((w) => w === originRaw);
|
|
51
|
+
if (typeof name !== 'string' || name === '' || origin === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
const unq = own(v, 'unqualifiedName');
|
|
54
|
+
const synced = [];
|
|
55
|
+
const rawSynced = own(v, 'syncedNames');
|
|
56
|
+
if (Array.isArray(rawSynced)) {
|
|
57
|
+
const n = own(rawSynced, 'length');
|
|
58
|
+
if (typeof n === 'number' && Number.isSafeInteger(n) && n >= 0 && n <= LIST_BUDGET) {
|
|
59
|
+
for (let i = 0; i < n; i++) {
|
|
60
|
+
const e = own(rawSynced, String(i));
|
|
61
|
+
const sn = own(e, 'name');
|
|
62
|
+
const sb = own(e, 'bare');
|
|
63
|
+
if (typeof sn === 'string' && sn !== '' && typeof sb === 'string' && sb !== '')
|
|
64
|
+
synced.push(Object.freeze({ name: sn, bare: sb }));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return Object.freeze({
|
|
69
|
+
name,
|
|
70
|
+
origin,
|
|
71
|
+
unqualifiedName: typeof unq === 'string' && unq !== '' ? unq : undefined,
|
|
72
|
+
bareNameReserved: own(v, 'bareNameReserved') === true,
|
|
73
|
+
aliases: Object.freeze(stringsOf(own(v, 'aliases'))),
|
|
74
|
+
mcpLabels: Object.freeze(stringsOf(own(v, 'mcpLabels')).filter((s) => s.includes(':'))),
|
|
75
|
+
reservedLabels: Object.freeze(stringsOf(own(v, 'reservedLabels'))),
|
|
76
|
+
syncedNames: Object.freeze(synced),
|
|
77
|
+
followsSyncedSkillState: own(v, 'followsSyncedSkillState') === true,
|
|
78
|
+
disableModelInvocation: own(v, 'disableModelInvocation') === true,
|
|
79
|
+
hiddenBehindPlugin: own(v, 'hiddenBehindPlugin') === true,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function overridesOf(doc) {
|
|
83
|
+
const ov = own(doc, 'skillOverrides');
|
|
84
|
+
return isRecord(ov) ? ov : undefined;
|
|
85
|
+
}
|
|
86
|
+
export function shapeSkillLayers(v) {
|
|
87
|
+
const docs = {};
|
|
88
|
+
for (const l of SKILL_OVERRIDE_LAYERS)
|
|
89
|
+
docs[l] = overridesOf(own(v, l));
|
|
90
|
+
const disabled = new Set(stringsOf(own(v, 'disabledSources')));
|
|
91
|
+
const session = own(v, 'session');
|
|
92
|
+
const enabled = (layer) => layer === 'policySettings' || layer === 'flagSettings' || !disabled.has(layer);
|
|
93
|
+
let fromSettings = false;
|
|
94
|
+
for (const l of MERGED) {
|
|
95
|
+
if (!enabled(l))
|
|
96
|
+
continue;
|
|
97
|
+
const b = own(own(v, l), 'disableBundledSkills');
|
|
98
|
+
if (typeof b === 'boolean') {
|
|
99
|
+
fromSettings = b;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return Object.freeze({
|
|
104
|
+
docs: Object.freeze(docs),
|
|
105
|
+
session: isRecord(session) ? session : undefined,
|
|
106
|
+
enabled,
|
|
107
|
+
bundledDisabled: fromSettings || own(v, 'bundledSkillsDisabledByEnv') === true,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
function at(ov, key) {
|
|
111
|
+
if (ov === undefined || key === undefined)
|
|
112
|
+
return undefined;
|
|
113
|
+
const w = own(ov, key);
|
|
114
|
+
return isState(w) ? w : undefined;
|
|
115
|
+
}
|
|
116
|
+
const hitAt = (ov, key, by) => {
|
|
117
|
+
const w = at(ov, key);
|
|
118
|
+
return w === undefined ? undefined : { value: w, by };
|
|
119
|
+
};
|
|
120
|
+
function stricter(a, b) {
|
|
121
|
+
if (a === undefined)
|
|
122
|
+
return b;
|
|
123
|
+
return b !== undefined && RANK[b.value] > RANK[a.value] ? b : a;
|
|
124
|
+
}
|
|
125
|
+
function strictestIn(ov, names, by) {
|
|
126
|
+
let r;
|
|
127
|
+
for (const n of names) {
|
|
128
|
+
const w = at(ov, n);
|
|
129
|
+
if (w !== undefined && (r === undefined || RANK[w] > RANK[r.value]))
|
|
130
|
+
r = { value: w, by };
|
|
131
|
+
}
|
|
132
|
+
return r;
|
|
133
|
+
}
|
|
134
|
+
export function bareNameOf(s) {
|
|
135
|
+
if (s.unqualifiedName === undefined)
|
|
136
|
+
return undefined;
|
|
137
|
+
if (s.origin !== 'synced')
|
|
138
|
+
return s.unqualifiedName;
|
|
139
|
+
return s.bareNameReserved ? undefined : s.unqualifiedName;
|
|
140
|
+
}
|
|
141
|
+
const freeLabels = (s) => s.mcpLabels.filter((l) => !s.reservedLabels.includes(l));
|
|
142
|
+
function aliasNamesOf(s) {
|
|
143
|
+
return [...s.aliases, ...(s.unqualifiedName !== undefined ? [s.unqualifiedName] : []), ...freeLabels(s)];
|
|
144
|
+
}
|
|
145
|
+
export function secondaryNamesOf(s) {
|
|
146
|
+
const bare = bareNameOf(s);
|
|
147
|
+
return [...(bare !== undefined ? [bare] : []), ...(s.origin === 'mcp' ? freeLabels(s) : [])];
|
|
148
|
+
}
|
|
149
|
+
function reservedTighten(ov, s, by) {
|
|
150
|
+
const r = strictestIn(ov, s.reservedLabels, by);
|
|
151
|
+
return r === undefined || r.value === 'on' ? undefined : r;
|
|
152
|
+
}
|
|
153
|
+
function mergedAt(L, key) {
|
|
154
|
+
for (const l of MERGED) {
|
|
155
|
+
if (!L.enabled(l))
|
|
156
|
+
continue;
|
|
157
|
+
const h = hitAt(L.docs[l], key, l);
|
|
158
|
+
if (h !== undefined)
|
|
159
|
+
return h;
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
function viewThenSession(L, names) {
|
|
164
|
+
for (const n of names) {
|
|
165
|
+
const h = mergedAt(L, n);
|
|
166
|
+
if (h !== undefined)
|
|
167
|
+
return h;
|
|
168
|
+
}
|
|
169
|
+
for (const n of names) {
|
|
170
|
+
const h = hitAt(L.session, n, 'session');
|
|
171
|
+
if (h !== undefined)
|
|
172
|
+
return h;
|
|
173
|
+
}
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
function managedOnly(L, names) {
|
|
177
|
+
for (const n of names)
|
|
178
|
+
for (const l of MANAGED) {
|
|
179
|
+
const h = hitAt(L.docs[l], n, l);
|
|
180
|
+
if (h !== undefined)
|
|
181
|
+
return h;
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
function mcpChain(L, s, rest) {
|
|
186
|
+
const names = [s.name, ...rest];
|
|
187
|
+
let m;
|
|
188
|
+
let tight;
|
|
189
|
+
for (const l of MANAGED) {
|
|
190
|
+
m = stricter(m, strictestIn(L.docs[l], names, l));
|
|
191
|
+
tight = stricter(tight, reservedTighten(L.docs[l], s, l));
|
|
192
|
+
}
|
|
193
|
+
if (m !== undefined)
|
|
194
|
+
return stricter(m, tight);
|
|
195
|
+
for (const l of PLAIN) {
|
|
196
|
+
if (!L.enabled(l))
|
|
197
|
+
continue;
|
|
198
|
+
const b = strictestIn(L.docs[l], names, l);
|
|
199
|
+
if (b !== undefined)
|
|
200
|
+
return stricter(b, tight);
|
|
201
|
+
}
|
|
202
|
+
return stricter(strictestIn(L.session, names, 'session'), tight);
|
|
203
|
+
}
|
|
204
|
+
function overrideChain(L, s, mode) {
|
|
205
|
+
const rest = secondaryNamesOf(s);
|
|
206
|
+
if (s.origin === 'mcp')
|
|
207
|
+
return mcpChain(L, s, rest);
|
|
208
|
+
let v = (mode === 'all' ? viewThenSession : managedOnly)(L, [s.name, ...rest]);
|
|
209
|
+
const aliases = aliasNamesOf(s);
|
|
210
|
+
if (aliases.length === 0)
|
|
211
|
+
return v;
|
|
212
|
+
for (const l of MANAGED) {
|
|
213
|
+
const ov = L.docs[l];
|
|
214
|
+
if (at(ov, s.name) !== undefined)
|
|
215
|
+
break;
|
|
216
|
+
const w = strictestIn(ov, aliases, l);
|
|
217
|
+
if (w !== undefined && (v === undefined || RANK[w.value] > RANK[v.value]))
|
|
218
|
+
v = w;
|
|
219
|
+
if (rest.some((d) => at(ov, d) !== undefined))
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
return v;
|
|
223
|
+
}
|
|
224
|
+
function managedLock(L, s, mode) {
|
|
225
|
+
const aliases = aliasNamesOf(s);
|
|
226
|
+
let found;
|
|
227
|
+
for (const l of MANAGED) {
|
|
228
|
+
const ov = L.docs[l];
|
|
229
|
+
const b = s.origin === 'mcp'
|
|
230
|
+
? stricter(strictestIn(ov, [s.name, ...aliases], l), reservedTighten(ov, s, l))?.value
|
|
231
|
+
: (at(ov, s.name) ?? strictestIn(ov, aliases, l)?.value ?? reservedTighten(ov, s, l)?.value);
|
|
232
|
+
if (b === undefined)
|
|
233
|
+
continue;
|
|
234
|
+
if (s.origin !== 'mcp') {
|
|
235
|
+
found = { value: b, source: l };
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
if (found === undefined || RANK[b] > RANK[found.value])
|
|
239
|
+
found = { value: b, source: l };
|
|
240
|
+
}
|
|
241
|
+
if (found === undefined)
|
|
242
|
+
return undefined;
|
|
243
|
+
const chain = overrideChain(L, s, mode);
|
|
244
|
+
return chain !== undefined ? { value: chain.value, source: found.source, by: chain.by } : { value: found.value, source: found.source, by: found.source };
|
|
245
|
+
}
|
|
246
|
+
function pluginManaged(L, s) {
|
|
247
|
+
if (s.origin !== 'plugin')
|
|
248
|
+
return managedLock(L, s, 'all');
|
|
249
|
+
let n;
|
|
250
|
+
for (const sn of s.syncedNames) {
|
|
251
|
+
const h = Object.freeze({
|
|
252
|
+
...EMPTY_SUBJECT,
|
|
253
|
+
name: sn.name,
|
|
254
|
+
origin: 'synced',
|
|
255
|
+
unqualifiedName: sn.bare,
|
|
256
|
+
bareNameReserved: !s.aliases.includes(sn.bare),
|
|
257
|
+
});
|
|
258
|
+
const y = managedLock(L, h, 'administrator');
|
|
259
|
+
if (y !== undefined && (n === undefined || RANK[y.value] > RANK[n.value]))
|
|
260
|
+
n = y;
|
|
261
|
+
}
|
|
262
|
+
return n;
|
|
263
|
+
}
|
|
264
|
+
const EMPTY_SUBJECT = Object.freeze({
|
|
265
|
+
name: '',
|
|
266
|
+
origin: 'skills',
|
|
267
|
+
unqualifiedName: undefined,
|
|
268
|
+
bareNameReserved: false,
|
|
269
|
+
aliases: Object.freeze([]),
|
|
270
|
+
mcpLabels: Object.freeze([]),
|
|
271
|
+
reservedLabels: Object.freeze([]),
|
|
272
|
+
syncedNames: Object.freeze([]),
|
|
273
|
+
followsSyncedSkillState: false,
|
|
274
|
+
disableModelInvocation: false,
|
|
275
|
+
hiddenBehindPlugin: false,
|
|
276
|
+
});
|
|
277
|
+
function pluginFollow(L, s) {
|
|
278
|
+
let r;
|
|
279
|
+
for (const sn of s.syncedNames) {
|
|
280
|
+
const y = viewThenSession(L, s.followsSyncedSkillState || s.aliases.includes(sn.bare) ? [sn.name, sn.bare] : [sn.name]);
|
|
281
|
+
if (s.followsSyncedSkillState || y?.value === 'user-invocable-only')
|
|
282
|
+
r = stricter(r, y);
|
|
283
|
+
}
|
|
284
|
+
return r;
|
|
285
|
+
}
|
|
286
|
+
const effective = (value, decidedBy) => Object.freeze({ value, decidedBy });
|
|
287
|
+
export function effectiveOfShaped(L, s) {
|
|
288
|
+
if (s.hiddenBehindPlugin)
|
|
289
|
+
return effective('off', 'hidden_behind_plugin');
|
|
290
|
+
if (s.origin === 'plugin') {
|
|
291
|
+
const m = pluginManaged(L, s);
|
|
292
|
+
const v = stricter(m === undefined ? undefined : { value: m.value, by: m.by }, pluginFollow(L, s));
|
|
293
|
+
return v === undefined ? effective('on', 'default') : effective(v.value, v.by);
|
|
294
|
+
}
|
|
295
|
+
const r = overrideChain(L, s, 'all');
|
|
296
|
+
const value = r?.value ?? 'on';
|
|
297
|
+
if (s.origin === 'builtin' && L.bundledDisabled)
|
|
298
|
+
return value === 'off' ? effective('off', r?.by ?? 'default') : effective('user-invocable-only', 'builtin_clamp');
|
|
299
|
+
return effective(value, r?.by ?? 'default');
|
|
300
|
+
}
|
|
301
|
+
const locked = (value, source) => Object.freeze({ value, source });
|
|
302
|
+
export function lockOfShaped(L, s) {
|
|
303
|
+
const n = pluginManaged(L, s);
|
|
304
|
+
if (n !== undefined) {
|
|
305
|
+
const t = s.origin === 'plugin' ? effectiveOfShaped(L, s).value : n.value;
|
|
306
|
+
return locked(t, t !== n.value ? 'plugin' : n.source === 'policySettings' ? 'policy' : 'flag');
|
|
307
|
+
}
|
|
308
|
+
if (SETTINGS_IS_RESERVED_MEMBER_NAME(s.name))
|
|
309
|
+
return locked(s.disableModelInvocation ? 'user-invocable-only' : 'on', 'reserved-name');
|
|
310
|
+
if (s.disableModelInvocation)
|
|
311
|
+
return locked('user-invocable-only', 'skill-author');
|
|
312
|
+
if (s.origin === 'plugin')
|
|
313
|
+
return locked(effectiveOfShaped(L, s).value, 'plugin');
|
|
314
|
+
return undefined;
|
|
315
|
+
}
|
|
316
|
+
export function skillOverrideEffectiveOf(layers, skill) {
|
|
317
|
+
try {
|
|
318
|
+
const s = shapeSkillSubject(skill);
|
|
319
|
+
if (s === undefined)
|
|
320
|
+
return undefined;
|
|
321
|
+
return effectiveOfShaped(shapeSkillLayers(layers), s);
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
export function skillOverrideLockOf(layers, skill) {
|
|
328
|
+
try {
|
|
329
|
+
const s = shapeSkillSubject(skill);
|
|
330
|
+
if (s === undefined)
|
|
331
|
+
return locked('on', 'reserved-name');
|
|
332
|
+
return lockOfShaped(shapeSkillLayers(layers), s);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return locked('on', 'reserved-name');
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
export function ownValueIn(ov, s) {
|
|
339
|
+
return s.origin === 'mcp' ? strictestIn(ov, [s.name, ...secondaryNamesOf(s)], 'default')?.value : at(ov, s.name);
|
|
340
|
+
}
|
|
341
|
+
export function stateAt(ov, key) {
|
|
342
|
+
return at(ov, key);
|
|
343
|
+
}
|
|
344
|
+
export function lowerTierOf(L, s, target, skipTargetBare) {
|
|
345
|
+
const doc = (l) => ((l === 'localSettings' && target === 'localSettings') || L.enabled(l) ? L.docs[l] : undefined);
|
|
346
|
+
if (s.origin === 'mcp') {
|
|
347
|
+
if (target === 'userSettings')
|
|
348
|
+
return undefined;
|
|
349
|
+
const names = [s.name, ...secondaryNamesOf(s)];
|
|
350
|
+
for (const l of ['projectSettings', 'userSettings']) {
|
|
351
|
+
if (!L.enabled(l))
|
|
352
|
+
continue;
|
|
353
|
+
const m = strictestIn(L.docs[l], names, l);
|
|
354
|
+
if (m !== undefined)
|
|
355
|
+
return m.value;
|
|
356
|
+
}
|
|
357
|
+
return undefined;
|
|
358
|
+
}
|
|
359
|
+
const bare = bareNameOf(s);
|
|
360
|
+
const bareChain = () => {
|
|
361
|
+
if (bare === undefined)
|
|
362
|
+
return undefined;
|
|
363
|
+
for (const l of PLAIN) {
|
|
364
|
+
if (skipTargetBare && l === target)
|
|
365
|
+
continue;
|
|
366
|
+
const w = at(doc(l), bare);
|
|
367
|
+
if (w !== undefined)
|
|
368
|
+
return w;
|
|
369
|
+
}
|
|
370
|
+
return undefined;
|
|
371
|
+
};
|
|
372
|
+
if (target === 'userSettings')
|
|
373
|
+
return bareChain();
|
|
374
|
+
return at(doc('projectSettings'), s.name) ?? at(doc('userSettings'), s.name) ?? bareChain();
|
|
375
|
+
}
|
|
376
|
+
export function withLayerDoc(L, layer, doc) {
|
|
377
|
+
return Object.freeze({ ...L, docs: Object.freeze({ ...L.docs, [layer]: overridesOf(doc) }) });
|
|
378
|
+
}
|
package/dist/skillsWireCaps.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SkillSpec } from '@sema-agent/sdk';
|
|
2
2
|
import { type SkillToolListsReading } from './skillToolListsCapability.js';
|
|
3
|
+
import { type SkillOverrideLayers, type SkillOverrideSubject } from './skillOverrideChain.js';
|
|
3
4
|
export interface SkillCmdLike {
|
|
4
5
|
type?: string;
|
|
5
6
|
name?: string;
|
|
@@ -10,6 +11,7 @@ export interface SkillCmdLike {
|
|
|
10
11
|
skillRoot?: string;
|
|
11
12
|
allowedTools?: readonly string[];
|
|
12
13
|
disallowedTools?: readonly string[];
|
|
14
|
+
skillOverrideSubject?: SkillOverrideSubject;
|
|
13
15
|
}
|
|
14
16
|
export declare function toCappedSpec(name: string, description: string, whenToUse: string, body: string): SkillSpec | null;
|
|
15
17
|
export type SkillSpecOnWire = SkillSpec & {
|
|
@@ -19,6 +21,7 @@ export interface SkillSpecsOptions {
|
|
|
19
21
|
toolsRunHere?: boolean;
|
|
20
22
|
platform?: 'posix' | 'win32';
|
|
21
23
|
skillToolLists?: SkillToolListsReading;
|
|
24
|
+
skillOverrides?: SkillOverrideLayers;
|
|
22
25
|
}
|
|
23
26
|
export declare function skillBaseDirOf(skillRoot: string | undefined, platform?: 'posix' | 'win32'): string | undefined;
|
|
24
27
|
export type SkillToolListKey = 'allowedTools' | 'disallowedTools';
|
package/dist/skillsWireCaps.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { skillToolListsAvailable } from './skillToolListsCapability.js';
|
|
2
2
|
import { msg, renderMessage } from './i18n/translate.js';
|
|
3
3
|
import { appendOwnElement } from './ownKey.js';
|
|
4
|
+
import { skillOverrideEffectiveOf } from './skillOverrideChain.js';
|
|
4
5
|
export function toCappedSpec(name, description, whenToUse, body) {
|
|
5
6
|
const n = name.trim();
|
|
6
7
|
const c = body.trim();
|
|
@@ -11,6 +12,13 @@ export function toCappedSpec(name, description, whenToUse, body) {
|
|
|
11
12
|
.join(' — ');
|
|
12
13
|
return { name: n, description: desc, content: c };
|
|
13
14
|
}
|
|
15
|
+
const ORIGIN_OF_SOURCE = { plugin: 'plugin', builtin: 'builtin', bundled: 'bundled', mcp: 'mcp' };
|
|
16
|
+
function overrideSubjectOf(cmd, name) {
|
|
17
|
+
if (cmd.skillOverrideSubject !== undefined)
|
|
18
|
+
return cmd.skillOverrideSubject;
|
|
19
|
+
const src = typeof cmd.source === 'string' && Object.hasOwn(ORIGIN_OF_SOURCE, cmd.source) ? ORIGIN_OF_SOURCE[cmd.source] : undefined;
|
|
20
|
+
return { name, origin: src ?? 'skills' };
|
|
21
|
+
}
|
|
14
22
|
export function skillBaseDirOf(skillRoot, platform = 'posix') {
|
|
15
23
|
if (skillRoot === undefined || skillRoot.length === 0 || skillRoot.length > 4096)
|
|
16
24
|
return undefined;
|
|
@@ -120,10 +128,17 @@ export function skillCommandsToSpecs(cmds, resolveBody, opts) {
|
|
|
120
128
|
for (const cmd of cmds) {
|
|
121
129
|
if (cmd.type !== 'prompt' || cmd.disableModelInvocation)
|
|
122
130
|
continue;
|
|
131
|
+
let nameOnly = false;
|
|
132
|
+
if (opts?.skillOverrides !== undefined) {
|
|
133
|
+
const eff = skillOverrideEffectiveOf(opts.skillOverrides, overrideSubjectOf(cmd, (cmd.name ?? '').trim()));
|
|
134
|
+
if (eff === undefined || eff.value === 'off' || eff.value === 'user-invocable-only')
|
|
135
|
+
continue;
|
|
136
|
+
nameOnly = eff.value === 'name-only';
|
|
137
|
+
}
|
|
123
138
|
const body = resolveBody(cmd);
|
|
124
139
|
if (!body)
|
|
125
140
|
continue;
|
|
126
|
-
const spec = toCappedSpec(cmd.name ?? '', cmd.description ?? '', cmd.whenToUse ?? '', body);
|
|
141
|
+
const spec = toCappedSpec(cmd.name ?? '', nameOnly ? '' : (cmd.description ?? ''), nameOnly ? '' : (cmd.whenToUse ?? ''), body);
|
|
127
142
|
if (!spec || seen.has(spec.name))
|
|
128
143
|
continue;
|
|
129
144
|
seen.add(spec.name);
|
package/dist/sseIdleTriage.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { hostEnv } from './hostEnv.js';
|
|
2
2
|
import { SseIdleError, StreamEndedWithoutTerminalError, probeHealth as sdkProbeHealth } from '@sema-agent/sdk';
|
|
3
|
+
import { classifyHealthProbe } from './engineHealthProbeVerdict.js';
|
|
3
4
|
import { THROWN_SLOT_UNREADABLE, readThrownSlot, thrownIsInstanceOf } from './wireFailureShape.js';
|
|
4
5
|
import { SDK_STREAM_ENDED_REASONS } from './generated/sdkFactTables.js';
|
|
5
6
|
import { msg, renderMessage } from './i18n/translate.js';
|
|
@@ -62,7 +63,7 @@ export function isStreamEndedWithoutTerminalError(err) {
|
|
|
62
63
|
return reading.kind !== 'unknown' || reading.why !== 'not_this_class';
|
|
63
64
|
}
|
|
64
65
|
export async function probeEngineAlive(baseUrl) {
|
|
65
|
-
return (await sdkProbeHealth(baseUrl))
|
|
66
|
+
return classifyHealthProbe(await sdkProbeHealth(baseUrl))?.kind === 'answered_ok';
|
|
66
67
|
}
|
|
67
68
|
export async function* diagnoseSseIdleTear(inner, baseUrl, signal) {
|
|
68
69
|
try {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare const STORE_DURABILITY_WORDS: readonly ["durable", "ephemeral", "unknown"];
|
|
2
|
+
export type EngineHealthStoreDurability = (typeof STORE_DURABILITY_WORDS)[number];
|
|
3
|
+
export type StoreDurabilityRead = {
|
|
4
|
+
readonly kind: 'word';
|
|
5
|
+
readonly durability: EngineHealthStoreDurability;
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'unrecognized';
|
|
8
|
+
readonly word: string;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'absent';
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'unreadable';
|
|
13
|
+
};
|
|
14
|
+
export declare function readStoreDurability(section: object): StoreDurabilityRead;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ownDataField } from './ownKey.js';
|
|
2
|
+
const STORE_DURABILITY_WORDS = ['durable', 'ephemeral', 'unknown'];
|
|
3
|
+
export function readStoreDurability(section) {
|
|
4
|
+
try {
|
|
5
|
+
const raw = ownDataField(section, 'durability');
|
|
6
|
+
if (raw === undefined)
|
|
7
|
+
return Object.freeze({ kind: 'absent' });
|
|
8
|
+
if (typeof raw !== 'string' || raw === '')
|
|
9
|
+
return Object.freeze({ kind: 'unreadable' });
|
|
10
|
+
for (const w of STORE_DURABILITY_WORDS)
|
|
11
|
+
if (raw === w)
|
|
12
|
+
return Object.freeze({ kind: 'word', durability: w });
|
|
13
|
+
return Object.freeze({ kind: 'unrecognized', word: raw });
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return Object.freeze({ kind: 'unreadable' });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { type SqlEngineCapabilityView } from './sqlEngineCapability.js';
|
|
2
|
+
import { type EngineHealthStoreDurability } from './storeDurabilityWord.js';
|
|
3
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
2
4
|
export interface StorePostureView {
|
|
3
5
|
declared: string;
|
|
4
6
|
backend: string;
|
|
5
|
-
durable
|
|
7
|
+
durable?: boolean;
|
|
8
|
+
durability?: EngineHealthStoreDurability;
|
|
9
|
+
unrecognizedDurability?: string;
|
|
6
10
|
degradedReason?: string;
|
|
7
11
|
sql?: SqlEngineCapabilityView;
|
|
8
12
|
}
|
|
@@ -19,5 +23,5 @@ export type StorePostureReading = {
|
|
|
19
23
|
export declare function projectStorePostureCapability(caps: unknown): StorePostureReading | undefined;
|
|
20
24
|
export declare function observedStorePosture(baseUrl?: string | undefined): StorePostureReading;
|
|
21
25
|
export declare function storePersistence(reading: StorePostureReading): 'durable' | 'not_durable' | 'unknown';
|
|
22
|
-
export declare function storePostureHeadWord(reading: StorePostureReading): string | undefined;
|
|
23
|
-
export declare function storePostureDoctorDetail(reading: StorePostureReading): string;
|
|
26
|
+
export declare function storePostureHeadWord(reading: StorePostureReading, lang?: UiLanguage): string | undefined;
|
|
27
|
+
export declare function storePostureDoctorDetail(reading: StorePostureReading, lang?: UiLanguage): string;
|
|
@@ -3,6 +3,8 @@ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
|
|
|
3
3
|
import { storeSeatOf, createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
4
4
|
import { projectSqlEngineCapability } from './sqlEngineCapability.js';
|
|
5
5
|
import { ownDataField } from './ownKey.js';
|
|
6
|
+
import { readStoreDurability } from './storeDurabilityWord.js';
|
|
7
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
6
8
|
const nonEmpty = (v) => typeof v === 'string' && v !== '';
|
|
7
9
|
export function projectStorePostureCapability(caps) {
|
|
8
10
|
try {
|
|
@@ -21,8 +23,8 @@ function projectStorePostureOf(caps) {
|
|
|
21
23
|
const store = seat.store;
|
|
22
24
|
const declared = ownDataField(store, 'declared');
|
|
23
25
|
const backend = ownDataField(store, 'backend');
|
|
24
|
-
const
|
|
25
|
-
if (!nonEmpty(declared) || !nonEmpty(backend) ||
|
|
26
|
+
const durability = durabilityOf(store, 'wire');
|
|
27
|
+
if (!nonEmpty(declared) || !nonEmpty(backend) || durability.kind === 'malformed')
|
|
26
28
|
return undefined;
|
|
27
29
|
const reason = ownDataField(store, 'degradedReason');
|
|
28
30
|
if (reason !== undefined && !nonEmpty(reason))
|
|
@@ -35,12 +37,44 @@ function projectStorePostureOf(caps) {
|
|
|
35
37
|
view: {
|
|
36
38
|
declared,
|
|
37
39
|
backend,
|
|
38
|
-
durable,
|
|
40
|
+
...(durability.kind === 'legacy' ? { durable: durability.durable } : {}),
|
|
41
|
+
...(durability.kind === 'word' ? { durability: durability.durability } : {}),
|
|
42
|
+
...(durability.kind === 'unrecognized' ? { unrecognizedDurability: durability.word } : {}),
|
|
39
43
|
...(nonEmpty(reason) ? { degradedReason: reason } : {}),
|
|
40
44
|
...(sqlReading.kind === 'present' ? { sql: sqlReading.view } : {}),
|
|
41
45
|
},
|
|
42
46
|
};
|
|
43
47
|
}
|
|
48
|
+
const MALFORMED_DURABILITY = Object.freeze({ kind: 'malformed' });
|
|
49
|
+
function durabilityOf(section, side) {
|
|
50
|
+
try {
|
|
51
|
+
const word = readStoreDurability(section);
|
|
52
|
+
const durable = ownDataField(section, 'durable');
|
|
53
|
+
const unrecognized = side === 'view' ? ownDataField(section, 'unrecognizedDurability') : undefined;
|
|
54
|
+
const present = (word.kind === 'absent' ? 0 : 1) + (durable === undefined ? 0 : 1) + (unrecognized === undefined ? 0 : 1);
|
|
55
|
+
if (present !== 1)
|
|
56
|
+
return MALFORMED_DURABILITY;
|
|
57
|
+
if (word.kind === 'word')
|
|
58
|
+
return { kind: 'word', durability: word.durability };
|
|
59
|
+
if (word.kind === 'unrecognized')
|
|
60
|
+
return { kind: 'unrecognized', word: word.word };
|
|
61
|
+
if (typeof durable === 'boolean')
|
|
62
|
+
return { kind: 'legacy', durable };
|
|
63
|
+
if (nonEmpty(unrecognized))
|
|
64
|
+
return { kind: 'unrecognized', word: unrecognized };
|
|
65
|
+
return MALFORMED_DURABILITY;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return MALFORMED_DURABILITY;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function persistenceOf(d) {
|
|
72
|
+
if (d.kind === 'legacy')
|
|
73
|
+
return d.durable ? 'durable' : 'not_durable';
|
|
74
|
+
if (d.kind !== 'word')
|
|
75
|
+
return 'unknown';
|
|
76
|
+
return d.durability === 'durable' ? 'durable' : d.durability === 'ephemeral' ? 'not_durable' : 'unknown';
|
|
77
|
+
}
|
|
44
78
|
const reader = createEngineCapReader({
|
|
45
79
|
name: 'store',
|
|
46
80
|
project: projectStorePostureCapability,
|
|
@@ -70,58 +104,54 @@ export function storePersistence(reading) {
|
|
|
70
104
|
const r = presentView(reading);
|
|
71
105
|
if (r?.kind !== 'present')
|
|
72
106
|
return 'unknown';
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
durable = r.view.durable;
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
return 'unknown';
|
|
79
|
-
}
|
|
80
|
-
return durable === true ? 'durable' : durable === false ? 'not_durable' : 'unknown';
|
|
107
|
+
return persistenceOf(durabilityOf(r.view, 'view'));
|
|
81
108
|
}
|
|
82
|
-
const
|
|
83
|
-
export function storePostureHeadWord(reading) {
|
|
84
|
-
return storePersistence(reading) === 'not_durable' ?
|
|
109
|
+
const notDurableHead = () => msg('notice.capability.storePosture.notDurableHead');
|
|
110
|
+
export function storePostureHeadWord(reading, lang) {
|
|
111
|
+
return storePersistence(reading) === 'not_durable' ? renderMessage(notDurableHead(), lang) : undefined;
|
|
85
112
|
}
|
|
86
113
|
const WORD_DETAIL_MAX = 40;
|
|
87
114
|
const word = (v) => capForDisplay(v, WORD_DETAIL_MAX);
|
|
88
|
-
export function storePostureDoctorDetail(reading) {
|
|
89
|
-
const
|
|
115
|
+
export function storePostureDoctorDetail(reading, lang) {
|
|
116
|
+
const say = (ref) => renderMessage(ref, lang);
|
|
117
|
+
const unobserved = msg('notice.capability.storePosture.unobserved');
|
|
90
118
|
const r = presentView(reading);
|
|
91
119
|
if (r?.kind === 'unreadable')
|
|
92
|
-
return unreadableReadingDetail('
|
|
93
|
-
if (r?.kind === 'not_reported')
|
|
94
|
-
return
|
|
95
|
-
}
|
|
120
|
+
return unreadableReadingDetail(say(msg('notice.capability.subject.storePosture')), lang);
|
|
121
|
+
if (r?.kind === 'not_reported')
|
|
122
|
+
return say(msg('notice.capability.storePosture.notReported'));
|
|
96
123
|
if (r?.kind !== 'present')
|
|
97
|
-
return unobserved;
|
|
124
|
+
return say(unobserved);
|
|
98
125
|
let declared;
|
|
99
126
|
let backend;
|
|
100
|
-
let durable;
|
|
101
127
|
let reason;
|
|
102
128
|
try {
|
|
103
129
|
declared = r.view.declared;
|
|
104
130
|
backend = r.view.backend;
|
|
105
|
-
durable = r.view.durable;
|
|
106
131
|
reason = r.view.degradedReason;
|
|
107
132
|
}
|
|
108
133
|
catch {
|
|
109
|
-
return unobserved;
|
|
110
|
-
}
|
|
111
|
-
if (!nonEmpty(declared) || !nonEmpty(backend) || typeof durable !== 'boolean')
|
|
112
|
-
return unobserved;
|
|
113
|
-
const assembled = declared === backend ? `store ${word(backend)}` : `store declared ${word(declared)}, running on ${word(backend)}`;
|
|
114
|
-
if (durable) {
|
|
115
|
-
return `${assembled} — durable: this replica persists its state, so it survives a restart`;
|
|
134
|
+
return say(unobserved);
|
|
116
135
|
}
|
|
117
|
-
const
|
|
136
|
+
const durability = durabilityOf(r.view, 'view');
|
|
137
|
+
if (!nonEmpty(declared) || !nonEmpty(backend) || durability.kind === 'malformed')
|
|
138
|
+
return say(unobserved);
|
|
139
|
+
const assembled = declared === backend
|
|
140
|
+
? msg('notice.capability.storePosture.assembled', { backend: word(backend) })
|
|
141
|
+
: msg('notice.capability.storePosture.assembledDeclared', { declared: word(declared), backend: word(backend) });
|
|
142
|
+
if (durability.kind === 'unrecognized')
|
|
143
|
+
return say(msg('notice.capability.storePosture.unrecognized', { assembled, word: word(durability.word) }));
|
|
144
|
+
const persistence = persistenceOf(durability);
|
|
145
|
+
if (persistence === 'durable')
|
|
146
|
+
return say(msg('notice.capability.storePosture.durable', { assembled }));
|
|
147
|
+
if (persistence === 'unknown')
|
|
148
|
+
return say(msg('notice.capability.storePosture.unknown', { assembled }));
|
|
149
|
+
const line = msg(durability.kind === 'legacy' ? 'notice.capability.storePosture.memory' : 'notice.capability.storePosture.ephemeral', { assembled, head: notDurableHead() });
|
|
118
150
|
if (!nonEmpty(reason))
|
|
119
|
-
return
|
|
120
|
-
if (reason === 'db_unreachable')
|
|
121
|
-
return
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
return `${assembled} — ${lost} (degraded for a reason this client does not know yet: "${word(reason)}")`;
|
|
151
|
+
return say(line);
|
|
152
|
+
if (reason === 'db_unreachable')
|
|
153
|
+
return say(msg('notice.capability.storePosture.degraded.dbUnreachable', { line }));
|
|
154
|
+
if (reason === 'local_unwritable')
|
|
155
|
+
return say(msg('notice.capability.storePosture.degraded.localUnwritable', { line }));
|
|
156
|
+
return say(msg('notice.capability.storePosture.degraded.other', { line, reason: word(reason) }));
|
|
127
157
|
}
|