super-dsh 0.1.9 → 0.1.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.
- package/README.md +25 -3
- package/agent-agy/cordis.patch.yml +7 -4
- package/agent-agy/dist/agent.d.ts +12 -11
- package/agent-agy/dist/agy-auth-gateway.d.ts +124 -0
- package/agent-agy/dist/agy-auth-gateway.js +233 -0
- package/agent-agy/dist/agy-auth.d.ts +153 -0
- package/agent-agy/dist/agy-auth.js +179 -0
- package/agent-agy/dist/agy-cli-client.d.ts +39 -9
- package/agent-agy/dist/agy-cli-client.js +82 -18
- package/agent-agy/dist/agy-store.d.ts +8 -0
- package/agent-agy/dist/index.d.ts +46 -16
- package/agent-agy/dist/index.js +82 -56
- package/agent-agy/dist/models.d.ts +70 -0
- package/agent-agy/dist/models.js +102 -3
- package/agent-agy/package.json +7 -5
- package/agent-agy-sdk/cordis.patch.yml +58 -0
- package/agent-agy-sdk/dist/adapter.d.ts +15 -0
- package/agent-agy-sdk/dist/adapter.js +42 -0
- package/agent-agy-sdk/dist/agent-preset-agy.d.ts +27 -0
- package/agent-agy-sdk/dist/agent-preset-agy.js +32 -0
- package/agent-agy-sdk/dist/agent.d.ts +138 -0
- package/agent-agy-sdk/dist/agent.js +494 -0
- package/{agent-agy → agent-agy-sdk}/dist/agy-client.d.ts +26 -6
- package/{agent-agy → agent-agy-sdk}/dist/agy-client.js +43 -25
- package/agent-agy-sdk/dist/agy-sessions.d.ts +25 -0
- package/agent-agy-sdk/dist/agy-sessions.js +107 -0
- package/agent-agy-sdk/dist/agy-store.d.ts +39 -0
- package/agent-agy-sdk/dist/agy-store.js +83 -0
- package/agent-agy-sdk/dist/inbox.d.ts +26 -0
- package/agent-agy-sdk/dist/inbox.js +53 -0
- package/agent-agy-sdk/dist/index.d.ts +93 -0
- package/agent-agy-sdk/dist/index.js +476 -0
- package/agent-agy-sdk/dist/models.d.ts +41 -0
- package/agent-agy-sdk/dist/models.js +74 -0
- package/agent-agy-sdk/dist/sdk-venv.d.ts +76 -0
- package/agent-agy-sdk/dist/sdk-venv.js +173 -0
- package/agent-agy-sdk/dist/world-plugin.d.ts +10 -0
- package/agent-agy-sdk/dist/world-plugin.js +82 -0
- package/agent-agy-sdk/package.json +64 -0
- package/agent-codex/README.md +141 -36
- package/agent-codex/cordis.patch.yml +14 -10
- package/agent-codex/dist/adapter.js +64 -28
- package/agent-codex/dist/agent.js +255 -81
- package/agent-codex/dist/app-server-approvals.js +165 -0
- package/agent-codex/dist/app-server-client.js +723 -0
- package/agent-codex/dist/app-server-events.js +432 -0
- package/agent-codex/dist/app-server-protocol.js +95 -0
- package/agent-codex/dist/app-server-wire.js +299 -0
- package/agent-codex/dist/codex-launch.js +78 -0
- package/agent-codex/dist/codex-native-config.js +392 -0
- package/agent-codex/dist/codex-provider-gateway.js +402 -0
- package/agent-codex/dist/codex-providers.js +376 -0
- package/agent-codex/dist/codex-route.js +86 -0
- package/agent-codex/dist/index.js +256 -115
- package/agent-codex/dist/permission.js +75 -1
- package/agent-codex/package.json +1 -2
- package/agent-codex-sdk/README.md +79 -0
- package/agent-codex-sdk/cordis.patch.yml +81 -0
- package/agent-codex-sdk/dist/adapter.js +91 -0
- package/agent-codex-sdk/dist/agent-preset-codex.js +32 -0
- package/agent-codex-sdk/dist/agent.js +1085 -0
- package/agent-codex-sdk/dist/codex-native-config.js +392 -0
- package/agent-codex-sdk/dist/codex-provider-gateway.js +402 -0
- package/agent-codex-sdk/dist/codex-providers.js +376 -0
- package/agent-codex-sdk/dist/codex-route.js +86 -0
- package/{agent-codex/dist/codex-client.js → agent-codex-sdk/dist/codex-sdk-client.js} +253 -32
- package/agent-codex-sdk/dist/codex-sdk-launch.js +92 -0
- package/agent-codex-sdk/dist/codex-store.js +180 -0
- package/agent-codex-sdk/dist/inbox.js +53 -0
- package/agent-codex-sdk/dist/index.js +739 -0
- package/agent-codex-sdk/dist/permission.js +71 -0
- package/agent-codex-sdk/dist/sdk-runtime.js +307 -0
- package/agent-codex-sdk/dist/session-map.js +167 -0
- package/agent-codex-sdk/dist/world-plugin.js +93 -0
- package/agent-codex-sdk/package.json +79 -0
- package/agent-codex-sdk/scripts/fetch-sdk-runtime.mjs +57 -0
- package/agent-omp/README.md +72 -55
- package/agent-omp/dist/agent.js +36 -11
- package/agent-omp/dist/index.js +92 -52
- package/agent-omp/dist/lazy-rpc.js +11 -4
- package/agent-omp/dist/omp-cli.js +114 -97
- package/agent-omp/dist/omp-store.js +12 -4
- package/agent-omp/dist/permission.js +70 -5
- package/agent-omp/dist/rpc-client.js +409 -0
- package/agent-omp/dist/world-plugin.js +36 -3
- package/agent-omp/package.json +2 -6
- package/agent-omp-sdk/README.md +103 -0
- package/agent-omp-sdk/cordis.patch.yml +108 -0
- package/agent-omp-sdk/dist/adapter.d.ts +21 -0
- package/agent-omp-sdk/dist/adapter.js +36 -0
- package/agent-omp-sdk/dist/agent-preset-omp.d.ts +31 -0
- package/agent-omp-sdk/dist/agent-preset-omp.js +32 -0
- package/agent-omp-sdk/dist/agent.d.ts +64 -0
- package/agent-omp-sdk/dist/agent.js +1178 -0
- package/agent-omp-sdk/dist/discovery.d.ts +57 -0
- package/agent-omp-sdk/dist/discovery.js +116 -0
- package/agent-omp-sdk/dist/inbox.d.ts +28 -0
- package/agent-omp-sdk/dist/inbox.js +53 -0
- package/agent-omp-sdk/dist/index.d.ts +60 -0
- package/agent-omp-sdk/dist/index.js +632 -0
- package/agent-omp-sdk/dist/knobs.d.ts +34 -0
- package/agent-omp-sdk/dist/knobs.js +50 -0
- package/agent-omp-sdk/dist/lazy-rpc.d.ts +98 -0
- package/agent-omp-sdk/dist/lazy-rpc.js +178 -0
- package/agent-omp-sdk/dist/mobile/zoom-guard.d.ts +187 -0
- package/agent-omp-sdk/dist/mobile/zoom-guard.js +294 -0
- package/agent-omp-sdk/dist/mobile-boot.d.ts +49 -0
- package/agent-omp-sdk/dist/mobile-boot.js +38 -0
- package/agent-omp-sdk/dist/models.d.ts +39 -0
- package/agent-omp-sdk/dist/models.js +299 -0
- package/agent-omp-sdk/dist/omp-cli.d.ts +67 -0
- package/agent-omp-sdk/dist/omp-cli.js +164 -0
- package/agent-omp-sdk/dist/omp-disk-discovery.d.ts +27 -0
- package/agent-omp-sdk/dist/omp-disk-discovery.js +178 -0
- package/agent-omp-sdk/dist/omp-executable.d.ts +2 -0
- package/agent-omp-sdk/dist/omp-executable.js +30 -0
- package/agent-omp-sdk/dist/omp-store.d.ts +134 -0
- package/agent-omp-sdk/dist/omp-store.js +526 -0
- package/agent-omp-sdk/dist/pairing.d.ts +7 -0
- package/agent-omp-sdk/dist/pairing.js +45 -0
- package/agent-omp-sdk/dist/permission.d.ts +138 -0
- package/agent-omp-sdk/dist/permission.js +161 -0
- package/agent-omp-sdk/dist/protocol.d.ts +189 -0
- package/agent-omp-sdk/dist/rpc-types.d.ts +77 -0
- package/agent-omp-sdk/dist/rpc-types.js +1 -0
- package/agent-omp-sdk/dist/sdk-client.d.ts +160 -0
- package/{agent-omp → agent-omp-sdk}/dist/sdk-client.js +108 -56
- package/agent-omp-sdk/dist/sdk-runtime.d.ts +211 -0
- package/agent-omp-sdk/dist/sdk-runtime.js +418 -0
- package/agent-omp-sdk/dist/sidecar-client.d.ts +87 -0
- package/agent-omp-sdk/dist/sidecar-client.js +197 -0
- package/agent-omp-sdk/dist/store/adapter.d.ts +17 -0
- package/agent-omp-sdk/dist/store/adapter.js +47 -0
- package/agent-omp-sdk/dist/store/db.d.ts +70 -0
- package/agent-omp-sdk/dist/store/db.js +210 -0
- package/agent-omp-sdk/dist/store/index.d.ts +23 -0
- package/agent-omp-sdk/dist/store/index.js +59 -0
- package/agent-omp-sdk/dist/store/reconcile.d.ts +15 -0
- package/agent-omp-sdk/dist/store/reconcile.js +51 -0
- package/agent-omp-sdk/dist/store/schema.d.ts +8 -0
- package/agent-omp-sdk/dist/store/schema.js +40 -0
- package/agent-omp-sdk/dist/transport.d.ts +49 -0
- package/agent-omp-sdk/dist/transport.js +35 -0
- package/agent-omp-sdk/dist/world-home.d.ts +4 -0
- package/agent-omp-sdk/dist/world-home.js +23 -0
- package/agent-omp-sdk/dist/world-plugin.d.ts +10 -0
- package/agent-omp-sdk/dist/world-plugin.js +137 -0
- package/agent-omp-sdk/package.json +87 -0
- package/client/index.js +1115 -93
- package/cordis.patch.yml +64 -0
- package/package.json +17 -7
- package/superd-hub/dist/client/agent-settings.d.ts +156 -0
- package/superd-hub/dist/client/agent-settings.js +229 -0
- package/superd-hub/dist/client/roster.js +6 -0
- package/superd-hub/dist/client/runtime-settings-api.d.ts +76 -0
- package/superd-hub/dist/client/runtime-settings-api.js +137 -0
- package/superd-hub/dist/client/switch.d.ts +165 -0
- package/superd-hub/dist/client/switch.js +295 -0
- package/superd-hub/lib/client/index.js +1115 -93
- package/agent-codex/dist/models.js +0 -152
- package/agent-omp/dist/sidecar-client.js +0 -195
- /package/{agent-agy → agent-agy-sdk}/bridge/agy_bridge.py +0 -0
- /package/{agent-agy → agent-agy-sdk}/bridge/gemini_openai_server.mjs +0 -0
- /package/{agent-codex/dist/codex-events.js → agent-codex-sdk/dist/codex-sdk-events.js} +0 -0
- /package/{agent-omp → agent-omp-sdk}/dist/protocol.js +0 -0
- /package/{agent-omp → agent-omp-sdk}/sidecar/main.ts +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK-line replacement for `OmpRpcClient` (apps/omp-web/src/rpc.ts).
|
|
3
|
+
*
|
|
4
|
+
* Same public surface — `on` / `onFailure` / `sendRaw` / `send` / `getState`
|
|
5
|
+
* / `getMessages` / `getSessionStats` / `getSubagents` / `prompt` / `followUp`
|
|
6
|
+
* / `steer` / `setModel` / `abort` / `newSession` / `close` — so the ported
|
|
7
|
+
* adapter layer (agent.ts / index.ts / …) compiles unchanged. Instead of one
|
|
8
|
+
* `omp --mode rpc` child per session, all clients multiplex ONE bun sidecar
|
|
9
|
+
* process that embeds the OMP agent core via the SDK (app-level
|
|
10
|
+
* authStorage / modelRegistry are shared; sessions are handle-addressed).
|
|
11
|
+
*
|
|
12
|
+
* Type-only imports keep the OMP wire shapes identical to the RPC line.
|
|
13
|
+
*/
|
|
14
|
+
import type { OmpMessage, OmpSessionStats, OmpState, RpcEvent, RpcResponse } from "./rpc-types.js";
|
|
15
|
+
import { OmpSdkSidecar, type SidecarRuntimeFetch, type SidecarSpawn } from "./sidecar-client.js";
|
|
16
|
+
/**
|
|
17
|
+
* The per-process sidecar pool: ONE bun child shared by every session in this
|
|
18
|
+
* dsh process, refcounted, plus the two bridge-level call helpers that ride the
|
|
19
|
+
* same instance.
|
|
20
|
+
*/
|
|
21
|
+
export interface OmpSdkSidecarPool {
|
|
22
|
+
/** Start a session on the shared sidecar (the SDK has no separate client). */
|
|
23
|
+
spawnSession(args?: string[], cwd?: string): Promise<OmpSdkClient>;
|
|
24
|
+
/** Whether the shared sidecar exists right now (someone holds/wants it). */
|
|
25
|
+
isLive(): boolean;
|
|
26
|
+
/** One call ONLY when the sidecar is already alive; `undefined` when cold. */
|
|
27
|
+
callIfLive<T>(method: string, params?: unknown): Promise<T | undefined>;
|
|
28
|
+
/** One call that MAY start the sidecar (the real-need path). */
|
|
29
|
+
call<T>(method: string, params?: unknown): Promise<T>;
|
|
30
|
+
/** The world home whose `<home>/sdk-runtime/` the child runs from. */
|
|
31
|
+
readonly worldHome: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build a sidecar pool over one world home.
|
|
35
|
+
*
|
|
36
|
+
* Exactly ONE construction per acquire cycle: a leaked merge once left a
|
|
37
|
+
* duplicate pair here, so every acquire started a second child with `OMP_HOME`
|
|
38
|
+
* unset and abandoned the first (started, unreferenced, never stopped) — 350
|
|
39
|
+
* live processes down the line. Whatever else changes, this block must build
|
|
40
|
+
* the child at most once and must pin the app home on it.
|
|
41
|
+
*
|
|
42
|
+
* `runtimeFetch` is injectable ONLY so tests can prove the singleton invariant
|
|
43
|
+
* and the lazy trigger without downloading ~900 MB: production always uses
|
|
44
|
+
* {@link OmpSdkSidecar}'s default, which awaits `ensureSdkRuntime` inside
|
|
45
|
+
* `start()` — i.e. on the first real dispatch and nowhere else.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createOmpSdkSidecarPool(options: {
|
|
48
|
+
worldHome: string;
|
|
49
|
+
env?: Record<string, string>;
|
|
50
|
+
runtimeFetch?: SidecarRuntimeFetch;
|
|
51
|
+
/** Test seam: replace the child spawn (see {@link SidecarSpawn}). */
|
|
52
|
+
spawnProcess?: SidecarSpawn;
|
|
53
|
+
}): OmpSdkSidecarPool;
|
|
54
|
+
/**
|
|
55
|
+
* The default pool, built lazily on first use so importing this module never
|
|
56
|
+
* resolves a home, touches disk, or spawns anything.
|
|
57
|
+
*/
|
|
58
|
+
export declare function defaultOmpSdkSidecarPool(): OmpSdkSidecarPool;
|
|
59
|
+
/** Whether the shared sidecar exists right now (someone holds/wants it). */
|
|
60
|
+
export declare function isSharedSidecarLive(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Run one bridge-level call ONLY when the shared sidecar is already alive
|
|
63
|
+
* (a live session or an in-flight on-demand op holds it). Cold → `undefined`
|
|
64
|
+
* with ZERO processes: this is the periodic path's entry (model-catalog
|
|
65
|
+
* refresh) so the reconcile tick can never conjure a sidecar.
|
|
66
|
+
*/
|
|
67
|
+
export declare function callSharedIfLive<T = unknown>(method: string, params?: unknown): Promise<T | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* Run one bridge-level (non-session) data-plane call on the shared sidecar:
|
|
70
|
+
* acquire the refcounted singleton, await startup, call `method`, then release.
|
|
71
|
+
* Used by `omp-cli.ts` for `models.list` and `settings.modelRoles.get/set` so
|
|
72
|
+
* those paths share the SAME sidecar process as live sessions — never a second
|
|
73
|
+
* one. Fails with a rejection when the sidecar cannot start or the method
|
|
74
|
+
* throws; callers translate that into `undefined`/`false` (fail-soft).
|
|
75
|
+
*/
|
|
76
|
+
export declare function callShared<T = unknown>(method: string, params?: unknown): Promise<T>;
|
|
77
|
+
/** One OMP skill's discovery metadata (name/description + body location). */
|
|
78
|
+
export interface OmpSkill {
|
|
79
|
+
name: string;
|
|
80
|
+
description: string;
|
|
81
|
+
filePath: string;
|
|
82
|
+
baseDir: string;
|
|
83
|
+
source: string;
|
|
84
|
+
}
|
|
85
|
+
/** One OMP slash command's discovery metadata. */
|
|
86
|
+
export interface OmpSlashCommand {
|
|
87
|
+
name: string;
|
|
88
|
+
description: string;
|
|
89
|
+
content: string;
|
|
90
|
+
source: string;
|
|
91
|
+
}
|
|
92
|
+
/** Discover OMP skills for a workspace (fail-soft: [] on sidecar error). */
|
|
93
|
+
export declare function listSkills(cwd?: string): Promise<OmpSkill[]>;
|
|
94
|
+
/** Discover OMP slash commands for a workspace (fail-soft: [] on sidecar error). */
|
|
95
|
+
export declare function listSlashCommands(cwd?: string): Promise<OmpSlashCommand[]>;
|
|
96
|
+
export declare class OmpSdkClient {
|
|
97
|
+
#private;
|
|
98
|
+
constructor(sidecar: OmpSdkSidecar, handle: string, release: () => void);
|
|
99
|
+
/** Register an OMP session-title listener; returns the unsubscriber. */
|
|
100
|
+
onTitle(listener: (title: string) => void): () => void;
|
|
101
|
+
/** Register an OMP event listener; returns the unsubscriber. */
|
|
102
|
+
on(listener: (event: RpcEvent) => void): () => void;
|
|
103
|
+
/** Register a failure listener; returns the unsubscriber. */
|
|
104
|
+
onFailure(listener: (error: Error) => void): () => void;
|
|
105
|
+
/**
|
|
106
|
+
* Raw-command escape hatch. The SDK line has no stdio command channel, so
|
|
107
|
+
* the RPC-specific `extension_ui_response` (approval-card answers) is
|
|
108
|
+
* accepted and logged — approval flows route through SDK-side approval
|
|
109
|
+
* events instead (parity work item, see README).
|
|
110
|
+
*/
|
|
111
|
+
sendRaw(command: Record<string, unknown>): void;
|
|
112
|
+
/**
|
|
113
|
+
* Generic command sender for compatibility. The RPC line's free-form
|
|
114
|
+
* command channel does not exist here; supported commands are mapped onto
|
|
115
|
+
* sidecar methods, everything else fails loudly.
|
|
116
|
+
*/
|
|
117
|
+
send(command: Record<string, unknown>): Promise<RpcResponse>;
|
|
118
|
+
/** Query session state; returns the `get_state`-shaped payload. */
|
|
119
|
+
getState(): Promise<OmpState>;
|
|
120
|
+
/** Query the full conversation. */
|
|
121
|
+
getMessages(): Promise<OmpMessage[]>;
|
|
122
|
+
/** Live token/context/cost accounting (live sessions only). */
|
|
123
|
+
getSessionStats(): Promise<OmpSessionStats>;
|
|
124
|
+
/** Live subagent registry (fail-soft: [] until the SDK exposes it). */
|
|
125
|
+
getSubagents(): Promise<unknown[]>;
|
|
126
|
+
/** Render the live session's full base system prompt (fail-soft). */
|
|
127
|
+
getSystemPrompt(): Promise<string | undefined>;
|
|
128
|
+
/** Start a turn with a user prompt (fire-and-forget acceptance). */
|
|
129
|
+
prompt(message: string): Promise<RpcResponse>;
|
|
130
|
+
/** Queue a follow-up on a busy session. */
|
|
131
|
+
followUp(message: string): Promise<RpcResponse>;
|
|
132
|
+
/** Steer an in-flight turn. */
|
|
133
|
+
steer(message: string): Promise<RpcResponse>;
|
|
134
|
+
/** Select the active model by provider + model id. */
|
|
135
|
+
setModel(provider: string, modelId: string): Promise<RpcResponse>;
|
|
136
|
+
/** Abort the current streaming run. */
|
|
137
|
+
abort(): Promise<RpcResponse>;
|
|
138
|
+
/**
|
|
139
|
+
* Run OMP's own context compaction on the live session (the TUI /compact
|
|
140
|
+
* handler's exact call). Resolves when the compaction settles.
|
|
141
|
+
*/
|
|
142
|
+
compact(instructions?: string): Promise<RpcResponse>;
|
|
143
|
+
/** Context-usage snapshot for pre/post compact metering (fail-soft). */
|
|
144
|
+
contextUsage(): Promise<{
|
|
145
|
+
tokens?: number;
|
|
146
|
+
percent?: number;
|
|
147
|
+
} | undefined>;
|
|
148
|
+
/** Discard the current conversation and start a fresh session (same handle). */
|
|
149
|
+
newSession(): Promise<RpcResponse>;
|
|
150
|
+
/**
|
|
151
|
+
* Lazy-surface parity: a real client is born live, so "ensure started" is a
|
|
152
|
+
* no-op (LazyOmpRpc implements the real deferred spawn behind the same
|
|
153
|
+
* OmpAgentRpc interface).
|
|
154
|
+
*/
|
|
155
|
+
ensureStarted(): Promise<void>;
|
|
156
|
+
/** Always true for a real client (see OmpAgentRpc.spawned). */
|
|
157
|
+
get spawned(): boolean;
|
|
158
|
+
/** Discard the current conversation and start a fresh session (same handle). */
|
|
159
|
+
close(): void;
|
|
160
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OmpSdkSidecar } from "./sidecar-client.js";
|
|
2
2
|
import { OMP_HOME } from "./knobs.js";
|
|
3
|
+
import { resolveOmpSdkWorldHome } from "./world-home.js";
|
|
3
4
|
/**
|
|
4
5
|
* Parse the CLI args the RPC line passed to `omp --mode rpc`. Only the subset
|
|
5
6
|
* the bridge actually uses is understood; unknown flags fail loudly rather
|
|
@@ -31,34 +32,118 @@ let shared = null;
|
|
|
31
32
|
let sharedStart = null;
|
|
32
33
|
let refcount = 0;
|
|
33
34
|
/**
|
|
34
|
-
*
|
|
35
|
+
* Build a sidecar pool over one world home.
|
|
35
36
|
*
|
|
36
37
|
* Exactly ONE construction per acquire cycle: a leaked merge once left a
|
|
37
38
|
* duplicate pair here, so every acquire started a second child with `OMP_HOME`
|
|
38
39
|
* unset and abandoned the first (started, unreferenced, never stopped) — 350
|
|
39
40
|
* live processes down the line. Whatever else changes, this block must build
|
|
40
41
|
* the child at most once and must pin the app home on it.
|
|
42
|
+
*
|
|
43
|
+
* `runtimeFetch` is injectable ONLY so tests can prove the singleton invariant
|
|
44
|
+
* and the lazy trigger without downloading ~900 MB: production always uses
|
|
45
|
+
* {@link OmpSdkSidecar}'s default, which awaits `ensureSdkRuntime` inside
|
|
46
|
+
* `start()` — i.e. on the first real dispatch and nowhere else.
|
|
41
47
|
*/
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
export function createOmpSdkSidecarPool(options) {
|
|
49
|
+
let shared = null;
|
|
50
|
+
let sharedStart = null;
|
|
51
|
+
let refcount = 0;
|
|
52
|
+
function acquire() {
|
|
53
|
+
if (shared === null) {
|
|
54
|
+
shared = new OmpSdkSidecar({
|
|
55
|
+
worldHome: options.worldHome,
|
|
56
|
+
env: { ...(options.env ?? {}) },
|
|
57
|
+
...(options.runtimeFetch === undefined ? {} : { runtimeFetch: options.runtimeFetch }),
|
|
58
|
+
...(options.spawnProcess === undefined ? {} : { spawnProcess: options.spawnProcess }),
|
|
59
|
+
});
|
|
60
|
+
const start = shared.start().then(() => undefined);
|
|
61
|
+
// A late spawn/ready failure must not be an unhandled rejection: observe
|
|
62
|
+
// it here (the raw promise below still rejects for real callers).
|
|
63
|
+
void start.catch(() => undefined);
|
|
64
|
+
sharedStart = start;
|
|
65
|
+
}
|
|
66
|
+
refcount++;
|
|
67
|
+
return shared;
|
|
68
|
+
}
|
|
69
|
+
function release() {
|
|
70
|
+
refcount = Math.max(0, refcount - 1);
|
|
71
|
+
if (refcount === 0 && shared !== null) {
|
|
72
|
+
const dying = shared;
|
|
73
|
+
shared = null;
|
|
74
|
+
sharedStart = null;
|
|
75
|
+
void dying.stop();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function callWith(sidecar, method, params) {
|
|
79
|
+
await sharedStart;
|
|
80
|
+
return await sidecar.call(method, params);
|
|
46
81
|
}
|
|
47
|
-
|
|
48
|
-
|
|
82
|
+
return {
|
|
83
|
+
worldHome: options.worldHome,
|
|
84
|
+
async spawnSession(args = [], cwd) {
|
|
85
|
+
const { approvalMode, resumeFile } = parseSpawnArgs(args);
|
|
86
|
+
const sidecar = acquire();
|
|
87
|
+
try {
|
|
88
|
+
await sharedStart;
|
|
89
|
+
const created = await sidecar.call("session.create", {
|
|
90
|
+
cwd,
|
|
91
|
+
persistence: "file",
|
|
92
|
+
...(approvalMode === undefined ? {} : { approvalMode }),
|
|
93
|
+
...(resumeFile === undefined ? {} : { resumeFile }),
|
|
94
|
+
});
|
|
95
|
+
return new OmpSdkClient(sidecar, created.handle, release);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
release();
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
isLive() {
|
|
103
|
+
return shared !== null;
|
|
104
|
+
},
|
|
105
|
+
async callIfLive(method, params) {
|
|
106
|
+
if (shared === null)
|
|
107
|
+
return undefined;
|
|
108
|
+
const sidecar = acquire();
|
|
109
|
+
try {
|
|
110
|
+
return await callWith(sidecar, method, params);
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
release();
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
async call(method, params) {
|
|
117
|
+
const sidecar = acquire();
|
|
118
|
+
try {
|
|
119
|
+
return await callWith(sidecar, method, params);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
release();
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
};
|
|
49
126
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// The process-wide default pool (the world plugin's world home)
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
let defaultPool = null;
|
|
131
|
+
/**
|
|
132
|
+
* The default pool, built lazily on first use so importing this module never
|
|
133
|
+
* resolves a home, touches disk, or spawns anything.
|
|
134
|
+
*/
|
|
135
|
+
export function defaultOmpSdkSidecarPool() {
|
|
136
|
+
if (defaultPool === null) {
|
|
137
|
+
defaultPool = createOmpSdkSidecarPool({
|
|
138
|
+
worldHome: resolveOmpSdkWorldHome(),
|
|
139
|
+
env: { OMP_HOME },
|
|
140
|
+
});
|
|
57
141
|
}
|
|
142
|
+
return defaultPool;
|
|
58
143
|
}
|
|
59
144
|
/** Whether the shared sidecar exists right now (someone holds/wants it). */
|
|
60
145
|
export function isSharedSidecarLive() {
|
|
61
|
-
return
|
|
146
|
+
return defaultPool !== null && defaultPool.isLive();
|
|
62
147
|
}
|
|
63
148
|
/**
|
|
64
149
|
* Run one bridge-level call ONLY when the shared sidecar is already alive
|
|
@@ -67,16 +152,9 @@ export function isSharedSidecarLive() {
|
|
|
67
152
|
* refresh) so the reconcile tick can never conjure a sidecar.
|
|
68
153
|
*/
|
|
69
154
|
export async function callSharedIfLive(method, params) {
|
|
70
|
-
if (
|
|
155
|
+
if (defaultPool === null)
|
|
71
156
|
return undefined;
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
await sharedStart;
|
|
75
|
-
return await sidecar.call(method, params);
|
|
76
|
-
}
|
|
77
|
-
finally {
|
|
78
|
-
release();
|
|
79
|
-
}
|
|
157
|
+
return await defaultPool.callIfLive(method, params);
|
|
80
158
|
}
|
|
81
159
|
/**
|
|
82
160
|
* Run one bridge-level (non-session) data-plane call on the shared sidecar:
|
|
@@ -87,14 +165,7 @@ export async function callSharedIfLive(method, params) {
|
|
|
87
165
|
* throws; callers translate that into `undefined`/`false` (fail-soft).
|
|
88
166
|
*/
|
|
89
167
|
export async function callShared(method, params) {
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
await sharedStart;
|
|
93
|
-
return await sidecar.call(method, params);
|
|
94
|
-
}
|
|
95
|
-
finally {
|
|
96
|
-
release();
|
|
97
|
-
}
|
|
168
|
+
return await defaultOmpSdkSidecarPool().call(method, params);
|
|
98
169
|
}
|
|
99
170
|
/** Discover OMP skills for a workspace (fail-soft: [] on sidecar error). */
|
|
100
171
|
export async function listSkills(cwd) {
|
|
@@ -119,6 +190,8 @@ export async function listSlashCommands(cwd) {
|
|
|
119
190
|
// ---------------------------------------------------------------------------
|
|
120
191
|
export class OmpSdkClient {
|
|
121
192
|
#sidecar;
|
|
193
|
+
/** The pool's refcount release — dropped when this client closes. */
|
|
194
|
+
#release;
|
|
122
195
|
#handle;
|
|
123
196
|
#listeners = new Set();
|
|
124
197
|
#titleListeners = new Set();
|
|
@@ -126,7 +199,8 @@ export class OmpSdkClient {
|
|
|
126
199
|
#closed = false;
|
|
127
200
|
#failure = null;
|
|
128
201
|
#unsub;
|
|
129
|
-
constructor(sidecar, handle) {
|
|
202
|
+
constructor(sidecar, handle, release) {
|
|
203
|
+
this.#release = release;
|
|
130
204
|
this.#sidecar = sidecar;
|
|
131
205
|
this.#handle = handle;
|
|
132
206
|
this.#unsub = sidecar.onEvent((frame) => {
|
|
@@ -162,28 +236,6 @@ export class OmpSdkClient {
|
|
|
162
236
|
}
|
|
163
237
|
});
|
|
164
238
|
}
|
|
165
|
-
/**
|
|
166
|
-
* Start a session on the shared sidecar and resolve once it is ready.
|
|
167
|
-
* Mirrors `OmpRpcClient.spawn(args, cwd)`.
|
|
168
|
-
*/
|
|
169
|
-
static async spawn(args = [], cwd) {
|
|
170
|
-
const { approvalMode, resumeFile } = parseSpawnArgs(args);
|
|
171
|
-
const sidecar = acquire();
|
|
172
|
-
try {
|
|
173
|
-
await sharedStart;
|
|
174
|
-
const created = await sidecar.call("session.create", {
|
|
175
|
-
cwd,
|
|
176
|
-
persistence: "file",
|
|
177
|
-
...(approvalMode === undefined ? {} : { approvalMode }),
|
|
178
|
-
...(resumeFile === undefined ? {} : { resumeFile }),
|
|
179
|
-
});
|
|
180
|
-
return new OmpSdkClient(sidecar, created.handle);
|
|
181
|
-
}
|
|
182
|
-
catch (error) {
|
|
183
|
-
release();
|
|
184
|
-
throw error;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
239
|
/** Register an OMP session-title listener; returns the unsubscriber. */
|
|
188
240
|
onTitle(listener) {
|
|
189
241
|
this.#titleListeners.add(listener);
|
|
@@ -352,7 +404,7 @@ export class OmpSdkClient {
|
|
|
352
404
|
this.#closed = true;
|
|
353
405
|
this.#unsub();
|
|
354
406
|
void this.#sidecar.call("session.dispose", { handle: this.#handle }).catch(() => { });
|
|
355
|
-
release();
|
|
407
|
+
this.#release();
|
|
356
408
|
this.#fail(new Error("omp sdk client closed"));
|
|
357
409
|
}
|
|
358
410
|
#call(method, params) {
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sdk-runtime.ts — the lazy, durable SDK runtime the opt-in `omp-sdk` line runs on.
|
|
3
|
+
*
|
|
4
|
+
* 2026-10-03 user ruling (spec §2.4): this package declares NO SDK and NO `bun`
|
|
5
|
+
* dependency and ships NO postinstall/allow-scripts hook. Nothing is fetched at
|
|
6
|
+
* install time; the FIRST real prompt fetches the runtime into the world home,
|
|
7
|
+
* where it is durable across sessions, restarts and package upgrades. A second
|
|
8
|
+
* use reuses it (idempotent), and a FAILED fetch leaves a trace on disk instead
|
|
9
|
+
* of silently degrading into a confusing sidecar crash.
|
|
10
|
+
*
|
|
11
|
+
* Why the world home rather than the package root: the package root is the
|
|
12
|
+
* installed tarball — read-only in every real consumer install, and shared by
|
|
13
|
+
* every world. The world home is per-runtime, writable, and already the home of
|
|
14
|
+
* this adapter's own state.
|
|
15
|
+
*
|
|
16
|
+
* What lands where (bun resolves `node_modules` from the runtime dir, so the
|
|
17
|
+
* sidecar must live there):
|
|
18
|
+
*
|
|
19
|
+
* <worldHome>/sdk-runtime/
|
|
20
|
+
* bin/bun (a) the bun release, unzipped into place
|
|
21
|
+
* package.json / node_modules/ (b) installed with that bun
|
|
22
|
+
* sidecar/main.ts (c) copied from this package
|
|
23
|
+
* dist/protocol.js (c) copied from this package
|
|
24
|
+
* <worldHome>/sdk-runtime.json marker — written LAST, its presence is the contract
|
|
25
|
+
* <worldHome>/sdk-runtime.lock atomic (mkdir) bootstrap lock
|
|
26
|
+
* <worldHome>/sdk-runtime.error.log written ONLY by a failed fetch
|
|
27
|
+
*
|
|
28
|
+
* Every step is idempotent, so a half-built runtime heals in place: an existing
|
|
29
|
+
* `bin/bun` is not re-downloaded, and a missing marker simply re-runs the
|
|
30
|
+
* remaining steps.
|
|
31
|
+
*
|
|
32
|
+
* Measured cost (2026-10-03 probe, spec §1 + §3.3). bun release zip 36.6 MB,
|
|
33
|
+
* `bun add` ~2-5 s. A FULL install is 1133 MB / 114 packages, but the largest
|
|
34
|
+
* chunk of that is dead weight here: `@huggingface/transformers` +
|
|
35
|
+
* `onnxruntime-{node,web}` (~234 MB) come in through `optionalDependencies` and
|
|
36
|
+
* their native postinstall is blocked by `--ignore-scripts` anyway.
|
|
37
|
+
* `--omit=optional` alone is 535 MB but BREAKS the import — `@oh-my-pi/pi-natives`
|
|
38
|
+
* declares its platform binding in `optionalDependencies`, so bun drops
|
|
39
|
+
* `@oh-my-pi/pi-natives-<platform>` and the sidecar dies with `Failed to load
|
|
40
|
+
* pi_natives native addon for <platform>`. Re-adding that platform package
|
|
41
|
+
* explicitly is the fix: **899 MB / 84 packages, import passes**. Escape hatch:
|
|
42
|
+
* `OMP_SDK_KEEP_OPTIONAL=1` drops `--omit=optional` and reinstates the full
|
|
43
|
+
* 1133 MB tree.
|
|
44
|
+
*
|
|
45
|
+
* bun's install cache is another ~1.2 GB, so it is redirected to
|
|
46
|
+
* `<runtime>/.cache` and deleted once the install succeeds.
|
|
47
|
+
*
|
|
48
|
+
* The pin defaults to 18.5.0 because 18.4.9 is BROKEN for source-level import:
|
|
49
|
+
* its `src/sdk.ts` imports `./ratchet/prelude` extensionless, so bun resolves
|
|
50
|
+
* the template file `src/ratchet/prelude.js` instead of the real module and
|
|
51
|
+
* `bun -e 'await import("@oh-my-pi/pi-coding-agent")'` dies with
|
|
52
|
+
* `SyntaxError: Export named 'createRatchetPrelude' not found in module
|
|
53
|
+
* '.../src/ratchet/prelude.js'`. Upstream fixed it in 18.5.0 by renaming the
|
|
54
|
+
* real module to `./ratchet/prelude-definition`. The smoke step in
|
|
55
|
+
* {@link ensureSdkRuntime} pins that diagnosis down at fetch time; 18.2.11 is
|
|
56
|
+
* the last known-good fallback (`OMP_SDK_PACKAGE_VERSION=18.2.11`).
|
|
57
|
+
*
|
|
58
|
+
* Probe evidence: 18.5.0 slim = 84 packages / 899 MB / smoke ✅; 18.5.0 full =
|
|
59
|
+
* 114 packages / 1133 MB / smoke ✅; 18.4.9 = smoke ❌ (`createRatchetPrelude`);
|
|
60
|
+
* 18.2.11 = smoke ✅ (no `src/ratchet/` at all).
|
|
61
|
+
*/
|
|
62
|
+
/** The coding-agent package the sidecar imports (same program as the `omp` binary). */
|
|
63
|
+
export declare const SDK_PACKAGE = "@oh-my-pi/pi-coding-agent";
|
|
64
|
+
/** Prefix of the per-platform native binding package (`-<platform>` is appended). */
|
|
65
|
+
export declare const SDK_NATIVES_PACKAGE_PREFIX = "@oh-my-pi/pi-natives";
|
|
66
|
+
/**
|
|
67
|
+
* Pin of {@link SDK_PACKAGE} (and of the native binding package). Defaults to
|
|
68
|
+
* the operator's local `omp --version` family (18.5.0) so both OMP faces run
|
|
69
|
+
* the same code; `OMP_SDK_PACKAGE_VERSION` overrides it. Do not go back to
|
|
70
|
+
* 18.4.9 — see the module doc (broken source-level import).
|
|
71
|
+
*/
|
|
72
|
+
export declare const SDK_PACKAGE_VERSION: string;
|
|
73
|
+
/** The bun release the sidecar runs on; `OMP_SDK_BUN_VERSION` overrides it. */
|
|
74
|
+
export declare const SDK_BUN_VERSION: string;
|
|
75
|
+
/** The bun release platform archive this adapter fetches (worlds run on linux-x64). */
|
|
76
|
+
export declare const SDK_BUN_PLATFORM = "linux-x64";
|
|
77
|
+
/** `@oh-my-pi/pi-natives` ships one binding package per platform tuple. */
|
|
78
|
+
export type SdkNativesPlatform = "linux-x64" | "linux-arm64" | "darwin-x64" | "darwin-arm64" | "win32-x64" | "win32-arm64";
|
|
79
|
+
/**
|
|
80
|
+
* Pure `process.platform`/`process.arch` → natives binding key.
|
|
81
|
+
* Throws for a tuple `@oh-my-pi/pi-natives` does not publish (fail loud rather
|
|
82
|
+
* than install a runtime whose addon cannot load).
|
|
83
|
+
*/
|
|
84
|
+
export declare function sdkNativesPlatform(platform?: string, arch?: string): SdkNativesPlatform;
|
|
85
|
+
/** The exact natives binding package name for a platform key. */
|
|
86
|
+
export declare function sdkNativesPackage(platform: SdkNativesPlatform): string;
|
|
87
|
+
/**
|
|
88
|
+
* The install argv (pure, so the slim-install recipe is testable).
|
|
89
|
+
*
|
|
90
|
+
* `--omit=optional` drops the ~234 MB transformers/onnxruntime weight; the
|
|
91
|
+
* explicit natives package restores the one optional dependency the import
|
|
92
|
+
* actually needs. `keepOptional` (env `OMP_SDK_KEEP_OPTIONAL=1`) reinstates the
|
|
93
|
+
* full tree.
|
|
94
|
+
*/
|
|
95
|
+
export declare function sdkInstallArgv(packageVersion: string, platform: SdkNativesPlatform, keepOptional?: boolean): string[];
|
|
96
|
+
/** The exact GitHub release asset URL of a bun version's linux-x64 build. */
|
|
97
|
+
export declare function bunReleaseZipUrl(bunVersion: string): string;
|
|
98
|
+
/** Layout of the durable SDK runtime inside a world home. */
|
|
99
|
+
export interface SdkRuntimeLayout {
|
|
100
|
+
/** The runtime root (holds `bin/`, `node_modules/`, `sidecar/`, `dist/`). */
|
|
101
|
+
dir: string;
|
|
102
|
+
/** The fetched bun binary the sidecar is spawned with. */
|
|
103
|
+
bun: string;
|
|
104
|
+
/** Written LAST; presence + matching identity means the runtime is complete. */
|
|
105
|
+
marker: string;
|
|
106
|
+
/** Bootstrap lock directory (mkdir is atomic on POSIX). */
|
|
107
|
+
lock: string;
|
|
108
|
+
/** Failure trace — only ever written by a failed fetch. */
|
|
109
|
+
errorLog: string;
|
|
110
|
+
/** Destination directory of the copied sidecar. */
|
|
111
|
+
sidecarDir: string;
|
|
112
|
+
/** The sidecar entrypoint inside the runtime dir (bun resolves modules from here). */
|
|
113
|
+
sidecarEntry: string;
|
|
114
|
+
/** Destination directory of the copied compiled protocol module. */
|
|
115
|
+
protocolDir: string;
|
|
116
|
+
}
|
|
117
|
+
export declare function sdkRuntimeLayout(worldHome: string): SdkRuntimeLayout;
|
|
118
|
+
/** Destination of the compiled protocol module copied beside the sidecar. */
|
|
119
|
+
export declare function sdkRuntimeProtocolEntry(layout: SdkRuntimeLayout): string;
|
|
120
|
+
/** The install marker: identity of the runtime plus where/when it landed. */
|
|
121
|
+
export interface SdkRuntimeRecord {
|
|
122
|
+
/** Version of this adapter package at fetch time. */
|
|
123
|
+
pluginVersion: string;
|
|
124
|
+
/** Installed version of {@link SDK_PACKAGE}. */
|
|
125
|
+
packageVersion: string;
|
|
126
|
+
/** Installed bun version. */
|
|
127
|
+
bunVersion: string;
|
|
128
|
+
/** Absolute path of the fetched bun binary. */
|
|
129
|
+
bunPath: string;
|
|
130
|
+
/** ISO timestamp of the successful fetch. */
|
|
131
|
+
installedAt: string;
|
|
132
|
+
}
|
|
133
|
+
/** The part of a record a caller can know before fetching (used for the compare). */
|
|
134
|
+
export interface SdkRuntimeIdentity {
|
|
135
|
+
pluginVersion: string;
|
|
136
|
+
packageVersion: string;
|
|
137
|
+
bunVersion: string;
|
|
138
|
+
}
|
|
139
|
+
/** Read the install marker; undefined when absent or unreadable. */
|
|
140
|
+
export declare function readSdkRuntimeRecord(worldHome: string): SdkRuntimeRecord | undefined;
|
|
141
|
+
/**
|
|
142
|
+
* Fast path: the runtime is complete AND matches `identity` → its record.
|
|
143
|
+
*
|
|
144
|
+
* Returns undefined when the marker is absent/corrupt, when any identity field
|
|
145
|
+
* differs (the adapter or a pin changed), or when the recorded bun binary is
|
|
146
|
+
* gone — in every such case the caller must (re)fetch.
|
|
147
|
+
*/
|
|
148
|
+
export declare function sdkRuntimeReady(worldHome: string, identity: SdkRuntimeIdentity): SdkRuntimeRecord | undefined;
|
|
149
|
+
/** Options for a single {@link SdkRuntimeDeps.run} invocation. */
|
|
150
|
+
export interface SdkRuntimeRunOptions {
|
|
151
|
+
/** Working directory for the command. */
|
|
152
|
+
cwd?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Environment OVERRIDES merged on top of the inherited environment (so PATH
|
|
155
|
+
* and friends survive). Used to redirect bun's install cache and to keep the
|
|
156
|
+
* smoke import out of the operator's native `~/.omp`.
|
|
157
|
+
*/
|
|
158
|
+
env?: Record<string, string | undefined>;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Everything {@link ensureSdkRuntime} touches outside its own filesystem work,
|
|
162
|
+
* injected so the bootstrap is testable with zero network and zero real bun.
|
|
163
|
+
*/
|
|
164
|
+
export interface SdkRuntimeDeps {
|
|
165
|
+
/** Fetch `url` to the file `dest` (real implementation shells out to curl). */
|
|
166
|
+
download(url: string, dest: string): Promise<void>;
|
|
167
|
+
/** Run a command to completion; must throw on a non-zero exit. */
|
|
168
|
+
run(cmd: string, args: string[], opts?: SdkRuntimeRunOptions): Promise<void>;
|
|
169
|
+
/** Copy a regular file (the sidecar source and the compiled protocol module). */
|
|
170
|
+
copy(from: string, to: string): void;
|
|
171
|
+
/** Version of this adapter package — part of the marker identity. */
|
|
172
|
+
pluginVersion: string;
|
|
173
|
+
/** Absolute path of this package's root (`sidecar/`, `dist/` sources live there). */
|
|
174
|
+
pluginDir: string;
|
|
175
|
+
/** One human-readable progress line. */
|
|
176
|
+
log(line: string): void;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The PRODUCTION {@link SdkRuntimeDeps}: everything the bootstrap touches
|
|
180
|
+
* outside its own filesystem work, wired to real OS primitives.
|
|
181
|
+
*
|
|
182
|
+
* Kept IN THE MODULE (not in `scripts/fetch-sdk-runtime.mjs`) so the manual
|
|
183
|
+
* pre-warm script and the first-prompt lazy fetch (sidecar `start()`) share ONE
|
|
184
|
+
* implementation: a second copy is exactly how the two paths would drift.
|
|
185
|
+
*
|
|
186
|
+
* `pluginDir` defaults to this package's root (the parent of the compiled
|
|
187
|
+
* `dist/`), from which the sidecar source and the compiled protocol module are
|
|
188
|
+
* copied into the runtime; the marker identity reads the package's own version.
|
|
189
|
+
*
|
|
190
|
+
* @param pluginDir - package root holding `sidecar/main.ts` + `dist/protocol.js`.
|
|
191
|
+
* @returns deps for {@link ensureSdkRuntime}.
|
|
192
|
+
*/
|
|
193
|
+
export declare function createSdkRuntimeDeps(pluginDir?: string): SdkRuntimeDeps;
|
|
194
|
+
/** The version of the adapter package at `pluginDir` (the marker identity half). */
|
|
195
|
+
export declare function readPluginVersion(pluginDir: string): string;
|
|
196
|
+
/**
|
|
197
|
+
* Return the record for `<worldHome>`'s durable SDK runtime, fetching it first
|
|
198
|
+
* when it is absent, incomplete or does not match the running adapter.
|
|
199
|
+
*
|
|
200
|
+
* Idempotent: a complete, matching runtime short-circuits without touching the
|
|
201
|
+
* network. Concurrent callers: the bootstrap is guarded by a `mkdir` lock — a
|
|
202
|
+
* second caller that finds a FRESH lock throws a clear "fetch in progress"
|
|
203
|
+
* error (no waiting; the SDK transport is a per-process singleton, so the real
|
|
204
|
+
* race is another dsh process on the same world home), while an abandoned lock
|
|
205
|
+
* (older than {@link LOCK_STALE_MS}) is reclaimed so a crashed fetch cannot
|
|
206
|
+
* brick the line.
|
|
207
|
+
*
|
|
208
|
+
* Failures append to `<worldHome>/sdk-runtime.error.log` and throw a single
|
|
209
|
+
* actionable error — never a partial runtime behind a success marker.
|
|
210
|
+
*/
|
|
211
|
+
export declare function ensureSdkRuntime(worldHome: string, deps: SdkRuntimeDeps): Promise<SdkRuntimeRecord>;
|