@flowy-agent-store/sdk 0.1.0-beta.10

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,248 @@
1
+ import { AppServerClient } from "@flowy-agent-store/client";
2
+ import { ClientCapabilities, ClientInfo, ExpertPack, InitializeResult } from "@flowy-agent-store/protocol";
3
+ //#region src/bin.d.ts
4
+ export declare function resolveAppServerBin(explicit?: string): string;
5
+ //#endregion
6
+ //#region src/export.d.ts
7
+ /**
8
+ * The wire faces this module needs, narrowed from {@link Harness} on purpose:
9
+ * unit tests hand a fake, and the dependency surface stays explicit instead of
10
+ * quietly reaching `store` / `conversations`. A real harness satisfies this
11
+ * structurally (`Harness` extends `AppServerClient`, which owns `agents` /
12
+ * `teams` / `skills` and the two flat asset methods).
13
+ */
14
+ interface ExportDeps {
15
+ agents: {
16
+ export(agentId: string): Promise<ExpertPack>;
17
+ };
18
+ teams: {
19
+ export(teamId: string, teamVersion?: string): Promise<ExpertPack>;
20
+ };
21
+ skills: {
22
+ files(skillId: string): Promise<{
23
+ files: {
24
+ path: string;
25
+ }[];
26
+ }>;
27
+ readFile(skillId: string, path: string): Promise<Uint8Array>;
28
+ };
29
+ /**
30
+ * The plugin-level snapshot asset byte face (`import/asset`, doc 38). The
31
+ * pack names the `avatars/`, `bin/` and `scripts/` files by reference —
32
+ * that list is the single source of what to fetch — and this fetches one
33
+ * file's bytes. (The listing method `import/assets` exists on the client;
34
+ * materialization deliberately trusts only the pack, so the exported
35
+ * directory can never contain a file the pack does not name.)
36
+ */
37
+ readImportAsset(snapshotId: string, path: string): Promise<Uint8Array>;
38
+ }
39
+ interface ExportResult {
40
+ /** The pack is also returned in memory: a consumer that never touches the disk needs no second call. */
41
+ pack: ExpertPack;
42
+ dir: string;
43
+ /** Skill names actually written (deduplicated). */
44
+ writtenSkills: string[];
45
+ /**
46
+ * Snapshot-relative asset paths actually written, in the pack's order. The
47
+ * materialized directory is therefore a complete **plugin root**: a team
48
+ * whose scripts resolve `PLUGIN_ROOT/bin/init_task.py` two levels above
49
+ * their skill finds it, and the `avatars/` references in its own skill
50
+ * documents resolve too (doc 38 §3.5).
51
+ */
52
+ writtenAssets: string[];
53
+ /**
54
+ * Skills the pack **declares** but this host cannot resolve (`skill/files`
55
+ * rejected them). Reported honestly, never skipped in silence: the pack
56
+ * states declarations, resolvability is a host fact the consumer has to
57
+ * judge (doc `32` §5 R8, live criterion EX-008).
58
+ */
59
+ danglingSkills: {
60
+ id: string;
61
+ error: string;
62
+ }[];
63
+ }
64
+ /**
65
+ * Write an in-hand pack to `dir` as a real directory (docs `35` §5 and `38`
66
+ * §3.5). "Materialize" here means exactly that: the in-memory pack object plus
67
+ * the skill and asset bytes it references become files on disk; the pack data
68
+ * itself is unchanged.
69
+ *
70
+ * ```text
71
+ * <dir>/expert-pack.json # the wire pack, byte-for-byte (JSON.stringify(_, 2))
72
+ * <dir>/persona.md # kind === "agent" only: pack.persona.instructions
73
+ * <dir>/members/<id>/persona.md # kind === "team" only, one per member
74
+ * <dir>/skills/<name>/… # every referenced skill's files, deduplicated by id
75
+ * <dir>/avatars/… # pack.assets, kind === "avatar", at their snapshot paths
76
+ * <dir>/bin/… · scripts/… # pack.assets, kind === "script" (doc 38 D5)
77
+ * ```
78
+ *
79
+ * Error semantics (doc `35` §6): the pack is fetched **before** anything is
80
+ * written, so a failed wire export leaves no directory behind; a `skill/files`
81
+ * rejection lands in {@link ExportResult.danglingSkills} and the loop
82
+ * continues; a `skill/file` or `import/asset` rejection after a successful
83
+ * listing **throws** — that is a host I/O failure, and swallowing it would
84
+ * produce a directory that lists files it does not contain. No rollback on
85
+ * mid-write failure.
86
+ */
87
+ export declare function materializePack(deps: ExportDeps, pack: ExpertPack, dir: string): Promise<ExportResult>;
88
+ /**
89
+ * Export one single-agent expert and write it out as a directory.
90
+ *
91
+ * Same preconditions as the wire method: the expert must be installed and
92
+ * enabled, or the host answers `agent_not_installed` / `agent_disabled` /
93
+ * `preset_disabled`; a host whose `[expert_export]` table refuses the id
94
+ * answers `policy_denied` (the capability bit only reports the seam). Check
95
+ * `capabilities.expert_export` for the seam, not for this id.
96
+ */
97
+ export declare function exportAgent(deps: ExportDeps, agentId: string, dir: string): Promise<ExportResult>;
98
+ /**
99
+ * Export one expert team and write it out as a directory, leader first.
100
+ *
101
+ * All-or-nothing stays on the server: if any member is uninstalled, disabled,
102
+ * or refused by policy, the whole call fails and nothing is written. A pack
103
+ * over 1 MiB fails with `response_too_large` rather than being truncated.
104
+ * `teamVersion` is an optional pin; a mismatch is `version_mismatch`.
105
+ */
106
+ export declare function exportTeam(deps: ExportDeps, teamId: string, dir: string, teamVersion?: string): Promise<ExportResult>;
107
+ //#endregion
108
+ //#region src/readiness.d.ts
109
+ /**
110
+ * Readiness protocol (docs/agent-store/12 P0-1).
111
+ *
112
+ * The runtime prints exactly one machine-readable line on stdout after the
113
+ * socket is bound. Tracing logs share stdout, so the host scans lines for a
114
+ * JSON object with `"agent_store": "listening"` and ignores everything else.
115
+ */
116
+ interface ReadinessInfo {
117
+ host: string;
118
+ port: number;
119
+ url: string;
120
+ protocol_version: string;
121
+ version: string;
122
+ auth: string;
123
+ }
124
+ /** Parse one stdout line; `null` when it is not the readiness line. */
125
+ export declare function parseReadinessLine(line: string): ReadinessInfo | null;
126
+ //#endregion
127
+ //#region src/spawn.d.ts
128
+ /** Fail when the runtime speaks a different wire protocol (§7 acceptance). */
129
+ export declare function assertProtocolCompatible(runtimeVersion: string): void;
130
+ interface SpawnOptions {
131
+ /** Explicit binary path (overrides `AGENT_STORE_BIN` / `PATH`). */
132
+ bin?: string;
133
+ /** Data directory the child owns. Defaults to a fresh temp dir (removed on `close`). */
134
+ dataDir?: string;
135
+ /** Port to bind. Defaults to `0` (OS-assigned, reported by the readiness line). */
136
+ port?: number;
137
+ /** Extra CLI args appended after the managed ones. */
138
+ extraArgs?: string[];
139
+ /**
140
+ * What the spawned host does with its default marketplace sources at boot
141
+ * (doc `37` §3.1). Sent as `AGENT_STORE_MARKET_DOWNLOAD`.
142
+ *
143
+ * - `"lazy"` — register the declared sources and download nothing; the
144
+ * archives wait for an explicit `market/refresh` / `refreshMarketplace()`;
145
+ * - `"none"` — register nothing at all, so `store/list` starts empty;
146
+ * - `"eager"` — fetch every declared source during boot.
147
+ *
148
+ * Omitted = the host's own policy (`download_on_start` per source, default
149
+ * `true`, so a declared source *is* downloaded unless it says otherwise).
150
+ * This is a process-scoped override: nothing is written to the user's config.
151
+ */
152
+ marketDownload?: "eager" | "lazy" | "none";
153
+ /**
154
+ * Config file for this child only (doc `37` §3.1). Sent as
155
+ * `AGENT_STORE_CONFIG`.
156
+ *
157
+ * Without it the host reads the per-user `~/.agent-store/config.toml` — which
158
+ * a spawned, SDK-owned host should not have to share. The data directory is
159
+ * independent of this (`dataDir`, always explicit).
160
+ */
161
+ configPath?: string;
162
+ /** How long to wait for the readiness line. Defaults to 120s (cold DB init). */
163
+ readyTimeoutMs?: number;
164
+ /**
165
+ * Extra environment variables, merged over the parent's `process.env`.
166
+ *
167
+ * An entry here **wins over the typed options above** (`marketDownload`,
168
+ * `configPath`): the raw map is the caller's most specific statement, and
169
+ * nothing this factory derives should silently overwrite it.
170
+ */
171
+ env?: Record<string, string | undefined>;
172
+ /** Working directory for the child. Defaults to the parent's cwd. */
173
+ cwd?: string;
174
+ /** Called once when the child exits, for any reason (crash included). */
175
+ onExit?: (info: SpawnExitInfo) => void;
176
+ }
177
+ /** How a spawned runtime process ended. */
178
+ interface SpawnExitInfo {
179
+ /** Exit code, or `null` when the process was terminated by a signal. */
180
+ code: number | null;
181
+ /** Terminating signal, or `null` on a normal exit. */
182
+ signal: string | null;
183
+ }
184
+ interface SpawnedServer {
185
+ readonly readiness: ReadinessInfo;
186
+ readonly dataDir: string;
187
+ /**
188
+ * Settles when the runtime process exits — including an unexpected crash,
189
+ * which is otherwise indistinguishable from "still starting up". Never
190
+ * rejects: inspect `code` / `signal`.
191
+ */
192
+ readonly exited: Promise<SpawnExitInfo>;
193
+ /** Terminate the child and remove the data dir when it was auto-created. */
194
+ close(): Promise<void>;
195
+ }
196
+ export declare function spawnAppServer(options?: SpawnOptions): Promise<SpawnedServer>;
197
+ //#endregion
198
+ //#region src/index.d.ts
199
+ export interface HarnessOptions extends SpawnOptions {
200
+ client: ClientInfo;
201
+ capabilities?: ClientCapabilities;
202
+ token?: string;
203
+ requestTimeoutMs?: number;
204
+ }
205
+ /**
206
+ * A connected `AppServerClient` that **owns the runtime process it spawned**
207
+ * (doc `31` §5 方案 B).
208
+ *
209
+ * Every `AppServerClient` member is available directly — `conversations`,
210
+ * `store`, `agents`, `onNotification`, … — because a factory that returned a
211
+ * *wrapper* was the lie this shape removes.
212
+ *
213
+ * Named after the external reference this shape follows (doc `31` §3.2):
214
+ * Kimi Code's `const harness = createKimiHarness(...)` hands back a `harness`
215
+ * you keep for the whole life of the run, not a one-shot launcher.
216
+ */
217
+ export interface Harness extends AppServerClient {
218
+ /** The child process: `readiness` / `dataDir` / `exited` / `close`. */
219
+ readonly server: SpawnedServer;
220
+ /**
221
+ * The handshake response captured at launch (**never null**).
222
+ *
223
+ * Not named `initializeResult`: that is a private field of the base class
224
+ * (`client.ts`), and the base's public `initializeInfo` is the *current*
225
+ * connection state — it goes back to `null` after `close()`. This member is
226
+ * the snapshot that proves which protocol fingerprint the session was
227
+ * admitted under.
228
+ */
229
+ readonly handshake: InitializeResult;
230
+ /**
231
+ * Unsubscribe → close the transport → terminate the child → remove an
232
+ * auto-created data dir. Idempotent.
233
+ *
234
+ * Deliberately widens the base's synchronous `close(): void`: awaiting a
235
+ * void-returning call is legal, so callers holding a plain `AppServerClient`
236
+ * are unaffected, while a launched session needs the promise to know the
237
+ * process is actually gone.
238
+ */
239
+ close(): Promise<void>;
240
+ }
241
+ /**
242
+ * Spawn a loopback runtime with its own data dir and return a connected,
243
+ * initialized client. Rejects non-loopback contact outright (P0-4): this
244
+ * entry point only ever dials the process it just spawned.
245
+ */
246
+ export declare function launchHarness(options: HarnessOptions): Promise<Harness>;
247
+ //#endregion
248
+ export type { ExportDeps, ExportResult, ReadinessInfo, SpawnExitInfo, SpawnOptions, SpawnedServer };
@@ -0,0 +1,248 @@
1
+ import { AppServerClient } from "@flowy-agent-store/client";
2
+ import { ClientCapabilities, ClientInfo, ExpertPack, InitializeResult } from "@flowy-agent-store/protocol";
3
+ //#region src/bin.d.ts
4
+ export declare function resolveAppServerBin(explicit?: string): string;
5
+ //#endregion
6
+ //#region src/export.d.ts
7
+ /**
8
+ * The wire faces this module needs, narrowed from {@link Harness} on purpose:
9
+ * unit tests hand a fake, and the dependency surface stays explicit instead of
10
+ * quietly reaching `store` / `conversations`. A real harness satisfies this
11
+ * structurally (`Harness` extends `AppServerClient`, which owns `agents` /
12
+ * `teams` / `skills` and the two flat asset methods).
13
+ */
14
+ interface ExportDeps {
15
+ agents: {
16
+ export(agentId: string): Promise<ExpertPack>;
17
+ };
18
+ teams: {
19
+ export(teamId: string, teamVersion?: string): Promise<ExpertPack>;
20
+ };
21
+ skills: {
22
+ files(skillId: string): Promise<{
23
+ files: {
24
+ path: string;
25
+ }[];
26
+ }>;
27
+ readFile(skillId: string, path: string): Promise<Uint8Array>;
28
+ };
29
+ /**
30
+ * The plugin-level snapshot asset byte face (`import/asset`, doc 38). The
31
+ * pack names the `avatars/`, `bin/` and `scripts/` files by reference —
32
+ * that list is the single source of what to fetch — and this fetches one
33
+ * file's bytes. (The listing method `import/assets` exists on the client;
34
+ * materialization deliberately trusts only the pack, so the exported
35
+ * directory can never contain a file the pack does not name.)
36
+ */
37
+ readImportAsset(snapshotId: string, path: string): Promise<Uint8Array>;
38
+ }
39
+ interface ExportResult {
40
+ /** The pack is also returned in memory: a consumer that never touches the disk needs no second call. */
41
+ pack: ExpertPack;
42
+ dir: string;
43
+ /** Skill names actually written (deduplicated). */
44
+ writtenSkills: string[];
45
+ /**
46
+ * Snapshot-relative asset paths actually written, in the pack's order. The
47
+ * materialized directory is therefore a complete **plugin root**: a team
48
+ * whose scripts resolve `PLUGIN_ROOT/bin/init_task.py` two levels above
49
+ * their skill finds it, and the `avatars/` references in its own skill
50
+ * documents resolve too (doc 38 §3.5).
51
+ */
52
+ writtenAssets: string[];
53
+ /**
54
+ * Skills the pack **declares** but this host cannot resolve (`skill/files`
55
+ * rejected them). Reported honestly, never skipped in silence: the pack
56
+ * states declarations, resolvability is a host fact the consumer has to
57
+ * judge (doc `32` §5 R8, live criterion EX-008).
58
+ */
59
+ danglingSkills: {
60
+ id: string;
61
+ error: string;
62
+ }[];
63
+ }
64
+ /**
65
+ * Write an in-hand pack to `dir` as a real directory (docs `35` §5 and `38`
66
+ * §3.5). "Materialize" here means exactly that: the in-memory pack object plus
67
+ * the skill and asset bytes it references become files on disk; the pack data
68
+ * itself is unchanged.
69
+ *
70
+ * ```text
71
+ * <dir>/expert-pack.json # the wire pack, byte-for-byte (JSON.stringify(_, 2))
72
+ * <dir>/persona.md # kind === "agent" only: pack.persona.instructions
73
+ * <dir>/members/<id>/persona.md # kind === "team" only, one per member
74
+ * <dir>/skills/<name>/… # every referenced skill's files, deduplicated by id
75
+ * <dir>/avatars/… # pack.assets, kind === "avatar", at their snapshot paths
76
+ * <dir>/bin/… · scripts/… # pack.assets, kind === "script" (doc 38 D5)
77
+ * ```
78
+ *
79
+ * Error semantics (doc `35` §6): the pack is fetched **before** anything is
80
+ * written, so a failed wire export leaves no directory behind; a `skill/files`
81
+ * rejection lands in {@link ExportResult.danglingSkills} and the loop
82
+ * continues; a `skill/file` or `import/asset` rejection after a successful
83
+ * listing **throws** — that is a host I/O failure, and swallowing it would
84
+ * produce a directory that lists files it does not contain. No rollback on
85
+ * mid-write failure.
86
+ */
87
+ export declare function materializePack(deps: ExportDeps, pack: ExpertPack, dir: string): Promise<ExportResult>;
88
+ /**
89
+ * Export one single-agent expert and write it out as a directory.
90
+ *
91
+ * Same preconditions as the wire method: the expert must be installed and
92
+ * enabled, or the host answers `agent_not_installed` / `agent_disabled` /
93
+ * `preset_disabled`; a host whose `[expert_export]` table refuses the id
94
+ * answers `policy_denied` (the capability bit only reports the seam). Check
95
+ * `capabilities.expert_export` for the seam, not for this id.
96
+ */
97
+ export declare function exportAgent(deps: ExportDeps, agentId: string, dir: string): Promise<ExportResult>;
98
+ /**
99
+ * Export one expert team and write it out as a directory, leader first.
100
+ *
101
+ * All-or-nothing stays on the server: if any member is uninstalled, disabled,
102
+ * or refused by policy, the whole call fails and nothing is written. A pack
103
+ * over 1 MiB fails with `response_too_large` rather than being truncated.
104
+ * `teamVersion` is an optional pin; a mismatch is `version_mismatch`.
105
+ */
106
+ export declare function exportTeam(deps: ExportDeps, teamId: string, dir: string, teamVersion?: string): Promise<ExportResult>;
107
+ //#endregion
108
+ //#region src/readiness.d.ts
109
+ /**
110
+ * Readiness protocol (docs/agent-store/12 P0-1).
111
+ *
112
+ * The runtime prints exactly one machine-readable line on stdout after the
113
+ * socket is bound. Tracing logs share stdout, so the host scans lines for a
114
+ * JSON object with `"agent_store": "listening"` and ignores everything else.
115
+ */
116
+ interface ReadinessInfo {
117
+ host: string;
118
+ port: number;
119
+ url: string;
120
+ protocol_version: string;
121
+ version: string;
122
+ auth: string;
123
+ }
124
+ /** Parse one stdout line; `null` when it is not the readiness line. */
125
+ export declare function parseReadinessLine(line: string): ReadinessInfo | null;
126
+ //#endregion
127
+ //#region src/spawn.d.ts
128
+ /** Fail when the runtime speaks a different wire protocol (§7 acceptance). */
129
+ export declare function assertProtocolCompatible(runtimeVersion: string): void;
130
+ interface SpawnOptions {
131
+ /** Explicit binary path (overrides `AGENT_STORE_BIN` / `PATH`). */
132
+ bin?: string;
133
+ /** Data directory the child owns. Defaults to a fresh temp dir (removed on `close`). */
134
+ dataDir?: string;
135
+ /** Port to bind. Defaults to `0` (OS-assigned, reported by the readiness line). */
136
+ port?: number;
137
+ /** Extra CLI args appended after the managed ones. */
138
+ extraArgs?: string[];
139
+ /**
140
+ * What the spawned host does with its default marketplace sources at boot
141
+ * (doc `37` §3.1). Sent as `AGENT_STORE_MARKET_DOWNLOAD`.
142
+ *
143
+ * - `"lazy"` — register the declared sources and download nothing; the
144
+ * archives wait for an explicit `market/refresh` / `refreshMarketplace()`;
145
+ * - `"none"` — register nothing at all, so `store/list` starts empty;
146
+ * - `"eager"` — fetch every declared source during boot.
147
+ *
148
+ * Omitted = the host's own policy (`download_on_start` per source, default
149
+ * `true`, so a declared source *is* downloaded unless it says otherwise).
150
+ * This is a process-scoped override: nothing is written to the user's config.
151
+ */
152
+ marketDownload?: "eager" | "lazy" | "none";
153
+ /**
154
+ * Config file for this child only (doc `37` §3.1). Sent as
155
+ * `AGENT_STORE_CONFIG`.
156
+ *
157
+ * Without it the host reads the per-user `~/.agent-store/config.toml` — which
158
+ * a spawned, SDK-owned host should not have to share. The data directory is
159
+ * independent of this (`dataDir`, always explicit).
160
+ */
161
+ configPath?: string;
162
+ /** How long to wait for the readiness line. Defaults to 120s (cold DB init). */
163
+ readyTimeoutMs?: number;
164
+ /**
165
+ * Extra environment variables, merged over the parent's `process.env`.
166
+ *
167
+ * An entry here **wins over the typed options above** (`marketDownload`,
168
+ * `configPath`): the raw map is the caller's most specific statement, and
169
+ * nothing this factory derives should silently overwrite it.
170
+ */
171
+ env?: Record<string, string | undefined>;
172
+ /** Working directory for the child. Defaults to the parent's cwd. */
173
+ cwd?: string;
174
+ /** Called once when the child exits, for any reason (crash included). */
175
+ onExit?: (info: SpawnExitInfo) => void;
176
+ }
177
+ /** How a spawned runtime process ended. */
178
+ interface SpawnExitInfo {
179
+ /** Exit code, or `null` when the process was terminated by a signal. */
180
+ code: number | null;
181
+ /** Terminating signal, or `null` on a normal exit. */
182
+ signal: string | null;
183
+ }
184
+ interface SpawnedServer {
185
+ readonly readiness: ReadinessInfo;
186
+ readonly dataDir: string;
187
+ /**
188
+ * Settles when the runtime process exits — including an unexpected crash,
189
+ * which is otherwise indistinguishable from "still starting up". Never
190
+ * rejects: inspect `code` / `signal`.
191
+ */
192
+ readonly exited: Promise<SpawnExitInfo>;
193
+ /** Terminate the child and remove the data dir when it was auto-created. */
194
+ close(): Promise<void>;
195
+ }
196
+ export declare function spawnAppServer(options?: SpawnOptions): Promise<SpawnedServer>;
197
+ //#endregion
198
+ //#region src/index.d.ts
199
+ export interface HarnessOptions extends SpawnOptions {
200
+ client: ClientInfo;
201
+ capabilities?: ClientCapabilities;
202
+ token?: string;
203
+ requestTimeoutMs?: number;
204
+ }
205
+ /**
206
+ * A connected `AppServerClient` that **owns the runtime process it spawned**
207
+ * (doc `31` §5 方案 B).
208
+ *
209
+ * Every `AppServerClient` member is available directly — `conversations`,
210
+ * `store`, `agents`, `onNotification`, … — because a factory that returned a
211
+ * *wrapper* was the lie this shape removes.
212
+ *
213
+ * Named after the external reference this shape follows (doc `31` §3.2):
214
+ * Kimi Code's `const harness = createKimiHarness(...)` hands back a `harness`
215
+ * you keep for the whole life of the run, not a one-shot launcher.
216
+ */
217
+ export interface Harness extends AppServerClient {
218
+ /** The child process: `readiness` / `dataDir` / `exited` / `close`. */
219
+ readonly server: SpawnedServer;
220
+ /**
221
+ * The handshake response captured at launch (**never null**).
222
+ *
223
+ * Not named `initializeResult`: that is a private field of the base class
224
+ * (`client.ts`), and the base's public `initializeInfo` is the *current*
225
+ * connection state — it goes back to `null` after `close()`. This member is
226
+ * the snapshot that proves which protocol fingerprint the session was
227
+ * admitted under.
228
+ */
229
+ readonly handshake: InitializeResult;
230
+ /**
231
+ * Unsubscribe → close the transport → terminate the child → remove an
232
+ * auto-created data dir. Idempotent.
233
+ *
234
+ * Deliberately widens the base's synchronous `close(): void`: awaiting a
235
+ * void-returning call is legal, so callers holding a plain `AppServerClient`
236
+ * are unaffected, while a launched session needs the promise to know the
237
+ * process is actually gone.
238
+ */
239
+ close(): Promise<void>;
240
+ }
241
+ /**
242
+ * Spawn a loopback runtime with its own data dir and return a connected,
243
+ * initialized client. Rejects non-loopback contact outright (P0-4): this
244
+ * entry point only ever dials the process it just spawned.
245
+ */
246
+ export declare function launchHarness(options: HarnessOptions): Promise<Harness>;
247
+ //#endregion
248
+ export type { ExportDeps, ExportResult, ReadinessInfo, SpawnExitInfo, SpawnOptions, SpawnedServer };