agent-dag 1.33.21 → 1.33.23
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/web/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>agents-deck</title>
|
|
7
7
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='84' font-size='84'%3E%E2%97%89%3C/text%3E%3C/svg%3E" />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DTNEy5xO.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-Cpi89XJ8.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-dag",
|
|
3
|
-
"version": "1.33.
|
|
3
|
+
"version": "1.33.23",
|
|
4
4
|
"description": "Live deck of Claude Code and Codex agents — watch parallel subagents fork, call tools, and return on one calm canvas. Also available as npx ccdeck and npx agent-dag.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/server/ccusage.mjs
CHANGED
|
@@ -37,6 +37,16 @@ const NPM_SHELL = process.platform === "win32";
|
|
|
37
37
|
let _installing = null; // Promise guard so concurrent calls share one install
|
|
38
38
|
let _checkedThisRun = false; // only kick the daily check once per process boot
|
|
39
39
|
|
|
40
|
+
// AGENTS_DECK_NO_INSTALL=1 is documented as "never install or update
|
|
41
|
+
// claude-swap / ccusage, and never ask npm about releases", so it has to hold
|
|
42
|
+
// on the lazy path too — opening the usage-history modal must not be a way to
|
|
43
|
+
// pull ccusage off the registry behind the user's back. Read per call rather
|
|
44
|
+
// than once at import, because the module is imported lazily and a test (or an
|
|
45
|
+
// embedder) may set it after load.
|
|
46
|
+
function installsDisabled() {
|
|
47
|
+
return process.env.AGENTS_DECK_NO_INSTALL === "1";
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
// ── managed install ─────────────────────────────────────────────────────────
|
|
41
51
|
|
|
42
52
|
// Absolute path to ccusage's CLI entry inside our managed install, or null if
|
|
@@ -103,6 +113,7 @@ function touchMarker() {
|
|
|
103
113
|
|
|
104
114
|
// Non-blocking: compare installed version to npm `latest`; install if newer.
|
|
105
115
|
function maybeBackgroundUpdate(installedVersion) {
|
|
116
|
+
if (installsDisabled()) return; // no `npm view`, no upgrade install
|
|
106
117
|
if (_checkedThisRun || !updateCheckDue()) return;
|
|
107
118
|
_checkedThisRun = true;
|
|
108
119
|
touchMarker();
|
|
@@ -127,6 +138,13 @@ async function getRunner() {
|
|
|
127
138
|
maybeBackgroundUpdate(resolved.version);
|
|
128
139
|
return { kind: "node", entry: resolved.entry };
|
|
129
140
|
}
|
|
141
|
+
// Nothing installed and installs are forbidden. The npx fallback is not an
|
|
142
|
+
// escape hatch — `npx -y ccusage@latest` downloads and runs the same package
|
|
143
|
+
// — so there is no runner to hand back. Fail with the reason, which the
|
|
144
|
+
// usage-history modal shows, instead of quietly installing.
|
|
145
|
+
if (installsDisabled()) {
|
|
146
|
+
throw new Error("ccusage is not installed, and installs are off (AGENTS_DECK_NO_INSTALL=1)");
|
|
147
|
+
}
|
|
130
148
|
// Cold: install once (deduped across concurrent callers).
|
|
131
149
|
if (!_installing) {
|
|
132
150
|
_installing = (async () => { installSync("latest"); })()
|
|
@@ -232,6 +250,13 @@ export async function fetchCcusageDaily({ since, until, force = false } = {}) {
|
|
|
232
250
|
* not hold up the server.
|
|
233
251
|
*/
|
|
234
252
|
export function primeCcusage() {
|
|
253
|
+
// The CLI already skips this call under AGENTS_DECK_NO_INSTALL=1; repeating
|
|
254
|
+
// the check here keeps the promise a property of the module rather than of
|
|
255
|
+
// one caller.
|
|
256
|
+
if (installsDisabled()) {
|
|
257
|
+
const have = resolveEntry();
|
|
258
|
+
return have ? { state: "present", version: have.version } : { state: "unavailable" };
|
|
259
|
+
}
|
|
235
260
|
const resolved = resolveEntry();
|
|
236
261
|
if (resolved) {
|
|
237
262
|
// Already installed: the daily check may still queue a background upgrade.
|
package/src/server/exec.mjs
CHANGED
|
@@ -224,7 +224,16 @@ export function runInteractive(cmd, args, { timeout = 300_000, maxOutput = 256 <
|
|
|
224
224
|
if (tryNext(err) && !stdout && !stderr) { child = null; return attempt(i + 1); }
|
|
225
225
|
finish(-1, err);
|
|
226
226
|
});
|
|
227
|
-
|
|
227
|
+
// Spawning proves a spelling exists — except a .cmd/.bat one, which is
|
|
228
|
+
// launched THROUGH cmd.exe. cmd.exe is always there, so it spawns just as
|
|
229
|
+
// happily for a batch file that is not, and only says so later by exiting
|
|
230
|
+
// non-zero with "is not recognized". Caching at spawn time therefore
|
|
231
|
+
// remembered a spelling that never existed, and since `candidates` then
|
|
232
|
+
// offers only the remembered one, the tool stayed unrunnable — with the
|
|
233
|
+
// false message "not on PATH" — even after it was installed. A batch
|
|
234
|
+
// spelling is confirmed by the clean exit below instead, which is the rule
|
|
235
|
+
// `run` already applies with `if (!err)`.
|
|
236
|
+
if (!isBatch(raw)) proc.on("spawn", () => resolved.set(cmd, raw));
|
|
228
237
|
// Capped so a runaway child cannot grow the heap without bound; the tail is
|
|
229
238
|
// what carries the error, so the head is what gets dropped.
|
|
230
239
|
const keep = (buf, text) => (buf + text).slice(-maxOutput);
|
|
@@ -242,6 +251,9 @@ export function runInteractive(cmd, args, { timeout = 300_000, maxOutput = 256 <
|
|
|
242
251
|
}
|
|
243
252
|
return finish(-1, { code: "ENOENT" });
|
|
244
253
|
}
|
|
254
|
+
// Ran to a clean exit, so this spelling is real — the only confirmation a
|
|
255
|
+
// batch one ever gets.
|
|
256
|
+
if (code === 0 && !killed && !timedOut) resolved.set(cmd, raw);
|
|
245
257
|
finish(code ?? -1, null);
|
|
246
258
|
});
|
|
247
259
|
};
|
|
@@ -281,7 +293,11 @@ export function runDetached(cmd, args) {
|
|
|
281
293
|
try {
|
|
282
294
|
const child = spawn(file, argv, { stdio: "ignore", shell: false, windowsHide: true, ...opts });
|
|
283
295
|
child.on("error", (err) => { if (tryNext(err)) attempt(i + 1); });
|
|
284
|
-
|
|
296
|
+
// Same trap as above: a batch spelling is spawned through cmd.exe, which
|
|
297
|
+
// succeeds whether or not the batch file is there, so only a clean exit
|
|
298
|
+
// proves this one is worth remembering.
|
|
299
|
+
if (isBatch(raw)) child.on("exit", (code) => { if (code === 0) resolved.set(cmd, raw); });
|
|
300
|
+
else child.on("spawn", () => resolved.set(cmd, raw));
|
|
285
301
|
child.unref?.();
|
|
286
302
|
} catch {
|
|
287
303
|
attempt(i + 1);
|