@sema-agent/client-core 0.98.0 → 0.100.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 +376 -0
- package/README.md +61 -35
- package/dist/adapt/arms.js +120 -55
- package/dist/adapt/panelTasks.d.ts +3 -2
- package/dist/adapt/panelTasks.js +34 -11
- package/dist/adapt/textStream.d.ts +1 -1
- package/dist/adapt/textStream.js +51 -28
- package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
- package/dist/adapter/activeRunSelfHeal.js +210 -294
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
- package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
- package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
- package/dist/adapter/downstream/wiringManifestView.js +1 -0
- package/dist/adapter/runStream.js +82 -40
- package/dist/adapter/types.d.ts +2 -0
- package/dist/adapter/types.js +2 -1
- package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
- package/dist/agentsWireCaps.d.ts +7 -3
- package/dist/agentsWireCaps.js +133 -39
- package/dist/cloudConfigWireCaps.d.ts +10 -1
- package/dist/cloudConfigWireCaps.js +181 -65
- package/dist/compactionStatus.d.ts +34 -0
- package/dist/compactionStatus.js +196 -0
- package/dist/controlRouter.d.ts +4 -2
- package/dist/controlRouter.js +39 -51
- package/dist/coreValuePorts.d.ts +26 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/corruptSessionCopy.d.ts +2 -1
- package/dist/corruptSessionCopy.js +3 -3
- package/dist/decideFailureNote.js +3 -3
- package/dist/declared/supportFloorDeclared.js +1 -1
- package/dist/detachWire.js +3 -2
- package/dist/devicesFace.d.ts +34 -0
- package/dist/devicesFace.js +90 -0
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +153 -5
- package/dist/engineAgentPanelStore.d.ts +14 -4
- package/dist/engineAgentPanelStore.js +14 -0
- package/dist/engineCapReader.d.ts +2 -1
- package/dist/engineCapReader.js +7 -5
- package/dist/engineCapsCache.d.ts +8 -0
- package/dist/engineCapsCache.js +59 -6
- package/dist/engineCapsChange.d.ts +2 -0
- package/dist/engineCapsChange.js +9 -0
- package/dist/engineErrorCodes.d.ts +11 -2
- package/dist/engineErrorCodes.js +11 -12
- package/dist/engineRowRef.js +4 -0
- package/dist/engineSessionMessages.d.ts +1 -0
- package/dist/engineSessionMessages.js +7 -1
- package/dist/engineTargetSeat.d.ts +27 -0
- package/dist/engineTargetSeat.js +199 -0
- package/dist/engineToolDirectory.d.ts +3 -0
- package/dist/engineToolDirectory.js +4 -2
- package/dist/engineWireFor.js +3 -8
- package/dist/env/uiLanguage.d.ts +2 -1
- package/dist/env/uiLanguage.js +3 -2
- package/dist/eventLeg.d.ts +7 -5
- package/dist/eventLeg.js +68 -49
- package/dist/fileHistoryCaptureCapability.d.ts +2 -4
- package/dist/fileHistoryCaptureCapability.js +12 -22
- package/dist/fileHistoryLegNotice.d.ts +2 -1
- package/dist/fileHistoryLegNotice.js +3 -3
- package/dist/frameBinding.d.ts +3 -0
- package/dist/frameBinding.js +12 -0
- package/dist/gateOutcome.js +16 -2
- package/dist/gateVocabulary.d.ts +8 -7
- package/dist/gateVocabulary.js +71 -73
- package/dist/generated/engineFactTables.d.ts +18 -1
- package/dist/generated/engineFactTables.js +56 -0
- package/dist/generated/engineNoticeTables.js +12 -3
- package/dist/generated/settingsSchemaFns.d.ts +18 -0
- package/dist/generated/settingsSchemaFns.js +70 -0
- package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +9 -0
- package/dist/generated/settingsSchemaTypes.d.ts +133 -0
- package/dist/generated/settingsSchemaTypes.js +1 -0
- package/dist/hitl/allowRuleShadow.d.ts +2 -1
- package/dist/hitl/allowRuleShadow.js +18 -15
- package/dist/hitl/approvalCardReasons.d.ts +3 -2
- package/dist/hitl/approvalCardReasons.js +29 -30
- package/dist/hitl/approvalHolds.d.ts +17 -0
- package/dist/hitl/approvalHolds.js +114 -29
- package/dist/hitl/askClassPair.d.ts +2 -2
- package/dist/hitl/askClassPair.js +16 -0
- package/dist/hitl/askGateWire.js +2 -1
- package/dist/hitl/askSettlementLine.d.ts +14 -4
- package/dist/hitl/askSettlementLine.js +67 -47
- package/dist/hitl/attributionLadder.d.ts +23 -0
- package/dist/hitl/attributionLadder.js +67 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
- package/dist/hitl/automaticAnswerVerdict.js +8 -8
- package/dist/hitl/crashConvergedNotice.d.ts +5 -4
- package/dist/hitl/crashConvergedNotice.js +28 -41
- package/dist/hitl/decisionLedger.d.ts +55 -0
- package/dist/hitl/decisionLedger.js +156 -0
- package/dist/hitl/decisionRefusal.d.ts +1 -0
- package/dist/hitl/decisionRefusal.js +1 -1
- package/dist/hitl/decisionSend.d.ts +113 -0
- package/dist/hitl/decisionSend.js +579 -0
- package/dist/hitl/frameRouter.js +7 -8
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +21 -9
- package/dist/hitl/persistedRulesWire.d.ts +6 -5
- package/dist/hitl/persistedRulesWire.js +55 -73
- package/dist/hitl/planReviewWire.d.ts +5 -0
- package/dist/hitl/planReviewWire.js +53 -76
- package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
- package/dist/hitl/sessionPolicyDeliverable.js +49 -9
- package/dist/hitl/sessionPolicyWire.d.ts +2 -1
- package/dist/hitl/sessionPolicyWire.js +23 -24
- package/dist/hitl/suspendedReopen.d.ts +2 -1
- package/dist/hitl/suspendedReopen.js +7 -10
- package/dist/hitl/toolApprovalWire.d.ts +17 -5
- package/dist/hitl/toolApprovalWire.js +120 -147
- package/dist/hooksWireCaps.js +145 -56
- package/dist/host.d.ts +21 -0
- package/dist/hostTurnSettings.d.ts +110 -0
- package/dist/hostTurnSettings.js +692 -0
- package/dist/humanTurn.d.ts +15 -1
- package/dist/humanTurn.js +100 -12
- package/dist/humanTurnRead.d.ts +2 -0
- package/dist/humanTurnRead.js +22 -1
- package/dist/i18n/messages.en.d.ts +713 -0
- package/dist/i18n/messages.en.js +713 -0
- package/dist/i18n/messages.zh.js +854 -1
- package/dist/index.d.ts +45 -13
- package/dist/index.js +27 -9
- package/dist/inheritEnvCapability.d.ts +4 -2
- package/dist/inheritEnvCapability.js +12 -5
- package/dist/inheritEnvWire.d.ts +3 -2
- package/dist/inheritEnvWire.js +14 -16
- package/dist/injectionLaneNotice.d.ts +5 -0
- package/dist/injectionLaneNotice.js +46 -0
- package/dist/interactiveHalt.js +17 -6
- package/dist/liveModelCatalog.d.ts +2 -1
- package/dist/liveModelCatalog.js +14 -8
- package/dist/mcpPanel.d.ts +10 -1
- package/dist/mcpPanel.js +42 -13
- package/dist/mcpProbeCapability.d.ts +2 -1
- package/dist/mcpProbeCapability.js +7 -11
- package/dist/mcpProbeWire.d.ts +3 -1
- package/dist/mcpProbeWire.js +5 -0
- package/dist/mcpReconnect.js +2 -2
- package/dist/mcpToolToggles.d.ts +6 -0
- package/dist/mcpToolToggles.js +46 -0
- package/dist/mcpWireCaps.d.ts +43 -3
- package/dist/mcpWireCaps.js +194 -59
- package/dist/mcpWireTransport.d.ts +4 -0
- package/dist/mcpWireTransport.js +18 -0
- package/dist/memoryEntriesWire.js +5 -10
- package/dist/model/onboardJudgement.d.ts +93 -0
- package/dist/model/onboardJudgement.js +415 -0
- package/dist/model/tierVocabulary.d.ts +2 -0
- package/dist/model/tierVocabulary.js +17 -5
- package/dist/modelCapabilityProbe.d.ts +65 -0
- package/dist/modelCapabilityProbe.js +601 -0
- package/dist/modelIdentityResolvability.d.ts +5 -0
- package/dist/modelIdentityResolvability.js +49 -22
- package/dist/ownKey.d.ts +33 -0
- package/dist/ownKey.js +109 -0
- package/dist/panelReduce.d.ts +11 -1
- package/dist/panelReduce.js +95 -16
- package/dist/panelStateHolder.d.ts +1 -0
- package/dist/panelStateHolder.js +10 -1
- package/dist/permissionRuleIssue.d.ts +2 -1
- package/dist/permissionRuleIssue.js +23 -20
- package/dist/permissionRulesWriteCapability.d.ts +2 -1
- package/dist/permissionRulesWriteCapability.js +8 -6
- package/dist/pluginHooksWire.d.ts +46 -3
- package/dist/pluginHooksWire.js +220 -12
- package/dist/prepareRefusal.d.ts +8 -0
- package/dist/prepareRefusal.js +72 -0
- package/dist/printModelStatus.d.ts +63 -0
- package/dist/printModelStatus.js +155 -0
- package/dist/request/taskRequest.d.ts +16 -10
- package/dist/request/taskRequest.js +195 -58
- package/dist/resumeRefusalCopy.d.ts +14 -9
- package/dist/resumeRefusalCopy.js +89 -144
- package/dist/retryStatus.d.ts +55 -0
- package/dist/retryStatus.js +155 -19
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +58 -0
- package/dist/sandboxWire.d.ts +2 -1
- package/dist/sandboxWire.js +55 -21
- package/dist/scenarioRefusal.d.ts +10 -0
- package/dist/scenarioRefusal.js +111 -0
- package/dist/seam.d.ts +48 -9
- package/dist/seam.js +54 -5
- package/dist/seatContract.d.ts +272 -14
- package/dist/seatContract.js +711 -23
- package/dist/selfOrchestrationDenial.js +7 -19
- package/dist/sessionIdSegment.d.ts +6 -0
- package/dist/sessionIdSegment.js +24 -0
- package/dist/sessionMemoryStatus.js +6 -11
- package/dist/sessionPolicyCapability.d.ts +2 -1
- package/dist/sessionPolicyCapability.js +8 -6
- package/dist/settingsCredentialKeyPaths.d.ts +8 -0
- package/dist/settingsCredentialKeyPaths.js +219 -0
- package/dist/settingsHooksSalvage.d.ts +44 -0
- package/dist/settingsHooksSalvage.js +211 -0
- package/dist/skillToolListsCapability.d.ts +2 -1
- package/dist/skillToolListsCapability.js +8 -6
- package/dist/skillsWireCaps.d.ts +0 -3
- package/dist/skillsWireCaps.js +1 -2
- package/dist/sseIdleTriage.js +3 -2
- package/dist/subagent/engineSubagentResume.js +15 -9
- package/dist/subagentContentStore.d.ts +4 -0
- package/dist/subagentContentStore.js +157 -27
- package/dist/toolHistoryMismatch.js +3 -2
- package/dist/toolRoster.d.ts +3 -2
- package/dist/toolRoster.js +21 -20
- package/dist/toolsFlagNames.d.ts +8 -0
- package/dist/toolsFlagNames.js +110 -0
- package/dist/turnFailurePresentation.d.ts +12 -1
- package/dist/turnFailurePresentation.js +220 -15
- package/dist/usageAnalytics.js +6 -11
- package/dist/userAttachmentEnvelope.d.ts +1 -0
- package/dist/userAttachmentEnvelope.js +37 -7
- package/dist/userAttachmentSeat.d.ts +21 -0
- package/dist/userAttachmentSeat.js +75 -0
- package/dist/userInvokedSkillsCapability.d.ts +11 -1
- package/dist/userInvokedSkillsCapability.js +31 -7
- package/dist/wireErrorTriage.d.ts +7 -0
- package/dist/wireErrorTriage.js +23 -1
- package/dist/wireFailureShape.js +2 -1
- package/dist/wireRefusalCopy.d.ts +62 -16
- package/dist/wireRefusalCopy.js +307 -148
- package/dist/workflowsJournalCapability.d.ts +2 -1
- package/dist/workflowsJournalCapability.js +8 -6
- package/docs/INTEGRATION-CLIENTS.md +951 -42
- package/package.json +5 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
2
|
import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
|
|
3
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
3
4
|
import { ownDataField } from './ownKey.js';
|
|
4
5
|
export function projectSkillToolListsCapability(caps) {
|
|
5
6
|
try {
|
|
@@ -30,17 +31,18 @@ export function skillToolListsAvailable(reading) {
|
|
|
30
31
|
return 'no';
|
|
31
32
|
return 'unknown';
|
|
32
33
|
}
|
|
33
|
-
export function skillToolListsDoctorDetail(reading) {
|
|
34
|
+
export function skillToolListsDoctorDetail(reading, lang) {
|
|
35
|
+
const subject = msg('notice.capability.subject.skillToolLists');
|
|
34
36
|
switch (reading.kind) {
|
|
35
37
|
case 'unreadable':
|
|
36
|
-
return unreadableReadingDetail(
|
|
38
|
+
return unreadableReadingDetail(renderMessage(subject, lang), lang);
|
|
37
39
|
case 'unobserved':
|
|
38
|
-
return
|
|
40
|
+
return renderMessage(msg('notice.capability.unobserved', { subject, key: 'skillToolLists' }), lang);
|
|
39
41
|
case 'not_reported':
|
|
40
|
-
return '
|
|
42
|
+
return renderMessage(msg('notice.capability.skillToolLists.notReported'), lang);
|
|
41
43
|
case 'absent':
|
|
42
|
-
return '
|
|
44
|
+
return renderMessage(msg('notice.capability.skillToolLists.absent'), lang);
|
|
43
45
|
case 'present':
|
|
44
|
-
return '
|
|
46
|
+
return renderMessage(msg('notice.capability.skillToolLists.present'), lang);
|
|
45
47
|
}
|
|
46
48
|
}
|
package/dist/skillsWireCaps.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import type { SkillSpec } from '@sema-agent/sdk';
|
|
2
2
|
import { type SkillToolListsReading } from './skillToolListsCapability.js';
|
|
3
|
-
export declare const SKILL_CAPS: {
|
|
4
|
-
readonly content: 1048576;
|
|
5
|
-
};
|
|
6
3
|
export interface SkillCmdLike {
|
|
7
4
|
type?: string;
|
|
8
5
|
name?: string;
|
package/dist/skillsWireCaps.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { skillToolListsAvailable } from './skillToolListsCapability.js';
|
|
2
|
-
export const SKILL_CAPS = { content: 1_048_576 };
|
|
3
2
|
export function toCappedSpec(name, description, whenToUse, body) {
|
|
4
3
|
const n = name.trim();
|
|
5
|
-
const c = body.trim()
|
|
4
|
+
const c = body.trim();
|
|
6
5
|
if (!n || !c)
|
|
7
6
|
return null;
|
|
8
7
|
const desc = [description.trim(), whenToUse.trim()]
|
package/dist/sseIdleTriage.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { hostEnv } from './hostEnv.js';
|
|
2
2
|
import { SseIdleError, probeHealth as sdkProbeHealth } from '@sema-agent/sdk';
|
|
3
|
+
import { readThrownSlot, thrownIsInstanceOf } from './wireFailureShape.js';
|
|
3
4
|
export const SSE_HEARTBEAT_GRACE_ENV = 'SEMA_SSE_HEARTBEAT_GRACE_MS';
|
|
4
5
|
export const SSE_GRACE_MIN_MS = 5_000;
|
|
5
6
|
export const SSE_GRACE_MAX_MS = 600_000;
|
|
@@ -27,9 +28,9 @@ export function engineAliveIdleElapsedMs(err) {
|
|
|
27
28
|
return typeof e.elapsedMs === 'number' && Number.isFinite(e.elapsedMs) ? e.elapsedMs : 0;
|
|
28
29
|
}
|
|
29
30
|
export function isSseIdleError(err) {
|
|
30
|
-
if (err
|
|
31
|
+
if (thrownIsInstanceOf(err, SseIdleError))
|
|
31
32
|
return true;
|
|
32
|
-
return err
|
|
33
|
+
return readThrownSlot(err, 'name', 'data') === 'SseIdleError';
|
|
33
34
|
}
|
|
34
35
|
export async function probeEngineAlive(baseUrl, timeoutMs = 2_000) {
|
|
35
36
|
return (await sdkProbeHealth(baseUrl, timeoutMs)).alive;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { hostLog } from '../host.js';
|
|
2
|
-
import { resumeRetryLaterFromError } from '../wireErrorTriage.js';
|
|
2
|
+
import { isNotFoundFailure, resumeRetryLaterFromError } from '../wireErrorTriage.js';
|
|
3
|
+
import { readThrownSlot, THROWN_SLOT_UNREADABLE } from '../wireFailureShape.js';
|
|
3
4
|
import { RESUME_SESSION_NOT_FOUND } from '../engineErrorCodes.js';
|
|
4
5
|
import { displayUntrusted } from '../displayUntrusted.js';
|
|
5
6
|
import { engineCapTrue } from '../engineCapsCache.js';
|
|
@@ -25,15 +26,22 @@ const RETENTION_LAPSED_CODES = new Set([
|
|
|
25
26
|
RESUME_SESSION_NOT_FOUND,
|
|
26
27
|
]);
|
|
27
28
|
function shapeOf(e) {
|
|
28
|
-
const
|
|
29
|
+
const status = readThrownSlot(e ?? {}, 'status', 'data');
|
|
30
|
+
const errorCode = readThrownSlot(e ?? {}, 'errorCode', 'data');
|
|
31
|
+
const message = readThrownSlot(e ?? {}, 'message');
|
|
32
|
+
if (status === THROWN_SLOT_UNREADABLE || errorCode === THROWN_SLOT_UNREADABLE) {
|
|
33
|
+
return { message: typeof message === 'string' && message !== '' ? message : String(e), unreadable: true };
|
|
34
|
+
}
|
|
29
35
|
return {
|
|
30
|
-
...(typeof
|
|
31
|
-
...(typeof
|
|
32
|
-
message: typeof
|
|
36
|
+
...(typeof status === 'number' ? { status } : {}),
|
|
37
|
+
...(typeof errorCode === 'string' ? { errorCode } : {}),
|
|
38
|
+
message: typeof message === 'string' && message !== '' ? message : String(e),
|
|
33
39
|
};
|
|
34
40
|
}
|
|
35
41
|
export function classifySubagentResumeFailure(e) {
|
|
36
|
-
const { status, errorCode, message } = shapeOf(e);
|
|
42
|
+
const { status, errorCode, message, unreadable } = shapeOf(e);
|
|
43
|
+
if (unreadable === true)
|
|
44
|
+
return { reason: 'error', detail: message };
|
|
37
45
|
if (status === undefined && errorCode === undefined) {
|
|
38
46
|
const noAnswer = typeof e === 'object' ? noAnswerDetailFrom(e) : null;
|
|
39
47
|
if (noAnswer !== null)
|
|
@@ -63,12 +71,10 @@ export function classifySubagentResumeFailure(e) {
|
|
|
63
71
|
return { reason: 'row-contended', detail: message };
|
|
64
72
|
if (errorCode === 'resume.row_gone')
|
|
65
73
|
return { reason: 'row-gone', detail: message };
|
|
66
|
-
if (
|
|
74
|
+
if (isNotFoundFailure(e) !== false)
|
|
67
75
|
return { reason: 'not-found', detail: message };
|
|
68
76
|
if (errorCode === undefined && status === 400)
|
|
69
77
|
return { reason: 'bad-request', detail: message };
|
|
70
|
-
if (errorCode?.startsWith('not_found.') === true)
|
|
71
|
-
return { reason: 'not-found', detail: message };
|
|
72
78
|
return { reason: 'error', detail: message };
|
|
73
79
|
}
|
|
74
80
|
export function resolveOwnerRunId(childTaskId, activeRunId) {
|
|
@@ -33,6 +33,9 @@ export interface SubagentContentEvent {
|
|
|
33
33
|
isError?: boolean | undefined;
|
|
34
34
|
}
|
|
35
35
|
export declare function coerceOutput(v: unknown): string | undefined;
|
|
36
|
+
export declare function subagentContentEventOf(ev: {
|
|
37
|
+
readonly type: string;
|
|
38
|
+
}): SubagentContentEvent | undefined;
|
|
36
39
|
export interface SubagentContentStoreConfig {
|
|
37
40
|
maxBytesPerTask: number;
|
|
38
41
|
maxBytesTotal: number;
|
|
@@ -41,6 +44,7 @@ export declare const SUBAGENT_CONTENT_STORE_DEFAULTS: Readonly<SubagentContentSt
|
|
|
41
44
|
export declare function configureSubagentContentStore(next: Partial<SubagentContentStoreConfig>): void;
|
|
42
45
|
export declare function subagentContentStoreConfig(): SubagentContentStoreConfig;
|
|
43
46
|
export declare function __resetSubagentContentStoreConfigForTests(): void;
|
|
47
|
+
export declare function bindSubagentIdentityReader(fn: (id: string) => readonly string[] | undefined): void;
|
|
44
48
|
export declare function registerSubagentContentAlias(parentToolCallId: string, taskId: string): void;
|
|
45
49
|
export declare function registerSubagentAlias(parentToolCallId: string, taskId: string): void;
|
|
46
50
|
export declare function publishSubagentContentEvent(ev: SubagentContentEvent): void;
|
|
@@ -3,6 +3,28 @@ import { toolEndOutputText } from './toolResultContent.js';
|
|
|
3
3
|
export function coerceOutput(v) {
|
|
4
4
|
return toolEndOutputText(v);
|
|
5
5
|
}
|
|
6
|
+
export function subagentContentEventOf(ev) {
|
|
7
|
+
const t = ev.type;
|
|
8
|
+
if (t !== 'text_delta' && t !== 'reasoning_delta' && t !== 'text' && t !== 'reasoning' && t !== 'tool_start' && t !== 'tool_end')
|
|
9
|
+
return undefined;
|
|
10
|
+
const sub = ev;
|
|
11
|
+
const parent = sub.parentToolCallId;
|
|
12
|
+
if (typeof parent !== 'string')
|
|
13
|
+
return undefined;
|
|
14
|
+
return {
|
|
15
|
+
type: sub.type,
|
|
16
|
+
taskId: sub.taskId ?? parent,
|
|
17
|
+
parentToolCallId: parent,
|
|
18
|
+
delta: sub.delta,
|
|
19
|
+
text: sub.text,
|
|
20
|
+
eventId: sub.eventId,
|
|
21
|
+
toolCallId: sub.toolCallId,
|
|
22
|
+
toolName: sub.toolName,
|
|
23
|
+
args: sub.args,
|
|
24
|
+
output: coerceOutput(sub.output),
|
|
25
|
+
isError: sub.isError,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
6
28
|
const MAX_ITEMS_PER_TASK = 200;
|
|
7
29
|
const MAX_TASKS = 32;
|
|
8
30
|
const NOTIFY_COALESCE_MS = 250;
|
|
@@ -207,8 +229,40 @@ function dropTask(key) {
|
|
|
207
229
|
totalBytes -= s.bytes;
|
|
208
230
|
tasks.delete(key);
|
|
209
231
|
}
|
|
232
|
+
let subagentIdsReader;
|
|
233
|
+
export function bindSubagentIdentityReader(fn) {
|
|
234
|
+
subagentIdsReader = fn;
|
|
235
|
+
}
|
|
236
|
+
function sameSubagentIds(id) {
|
|
237
|
+
let ids;
|
|
238
|
+
try {
|
|
239
|
+
ids = subagentIdsReader?.(id);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
ids = undefined;
|
|
243
|
+
}
|
|
244
|
+
if (ids === undefined)
|
|
245
|
+
return [id];
|
|
246
|
+
return ids.includes(id) ? ids : [...ids, id];
|
|
247
|
+
}
|
|
248
|
+
function homeKeyOf(key) {
|
|
249
|
+
return sameSubagentIds(key).find((id) => tasks.has(id)) ?? key;
|
|
250
|
+
}
|
|
251
|
+
function contentKeyOf(taskId) {
|
|
252
|
+
const ids = sameSubagentIds(taskId);
|
|
253
|
+
const direct = ids.find((id) => tasks.has(id));
|
|
254
|
+
if (direct !== undefined)
|
|
255
|
+
return direct;
|
|
256
|
+
for (const id of ids) {
|
|
257
|
+
const parked = taskToParent.get(id)?.card;
|
|
258
|
+
if (parked !== undefined && tasks.has(parked))
|
|
259
|
+
return parked;
|
|
260
|
+
}
|
|
261
|
+
return '';
|
|
262
|
+
}
|
|
210
263
|
const parentToTask = new Map();
|
|
211
264
|
const taskToParent = new Map();
|
|
265
|
+
let parentStampSeq = 0;
|
|
212
266
|
let notifyListener = null;
|
|
213
267
|
const pendingNotify = new Set();
|
|
214
268
|
let notifyTimer = null;
|
|
@@ -361,7 +415,8 @@ function aliasContentKey(parentToolCallId, taskId) {
|
|
|
361
415
|
export function registerSubagentAlias(parentToolCallId, taskId) {
|
|
362
416
|
if (!aliasContentKey(parentToolCallId, taskId))
|
|
363
417
|
return;
|
|
364
|
-
taskToParent.
|
|
418
|
+
if (taskToParent.get(taskId)?.card !== parentToolCallId)
|
|
419
|
+
taskToParent.set(taskId, { card: parentToolCallId, stamp: ++parentStampSeq });
|
|
365
420
|
}
|
|
366
421
|
function replaySeen(s, ev) {
|
|
367
422
|
const id = ev.eventId;
|
|
@@ -437,7 +492,7 @@ function canonicalKey(ev) {
|
|
|
437
492
|
return parentToTask.get(ev.parentToolCallId) ?? ev.parentToolCallId;
|
|
438
493
|
}
|
|
439
494
|
export function publishSubagentContentEvent(ev) {
|
|
440
|
-
const key = canonicalKey(ev);
|
|
495
|
+
const key = homeKeyOf(canonicalKey(ev));
|
|
441
496
|
const s = stateFor(key, ev.parentToolCallId);
|
|
442
497
|
switch (ev.type) {
|
|
443
498
|
case 'text_delta':
|
|
@@ -539,15 +594,17 @@ export function publishSubagentContentEvent(ev) {
|
|
|
539
594
|
scheduleNotify(key);
|
|
540
595
|
}
|
|
541
596
|
export function pushSubagentLocalEcho(taskId, text) {
|
|
542
|
-
const
|
|
597
|
+
const known = contentKeyOf(taskId);
|
|
598
|
+
const key = known !== '' ? known : taskId;
|
|
599
|
+
const s = stateFor(key, tasks.get(key)?.parentToolCallId ?? '');
|
|
543
600
|
flushBuffers(s);
|
|
544
601
|
pushItem(s, { kind: 'echo', text });
|
|
545
602
|
enforceTaskCap(s);
|
|
546
|
-
enforceTotalCap(
|
|
547
|
-
scheduleNotify(
|
|
603
|
+
enforceTotalCap(key);
|
|
604
|
+
scheduleNotify(key);
|
|
548
605
|
}
|
|
549
606
|
export function getSubagentContentSnapshot(taskId) {
|
|
550
|
-
const key =
|
|
607
|
+
const key = contentKeyOf(taskId);
|
|
551
608
|
const s = tasks.get(key);
|
|
552
609
|
if (!s)
|
|
553
610
|
return null;
|
|
@@ -593,17 +650,42 @@ export function planSubagentViewSlots(taskId) {
|
|
|
593
650
|
return out;
|
|
594
651
|
}
|
|
595
652
|
export function parentToolCallIdOf(taskId) {
|
|
596
|
-
|
|
653
|
+
const ids = sameSubagentIds(taskId);
|
|
654
|
+
let stated;
|
|
655
|
+
let statedStamp = -1;
|
|
656
|
+
for (const id of ids) {
|
|
657
|
+
const hit = taskToParent.get(id);
|
|
658
|
+
if (hit === undefined)
|
|
659
|
+
continue;
|
|
660
|
+
if (stated === undefined || hit.stamp > statedStamp) {
|
|
661
|
+
stated = hit.card;
|
|
662
|
+
statedStamp = hit.stamp;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (stated !== undefined)
|
|
666
|
+
return stated;
|
|
667
|
+
for (const id of ids) {
|
|
668
|
+
const fromContent = tasks.get(id)?.parentToolCallId;
|
|
669
|
+
if (fromContent !== undefined)
|
|
670
|
+
return fromContent;
|
|
671
|
+
}
|
|
672
|
+
return undefined;
|
|
597
673
|
}
|
|
598
674
|
export function settleSubagentContent(taskId) {
|
|
599
|
-
const
|
|
675
|
+
const key = contentKeyOf(taskId);
|
|
676
|
+
const s = tasks.get(key);
|
|
600
677
|
if (!s)
|
|
601
678
|
return;
|
|
602
679
|
flushBuffers(s);
|
|
603
|
-
scheduleNotify(
|
|
680
|
+
scheduleNotify(key);
|
|
604
681
|
}
|
|
605
682
|
export function clearSubagentContent(taskId) {
|
|
606
|
-
|
|
683
|
+
for (;;) {
|
|
684
|
+
const key = contentKeyOf(taskId);
|
|
685
|
+
if (key === '')
|
|
686
|
+
return;
|
|
687
|
+
dropTask(key);
|
|
688
|
+
}
|
|
607
689
|
}
|
|
608
690
|
const bgFacts = new Map();
|
|
609
691
|
export function recordBgTerminalFacts(taskId, facts) {
|
|
@@ -619,10 +701,12 @@ export function recordBgTerminalFacts(taskId, facts) {
|
|
|
619
701
|
scheduleNotify(taskId);
|
|
620
702
|
}
|
|
621
703
|
export function clearBgTerminalFacts(taskId) {
|
|
622
|
-
|
|
704
|
+
for (const id of sameSubagentIds(taskId))
|
|
705
|
+
bgFacts.delete(id);
|
|
623
706
|
}
|
|
624
707
|
export function getBgTerminalFacts(taskId) {
|
|
625
|
-
const
|
|
708
|
+
const ids = sameSubagentIds(taskId);
|
|
709
|
+
const key = ids.find((id) => bgFacts.has(id)) ?? ids.map((id) => taskToParent.get(id)?.card).find((c) => c !== undefined) ?? '';
|
|
626
710
|
touchLru(bgFacts, key);
|
|
627
711
|
return bgFacts.get(key);
|
|
628
712
|
}
|
|
@@ -643,15 +727,35 @@ export function recordBgParentRun(taskId, runId, sessionId, sessionKey) {
|
|
|
643
727
|
export function recordSubagentOwner(taskId, runId, sessionId, sessionKey) {
|
|
644
728
|
if (!taskId || typeof runId !== 'string' || runId === '' || taskId === runId)
|
|
645
729
|
return;
|
|
646
|
-
|
|
730
|
+
const ids = sameSubagentIds(taskId);
|
|
731
|
+
const heldKeys = ids.filter((k) => bgParentRun.has(k));
|
|
732
|
+
const heldRecs = [];
|
|
733
|
+
for (const k of heldKeys) {
|
|
734
|
+
const rec = bgParentRun.get(k);
|
|
735
|
+
if (rec !== undefined)
|
|
736
|
+
heldRecs.push(rec);
|
|
737
|
+
}
|
|
738
|
+
if (bgParentRun.size >= MAX_BG_PARENT_RUNS && heldKeys.length === 0) {
|
|
647
739
|
const oldest = bgParentRun.keys().next().value;
|
|
648
740
|
if (oldest !== undefined)
|
|
649
741
|
bgParentRun.delete(oldest);
|
|
650
742
|
}
|
|
651
|
-
const
|
|
652
|
-
if (
|
|
743
|
+
const quarantinedHere = ids.some((k) => conflictQuarantine.get(k) === runId);
|
|
744
|
+
if (quarantinedHere)
|
|
653
745
|
return;
|
|
654
|
-
const
|
|
746
|
+
const sameRunHeld = heldRecs.filter((r) => r.runId === runId);
|
|
747
|
+
const heldSlots = new Set(sameRunHeld.map((r) => r.sessionKey ?? DEFAULT_SESSION_KEY));
|
|
748
|
+
if (sameRunHeld.length > 1 && heldSlots.size > 1) {
|
|
749
|
+
ownerSessionConflictCount++;
|
|
750
|
+
const pairOf = (r) => ({
|
|
751
|
+
...(r.sessionId !== undefined ? { sessionId: r.sessionId } : {}),
|
|
752
|
+
...(r.sessionKey !== undefined ? { sessionKey: r.sessionKey } : {}),
|
|
753
|
+
});
|
|
754
|
+
lastOwnerSessionConflict = { taskId, runId, prior: pairOf(sameRunHeld[0]), next: pairOf(sameRunHeld[1]) };
|
|
755
|
+
quarantineRun(ids, runId);
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
const prior = heldRecs.find((r) => r.runId === runId) ?? heldRecs[0];
|
|
655
759
|
const sameRun = prior?.runId === runId;
|
|
656
760
|
const incoming = typeof sessionId === 'string' && sessionId !== '' ? sessionId : undefined;
|
|
657
761
|
const incomingKey = typeof sessionKey === 'string' && sessionKey !== '' ? sessionKey : undefined;
|
|
@@ -685,16 +789,13 @@ export function recordSubagentOwner(taskId, runId, sessionId, sessionKey) {
|
|
|
685
789
|
const priorSlot = prior?.sessionKey ?? DEFAULT_SESSION_KEY;
|
|
686
790
|
const nextSlot = nextPair.sessionKey ?? DEFAULT_SESSION_KEY;
|
|
687
791
|
if (priorSlot !== nextSlot) {
|
|
688
|
-
|
|
689
|
-
if (conflictQuarantine.size >= MAX_BG_PARENT_RUNS && !conflictQuarantine.has(taskId)) {
|
|
690
|
-
const oldestQ = conflictQuarantine.keys().next().value;
|
|
691
|
-
if (oldestQ !== undefined)
|
|
692
|
-
conflictQuarantine.delete(oldestQ);
|
|
693
|
-
}
|
|
694
|
-
conflictQuarantine.set(taskId, runId);
|
|
792
|
+
quarantineRun(ids, runId);
|
|
695
793
|
return;
|
|
696
794
|
}
|
|
697
795
|
}
|
|
796
|
+
for (const k of ids)
|
|
797
|
+
if (k !== taskId)
|
|
798
|
+
bgParentRun.delete(k);
|
|
698
799
|
bgParentRun.delete(taskId);
|
|
699
800
|
bgParentRun.set(taskId, { runId, ...nextPair });
|
|
700
801
|
}
|
|
@@ -711,14 +812,43 @@ export function recordSubagentOwnerFromProgress(ev, ownerRunId, ownerSessionId,
|
|
|
711
812
|
recordSubagentOwner(o.taskId, ownerRunId, ownerSessionId, ownerSessionKey);
|
|
712
813
|
}
|
|
713
814
|
export function getBgParentRun(taskId) {
|
|
714
|
-
|
|
715
|
-
return bgParentRun.get(taskId)?.runId;
|
|
815
|
+
return getBgParentRunOwner(taskId)?.runId;
|
|
716
816
|
}
|
|
717
817
|
export function getBgParentRunOwner(taskId) {
|
|
718
818
|
if (typeof taskId !== 'string' || taskId === '')
|
|
719
819
|
return undefined;
|
|
720
|
-
|
|
721
|
-
|
|
820
|
+
const live = liveOwnerEntries(sameSubagentIds(taskId));
|
|
821
|
+
const first = live[0];
|
|
822
|
+
if (first === undefined)
|
|
823
|
+
return undefined;
|
|
824
|
+
if (!live.every(([, rec]) => sameOwnerRecord(rec, first[1])))
|
|
825
|
+
return undefined;
|
|
826
|
+
touchLru(bgParentRun, first[0]);
|
|
827
|
+
return first[1];
|
|
828
|
+
}
|
|
829
|
+
function liveOwnerEntries(ids) {
|
|
830
|
+
const out = [];
|
|
831
|
+
for (const k of ids) {
|
|
832
|
+
const rec = bgParentRun.get(k);
|
|
833
|
+
if (rec === undefined)
|
|
834
|
+
continue;
|
|
835
|
+
if (ids.some((q) => conflictQuarantine.get(q) === rec.runId))
|
|
836
|
+
continue;
|
|
837
|
+
out.push([k, rec]);
|
|
838
|
+
}
|
|
839
|
+
return out;
|
|
840
|
+
}
|
|
841
|
+
const sameOwnerRecord = (a, b) => a.runId === b.runId && a.sessionId === b.sessionId && a.sessionKey === b.sessionKey;
|
|
842
|
+
function quarantineRun(ids, runId) {
|
|
843
|
+
for (const k of ids) {
|
|
844
|
+
bgParentRun.delete(k);
|
|
845
|
+
if (conflictQuarantine.size >= MAX_BG_PARENT_RUNS && !conflictQuarantine.has(k)) {
|
|
846
|
+
const oldestQ = conflictQuarantine.keys().next().value;
|
|
847
|
+
if (oldestQ !== undefined)
|
|
848
|
+
conflictQuarantine.delete(oldestQ);
|
|
849
|
+
}
|
|
850
|
+
conflictQuarantine.set(k, runId);
|
|
851
|
+
}
|
|
722
852
|
}
|
|
723
853
|
export function __resetSubagentOwnerLedgerForTests() {
|
|
724
854
|
bgParentRun.clear();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { rewindArchiveReadingAt, rewindConversationAvailability } from './rewindArchiveReading.js';
|
|
2
|
+
import { ownDataField } from './ownKey.js';
|
|
2
3
|
export const TOOL_HISTORY_MISMATCH_KINDS = Object.freeze([
|
|
3
4
|
'tool_use_without_result',
|
|
4
5
|
'orphan_tool_result',
|
|
@@ -191,8 +192,8 @@ export function classifyToolHistoryMismatch(err) {
|
|
|
191
192
|
let status;
|
|
192
193
|
let rawMessage;
|
|
193
194
|
try {
|
|
194
|
-
code = err
|
|
195
|
-
status = err
|
|
195
|
+
code = ownDataField(err, 'code');
|
|
196
|
+
status = ownDataField(err, 'status');
|
|
196
197
|
rawMessage = err.message;
|
|
197
198
|
}
|
|
198
199
|
catch {
|
package/dist/toolRoster.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
1
2
|
export interface ToolRosterPathTargetView {
|
|
2
3
|
param: string;
|
|
3
4
|
access: string;
|
|
@@ -77,8 +78,8 @@ export type HandsSeamReading = {
|
|
|
77
78
|
export declare function handsSeamReadingOf(view: {
|
|
78
79
|
readonly hands?: WiringManifestHandsView;
|
|
79
80
|
} | null | undefined): HandsSeamReading;
|
|
80
|
-
export declare function handsSeamDetail(reading: HandsSeamReading): string;
|
|
81
|
-
export declare function handsMountedDetail(reading: HandsMountedReading): string;
|
|
81
|
+
export declare function handsSeamDetail(reading: HandsSeamReading, lang?: UiLanguage): string;
|
|
82
|
+
export declare function handsMountedDetail(reading: HandsMountedReading, lang?: UiLanguage): string;
|
|
82
83
|
export declare function toolRosterNames(roster: ToolRosterView | undefined): readonly string[];
|
|
83
84
|
export interface ToolShim {
|
|
84
85
|
name: string;
|
package/dist/toolRoster.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { displayUntrusted } from './displayUntrusted.js';
|
|
2
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
2
3
|
import { HANDS_REASON_NO_EXECUTION_ENV, projectHandsSection } from './handsSeam.js';
|
|
3
4
|
const str = (v) => typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
4
5
|
const strArr = (v) => Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined;
|
|
@@ -144,55 +145,55 @@ export function handsSeamReadingOf(view) {
|
|
|
144
145
|
return { kind: 'mounted' };
|
|
145
146
|
return seam.reason !== undefined ? { kind: 'not_mounted', reason: seam.reason } : { kind: 'not_mounted' };
|
|
146
147
|
}
|
|
147
|
-
const HANDS_NONE_STEM = 'this leg of the run was assembled with NO built-in file-and-shell tools';
|
|
148
|
-
const HANDS_NONE_TAIL = "so on this leg the model had no tool of the engine's own for editing files or running commands (tools mounted by other conditions, such as external servers, and sub-runs delegated to other legs are not covered by this reading)";
|
|
149
148
|
const HANDS_REASON_DISPLAY_MAX = 64;
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
function handsNotReported(lang) {
|
|
150
|
+
return renderMessage(msg('notice.capability.hands.notReported'), lang);
|
|
151
|
+
}
|
|
152
|
+
export function handsSeamDetail(reading, lang) {
|
|
152
153
|
const kind = typeof reading === 'object' && reading !== null ? reading.kind : undefined;
|
|
153
154
|
switch (kind) {
|
|
154
155
|
case 'mounted':
|
|
155
|
-
return '
|
|
156
|
+
return renderMessage(msg('notice.capability.hands.seamMounted'), lang);
|
|
156
157
|
case 'not_mounted': {
|
|
157
158
|
const raw = reading.reason;
|
|
158
159
|
const reason = typeof raw === 'string' && raw.length > 0 ? raw : undefined;
|
|
159
160
|
const why = reason === undefined
|
|
160
|
-
? '
|
|
161
|
+
? msg('notice.capability.hands.whyNoReason')
|
|
161
162
|
: reason === HANDS_REASON_NO_EXECUTION_ENV
|
|
162
|
-
? '
|
|
163
|
-
:
|
|
164
|
-
return
|
|
163
|
+
? msg('notice.capability.hands.whyNoExecutionEnv')
|
|
164
|
+
: msg('notice.capability.hands.whyUnknownReason', { reason: displayUntrusted(reason, { max: HANDS_REASON_DISPLAY_MAX }) });
|
|
165
|
+
return renderMessage(msg('notice.capability.hands.noneLine', { stem: msg('notice.capability.hands.noneStem'), why, tail: msg('notice.capability.hands.noneTail') }), lang);
|
|
165
166
|
}
|
|
166
167
|
default:
|
|
167
|
-
return
|
|
168
|
+
return handsNotReported(lang);
|
|
168
169
|
}
|
|
169
170
|
}
|
|
170
|
-
export function handsMountedDetail(reading) {
|
|
171
|
+
export function handsMountedDetail(reading, lang) {
|
|
171
172
|
const r = reading;
|
|
172
173
|
const kind = typeof r === 'object' && r !== null ? r.kind : undefined;
|
|
173
174
|
switch (kind) {
|
|
174
175
|
case 'mounted': {
|
|
175
176
|
const rows = r.rows;
|
|
176
177
|
if (typeof rows === 'number' && Number.isInteger(rows) && rows > 0)
|
|
177
|
-
return
|
|
178
|
-
return
|
|
178
|
+
return renderMessage(msg('notice.capability.hands.rosterMounted', { rows }), lang);
|
|
179
|
+
return handsNotReported(lang);
|
|
179
180
|
}
|
|
180
181
|
case 'not-mounted':
|
|
181
|
-
return
|
|
182
|
+
return renderMessage(msg('notice.capability.hands.rosterNotMounted', { stem: msg('notice.capability.hands.noneStem'), tail: msg('notice.capability.hands.noneTail') }), lang);
|
|
182
183
|
case 'unknown':
|
|
183
184
|
switch (r.why) {
|
|
184
185
|
case 'no-manifest':
|
|
185
|
-
return '
|
|
186
|
+
return renderMessage(msg('notice.capability.hands.unknownNoManifest'), lang);
|
|
186
187
|
case 'no-roster':
|
|
187
|
-
return '
|
|
188
|
+
return renderMessage(msg('notice.capability.hands.unknownNoRoster'), lang);
|
|
188
189
|
case 'roster-unreadable':
|
|
189
|
-
return '
|
|
190
|
+
return renderMessage(msg('notice.capability.hands.unknownRosterUnreadable'), lang);
|
|
190
191
|
case 'mount-condition-absent':
|
|
191
|
-
return '
|
|
192
|
+
return renderMessage(msg('notice.capability.hands.unknownMountConditionAbsent'), lang);
|
|
192
193
|
}
|
|
193
|
-
return
|
|
194
|
+
return handsNotReported(lang);
|
|
194
195
|
}
|
|
195
|
-
return
|
|
196
|
+
return handsNotReported(lang);
|
|
196
197
|
}
|
|
197
198
|
export function toolRosterNames(roster) {
|
|
198
199
|
return roster?.entries.map((e) => e.name) ?? [];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ToolsFlagNames {
|
|
2
|
+
readonly kept: readonly string[];
|
|
3
|
+
readonly excluded: readonly string[];
|
|
4
|
+
readonly bare: boolean;
|
|
5
|
+
readonly detached: readonly string[];
|
|
6
|
+
readonly scoped: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function parseToolsFlagNames(values: readonly string[]): ToolsFlagNames;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
function readableStrings(values) {
|
|
2
|
+
const out = [];
|
|
3
|
+
try {
|
|
4
|
+
if (!Array.isArray(values))
|
|
5
|
+
return out;
|
|
6
|
+
const n = values.length;
|
|
7
|
+
for (let i = 0; i < n; i++) {
|
|
8
|
+
try {
|
|
9
|
+
const v = values[i];
|
|
10
|
+
if (typeof v === 'string')
|
|
11
|
+
out.push(v);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
function splitToolsFlagTokens(values) {
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const value of values) {
|
|
26
|
+
if (value === '')
|
|
27
|
+
continue;
|
|
28
|
+
let cur = '';
|
|
29
|
+
let inParen = false;
|
|
30
|
+
for (const ch of value) {
|
|
31
|
+
if (ch === '(') {
|
|
32
|
+
inParen = true;
|
|
33
|
+
cur += ch;
|
|
34
|
+
}
|
|
35
|
+
else if (ch === ')') {
|
|
36
|
+
inParen = false;
|
|
37
|
+
cur += ch;
|
|
38
|
+
}
|
|
39
|
+
else if (ch === ',') {
|
|
40
|
+
if (inParen)
|
|
41
|
+
cur += ch;
|
|
42
|
+
else {
|
|
43
|
+
if (cur.trim() !== '')
|
|
44
|
+
out.push(cur.trim());
|
|
45
|
+
cur = '';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (ch === ' ') {
|
|
49
|
+
if (inParen)
|
|
50
|
+
cur += ch;
|
|
51
|
+
else if (cur.trim() !== '') {
|
|
52
|
+
out.push(cur.trim());
|
|
53
|
+
cur = '';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (cur !== '' || ch.trim() !== '') {
|
|
57
|
+
cur += ch;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (cur.trim() !== '')
|
|
61
|
+
out.push(cur.trim());
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
export function parseToolsFlagNames(values) {
|
|
66
|
+
const tokens = splitToolsFlagTokens(readableStrings(values));
|
|
67
|
+
const kept = [];
|
|
68
|
+
const excluded = new Set();
|
|
69
|
+
const detached = [];
|
|
70
|
+
const scoped = [];
|
|
71
|
+
let bare = false;
|
|
72
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
73
|
+
let token = tokens[i];
|
|
74
|
+
if (token === undefined)
|
|
75
|
+
continue;
|
|
76
|
+
if (!token.startsWith('!')) {
|
|
77
|
+
kept.push(token);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
let name = token.slice(1);
|
|
81
|
+
if (name === '') {
|
|
82
|
+
const next = tokens[i + 1];
|
|
83
|
+
if (next === undefined || next.startsWith('!') || next.startsWith('(')) {
|
|
84
|
+
bare = true;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
i++;
|
|
88
|
+
detached.push(next);
|
|
89
|
+
token = `!${next}`;
|
|
90
|
+
name = next;
|
|
91
|
+
}
|
|
92
|
+
const paren = name.indexOf('(');
|
|
93
|
+
if (paren === 0) {
|
|
94
|
+
bare = true;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (paren > 0) {
|
|
98
|
+
name = name.slice(0, paren);
|
|
99
|
+
scoped.push(token);
|
|
100
|
+
}
|
|
101
|
+
excluded.add(name);
|
|
102
|
+
}
|
|
103
|
+
return Object.freeze({
|
|
104
|
+
kept: Object.freeze(kept),
|
|
105
|
+
excluded: Object.freeze([...excluded]),
|
|
106
|
+
bare,
|
|
107
|
+
detached: Object.freeze(detached),
|
|
108
|
+
scoped: Object.freeze(scoped),
|
|
109
|
+
});
|
|
110
|
+
}
|