@vantaloom/runtime-win32-x64 0.10.10 → 0.11.0
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/VERSION +1 -1
- package/bin/vantaloom-agent.exe +0 -0
- package/bin/vantaloom-api.exe +0 -0
- package/bin/vantaloom-browser.exe +0 -0
- package/bin/vantaloomctl.exe +0 -0
- package/cli/adapters/claude-sdk-bridge/index.mjs +454 -0
- package/cli/adapters/claude-sdk-bridge/package.json +17 -0
- package/cli/package.json +2 -1
- package/cli/src/cli.mjs +47 -456
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/web/404.html +1 -1
- package/web/__next.__PAGE__.txt +2 -2
- package/web/__next._full.txt +3 -3
- package/web/__next._head.txt +1 -1
- package/web/__next._index.txt +2 -2
- package/web/__next._tree.txt +2 -2
- package/web/_next/static/chunks/68943544d6b0cdba.js +52 -0
- package/web/_next/static/chunks/f1617c3f0c1d5213.css +2 -0
- package/web/_not-found/__next._full.txt +2 -2
- package/web/_not-found/__next._head.txt +1 -1
- package/web/_not-found/__next._index.txt +2 -2
- package/web/_not-found/__next._not-found/__PAGE__.txt +1 -1
- package/web/_not-found/__next._not-found.txt +1 -1
- package/web/_not-found/__next._tree.txt +2 -2
- package/web/_not-found.html +1 -1
- package/web/_not-found.txt +2 -2
- package/web/index.html +1 -1
- package/web/index.txt +3 -3
- package/web/_next/static/chunks/32465f0c99c890c8.css +0 -2
- package/web/_next/static/chunks/bb996b321cc15bb4.js +0 -52
- /package/web/_next/static/{MTlaHCqTqdyPeUkv5vt_b → az8-PLKsfpbj9aLIQwv-x}/_buildManifest.js +0 -0
- /package/web/_next/static/{MTlaHCqTqdyPeUkv5vt_b → az8-PLKsfpbj9aLIQwv-x}/_clientMiddlewareManifest.json +0 -0
- /package/web/_next/static/{MTlaHCqTqdyPeUkv5vt_b → az8-PLKsfpbj9aLIQwv-x}/_ssgManifest.js +0 -0
package/cli/src/cli.mjs
CHANGED
|
@@ -121,12 +121,13 @@ const fallbackNpmRegistries = [
|
|
|
121
121
|
"https://registry.npmmirror.com",
|
|
122
122
|
]
|
|
123
123
|
|
|
124
|
-
// The Claude
|
|
125
|
-
// `node <installDir>/adapters/
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
|
|
124
|
+
// The Claude SDK bridge the Go backend spawns as
|
|
125
|
+
// `node <installDir>/adapters/claude-sdk-bridge/index.mjs`. The bridge source ships
|
|
126
|
+
// inside this CLI package (packages/cli/adapters/claude-sdk-bridge); bundleAdapter
|
|
127
|
+
// installs its sole dependency (@anthropic-ai/claude-agent-sdk, version pinned in the
|
|
128
|
+
// bridge's own package.json) into adapters/claude-sdk-bridge/node_modules at
|
|
129
|
+
// install-adapter time. There is NO @zed-industries/claude-code-acp anymore — the
|
|
130
|
+
// engine speaks the SDK's native stream-json directly.
|
|
130
131
|
|
|
131
132
|
// Inherit strict-ssl=false from npm/npx config, or respect NODE_TLS_REJECT_UNAUTHORIZED.
|
|
132
133
|
// When npm runs us via npx with strict-ssl disabled, it sets npm_config_strict_ssl="false".
|
|
@@ -355,17 +356,22 @@ async function buildRuntimePackage(sourceRoot, packageRoot, options) {
|
|
|
355
356
|
return { platform, version }
|
|
356
357
|
}
|
|
357
358
|
|
|
358
|
-
// bundleAdapter
|
|
359
|
-
//
|
|
360
|
-
//
|
|
361
|
-
//
|
|
359
|
+
// bundleAdapter installs the Claude Agent SDK into
|
|
360
|
+
// <packageRoot>/adapters/claude-sdk-bridge/node_modules and copies the bridge source
|
|
361
|
+
// (the thin node sidecar that runs the SDK's query() and pipes its native stream-json
|
|
362
|
+
// to the Go runtime). It also writes the reclaude shim the Go engine points the SDK's
|
|
363
|
+
// pathToClaudeCodeExecutable at. The SDK version is pinned in the bridge's own
|
|
364
|
+
// package.json (single source of truth); native optional deps (e.g. sharp) are
|
|
365
|
+
// selected per TARGET platform.
|
|
362
366
|
async function bundleAdapter(packageRoot, options = {}) {
|
|
363
367
|
const adaptersRoot = path.join(packageRoot, "adapters")
|
|
368
|
+
const bridgeDest = path.join(adaptersRoot, "claude-sdk-bridge")
|
|
369
|
+
const bridgeSrc = path.join(cliRoot, "adapters", "claude-sdk-bridge")
|
|
364
370
|
const shimPath = path.join(adaptersRoot, "reclaude-shim.mjs")
|
|
365
|
-
const shimSource = `// Vantaloom reclaude shim: the
|
|
366
|
-
// we re-exec the real reclaude binary (path in VANTALOOM_RECLAUDE_EXE)
|
|
367
|
-
// same args + inherited stdio. reclaude's banner goes to stderr, keeping
|
|
368
|
-
// stdout clean.
|
|
371
|
+
const shimSource = `// Vantaloom reclaude shim: the Claude Agent SDK runs \`node <this>\` as the claude
|
|
372
|
+
// executable, so we re-exec the real reclaude binary (path in VANTALOOM_RECLAUDE_EXE)
|
|
373
|
+
// with the same args + inherited stdio. reclaude's banner goes to stderr, keeping the
|
|
374
|
+
// SDK's stdout protocol clean.
|
|
369
375
|
import { spawn } from "node:child_process";
|
|
370
376
|
const exe = process.env.VANTALOOM_RECLAUDE_EXE;
|
|
371
377
|
if (!exe) {
|
|
@@ -380,29 +386,34 @@ child.on("error", (e) => {
|
|
|
380
386
|
});
|
|
381
387
|
`
|
|
382
388
|
|
|
383
|
-
|
|
389
|
+
if (!existsSync(path.join(bridgeSrc, "index.mjs"))) {
|
|
390
|
+
const msg = `claude-sdk-bridge source missing at ${bridgeSrc}`
|
|
391
|
+
if (options.skipAdapter) {
|
|
392
|
+
console.warn(` warning: skipping SDK bridge bundle (${msg})`)
|
|
393
|
+
return
|
|
394
|
+
}
|
|
395
|
+
throw new Error(msg)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Resolve the SDK's platform-gated native optional deps (e.g. sharp's
|
|
384
399
|
// @img/sharp-<os>-<cpu>) for the TARGET platform, not the build host — otherwise a
|
|
385
|
-
// Windows-built bundle would ship the wrong native binary to the mac/linux
|
|
386
|
-
// packages. (ripgrep is vendored for all platforms inside the SDK, so it's
|
|
387
|
-
// unaffected by this.)
|
|
400
|
+
// Windows-built bundle would ship the wrong native binary to the mac/linux packages.
|
|
388
401
|
const { os: targetOs, cpu: targetCpu } = parsePlatformId(options.platform ?? platformId())
|
|
389
|
-
console.log(` bundling
|
|
390
|
-
const tmp = mkdtempSync(path.join(os.tmpdir(), "vantaloom-
|
|
402
|
+
console.log(` bundling Claude Agent SDK bridge (os=${targetOs} cpu=${targetCpu}) ...`)
|
|
403
|
+
const tmp = mkdtempSync(path.join(os.tmpdir(), "vantaloom-sdk-bridge-"))
|
|
391
404
|
try {
|
|
392
|
-
|
|
393
|
-
//
|
|
394
|
-
// global .npmrc points at npmmirror, which may not mirror this package.
|
|
395
|
-
|
|
405
|
+
// Install the bridge's OWN dependencies (the SDK, version pinned in its
|
|
406
|
+
// package.json) into a temp prefix from the PUBLIC registry explicitly: the
|
|
407
|
+
// machine's global .npmrc points at npmmirror, which may not mirror this package.
|
|
408
|
+
cpSync(path.join(bridgeSrc, "package.json"), path.join(tmp, "package.json"))
|
|
396
409
|
const npmArgs = [
|
|
397
410
|
"install",
|
|
398
|
-
CC_ADAPTER_PKG,
|
|
399
411
|
"--prefix",
|
|
400
412
|
tmp,
|
|
401
413
|
"--registry",
|
|
402
414
|
"https://registry.npmjs.org/",
|
|
403
415
|
"--no-audit",
|
|
404
416
|
"--no-fund",
|
|
405
|
-
"--no-save",
|
|
406
417
|
"--omit=dev",
|
|
407
418
|
"--os",
|
|
408
419
|
targetOs,
|
|
@@ -416,450 +427,30 @@ child.on("error", (e) => {
|
|
|
416
427
|
|
|
417
428
|
const tmpModules = path.join(tmp, "node_modules")
|
|
418
429
|
if (!existsSync(tmpModules)) {
|
|
419
|
-
throw new Error(`
|
|
430
|
+
throw new Error(`SDK install produced no node_modules at ${tmpModules}`)
|
|
420
431
|
}
|
|
421
432
|
|
|
422
433
|
removeKnownPath(adaptersRoot, path.dirname(adaptersRoot))
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
cpSync(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
434
|
+
mkdirSync(bridgeDest, { recursive: true })
|
|
435
|
+
// Bridge source: index.mjs (+ package.json, for reference/version).
|
|
436
|
+
cpSync(path.join(bridgeSrc, "index.mjs"), path.join(bridgeDest, "index.mjs"))
|
|
437
|
+
cpSync(path.join(bridgeSrc, "package.json"), path.join(bridgeDest, "package.json"))
|
|
438
|
+
// The SDK + its dependency tree.
|
|
439
|
+
cpSync(tmpModules, path.join(bridgeDest, "node_modules"), { recursive: true })
|
|
429
440
|
|
|
430
441
|
writeFileSync(shimPath, shimSource)
|
|
431
|
-
console.log(` bundled
|
|
442
|
+
console.log(` bundled SDK bridge -> adapters/claude-sdk-bridge + reclaude-shim.mjs`)
|
|
432
443
|
} catch (error) {
|
|
433
444
|
if (options.skipAdapter) {
|
|
434
|
-
console.warn(` warning: skipping
|
|
445
|
+
console.warn(` warning: skipping SDK bridge bundle (${error.message})`)
|
|
435
446
|
return
|
|
436
447
|
}
|
|
437
|
-
throw new Error(`failed to bundle
|
|
448
|
+
throw new Error(`failed to bundle SDK bridge: ${error.message}`)
|
|
438
449
|
} finally {
|
|
439
450
|
rmSync(tmp, { recursive: true, force: true })
|
|
440
451
|
}
|
|
441
452
|
}
|
|
442
453
|
|
|
443
|
-
// patchAdapterLocalCommands patches the bundled claude-code-acp adapter so the
|
|
444
|
-
// output of ALL local slash commands (/usage, /context, /cost, …) is forwarded
|
|
445
|
-
// to the client as an assistant message. Stock 0.16.2 only forwards the one that
|
|
446
|
-
// contains "Context Usage" (/context) and silently drops every other local
|
|
447
|
-
// command's stdout — so /usage etc. showed nothing in Vantaloom. We bundle the
|
|
448
|
-
// adapter ourselves, so this is a targeted source edit, not a runtime monkeypatch.
|
|
449
|
-
// Idempotent + version-tolerant: logs a warning (never throws) if the anchor
|
|
450
|
-
// string isn't found, so a future adapter bump doesn't break packaging silently.
|
|
451
|
-
function patchAdapterLocalCommands(destModules) {
|
|
452
|
-
const agentFile = path.join(
|
|
453
|
-
destModules,
|
|
454
|
-
"@zed-industries",
|
|
455
|
-
"claude-code-acp",
|
|
456
|
-
"dist",
|
|
457
|
-
"acp-agent.js",
|
|
458
|
-
)
|
|
459
|
-
if (!existsSync(agentFile)) {
|
|
460
|
-
console.warn(` warning: adapter patch target missing (${agentFile}); /usage,/context output may be dropped`)
|
|
461
|
-
return
|
|
462
|
-
}
|
|
463
|
-
const src = readFileSync(agentFile, "utf8")
|
|
464
|
-
const anchor = `message.message.content.includes("Context Usage")`
|
|
465
|
-
if (!src.includes(anchor)) {
|
|
466
|
-
console.warn(` warning: adapter local-command anchor not found; skipping /usage,/context output patch`)
|
|
467
|
-
return
|
|
468
|
-
}
|
|
469
|
-
// Forward EVERY <local-command-stdout> block (the outer if already gates on it),
|
|
470
|
-
// not just the "Context Usage" one.
|
|
471
|
-
const patched = src.split(anchor).join("true /* vantaloom: forward all local-command stdout */")
|
|
472
|
-
writeFileSync(agentFile, patched)
|
|
473
|
-
console.log(` patched adapter: forward all local slash-command output (/usage, /context, …)`)
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// patchAdapterProactiveDrain rewrites the bundled claude-code-acp adapter so that
|
|
477
|
-
// agent-initiated ("proactive") turns stream live to the client. In stock 0.16.2
|
|
478
|
-
// the ACP prompt(params) handler is the ONLY consumer of the long-lived Claude
|
|
479
|
-
// Code `query` async generator and it stops reading at the first `result`. When
|
|
480
|
-
// Claude Code is idle it fires proactive turns (background-task completion,
|
|
481
|
-
// scheduled wakeup, proactive tick) as fresh run() loops that push a full
|
|
482
|
-
// running→messages→result→idle cycle onto the SAME stream. Because nobody calls
|
|
483
|
-
// query.next() between prompts, those messages buffer and are only drained one
|
|
484
|
-
// per user prompt(). This patch installs a SINGLE continuous drainer that reads
|
|
485
|
-
// query.next() forever and forwards every message via client.sessionUpdate;
|
|
486
|
-
// prompt() just pushes input and awaits the next turn's result via a FIFO of
|
|
487
|
-
// turn-waiters. Idempotent + version-tolerant: logs a warning (never throws) if
|
|
488
|
-
// either anchor isn't found, so a future adapter bump doesn't break packaging.
|
|
489
|
-
// NOTE: this runs AFTER patchAdapterLocalCommands, so the prompt() anchor below
|
|
490
|
-
// matches the post-local-patch source (the `true /* vantaloom: ... */` form).
|
|
491
|
-
function patchAdapterProactiveDrain(destModules) {
|
|
492
|
-
const agentFile = path.join(
|
|
493
|
-
destModules,
|
|
494
|
-
"@zed-industries",
|
|
495
|
-
"claude-code-acp",
|
|
496
|
-
"dist",
|
|
497
|
-
"acp-agent.js",
|
|
498
|
-
)
|
|
499
|
-
if (!existsSync(agentFile)) {
|
|
500
|
-
console.warn(` warning: adapter patch target missing (${agentFile}); proactive turns may not stream live`)
|
|
501
|
-
return
|
|
502
|
-
}
|
|
503
|
-
const src = readFileSync(agentFile, "utf8")
|
|
504
|
-
if (src.includes("_vantaloomDrain")) {
|
|
505
|
-
// Already patched (idempotent).
|
|
506
|
-
return
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
// Anchor 1: the EXACT original prompt(params) method (byte-exact for 0.16.2,
|
|
510
|
-
// post-local-command-patch — 4-space nesting). Begins at ` async prompt`
|
|
511
|
-
// and ends at the closing brace after the "Session did not end in result" throw.
|
|
512
|
-
const promptAnchor = ` async prompt(params) {
|
|
513
|
-
if (!this.sessions[params.sessionId]) {
|
|
514
|
-
throw new Error("Session not found");
|
|
515
|
-
}
|
|
516
|
-
this.sessions[params.sessionId].cancelled = false;
|
|
517
|
-
const { query, input } = this.sessions[params.sessionId];
|
|
518
|
-
input.push(promptToClaude(params));
|
|
519
|
-
while (true) {
|
|
520
|
-
const { value: message, done } = await query.next();
|
|
521
|
-
if (done || !message) {
|
|
522
|
-
if (this.sessions[params.sessionId].cancelled) {
|
|
523
|
-
return { stopReason: "cancelled" };
|
|
524
|
-
}
|
|
525
|
-
break;
|
|
526
|
-
}
|
|
527
|
-
switch (message.type) {
|
|
528
|
-
case "system":
|
|
529
|
-
switch (message.subtype) {
|
|
530
|
-
case "init":
|
|
531
|
-
break;
|
|
532
|
-
case "compact_boundary":
|
|
533
|
-
case "hook_started":
|
|
534
|
-
case "task_notification":
|
|
535
|
-
case "hook_progress":
|
|
536
|
-
case "hook_response":
|
|
537
|
-
case "status":
|
|
538
|
-
case "files_persisted":
|
|
539
|
-
// Todo: process via status api: https://docs.claude.com/en/docs/claude-code/hooks#hook-output
|
|
540
|
-
break;
|
|
541
|
-
default:
|
|
542
|
-
unreachable(message, this.logger);
|
|
543
|
-
break;
|
|
544
|
-
}
|
|
545
|
-
break;
|
|
546
|
-
case "result": {
|
|
547
|
-
if (this.sessions[params.sessionId].cancelled) {
|
|
548
|
-
return { stopReason: "cancelled" };
|
|
549
|
-
}
|
|
550
|
-
switch (message.subtype) {
|
|
551
|
-
case "success": {
|
|
552
|
-
if (message.result.includes("Please run /login")) {
|
|
553
|
-
throw RequestError.authRequired();
|
|
554
|
-
}
|
|
555
|
-
if (message.is_error) {
|
|
556
|
-
throw RequestError.internalError(undefined, message.result);
|
|
557
|
-
}
|
|
558
|
-
return { stopReason: "end_turn" };
|
|
559
|
-
}
|
|
560
|
-
case "error_during_execution":
|
|
561
|
-
if (message.is_error) {
|
|
562
|
-
throw RequestError.internalError(undefined, message.errors.join(", ") || message.subtype);
|
|
563
|
-
}
|
|
564
|
-
return { stopReason: "end_turn" };
|
|
565
|
-
case "error_max_budget_usd":
|
|
566
|
-
case "error_max_turns":
|
|
567
|
-
case "error_max_structured_output_retries":
|
|
568
|
-
if (message.is_error) {
|
|
569
|
-
throw RequestError.internalError(undefined, message.errors.join(", ") || message.subtype);
|
|
570
|
-
}
|
|
571
|
-
return { stopReason: "max_turn_requests" };
|
|
572
|
-
default:
|
|
573
|
-
unreachable(message, this.logger);
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
break;
|
|
577
|
-
}
|
|
578
|
-
case "stream_event": {
|
|
579
|
-
for (const notification of streamEventToAcpNotifications(message, params.sessionId, this.toolUseCache, this.client, this.logger)) {
|
|
580
|
-
await this.client.sessionUpdate(notification);
|
|
581
|
-
}
|
|
582
|
-
break;
|
|
583
|
-
}
|
|
584
|
-
case "user":
|
|
585
|
-
case "assistant": {
|
|
586
|
-
if (this.sessions[params.sessionId].cancelled) {
|
|
587
|
-
break;
|
|
588
|
-
}
|
|
589
|
-
// Slash commands like /compact can generate invalid output... doesn't match
|
|
590
|
-
// their own docs: https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-slash-commands#%2Fcompact-compact-conversation-history
|
|
591
|
-
if (typeof message.message.content === "string" &&
|
|
592
|
-
message.message.content.includes("<local-command-stdout>")) {
|
|
593
|
-
// Handle /context by sending its reply as regular agent message.
|
|
594
|
-
if (true /* vantaloom: forward all local-command stdout */) {
|
|
595
|
-
for (const notification of toAcpNotifications(message.message.content
|
|
596
|
-
.replace("<local-command-stdout>", "")
|
|
597
|
-
.replace("</local-command-stdout>", ""), "assistant", params.sessionId, this.toolUseCache, this.client, this.logger)) {
|
|
598
|
-
await this.client.sessionUpdate(notification);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
this.logger.log(message.message.content);
|
|
602
|
-
break;
|
|
603
|
-
}
|
|
604
|
-
if (typeof message.message.content === "string" &&
|
|
605
|
-
message.message.content.includes("<local-command-stderr>")) {
|
|
606
|
-
this.logger.error(message.message.content);
|
|
607
|
-
break;
|
|
608
|
-
}
|
|
609
|
-
// Skip these user messages for now, since they seem to just be messages we don't want in the feed
|
|
610
|
-
if (message.type === "user" &&
|
|
611
|
-
(typeof message.message.content === "string" ||
|
|
612
|
-
(Array.isArray(message.message.content) &&
|
|
613
|
-
message.message.content.length === 1 &&
|
|
614
|
-
message.message.content[0].type === "text"))) {
|
|
615
|
-
break;
|
|
616
|
-
}
|
|
617
|
-
if (message.type === "assistant" &&
|
|
618
|
-
message.message.model === "<synthetic>" &&
|
|
619
|
-
Array.isArray(message.message.content) &&
|
|
620
|
-
message.message.content.length === 1 &&
|
|
621
|
-
message.message.content[0].type === "text" &&
|
|
622
|
-
message.message.content[0].text.includes("Please run /login")) {
|
|
623
|
-
throw RequestError.authRequired();
|
|
624
|
-
}
|
|
625
|
-
const content = message.type === "assistant"
|
|
626
|
-
? // Handled by stream events above
|
|
627
|
-
message.message.content.filter((item) => !["text", "thinking"].includes(item.type))
|
|
628
|
-
: message.message.content;
|
|
629
|
-
for (const notification of toAcpNotifications(content, message.message.role, params.sessionId, this.toolUseCache, this.client, this.logger)) {
|
|
630
|
-
await this.client.sessionUpdate(notification);
|
|
631
|
-
}
|
|
632
|
-
break;
|
|
633
|
-
}
|
|
634
|
-
case "tool_progress":
|
|
635
|
-
case "tool_use_summary":
|
|
636
|
-
break;
|
|
637
|
-
case "auth_status":
|
|
638
|
-
break;
|
|
639
|
-
default:
|
|
640
|
-
unreachable(message);
|
|
641
|
-
break;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
throw new Error("Session did not end in result");
|
|
645
|
-
}`
|
|
646
|
-
|
|
647
|
-
// Anchor 2: the exact session-struct assignment block.
|
|
648
|
-
const structAnchor = ` this.sessions[sessionId] = {
|
|
649
|
-
query: q,
|
|
650
|
-
input: input,
|
|
651
|
-
cancelled: false,
|
|
652
|
-
permissionMode,
|
|
653
|
-
settingsManager,
|
|
654
|
-
};`
|
|
655
|
-
|
|
656
|
-
if (!src.includes(promptAnchor)) {
|
|
657
|
-
console.warn(` warning: adapter prompt() anchor not found; skipping proactive-drain patch (proactive turns won't stream live)`)
|
|
658
|
-
return
|
|
659
|
-
}
|
|
660
|
-
if (!src.includes(structAnchor)) {
|
|
661
|
-
console.warn(` warning: adapter session-struct anchor not found; skipping proactive-drain patch (proactive turns won't stream live)`)
|
|
662
|
-
return
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// Replacement 1: add a turn-waiter FIFO to the session and start the drainer.
|
|
666
|
-
const structReplacement = ` this.sessions[sessionId] = {
|
|
667
|
-
query: q,
|
|
668
|
-
input: input,
|
|
669
|
-
cancelled: false,
|
|
670
|
-
permissionMode,
|
|
671
|
-
settingsManager,
|
|
672
|
-
_turnWaiters: [], /* vantaloom: pending prompt() resolvers, FIFO */
|
|
673
|
-
};
|
|
674
|
-
this._vantaloomDrain(sessionId); /* vantaloom: continuous drain so proactive turns stream live */`
|
|
675
|
-
|
|
676
|
-
// Replacement 2: split prompt() into prompt + _vantaloomDrain + _vantaloomHandle.
|
|
677
|
-
// _vantaloomHandle is a faithful copy of the original switch body with
|
|
678
|
-
// params.sessionId → sessionId, returning null for non-terminal messages and
|
|
679
|
-
// returning/throwing exactly as the original did for terminal ones.
|
|
680
|
-
const promptReplacement = ` async prompt(params) {
|
|
681
|
-
if (!this.sessions[params.sessionId]) {
|
|
682
|
-
throw new Error("Session not found");
|
|
683
|
-
}
|
|
684
|
-
const session = this.sessions[params.sessionId];
|
|
685
|
-
session.cancelled = false;
|
|
686
|
-
const turn = new Promise((resolve, reject) => {
|
|
687
|
-
session._turnWaiters.push({ resolve, reject });
|
|
688
|
-
});
|
|
689
|
-
session.input.push(promptToClaude(params));
|
|
690
|
-
return await turn;
|
|
691
|
-
}
|
|
692
|
-
async _vantaloomDrain(sessionId) {
|
|
693
|
-
const session = this.sessions[sessionId];
|
|
694
|
-
if (!session || session._draining) {
|
|
695
|
-
return;
|
|
696
|
-
}
|
|
697
|
-
session._draining = true;
|
|
698
|
-
try {
|
|
699
|
-
while (true) {
|
|
700
|
-
let next;
|
|
701
|
-
try {
|
|
702
|
-
next = await session.query.next();
|
|
703
|
-
} catch (err) {
|
|
704
|
-
const w = session._turnWaiters.shift();
|
|
705
|
-
if (w) { w.reject(err); } else { this.logger.error(\`[vantaloom] drain error: \${err}\`); }
|
|
706
|
-
continue;
|
|
707
|
-
}
|
|
708
|
-
if (!this.sessions[sessionId]) {
|
|
709
|
-
break;
|
|
710
|
-
}
|
|
711
|
-
const { value: message, done } = next;
|
|
712
|
-
if (done || !message) {
|
|
713
|
-
const w = session._turnWaiters.shift();
|
|
714
|
-
if (w) { w.resolve({ stopReason: session.cancelled ? "cancelled" : "end_turn" }); }
|
|
715
|
-
break;
|
|
716
|
-
}
|
|
717
|
-
let outcome = null;
|
|
718
|
-
try {
|
|
719
|
-
outcome = await this._vantaloomHandle(sessionId, message);
|
|
720
|
-
} catch (err) {
|
|
721
|
-
const w = session._turnWaiters.shift();
|
|
722
|
-
if (w) { w.reject(err); } else { this.logger.error(\`[vantaloom] handle error: \${err}\`); }
|
|
723
|
-
continue;
|
|
724
|
-
}
|
|
725
|
-
if (outcome) {
|
|
726
|
-
// A turn ended. Resolve the oldest waiting prompt(); if none is
|
|
727
|
-
// waiting this was an agent-initiated (proactive) turn — its
|
|
728
|
-
// messages were already forwarded live, so just keep draining.
|
|
729
|
-
const w = session._turnWaiters.shift();
|
|
730
|
-
if (w) { w.resolve(outcome); }
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
} finally {
|
|
734
|
-
session._draining = false;
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
async _vantaloomHandle(sessionId, message) {
|
|
738
|
-
switch (message.type) {
|
|
739
|
-
case "system":
|
|
740
|
-
switch (message.subtype) {
|
|
741
|
-
case "init":
|
|
742
|
-
break;
|
|
743
|
-
case "compact_boundary":
|
|
744
|
-
case "hook_started":
|
|
745
|
-
case "task_notification":
|
|
746
|
-
case "hook_progress":
|
|
747
|
-
case "hook_response":
|
|
748
|
-
case "status":
|
|
749
|
-
case "files_persisted":
|
|
750
|
-
// Todo: process via status api: https://docs.claude.com/en/docs/claude-code/hooks#hook-output
|
|
751
|
-
break;
|
|
752
|
-
default:
|
|
753
|
-
unreachable(message, this.logger);
|
|
754
|
-
break;
|
|
755
|
-
}
|
|
756
|
-
break;
|
|
757
|
-
case "result": {
|
|
758
|
-
if (this.sessions[sessionId].cancelled) {
|
|
759
|
-
return { stopReason: "cancelled" };
|
|
760
|
-
}
|
|
761
|
-
switch (message.subtype) {
|
|
762
|
-
case "success": {
|
|
763
|
-
if (message.result.includes("Please run /login")) {
|
|
764
|
-
throw RequestError.authRequired();
|
|
765
|
-
}
|
|
766
|
-
if (message.is_error) {
|
|
767
|
-
throw RequestError.internalError(undefined, message.result);
|
|
768
|
-
}
|
|
769
|
-
return { stopReason: "end_turn" };
|
|
770
|
-
}
|
|
771
|
-
case "error_during_execution":
|
|
772
|
-
if (message.is_error) {
|
|
773
|
-
throw RequestError.internalError(undefined, message.errors.join(", ") || message.subtype);
|
|
774
|
-
}
|
|
775
|
-
return { stopReason: "end_turn" };
|
|
776
|
-
case "error_max_budget_usd":
|
|
777
|
-
case "error_max_turns":
|
|
778
|
-
case "error_max_structured_output_retries":
|
|
779
|
-
if (message.is_error) {
|
|
780
|
-
throw RequestError.internalError(undefined, message.errors.join(", ") || message.subtype);
|
|
781
|
-
}
|
|
782
|
-
return { stopReason: "max_turn_requests" };
|
|
783
|
-
default:
|
|
784
|
-
unreachable(message, this.logger);
|
|
785
|
-
break;
|
|
786
|
-
}
|
|
787
|
-
break;
|
|
788
|
-
}
|
|
789
|
-
case "stream_event": {
|
|
790
|
-
for (const notification of streamEventToAcpNotifications(message, sessionId, this.toolUseCache, this.client, this.logger)) {
|
|
791
|
-
await this.client.sessionUpdate(notification);
|
|
792
|
-
}
|
|
793
|
-
break;
|
|
794
|
-
}
|
|
795
|
-
case "user":
|
|
796
|
-
case "assistant": {
|
|
797
|
-
if (this.sessions[sessionId].cancelled) {
|
|
798
|
-
break;
|
|
799
|
-
}
|
|
800
|
-
// Slash commands like /compact can generate invalid output... doesn't match
|
|
801
|
-
// their own docs: https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-slash-commands#%2Fcompact-compact-conversation-history
|
|
802
|
-
if (typeof message.message.content === "string" &&
|
|
803
|
-
message.message.content.includes("<local-command-stdout>")) {
|
|
804
|
-
// Handle /context by sending its reply as regular agent message.
|
|
805
|
-
if (true /* vantaloom: forward all local-command stdout */) {
|
|
806
|
-
for (const notification of toAcpNotifications(message.message.content
|
|
807
|
-
.replace("<local-command-stdout>", "")
|
|
808
|
-
.replace("</local-command-stdout>", ""), "assistant", sessionId, this.toolUseCache, this.client, this.logger)) {
|
|
809
|
-
await this.client.sessionUpdate(notification);
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
this.logger.log(message.message.content);
|
|
813
|
-
break;
|
|
814
|
-
}
|
|
815
|
-
if (typeof message.message.content === "string" &&
|
|
816
|
-
message.message.content.includes("<local-command-stderr>")) {
|
|
817
|
-
this.logger.error(message.message.content);
|
|
818
|
-
break;
|
|
819
|
-
}
|
|
820
|
-
// Skip these user messages for now, since they seem to just be messages we don't want in the feed
|
|
821
|
-
if (message.type === "user" &&
|
|
822
|
-
(typeof message.message.content === "string" ||
|
|
823
|
-
(Array.isArray(message.message.content) &&
|
|
824
|
-
message.message.content.length === 1 &&
|
|
825
|
-
message.message.content[0].type === "text"))) {
|
|
826
|
-
break;
|
|
827
|
-
}
|
|
828
|
-
if (message.type === "assistant" &&
|
|
829
|
-
message.message.model === "<synthetic>" &&
|
|
830
|
-
Array.isArray(message.message.content) &&
|
|
831
|
-
message.message.content.length === 1 &&
|
|
832
|
-
message.message.content[0].type === "text" &&
|
|
833
|
-
message.message.content[0].text.includes("Please run /login")) {
|
|
834
|
-
throw RequestError.authRequired();
|
|
835
|
-
}
|
|
836
|
-
const content = message.type === "assistant"
|
|
837
|
-
? // Handled by stream events above
|
|
838
|
-
message.message.content.filter((item) => !["text", "thinking"].includes(item.type))
|
|
839
|
-
: message.message.content;
|
|
840
|
-
for (const notification of toAcpNotifications(content, message.message.role, sessionId, this.toolUseCache, this.client, this.logger)) {
|
|
841
|
-
await this.client.sessionUpdate(notification);
|
|
842
|
-
}
|
|
843
|
-
break;
|
|
844
|
-
}
|
|
845
|
-
case "tool_progress":
|
|
846
|
-
case "tool_use_summary":
|
|
847
|
-
break;
|
|
848
|
-
case "auth_status":
|
|
849
|
-
break;
|
|
850
|
-
default:
|
|
851
|
-
unreachable(message);
|
|
852
|
-
break;
|
|
853
|
-
}
|
|
854
|
-
return null;
|
|
855
|
-
}`
|
|
856
|
-
|
|
857
|
-
let patched = src.split(structAnchor).join(structReplacement)
|
|
858
|
-
patched = patched.split(promptAnchor).join(promptReplacement)
|
|
859
|
-
writeFileSync(agentFile, patched)
|
|
860
|
-
console.log(` patched adapter: continuous drain so proactive (agent-initiated) turns stream live`)
|
|
861
|
-
}
|
|
862
|
-
|
|
863
454
|
// copyEasyTier bundles the vendored EasyTier binaries (easytier-core/easytier-cli,
|
|
864
455
|
// plus wintun.dll on Windows) for the target platform into the package bin/ dir.
|
|
865
456
|
async function copyEasyTier(sourceRoot, buildBin, platform) {
|
package/manifest.json
CHANGED
package/package.json
CHANGED
package/web/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
1
|
+
<!DOCTYPE html><!--az8_PLKsfpbj9aLIQwv_x--><html lang="zh-CN" class="font-sans antialiased" data-vtl-theme="default" data-vtl-density="default" data-vtl-motion="default"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/f1617c3f0c1d5213.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/ccc016f22e340d7a.js"/><script src="/_next/static/chunks/465977caba526416.js" async=""></script><script src="/_next/static/chunks/757e2e1b77b5bacc.js" async=""></script><script src="/_next/static/chunks/turbopack-74ec218a8e8a6a34.js" async=""></script><script src="/_next/static/chunks/2f05240e9e23a8f9.js" async=""></script><script src="/_next/static/chunks/83c973dd6794ff6b.js" async=""></script><script src="/_next/static/chunks/7dfeab42587bcc0e.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Vantaloom</title><meta name="description" content="Vantaloom local agent operations console."/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","system",null,["light","dark"],null,true,true)</script><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/ccc016f22e340d7a.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[22332,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"ThemeProvider\"]\n3:I[64990,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"TourProvider\"]\n4:I[45121,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"default\"]\n5:I[60512,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"default\"]\n6:I[35417,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\n9:I[35417,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"ViewportBoundary\"]\nb:I[35417,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"MetadataBoundary\"]\nd:I[50025,[\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"/_next/static/chunks/83c973dd6794ff6b.js\",\"/_next/static/chunks/7dfeab42587bcc0e.js\"],\"default\"]\n:HL[\"/_next/static/chunks/f1617c3f0c1d5213.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"az8-PLKsfpbj9aLIQwv-x\",\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/f1617c3f0c1d5213.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/2f05240e9e23a8f9.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/83c973dd6794ff6b.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/7dfeab42587bcc0e.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"zh-CN\",\"suppressHydrationWarning\":true,\"className\":\"font-sans antialiased\",\"data-vtl-theme\":\"default\",\"data-vtl-density\":\"default\",\"data-vtl-motion\":\"default\",\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lc\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"8:null\nc:[[\"$\",\"title\",\"0\",{\"children\":\"Vantaloom\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Vantaloom local agent operations console.\"}]]\n"])</script></body></html>
|