dahrk-node 0.1.15 → 0.1.17
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/main.js +82 -22
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -902,6 +902,10 @@ function mapUsage2(u) {
|
|
|
902
902
|
|
|
903
903
|
// ../../packages/executor-worktree/src/codex-adapter.ts
|
|
904
904
|
var COALESCE_MS2 = Number(process.env.DAHRK_COALESCE_MS ?? process.env.SKAKEL_COALESCE_MS ?? 40);
|
|
905
|
+
var CODEX_COST_UNAVAILABLE_NOTE = "codex-adapter: cost reporting unavailable for the Codex runtime (the SDK reports tokens, not price); costUsd left unset, not $0\n";
|
|
906
|
+
function warnCostUnavailable(write = (s) => void process.stderr.write(s)) {
|
|
907
|
+
write(CODEX_COST_UNAVAILABLE_NOTE);
|
|
908
|
+
}
|
|
905
909
|
function runtimeEnvOptions2(ctx) {
|
|
906
910
|
if (!ctx.runtimeEnv) return {};
|
|
907
911
|
const env = {};
|
|
@@ -961,6 +965,7 @@ function createCodexRunner() {
|
|
|
961
965
|
}
|
|
962
966
|
captureThreadId(t);
|
|
963
967
|
if (cancelled) status = "fail";
|
|
968
|
+
warnCostUnavailable();
|
|
964
969
|
return { status, ...sessionId ? { sessionId } : {} };
|
|
965
970
|
},
|
|
966
971
|
async runInteractive(ctx, turns, onTrace) {
|
|
@@ -1031,6 +1036,7 @@ function createCodexRunner() {
|
|
|
1031
1036
|
summary = "(stage cancelled)";
|
|
1032
1037
|
}
|
|
1033
1038
|
captureThreadId(t);
|
|
1039
|
+
warnCostUnavailable();
|
|
1034
1040
|
return { status, summary, ...sessionId ? { sessionId } : {} };
|
|
1035
1041
|
},
|
|
1036
1042
|
async summarise(ctx) {
|
|
@@ -1186,6 +1192,10 @@ function createPiRunner(deps = {}) {
|
|
|
1186
1192
|
const captureSessionId = (s) => {
|
|
1187
1193
|
if (s.sessionId) sessionId = s.sessionId;
|
|
1188
1194
|
};
|
|
1195
|
+
const readSessionCost = (s) => {
|
|
1196
|
+
const cost = s.getSessionStats?.()?.cost;
|
|
1197
|
+
return typeof cost === "number" ? cost : void 0;
|
|
1198
|
+
};
|
|
1189
1199
|
return {
|
|
1190
1200
|
runtime: "pi",
|
|
1191
1201
|
async runBatch(ctx, onTrace) {
|
|
@@ -1209,7 +1219,8 @@ function createPiRunner(deps = {}) {
|
|
|
1209
1219
|
}
|
|
1210
1220
|
captureSessionId(s);
|
|
1211
1221
|
if (cancelled) status = "fail";
|
|
1212
|
-
|
|
1222
|
+
const costUsd = readSessionCost(s);
|
|
1223
|
+
return { status, ...sessionId ? { sessionId } : {}, ...costUsd !== void 0 ? { costUsd } : {} };
|
|
1213
1224
|
},
|
|
1214
1225
|
async runInteractive(ctx, turns, onTrace) {
|
|
1215
1226
|
const emit = makeEmit("pi", onTrace);
|
|
@@ -1304,7 +1315,13 @@ function createPiRunner(deps = {}) {
|
|
|
1304
1315
|
}
|
|
1305
1316
|
unsub();
|
|
1306
1317
|
captureSessionId(s);
|
|
1307
|
-
|
|
1318
|
+
const costUsd = readSessionCost(s);
|
|
1319
|
+
return {
|
|
1320
|
+
status,
|
|
1321
|
+
summary,
|
|
1322
|
+
...sessionId ? { sessionId } : {},
|
|
1323
|
+
...costUsd !== void 0 ? { costUsd } : {}
|
|
1324
|
+
};
|
|
1308
1325
|
},
|
|
1309
1326
|
async summarise(ctx) {
|
|
1310
1327
|
if (!session) return "(no summary: session not established)";
|
|
@@ -1354,7 +1371,9 @@ async function defaultCreatePiSession(ctx) {
|
|
|
1354
1371
|
let model;
|
|
1355
1372
|
if (ctx.config.model) {
|
|
1356
1373
|
const resolved = resolveCliModel({ cliModel: ctx.config.model, modelRegistry });
|
|
1357
|
-
if (!resolved?.error)
|
|
1374
|
+
if (!resolved?.error) {
|
|
1375
|
+
model = pickAuthedModel(resolved?.model, modelRegistry.getAvailable());
|
|
1376
|
+
}
|
|
1358
1377
|
}
|
|
1359
1378
|
const stageComplete = defineTool({
|
|
1360
1379
|
name: PI_STAGE_COMPLETE_TOOL,
|
|
@@ -1379,6 +1398,17 @@ var PROVIDER_BY_ENV = {
|
|
|
1379
1398
|
GEMINI_API_KEY: "google",
|
|
1380
1399
|
GOOGLE_API_KEY: "google"
|
|
1381
1400
|
};
|
|
1401
|
+
function modelFamily(id) {
|
|
1402
|
+
const last = id.split(".").pop() ?? id;
|
|
1403
|
+
return last.replace(/-v\d+:\d+$/, "").toLowerCase();
|
|
1404
|
+
}
|
|
1405
|
+
function pickAuthedModel(resolved, available) {
|
|
1406
|
+
if (!resolved || !available?.length) return resolved;
|
|
1407
|
+
const providers = new Set(available.map((m) => m.provider));
|
|
1408
|
+
if (providers.has(resolved.provider)) return resolved;
|
|
1409
|
+
const family = modelFamily(resolved.id);
|
|
1410
|
+
return available.find((m) => modelFamily(m.id) === family) ?? resolved;
|
|
1411
|
+
}
|
|
1382
1412
|
|
|
1383
1413
|
// ../../packages/executor-worktree/src/git-service.ts
|
|
1384
1414
|
import { execFileSync } from "child_process";
|
|
@@ -6265,6 +6295,7 @@ async function runUpdate(inputs, deps = {}) {
|
|
|
6265
6295
|
d.out(hint(`You are on ${current}. See https://www.npmjs.com/package/dahrk-node for releases.`));
|
|
6266
6296
|
return 1;
|
|
6267
6297
|
}
|
|
6298
|
+
d.saveResult({ updateCheckedAt: new Date(d.now()).toISOString(), updateLatest: latest });
|
|
6268
6299
|
if (!isNewer(latest, current)) {
|
|
6269
6300
|
d.out(verdict("ok", `Already on the latest version (${current}).`));
|
|
6270
6301
|
return 0;
|
|
@@ -6352,6 +6383,10 @@ var defaultDeps4 = () => ({
|
|
|
6352
6383
|
binPath: process.argv[1],
|
|
6353
6384
|
fetchLatest: fetchLatestVersion,
|
|
6354
6385
|
runUpgrade: spawnUpgrade,
|
|
6386
|
+
// The same cache the daemon's periodic check writes (`updateCheckDeps` in main.ts), so both writers agree
|
|
6387
|
+
// on where "what the registry last said" lives and `status` has one place to read it from.
|
|
6388
|
+
saveResult: (patch) => writeState(process.env, patch),
|
|
6389
|
+
now: () => Date.now(),
|
|
6355
6390
|
nodeRunning: nodeIsRunning,
|
|
6356
6391
|
interactive: isInteractive,
|
|
6357
6392
|
confirm,
|
|
@@ -6367,7 +6402,8 @@ var defaultDeps4 = () => ({
|
|
|
6367
6402
|
});
|
|
6368
6403
|
|
|
6369
6404
|
// src/update-check.ts
|
|
6370
|
-
var DEFAULT_INTERVAL_MS =
|
|
6405
|
+
var DEFAULT_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
6406
|
+
var STALE_AFTER_INTERVALS = 4;
|
|
6371
6407
|
var FETCH_TIMEOUT_MS = 1500;
|
|
6372
6408
|
function checkSuppressed(env) {
|
|
6373
6409
|
return Boolean(env.DAHRK_NO_UPDATE_CHECK || env.NO_UPDATE_NOTIFIER || env.CI);
|
|
@@ -6400,7 +6436,8 @@ async function checkForUpdate(currentVersion, deps) {
|
|
|
6400
6436
|
if (checkSuppressed(deps.env)) return void 0;
|
|
6401
6437
|
const state = deps.readState();
|
|
6402
6438
|
if (!shouldCheck(deps.now(), state.updateCheckedAt, checkIntervalMs(deps.env), deps.env)) {
|
|
6403
|
-
|
|
6439
|
+
const cached = cachedUpdate(state, currentVersion, deps.binPath);
|
|
6440
|
+
return cached.kind === "available" ? cached : void 0;
|
|
6404
6441
|
}
|
|
6405
6442
|
let latest;
|
|
6406
6443
|
try {
|
|
@@ -6412,10 +6449,12 @@ async function checkForUpdate(currentVersion, deps) {
|
|
|
6412
6449
|
if (!isNewer(latest, currentVersion)) return void 0;
|
|
6413
6450
|
return { current: currentVersion, latest, channel: detectChannel(deps.binPath) };
|
|
6414
6451
|
}
|
|
6452
|
+
var isStale = (checkedAt, now, intervalMs) => now - checkedAt >= intervalMs * STALE_AFTER_INTERVALS;
|
|
6415
6453
|
function cachedUpdate(state, currentVersion, binPath) {
|
|
6416
|
-
const latest = state
|
|
6417
|
-
|
|
6418
|
-
|
|
6454
|
+
const { updateLatest: latest, updateCheckedAt } = state;
|
|
6455
|
+
const checkedAt = updateCheckedAt ? Date.parse(updateCheckedAt) : NaN;
|
|
6456
|
+
if (!latest || !Number.isFinite(checkedAt)) return { kind: "unknown" };
|
|
6457
|
+
return isNewer(latest, currentVersion) ? { kind: "available", checkedAt, current: currentVersion, latest, channel: detectChannel(binPath) } : { kind: "current", checkedAt };
|
|
6419
6458
|
}
|
|
6420
6459
|
|
|
6421
6460
|
// src/status.ts
|
|
@@ -6454,7 +6493,13 @@ function presenceHints(f) {
|
|
|
6454
6493
|
}
|
|
6455
6494
|
function renderStatus(f) {
|
|
6456
6495
|
const v = presenceVerdict(f);
|
|
6457
|
-
const lines = ["", verdict(v.level, v.text)
|
|
6496
|
+
const lines = ["", verdict(v.level, v.text)];
|
|
6497
|
+
if (f.update?.kind === "available") {
|
|
6498
|
+
lines.push(
|
|
6499
|
+
verdict("warn", `Update available: ${f.clientVersion} ${arrow()} ${f.update.latest}`) + ` ${dim("run `dahrk update`")}`
|
|
6500
|
+
);
|
|
6501
|
+
}
|
|
6502
|
+
lines.push("");
|
|
6458
6503
|
const { nodeId, name, tenantId, enrolToken } = f.state;
|
|
6459
6504
|
if (enrolToken) {
|
|
6460
6505
|
const who = name ? name : "yes";
|
|
@@ -6465,12 +6510,7 @@ function renderStatus(f) {
|
|
|
6465
6510
|
lines.push(kv("Enrolled", `no ${dim("run `dahrk start --token <token>` once to enrol")}`));
|
|
6466
6511
|
}
|
|
6467
6512
|
lines.push(kv("Node id", nodeId ?? dim("not yet minted (first `dahrk start` mints one)")));
|
|
6468
|
-
lines.push(
|
|
6469
|
-
kv(
|
|
6470
|
-
"Client",
|
|
6471
|
-
f.update ? `${f.clientVersion} ${dim(`(update available: ${f.update.latest} - run \`dahrk update\`)`)}` : f.clientVersion
|
|
6472
|
-
)
|
|
6473
|
-
);
|
|
6513
|
+
lines.push(kv("Client", `${f.clientVersion}${currency(f)}`));
|
|
6474
6514
|
const conn = f.connection ? ` ${dim(`(${f.connection.event} ${ago(f.now - f.connection.at)}${f.connection.detail ? `, ${f.connection.detail}` : ""})`)}` : "";
|
|
6475
6515
|
lines.push(kv("Hub", `${f.hubUrl}${conn}`));
|
|
6476
6516
|
const installed = f.runtimes.filter((r) => r.installed);
|
|
@@ -6491,6 +6531,19 @@ function renderStatus(f) {
|
|
|
6491
6531
|
lines.push("", dim(` State file: ${f.stateFile}`));
|
|
6492
6532
|
return lines;
|
|
6493
6533
|
}
|
|
6534
|
+
function currency(f) {
|
|
6535
|
+
const u = f.update;
|
|
6536
|
+
if (!u) return "";
|
|
6537
|
+
if (u.kind === "unknown") {
|
|
6538
|
+
return ` ${dim("update status unknown - run `dahrk update --check`")}`;
|
|
6539
|
+
}
|
|
6540
|
+
const age = ago(f.now - u.checkedAt);
|
|
6541
|
+
if (isStale(u.checkedAt, f.now, f.updateIntervalMs)) {
|
|
6542
|
+
return ` ${dim(`as of ${age} - run \`dahrk update --check\` to refresh`)}`;
|
|
6543
|
+
}
|
|
6544
|
+
if (u.kind === "available") return ` ${dim(`(checked ${age})`)}`;
|
|
6545
|
+
return ` ${symbol("ok")} ${dim(`up to date (checked ${age})`)}`;
|
|
6546
|
+
}
|
|
6494
6547
|
function jobLine(j, now) {
|
|
6495
6548
|
const where = j.stageId ? `${j.runId} ${dim("/")} ${j.stageId}` : `${j.runId} ${dim(`(${j.kind})`)}`;
|
|
6496
6549
|
return `${where} ${dim(humanDuration(now - j.startedAt))}`;
|
|
@@ -6530,6 +6583,7 @@ async function gatherFacts(inputs, deps) {
|
|
|
6530
6583
|
runtimes: await deps.probeRuntimes(),
|
|
6531
6584
|
presence,
|
|
6532
6585
|
jobs,
|
|
6586
|
+
updateIntervalMs: checkIntervalMs(deps.env),
|
|
6533
6587
|
now: deps.now(),
|
|
6534
6588
|
...service ? { service } : {},
|
|
6535
6589
|
...connection ? { connection } : {},
|
|
@@ -6567,7 +6621,7 @@ async function runStatus(inputs, deps) {
|
|
|
6567
6621
|
}
|
|
6568
6622
|
|
|
6569
6623
|
// src/main.ts
|
|
6570
|
-
var CLIENT_VERSION = "0.1.
|
|
6624
|
+
var CLIENT_VERSION = "0.1.17";
|
|
6571
6625
|
var DEFAULT_HUB_URL = "wss://api.dahrk.ai";
|
|
6572
6626
|
var list = (v) => (v ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
6573
6627
|
var RUNTIMES2 = ["claude-code", "codex", "pi"];
|
|
@@ -6757,6 +6811,9 @@ async function stop(env, force) {
|
|
|
6757
6811
|
if (code === 0 || code === STOP_FOREIGN_NODE) setDesired(env, "stopped");
|
|
6758
6812
|
return code;
|
|
6759
6813
|
}
|
|
6814
|
+
var updateStateDeps = (env) => ({
|
|
6815
|
+
saveResult: (patch) => writeState(env, patch)
|
|
6816
|
+
});
|
|
6760
6817
|
function updateCheckDeps(env) {
|
|
6761
6818
|
return {
|
|
6762
6819
|
env,
|
|
@@ -6774,7 +6831,7 @@ async function offerUpdate(env) {
|
|
|
6774
6831
|
out(renderUpdateNotice(available));
|
|
6775
6832
|
if (!isInteractive()) return;
|
|
6776
6833
|
if (!await confirm("Update now?")) return;
|
|
6777
|
-
const code = await runUpdate({ currentVersion: CLIENT_VERSION, check: false });
|
|
6834
|
+
const code = await runUpdate({ currentVersion: CLIENT_VERSION, check: false }, updateStateDeps(env));
|
|
6778
6835
|
if (code !== 0) out(hint("Update failed; starting the node on the current version anyway."));
|
|
6779
6836
|
}
|
|
6780
6837
|
function scheduleUpdateChecks(env) {
|
|
@@ -6924,11 +6981,14 @@ async function main() {
|
|
|
6924
6981
|
break;
|
|
6925
6982
|
}
|
|
6926
6983
|
case "update":
|
|
6927
|
-
process.exitCode = await runUpdate(
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6984
|
+
process.exitCode = await runUpdate(
|
|
6985
|
+
{
|
|
6986
|
+
currentVersion: CLIENT_VERSION,
|
|
6987
|
+
check: parsed.flags.check,
|
|
6988
|
+
verbose: parsed.flags.verbose
|
|
6989
|
+
},
|
|
6990
|
+
updateStateDeps(applyEnvAliases(process.env))
|
|
6991
|
+
);
|
|
6932
6992
|
break;
|
|
6933
6993
|
case "start":
|
|
6934
6994
|
process.exitCode = await start(parsed.flags);
|