agent-shim 8.15.0 → 8.17.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/README.md +5 -2
- package/dist/cli.cjs +1406 -217
- package/dist/index.cjs +376 -46
- package/dist/index.mjs +365 -45
- package/dist/types/index.d.ts +174 -30
- package/package.json +1 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -201,6 +201,10 @@ declare const CodexProviderConfigSchema: z.ZodObject<{
|
|
|
201
201
|
medium: "medium";
|
|
202
202
|
high: "high";
|
|
203
203
|
}>>;
|
|
204
|
+
login: z.ZodOptional<z.ZodEnum<{
|
|
205
|
+
"codex-cli": "codex-cli";
|
|
206
|
+
"chatgpt-sign-in": "chatgpt-sign-in";
|
|
207
|
+
}>>;
|
|
204
208
|
}, z.core.$strict>;
|
|
205
209
|
type CodexProviderConfig = z.infer<typeof CodexProviderConfigSchema>;
|
|
206
210
|
/** Either kind of provider; see `HttpProviderSchema` for the shared fields. */
|
|
@@ -299,6 +303,10 @@ declare const ProviderSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
299
303
|
medium: "medium";
|
|
300
304
|
high: "high";
|
|
301
305
|
}>>;
|
|
306
|
+
login: z.ZodOptional<z.ZodEnum<{
|
|
307
|
+
"codex-cli": "codex-cli";
|
|
308
|
+
"chatgpt-sign-in": "chatgpt-sign-in";
|
|
309
|
+
}>>;
|
|
302
310
|
}, z.core.$strict>>;
|
|
303
311
|
}, z.core.$strict>], "kind">;
|
|
304
312
|
type Provider = z.infer<typeof ProviderSchema>;
|
|
@@ -363,6 +371,14 @@ declare const DirectoryRuleSchema: z.ZodObject<{
|
|
|
363
371
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
364
372
|
}, z.core.$strict>;
|
|
365
373
|
}, z.core.$strict>]>>>;
|
|
374
|
+
launch: z.ZodOptional<z.ZodObject<{
|
|
375
|
+
skipPermissions: z.ZodOptional<z.ZodBoolean>;
|
|
376
|
+
remoteControl: z.ZodOptional<z.ZodBoolean>;
|
|
377
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
378
|
+
headroom: z.ZodOptional<z.ZodBoolean>;
|
|
379
|
+
trackUsage: z.ZodOptional<z.ZodBoolean>;
|
|
380
|
+
claudeVersion: z.ZodOptional<z.ZodString>;
|
|
381
|
+
}, z.core.$strict>>;
|
|
366
382
|
$schema: z.ZodOptional<z.ZodString>;
|
|
367
383
|
extends: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
368
384
|
categories: z.ZodOptional<z.ZodPipe<z.ZodObject<{
|
|
@@ -378,14 +394,6 @@ declare const DirectoryRuleSchema: z.ZodObject<{
|
|
|
378
394
|
knowledge?: boolean | undefined;
|
|
379
395
|
settings?: boolean | undefined;
|
|
380
396
|
}>>>;
|
|
381
|
-
launch: z.ZodOptional<z.ZodObject<{
|
|
382
|
-
skipPermissions: z.ZodOptional<z.ZodBoolean>;
|
|
383
|
-
remoteControl: z.ZodOptional<z.ZodBoolean>;
|
|
384
|
-
provider: z.ZodOptional<z.ZodString>;
|
|
385
|
-
headroom: z.ZodOptional<z.ZodBoolean>;
|
|
386
|
-
trackUsage: z.ZodOptional<z.ZodBoolean>;
|
|
387
|
-
claudeVersion: z.ZodOptional<z.ZodString>;
|
|
388
|
-
}, z.core.$strict>>;
|
|
389
397
|
path: z.ZodString;
|
|
390
398
|
configProfile: z.ZodOptional<z.ZodString>;
|
|
391
399
|
identity: z.ZodOptional<z.ZodString>;
|
|
@@ -412,6 +420,14 @@ declare const DirectoryRulesSchema: z.ZodObject<{
|
|
|
412
420
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
413
421
|
}, z.core.$strict>;
|
|
414
422
|
}, z.core.$strict>]>>>;
|
|
423
|
+
launch: z.ZodOptional<z.ZodObject<{
|
|
424
|
+
skipPermissions: z.ZodOptional<z.ZodBoolean>;
|
|
425
|
+
remoteControl: z.ZodOptional<z.ZodBoolean>;
|
|
426
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
427
|
+
headroom: z.ZodOptional<z.ZodBoolean>;
|
|
428
|
+
trackUsage: z.ZodOptional<z.ZodBoolean>;
|
|
429
|
+
claudeVersion: z.ZodOptional<z.ZodString>;
|
|
430
|
+
}, z.core.$strict>>;
|
|
415
431
|
$schema: z.ZodOptional<z.ZodString>;
|
|
416
432
|
extends: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
417
433
|
categories: z.ZodOptional<z.ZodPipe<z.ZodObject<{
|
|
@@ -427,14 +443,6 @@ declare const DirectoryRulesSchema: z.ZodObject<{
|
|
|
427
443
|
knowledge?: boolean | undefined;
|
|
428
444
|
settings?: boolean | undefined;
|
|
429
445
|
}>>>;
|
|
430
|
-
launch: z.ZodOptional<z.ZodObject<{
|
|
431
|
-
skipPermissions: z.ZodOptional<z.ZodBoolean>;
|
|
432
|
-
remoteControl: z.ZodOptional<z.ZodBoolean>;
|
|
433
|
-
provider: z.ZodOptional<z.ZodString>;
|
|
434
|
-
headroom: z.ZodOptional<z.ZodBoolean>;
|
|
435
|
-
trackUsage: z.ZodOptional<z.ZodBoolean>;
|
|
436
|
-
claudeVersion: z.ZodOptional<z.ZodString>;
|
|
437
|
-
}, z.core.$strict>>;
|
|
438
446
|
path: z.ZodString;
|
|
439
447
|
configProfile: z.ZodOptional<z.ZodString>;
|
|
440
448
|
identity: z.ZodOptional<z.ZodString>;
|
|
@@ -462,6 +470,14 @@ declare const PortableConfigSchema: z.ZodObject<{
|
|
|
462
470
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
463
471
|
}, z.core.$strict>;
|
|
464
472
|
}, z.core.$strict>]>>>;
|
|
473
|
+
launch: z.ZodOptional<z.ZodObject<{
|
|
474
|
+
skipPermissions: z.ZodOptional<z.ZodBoolean>;
|
|
475
|
+
remoteControl: z.ZodOptional<z.ZodBoolean>;
|
|
476
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
477
|
+
headroom: z.ZodOptional<z.ZodBoolean>;
|
|
478
|
+
trackUsage: z.ZodOptional<z.ZodBoolean>;
|
|
479
|
+
claudeVersion: z.ZodOptional<z.ZodString>;
|
|
480
|
+
}, z.core.$strict>>;
|
|
465
481
|
$schema: z.ZodOptional<z.ZodString>;
|
|
466
482
|
extends: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
467
483
|
categories: z.ZodOptional<z.ZodPipe<z.ZodObject<{
|
|
@@ -477,14 +493,6 @@ declare const PortableConfigSchema: z.ZodObject<{
|
|
|
477
493
|
knowledge?: boolean | undefined;
|
|
478
494
|
settings?: boolean | undefined;
|
|
479
495
|
}>>>;
|
|
480
|
-
launch: z.ZodOptional<z.ZodObject<{
|
|
481
|
-
skipPermissions: z.ZodOptional<z.ZodBoolean>;
|
|
482
|
-
remoteControl: z.ZodOptional<z.ZodBoolean>;
|
|
483
|
-
provider: z.ZodOptional<z.ZodString>;
|
|
484
|
-
headroom: z.ZodOptional<z.ZodBoolean>;
|
|
485
|
-
trackUsage: z.ZodOptional<z.ZodBoolean>;
|
|
486
|
-
claudeVersion: z.ZodOptional<z.ZodString>;
|
|
487
|
-
}, z.core.$strict>>;
|
|
488
496
|
configProfile: z.ZodOptional<z.ZodString>;
|
|
489
497
|
identity: z.ZodOptional<z.ZodString>;
|
|
490
498
|
when: z.ZodOptional<z.ZodObject<{
|
|
@@ -700,6 +708,8 @@ interface LayoutPaths {
|
|
|
700
708
|
readonly frontdoorCaKeyFile: string;
|
|
701
709
|
/** Directory of combined CA bundles: a parent environment's own NODE_EXTRA_CA_CERTS (for a routed child) or HEADROOM_CA_BUNDLE (for the headroom daemon) file plus the front door's CA, one file per distinct combination, for processes that must keep trusting both. */
|
|
702
710
|
readonly frontdoorCaBundlesDir: string;
|
|
711
|
+
/** Path to the Sign in with ChatGPT file (the host id and, once signed in, the grant, mode 0600): whoever can read it can spend the person's ChatGPT plan until it is signed out. */
|
|
712
|
+
readonly chatgptSignInFile: string;
|
|
703
713
|
/** Path to the front door's state.json: its supervisor pid, its port, and the sticky port it last served on. */
|
|
704
714
|
readonly frontdoorStateFile: string;
|
|
705
715
|
/** Path to the exclusive-create marker guarding "who spawns the front-door supervisor" so concurrent launches start at most one. */
|
|
@@ -3144,6 +3154,11 @@ interface RunDoctorParams {
|
|
|
3144
3154
|
readonly installedClaudeVersions?: readonly string[];
|
|
3145
3155
|
/** Where cached credentials live. Omit to leave a credential cache's age out of the identity and provider findings; with it, a block that caches reports whether it holds an entry, how old it is and whether it has expired, never the token. */
|
|
3146
3156
|
readonly credentialCache?: CredentialCacheEnv;
|
|
3157
|
+
/** The Sign in with ChatGPT file. Omit to leave it out of the findings; with it, a codex provider whose `codex.login` is `chatgpt-sign-in` warns when there is no usable sign-in to spend. */
|
|
3158
|
+
readonly chatgptSignIn?: {
|
|
3159
|
+
readonly path: string;
|
|
3160
|
+
readonly raw: string | undefined;
|
|
3161
|
+
};
|
|
3147
3162
|
readonly identities: readonly DoctorIdentityInput[];
|
|
3148
3163
|
readonly configProfiles: readonly DoctorConfigProfileInput[];
|
|
3149
3164
|
readonly providers: readonly DoctorProviderInput[];
|
|
@@ -3337,6 +3352,111 @@ declare const UsageSnapshotSchema: z.ZodObject<{
|
|
|
3337
3352
|
}, z.core.$strict>;
|
|
3338
3353
|
type UsageSnapshot = z.infer<typeof UsageSnapshotSchema>;
|
|
3339
3354
|
|
|
3355
|
+
/**
|
|
3356
|
+
* The Zod schemas of the door's event backbone: the envelope every source-tagged event carries, the source filter the subscription takes, and the launch lifecycle's own payload family. The backbone's TypeScript shapes in `eventHub.ts` and `launchEvents.ts` stay the implementations' types; these schemas are what the typed API's contract validates through, and because the backbone's publishers produce those interfaces' values, a drift between a schema and its interface fails the API's own output validation (exercised by its tests) rather than shipping silently. This module deliberately imports nothing from oRPC: it is a plain Zod leaf, so the backbone and its publishers can share it without depending on the API layer.
|
|
3357
|
+
*/
|
|
3358
|
+
/** The source tag the Remote Control client stream's events carry on the backbone: the first publisher, wrapped rather than rewritten, so its own surfaces keep their shapes untouched. */
|
|
3359
|
+
declare const DOOR_EVENT_SOURCE_RC = "rc";
|
|
3360
|
+
/** The source tag every launch lifecycle event carries: the registry's own register, prune and end moments, the first publisher the door itself owns. */
|
|
3361
|
+
declare const LAUNCH_EVENT_SOURCE = "launch";
|
|
3362
|
+
/** One event on the door's backbone, exactly as the subscription yields it: the source that published it, the sequence the backbone assigned that source, and the publisher's own payload carried verbatim for the consumer to narrow. */
|
|
3363
|
+
declare const DoorEventSchema: z.ZodObject<{
|
|
3364
|
+
source: z.ZodString;
|
|
3365
|
+
sequence: z.ZodNumber;
|
|
3366
|
+
payload: z.ZodUnknown;
|
|
3367
|
+
}, z.core.$strict>;
|
|
3368
|
+
/** One event on the backbone, as the TypeScript every in-process consumer handles it (the schema's own inferred type, so the two cannot drift). */
|
|
3369
|
+
type DoorEvent = z.output<typeof DoorEventSchema>;
|
|
3370
|
+
/**
|
|
3371
|
+
* The query the backbone's subscription takes: optionally named sources, every source when omitted. An empty list is refused rather than read as "everything" or as "nothing", because a caller building it programmatically has almost certainly failed to append, and silently streaming no events at all is the one answer that would never be noticed.
|
|
3372
|
+
*/
|
|
3373
|
+
declare const DoorEventSourceQuerySchema: z.ZodObject<{
|
|
3374
|
+
sources: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3375
|
+
}, z.core.$strict>;
|
|
3376
|
+
/**
|
|
3377
|
+
* One launch lifecycle event: what the session registry already records (a launch registering, a capability pruned because its launcher died, a session ending by its launcher's own exit hook), observed at the tick that saw it. `startedAt` is the registry record's own value; `observedAt` is when the door observed the change, which is the tick, not the change itself.
|
|
3378
|
+
*/
|
|
3379
|
+
declare const LaunchLifecycleEventSchema: z.ZodObject<{
|
|
3380
|
+
kind: z.ZodEnum<{
|
|
3381
|
+
registered: "registered";
|
|
3382
|
+
pruned: "pruned";
|
|
3383
|
+
ended: "ended";
|
|
3384
|
+
}>;
|
|
3385
|
+
pid: z.ZodNumber;
|
|
3386
|
+
startedAt: z.ZodNumber;
|
|
3387
|
+
observedAt: z.ZodNumber;
|
|
3388
|
+
}, z.core.$strict>;
|
|
3389
|
+
/** One launch lifecycle event, as the TypeScript the publisher emits and its consumers handle. */
|
|
3390
|
+
type LaunchLifecycleEvent = z.output<typeof LaunchLifecycleEventSchema>;
|
|
3391
|
+
|
|
3392
|
+
/**
|
|
3393
|
+
* The door's event backbone: the publisher/subscriber machinery the Remote Control client stream's fan-out first proved, generalised so any door-wide source can publish and any consumer can subscribe once instead of each source growing its own channel. A publisher registers under a source tag and publishes payloads; the backbone stamps each event with its source's own monotonic sequence and delivers to every matching subscriber synchronously, in publication order. A source that carries its own ordering on the wire (the Remote Control envelope's per-session `sequence_num`, the number its resume rule resumes after) keeps it inside the payload, verbatim: the backbone's sequence is deliberately not any protocol's number.
|
|
3394
|
+
*
|
|
3395
|
+
* The Remote Control client stream is the first publisher, through `rcFanoutOnDoorHub` below: the wrap publishes every event the fan-out is handed onto the backbone beside the fan-out's own delivery, and moves nothing about how Remote Control events flow, so the fan-out's existing subscribers (the tracker's filing rides the same publish, the typed API's subscription and the watch verb read the same subscribe) never know the backbone exists. The launch lifecycle is the first publisher the door itself owns (see `launchEvents.ts`).
|
|
3396
|
+
*
|
|
3397
|
+
* Slow consumers are bounded where the backbone bridges its synchronous publish to a pull: `stream` holds at most `DOOR_EVENT_BUFFER_EVENTS` events per subscriber and drops the oldest past that, whose absence the consumer detects by the gap it leaves in the source's sequence, the same contract the Remote Control subscription's bridge keeps. Everything here is in memory only and dies with the door process; the backbone holds no replay, so a subscriber that arrives late simply does not see earlier events.
|
|
3398
|
+
*/
|
|
3399
|
+
/**
|
|
3400
|
+
* How many events one stream subscriber's bridge holds while the consumer behind it has not pulled them. Not a fresh number: it is the bound oRPC's own `EventPublisher` documents as its default for exactly this slow-consumer case (a buffer without one grows without limit), and a full buffer drops the oldest event, whose absence a consumer detects by the gap it leaves in the sequence numbers.
|
|
3401
|
+
*/
|
|
3402
|
+
declare const DOOR_EVENT_BUFFER_EVENTS = 100;
|
|
3403
|
+
/** One registered source: the tag its events carry and the publish call the source owns. */
|
|
3404
|
+
interface DoorEventPublisher {
|
|
3405
|
+
/** The source's tag, the name a subscriber's filter names. */
|
|
3406
|
+
readonly source: string;
|
|
3407
|
+
/** Publishes one event: stamps the source's next sequence and delivers it to every matching subscriber synchronously, in publication order. */
|
|
3408
|
+
readonly publish: (payload: unknown) => void;
|
|
3409
|
+
}
|
|
3410
|
+
/** The pull side of one subscription: a bounded bridge from the backbone's synchronous publish to a consumer that asks for events one at a time. */
|
|
3411
|
+
interface DoorEventStream {
|
|
3412
|
+
/**
|
|
3413
|
+
* Resolves the next event the bridge holds, waiting for one to arrive when it holds none, and resolves done once the stream is closed and drained. Serves one pull at a time: a caller that pulls concurrently forfeits the earlier pull's wake, so the contract is a serial loop (the shape every consumer of this type, the typed API's subscription included, already has).
|
|
3414
|
+
*/
|
|
3415
|
+
readonly next: () => Promise<IteratorResult<DoorEvent>>;
|
|
3416
|
+
/** Stops the delivery: detaches from the backbone and resolves a waiting pull (or the next one) with done. The buffer's contents are abandoned, not delivered. */
|
|
3417
|
+
readonly close: () => void;
|
|
3418
|
+
}
|
|
3419
|
+
/** The door's event backbone. One per door process; everything it holds dies with it. */
|
|
3420
|
+
interface DoorEventHub {
|
|
3421
|
+
/**
|
|
3422
|
+
* Registers one source and returns its publisher. Idempotent in the tag: a second registration of the same name publishes through the same sequence counter, so two handles of one source cannot split its ordering. The set of registered names is fixed when the door's assembly finishes, which is what the subscription's filter validation reads.
|
|
3423
|
+
*/
|
|
3424
|
+
readonly publisher: (source: string) => DoorEventPublisher;
|
|
3425
|
+
/** Adds one listener, told every event whose source it matches; `undefined` listens to every source. Returns the detach function. */
|
|
3426
|
+
readonly subscribe: (sources: readonly string[] | undefined, listener: (event: DoorEvent) => void) => () => void;
|
|
3427
|
+
/** Opens one pull subscription over the backbone with the bounded drop-oldest bridge; `undefined` subscribes to every source. */
|
|
3428
|
+
readonly stream: (sources: readonly string[] | undefined) => DoorEventStream;
|
|
3429
|
+
/** Every registered source tag, sorted, as the subscription's filter validation names them. */
|
|
3430
|
+
readonly sources: () => readonly string[];
|
|
3431
|
+
}
|
|
3432
|
+
/** Creates the backbone: plain synchronous listener sets, one per source plus one for every-source listeners, and a monotonic sequence counter per source. */
|
|
3433
|
+
declare function createDoorEventHub(): DoorEventHub;
|
|
3434
|
+
/**
|
|
3435
|
+
* Wraps one Remote Control fan-out so the client read stream becomes the backbone's first publisher: the stream hub the wrap is handed to publishes through it, every event reaching the fan-out exactly as before (its subscribers, the tracker's filing included, are served first) and the backbone beside it, source-tagged `rc` with the backbone's own sequence while the envelope's per-session `sequence_num` rides inside the payload verbatim. Subscribing through the wrap is the fan-out's own subscribe, untouched, so the Remote Control surfaces that read it keep their session filtering and their shapes.
|
|
3436
|
+
*/
|
|
3437
|
+
declare function rcFanoutOnDoorHub(fanout: RcEventFanout, hub: DoorEventHub): RcEventFanout;
|
|
3438
|
+
|
|
3439
|
+
/**
|
|
3440
|
+
* The door-wide events surface of the typed API: `events.subscribe`, the generalisation of `rc.subscribe`'s pattern from one source to the backbone's every source. A consumer (a statusline, a watchdog, an automation) presents the same per-generation owner-only control token, asks for every source or names the ones it wants, and receives one stream of source-tagged events, SSE-framed by oRPC's event iterator with the backbone's per-source sequence as the SSE event id, so a slow consumer that had events dropped by its bounded bridge sees the gap in that number exactly as a Remote Control subscriber sees one in the envelope's own.
|
|
3441
|
+
*
|
|
3442
|
+
* The router this module builds is mounted by `controlApi.ts` beside the Remote Control and control-plane routers on the one prefix the provider listener already serves, so every surface of the door's typed API shares one token gate, one body cap and one transport.
|
|
3443
|
+
*/
|
|
3444
|
+
/** Everything the events surface needs: the token every typed door API procedure demands, and the backbone whose events the subscription yields. */
|
|
3445
|
+
interface DoorEventsApiDeps {
|
|
3446
|
+
/** This generation's control token: the same value the Remote Control router checks, since one mount serves both. */
|
|
3447
|
+
readonly expectedToken: string;
|
|
3448
|
+
/** The door's event backbone: the publisher registry every source registers on and this subscription reads. */
|
|
3449
|
+
readonly events: DoorEventHub;
|
|
3450
|
+
}
|
|
3451
|
+
/** Builds the events router: one streaming procedure behind the control-token middleware. */
|
|
3452
|
+
declare function createEventsApiRouter(deps: DoorEventsApiDeps): {
|
|
3453
|
+
events: {
|
|
3454
|
+
subscribe: _orpc_server.DecoratedProcedure<_orpc_server.MergedInitialContext<DoorApiContext & Record<never, never>, DoorApiContext, DoorApiContext>, any, zod.ZodObject<{
|
|
3455
|
+
sources: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
|
|
3456
|
+
}, zod_v4_core.$strict>, any, Record<never, never>, Record<never, never>>;
|
|
3457
|
+
};
|
|
3458
|
+
};
|
|
3459
|
+
|
|
3340
3460
|
/** The record held in one front-door session-registry file: the launcher's pid plus the per-launch capability token its child presents on every request. */
|
|
3341
3461
|
declare const FrontDoorSessionSchema: z.ZodObject<{
|
|
3342
3462
|
pid: z.ZodNumber;
|
|
@@ -3395,7 +3515,7 @@ declare function formatFrontDoorStatus(status: FrontDoorStatus, caCertPath: stri
|
|
|
3395
3515
|
* - `frontdoor.*` returns what `agent-shim frontdoor status` returns: the supervisor state, its liveness, the session registry's launches and the headroom hop.
|
|
3396
3516
|
* - `check.run` and `doctor.run` return the reports `agent-shim check` and `agent-shim doctor` print, as data, `check.run` parameterised by an absolute directory path.
|
|
3397
3517
|
*
|
|
3398
|
-
* Read-only by design: identity, configuration-profile, provider, pool and directory-rule management stay CLI-side, and adding writes over this mount is a decision of its own rather than a gap here. `createDoorApiNodeHandler` mounts these routers beside the Remote Control router on the one prefix the provider listener already serves, so a consumer dials one address with one token for the whole door.
|
|
3518
|
+
* Read-only by design: identity, configuration-profile, provider, pool and directory-rule management stay CLI-side, and adding writes over this mount is a decision of its own rather than a gap here. `createDoorApiNodeHandler` mounts these routers and the door-wide `events.subscribe` router beside the Remote Control router on the one prefix the provider listener already serves, so a consumer dials one address with one token for the whole door.
|
|
3399
3519
|
*/
|
|
3400
3520
|
/** Everything the control-plane procedures need, injected so they serve against fakes in tests exactly as the door's real wiring serves against this machine. */
|
|
3401
3521
|
interface ControlApiDeps {
|
|
@@ -3883,11 +4003,16 @@ declare function createControlApiRouter(deps: ControlApiDeps): {
|
|
|
3883
4003
|
type ControlApiRouter = ReturnType<typeof createControlApiRouter>;
|
|
3884
4004
|
/** The control plane alone as a client sees it: every call presents the control token, over TLS trusting only the CA file the door's own state names. */
|
|
3885
4005
|
type ControlApiClient = RouterClient<ControlApiRouter>;
|
|
3886
|
-
/** Everything the door's whole typed API needs: the Remote Control operations
|
|
3887
|
-
interface DoorApiDeps extends RcApiDeps, ControlApiDeps {
|
|
4006
|
+
/** Everything the door's whole typed API needs: the Remote Control operations, the control-plane reads and the door-wide event stream, one deps object because one mount serves them under one token. */
|
|
4007
|
+
interface DoorApiDeps extends RcApiDeps, ControlApiDeps, DoorEventsApiDeps {
|
|
3888
4008
|
}
|
|
3889
|
-
/** Builds the door's whole typed API: the Remote Control router
|
|
4009
|
+
/** Builds the door's whole typed API: the Remote Control router, the control-plane routers and the events router beside them, one object for the one handler the provider listener mounts. */
|
|
3890
4010
|
declare function createDoorApiRouter(deps: DoorApiDeps): {
|
|
4011
|
+
events: {
|
|
4012
|
+
subscribe: _orpc_server.DecoratedProcedure<_orpc_server.MergedInitialContext<DoorApiContext & Record<never, never>, DoorApiContext, DoorApiContext>, any, zod.ZodObject<{
|
|
4013
|
+
sources: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
|
|
4014
|
+
}, zod_v4_core.$strict>, any, Record<never, never>, Record<never, never>>;
|
|
4015
|
+
};
|
|
3891
4016
|
usage: {
|
|
3892
4017
|
list: _orpc_server.DecoratedProcedure<_orpc_server.MergedInitialContext<DoorApiContext & Record<never, never>, DoorApiContext, DoorApiContext>, any, Schema<unknown, unknown>, zod.ZodObject<{
|
|
3893
4018
|
snapshots: zod.ZodReadonly<zod.ZodArray<zod.ZodObject<{
|
|
@@ -4673,6 +4798,21 @@ declare const DoctorRunOutputSchema: z.ZodObject<{
|
|
|
4673
4798
|
}, z.core.$strict>>>;
|
|
4674
4799
|
}, z.core.$strict>;
|
|
4675
4800
|
|
|
4801
|
+
/**
|
|
4802
|
+
* The launch lifecycle publisher: the door's first event source of its own, turning the session registry the supervisor already reads each tick into source-tagged backbone events. A launch registering, a capability pruned because its launcher died, and a session ending by its launcher's own exit hook are all registry facts before they are events, which is why the publisher emits nothing of its own: it is fed the tick's listing and the pids the prune removed, and publishes the diff against the previous tick.
|
|
4803
|
+
*
|
|
4804
|
+
* The first observation establishes the baseline and emits nothing, because a session the registry already held registered before this door generation began and the door never observed the moment; the backbone holds no replay in any case. Within one observation the departures publish before the arrivals (the prune the tick performs, then the ends the tick discovered, then the registrations), each group in the registry's own pid order, the one ordering the facts genuinely carry; anything finer happened between ticks and no claim about it would be honest.
|
|
4805
|
+
*/
|
|
4806
|
+
/** Everything the launch lifecycle publisher needs: the backbone it publishes on and the clock its events are observed at. */
|
|
4807
|
+
interface LaunchEventPublisher {
|
|
4808
|
+
/**
|
|
4809
|
+
* Reports one tick's registry facts: the sessions the tick's listing saw (taken before the prune, so a pruned launch's record is still there to name its start time) and the pids the tick's prune removed. Publishes the diff against the previous observation; the first observation is the baseline and publishes nothing.
|
|
4810
|
+
*/
|
|
4811
|
+
readonly observe: (sessions: readonly FrontDoorSessionSummary[], pruned: readonly number[]) => void;
|
|
4812
|
+
}
|
|
4813
|
+
/** Creates the launch lifecycle publisher. One per door process, fed by the supervisor's tick. */
|
|
4814
|
+
declare function createLaunchEventPublisher(hub: DoorEventHub, now: () => number): LaunchEventPublisher;
|
|
4815
|
+
|
|
4676
4816
|
/**
|
|
4677
4817
|
* The self-hosted Remote Control service: the door serving, locally, the CCR surface it normally only observes (ExaDev/agent-shim#207). When the mode is on, a Claude Code session activates Remote Control against this surface and is controlled through it with no Anthropic credential anywhere: the door answers the session family itself instead of piping it to the real API host, so the `cse_` sessions, their sequence numbers, their worker and client streams and their event writes all live on this machine.
|
|
4678
4818
|
*
|
|
@@ -4847,6 +4987,10 @@ interface FrontDoorSupervisorPorts {
|
|
|
4847
4987
|
* Stops the Remote Control stream hub: persists every live attachment's sequence cursor synchronously, then frees the dials. Called exactly once on every exit the supervisor owns, after every listener it started is down (a live listener could still settle an observed Remote Control exchange, and the reconcile that follows would re-attach a stream the close had just ended) and before the final state write and the process's exit.
|
|
4848
4988
|
*/
|
|
4849
4989
|
readonly closeRcStreamHub: () => void;
|
|
4990
|
+
/**
|
|
4991
|
+
* Reports one tick's session-registry facts to the door's event backbone: the sessions the tick's listing saw (taken before the prune, so a pruned launch's record is still there to name its start time) and the pids the tick's prune removed. The launch lifecycle publisher turns the diff between ticks into source-tagged events; the listing is also this loop's own idle input, so the two read one fact instead of two.
|
|
4992
|
+
*/
|
|
4993
|
+
readonly observeLaunchRegistry: (sessions: readonly FrontDoorSessionSummary[], pruned: readonly number[]) => void;
|
|
4850
4994
|
readonly log: (line: string) => void;
|
|
4851
4995
|
}
|
|
4852
4996
|
/** Options for `runFrontDoorSupervisor`. */
|
|
@@ -5540,5 +5684,5 @@ interface PrepareClaudeLaunchOptions {
|
|
|
5540
5684
|
*/
|
|
5541
5685
|
declare function prepareClaudeLaunch(options: PrepareClaudeLaunchOptions): LaunchPlan;
|
|
5542
5686
|
|
|
5543
|
-
export { AMBIENT_CREDENTIAL_VARS, CHECK_CREDENTIAL_APPLIES, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CheckReportJsonSchema, CheckRunInputSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, DoctorFindingSchema, DoctorRunOutputSchema, EXIT_FAILURE, EXIT_USAGE, EffectiveWindowSchema, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorSessionStatusSchema, FrontDoorSessionsOutputSchema, FrontDoorStartError, FrontDoorStateSchema, FrontDoorStatusOutputSchema, GlobalConfigSchema, HeadroomSocketTargetSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LaunchRefusedError, LegacyProviderFileError, PROMPT_CACHE_TTL_MS, PlanClassSchema, PoolNameSchema, PoolNotFoundError, PoolPickReportSchema, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, RC_IDLE_EXPIRY_MS, RC_ORPC_PATH_PREFIX, RC_PENDING_DEADLINE_MS, RC_PERMISSION_MODES, RC_REQUEST_PARSE_CAP_BYTES, RC_SELF_HOST_ENV, RC_SELF_HOST_KEEPALIVE_MS, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE, RC_SELF_HOST_RETENTION_MS, RC_SELF_HOST_SCOPE_LIST, RC_SELF_HOST_WORKER_JWT_TTL_SECONDS, RC_SESSIONS_PATH_PREFIX, RC_STREAM_BACKOFF_MS, ROUTED_PATH_PREFIX, RcPermissionModeSchema, RcStreamEnvelopeSchema, RcStreamEventSchema, UsageError, UsageListOutputSchema, UsageSnapshotError, UsageSnapshotSchema, UsageWindowsInputSchema, UsageWindowsOutputSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, buildEntryFacts, buildLayoutPaths, buildRcControlResponsePayload, buildRcEventWriteBody, buildRcInterruptPayload, buildRcSetModelPayload, buildRcSetPermissionModePayload, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, collectFrontDoorStatus, collectPoolPick, createControlApiRouter, createDoorApiNodeHandler, createDoorApiRouter, createLeafCache, createProfile, createRcApiNodeHandler, createRcApiRouter, createRcControlHandler, createRcCredentialStore, createRcEventFanout, createRcSelfHostSurface, createRcSessionTracker, createRcStreamHub, createSseParser, describeProviderEndpoint, detectAmbientCredential, doorApiAuth, doorApiNodeHandlerOf, effectiveWindow, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, evaluateWhen, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, formatFrontDoorStatus, forwardableHeaders, frontDoorApiClient, frontDoorApiLink, frontDoorRcApiClient, frontDoorRcControl, generateCa, headroomSocketTarget, identityExists, injectRcUserMessage, interruptRcSession, isIdentityDirectoryName, isInterceptedHost, isRcPermissionMode, lateRcEventDial, lateRcStreamDial, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, matchBranch, mintLeaf, mintRcSelfHostCredential, observingRoutedRoute, parseConnectTarget, parseRcStreamEnvelope, planOf, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rankPool, rcEventWriteResultFromAnswer, rcObserverAsPassthrough, rcSelfHostFromEnv, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readRcSelfHostRecord, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, realRcStreamDial, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runLauncher, runSupervisor, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, setRcSessionModel, setRcSessionPermissionMode, snapshotPath, spawnClaude, startConnectServer, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
|
|
5544
|
-
export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, Candidate, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CheckReportJson, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConditionContext, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectLocalSurface, ConnectServerConfig, ConnectServerHandle, ConnectTarget, ControlApiClient, ControlApiDeps, ControlApiRouter, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, DoorApiClient, DoorApiContext, DoorApiDeps, DoorApiRouter, EffectiveWindow, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSessionStatus, FrontDoorStatus, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, PlanClass, Pool, PoolMember, PoolPickReport, PoolRanking, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, RankPoolInput, RcAnswerDecision, RcAnswerDeps, RcApiClient, RcApiDeps, RcApiRouter, RcControlAnswer, RcControlHandlerDeps, RcControlRequestDeps, RcControlTransport, RcCredentialStore, RcDialAnswer, RcDialTarget, RcEventDial, RcEventFanout, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcPermissionMode, RcPresenceAnswer, RcSelfHostCredentialRecord, RcSelfHostDeps, RcSelfHostMintResult, RcSelfHostSurface, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcStreamAnswer, RcStreamDial, RcStreamEnvelope, RcStreamEvent, RcStreamHub, RcStreamHubDeps, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunLauncherParams, RunSupervisorOptions, SpawnClaudeParams, SseParsedEvent, StickyPick, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageReadFs, UsageSnapshot, WhenCondition, WhenEvaluation };
|
|
5687
|
+
export { AMBIENT_CREDENTIAL_VARS, CHECK_CREDENTIAL_APPLIES, CONNECT_INTERCEPT_HOST, CONNECT_INTERCEPT_HOSTS, CONNECT_LIMITS, CONTROL_PATH_PREFIX, CategoryClassificationOverlaySchema, CategoryClassificationSchema, CategoryMapSchema, CheckReportJsonSchema, CheckRunInputSchema, CliError, ConfigProfileSchema, CredentialCacheSchema, CredentialSchema, CredentialSourceSchema, DOOR_EVENT_BUFFER_EVENTS, DOOR_EVENT_SOURCE_RC, DirectoryRuleAlreadyExistsError, DirectoryRuleMissingTargetError, DirectoryRuleNotFoundError, DirectoryRuleSchema, DirectoryRulesSchema, DoctorFindingSchema, DoctorRunOutputSchema, DoorEventSchema, DoorEventSourceQuerySchema, EXIT_FAILURE, EXIT_USAGE, EffectiveWindowSchema, EntryValueSchema, FARM_MANIFEST_FILENAME, FrontDoorSessionStatusSchema, FrontDoorSessionsOutputSchema, FrontDoorStartError, FrontDoorStateSchema, FrontDoorStatusOutputSchema, GlobalConfigSchema, HeadroomSocketTargetSchema, HeadroomStartError, IdentityAlreadyExistsError, IdentityNotFoundError, IdentitySchema, InvalidCategoryNameError, InvalidIdentityNameError, InvalidProviderNameError, LAUNCH_EVENT_SOURCE, LaunchLifecycleEventSchema, LaunchRefusedError, LegacyProviderFileError, PROMPT_CACHE_TTL_MS, PlanClassSchema, PoolNameSchema, PoolNotFoundError, PoolPickReportSchema, PoolSchema, PortableConfigSchema, ProfileAlreadyExistsError, ProfileNotFoundError, ProviderAlreadyExistsError, ProviderKindMismatchError, ProviderNotFoundError, ProviderSchema, RC_IDLE_EXPIRY_MS, RC_ORPC_PATH_PREFIX, RC_PENDING_DEADLINE_MS, RC_PERMISSION_MODES, RC_REQUEST_PARSE_CAP_BYTES, RC_SELF_HOST_ENV, RC_SELF_HOST_KEEPALIVE_MS, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE, RC_SELF_HOST_RETENTION_MS, RC_SELF_HOST_SCOPE_LIST, RC_SELF_HOST_WORKER_JWT_TTL_SECONDS, RC_SESSIONS_PATH_PREFIX, RC_STREAM_BACKOFF_MS, ROUTED_PATH_PREFIX, RcPermissionModeSchema, RcStreamEnvelopeSchema, RcStreamEventSchema, UsageError, UsageListOutputSchema, UsageSnapshotError, UsageSnapshotSchema, UsageWindowsInputSchema, UsageWindowsOutputSchema, WhenSchema, addDirectoryRule, addIdentity, addPool, addProvider, answerRcControlRequest, buildEntryFacts, buildLayoutPaths, buildRcControlResponsePayload, buildRcEventWriteBody, buildRcInterruptPayload, buildRcSetModelPayload, buildRcSetPermissionModePayload, buildRcUserMessagePayload, carryOver, checkReportHasWarnings, checkReportToJson, collectCheckReport, collectDoctorReport, collectFrontDoorStatus, collectPoolPick, createControlApiRouter, createDoorApiNodeHandler, createDoorApiRouter, createDoorEventHub, createEventsApiRouter, createLaunchEventPublisher, createLeafCache, createProfile, createRcApiNodeHandler, createRcApiRouter, createRcControlHandler, createRcCredentialStore, createRcEventFanout, createRcSelfHostSurface, createRcSessionTracker, createRcStreamHub, createSseParser, describeProviderEndpoint, detectAmbientCredential, doorApiAuth, doorApiNodeHandlerOf, effectiveWindow, ensureCa, ensureFrontDoor, ensureHeadroom, evaluateAmbientCredentialGuard, evaluateWhen, formatAmbientCredentialGuardMessage, formatCheckReport, formatDoctorReport, formatFrontDoorStatus, forwardableHeaders, frontDoorApiClient, frontDoorApiLink, frontDoorRcApiClient, frontDoorRcControl, generateCa, headroomSocketTarget, identityExists, injectRcUserMessage, interruptRcSession, isIdentityDirectoryName, isInterceptedHost, isRcPermissionMode, lateRcEventDial, lateRcStreamDial, listDirectoryRules, listIdentities, listProfiles, listProviders, listUsageSnapshots, matchBranch, mintLeaf, mintRcSelfHostCredential, observingRoutedRoute, parseConnectTarget, parseRcStreamEnvelope, planOf, prepareClaudeLaunch, prepareLaunch, profileExists, providerExists, rankPool, rcEventWriteResultFromAnswer, rcFanoutOnDoorHub, rcObserverAsPassthrough, rcSelfHostFromEnv, readActiveIdentity, readDirectoryRules, readFarmManifest, readGlobalConfig, readIdentity, readPools, readProfile, readProvider, readRcSelfHostRecord, readUsageSnapshot, realConnectCertStore, realConnectEffects, realRcControlTransport, realRcEventDial, realRcStreamDial, recoverFarm, recoveryDiagnostics, removeDirectoryRule, removeIdentity, removePool, removeProfile, removeProvider, requirePool, resolveAgentShimHome, resolveClaudeHome, resolveDecisions, resolveLayoutPaths, resolveSupervisorConfig, resyncFarm, runCheck, runDoctor, runFrontDoorSupervisor, runLauncher, runSupervisor, servedByPipeline, setAllowAmbientCredential, setDefaultConfigProfile, setGlobalDefaultProfile, setIdentityCredential, setPool, setProfileCategories, setProfileEntries, setProfileLaunchFlags, setProfileMetadata, setRcSessionModel, setRcSessionPermissionMode, snapshotPath, spawnClaude, startConnectServer, topLevelNames, updateDirectoryRule, updateProvider, useIdentity, writeDirectoryRules };
|
|
5688
|
+
export type { AddDirectoryRuleOptions, AddProviderInput, AmbientCredentialDetection, AmbientCredentialGuardResult, AmbientCredentialVar, BuildEntryFactsParams, CaMaterial, Candidate, CarryOverParams, CarryOverResult, CategoryMap, CheckReport, CheckReportJson, CollectCheckReportParams, CollectDoctorReportParams, CompiledRule, ConditionContext, ConfigProfile, ConnectCertStore, ConnectEffects, ConnectLimits, ConnectLocalSurface, ConnectServerConfig, ConnectServerHandle, ConnectTarget, ControlApiClient, ControlApiDeps, ControlApiRouter, Credential, CredentialSource, Decision, Diagnostic, DirectoryRule, DirectoryRules, DoctorReport, DoorApiClient, DoorApiContext, DoorApiDeps, DoorApiRouter, DoorEvent, DoorEventHub, DoorEventPublisher, DoorEventStream, DoorEventsApiDeps, EffectiveWindow, EliminatedRule, EnsureFrontDoorPorts, EnsureHeadroomPorts, EntryFact, EntryFacts, EntryValue, EvaluateAmbientCredentialGuardParams, FlattenedCascade, FrontDoorRcControl, FrontDoorSessionStatus, FrontDoorStatus, FrontDoorSupervisorPorts, GlobalConfig, HeadroomSupervisorConfig, Identity, IdentityCredentialChange, IdentityListEntry, IdentityListing, InjectedCredential, LaunchEventPublisher, LaunchLifecycleEvent, LaunchPlan, Layer, LayerId, LayoutPaths, LeafCert, PlanClass, Pool, PoolMember, PoolPickReport, PoolRanking, PortableConfig, PrepareClaudeLaunchOptions, PrepareLaunchParams, ProfileListEntry, Provider, ProviderListEntry, RankPoolInput, RcAnswerDecision, RcAnswerDeps, RcApiClient, RcApiDeps, RcApiRouter, RcControlAnswer, RcControlHandlerDeps, RcControlRequestDeps, RcControlTransport, RcCredentialStore, RcDialAnswer, RcDialTarget, RcEventDial, RcEventFanout, RcEventWriteResult, RcExchangeObserver, RcInjectDeps, RcObservedCredential, RcObservedRequest, RcPendingRequestSummary, RcPermissionMode, RcPresenceAnswer, RcSelfHostCredentialRecord, RcSelfHostDeps, RcSelfHostMintResult, RcSelfHostSurface, RcSessionStatus, RcSessionSummary, RcSessionTracker, RcSessionTrackerDeps, RcStreamAnswer, RcStreamDial, RcStreamEnvelope, RcStreamEvent, RcStreamHub, RcStreamHubDeps, RcWorkerFact, RcWriteHeaders, RecoverFarmParams, RecoveryResult, ResolveDecisionsInput, ResolvedState, ResyncFarmParams, ResyncFarmResult, RunCheckParams, RunDoctorParams, RunFrontDoorSupervisorOptions, RunLauncherParams, RunSupervisorOptions, SpawnClaudeParams, SseParsedEvent, StickyPick, SupervisorPorts, UnreadableIdentityListEntry, UpdateDirectoryRuleOptions, UpdateProviderInput, UsageReadFs, UsageSnapshot, WhenCondition, WhenEvaluation };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-shim",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.17.0",
|
|
4
4
|
"description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joseph Mearman <joseph@mearman.co.uk>",
|