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
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codex model catalog for the Dash model selector (AW-E Task 5).
|
|
3
|
-
*
|
|
4
|
-
* Reads the adapter's nested codex home the native way (spec S7: the native
|
|
5
|
-
* app self-populates its config; we read, never write):
|
|
6
|
-
* - `config.toml` top-level keys `model`, `model_reasoning_effort`,
|
|
7
|
-
* `model_provider`, `model_catalog_json` (minimal line parser — the full
|
|
8
|
-
* TOML grammar is deliberately not implemented; unknown lines are skipped);
|
|
9
|
-
* - `model_catalog_json` (relative to the codex home) → per-model identity
|
|
10
|
-
* fields (slug / display_name / default_reasoning_level / context_window).
|
|
11
|
-
*
|
|
12
|
-
* The frozen multi-agent-ctx models.ts used the app-server `model/list` —
|
|
13
|
-
* that surface does not exist on the SDK line, so the TOML+catalog pair is
|
|
14
|
-
* the only catalog source. Fail-soft everywhere: any missing/unparsable piece
|
|
15
|
-
* degrades toward a single `codex-default` placeholder, never a throw.
|
|
16
|
-
*/
|
|
17
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
18
|
-
import { join } from "node:path";
|
|
19
|
-
import { resolveCodexHome, useCodexHome } from "./codex-store.js";
|
|
20
|
-
/** Minimal top-level TOML scan: `key = value` pairs + `[section]` headers. */
|
|
21
|
-
function parseTopLevelToml(text) {
|
|
22
|
-
const values = {};
|
|
23
|
-
const sections = new Map();
|
|
24
|
-
let current = null;
|
|
25
|
-
let currentName = "";
|
|
26
|
-
for (const rawLine of text.split("\n")) {
|
|
27
|
-
const lineText = rawLine.trim();
|
|
28
|
-
if (lineText === "" || lineText.startsWith("#"))
|
|
29
|
-
continue;
|
|
30
|
-
const header = /^\[([^\]]+)\]$/.exec(lineText);
|
|
31
|
-
if (header !== null) {
|
|
32
|
-
currentName = header[1].trim();
|
|
33
|
-
current = {};
|
|
34
|
-
sections.set(currentName, current);
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
const eq = lineText.indexOf("=");
|
|
38
|
-
if (eq <= 0)
|
|
39
|
-
continue; // broken line — tolerated
|
|
40
|
-
const key = lineText.slice(0, eq).trim();
|
|
41
|
-
let value = lineText.slice(eq + 1).trim();
|
|
42
|
-
if (value.startsWith('"') && value.endsWith('"') && value.length >= 2) {
|
|
43
|
-
value = value.slice(1, -1);
|
|
44
|
-
}
|
|
45
|
-
else if (value.startsWith("'") && value.endsWith("'") && value.length >= 2) {
|
|
46
|
-
value = value.slice(1, -1);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
// strip trailing comment on bare values; keep numbers/bools as strings
|
|
50
|
-
const hash = value.indexOf(" #");
|
|
51
|
-
if (hash >= 0)
|
|
52
|
-
value = value.slice(0, hash).trim();
|
|
53
|
-
}
|
|
54
|
-
if (current !== null && currentName !== "")
|
|
55
|
-
current[key] = value;
|
|
56
|
-
else
|
|
57
|
-
values[key] = value;
|
|
58
|
-
}
|
|
59
|
-
return { values, sections };
|
|
60
|
-
}
|
|
61
|
-
/** The fail-soft placeholder model id (never sent to the real codex binary). */
|
|
62
|
-
export const CODEX_DEFAULT_MODEL_PLACEHOLDER = "codex-default";
|
|
63
|
-
/** The fail-soft placeholder: one entry, no claims about the runtime. */
|
|
64
|
-
function placeholder(defaultModel = CODEX_DEFAULT_MODEL_PLACEHOLDER) {
|
|
65
|
-
return { defaultModel, models: [{ id: defaultModel, label: "Codex default" }] };
|
|
66
|
-
}
|
|
67
|
-
/** Read the model catalog out of the codex home (fail-soft, never throws). */
|
|
68
|
-
export function readCodexModelCatalog(codexHome) {
|
|
69
|
-
let home;
|
|
70
|
-
try {
|
|
71
|
-
home = codexHome !== undefined ? useCodexHome(codexHome) : resolveCodexHome();
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
return placeholder();
|
|
75
|
-
}
|
|
76
|
-
let configValues = {};
|
|
77
|
-
let providerName;
|
|
78
|
-
const configPath = join(home, "config.toml");
|
|
79
|
-
if (existsSync(configPath)) {
|
|
80
|
-
try {
|
|
81
|
-
const parsed = parseTopLevelToml(readFileSync(configPath, "utf8"));
|
|
82
|
-
configValues = parsed.values;
|
|
83
|
-
const providerId = configValues["model_provider"];
|
|
84
|
-
if (providerId !== undefined) {
|
|
85
|
-
const section = parsed.sections.get(`model_providers.${providerId}`);
|
|
86
|
-
if (section !== undefined && typeof section["name"] === "string" && section["name"] !== "") {
|
|
87
|
-
providerName = section["name"];
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
return placeholder();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const configModel = configValues["model"];
|
|
96
|
-
const catalogRel = configValues["model_catalog_json"];
|
|
97
|
-
const entries = [];
|
|
98
|
-
if (catalogRel !== undefined && catalogRel !== "") {
|
|
99
|
-
const catalogPath = join(home, catalogRel);
|
|
100
|
-
if (existsSync(catalogPath)) {
|
|
101
|
-
try {
|
|
102
|
-
const parsed = JSON.parse(readFileSync(catalogPath, "utf8"));
|
|
103
|
-
const models = parsed?.models;
|
|
104
|
-
if (Array.isArray(models)) {
|
|
105
|
-
for (const raw of models) {
|
|
106
|
-
if (raw === null || typeof raw !== "object")
|
|
107
|
-
continue;
|
|
108
|
-
const m = raw;
|
|
109
|
-
const slug = m["slug"];
|
|
110
|
-
if (typeof slug !== "string" || slug === "")
|
|
111
|
-
continue;
|
|
112
|
-
const label = typeof m["display_name"] === "string" && m["display_name"] !== "" ? m["display_name"] : slug;
|
|
113
|
-
const entry = {
|
|
114
|
-
id: slug,
|
|
115
|
-
label,
|
|
116
|
-
...(typeof m["default_reasoning_level"] === "string" && m["default_reasoning_level"] !== ""
|
|
117
|
-
? { reasoningEffort: m["default_reasoning_level"] }
|
|
118
|
-
: {}),
|
|
119
|
-
...(typeof m["context_window"] === "number" && Number.isSafeInteger(m["context_window"])
|
|
120
|
-
? { contextWindow: m["context_window"] }
|
|
121
|
-
: {}),
|
|
122
|
-
};
|
|
123
|
-
entries.push(entry);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
// unparsable catalog — fall through to the config-model entry
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (entries.length === 0) {
|
|
133
|
-
if (configModel === undefined || configModel === "")
|
|
134
|
-
return placeholder();
|
|
135
|
-
return {
|
|
136
|
-
defaultModel: configModel,
|
|
137
|
-
...(providerName === undefined ? {} : { provider: providerName }),
|
|
138
|
-
models: [{ id: configModel, label: configModel }],
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
// The configured model is what sessions actually run, so it must be
|
|
142
|
-
// selectable even when the provider's own catalog file does not list it
|
|
143
|
-
// (cc-switch ships a fixed list; `config.toml` may name a newer entry).
|
|
144
|
-
const models = configModel !== undefined && configModel !== "" && !entries.some((entry) => entry.id === configModel)
|
|
145
|
-
? [{ id: configModel, label: configModel }, ...entries]
|
|
146
|
-
: entries;
|
|
147
|
-
return {
|
|
148
|
-
defaultModel: configModel !== undefined && configModel !== "" ? configModel : entries[0].id,
|
|
149
|
-
...(providerName === undefined ? {} : { provider: providerName }),
|
|
150
|
-
models,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Node-side client for the agent-omp bun sidecar.
|
|
3
|
-
* Spawns `bun run sidecar/main.ts`, speaks the v0 JSON-lines protocol,
|
|
4
|
-
* correlates requests by id and dispatches pushed event frames.
|
|
5
|
-
*/
|
|
6
|
-
import { spawn } from "node:child_process";
|
|
7
|
-
import { existsSync } from "node:fs";
|
|
8
|
-
import { createRequire } from "node:module";
|
|
9
|
-
import path from "node:path";
|
|
10
|
-
import { fileURLToPath } from "node:url";
|
|
11
|
-
import { PROTOCOL_VERSION, } from "./protocol.js";
|
|
12
|
-
const require = createRequire(import.meta.url);
|
|
13
|
-
const pkgDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
14
|
-
/**
|
|
15
|
-
* Locate the bun binary for the sidecar spawn.
|
|
16
|
-
*
|
|
17
|
-
* Layout-dependent: a checkout has it at `<pkg>/node_modules/.bin/bun`, but a
|
|
18
|
-
* pnpm-hoisted profile install (prod) puts binaries in the profile root's
|
|
19
|
-
* `node_modules/.bin` with the package itself symlinked under
|
|
20
|
-
* `node_modules/<name>` — so walk the ancestors' .bin directories, and fall
|
|
21
|
-
* back to a plain `bun` on PATH.
|
|
22
|
-
*/
|
|
23
|
-
function resolveBunBinary(fromDir) {
|
|
24
|
-
const local = path.join(fromDir, "node_modules", ".bin", "bun");
|
|
25
|
-
if (existsSync(local))
|
|
26
|
-
return local;
|
|
27
|
-
let dir = fromDir;
|
|
28
|
-
for (let i = 0; i < 8; i++) {
|
|
29
|
-
const parent = path.dirname(dir);
|
|
30
|
-
if (parent === dir)
|
|
31
|
-
break;
|
|
32
|
-
dir = parent;
|
|
33
|
-
const candidate = path.join(dir, "node_modules", ".bin", "bun");
|
|
34
|
-
if (existsSync(candidate))
|
|
35
|
-
return candidate;
|
|
36
|
-
}
|
|
37
|
-
return "bun";
|
|
38
|
-
}
|
|
39
|
-
export class OmpSdkSidecar {
|
|
40
|
-
options;
|
|
41
|
-
proc = null;
|
|
42
|
-
nextId = 1;
|
|
43
|
-
pending = new Map();
|
|
44
|
-
eventHandlers = new Set();
|
|
45
|
-
readyPromise = null;
|
|
46
|
-
buffer = "";
|
|
47
|
-
startError = null;
|
|
48
|
-
constructor(options = {}) {
|
|
49
|
-
this.options = options;
|
|
50
|
-
}
|
|
51
|
-
get started() {
|
|
52
|
-
return this.proc !== null;
|
|
53
|
-
}
|
|
54
|
-
onEvent(handler) {
|
|
55
|
-
this.eventHandlers.add(handler);
|
|
56
|
-
return () => this.eventHandlers.delete(handler);
|
|
57
|
-
}
|
|
58
|
-
async start() {
|
|
59
|
-
if (this.readyPromise)
|
|
60
|
-
return this.readyPromise;
|
|
61
|
-
this.readyPromise = new Promise((resolve, reject) => {
|
|
62
|
-
const bunBin = resolveBunBinary(pkgDir);
|
|
63
|
-
const sidecarEntry = path.join(pkgDir, "sidecar", "main.ts");
|
|
64
|
-
const env = {
|
|
65
|
-
...process.env,
|
|
66
|
-
...this.options.env,
|
|
67
|
-
};
|
|
68
|
-
let proc;
|
|
69
|
-
try {
|
|
70
|
-
proc = spawn(bunBin, ["run", sidecarEntry], {
|
|
71
|
-
cwd: this.options.cwd ?? pkgDir,
|
|
72
|
-
env,
|
|
73
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
catch (err) {
|
|
77
|
-
reject(new Error(`failed to spawn bun sidecar: ${err.message}`));
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
this.proc = proc;
|
|
81
|
-
const timeout = setTimeout(() => reject(new Error(`sidecar ready timeout (60s): ${this.startError ?? "no output"}`)), 60_000);
|
|
82
|
-
const settle = (fn) => { clearTimeout(timeout); fn(); };
|
|
83
|
-
// A dead sidecar surfaces as EPIPE on stdin writes; keep a permanent
|
|
84
|
-
// no-op error sink so no window exists where the stream throws out of the
|
|
85
|
-
// event loop (per-call degradation is handled by #writeSafe).
|
|
86
|
-
proc.stdin.on("error", () => { });
|
|
87
|
-
proc.stdout.setEncoding("utf8");
|
|
88
|
-
proc.stdout.on("data", (chunk) => this.consume(chunk, (r) => settle(() => resolve(r))));
|
|
89
|
-
proc.stderr.setEncoding("utf8");
|
|
90
|
-
proc.stderr.on("data", (chunk) => {
|
|
91
|
-
this.startError = (this.startError ?? "") + chunk;
|
|
92
|
-
process.stderr.write(`[omp-sdk-sidecar] ${chunk}`);
|
|
93
|
-
});
|
|
94
|
-
proc.on("exit", (code, signal) => {
|
|
95
|
-
settle(() => reject(new Error(`sidecar exited before ready (${code ?? signal}): ${this.startError ?? ""}`)));
|
|
96
|
-
for (const [, p] of this.pending)
|
|
97
|
-
p.reject(new Error(`sidecar exited (${code ?? signal})`));
|
|
98
|
-
this.pending.clear();
|
|
99
|
-
this.proc = null;
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
return this.readyPromise;
|
|
103
|
-
}
|
|
104
|
-
consume(chunk, onReady) {
|
|
105
|
-
this.buffer += chunk;
|
|
106
|
-
let nl;
|
|
107
|
-
while ((nl = this.buffer.indexOf("\n")) >= 0) {
|
|
108
|
-
const raw = this.buffer.slice(0, nl).trim();
|
|
109
|
-
this.buffer = this.buffer.slice(nl + 1);
|
|
110
|
-
if (!raw)
|
|
111
|
-
continue;
|
|
112
|
-
let frame;
|
|
113
|
-
try {
|
|
114
|
-
frame = JSON.parse(raw);
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
if (frame.event === "ready") {
|
|
120
|
-
onReady?.({ protocol: frame.payload?.protocol ?? PROTOCOL_VERSION });
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (typeof frame.id === "number" && ("ok" in frame)) {
|
|
124
|
-
const p = this.pending.get(frame.id);
|
|
125
|
-
if (p) {
|
|
126
|
-
this.pending.delete(frame.id);
|
|
127
|
-
if (frame.ok)
|
|
128
|
-
p.resolve(frame.result);
|
|
129
|
-
else
|
|
130
|
-
p.reject(new Error(frame.error));
|
|
131
|
-
}
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
if (frame.event) {
|
|
135
|
-
for (const h of this.eventHandlers)
|
|
136
|
-
h(frame);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
call(method, params) {
|
|
141
|
-
if (!this.proc?.stdin)
|
|
142
|
-
return Promise.reject(new Error("sidecar not started"));
|
|
143
|
-
const id = this.nextId++;
|
|
144
|
-
const frame = { id, method, params };
|
|
145
|
-
return new Promise((resolve, reject) => {
|
|
146
|
-
this.pending.set(id, { resolve, reject });
|
|
147
|
-
this.#writeSafe(JSON.stringify(frame) + "\n", () => {
|
|
148
|
-
this.pending.delete(id);
|
|
149
|
-
reject(new Error(`sidecar write failed: ${method}`));
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
/** Write to the sidecar's stdin without ever throwing EPIPE out of the loop. */
|
|
154
|
-
#writeSafe(chunk, onLost) {
|
|
155
|
-
const stdin = this.proc?.stdin;
|
|
156
|
-
if (!stdin)
|
|
157
|
-
return onLost();
|
|
158
|
-
const fail = (err) => {
|
|
159
|
-
// EPIPE/ECONNRESET when the sidecar died between checks — a lost frame
|
|
160
|
-
// must degrade the caller, never crash the host process.
|
|
161
|
-
stdin.removeListener("error", fail);
|
|
162
|
-
try {
|
|
163
|
-
stdin.destroy();
|
|
164
|
-
}
|
|
165
|
-
catch { /* already gone */ }
|
|
166
|
-
onLost();
|
|
167
|
-
};
|
|
168
|
-
stdin.once("error", fail);
|
|
169
|
-
try {
|
|
170
|
-
stdin.write(chunk, () => stdin.removeListener("error", fail));
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
fail(new Error("write threw"));
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
notify(method, params) {
|
|
177
|
-
if (!this.proc?.stdin)
|
|
178
|
-
return;
|
|
179
|
-
this.#writeSafe(JSON.stringify({ method, params }) + "\n", () => { });
|
|
180
|
-
}
|
|
181
|
-
async stop() {
|
|
182
|
-
const proc = this.proc;
|
|
183
|
-
if (!proc)
|
|
184
|
-
return;
|
|
185
|
-
this.proc = null;
|
|
186
|
-
await new Promise((resolve) => {
|
|
187
|
-
proc.once("exit", () => resolve());
|
|
188
|
-
proc.stdin.end();
|
|
189
|
-
setTimeout(() => {
|
|
190
|
-
proc.kill("SIGTERM");
|
|
191
|
-
setTimeout(() => proc.kill("SIGKILL"), 3000);
|
|
192
|
-
}, 3000).unref?.();
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|