@sema-agent/client-core 0.93.0 → 0.94.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 +261 -0
- package/README.md +31 -18
- package/dist/adapt/arms.js +8 -5
- package/dist/adapter/downstream/terminalToSdkResult.js +2 -3
- package/dist/agentSession/engineSessionBackgroundStop.js +2 -1
- package/dist/agentsWireCaps.d.ts +15 -0
- package/dist/agentsWireCaps.js +111 -1
- package/dist/approvalReachWire.d.ts +18 -0
- package/dist/approvalReachWire.js +58 -0
- package/dist/approvalsStreamLiveCapability.js +16 -11
- package/dist/callerCwdCapability.d.ts +16 -0
- package/dist/callerCwdCapability.js +47 -0
- package/dist/controlRouter.js +3 -10
- package/dist/coreValuePorts.d.ts +64 -1
- package/dist/coreValuePorts.js +30 -0
- package/dist/detachWire.d.ts +1 -4
- package/dist/detachWire.js +1 -1
- package/dist/deviceExecutorManagementCapability.js +39 -34
- package/dist/deviceFlowPolling.d.ts +5 -0
- package/dist/deviceFlowPolling.js +28 -0
- package/dist/displayUntrusted.js +652 -21
- package/dist/engineErrorCodes.d.ts +5 -1
- package/dist/engineErrorCodes.js +9 -12
- package/dist/engineNoticeCodes.d.ts +22 -2
- package/dist/engineNoticeCodes.js +73 -6
- package/dist/engineRefusedToolName.d.ts +1 -0
- package/dist/engineRefusedToolName.js +8 -0
- package/dist/executionLaneCapability.js +14 -9
- package/dist/fileHistoryCaptureCapability.js +14 -9
- package/dist/fileHistoryLegNotice.d.ts +11 -0
- package/dist/fileHistoryLegNotice.js +50 -13
- package/dist/fleet/fleetLedger.js +5 -0
- package/dist/gateOutcome.d.ts +2 -1
- package/dist/gateOutcome.js +3 -0
- package/dist/gateVocabulary.js +1 -1
- package/dist/generated/engineAskFaceTables.d.ts +3 -0
- package/dist/generated/engineAskFaceTables.js +12 -0
- package/dist/generated/engineFactTables.d.ts +4 -2
- package/dist/generated/engineFactTables.js +13 -0
- package/dist/generated/engineNoticeTables.d.ts +5 -0
- package/dist/generated/engineNoticeTables.js +7 -0
- package/dist/generated/sdkFactTables.d.ts +3 -0
- package/dist/generated/sdkFactTables.js +17 -0
- package/dist/generated/settingsSchemaTables.d.ts +3 -0
- package/dist/generated/settingsSchemaTables.js +3 -0
- package/dist/headlessPermissionModeWire.d.ts +2 -2
- package/dist/headlessPermissionModeWire.js +11 -21
- package/dist/hitl/approvalHolds.d.ts +36 -0
- package/dist/hitl/approvalHolds.js +89 -0
- package/dist/hitl/approvalOutcomeNote.js +2 -1
- package/dist/hitl/approvalResolution.d.ts +3 -2
- package/dist/hitl/approvalResolution.js +21 -0
- package/dist/hitl/approvalsFeed.js +5 -0
- package/dist/hitl/askGateWire.js +3 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +8 -2
- package/dist/hitl/automaticAnswerVerdict.js +69 -21
- package/dist/hitl/decisionRefusal.d.ts +19 -0
- package/dist/hitl/decisionRefusal.js +63 -0
- package/dist/hitl/frameRouter.d.ts +10 -0
- package/dist/hitl/frameRouter.js +59 -3
- package/dist/hitl/gateLedger.d.ts +3 -0
- package/dist/hitl/gateLedger.js +17 -0
- package/dist/hitl/hitlBridge.d.ts +2 -2
- package/dist/hitl/hitlBridge.js +8 -10
- package/dist/hitl/hitlHostSurface.d.ts +6 -0
- package/dist/hitl/hitlHostSurface.js +25 -4
- package/dist/hitl/localAllowRule.js +2 -1
- package/dist/hitl/noAllowCause.d.ts +9 -0
- package/dist/hitl/noAllowCause.js +26 -0
- package/dist/hitl/parkResolver.js +6 -3
- package/dist/hitl/parkRowBirthWait.js +2 -1
- package/dist/hitl/persistedRulesWire.d.ts +6 -1
- package/dist/hitl/persistedRulesWire.js +12 -4
- package/dist/hitl/planReviewWire.d.ts +0 -1
- package/dist/hitl/planReviewWire.js +30 -9
- package/dist/hitl/sessionPolicyDeliverable.d.ts +1 -1
- package/dist/hitl/sessionPolicyDeliverable.js +3 -8
- package/dist/hitl/sessionPolicyWire.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +37 -2
- package/dist/hitl/toolApprovalWire.js +392 -13
- package/dist/humanTurnRead.d.ts +15 -1
- package/dist/humanTurnRead.js +28 -2
- package/dist/index.d.ts +18 -6
- package/dist/index.js +14 -5
- package/dist/limitsWire.d.ts +0 -1
- package/dist/limitsWire.js +2 -10
- package/dist/liveModelCatalog.d.ts +14 -0
- package/dist/liveModelCatalog.js +61 -0
- package/dist/mcpProbeCapability.js +14 -9
- package/dist/mcpReconnect.js +13 -8
- package/dist/memoryComplianceCapability.js +15 -10
- package/dist/memoryOriginCapability.js +15 -10
- package/dist/modelIdentityResolvability.d.ts +4 -2
- package/dist/modelIdentityResolvability.js +31 -4
- package/dist/outputStyleSeatCapability.d.ts +16 -0
- package/dist/outputStyleSeatCapability.js +47 -0
- package/dist/ownKey.d.ts +1 -0
- package/dist/ownKey.js +10 -0
- package/dist/peerLaneCapability.js +16 -11
- package/dist/permissionRuleIssue.js +1 -1
- package/dist/permissionRulesWriteCapability.js +16 -11
- package/dist/permissionsAllowGrantCapability.d.ts +2 -0
- package/dist/permissionsAllowGrantCapability.js +38 -16
- package/dist/permissionsDeclaration.d.ts +10 -1
- package/dist/permissionsDeclaration.js +97 -15
- package/dist/protocolSegment.d.ts +1 -0
- package/dist/protocolSegment.js +13 -1
- package/dist/request/taskRequest.d.ts +11 -3
- package/dist/request/taskRequest.js +13 -1
- package/dist/resultFrameKeys.d.ts +4 -0
- package/dist/resultFrameKeys.js +13 -0
- package/dist/resumeRefusalCopy.js +6 -16
- package/dist/retryStatus.js +6 -4
- package/dist/rewindArchiveCapability.js +13 -8
- package/dist/{hitl/rosterMountedNames.d.ts → rosterMountedNames.d.ts} +1 -1
- package/dist/runCancelContext.js +2 -1
- package/dist/sealedKeyCapability.js +19 -14
- package/dist/seatContract.d.ts +33 -5
- package/dist/seatContract.js +143 -2
- package/dist/sessionPolicyCapability.js +15 -10
- package/dist/sessionReadRedactionCapability.d.ts +16 -0
- package/dist/sessionReadRedactionCapability.js +47 -0
- package/dist/sessionSyncFileHistoryCapability.js +14 -9
- package/dist/skillToolListsCapability.js +14 -9
- package/dist/sqlEngineCapability.js +18 -13
- package/dist/steerPriorityCapability.js +21 -16
- package/dist/subagent/agentStateDetail.d.ts +1 -0
- package/dist/subagent/agentStateDetail.js +41 -0
- package/dist/subagent/engineCompactWire.d.ts +15 -0
- package/dist/subagent/engineCompactWire.js +75 -13
- package/dist/supportFloor.js +1 -1
- package/dist/taskRequestWords.d.ts +2 -4
- package/dist/taskRequestWords.js +3 -2
- package/dist/types/engineState.d.ts +1 -1
- package/dist/userAttachmentEnvelope.d.ts +22 -1
- package/dist/userAttachmentEnvelope.js +90 -2
- package/dist/userInvokedSkillsCapability.js +14 -9
- package/dist/webSearchBackendCapability.js +21 -16
- package/dist/wireErrorTriage.d.ts +11 -0
- package/dist/wireErrorTriage.js +35 -0
- package/dist/wireFailureShape.d.ts +6 -0
- package/dist/wireFailureShape.js +30 -3
- package/dist/wireRefusalCopy.d.ts +6 -1
- package/dist/wireRefusalCopy.js +22 -8
- package/dist/wiringInstructionsAttribution.d.ts +10 -0
- package/dist/wiringInstructionsAttribution.js +67 -0
- package/dist/workflowClient.js +22 -1
- package/dist/workflowsJournalCapability.js +14 -9
- package/dist/writeProtectionCapability.js +28 -23
- package/docs/INTEGRATION-CLIENTS.md +817 -45
- package/package.json +5 -5
- package/dist/askSurvivesStandingAnswer.d.ts +0 -13
- package/dist/askSurvivesStandingAnswer.js +0 -53
- package/dist/hitl/askSurvivesPosture.d.ts +0 -20
- package/dist/hitl/askSurvivesPosture.js +0 -48
- /package/dist/{hitl/rosterMountedNames.js → rosterMountedNames.js} +0 -0
package/dist/wireErrorTriage.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readErrorNumber, readErrorString, readErrorStringList } from './wireFailureShape.js';
|
|
2
2
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
3
|
+
import { readOwnDataValue } from './ownKey.js';
|
|
3
4
|
import { fleetLeaseUnavailableFromError } from './wireRefusalCopy.js';
|
|
4
5
|
import { DRAINING_ERROR_CODE, isCorruptSessionCode, RESUME_AT_ERROR_CODE_PREFIX, RESUME_POLICY_FOLD_CODE, RESUME_RETRY_LATER_CODES, RESUME_USAGE_WINDOW_EXHAUSTED, SCENARIO_NOT_ALLOWED_ERROR_CODE, } from './engineErrorCodes.js';
|
|
5
6
|
export const WIRE_NETWORK_ERROR_PATTERN = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EPIPE|socket hang up|UND_ERR|terminated|other side closed/i;
|
|
@@ -87,6 +88,40 @@ export function drainingRetryDelayMs(err, attempt, opts) {
|
|
|
87
88
|
const ladder = opts?.ladder && opts.ladder.length > 0 ? opts.ladder : [1_000, 2_000, 4_000];
|
|
88
89
|
return ladder[Math.min(attempt, ladder.length - 1)] ?? 1_000;
|
|
89
90
|
}
|
|
91
|
+
export function isInStreamDrainingEnd(frame) {
|
|
92
|
+
try {
|
|
93
|
+
if (typeof frame !== 'object' || frame === null)
|
|
94
|
+
return false;
|
|
95
|
+
if (typeof readOwnDataValue(frame, 'status') === 'number')
|
|
96
|
+
return false;
|
|
97
|
+
const typeSlot = Object.getOwnPropertyDescriptor(frame, 'type');
|
|
98
|
+
const outerType = typeSlot !== undefined && Object.hasOwn(typeSlot, 'value') ? typeSlot.value : undefined;
|
|
99
|
+
if (outerType === 'error')
|
|
100
|
+
return readOwnDataValue(frame, 'errorCode') === DRAINING_ERROR_CODE;
|
|
101
|
+
if (typeSlot !== undefined && outerType !== 'unknown')
|
|
102
|
+
return false;
|
|
103
|
+
if (readOwnDataValue(frame, 'event') !== 'error')
|
|
104
|
+
return false;
|
|
105
|
+
const data = readOwnDataValue(frame, 'data');
|
|
106
|
+
if (typeof data !== 'object' || data === null)
|
|
107
|
+
return false;
|
|
108
|
+
const dataType = readOwnDataValue(data, 'type');
|
|
109
|
+
if (dataType !== undefined && dataType !== 'error')
|
|
110
|
+
return false;
|
|
111
|
+
return readOwnDataValue(data, 'errorCode') === DRAINING_ERROR_CODE;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export const STREAM_DRAINING_RECONNECT_MAX = 3;
|
|
118
|
+
export function streamDrainingDecision(frame, attempt, opts) {
|
|
119
|
+
if (!isInStreamDrainingEnd(frame))
|
|
120
|
+
return { giveUp: 'not_draining_end' };
|
|
121
|
+
if (!Number.isSafeInteger(attempt) || attempt < 0 || attempt >= STREAM_DRAINING_RECONNECT_MAX)
|
|
122
|
+
return { giveUp: 'attempts_exhausted' };
|
|
123
|
+
return { reconnectAfterMs: drainingRetryDelayMs(null, attempt, opts?.ladder !== undefined ? { ladder: opts.ladder } : undefined) };
|
|
124
|
+
}
|
|
90
125
|
export function scenarioDenyFromError(err) {
|
|
91
126
|
if (typeof err !== 'object' || err === null)
|
|
92
127
|
return null;
|
|
@@ -8,6 +8,7 @@ interface WireFailureShape {
|
|
|
8
8
|
bodyVerdict?: string;
|
|
9
9
|
bodyCurrentName?: string;
|
|
10
10
|
message: string;
|
|
11
|
+
ownMessage?: string;
|
|
11
12
|
}
|
|
12
13
|
export declare function readErrorNumber(o: object, key: string): number | undefined;
|
|
13
14
|
export declare function readErrorRecord(o: object, key: string): object | undefined;
|
|
@@ -15,4 +16,9 @@ export declare function readErrorString(o: object, key: string): string | undefi
|
|
|
15
16
|
export declare function readErrorStringList(o: object, key: string): readonly string[] | undefined;
|
|
16
17
|
export declare function readErrorStrictStringList(o: object, key: string): readonly string[] | undefined;
|
|
17
18
|
export declare function wireFailureShapeOf(e: unknown): WireFailureShape;
|
|
19
|
+
export declare const WIRE_FAILURE_UNRENDERABLE_TEXT = "the call failed with an error this client could not render";
|
|
20
|
+
export declare function wireFailureTextsOf(e: unknown): {
|
|
21
|
+
reason: string;
|
|
22
|
+
log: string;
|
|
23
|
+
};
|
|
18
24
|
export {};
|
package/dist/wireFailureShape.js
CHANGED
|
@@ -97,7 +97,14 @@ export function wireFailureShapeOf(e) {
|
|
|
97
97
|
catch {
|
|
98
98
|
extraUnreadable = true;
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
let extraObj;
|
|
101
|
+
try {
|
|
102
|
+
extraObj = typeof extra === 'object' && extra !== null && !Array.isArray(extra) ? extra : undefined;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
extraObj = undefined;
|
|
106
|
+
extraUnreadable = true;
|
|
107
|
+
}
|
|
101
108
|
let committedPresent = false;
|
|
102
109
|
let committedRaw;
|
|
103
110
|
if (extraObj !== undefined) {
|
|
@@ -133,12 +140,13 @@ export function wireFailureShapeOf(e) {
|
|
|
133
140
|
const bodyName = ownString('name');
|
|
134
141
|
const bodyVerdict = ownString('verdict');
|
|
135
142
|
const bodyCurrentName = ownString('currentName');
|
|
143
|
+
const ownMessage = typeof rawMessage === 'string' && rawMessage !== '' ? rawMessage : undefined;
|
|
136
144
|
let message;
|
|
137
145
|
try {
|
|
138
|
-
message =
|
|
146
|
+
message = ownMessage !== undefined ? ownMessage : String(e);
|
|
139
147
|
}
|
|
140
148
|
catch {
|
|
141
|
-
message =
|
|
149
|
+
message = WIRE_FAILURE_UNRENDERABLE_TEXT;
|
|
142
150
|
}
|
|
143
151
|
const sec = typeof retryAfterMs === 'number' && Number.isFinite(retryAfterMs) && retryAfterMs >= 0
|
|
144
152
|
? Math.ceil(retryAfterMs / 1000)
|
|
@@ -160,5 +168,24 @@ export function wireFailureShapeOf(e) {
|
|
|
160
168
|
...(bodyVerdict !== undefined ? { bodyVerdict } : {}),
|
|
161
169
|
...(bodyCurrentName !== undefined ? { bodyCurrentName } : {}),
|
|
162
170
|
message,
|
|
171
|
+
...(ownMessage !== undefined ? { ownMessage } : {}),
|
|
163
172
|
};
|
|
164
173
|
}
|
|
174
|
+
export const WIRE_FAILURE_UNRENDERABLE_TEXT = 'the call failed with an error this client could not render';
|
|
175
|
+
export function wireFailureTextsOf(e) {
|
|
176
|
+
const { ownMessage } = wireFailureShapeOf(e);
|
|
177
|
+
let log;
|
|
178
|
+
try {
|
|
179
|
+
log = String(e).slice(0, 300);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
log = '<unprintable thrown value>';
|
|
183
|
+
}
|
|
184
|
+
if (ownMessage !== undefined)
|
|
185
|
+
return { reason: ownMessage, log };
|
|
186
|
+
if (typeof e === 'string')
|
|
187
|
+
return { reason: e !== '' ? e : WIRE_FAILURE_UNRENDERABLE_TEXT, log };
|
|
188
|
+
if (typeof e === 'number' || typeof e === 'boolean' || typeof e === 'bigint')
|
|
189
|
+
return { reason: String(e), log };
|
|
190
|
+
return { reason: WIRE_FAILURE_UNRENDERABLE_TEXT, log };
|
|
191
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FLEET_LEASE_UNAVAILABLE, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
1
|
+
import { FLEET_LEASE_UNAVAILABLE, REQUEST_AUTONOMY_LANE_REFUSED, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
2
2
|
import type { TaskRequestLike } from './request/taskRequest.js';
|
|
3
3
|
export declare const CONFLICT_APPROVAL_SETTLED = "conflict.approval_settled";
|
|
4
4
|
export declare const CONFLICT_RUN_NOT_RUNNING = "conflict.run_not_running";
|
|
@@ -83,3 +83,8 @@ export interface HookMatcherRefusal {
|
|
|
83
83
|
readonly canonical: string;
|
|
84
84
|
}
|
|
85
85
|
export declare function hookMatcherRefusalFromError(err: unknown): HookMatcherRefusal | undefined;
|
|
86
|
+
export interface AutonomyLaneRefusalDetail {
|
|
87
|
+
readonly code: typeof REQUEST_AUTONOMY_LANE_REFUSED;
|
|
88
|
+
}
|
|
89
|
+
export declare function autonomyLaneRefusalFromError(err: unknown): AutonomyLaneRefusalDetail | null;
|
|
90
|
+
export declare function autonomyLaneRefusalContent(): string;
|
package/dist/wireRefusalCopy.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readErrorNumber, readErrorRecord, readErrorStrictStringList, readErrorString, readErrorStringList } from './wireFailureShape.js';
|
|
2
2
|
import { readOwnNonEmptyString } from './ownKey.js';
|
|
3
|
-
import { ACTIVE_RUN_BUSY_ERROR_CODE, FLEET_LEASE_UNAVAILABLE, REQUEST_FIELD_CONFLICT, RESUME_POLICY_FOLD_CODE, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
3
|
+
import { ACTIVE_RUN_BUSY_ERROR_CODE, FLEET_LEASE_UNAVAILABLE, REQUEST_AUTONOMY_LANE_REFUSED, REQUEST_FIELD_CONFLICT, RESUME_POLICY_FOLD_CODE, SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
|
|
4
4
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
5
5
|
import { effectiveWireErrorCode } from './wireErrorTriage.js';
|
|
6
6
|
import { CORE_TOOL_DECLARATION_CODES } from './generated/engineFactTables.js';
|
|
@@ -11,24 +11,31 @@ function readStringField(o, key) {
|
|
|
11
11
|
return typeof v === 'string' && v !== '' ? v : undefined;
|
|
12
12
|
}
|
|
13
13
|
export function cancelConflictFromError(err) {
|
|
14
|
+
let o;
|
|
14
15
|
try {
|
|
15
16
|
if (err === null || typeof err !== 'object')
|
|
16
17
|
return null;
|
|
17
|
-
|
|
18
|
+
o = err;
|
|
18
19
|
const rawStatus = o.status ?? o.statusCode;
|
|
19
20
|
const is409 = rawStatus === 409 || (rawStatus === undefined && o.name === 'ConflictError');
|
|
20
21
|
if (!is409)
|
|
21
22
|
return null;
|
|
22
|
-
const code = readStringField(o, 'errorCode');
|
|
23
|
-
if (code === CONFLICT_APPROVAL_SETTLED)
|
|
24
|
-
return { kind: 'approval_settled', code };
|
|
25
|
-
if (code === CONFLICT_RUN_NOT_RUNNING)
|
|
26
|
-
return { kind: 'run_not_running', code };
|
|
27
|
-
return { kind: 'unrecognized', ...(code !== undefined ? { code } : {}) };
|
|
28
23
|
}
|
|
29
24
|
catch {
|
|
30
25
|
return null;
|
|
31
26
|
}
|
|
27
|
+
let code;
|
|
28
|
+
try {
|
|
29
|
+
code = readStringField(o, 'errorCode');
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
code = undefined;
|
|
33
|
+
}
|
|
34
|
+
if (code === CONFLICT_APPROVAL_SETTLED)
|
|
35
|
+
return { kind: 'approval_settled', code };
|
|
36
|
+
if (code === CONFLICT_RUN_NOT_RUNNING)
|
|
37
|
+
return { kind: 'run_not_running', code };
|
|
38
|
+
return { kind: 'unrecognized', ...(code !== undefined ? { code } : {}) };
|
|
32
39
|
}
|
|
33
40
|
export function cancelConflictContent(detail) {
|
|
34
41
|
switch (detail.kind) {
|
|
@@ -619,3 +626,10 @@ export function hookMatcherRefusalFromError(err) {
|
|
|
619
626
|
return undefined;
|
|
620
627
|
}
|
|
621
628
|
}
|
|
629
|
+
export function autonomyLaneRefusalFromError(err) {
|
|
630
|
+
return effectiveWireErrorCode(err) === REQUEST_AUTONOMY_LANE_REFUSED ? { code: REQUEST_AUTONOMY_LANE_REFUSED } : null;
|
|
631
|
+
}
|
|
632
|
+
export function autonomyLaneRefusalContent() {
|
|
633
|
+
return ('The engine did not start this leader run: this deployment runs in plan-only autonomy, and a leader run has no way to have its plan reviewed, ' +
|
|
634
|
+
'so nothing was started · Submit the work as a regular run instead, or ask whoever operates the engine to change its autonomy setting');
|
|
635
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type CallerCwdReading } from './callerCwdCapability.js';
|
|
2
|
+
export declare function legCwdOfBody(body: object | null | undefined, callerCwd: CallerCwdReading | undefined): string | undefined;
|
|
3
|
+
export interface InstructionsAttributionInput {
|
|
4
|
+
legCwd: string | undefined;
|
|
5
|
+
currentCwd: string;
|
|
6
|
+
realPathOf: (path: string) => string;
|
|
7
|
+
}
|
|
8
|
+
export declare function engineSelectedInstructionsFile(view: {
|
|
9
|
+
readonly selected: readonly string[];
|
|
10
|
+
} | null | undefined, input: InstructionsAttributionInput): string | undefined;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { callerCwdAdmitted } from './callerCwdCapability.js';
|
|
2
|
+
import { displayUntrusted } from './displayUntrusted.js';
|
|
3
|
+
import { readOutboundBodyField } from './fileHistoryLegNotice.js';
|
|
4
|
+
export function legCwdOfBody(body, callerCwd) {
|
|
5
|
+
if (!callerCwdAdmitted(callerCwd))
|
|
6
|
+
return undefined;
|
|
7
|
+
const r = readOutboundBodyField(body, 'cwd');
|
|
8
|
+
return r.kind === 'value' && typeof r.value === 'string' && r.value.length > 0 ? r.value : undefined;
|
|
9
|
+
}
|
|
10
|
+
function realOf(realPathOf, path) {
|
|
11
|
+
try {
|
|
12
|
+
if (typeof realPathOf !== 'function')
|
|
13
|
+
return undefined;
|
|
14
|
+
const r = realPathOf(path);
|
|
15
|
+
return typeof r === 'string' && r.length > 0 ? r : undefined;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function safeRelativeMember(member) {
|
|
22
|
+
if (typeof member !== 'string' || member.length === 0)
|
|
23
|
+
return false;
|
|
24
|
+
if (displayUntrusted(member) !== member)
|
|
25
|
+
return false;
|
|
26
|
+
if (member.includes('\\') || member.startsWith('/') || /^[A-Za-z]:/.test(member))
|
|
27
|
+
return false;
|
|
28
|
+
return member.split('/').every((seg) => seg !== '' && seg !== '..');
|
|
29
|
+
}
|
|
30
|
+
function isSep(path, c) {
|
|
31
|
+
return c === '/' || (!path.startsWith('/') && c === '\\');
|
|
32
|
+
}
|
|
33
|
+
function trimSeps(path) {
|
|
34
|
+
let end = path.length;
|
|
35
|
+
while (end > 0 && isSep(path, path.charAt(end - 1)))
|
|
36
|
+
end--;
|
|
37
|
+
return path.slice(0, end);
|
|
38
|
+
}
|
|
39
|
+
function strictlyWithin(child, dir) {
|
|
40
|
+
const trimmed = trimSeps(dir);
|
|
41
|
+
if (!child.startsWith(trimmed) || child.length <= trimmed.length)
|
|
42
|
+
return false;
|
|
43
|
+
return isSep(dir, child.charAt(trimmed.length));
|
|
44
|
+
}
|
|
45
|
+
export function engineSelectedInstructionsFile(view, input) {
|
|
46
|
+
try {
|
|
47
|
+
if (view === null || typeof view !== 'object' || input === null || typeof input !== 'object')
|
|
48
|
+
return undefined;
|
|
49
|
+
const { legCwd, currentCwd, realPathOf } = input;
|
|
50
|
+
if (typeof legCwd !== 'string' || legCwd.length === 0 || legCwd !== currentCwd)
|
|
51
|
+
return undefined;
|
|
52
|
+
const selected = view.selected;
|
|
53
|
+
if (!Array.isArray(selected) || selected.length === 0)
|
|
54
|
+
return undefined;
|
|
55
|
+
const member = selected[0];
|
|
56
|
+
if (!safeRelativeMember(member))
|
|
57
|
+
return undefined;
|
|
58
|
+
const realDir = realOf(realPathOf, currentCwd);
|
|
59
|
+
const realFile = realOf(realPathOf, `${trimSeps(currentCwd)}/${member}`);
|
|
60
|
+
if (realDir === undefined || realFile === undefined || !strictlyWithin(realFile, realDir))
|
|
61
|
+
return undefined;
|
|
62
|
+
return member;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
package/dist/workflowClient.js
CHANGED
|
@@ -5,6 +5,7 @@ import { makeEngineWireClient } from './engineWireSdk.js';
|
|
|
5
5
|
import { engineWireDebugEnabled } from './engineWireTarget.js';
|
|
6
6
|
import { hostLog } from './host.js';
|
|
7
7
|
import { isReadCredentialRefusal } from './readCredentialRefusal.js';
|
|
8
|
+
import { isInStreamDrainingEnd, streamDrainingDecision } from './wireErrorTriage.js';
|
|
8
9
|
function coerceRunStatus(s) {
|
|
9
10
|
switch (s) {
|
|
10
11
|
case 'completed':
|
|
@@ -584,9 +585,11 @@ async function consumeWorkflowActivity(l, cfg) {
|
|
|
584
585
|
emitActivityTick(l);
|
|
585
586
|
return;
|
|
586
587
|
}
|
|
588
|
+
let drainEnds = 0;
|
|
587
589
|
while (!l.closed && !l.abort.signal.aborted) {
|
|
588
590
|
let sawFrame = false;
|
|
589
591
|
let threw = false;
|
|
592
|
+
let lastDrainEnd;
|
|
590
593
|
try {
|
|
591
594
|
const stream = client.workflows.stream(l.workflowId, {
|
|
592
595
|
signal: l.abort.signal,
|
|
@@ -597,6 +600,12 @@ async function consumeWorkflowActivity(l, cfg) {
|
|
|
597
600
|
return;
|
|
598
601
|
sawFrame = true;
|
|
599
602
|
l.connected = true;
|
|
603
|
+
if (isInStreamDrainingEnd(frame)) {
|
|
604
|
+
lastDrainEnd = frame;
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
lastDrainEnd = undefined;
|
|
608
|
+
drainEnds = 0;
|
|
600
609
|
try {
|
|
601
610
|
foldWorkflowActivityFrame(l, frame);
|
|
602
611
|
}
|
|
@@ -632,9 +641,21 @@ async function consumeWorkflowActivity(l, cfg) {
|
|
|
632
641
|
return;
|
|
633
642
|
}
|
|
634
643
|
}
|
|
644
|
+
let waitMs = WORKFLOW_ACTIVITY_RECONNECT_MS;
|
|
645
|
+
if (lastDrainEnd !== undefined) {
|
|
646
|
+
const decision = streamDrainingDecision(lastDrainEnd, drainEnds++);
|
|
647
|
+
if ('giveUp' in decision) {
|
|
648
|
+
l.closed = true;
|
|
649
|
+
l.closedReason = 'error';
|
|
650
|
+
l.lastError = 'the engine kept ending this stream because it is going down (drain end frames)';
|
|
651
|
+
emitActivityTick(l);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
waitMs = decision.reconnectAfterMs;
|
|
655
|
+
}
|
|
635
656
|
emitActivityTick(l);
|
|
636
657
|
if (!l.closed && !l.abort.signal.aborted) {
|
|
637
|
-
await abortableSleep(
|
|
658
|
+
await abortableSleep(waitMs, l.abort.signal);
|
|
638
659
|
}
|
|
639
660
|
}
|
|
640
661
|
emitActivityTick(l);
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
2
|
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
3
|
export function projectWorkflowsJournalCapability(caps) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
try {
|
|
5
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
6
|
+
return undefined;
|
|
7
|
+
if (!Object.hasOwn(caps, 'workflowsJournal'))
|
|
8
|
+
return { kind: 'not_reported' };
|
|
9
|
+
const v = caps.workflowsJournal;
|
|
10
|
+
if (v === undefined)
|
|
11
|
+
return { kind: 'not_reported' };
|
|
12
|
+
if (typeof v !== 'boolean')
|
|
13
|
+
return undefined;
|
|
14
|
+
return v ? { kind: 'present' } : { kind: 'absent' };
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
12
17
|
return undefined;
|
|
13
|
-
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
20
|
const reader = createEngineCapReader({
|
|
16
21
|
name: 'workflowsJournal',
|
|
@@ -2,30 +2,35 @@ import { capForDisplay } from './fleetTaskDesc.js';
|
|
|
2
2
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
3
3
|
import { createEngineCapReader } from './engineCapReader.js';
|
|
4
4
|
export function projectWriteProtectionCapability(caps) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
5
|
+
try {
|
|
6
|
+
if (caps === null || typeof caps !== 'object')
|
|
7
|
+
return undefined;
|
|
8
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
9
|
+
return undefined;
|
|
10
|
+
if (!Object.hasOwn(caps, 'writeProtection'))
|
|
11
|
+
return { kind: 'not_reported' };
|
|
12
|
+
const wp = caps.writeProtection;
|
|
13
|
+
if (wp === null)
|
|
14
|
+
return { kind: 'none' };
|
|
15
|
+
if (wp === undefined)
|
|
16
|
+
return { kind: 'not_reported' };
|
|
17
|
+
if (typeof wp !== 'object' || Array.isArray(wp))
|
|
18
|
+
return undefined;
|
|
19
|
+
const w = wp;
|
|
20
|
+
const armed = w.armed;
|
|
21
|
+
const replaced = w.replaced;
|
|
22
|
+
const rows = w.rows;
|
|
23
|
+
if (typeof armed !== 'boolean')
|
|
24
|
+
return undefined;
|
|
25
|
+
if (typeof replaced !== 'boolean')
|
|
26
|
+
return undefined;
|
|
27
|
+
if (typeof rows !== 'number' || !Number.isInteger(rows) || rows < 0)
|
|
28
|
+
return undefined;
|
|
29
|
+
return { kind: 'present', view: { armed, rows, replaced } };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
27
32
|
return undefined;
|
|
28
|
-
|
|
33
|
+
}
|
|
29
34
|
}
|
|
30
35
|
export function projectWriteProtectionPosture(wiring) {
|
|
31
36
|
if (wiring === null || typeof wiring !== 'object')
|