@corenel/sidecar 0.4.3 → 0.4.4
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/dist/cli.js +73 -17
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -22606,6 +22606,26 @@ async function loadOrCreateToken() {
|
|
|
22606
22606
|
return token;
|
|
22607
22607
|
}
|
|
22608
22608
|
|
|
22609
|
+
// ../harness/redact.ts
|
|
22610
|
+
var MASK = "[redacted]";
|
|
22611
|
+
var KEY_PATTERNS = [
|
|
22612
|
+
/\bsk-[A-Za-z0-9_*-]{8,}/g,
|
|
22613
|
+
// OpenAI + Anthropic: sk-, sk-proj-, sk-svcacct-, sk-ant-
|
|
22614
|
+
/\bgsk_[A-Za-z0-9_*-]{8,}/g,
|
|
22615
|
+
// Groq
|
|
22616
|
+
/\bAIza[A-Za-z0-9_*-]{8,}/g,
|
|
22617
|
+
// Google
|
|
22618
|
+
/\bxai-[A-Za-z0-9_*-]{8,}/g
|
|
22619
|
+
// xAI
|
|
22620
|
+
];
|
|
22621
|
+
var BEARER = /\bBearer\s+[A-Za-z0-9._*-]+/gi;
|
|
22622
|
+
function redactSecrets(text) {
|
|
22623
|
+
let out = text;
|
|
22624
|
+
for (const re2 of KEY_PATTERNS) out = out.replace(re2, MASK);
|
|
22625
|
+
out = out.replace(BEARER, `Bearer ${MASK}`);
|
|
22626
|
+
return out;
|
|
22627
|
+
}
|
|
22628
|
+
|
|
22609
22629
|
// ../harness/api/client.ts
|
|
22610
22630
|
var ApiError = class extends Error {
|
|
22611
22631
|
status;
|
|
@@ -22646,7 +22666,7 @@ var CorenelApiClient = class {
|
|
|
22646
22666
|
body = text;
|
|
22647
22667
|
}
|
|
22648
22668
|
if (!res.ok) {
|
|
22649
|
-
const message = String(rec(body).error || res.statusText || `HTTP ${res.status}`);
|
|
22669
|
+
const message = redactSecrets(String(rec(body).error || res.statusText || `HTTP ${res.status}`));
|
|
22650
22670
|
if (res.status === 409 && "epoch" in rec(body)) {
|
|
22651
22671
|
throw new LeaseConflict(res.status, message, body, Number(rec(body).epoch));
|
|
22652
22672
|
}
|
|
@@ -23551,6 +23571,19 @@ var MAX_CHUNKS = 400;
|
|
|
23551
23571
|
var MAX_CHARS = 2e5;
|
|
23552
23572
|
var KEEP_EXITED = 20;
|
|
23553
23573
|
var KILL_GRACE_MS = 3e3;
|
|
23574
|
+
function signalTree(child, sig) {
|
|
23575
|
+
if (process.platform !== "win32" && typeof child.pid === "number") {
|
|
23576
|
+
try {
|
|
23577
|
+
process.kill(-child.pid, sig);
|
|
23578
|
+
return;
|
|
23579
|
+
} catch {
|
|
23580
|
+
}
|
|
23581
|
+
}
|
|
23582
|
+
try {
|
|
23583
|
+
child.kill(sig);
|
|
23584
|
+
} catch {
|
|
23585
|
+
}
|
|
23586
|
+
}
|
|
23554
23587
|
function createNodeProcs(opts) {
|
|
23555
23588
|
const entries = /* @__PURE__ */ new Map();
|
|
23556
23589
|
const subs = /* @__PURE__ */ new Set();
|
|
@@ -23594,7 +23627,12 @@ function createNodeProcs(opts) {
|
|
|
23594
23627
|
const isWin = process.platform === "win32";
|
|
23595
23628
|
const shell = isWin ? "cmd.exe" : "/bin/sh";
|
|
23596
23629
|
const shellArgs = isWin ? ["/d", "/s", "/c", line] : ["-c", line];
|
|
23597
|
-
const child = spawn2(shell, shellArgs, {
|
|
23630
|
+
const child = spawn2(shell, shellArgs, {
|
|
23631
|
+
cwd: dir,
|
|
23632
|
+
windowsHide: true,
|
|
23633
|
+
stdio: "pipe",
|
|
23634
|
+
detached: !isWin
|
|
23635
|
+
});
|
|
23598
23636
|
const info = {
|
|
23599
23637
|
procId: nextId(),
|
|
23600
23638
|
command: line,
|
|
@@ -23651,9 +23689,9 @@ function createNodeProcs(opts) {
|
|
|
23651
23689
|
if (!e2) throw new Error(`no such process: ${procId}`);
|
|
23652
23690
|
if (!e2.info.running || !e2.child) return;
|
|
23653
23691
|
const child = e2.child;
|
|
23654
|
-
child
|
|
23692
|
+
signalTree(child, "SIGTERM");
|
|
23655
23693
|
const timer = setTimeout(() => {
|
|
23656
|
-
if (e2.info.running) child
|
|
23694
|
+
if (e2.info.running) signalTree(child, "SIGKILL");
|
|
23657
23695
|
}, KILL_GRACE_MS);
|
|
23658
23696
|
timer.unref?.();
|
|
23659
23697
|
child.once("close", () => clearTimeout(timer));
|
|
@@ -23667,12 +23705,7 @@ function createNodeProcs(opts) {
|
|
|
23667
23705
|
shutdown() {
|
|
23668
23706
|
closed = true;
|
|
23669
23707
|
for (const e2 of entries.values()) {
|
|
23670
|
-
if (e2.info.running && e2.child)
|
|
23671
|
-
try {
|
|
23672
|
-
e2.child.kill("SIGKILL");
|
|
23673
|
-
} catch {
|
|
23674
|
-
}
|
|
23675
|
-
}
|
|
23708
|
+
if (e2.info.running && e2.child) signalTree(e2.child, "SIGKILL");
|
|
23676
23709
|
}
|
|
23677
23710
|
subs.clear();
|
|
23678
23711
|
}
|
|
@@ -28384,17 +28417,19 @@ async function workspaceRootsFor(dirName2, hostDir) {
|
|
|
28384
28417
|
for (const entry of entries) {
|
|
28385
28418
|
if (!entry.isDirectory()) continue;
|
|
28386
28419
|
if (!WORKSPACE_ID_RE.test(entry.name)) continue;
|
|
28420
|
+
const wsDir = join8(hostDir, WORKSPACES_SEG, entry.name);
|
|
28387
28421
|
out.push({
|
|
28388
28422
|
owner: `${dirName2}/ws/${entry.name}`,
|
|
28389
|
-
files: new NodeFileService(
|
|
28390
|
-
root: "crew"
|
|
28423
|
+
files: new NodeFileService(wsDir),
|
|
28424
|
+
root: "crew",
|
|
28425
|
+
dir: wsDir
|
|
28391
28426
|
});
|
|
28392
28427
|
}
|
|
28393
28428
|
return out;
|
|
28394
28429
|
}
|
|
28395
28430
|
async function listOwnerRoots(stateDir) {
|
|
28396
28431
|
const roots = [
|
|
28397
|
-
{ owner: "", files: new NodeFileService(stateDir), root: "crew" }
|
|
28432
|
+
{ owner: "", files: new NodeFileService(stateDir), root: "crew", dir: stateDir }
|
|
28398
28433
|
];
|
|
28399
28434
|
let entries;
|
|
28400
28435
|
try {
|
|
@@ -28411,7 +28446,7 @@ async function listOwnerRoots(stateDir) {
|
|
|
28411
28446
|
} catch {
|
|
28412
28447
|
continue;
|
|
28413
28448
|
}
|
|
28414
|
-
roots.push({ owner: dirName2, files: new NodeFileService(hostDir), root: "crew" });
|
|
28449
|
+
roots.push({ owner: dirName2, files: new NodeFileService(hostDir), root: "crew", dir: hostDir });
|
|
28415
28450
|
roots.push(...await workspaceRootsFor(dirName2, hostDir));
|
|
28416
28451
|
}
|
|
28417
28452
|
return roots;
|
|
@@ -37069,7 +37104,9 @@ async function streamCompletion(client, params, signal, onText) {
|
|
|
37069
37104
|
} catch (e2) {
|
|
37070
37105
|
const err = e2;
|
|
37071
37106
|
const raw = err?.error;
|
|
37072
|
-
const detail = (
|
|
37107
|
+
const detail = redactSecrets(
|
|
37108
|
+
String((typeof raw === "string" ? raw : raw?.error || raw?.message) || err?.message || String(e2))
|
|
37109
|
+
);
|
|
37073
37110
|
const msg = typeof err?.status === "number" ? `Gateway ${err.status}: ${detail}` : detail;
|
|
37074
37111
|
alog("stream:create-error", msg);
|
|
37075
37112
|
throw new Error(msg);
|
|
@@ -39700,6 +39737,14 @@ function safeForLog(id) {
|
|
|
39700
39737
|
function makeHostSync(opts) {
|
|
39701
39738
|
const log = opts.log ?? (() => {
|
|
39702
39739
|
});
|
|
39740
|
+
const woke = () => {
|
|
39741
|
+
if (!opts.onWrite) return;
|
|
39742
|
+
try {
|
|
39743
|
+
opts.onWrite();
|
|
39744
|
+
} catch (err) {
|
|
39745
|
+
log(`host-sync: onWrite failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
39746
|
+
}
|
|
39747
|
+
};
|
|
39703
39748
|
const recordFor = async (clientId) => {
|
|
39704
39749
|
const rec5 = (await opts.manifest.list())[clientId];
|
|
39705
39750
|
if (!rec5) throw new Error(`unknown client "${safeForLog(clientId)}" -- no hosts.json entry`);
|
|
@@ -39724,12 +39769,14 @@ function makeHostSync(opts) {
|
|
|
39724
39769
|
await syncWrite(hostFilesFor(opts.stateDir, rec5.dirName), path, content);
|
|
39725
39770
|
await ensureMaterialized(clientId, rec5);
|
|
39726
39771
|
log(`host-sync: wrote ${rec5.dirName}/${path}`);
|
|
39772
|
+
woke();
|
|
39727
39773
|
},
|
|
39728
39774
|
async remove(clientId, path) {
|
|
39729
39775
|
assertSyncPath(path);
|
|
39730
39776
|
const rec5 = await recordFor(clientId);
|
|
39731
39777
|
await syncRemove(hostFilesFor(opts.stateDir, rec5.dirName), path);
|
|
39732
39778
|
log(`host-sync: removed ${rec5.dirName}/${path}`);
|
|
39779
|
+
woke();
|
|
39733
39780
|
}
|
|
39734
39781
|
};
|
|
39735
39782
|
}
|
|
@@ -42086,7 +42133,16 @@ async function main() {
|
|
|
42086
42133
|
await assertPortFree(probeAddress(args.host), args.port);
|
|
42087
42134
|
await assertStateDirFree(sidecarSubdir(args.stateDir));
|
|
42088
42135
|
await checkHostsDrift(args.stateDir, hosts, slog);
|
|
42089
|
-
const hostSync = makeHostSync({
|
|
42136
|
+
const hostSync = makeHostSync({
|
|
42137
|
+
stateDir: args.stateDir,
|
|
42138
|
+
manifest: hosts,
|
|
42139
|
+
log: slog,
|
|
42140
|
+
// Same late-bound `core` holder as onScheduleSelf/onRunComplete below: a
|
|
42141
|
+
// synced definition is useless until a clock pass reads it, and with
|
|
42142
|
+
// nothing due the clock sleeps up to 15 minutes. Without this a deployed
|
|
42143
|
+
// schedule looks broken for a quarter of an hour.
|
|
42144
|
+
onWrite: () => core?.wake()
|
|
42145
|
+
});
|
|
42090
42146
|
const attendance = makeAttendanceRegistry({ log: slog });
|
|
42091
42147
|
const runs = makeRunHub({ log: slog });
|
|
42092
42148
|
let core;
|
|
@@ -42138,7 +42194,7 @@ async function main() {
|
|
|
42138
42194
|
if (args.daemon && runner) {
|
|
42139
42195
|
const flipped = await runner.reconcilePendingOnBoot();
|
|
42140
42196
|
if (flipped > 0) slog(`daemon: marked ${flipped} stale pending permission record(s) dead (daemon restarted)`);
|
|
42141
|
-
const hostCrewDirs = (await listOwnerRoots(args.stateDir)).filter((r2) => r2.owner !== "").map((r2) => join15(
|
|
42197
|
+
const hostCrewDirs = (await listOwnerRoots(args.stateDir)).filter((r2) => r2.owner !== "").map((r2) => join15(r2.dir, r2.root));
|
|
42142
42198
|
const watchDirs = [
|
|
42143
42199
|
join15(args.stateDir, "crew"),
|
|
42144
42200
|
...args.roots.map((r2) => join15(r2, stateDirName(), "crew")),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corenel/sidecar",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Elastic-2.0",
|
|
6
6
|
"description": "Prompd sidecar — a local capability server. Run it next to Prompd (prompd.app) so the browser app can reach your machine: local LLMs (Ollama/LM Studio/vLLM) without CORS, your filesystem, and (opt-in) shell.",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"tsx": "^4.19.2",
|
|
38
38
|
"typescript": "^5.9.3",
|
|
39
39
|
"@corenel/protocol": "0.4.2",
|
|
40
|
-
"@corenel/harness": "0.4.1",
|
|
41
40
|
"@corenel/tools-node": "0.2.2",
|
|
41
|
+
"@corenel/harness": "0.4.1",
|
|
42
42
|
"@corenel/crew": "0.0.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|