agent-director 0.4.1 → 0.4.2

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.
@@ -0,0 +1,99 @@
1
+ import type { ClientOptions } from "./types.js";
2
+ import type { SpawnParams, SpawnResult, StatusParams, StatusResult, GetParams, GetResult, SendKeysParams, SendKeysResult, ReadPaneParams, ReadPaneResult, KillParams, KillResult, DecideParams, DecideResult, ResumeParams, ResumeResult, FindMissingParams, FindMissingResult, ExpireParams, ExpireResult, DeleteParams, DeleteResult, MakeTemplateParams, MakeTemplateResult, ListParams, ListResult, PauseParams, PauseResult, VersionParams, VersionResult } from "./types.js";
3
+ export { AgentDirectorError, ErrClientClosed } from "./errors.js";
4
+ export type { ClientOptions } from "./types.js";
5
+ /**
6
+ * Client — the public entry point for agent-director.
7
+ *
8
+ * Construction is synchronous: the constructor calls `ad_open` over Bun FFI,
9
+ * receives an opaque handle, and stores it. Every subsequent verb call will
10
+ * carry this handle across the FFI boundary.
11
+ *
12
+ * Lifecycle:
13
+ * 1. `new Client(opts)` → calls ad_open; throws on error envelope.
14
+ * 2. `client.close()` → calls ad_close; idempotent, never throws.
15
+ * 3. `[Symbol.dispose]()` → delegates to close() for `using` blocks.
16
+ * 4. Any verb method calls `_assertOpen()` first; post-close calls throw
17
+ * ErrClientClosed.
18
+ *
19
+ * Tilde expansion (`~` → home directory) is applied to `storePath` and
20
+ * `configPath` TS-side before the paths cross the FFI boundary. The C-ABI
21
+ * never receives a leading `~`.
22
+ */
23
+ export declare class Client {
24
+ /** Opaque handle returned by ad_open. Nulled after close(). */
25
+ private _handle;
26
+ /** Whether this client is still open and usable. */
27
+ private _open;
28
+ /** Optional logger for non-fatal warnings (e.g. ad_close error envelopes). */
29
+ private _logger;
30
+ constructor(opts: ClientOptions);
31
+ /**
32
+ * _assertOpen throws ErrClientClosed if the client has been closed.
33
+ * Called at the top of every verb method. May also be invoked from tests
34
+ * via `(client as any)._assertOpen()` — TS private fields are erased at
35
+ * runtime, so the cast works.
36
+ */
37
+ private _assertOpen;
38
+ /**
39
+ * close releases the ad_open handle via ad_close.
40
+ *
41
+ * - Idempotent: a second call is a no-op.
42
+ * - Never throws: if ad_close returns an error envelope, the error is
43
+ * logged via the optional logger (warn level) but the handle is still
44
+ * nulled and _open set to false.
45
+ */
46
+ close(): void;
47
+ /**
48
+ * [Symbol.dispose] enables `using` block syntax (Explicit Resource Management).
49
+ *
50
+ * {
51
+ * using client = new Client(opts);
52
+ * // ... client.someVerb() ...
53
+ * } // client.close() called automatically here
54
+ */
55
+ [Symbol.dispose](): void;
56
+ /** spawn — launch a tracked Claude Code instance in a new tmux session. */
57
+ spawn(params: SpawnParams): Promise<SpawnResult>;
58
+ /** status — get the current state of a Spawn. */
59
+ status(params: StatusParams): Promise<StatusResult>;
60
+ /** get — fetch the full Spawn record. */
61
+ get(params: GetParams): Promise<GetResult>;
62
+ /** sendKeys — send keystrokes to a Spawn's tmux pane. */
63
+ sendKeys(params: SendKeysParams): Promise<SendKeysResult>;
64
+ /** readPane — read the current contents of a Spawn's tmux pane. */
65
+ readPane(params: ReadPaneParams): Promise<ReadPaneResult>;
66
+ /** kill — terminate a Spawn's tmux session. */
67
+ kill(params: KillParams): Promise<KillResult>;
68
+ /** decide — resolve a pending permission request. */
69
+ decide(params: DecideParams): Promise<DecideResult>;
70
+ /** resume — restart a terminated Spawn via `claude --resume`. */
71
+ resume(params: ResumeParams): Promise<ResumeResult>;
72
+ /** findMissing — reconcile Spawns whose tmux sessions have disappeared. */
73
+ findMissing(params: FindMissingParams): Promise<FindMissingResult>;
74
+ /** expire — remove terminal-state rows older than the retention window. */
75
+ expire(params: ExpireParams): Promise<ExpireResult>;
76
+ /** delete — hard-delete Spawn rows by id. */
77
+ delete(params: DeleteParams): Promise<DeleteResult>;
78
+ /** makeTemplate — save a reusable spawn preset. */
79
+ makeTemplate(params: MakeTemplateParams): Promise<MakeTemplateResult>;
80
+ /** list — query Spawns with optional filter params. */
81
+ list(params: ListParams): Promise<ListResult>;
82
+ /** pause — politely shut down a waiting Spawn. */
83
+ pause(params: PauseParams): Promise<PauseResult>;
84
+ /**
85
+ * version — return the binary's build-time version stamp.
86
+ *
87
+ * This is the only handle-free verb: it passes null instead of the Client
88
+ * handle because the C-ABI ignores any handle field for ad_version.
89
+ */
90
+ version(params: VersionParams): Promise<VersionResult>;
91
+ /**
92
+ * _assertOpenForTests exposes _assertOpen to test code without forcing
93
+ * public visibility. TypeScript `private` is erased at runtime, but this
94
+ * alias makes the intent explicit and avoids the `(client as any)` cast.
95
+ *
96
+ * @internal Tests only — do not call from application code.
97
+ */
98
+ _assertOpenForTests(): void;
99
+ }
@@ -0,0 +1,173 @@
1
+ export { TS_ONLY_ERROR_NAMES } from "./internal/tsOnlyErrors.js";
2
+ /**
3
+ * AgentDirectorError — base class for all typed errors surfaced by this
4
+ * client library.
5
+ *
6
+ * `verb` names the callable verb that triggered the error (e.g. "spawn").
7
+ * `errName` is the canonical error name from the Go errnames catalog.
8
+ * `errDescription` is the human-readable description from the C-ABI envelope.
9
+ * `message` is formatted as "${errName}: ${errDescription}".
10
+ */
11
+ export declare class AgentDirectorError extends Error {
12
+ /** Verb that triggered this error (e.g. "spawn", "status"). Empty for lifecycle ops. */
13
+ readonly verb: string;
14
+ /** Canonical error name, matching the Go errnames catalog (e.g. "ErrSpawnNotFound"). */
15
+ readonly errName: string;
16
+ /** Human-readable description forwarded from the C-ABI envelope. */
17
+ readonly errDescription: string;
18
+ constructor(verb: string, err_name: string, err_description: string);
19
+ }
20
+ /**
21
+ * ErrClientClosed — thrown when a verb method (or _assertOpen) is called on a
22
+ * Client that has already been closed.
23
+ *
24
+ * TS-ONLY ERROR — no counterpart in pkg/api/errnames/catalog.json.
25
+ * Listed in `src/internal/tsOnlyErrors.ts::TS_ONLY_ERROR_NAMES` so the
26
+ * catalog-drift test never flags it as an unexpected class.
27
+ */
28
+ export declare class ErrClientClosed extends AgentDirectorError {
29
+ constructor();
30
+ }
31
+ /**
32
+ * ErrUnsupportedPlatform — thrown when `process.platform` + `process.arch`
33
+ * produce a tuple that has no corresponding native sub-package.
34
+ *
35
+ * TS-ONLY ERROR — no counterpart in pkg/api/errnames/catalog.json.
36
+ * Listed in `src/internal/tsOnlyErrors.ts::TS_ONLY_ERROR_NAMES`.
37
+ */
38
+ export declare class ErrUnsupportedPlatform extends AgentDirectorError {
39
+ constructor(tuple: string);
40
+ }
41
+ /**
42
+ * ErrPlatformPackageMissing — thrown when the optional npm sub-package for
43
+ * the current platform is not installed, or when its native binary file is
44
+ * absent from the installed package directory.
45
+ *
46
+ * TS-ONLY ERROR — no counterpart in pkg/api/errnames/catalog.json.
47
+ * Listed in `src/internal/tsOnlyErrors.ts::TS_ONLY_ERROR_NAMES`.
48
+ */
49
+ export declare class ErrPlatformPackageMissing extends AgentDirectorError {
50
+ constructor(pkgName: string, detail?: string);
51
+ }
52
+ /**
53
+ * ErrBunVersionTooOld — thrown when Bun.version is below the declared minimum.
54
+ *
55
+ * TS-ONLY ERROR — no counterpart in pkg/api/errnames/catalog.json.
56
+ * Listed in `src/internal/tsOnlyErrors.ts::TS_ONLY_ERROR_NAMES`.
57
+ */
58
+ export declare class ErrBunVersionTooOld extends AgentDirectorError {
59
+ constructor(actual: string, minimum: string);
60
+ }
61
+ /** Mirrors ErrCwdMissing (package: spawn) */
62
+ export declare class ErrCwdMissing extends AgentDirectorError {
63
+ }
64
+ /** Mirrors ErrCwdNotAPath (package: spawn) */
65
+ export declare class ErrCwdNotAPath extends AgentDirectorError {
66
+ }
67
+ /** Mirrors ErrCwdNotFound (package: spawn) */
68
+ export declare class ErrCwdNotFound extends AgentDirectorError {
69
+ }
70
+ /** Mirrors ErrCwdNotADirectory (package: spawn) */
71
+ export declare class ErrCwdNotADirectory extends AgentDirectorError {
72
+ }
73
+ /** Mirrors ErrRelayModeInvalid (package: spawn) */
74
+ export declare class ErrRelayModeInvalid extends AgentDirectorError {
75
+ }
76
+ /** Mirrors ErrSpawnDeniedFlag (package: spawn) */
77
+ export declare class ErrSpawnDeniedFlag extends AgentDirectorError {
78
+ }
79
+ /** Mirrors ErrReservedEnvKey (package: spawn) */
80
+ export declare class ErrReservedEnvKey extends AgentDirectorError {
81
+ }
82
+ /** Mirrors ErrInstanceIdCollision (package: spawn) */
83
+ export declare class ErrInstanceIdCollision extends AgentDirectorError {
84
+ }
85
+ /** Mirrors ErrTmuxSessionNameEmpty (package: spawn) */
86
+ export declare class ErrTmuxSessionNameEmpty extends AgentDirectorError {
87
+ }
88
+ /** Mirrors ErrTmuxSessionNameInvalid (package: spawn) */
89
+ export declare class ErrTmuxSessionNameInvalid extends AgentDirectorError {
90
+ }
91
+ /** Mirrors ErrTmuxSessionNameTooLong (package: spawn) */
92
+ export declare class ErrTmuxSessionNameTooLong extends AgentDirectorError {
93
+ }
94
+ /** Mirrors ErrSpawnNotFound (package: store) */
95
+ export declare class ErrSpawnNotFound extends AgentDirectorError {
96
+ }
97
+ /** Mirrors ErrTmuxNotAvailable (package: tmux) */
98
+ export declare class ErrTmuxNotAvailable extends AgentDirectorError {
99
+ }
100
+ /** Mirrors ErrTmuxSessionCreate (package: tmux) */
101
+ export declare class ErrTmuxSessionCreate extends AgentDirectorError {
102
+ }
103
+ /** Mirrors ErrTmuxSendKeys (package: tmux) */
104
+ export declare class ErrTmuxSendKeys extends AgentDirectorError {
105
+ }
106
+ /** Mirrors ErrTmuxCaptureFailed (package: tmux) */
107
+ export declare class ErrTmuxCaptureFailed extends AgentDirectorError {
108
+ }
109
+ /** Mirrors ErrSpawnNotInteractive (package: api) */
110
+ export declare class ErrSpawnNotInteractive extends AgentDirectorError {
111
+ }
112
+ /** Mirrors ErrSendKeysWhileRelayed (package: api) */
113
+ export declare class ErrSendKeysWhileRelayed extends AgentDirectorError {
114
+ }
115
+ /** Mirrors ErrSpawnNotPausable (package: api) */
116
+ export declare class ErrSpawnNotPausable extends AgentDirectorError {
117
+ }
118
+ /** Mirrors ErrPauseTimeout (package: api) */
119
+ export declare class ErrPauseTimeout extends AgentDirectorError {
120
+ }
121
+ /** Mirrors ErrListInvalidLabel (package: api) */
122
+ export declare class ErrListInvalidLabel extends AgentDirectorError {
123
+ }
124
+ /** Mirrors ErrTemplateNameUnsafe (package: config) */
125
+ export declare class ErrTemplateNameUnsafe extends AgentDirectorError {
126
+ }
127
+ /** Mirrors ErrTemplateNotFound (package: config) */
128
+ export declare class ErrTemplateNotFound extends AgentDirectorError {
129
+ }
130
+ /** Mirrors ErrTemplateMalformed (package: config) */
131
+ export declare class ErrTemplateMalformed extends AgentDirectorError {
132
+ }
133
+ /** Mirrors ErrTemplateExists (package: config) */
134
+ export declare class ErrTemplateExists extends AgentDirectorError {
135
+ }
136
+ /** Mirrors ErrProbeUnsupported (package: probe) */
137
+ export declare class ErrProbeUnsupported extends AgentDirectorError {
138
+ }
139
+ /** Mirrors ErrSpawnNotResumable (package: api) */
140
+ export declare class ErrSpawnNotResumable extends AgentDirectorError {
141
+ }
142
+ /** Mirrors ErrNoSessionId (package: api) */
143
+ export declare class ErrNoSessionId extends AgentDirectorError {
144
+ }
145
+ /** Mirrors ErrJsonlMissing (package: api) */
146
+ export declare class ErrJsonlMissing extends AgentDirectorError {
147
+ }
148
+ /** Mirrors ErrRelayModeOff (package: api) */
149
+ export declare class ErrRelayModeOff extends AgentDirectorError {
150
+ }
151
+ /** Mirrors ErrInvalidDecision (package: api) */
152
+ export declare class ErrInvalidDecision extends AgentDirectorError {
153
+ }
154
+ /** Mirrors ErrNoOpenPermissionRequest (package: store) */
155
+ export declare class ErrNoOpenPermissionRequest extends AgentDirectorError {
156
+ }
157
+ /** Mirrors ErrAlreadyDecided (package: store) */
158
+ export declare class ErrAlreadyDecided extends AgentDirectorError {
159
+ }
160
+ /** Mirrors ErrUnknownHandle (package: cabi, scope: cabi) */
161
+ export declare class ErrUnknownHandle extends AgentDirectorError {
162
+ }
163
+ /**
164
+ * errorFromEnvelope creates a typed AgentDirectorError subclass from the
165
+ * C-ABI error envelope fields.
166
+ *
167
+ * @param verb The verb name that produced the error (e.g. "spawn").
168
+ * @param err_name The canonical error name from the envelope.
169
+ * @param err_description The human-readable description from the envelope.
170
+ * @returns A typed subclass when err_name matches the catalog; a plain
171
+ * AgentDirectorError (with a console.warn) for unknown names.
172
+ */
173
+ export declare function errorFromEnvelope(verb: string, err_name: string, err_description: string): AgentDirectorError;
package/dist/ffi.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * ffi.ts — public facade for the C-ABI call recipe.
3
+ *
4
+ * The six-step FFI recipe is split across three files:
5
+ *
6
+ * src/internal/worker.ts — steps 1–4 (runs inside the worker thread)
7
+ * 1. Encode params as null-terminated UTF-8 JSON
8
+ * 2. Call the C symbol via Bun dlopen
9
+ * 3. Copy the returned CString to a JS string
10
+ * 4. Free the C pointer via ad_free_cstring (try/finally — error path frees too)
11
+ *
12
+ * src/internal/workerProxy.ts — steps 5–6 (main thread, post-worker)
13
+ * 5. Parse the raw JSON string
14
+ * 6. If err_name present → throw typed error via errorFromEnvelope;
15
+ * else → return parsed result
16
+ *
17
+ * src/ffi.ts (this file) — thin public facade
18
+ * Exposes callVerb<P, R> that routes to workerProxy.dispatch and casts.
19
+ *
20
+ * WHY a worker?
21
+ * Bun FFI has no per-symbol `async: true` marker. Without the worker, every
22
+ * C call would block the JS event loop. The worker runs in a separate thread
23
+ * so verb calls are off-main-thread and the event loop stays responsive.
24
+ * See src/internal/workerProxy.ts for the singleton design rationale.
25
+ *
26
+ * Internal — NOT re-exported from src/index.ts.
27
+ */
28
+ export { VERBS, KEBAB_TO_CAMEL } from "./internal/verbs.js";
29
+ export type { VerbName } from "./internal/verbs.js";
30
+ export { BINDING_SYMBOL_NAMES } from "./internal/bindingSpec.js";
31
+ export { shutdown as shutdownWorker } from "./internal/workerProxy.js";
32
+ /**
33
+ * callVerb dispatches a verb call through the dedicated worker thread and
34
+ * returns a Promise that resolves with the typed result R or rejects with a
35
+ * typed AgentDirectorError.
36
+ *
37
+ * @param verb Kebab-case verb name (e.g. "send-keys", "make-template")
38
+ * @param handle Opaque Client handle from ad_open, or null for handle-free
39
+ * verbs (currently only "version")
40
+ * @param params Verb-specific params object; JSON-serialized inside dispatch
41
+ */
42
+ export declare function callVerb<P, R>(verb: string, handle: string | null, params: P): Promise<R>;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public entry point for agent-director.
3
+ *
4
+ * ffi.ts and platform.ts are internal — they are NOT re-exported here.
5
+ */
6
+ export { Client } from "./client.js";
7
+ export { AgentDirectorError, ErrClientClosed, ErrUnsupportedPlatform, ErrPlatformPackageMissing, ErrBunVersionTooOld, errorFromEnvelope, ErrCwdMissing, ErrCwdNotAPath, ErrCwdNotFound, ErrCwdNotADirectory, ErrRelayModeInvalid, ErrSpawnDeniedFlag, ErrReservedEnvKey, ErrInstanceIdCollision, ErrTmuxSessionNameEmpty, ErrTmuxSessionNameInvalid, ErrTmuxSessionNameTooLong, ErrSpawnNotFound, ErrTmuxNotAvailable, ErrTmuxSessionCreate, ErrTmuxSendKeys, ErrTmuxCaptureFailed, ErrSpawnNotInteractive, ErrSendKeysWhileRelayed, ErrSpawnNotPausable, ErrPauseTimeout, ErrListInvalidLabel, ErrTemplateNameUnsafe, ErrTemplateNotFound, ErrTemplateMalformed, ErrTemplateExists, ErrProbeUnsupported, ErrSpawnNotResumable, ErrNoSessionId, ErrJsonlMissing, ErrRelayModeOff, ErrInvalidDecision, ErrNoOpenPermissionRequest, ErrAlreadyDecided, ErrUnknownHandle, } from "./errors.js";
8
+ export type { ClientOptions, Logger } from "./types.js";
9
+ export type { VerbSummary, PermissionRequestInfo, ListRow } from "./types.js";
10
+ export type { SpawnParams, SpawnResult, StatusParams, StatusResult, GetParams, GetResult, SendKeysParams, SendKeysResult, ReadPaneParams, ReadPaneResult, KillParams, KillResult, DecideParams, DecideResult, ResumeParams, ResumeResult, FindMissingParams, FindMissingResult, ExpireParams, ExpireResult, DeleteParams, DeleteResult, MakeTemplateParams, MakeTemplateResult, ListParams, ListResult, PauseParams, PauseResult, VersionParams, VersionResult, } from "./types.js";