@wrongstack/core 0.6.7 → 0.7.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/dist/{agent-bridge-BCVxmrOn.d.ts → agent-bridge-CrQpYjM7.d.ts} +1 -1
- package/dist/{compactor-BUJ8550X.d.ts → compactor-CWV1u-IU.d.ts} +1 -1
- package/dist/{config-BHkYGzUT.d.ts → config-C34JRwl4.d.ts} +1 -1
- package/dist/{context-C8mBUzBv.d.ts → context-bmR0YgBm.d.ts} +71 -3
- package/dist/coordination/index.d.ts +11 -11
- package/dist/coordination/index.js +53 -9
- package/dist/coordination/index.js.map +1 -1
- package/dist/default-config-DvRSTELf.d.ts +20 -0
- package/dist/defaults/index.d.ts +20 -19
- package/dist/defaults/index.js +130 -32
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-DounT6pP.d.ts → events-CEKFTmIY.d.ts} +1 -1
- package/dist/execution/index.d.ts +19 -13
- package/dist/execution/index.js +94 -22
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/extension/index.js +3 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/{index-DiIGZh5I.d.ts → index-BJIFLGII.d.ts} +5 -5
- package/dist/{index-BlVITqm-.d.ts → index-CZR0HjxM.d.ts} +12 -105
- package/dist/index.d.ts +27 -26
- package/dist/index.js +184 -53
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/kernel/index.d.ts +9 -9
- package/dist/kernel/index.js +8 -4
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-CXFfDN_d.d.ts → mcp-servers-BRJicm5o.d.ts} +3 -3
- package/dist/models/index.d.ts +2 -2
- package/dist/{multi-agent-Iy8YUe3v.d.ts → multi-agent-Cm1wYSrw.d.ts} +7 -2
- package/dist/{agent-subagent-runner-BTloSwjE.d.ts → multi-agent-coordinator-CCupVFqv.d.ts} +117 -4
- package/dist/observability/index.d.ts +2 -2
- package/dist/{path-resolver-DwJO5XBn.d.ts → path-resolver-CfT7e_HT.d.ts} +2 -2
- package/dist/{plan-templates-CG_pInJV.d.ts → plan-templates-Q78an-GJ.d.ts} +4 -4
- package/dist/{provider-runner-DoohzfyD.d.ts → provider-runner-WDj28o7J.d.ts} +3 -3
- package/dist/{retry-policy-DOnwHAyz.d.ts → retry-policy-Dpxp4SET.d.ts} +1 -1
- package/dist/sdd/index.d.ts +3 -3
- package/dist/{secret-scrubber-C9UJxFCJ.d.ts → secret-scrubber-C2YCYtkn.d.ts} +1 -1
- package/dist/{secret-scrubber-DcTK9JHC.d.ts → secret-scrubber-CowtdEF8.d.ts} +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/{selector-DVo3eT-P.d.ts → selector-CP39HhCe.d.ts} +1 -1
- package/dist/{session-reader-BXWxFAhS.d.ts → session-reader-Dwjn4WZR.d.ts} +1 -1
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js +93 -10
- package/dist/storage/index.js.map +1 -1
- package/dist/{system-prompt-BBGles-N.d.ts → system-prompt-CfgXqyv2.d.ts} +1 -1
- package/dist/{tool-executor-CwpjhwHC.d.ts → tool-executor-D5NFi_LV.d.ts} +5 -5
- package/dist/types/index.d.ts +16 -15
- package/dist/types/index.js +101 -20
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-
|
|
1
|
+
import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-Cm1wYSrw.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* In-memory pub/sub transport for agent-to-agent messaging.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { W as WireFamily } from './models-registry-Y2xbog0E.js';
|
|
2
|
-
import { P as Permission } from './context-
|
|
2
|
+
import { P as Permission } from './context-bmR0YgBm.js';
|
|
3
3
|
|
|
4
4
|
type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';
|
|
5
5
|
type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';
|
|
@@ -91,8 +91,62 @@ declare function asText(content: string | ContentBlock[]): string;
|
|
|
91
91
|
* This lets consumers (CLI, TUI, plugins, tests) branch on structured
|
|
92
92
|
* data instead of parsing error messages.
|
|
93
93
|
*/
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Machine-readable error codes as frozen constants.
|
|
96
|
+
*
|
|
97
|
+
* Use `ERROR_CODES.X` instead of raw string literals for:
|
|
98
|
+
* - IDE autocomplete and compile-time validation
|
|
99
|
+
* - Safe refactoring (rename updates all usages)
|
|
100
|
+
* - Plugin extensibility (extend the object to add custom codes)
|
|
101
|
+
*
|
|
102
|
+
* The `ErrorCode` type is derived from this object, so adding a new
|
|
103
|
+
* code here automatically updates the type without extra changes.
|
|
104
|
+
*/
|
|
105
|
+
declare const ERROR_CODES: {
|
|
106
|
+
readonly PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED";
|
|
107
|
+
readonly PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED";
|
|
108
|
+
readonly PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED";
|
|
109
|
+
readonly PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST";
|
|
110
|
+
readonly PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR";
|
|
111
|
+
readonly PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR";
|
|
112
|
+
readonly PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW";
|
|
113
|
+
readonly TOOL_NOT_FOUND: "TOOL_NOT_FOUND";
|
|
114
|
+
readonly TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED";
|
|
115
|
+
readonly TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED";
|
|
116
|
+
readonly TOOL_TIMEOUT: "TOOL_TIMEOUT";
|
|
117
|
+
readonly TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID";
|
|
118
|
+
readonly CONFIG_INVALID: "CONFIG_INVALID";
|
|
119
|
+
readonly CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND";
|
|
120
|
+
readonly CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED";
|
|
121
|
+
readonly CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED";
|
|
122
|
+
readonly PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED";
|
|
123
|
+
readonly PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH";
|
|
124
|
+
readonly PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY";
|
|
125
|
+
readonly AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT";
|
|
126
|
+
readonly AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW";
|
|
127
|
+
readonly AGENT_ABORTED: "AGENT_ABORTED";
|
|
128
|
+
readonly AGENT_RUN_FAILED: "AGENT_RUN_FAILED";
|
|
129
|
+
readonly SESSION_NOT_FOUND: "SESSION_NOT_FOUND";
|
|
130
|
+
readonly SESSION_CORRUPTED: "SESSION_CORRUPTED";
|
|
131
|
+
readonly SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED";
|
|
132
|
+
readonly CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND";
|
|
133
|
+
readonly CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND";
|
|
134
|
+
readonly REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE";
|
|
135
|
+
readonly REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND";
|
|
136
|
+
readonly FS_READ_FAILED: "FS_READ_FAILED";
|
|
137
|
+
readonly FS_WRITE_FAILED: "FS_WRITE_FAILED";
|
|
138
|
+
readonly FS_MKDIR_FAILED: "FS_MKDIR_FAILED";
|
|
139
|
+
readonly FS_DELETE_FAILED: "FS_DELETE_FAILED";
|
|
140
|
+
readonly FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED";
|
|
141
|
+
readonly UNKNOWN: "UNKNOWN";
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`
|
|
145
|
+
* instead of a string literal union means TypeScript auto-updates the type whenever
|
|
146
|
+
* a new code is added to `ERROR_CODES` — no need to keep two lists in sync.
|
|
147
|
+
*/
|
|
148
|
+
type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
|
|
149
|
+
type ErrorSubsystem = 'provider' | 'tool' | 'config' | 'plugin' | 'agent' | 'session' | 'container' | 'fs' | 'general';
|
|
96
150
|
type ErrorSeverity = 'fatal' | 'error' | 'warning';
|
|
97
151
|
declare class WrongStackError extends Error {
|
|
98
152
|
readonly code: ErrorCode;
|
|
@@ -186,12 +240,26 @@ declare class SessionError extends WrongStackError {
|
|
|
186
240
|
cause?: unknown;
|
|
187
241
|
});
|
|
188
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* File system operation errors.
|
|
245
|
+
*/
|
|
246
|
+
declare class FsError extends WrongStackError {
|
|
247
|
+
readonly path?: string;
|
|
248
|
+
constructor(opts: {
|
|
249
|
+
message: string;
|
|
250
|
+
code: Extract<ErrorCode, 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'>;
|
|
251
|
+
path?: string;
|
|
252
|
+
context?: Record<string, unknown>;
|
|
253
|
+
cause?: unknown;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
189
256
|
declare function isWrongStackError(err: unknown): err is WrongStackError;
|
|
190
257
|
declare function isToolError(err: unknown): err is ToolError;
|
|
191
258
|
declare function isConfigError(err: unknown): err is ConfigError;
|
|
192
259
|
declare function isPluginError(err: unknown): err is PluginError;
|
|
193
260
|
declare function isSessionError(err: unknown): err is SessionError;
|
|
194
261
|
declare function isAgentError(err: unknown): err is AgentError;
|
|
262
|
+
declare function isFsError(err: unknown): err is FsError;
|
|
195
263
|
|
|
196
264
|
type Permission = 'auto' | 'confirm' | 'deny';
|
|
197
265
|
/**
|
|
@@ -970,4 +1038,4 @@ declare class Context implements RunEnv {
|
|
|
970
1038
|
usage(): Usage;
|
|
971
1039
|
}
|
|
972
1040
|
|
|
973
|
-
export {
|
|
1041
|
+
export { isThinkingBlock as $, AgentError as A, type ToolFinalEvent as B, type Capabilities as C, type ToolProgressEvent as D, ERROR_CODES as E, type FileSnapshot as F, type ToolResultBlock as G, type ToolStreamEvent as H, type ImageBlock as I, type JSONSchema as J, type ToolUseBlock as K, asBlocks as L, type Message as M, asText as N, isAgentError as O, type Permission as P, isConfigError as Q, type Request as R, type SessionData as S, type TextBlock as T, type Usage as U, isFsError as V, WrongStackError as W, isImageBlock as X, isPluginError as Y, isSessionError as Z, isTextBlock as _, ConfigError as a, isToolError as a0, isToolResultBlock as a1, isToolUseBlock as a2, isWrongStackError as a3, toWrongStackError as a4, Context as a5, type TokenCounter as a6, type CacheStats as a7, type TodoItem as a8, ConversationState as a9, type ContextInit as aa, type ReadonlyConversationState as ab, type RunEnv as ac, type RunOptions as ad, type StateChange as ae, type StateChangeHandler as af, extractRunEnv as ag, wrapAsState as ah, type ContentBlock as b, type ErrorCode as c, type ErrorSeverity as d, type ErrorSubsystem as e, FsError as f, type MessageRole as g, PluginError as h, type Provider as i, ProviderError as j, type ProviderErrorBody as k, type Response as l, type ResumedSession as m, type RiskTier as n, SessionError as o, type SessionEvent as p, type SessionMetadata as q, type SessionStore as r, type SessionSummary as s, type SessionWriter as t, type StopReason as u, type StreamEvent as v, type ThinkingBlock as w, type Tool as x, type ToolCallContext as y, ToolError as z };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-
|
|
1
|
+
export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as DelegateHost, d as Director, e as DirectorPromptParts, f as DirectorSessionFactory, g as DirectorSessionFactoryOptions, F as FLEET_ROSTER, t as FleetCostCapError, i as FleetManager, j as FleetManagerOptions, k as FleetSpawnBudgetError, I as ICoordinator, l as IFleetManager, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, m as SubagentPromptParts, o as composeDirectorPrompt, p as composeSubagentPrompt, q as createDelegateTool, r as makeDirectorSessionFactory, s as rosterSummaryFromConfigs } from '../index-CZR0HjxM.js';
|
|
2
|
+
export { A as AgentFactory, a as AgentFactoryResult, b as AgentRunnerOptions, D as DefaultMultiAgentCoordinator, F as FleetBus, c as FleetEvent, d as FleetHandler, e as FleetUsage, f as FleetUsageAggregator, M as MultiAgentCoordinatorOptions, S as SubagentUsageSnapshot, m as makeAgentSubagentRunner } from '../multi-agent-coordinator-CCupVFqv.js';
|
|
3
|
+
export { n as BudgetExceededError, o as BudgetKind, p as BudgetLimits, s as BudgetThresholdDecision, t as BudgetThresholdHandler, u as BudgetThresholdSignal, q as BudgetUsage, r as SubagentBudget } from '../multi-agent-Cm1wYSrw.js';
|
|
4
|
+
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-CrQpYjM7.js';
|
|
5
5
|
import '../director-state-BmYi3DGA.js';
|
|
6
|
-
import '../context-
|
|
7
|
-
import '
|
|
8
|
-
import '../events-DounT6pP.js';
|
|
9
|
-
import '../index-DiIGZh5I.js';
|
|
6
|
+
import '../context-bmR0YgBm.js';
|
|
7
|
+
import '../index-BJIFLGII.js';
|
|
10
8
|
import '../logger-BMQgxvdy.js';
|
|
11
|
-
import '../system-prompt-
|
|
9
|
+
import '../system-prompt-CfgXqyv2.js';
|
|
12
10
|
import '../observability-BhnVLBLS.js';
|
|
13
|
-
import '../
|
|
14
|
-
import '../
|
|
11
|
+
import '../events-CEKFTmIY.js';
|
|
12
|
+
import '../secret-scrubber-C2YCYtkn.js';
|
|
13
|
+
import '../config-C34JRwl4.js';
|
|
15
14
|
import '../models-registry-Y2xbog0E.js';
|
|
15
|
+
import 'node:events';
|
|
@@ -633,6 +633,14 @@ var FleetUsageAggregator = class {
|
|
|
633
633
|
};
|
|
634
634
|
|
|
635
635
|
// src/types/errors.ts
|
|
636
|
+
var ERROR_CODES = {
|
|
637
|
+
// Provider
|
|
638
|
+
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
639
|
+
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
640
|
+
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
641
|
+
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
642
|
+
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
643
|
+
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR"};
|
|
636
644
|
var WrongStackError = class extends Error {
|
|
637
645
|
code;
|
|
638
646
|
subsystem;
|
|
@@ -724,14 +732,14 @@ function truncate(s, n) {
|
|
|
724
732
|
return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
|
|
725
733
|
}
|
|
726
734
|
function providerStatusToCode(status, type) {
|
|
727
|
-
if (status === 0) return
|
|
728
|
-
if (type === "rate_limit_error" || status === 429) return
|
|
729
|
-
if (type === "authentication_error" || status === 401) return
|
|
730
|
-
if (type === "overloaded_error" || status === 529) return
|
|
731
|
-
if (type === "invalid_request_error" || status === 400) return
|
|
732
|
-
if (status === 408) return
|
|
733
|
-
if (status >= 500) return
|
|
734
|
-
return
|
|
735
|
+
if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
|
|
736
|
+
if (type === "rate_limit_error" || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;
|
|
737
|
+
if (type === "authentication_error" || status === 401) return ERROR_CODES.PROVIDER_AUTH_FAILED;
|
|
738
|
+
if (type === "overloaded_error" || status === 529) return ERROR_CODES.PROVIDER_OVERLOADED;
|
|
739
|
+
if (type === "invalid_request_error" || status === 400) return ERROR_CODES.PROVIDER_INVALID_REQUEST;
|
|
740
|
+
if (status === 408) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
|
|
741
|
+
if (status >= 500) return ERROR_CODES.PROVIDER_SERVER_ERROR;
|
|
742
|
+
return ERROR_CODES.PROVIDER_INVALID_REQUEST;
|
|
735
743
|
}
|
|
736
744
|
|
|
737
745
|
// src/coordination/subagent-budget.ts
|
|
@@ -1283,6 +1291,30 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1283
1291
|
this.drainPendingAsAborted("Coordinator stopAll() drained the pending queue");
|
|
1284
1292
|
await Promise.allSettled([...this.subagents.keys()].map((id) => this.stop(id)));
|
|
1285
1293
|
}
|
|
1294
|
+
async remove(subagentId) {
|
|
1295
|
+
await this.stop(subagentId);
|
|
1296
|
+
this.subagents.delete(subagentId);
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Get current coordinator stats for monitoring/debugging.
|
|
1300
|
+
*/
|
|
1301
|
+
getStats() {
|
|
1302
|
+
let running = 0, idle = 0, stopped = 0;
|
|
1303
|
+
for (const [, entry] of this.subagents) {
|
|
1304
|
+
if (entry.status === "running") running++;
|
|
1305
|
+
else if (entry.status === "idle") idle++;
|
|
1306
|
+
else stopped++;
|
|
1307
|
+
}
|
|
1308
|
+
return {
|
|
1309
|
+
total: this.subagents.size,
|
|
1310
|
+
running,
|
|
1311
|
+
idle,
|
|
1312
|
+
stopped,
|
|
1313
|
+
inFlight: this.inFlight,
|
|
1314
|
+
pending: this.pendingTasks.length,
|
|
1315
|
+
completed: this.completedResults.length
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1286
1318
|
getStatus() {
|
|
1287
1319
|
return {
|
|
1288
1320
|
coordinatorId: this.coordinatorId,
|
|
@@ -2531,6 +2563,9 @@ var Director = class {
|
|
|
2531
2563
|
async terminateAll() {
|
|
2532
2564
|
await this.coordinator.stopAll();
|
|
2533
2565
|
}
|
|
2566
|
+
async remove(subagentId) {
|
|
2567
|
+
await this.coordinator.remove(subagentId);
|
|
2568
|
+
}
|
|
2534
2569
|
status() {
|
|
2535
2570
|
return this.coordinator.getStatus();
|
|
2536
2571
|
}
|
|
@@ -3000,6 +3035,7 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
3000
3035
|
}
|
|
3001
3036
|
}
|
|
3002
3037
|
} catch {
|
|
3038
|
+
continue;
|
|
3003
3039
|
}
|
|
3004
3040
|
}
|
|
3005
3041
|
return {
|
|
@@ -3305,8 +3341,16 @@ var DefaultSessionStore = class {
|
|
|
3305
3341
|
}
|
|
3306
3342
|
}
|
|
3307
3343
|
async resume(id) {
|
|
3308
|
-
const data = await this.load(id);
|
|
3309
3344
|
const file = path4.join(this.dir, `${id}.jsonl`);
|
|
3345
|
+
try {
|
|
3346
|
+
await fsp4.access(file, fsp4.constants.R_OK);
|
|
3347
|
+
} catch {
|
|
3348
|
+
throw new Error(
|
|
3349
|
+
`Session "${id}" not found \u2014 the session file does not exist or was deleted.`,
|
|
3350
|
+
{ cause: new Error("ENOENT") }
|
|
3351
|
+
);
|
|
3352
|
+
}
|
|
3353
|
+
const data = await this.load(id);
|
|
3310
3354
|
let handle;
|
|
3311
3355
|
try {
|
|
3312
3356
|
handle = await fsp4.open(file, "a", 384);
|