@bjorntech/key-ferry 0.1.6 → 0.1.8

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/README.md CHANGED
@@ -52,7 +52,7 @@ and preserve any unrelated entries already there:
52
52
  {
53
53
  "plugins": [
54
54
  {
55
- "package": "@bjorntech/key-ferry@0.1.5",
55
+ "package": "@bjorntech/key-ferry",
56
56
  "options": {
57
57
  "enabled": true,
58
58
  "requireStrictEgress": true,
@@ -0,0 +1,30 @@
1
+ import { Effect, Stream } from "effect";
2
+ import { type ProjectKeyFerryManagerFactory, type ProjectKeyFerryManagerOptions, type ProjectKeyFerryManagerService, type ResolvedEnvironment, type SafeStatus } from "./contracts.js";
3
+ export interface BrokerSubscription {
4
+ readonly current: Effect.Effect<SafeStatus>;
5
+ readonly changes: Stream.Stream<SafeStatus>;
6
+ }
7
+ export interface BrokerLease extends ProjectKeyFerryManagerService {
8
+ readonly subscribe: Effect.Effect<BrokerSubscription>;
9
+ readonly release: Effect.Effect<void>;
10
+ }
11
+ export interface BrokerRegistryOptions {
12
+ readonly canonicalize?: (directory: string) => Effect.Effect<string, unknown>;
13
+ readonly maxEntries?: number;
14
+ }
15
+ type BrokerResult = {
16
+ readonly status: SafeStatus;
17
+ readonly environment: ResolvedEnvironment;
18
+ };
19
+ /** A module-local broker; it deliberately does not communicate across processes. */
20
+ export declare function makeBrokerRegistry(configuration?: BrokerRegistryOptions): {
21
+ acquire: <R>(factory: ProjectKeyFerryManagerFactory<R>, options: ProjectKeyFerryManagerOptions) => Effect.Effect<BrokerLease, any, never>;
22
+ retry: (factory: ProjectKeyFerryManagerFactory<any>, options: ProjectKeyFerryManagerOptions) => Effect.Effect<BrokerResult, any, never>;
23
+ };
24
+ export declare const brokerRegistry: {
25
+ acquire: <R>(factory: ProjectKeyFerryManagerFactory<R>, options: ProjectKeyFerryManagerOptions) => Effect.Effect<BrokerLease, any, never>;
26
+ retry: (factory: ProjectKeyFerryManagerFactory<any>, options: ProjectKeyFerryManagerOptions) => Effect.Effect<BrokerResult, any, never>;
27
+ };
28
+ export type BrokerRegistry = ReturnType<typeof makeBrokerRegistry>;
29
+ export {};
30
+ //# sourceMappingURL=broker-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-registry.d.ts","sourceRoot":"","sources":["../src/broker-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,MAAM,EAON,MAAM,EACP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,6BAA6B,EAClC,KAAK,6BAA6B,EAClC,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAEhB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,WAAY,SAAQ,6BAA6B;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,KAAK,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAA;CAAE,CAAC;AA0H/F,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,aAAa,GAAE,qBAA0B;cAwPzD,CAAC,WACP,6BAA6B,CAAC,CAAC,CAAC,WAChC,6BAA6B,KACrC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC;qBA2B9B,6BAA6B,CAAC,GAAG,CAAC,WAClC,6BAA6B,KACrC,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC;EAiD3C;AAED,eAAO,MAAM,cAAc;cAnFR,CAAC,WACP,6BAA6B,CAAC,CAAC,CAAC,WAChC,6BAA6B,KACrC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC;qBA2B9B,6BAA6B,CAAC,GAAG,CAAC,WAClC,6BAA6B,KACrC,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC;CAmDM,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,347 @@
1
+ import { realpath } from "node:fs/promises";
2
+ import { Context, Deferred, Effect, Exit, Fiber, Layer, PubSub, Scope, Semaphore, Stream, } from "effect";
3
+ import { ProjectKeyFerryManager, VarlockError, } from "./contracts.js";
4
+ const adapterKeys = new Set([
5
+ "command",
6
+ "environmentKeys",
7
+ "startupTimeoutMs",
8
+ "commandTimeoutMs",
9
+ "reloadTimeoutMs",
10
+ "pollIntervalMs",
11
+ "requireStrictEgress",
12
+ ]);
13
+ function safeError(error, code) {
14
+ if (error instanceof VarlockError)
15
+ return error;
16
+ return new VarlockError({
17
+ code,
18
+ message: "Key Ferry manager operation failed",
19
+ retryable: code !== "disposed",
20
+ });
21
+ }
22
+ function stable(value) {
23
+ if (Array.isArray(value))
24
+ return `[${value.map(stable).join(",")}]`;
25
+ if (value && typeof value === "object")
26
+ return `{${Object.entries(value)
27
+ .sort(([a], [b]) => a.localeCompare(b))
28
+ .map(([key, item]) => `${JSON.stringify(key)}:${stable(item)}`)
29
+ .join(",")}}`;
30
+ return JSON.stringify(value);
31
+ }
32
+ function adapterOf(options) {
33
+ if (!options.adapter || typeof options.adapter !== "object")
34
+ throw new TypeError("manager adapter options are required");
35
+ return options.adapter;
36
+ }
37
+ function validateAdapterKeys(adapter) {
38
+ for (const key of Object.keys(adapter))
39
+ if (!adapterKeys.has(key))
40
+ throw new TypeError(`unsupported manager option: ${key}`);
41
+ }
42
+ function validateAdapterShape(adapter) {
43
+ if (!Array.isArray(adapter.command) || !Array.isArray(adapter.environmentKeys))
44
+ throw new TypeError("invalid manager adapter options");
45
+ if (adapter.environmentKeys.some((key) => typeof key !== "string"))
46
+ throw new TypeError("environmentKeys must be strings");
47
+ }
48
+ function validateOptions(options) {
49
+ const adapter = adapterOf(options);
50
+ validateAdapterKeys(adapter);
51
+ validateAdapterShape(adapter);
52
+ return adapter;
53
+ }
54
+ function keyFor(directory, options) {
55
+ const adapter = validateOptions(options);
56
+ return stable({
57
+ projectDirectory: directory,
58
+ owner: options.owner,
59
+ sessionID: options.sessionID,
60
+ command: adapter.command,
61
+ environmentKeys: [...new Set(adapter.environmentKeys)].sort(),
62
+ startupTimeoutMs: adapter.startupTimeoutMs,
63
+ commandTimeoutMs: adapter.commandTimeoutMs,
64
+ reloadTimeoutMs: adapter.reloadTimeoutMs,
65
+ pollIntervalMs: adapter.pollIntervalMs,
66
+ requireStrictEgress: adapter.requireStrictEgress,
67
+ });
68
+ }
69
+ function readinessChanged(entry, revision, ready) {
70
+ return revision !== entry.readinessRevision || ready !== entry.ready;
71
+ }
72
+ function awaitRefresh(entry, revision, ready, refresh) {
73
+ return Effect.gen(function* () {
74
+ const refreshed = yield* Deferred.await(refresh);
75
+ if (!readinessChanged(entry, revision, ready) && entry.ready === refresh)
76
+ return refreshed;
77
+ return yield* awaitCurrentReady(entry);
78
+ });
79
+ }
80
+ function awaitCurrentReady(entry) {
81
+ return Effect.gen(function* () {
82
+ while (true) {
83
+ const revision = entry.readinessRevision;
84
+ const ready = entry.ready;
85
+ const refresh = entry.refresh;
86
+ const result = yield* Deferred.await(ready);
87
+ if (readinessChanged(entry, revision, ready))
88
+ continue;
89
+ if (!refresh)
90
+ return result;
91
+ return yield* awaitRefresh(entry, revision, ready, refresh);
92
+ }
93
+ });
94
+ }
95
+ /** A module-local broker; it deliberately does not communicate across processes. */
96
+ export function makeBrokerRegistry(configuration = {}) {
97
+ const entries = new Set();
98
+ const factories = new WeakMap();
99
+ const lock = Effect.runSync(Semaphore.make(1));
100
+ const canonicalize = configuration.canonicalize ??
101
+ ((directory) => Effect.tryPromise(() => realpath(directory)));
102
+ const maxEntries = configuration.maxEntries ?? 128;
103
+ const publish = (entry, status) => {
104
+ entry.status = status;
105
+ return PubSub.publish(entry.events, status);
106
+ };
107
+ const start = (entry) => {
108
+ const operation = Effect.gen(function* () {
109
+ const context = yield* Layer.build(entry.factory.layer(entry.options)).pipe(Effect.provideService(Scope.Scope, entry.scope));
110
+ const manager = Context.get(context, ProjectKeyFerryManager);
111
+ entry.manager = manager;
112
+ const result = yield* manager.ensureReady;
113
+ yield* publish(entry, result.status);
114
+ return result;
115
+ });
116
+ return operation.pipe(Effect.catch((error) => {
117
+ const failure = safeError(error, "start_failed");
118
+ entry.failure = failure;
119
+ return publish(entry, {
120
+ phase: "failed",
121
+ projectDirectory: entry.options.projectDirectory,
122
+ generation: entry.status?.generation ?? 0,
123
+ error: failure,
124
+ }).pipe(Effect.flatMap(() => Effect.fail(failure)));
125
+ }));
126
+ };
127
+ const ensure = (entry) => Effect.gen(function* () {
128
+ if (entry.failure)
129
+ return yield* Effect.fail(entry.failure);
130
+ if (!entry.startup) {
131
+ entry.startup = yield* start(entry).pipe(Effect.forkDetach);
132
+ yield* Deferred.await(entry.ready).pipe(Effect.ignore);
133
+ }
134
+ return yield* awaitCurrentReady(entry);
135
+ });
136
+ const completeStartup = (entry, target) => Fiber.join(entry.startup).pipe(Effect.flatMap((result) => Deferred.succeed(target, result)), Effect.catch((error) => Deferred.fail(target, safeError(error, "start_failed"))), Effect.tap(() => Effect.sync(() => {
137
+ entry.attemptPending = false;
138
+ })), Effect.forkDetach);
139
+ const refreshShared = (entry) => Effect.gen(function* () {
140
+ if (entry.failure)
141
+ return yield* Effect.fail(entry.failure);
142
+ yield* Deferred.await(entry.ready);
143
+ const deferred = yield* lock.withPermit(Effect.gen(function* () {
144
+ if (entry.refresh)
145
+ return entry.refresh;
146
+ const next = yield* Deferred.make();
147
+ entry.refresh = next;
148
+ entry.readinessRevision += 1;
149
+ yield* publish(entry, {
150
+ phase: "starting",
151
+ projectDirectory: entry.options.projectDirectory,
152
+ generation: entry.status?.generation ?? 0,
153
+ });
154
+ yield* Effect.gen(function* () {
155
+ const result = yield* entry.manager.refreshReady;
156
+ yield* publish(entry, result.status);
157
+ yield* Deferred.succeed(next, result);
158
+ entry.ready = next;
159
+ entry.refresh = undefined;
160
+ }).pipe(Effect.catch((error) => {
161
+ const failure = safeError(error, "refresh_failed");
162
+ entry.failure = failure;
163
+ entry.refresh = undefined;
164
+ return publish(entry, {
165
+ phase: "failed",
166
+ projectDirectory: entry.options.projectDirectory,
167
+ generation: entry.status?.generation ?? 0,
168
+ error: failure,
169
+ }).pipe(Effect.flatMap(() => Deferred.fail(next, failure)));
170
+ }), Effect.forkIn(entry.scope));
171
+ return next;
172
+ }));
173
+ return yield* Deferred.await(deferred);
174
+ });
175
+ const getOrCreateEntry = (factory, options, directory) => Effect.gen(function* () {
176
+ const key = keyFor(directory, options);
177
+ const factoryMap = factories.get(factory) ?? new Map();
178
+ factories.set(factory, factoryMap);
179
+ const existing = factoryMap.get(key);
180
+ if (existing)
181
+ return existing;
182
+ if (entries.size >= maxEntries)
183
+ return yield* Effect.die(new Error("broker registry capacity reached"));
184
+ const entry = {
185
+ key,
186
+ options: {
187
+ ...options,
188
+ projectDirectory: directory,
189
+ },
190
+ factory,
191
+ scope: yield* Scope.make(),
192
+ events: yield* PubSub.unbounded({ replay: 1 }),
193
+ ready: yield* Deferred.make(),
194
+ leases: new Set(),
195
+ readinessRevision: 0,
196
+ disposed: false,
197
+ };
198
+ factoryMap.set(key, entry);
199
+ entries.add(entry);
200
+ return entry;
201
+ });
202
+ const disposeLeaseEntry = (entry, factoryMap, close) => Effect.gen(function* () {
203
+ if (entry.startup)
204
+ yield* Fiber.interrupt(entry.startup);
205
+ if (entry.manager)
206
+ yield* entry.manager.dispose;
207
+ yield* Scope.close(entry.scope, Exit.void);
208
+ }).pipe(Effect.catch(() => Effect.void), Effect.flatMap(() => lock.withPermit(Effect.gen(function* () {
209
+ if (entry.closing !== close)
210
+ return;
211
+ entry.manager = undefined;
212
+ entry.startup = undefined;
213
+ if (!entry.failure) {
214
+ entries.delete(entry);
215
+ factoryMap.delete(entry.key);
216
+ }
217
+ entry.closing = undefined;
218
+ yield* Deferred.succeed(close, undefined);
219
+ }))));
220
+ const acquireAttempt = (factory, options) => lock.withPermit(Effect.gen(function* () {
221
+ const directory = yield* canonicalize(options.projectDirectory).pipe(Effect.mapError(() => new TypeError("project directory does not exist")));
222
+ const factoryMap = factories.get(factory) ?? new Map();
223
+ factories.set(factory, factoryMap);
224
+ const entry = yield* getOrCreateEntry(factory, options, directory);
225
+ if (entry.closing)
226
+ return { waiting: entry.closing };
227
+ const leaseID = Symbol();
228
+ entry.leases.add(leaseID);
229
+ if (!entry.startup && !entry.failure) {
230
+ entry.attempt = entry.ready;
231
+ entry.attemptPending = true;
232
+ entry.startup = yield* start(entry).pipe(Effect.forkDetach);
233
+ yield* completeStartup(entry, entry.ready);
234
+ }
235
+ let released = false;
236
+ const managerEffect = (operation) => Effect.gen(function* () {
237
+ if (released)
238
+ return yield* Effect.die(safeError(undefined, "disposed"));
239
+ return yield* operation(entry.manager);
240
+ });
241
+ const release = Effect.gen(function* () {
242
+ const close = yield* lock.withPermit(Effect.gen(function* () {
243
+ if (released)
244
+ return undefined;
245
+ released = true;
246
+ entry.leases.delete(leaseID);
247
+ if (entry.leases.size !== 0 || entry.disposed)
248
+ return undefined;
249
+ entry.disposed = true;
250
+ const deferred = yield* Deferred.make();
251
+ entry.closing = deferred;
252
+ yield* disposeLeaseEntry(entry, factoryMap, deferred).pipe(Effect.forkDetach);
253
+ return deferred;
254
+ }));
255
+ if (close)
256
+ yield* Deferred.await(close);
257
+ });
258
+ const leaseEnsure = Effect.gen(function* () {
259
+ if (released)
260
+ return yield* Effect.fail(safeError(undefined, "disposed"));
261
+ return yield* ensure(entry);
262
+ });
263
+ const lease = {
264
+ status: Effect.sync(() => entry.status ?? {
265
+ phase: "starting",
266
+ projectDirectory: directory,
267
+ generation: 0,
268
+ }),
269
+ ensureStarted: leaseEnsure.pipe(Effect.flatMap(() => managerEffect((manager) => manager.ensureStarted))),
270
+ ensureReady: leaseEnsure,
271
+ environment: leaseEnsure.pipe(Effect.flatMap(() => managerEffect((manager) => manager.environment))),
272
+ refresh: refreshShared(entry).pipe(Effect.map(({ status }) => status)),
273
+ refreshReady: refreshShared(entry),
274
+ dispose: release,
275
+ withExclusive: (effect) => managerEffect((manager) => manager.withExclusive(effect)),
276
+ subscribe: Effect.succeed({
277
+ current: Effect.sync(() => entry.status ?? {
278
+ phase: "starting",
279
+ projectDirectory: directory,
280
+ generation: 0,
281
+ }),
282
+ changes: Stream.fromPubSub(entry.events),
283
+ }),
284
+ release,
285
+ };
286
+ return lease;
287
+ }));
288
+ const acquire = (factory, options) => Effect.gen(function* () {
289
+ const result = yield* acquireAttempt(factory, options);
290
+ if ("waiting" in result) {
291
+ yield* Deferred.await(result.waiting);
292
+ return yield* acquire(factory, options);
293
+ }
294
+ return result;
295
+ });
296
+ const retryAttempt = (factory, options) => Effect.gen(function* () {
297
+ const directory = yield* canonicalize(options.projectDirectory);
298
+ const target = yield* lock.withPermit(Effect.gen(function* () {
299
+ const entry = factories.get(factory)?.get(keyFor(directory, options));
300
+ return yield* retryEntry(entry);
301
+ }));
302
+ if ("waiting" in target)
303
+ return target;
304
+ return yield* Deferred.await(target);
305
+ });
306
+ const retry = (factory, options) => Effect.gen(function* () {
307
+ const result = yield* retryAttempt(factory, options);
308
+ if ("waiting" in result) {
309
+ yield* Deferred.await(result.waiting);
310
+ return yield* retry(factory, options);
311
+ }
312
+ return result;
313
+ });
314
+ const retryEntry = (entry) => {
315
+ if (!entry)
316
+ return Effect.fail(new VarlockError({
317
+ code: "not_ready",
318
+ message: "No failed broker entry",
319
+ retryable: false,
320
+ }));
321
+ if (entry.closing)
322
+ return Effect.succeed({ waiting: entry.closing });
323
+ if (entry.attempt && entry.attemptPending)
324
+ return Effect.succeed(entry.attempt);
325
+ if (!entry.failure)
326
+ return Effect.fail(new VarlockError({
327
+ code: "not_ready",
328
+ message: "No failed broker entry",
329
+ retryable: false,
330
+ }));
331
+ return Effect.gen(function* () {
332
+ entry.failure = undefined;
333
+ entry.disposed = false;
334
+ entry.scope = yield* Scope.make();
335
+ entry.manager = undefined;
336
+ entry.ready = yield* Deferred.make();
337
+ entry.attempt = entry.ready;
338
+ entry.attemptPending = true;
339
+ entry.startup = yield* start(entry).pipe(Effect.forkDetach);
340
+ yield* completeStartup(entry, entry.ready);
341
+ return entry.ready;
342
+ });
343
+ };
344
+ return { acquire, retry };
345
+ }
346
+ export const brokerRegistry = makeBrokerRegistry();
347
+ //# sourceMappingURL=broker-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-registry.js","sourceRoot":"","sources":["../src/broker-registry.ts"],"names":[],"mappings":"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"}
package/dist/options.d.ts CHANGED
@@ -39,6 +39,6 @@ export interface ValidatedOptions {
39
39
  * `enabled: false` explicitly means no manager layer, MCP transform, or RPC
40
40
  * is installed and existing MCP configuration is left untouched.
41
41
  */
42
- export declare function parseOptions(raw: unknown, directory?: string, resolveProjectDirectory?: boolean): ValidatedOptions;
42
+ export declare function parseOptions(raw: unknown, directory?: string, resolveDirectory?: boolean): ValidatedOptions;
43
43
  export declare function managerOptions(options: ValidatedOptions, directory: string): ProjectKeyFerryManagerOptions;
44
44
  //# sourceMappingURL=options.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,6BAA6B,EAC7B,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC;KAC1E,CAAC;CACH;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,2BAA2B,CAAC;AAE9F,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC7D,oFAAoF;IACpF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,GAAG;QACzD,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;KACzC,CAAC;CACH;AA6JD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,uBAAuB,UAAO,GAC7B,gBAAgB,CAwHlB;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,GAChB,6BAA6B,CA6B/B"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,6BAA6B,EAC7B,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC;KAC1E,CAAC;CACH;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,2BAA2B,CAAC;AAE9F,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC7D,oFAAoF;IACpF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,GAAG;QACzD,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;KACzC,CAAC;CACH;AA4QD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,UAAO,GACtB,gBAAgB,CAQlB;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,GAChB,6BAA6B,CA6B/B"}
package/dist/options.js CHANGED
@@ -126,77 +126,47 @@ function normalizeRemoteServer(name, value) {
126
126
  throw new TypeError(`servers.${name}.remote.headers must not be empty`);
127
127
  return { remote: { headers: result } };
128
128
  }
129
- /**
130
- * Decode untrusted OpenCode plugin options without touching process.env.
131
- * `enabled: false` explicitly means no manager layer, MCP transform, or RPC
132
- * is installed and existing MCP configuration is left untouched.
133
- */
134
- export function parseOptions(raw, directory, resolveProjectDirectory = true) {
135
- const input = isRecord(raw) ? raw : {};
136
- if ("failClosed" in input)
137
- throw new TypeError("failClosed is not supported; protection is always fail-closed");
138
- const enabled = input.enabled === undefined
139
- ? true
140
- : typeof input.enabled === "boolean"
141
- ? input.enabled
142
- : (() => {
143
- throw new TypeError("enabled must be a boolean");
144
- })();
145
- const resolvedProjectDirectory = input.projectDirectory === undefined
146
- ? directory === undefined
147
- ? undefined
148
- : brandProjectDirectory(directory)
149
- : (() => {
150
- if (typeof input.projectDirectory !== "string" ||
151
- input.projectDirectory.trim().length === 0) {
152
- throw new TypeError("projectDirectory must be a non-empty path");
153
- }
154
- return brandProjectDirectory(resolveProjectDirectory
155
- ? resolve(directory ?? process.cwd(), input.projectDirectory)
156
- : input.projectDirectory);
157
- })();
158
- const command = input.command === undefined ? ["varlock"] : stringArray(input.command, "command");
159
- const startupTimeoutMs = input.startupTimeoutMs === undefined
160
- ? DEFAULT_STARTUP_TIMEOUT_MS
161
- : positiveInteger(input.startupTimeoutMs, "startupTimeoutMs");
162
- const commandTimeoutMs = input.commandTimeoutMs === undefined
163
- ? DEFAULT_COMMAND_TIMEOUT_MS
164
- : positiveInteger(input.commandTimeoutMs, "commandTimeoutMs", MAX_TIMEOUT_MS);
165
- // Accept the old spelling while emitting only the manager's canonical
166
- // reloadTimeoutMs option. This avoids silently turning a refresh timeout
167
- // into a startup timeout for existing configurations.
168
- const usesLegacyReloadName = input.reloadTimeoutMs === undefined && input.refreshTimeoutMs !== undefined;
169
- const reloadInput = input.reloadTimeoutMs ?? input.refreshTimeoutMs;
170
- const reloadTimeoutMs = reloadInput === undefined
129
+ function readBoolean(input, name, fallback) {
130
+ const value = input[name];
131
+ if (value === undefined)
132
+ return fallback;
133
+ if (typeof value !== "boolean")
134
+ throw new TypeError(`${name} must be a boolean`);
135
+ return value;
136
+ }
137
+ function readTimeout(input, name, fallback, maximum) {
138
+ const value = input[name];
139
+ return value === undefined ? fallback : positiveInteger(value, name, maximum);
140
+ }
141
+ function normalizeReloadTimeout(input) {
142
+ const usesLegacyName = input.reloadTimeoutMs === undefined && input.refreshTimeoutMs !== undefined;
143
+ const value = input.reloadTimeoutMs ?? input.refreshTimeoutMs;
144
+ return value === undefined
171
145
  ? DEFAULT_RELOAD_TIMEOUT_MS
172
- : positiveInteger(reloadInput, "reloadTimeoutMs", usesLegacyReloadName ? 900_000 : MAX_RELOAD_TIMEOUT_MS);
173
- const pollIntervalMs = input.pollIntervalMs === undefined
174
- ? DEFAULT_POLL_INTERVAL_MS
175
- : positiveInteger(input.pollIntervalMs, "pollIntervalMs", 10_000);
176
- const requireStrictEgress = input.requireStrictEgress === undefined
177
- ? true
178
- : typeof input.requireStrictEgress === "boolean"
179
- ? input.requireStrictEgress
180
- : (() => {
181
- throw new TypeError("requireStrictEgress must be a boolean");
182
- })();
183
- const allowPrivateNetwork = input.allowPrivateNetwork === undefined
184
- ? false
185
- : typeof input.allowPrivateNetwork === "boolean"
186
- ? input.allowPrivateNetwork
187
- : (() => {
188
- throw new TypeError("allowPrivateNetwork must be a boolean");
189
- })();
146
+ : positiveInteger(value, "reloadTimeoutMs", usesLegacyName ? 900_000 : MAX_RELOAD_TIMEOUT_MS);
147
+ }
148
+ function normalizeServers(input) {
149
+ const rawServers = input.servers;
150
+ if (rawServers === undefined)
151
+ return Object.create(null);
152
+ if (!isRecord(rawServers))
153
+ throw new TypeError("servers must be an object");
190
154
  const servers = Object.create(null);
191
- if (input.servers !== undefined) {
192
- if (!isRecord(input.servers))
193
- throw new TypeError("servers must be an object");
194
- for (const [name, value] of Object.entries(input.servers)) {
195
- if (!name || unsafeName(name))
196
- throw new TypeError("server names must be safe non-empty names");
197
- servers[name] = normalizeServer(name, value);
198
- }
155
+ for (const [name, value] of Object.entries(rawServers)) {
156
+ if (!name || unsafeName(name))
157
+ throw new TypeError("server names must be safe non-empty names");
158
+ servers[name] = normalizeServer(name, value);
199
159
  }
160
+ return servers;
161
+ }
162
+ function normalizeAdapter(input) {
163
+ const command = input.command === undefined ? ["varlock"] : stringArray(input.command, "command");
164
+ const startupTimeoutMs = readTimeout(input, "startupTimeoutMs", DEFAULT_STARTUP_TIMEOUT_MS);
165
+ const commandTimeoutMs = readTimeout(input, "commandTimeoutMs", DEFAULT_COMMAND_TIMEOUT_MS, MAX_TIMEOUT_MS);
166
+ const reloadTimeoutMs = normalizeReloadTimeout(input);
167
+ const pollIntervalMs = readTimeout(input, "pollIntervalMs", DEFAULT_POLL_INTERVAL_MS, 10_000);
168
+ const requireStrictEgress = readBoolean(input, "requireStrictEgress", true);
169
+ const allowPrivateNetwork = readBoolean(input, "allowPrivateNetwork", false);
200
170
  const adapter = {
201
171
  command,
202
172
  startupTimeoutMs,
@@ -205,7 +175,7 @@ export function parseOptions(raw, directory, resolveProjectDirectory = true) {
205
175
  pollIntervalMs,
206
176
  requireStrictEgress,
207
177
  allowPrivateNetwork,
208
- servers,
178
+ servers: normalizeServers(input),
209
179
  };
210
180
  // Existing consumers read this property directly. It is deliberately not
211
181
  // enumerable so managerOptions can pass an exact canonical adapter shape.
@@ -214,22 +184,48 @@ export function parseOptions(raw, directory, resolveProjectDirectory = true) {
214
184
  enumerable: false,
215
185
  configurable: false,
216
186
  });
187
+ return adapter;
188
+ }
189
+ function validateProjectPath(value) {
190
+ if (typeof value !== "string" || value.trim().length === 0)
191
+ throw new TypeError("projectDirectory must be a non-empty path");
192
+ return value;
193
+ }
194
+ function resolveProjectDirectory(input, directory, resolveDirectory) {
195
+ if (input.projectDirectory === undefined) {
196
+ return directory === undefined ? undefined : brandProjectDirectory(directory);
197
+ }
198
+ const configured = validateProjectPath(input.projectDirectory);
199
+ const value = resolveDirectory ? resolve(directory ?? process.cwd(), configured) : configured;
200
+ return brandProjectDirectory(value);
201
+ }
202
+ function makeValidatedOptions(enabled, projectDirectory, adapter) {
217
203
  const manager = {
218
204
  enabled,
219
- ...(resolvedProjectDirectory === undefined
220
- ? {}
221
- : { projectDirectory: resolvedProjectDirectory }),
205
+ ...(projectDirectory === undefined ? {} : { projectDirectory }),
222
206
  adapter,
223
207
  };
224
208
  return {
225
209
  enabled,
226
- ...(resolvedProjectDirectory === undefined
227
- ? {}
228
- : { projectDirectory: resolvedProjectDirectory }),
210
+ ...(projectDirectory === undefined ? {} : { projectDirectory }),
229
211
  adapter,
230
212
  manager,
231
213
  };
232
214
  }
215
+ /**
216
+ * Decode untrusted OpenCode plugin options without touching process.env.
217
+ * `enabled: false` explicitly means no manager layer, MCP transform, or RPC
218
+ * is installed and existing MCP configuration is left untouched.
219
+ */
220
+ export function parseOptions(raw, directory, resolveDirectory = true) {
221
+ const input = isRecord(raw) ? raw : {};
222
+ if ("failClosed" in input)
223
+ throw new TypeError("failClosed is not supported; protection is always fail-closed");
224
+ const enabled = readBoolean(input, "enabled", true);
225
+ const adapter = normalizeAdapter(input);
226
+ const projectDirectory = resolveProjectDirectory(input, directory, resolveDirectory);
227
+ return makeValidatedOptions(enabled, projectDirectory, adapter);
228
+ }
233
229
  export function managerOptions(options, directory) {
234
230
  const environmentKeys = [
235
231
  ...new Set(Object.values(options.adapter.servers).flatMap((mapping) => {