@auto-ai/agent 2.1.211 → 2.1.213

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.
Files changed (44) hide show
  1. package/dist/safe-a/404/index.html +1 -1
  2. package/dist/safe-a/404.html +1 -1
  3. package/dist/safe-a/index.html +2 -2
  4. package/dist/safe-a/index.txt +1 -1
  5. package/dist/safe-a/manage/about/index.html +2 -2
  6. package/dist/safe-a/manage/about/index.txt +1 -1
  7. package/dist/safe-a/manage/env/index.html +2 -2
  8. package/dist/safe-a/manage/env/index.txt +1 -1
  9. package/dist/safe-a/manage/geelib/index.html +2 -2
  10. package/dist/safe-a/manage/geelib/index.txt +1 -1
  11. package/dist/safe-a/manage/general/index.html +2 -2
  12. package/dist/safe-a/manage/general/index.txt +1 -1
  13. package/dist/safe-a/manage/git/index.html +2 -2
  14. package/dist/safe-a/manage/git/index.txt +1 -1
  15. package/dist/safe-a/manage/im/index.html +2 -2
  16. package/dist/safe-a/manage/im/index.txt +1 -1
  17. package/dist/safe-a/manage/index.html +2 -2
  18. package/dist/safe-a/manage/index.txt +1 -1
  19. package/dist/safe-a/manage/library/index.html +2 -2
  20. package/dist/safe-a/manage/library/index.txt +1 -1
  21. package/dist/safe-a/manage/mcp/index.html +2 -2
  22. package/dist/safe-a/manage/mcp/index.txt +1 -1
  23. package/dist/safe-a/manage/permissions/index.html +2 -2
  24. package/dist/safe-a/manage/permissions/index.txt +1 -1
  25. package/dist/safe-a/manage/skills/index.html +2 -2
  26. package/dist/safe-a/manage/skills/index.txt +1 -1
  27. package/dist/safe-a/manage/task/index.html +2 -2
  28. package/dist/safe-a/manage/task/index.txt +1 -1
  29. package/dist/safe-a/manage/teams/index.html +2 -2
  30. package/dist/safe-a/manage/teams/index.txt +1 -1
  31. package/dist/safe-a/manage/tools/index.html +2 -2
  32. package/dist/safe-a/manage/tools/index.txt +1 -1
  33. package/dist/ws-test/vendor/xterm-addon-fit.js +2 -0
  34. package/dist/ws-test/vendor/xterm.css +285 -0
  35. package/dist/ws-test/vendor/xterm.js +2 -0
  36. package/dist/ws-test/ws-test.css +43 -0
  37. package/dist/ws-test/ws-test.html +17 -0
  38. package/dist/ws-test/ws-test.js +244 -0
  39. package/mcps-runtime/claude-geelib-channel/server/index.mjs +5 -0
  40. package/mcps-runtime/claude-ws-channel/server/gateway.bundle.mjs +312 -49
  41. package/package.json +6 -6
  42. /package/dist/safe-a/_next/static/{sLkb5O425Rfm5_5LxMwvi → ydg1pWMUiUWUhsV4OnPd9}/_buildManifest.js +0 -0
  43. /package/dist/safe-a/_next/static/{sLkb5O425Rfm5_5LxMwvi → ydg1pWMUiUWUhsV4OnPd9}/_clientMiddlewareManifest.json +0 -0
  44. /package/dist/safe-a/_next/static/{sLkb5O425Rfm5_5LxMwvi → ydg1pWMUiUWUhsV4OnPd9}/_ssgManifest.js +0 -0
@@ -298983,6 +298983,23 @@ function isGeelibListenerStorageSession(agentId, storageId) {
298983
298983
  return false;
298984
298984
  }
298985
298985
  }
298986
+ function isTuituiChannelListenerStorageSession(agentId, storageId, env5) {
298987
+ const sid = storageId?.trim();
298988
+ if (!sid) {
298989
+ return false;
298990
+ }
298991
+ try {
298992
+ const expected = resolveTuituiChannelSessionId(agentId, env5);
298993
+ const expectedStorage = parseWsSessionStorageId(expected);
298994
+ const parsed = parseWsSessionStorageId(sid) ?? resolveSessionTranscriptStorageId(sid);
298995
+ return parsed !== null && expectedStorage !== null && parsed === expectedStorage;
298996
+ } catch {
298997
+ return false;
298998
+ }
298999
+ }
299000
+ function isChannelListenerStorageSession(agentId, storageId, env5) {
299001
+ return isGeelibListenerStorageSession(agentId, storageId) || isTuituiChannelListenerStorageSession(agentId, storageId, env5);
299002
+ }
298986
299003
  function buildTuituiChannelSessionKey(agentId, appId) {
298987
299004
  const agent = agentId.trim();
298988
299005
  const app = appId.trim();
@@ -299005,7 +299022,13 @@ function parsePrefixedStorageSessionId(trimmed) {
299005
299022
  }
299006
299023
  if (trimmed.startsWith(GEELIB_TASK_SESSION_PREFIX)) {
299007
299024
  const body = trimmed.slice(GEELIB_TASK_SESSION_PREFIX.length);
299008
- return validateUuid(body) !== null ? trimmed : null;
299025
+ if (validateUuid(body) !== null) {
299026
+ return trimmed;
299027
+ }
299028
+ if (body.startsWith("listener-") && body.length > "listener-".length) {
299029
+ return trimmed;
299030
+ }
299031
+ return null;
299009
299032
  }
299010
299033
  if (trimmed.startsWith(TUITUI_CHANNEL_SESSION_PREFIX)) {
299011
299034
  const body = trimmed.slice(TUITUI_CHANNEL_SESSION_PREFIX.length);
@@ -299467,8 +299490,12 @@ var init_wsSubprocess = __esm(() => {
299467
299490
 
299468
299491
  // src/server/session/wsTeammateDispatcher.ts
299469
299492
  import { randomUUID as randomUUID12 } from "crypto";
299470
- function setWsPermissionRequestSink(sink) {
299471
- emitPermissionRequestEvent = sink;
299493
+ function clearPendingTeammatePermissionsForRun(runId) {
299494
+ for (const [requestId, pending] of pendingTeammatePermissionByRequestId) {
299495
+ if (pending.runId === runId) {
299496
+ pendingTeammatePermissionByRequestId.delete(requestId);
299497
+ }
299498
+ }
299472
299499
  }
299473
299500
  function emit2(event) {
299474
299501
  emitWsAgentEvent?.(event);
@@ -299609,6 +299636,7 @@ function abortTeammateRunOnIdleTimeout(correlationId) {
299609
299636
  return;
299610
299637
  }
299611
299638
  state.stopped = true;
299639
+ clearPendingTeammatePermissionsForRun(task.runId);
299612
299640
  state.permissionRelay.rejectAll(task.runId, "idle_timeout");
299613
299641
  state.channel?.destroy();
299614
299642
  state.channel = null;
@@ -299760,9 +299788,6 @@ async function dispatchWsTeammateTask(params) {
299760
299788
  stopped: false,
299761
299789
  permissionRelay: createWsPermissionRelay()
299762
299790
  };
299763
- setWsPermissionRequestSink((event) => {
299764
- emitPermissionRequestEvent?.(event);
299765
- });
299766
299791
  let latestFinalAssistantText = "";
299767
299792
  let emittedTerminal = false;
299768
299793
  const emitTerminal = (status, reason, resultText) => {
@@ -299799,6 +299824,7 @@ async function dispatchWsTeammateTask(params) {
299799
299824
  return;
299800
299825
  }
299801
299826
  state.stopped = true;
299827
+ clearPendingTeammatePermissionsForRun(runId);
299802
299828
  state.permissionRelay.rejectAll(runId, "subprocess_stopped");
299803
299829
  state.channel?.destroy();
299804
299830
  state.channel = null;
@@ -299817,7 +299843,11 @@ async function dispatchWsTeammateTask(params) {
299817
299843
  touchTaskActivity(correlationId);
299818
299844
  if (parsed.type === "permission.request") {
299819
299845
  const req = parsed;
299820
- if (typeof req.requestId === "string" && typeof req.toolName === "string") {
299846
+ if (typeof req.requestId === "string" && typeof req.toolName === "string" && state.channel) {
299847
+ pendingTeammatePermissionByRequestId.set(req.requestId, {
299848
+ runId: state.runId,
299849
+ channel: state.channel
299850
+ });
299821
299851
  const event = {
299822
299852
  runId: state.runId,
299823
299853
  payload: {
@@ -299964,7 +299994,7 @@ async function dispatchWsTeammateTask(params) {
299964
299994
  logForDebugging(`[wsTeammateDispatcher] dispatch started corr=${correlationId} run=${runId} sourceAgent=${sourceAgent} sessionId=${sessionId ?? ""} promptLen=${prompt.length}`);
299965
299995
  return { runId, correlationId };
299966
299996
  }
299967
- var activeRuns, taskByCorrelationId, taskByDedupeKey, taskAwaiters, DEFAULT_IDLE_TIMEOUT_MS = 60000, IDLE_CHECK_INTERVAL_MS = 1000, emitWsAgentEvent, emitPermissionRequestEvent;
299997
+ var activeRuns, taskByCorrelationId, taskByDedupeKey, taskAwaiters, pendingTeammatePermissionByRequestId, DEFAULT_IDLE_TIMEOUT_MS = 60000, IDLE_CHECK_INTERVAL_MS = 1000, emitWsAgentEvent, emitPermissionRequestEvent;
299968
299998
  var init_wsTeammateDispatcher = __esm(() => {
299969
299999
  init_wsSessionOverrides();
299970
300000
  init_wsAgentWorkspace();
@@ -299975,6 +300005,7 @@ var init_wsTeammateDispatcher = __esm(() => {
299975
300005
  taskByCorrelationId = new Map;
299976
300006
  taskByDedupeKey = new Map;
299977
300007
  taskAwaiters = new Map;
300008
+ pendingTeammatePermissionByRequestId = new Map;
299978
300009
  });
299979
300010
 
299980
300011
  // src/server/session/wsSpawnTeammate.ts
@@ -405597,7 +405628,7 @@ var init_wsAgentScheduleRun = __esm(() => {
405597
405628
 
405598
405629
  // src/server/wsMcp/httpGateway.ts
405599
405630
  import { existsSync as existsSync15 } from "fs";
405600
- import { join as join121 } from "path";
405631
+ import { join as join122 } from "path";
405601
405632
 
405602
405633
  // src/server/api/modelsController.ts
405603
405634
  init_llmProviders();
@@ -407659,6 +407690,9 @@ var activeChannelManagerService = null;
407659
407690
  function getChannelManagerService() {
407660
407691
  return activeChannelManagerService;
407661
407692
  }
407693
+ function reloadAgentConfigForAgent(agentId) {
407694
+ activeChannelManagerService?.reloadAgentConfigForAgent(agentId);
407695
+ }
407662
407696
 
407663
407697
  class ChannelManagerService {
407664
407698
  sessionRuntimes = new Map;
@@ -407681,6 +407715,23 @@ class ChannelManagerService {
407681
407715
  getChannelManager() {
407682
407716
  return this.channelManager;
407683
407717
  }
407718
+ reloadAgentConfigForAgent(agentId) {
407719
+ const trimmed = agentId.trim();
407720
+ if (!trimmed) {
407721
+ return;
407722
+ }
407723
+ for (const runtime of this.sessionRuntimes.values()) {
407724
+ if (runtime.agent !== trimmed || !runtime.sessionChannel) {
407725
+ continue;
407726
+ }
407727
+ this.writeChildMessage(runtime.sessionChannel, {
407728
+ jsonrpc: "2.0",
407729
+ id: null,
407730
+ method: "reloadAgentConfig",
407731
+ params: {}
407732
+ });
407733
+ }
407734
+ }
407684
407735
  async start() {
407685
407736
  startWsScheduleDispatcher();
407686
407737
  configureWsScheduleWsBridge(createMainProcessWsBrowserPush({
@@ -408051,8 +408102,18 @@ class ChannelManagerService {
408051
408102
  kickPendingDrainOnChannel(runtime.sessionChannel, acpId);
408052
408103
  }
408053
408104
  }
408054
- shouldPersistSessionAfterTurn(_runtime) {
408055
- return isSessionChildPersist();
408105
+ shouldPersistSessionAfterTurn(runtime) {
408106
+ if (isSessionChildPersist()) {
408107
+ return true;
408108
+ }
408109
+ if (runtime.wsBrowserActive) {
408110
+ return true;
408111
+ }
408112
+ const storageId = resolveRuntimeStorageSessionId(runtime);
408113
+ if (storageId && isChannelListenerStorageSession(runtime.agent, storageId, runtime.agentEnv)) {
408114
+ return true;
408115
+ }
408116
+ return false;
408056
408117
  }
408057
408118
  async applySessionExitPolicy(runtime, storageId, resultText, triggerReason) {
408058
408119
  const persist = this.shouldPersistSessionAfterTurn(runtime);
@@ -408060,7 +408121,7 @@ class ChannelManagerService {
408060
408121
  if (persist) {
408061
408122
  return;
408062
408123
  }
408063
- this.terminateSessionRuntime(runtime, `exitAfterTurn:${triggerReason}`);
408124
+ await this.terminateSessionRuntimeAsync(runtime, `exitAfterTurn:${triggerReason}`);
408064
408125
  for (const channelType of listChannelRuntimeServerNames()) {
408065
408126
  this.channelManager.pruneSessionMeta(runtime.agent, channelType, storageId);
408066
408127
  }
@@ -408139,6 +408200,7 @@ class ChannelManagerService {
408139
408200
  this.unregisterBrowserSession(agent, sessionId);
408140
408201
  const cfg = await readWsAgentConfigFile(workspaceDir);
408141
408202
  const browserData = {
408203
+ kind: "session",
408142
408204
  agent: rawAgent,
408143
408205
  sessionId: nextSid,
408144
408206
  workspaceDir,
@@ -408173,6 +408235,13 @@ class ChannelManagerService {
408173
408235
  method: "reloadAgentPrompt",
408174
408236
  params: {}
408175
408237
  });
408238
+ } else if (type === "reloadAgentConfig") {
408239
+ this.writeChildMessage(runtime.sessionChannel, {
408240
+ jsonrpc: "2.0",
408241
+ id: null,
408242
+ method: "reloadAgentConfig",
408243
+ params: {}
408244
+ });
408176
408245
  } else if (type === "reloadSessionOverrides") {
408177
408246
  this.writeChildMessage(runtime.sessionChannel, {
408178
408247
  jsonrpc: "2.0",
@@ -408581,6 +408650,7 @@ class ChannelManagerService {
408581
408650
  }
408582
408651
 
408583
408652
  // src/server/api/agentController.ts
408653
+ init_wsAgentTeamsValidation();
408584
408654
  function agentsCors() {
408585
408655
  return {
408586
408656
  "Access-Control-Allow-Origin": "*",
@@ -408748,6 +408818,9 @@ async function handleAgentsApi(req, url3) {
408748
408818
  }
408749
408819
  try {
408750
408820
  const { config: config7, added } = await addAgentTeamMember(agentCwd, leaderId, agentType);
408821
+ if (added) {
408822
+ reloadAgentConfigForAgent(leaderId);
408823
+ }
408751
408824
  const row = await withAgentTeamListFields({
408752
408825
  id: leaderId,
408753
408826
  cwd: agentCwd
@@ -408773,6 +408846,7 @@ async function handleAgentsApi(req, url3) {
408773
408846
  }
408774
408847
  try {
408775
408848
  const config7 = await removeAgentTeamMember(agentCwd, agentType);
408849
+ reloadAgentConfigForAgent(leaderId);
408776
408850
  const row = await withAgentTeamListFields({
408777
408851
  id: leaderId,
408778
408852
  cwd: agentCwd
@@ -408884,6 +408958,7 @@ async function handleAgentsApi(req, url3) {
408884
408958
  nextCfg.llmProviders = mergedProviders.providers;
408885
408959
  }
408886
408960
  const mcpServersChanged = oldCfg.mcpServers.join("\x00") !== nextCfg.mcpServers.join("\x00");
408961
+ const agentTeamsChanged = normalizeWsAgentTeamTypes(oldCfg.agentTeams).join("\x00") !== normalizeWsAgentTeamTypes(nextCfg.agentTeams).join("\x00");
408887
408962
  await writeWsAgentConfigFile(agentCwd, nextCfg);
408888
408963
  if (mcpServersChanged) {
408889
408964
  const channelManager = getChannelManagerService();
@@ -408891,6 +408966,9 @@ async function handleAgentsApi(req, url3) {
408891
408966
  channelManager.reconcileChannelPairSessions();
408892
408967
  }
408893
408968
  }
408969
+ if (agentTeamsChanged) {
408970
+ reloadAgentConfigForAgent(singleName);
408971
+ }
408894
408972
  }
408895
408973
  let st;
408896
408974
  try {
@@ -412397,6 +412475,155 @@ async function handleRepoApi(req, url3) {
412397
412475
  return;
412398
412476
  }
412399
412477
 
412478
+ // src/server/api/terminalController.ts
412479
+ init_wsAgentWorkspace();
412480
+ import { join as join119 } from "path";
412481
+ var AGENT_WORKSPACE_SUBDIR2 = "workspace";
412482
+ var DEFAULT_COLS = 80;
412483
+ var DEFAULT_ROWS = 24;
412484
+ var terminalSessions = new WeakMap;
412485
+ function isTerminalWs(ws) {
412486
+ return ws.data.kind === "terminal";
412487
+ }
412488
+ function pushTerminalExit(ws, code) {
412489
+ if (ws.readyState !== WebSocket.OPEN) {
412490
+ return;
412491
+ }
412492
+ try {
412493
+ ws.send(JSON.stringify({ type: "exit", code }));
412494
+ } catch {}
412495
+ }
412496
+ function teardownTerminalSession(ws) {
412497
+ const session2 = terminalSessions.get(ws);
412498
+ if (!session2 || session2.closed) {
412499
+ return;
412500
+ }
412501
+ session2.closed = true;
412502
+ terminalSessions.delete(ws);
412503
+ try {
412504
+ session2.proc.kill();
412505
+ } catch {}
412506
+ try {
412507
+ session2.proc.terminal?.close();
412508
+ } catch {}
412509
+ }
412510
+ async function handleTerminalWsUpgrade(req, server) {
412511
+ const url3 = new URL(req.url);
412512
+ const agentParam = url3.searchParams.get("agent");
412513
+ let cwd2;
412514
+ let agent;
412515
+ try {
412516
+ const r4 = resolveWsAgentWorkspace({ agentParam });
412517
+ agent = r4.agent;
412518
+ await requireAgentWorkspaceExists(r4.agentDir, agent);
412519
+ await ensureAgentOperWorkspaceDir(r4.agentDir);
412520
+ cwd2 = join119(r4.operWorkspaceDir, AGENT_WORKSPACE_SUBDIR2);
412521
+ } catch (e5) {
412522
+ return new Response(JSON.stringify({ error: true, message: String(e5) }), {
412523
+ status: 400,
412524
+ headers: { "content-type": "application/json; charset=utf-8" }
412525
+ });
412526
+ }
412527
+ const ok = server.upgrade(req, {
412528
+ data: {
412529
+ kind: "terminal",
412530
+ agent,
412531
+ cwd: cwd2
412532
+ }
412533
+ });
412534
+ if (!ok) {
412535
+ return new Response("WebSocket upgrade failed", { status: 400 });
412536
+ }
412537
+ return;
412538
+ }
412539
+ function handleTerminalWsOpen(ws) {
412540
+ if (!isTerminalWs(ws)) {
412541
+ return;
412542
+ }
412543
+ const { cwd: cwd2 } = ws.data;
412544
+ const cols = DEFAULT_COLS;
412545
+ const rows = DEFAULT_ROWS;
412546
+ const bashPath = Bun.which("bash");
412547
+ if (!bashPath) {
412548
+ try {
412549
+ ws.send(JSON.stringify({ type: "error", message: "bash not found in PATH" }));
412550
+ ws.close();
412551
+ } catch {}
412552
+ return;
412553
+ }
412554
+ let proc;
412555
+ try {
412556
+ proc = Bun.spawn([bashPath], {
412557
+ cwd: cwd2,
412558
+ env: {
412559
+ ...process.env,
412560
+ TERM: "xterm-256color"
412561
+ },
412562
+ terminal: {
412563
+ cols,
412564
+ rows,
412565
+ data(_term, data) {
412566
+ if (ws.readyState !== WebSocket.OPEN) {
412567
+ return;
412568
+ }
412569
+ try {
412570
+ ws.send(data);
412571
+ } catch {}
412572
+ }
412573
+ }
412574
+ });
412575
+ } catch (e5) {
412576
+ try {
412577
+ ws.send(JSON.stringify({ type: "error", message: String(e5) }));
412578
+ ws.close();
412579
+ } catch {}
412580
+ return;
412581
+ }
412582
+ terminalSessions.set(ws, { proc, closed: false });
412583
+ proc.exited.then((code) => {
412584
+ pushTerminalExit(ws, code);
412585
+ teardownTerminalSession(ws);
412586
+ try {
412587
+ ws.close();
412588
+ } catch {}
412589
+ });
412590
+ }
412591
+ function handleTerminalWsMessage(ws, message) {
412592
+ if (!isTerminalWs(ws)) {
412593
+ return;
412594
+ }
412595
+ const session2 = terminalSessions.get(ws);
412596
+ if (!session2 || session2.closed) {
412597
+ return;
412598
+ }
412599
+ const term = session2.proc.terminal;
412600
+ if (!term) {
412601
+ return;
412602
+ }
412603
+ if (typeof message !== "string") {
412604
+ term.write(message);
412605
+ return;
412606
+ }
412607
+ let parsed;
412608
+ try {
412609
+ parsed = JSON.parse(message);
412610
+ } catch {
412611
+ return;
412612
+ }
412613
+ if (parsed.type !== "resize") {
412614
+ return;
412615
+ }
412616
+ const cols = Number(parsed.cols);
412617
+ const rows = Number(parsed.rows);
412618
+ if (!Number.isFinite(cols) || !Number.isFinite(rows) || cols < 1 || rows < 1) {
412619
+ return;
412620
+ }
412621
+ term.resize(Math.floor(cols), Math.floor(rows));
412622
+ }
412623
+ function handleTerminalWsClose(ws) {
412624
+ teardownTerminalSession(ws);
412625
+ }
412626
+
412400
412627
  // src/server/api/runtimePackage/mcpItemConfigController.ts
412401
412628
  init_wsAgentMcpOverlay();
412402
412629
 
@@ -412516,7 +412743,7 @@ init_zip();
412516
412743
  init_wsRuntimeCompiled();
412517
412744
  init_wsRuntimeLayout();
412518
412745
  import { mkdir as mkdir35, readdir as readdir33, readFile as readFile49, rm as rm11, stat as stat38, writeFile as writeFile36 } from "fs/promises";
412519
- import { extname as extname11, join as join119 } from "path";
412746
+ import { extname as extname11, join as join120 } from "path";
412520
412747
  import { pathToFileURL as pathToFileURL6 } from "url";
412521
412748
  var TOOL_ALLOWED_EXT = new Set([".js", ".mjs", ".cjs"]);
412522
412749
  var MCP_COMPILED_FILES = [".mcp.json", "index.js"];
@@ -412560,7 +412787,7 @@ function extractToolNamesFromModule(moduleValue) {
412560
412787
  return [...new Set(collected)];
412561
412788
  }
412562
412789
  async function collectToolPackageFiles(rootAbs, relativeDir) {
412563
- const current2 = relativeDir ? join119(rootAbs, relativeDir) : rootAbs;
412790
+ const current2 = relativeDir ? join120(rootAbs, relativeDir) : rootAbs;
412564
412791
  let entries;
412565
412792
  try {
412566
412793
  entries = await readdir33(current2, { withFileTypes: true });
@@ -412584,7 +412811,7 @@ async function collectToolPackageFiles(rootAbs, relativeDir) {
412584
412811
  return out;
412585
412812
  }
412586
412813
  async function readMcpServerNames(packageRoot) {
412587
- const filePath = join119(packageRoot, ".mcp.json");
412814
+ const filePath = join120(packageRoot, ".mcp.json");
412588
412815
  const { config: config7, errors: errors8 } = parseMcpConfigFromFilePath({
412589
412816
  filePath,
412590
412817
  expandVars: true,
@@ -412598,7 +412825,7 @@ async function readMcpServerNames(packageRoot) {
412598
412825
  async function collectMcpExportRels(rootAbs) {
412599
412826
  const out = [];
412600
412827
  for (const fileName of MCP_COMPILED_FILES) {
412601
- const st = await stat38(join119(rootAbs, fileName)).catch(() => null);
412828
+ const st = await stat38(join120(rootAbs, fileName)).catch(() => null);
412602
412829
  if (st?.isFile()) {
412603
412830
  out.push(fileName);
412604
412831
  }
@@ -412646,7 +412873,7 @@ async function listMcpsRuntimePackages() {
412646
412873
  return items;
412647
412874
  }
412648
412875
  async function collectToolsExportEntries(packageId) {
412649
- const entryAbs = join119(agentRuntimeDir("tools"), packageId);
412876
+ const entryAbs = join120(agentRuntimeDir("tools"), packageId);
412650
412877
  const entrySt = await stat38(entryAbs).catch(() => null);
412651
412878
  if (!entrySt?.isDirectory()) {
412652
412879
  return null;
@@ -412657,13 +412884,13 @@ async function collectToolsExportEntries(packageId) {
412657
412884
  }
412658
412885
  const zipEntries = {};
412659
412886
  for (const rel of rels) {
412660
- const buf = await readFile49(join119(entryAbs, rel));
412887
+ const buf = await readFile49(join120(entryAbs, rel));
412661
412888
  zipEntries[`${packageId}/${rel}`] = new Uint8Array(buf);
412662
412889
  }
412663
412890
  return zipEntries;
412664
412891
  }
412665
412892
  async function collectMcpsExportEntries(packageId) {
412666
- const entryAbs = join119(agentRuntimeDir("mcps"), packageId);
412893
+ const entryAbs = join120(agentRuntimeDir("mcps"), packageId);
412667
412894
  const entrySt = await stat38(entryAbs).catch(() => null);
412668
412895
  if (!entrySt?.isDirectory()) {
412669
412896
  return null;
@@ -412674,7 +412901,7 @@ async function collectMcpsExportEntries(packageId) {
412674
412901
  }
412675
412902
  const zipEntries = {};
412676
412903
  for (const rel of rels) {
412677
- const buf = await readFile49(join119(entryAbs, rel));
412904
+ const buf = await readFile49(join120(entryAbs, rel));
412678
412905
  zipEntries[`${packageId}/${rel}`] = new Uint8Array(buf);
412679
412906
  }
412680
412907
  return zipEntries;
@@ -412685,7 +412912,7 @@ async function deleteToolsRuntimePackage(packageId) {
412685
412912
  if (pkg?.layer === "system") {
412686
412913
  return { ok: false, message: "system runtime package cannot be deleted" };
412687
412914
  }
412688
- const target = join119(agentRuntimeDir("tools"), packageId);
412915
+ const target = join120(agentRuntimeDir("tools"), packageId);
412689
412916
  try {
412690
412917
  const st = await stat38(target);
412691
412918
  if (!st.isDirectory()) {
@@ -412706,7 +412933,7 @@ async function resolveMcpPackageIdByServerName(serverName) {
412706
412933
  return pkg.packageId;
412707
412934
  }
412708
412935
  }
412709
- const direct = join119(dir, serverName);
412936
+ const direct = join120(dir, serverName);
412710
412937
  const st = await stat38(direct).catch(() => null);
412711
412938
  if (st?.isDirectory()) {
412712
412939
  return serverName;
@@ -412716,13 +412943,13 @@ async function resolveMcpPackageIdByServerName(serverName) {
412716
412943
  async function deleteMcpsRuntimePackage(packageIdOrServer) {
412717
412944
  const runtimeDir = agentRuntimeDir("mcps");
412718
412945
  let targetName = packageIdOrServer;
412719
- let target = join119(runtimeDir, targetName);
412946
+ let target = join120(runtimeDir, targetName);
412720
412947
  let st = await stat38(target).catch(() => null);
412721
412948
  if (!st?.isDirectory()) {
412722
412949
  const byServer = await resolveMcpPackageIdByServerName(packageIdOrServer);
412723
412950
  if (byServer) {
412724
412951
  targetName = byServer;
412725
- target = join119(runtimeDir, targetName);
412952
+ target = join120(runtimeDir, targetName);
412726
412953
  st = await stat38(target).catch(() => null);
412727
412954
  }
412728
412955
  }
@@ -412799,8 +413026,8 @@ async function importToolsRuntimeZip(zipBuffer) {
412799
413026
  continue;
412800
413027
  }
412801
413028
  const relativeTarget = [rootDir, ...rest].join("/");
412802
- const target = join119(dir, relativeTarget);
412803
- await mkdir35(join119(dir, rootDir, ...mid), { recursive: true });
413029
+ const target = join120(dir, relativeTarget);
413030
+ await mkdir35(join120(dir, rootDir, ...mid), { recursive: true });
412804
413031
  let existed = false;
412805
413032
  try {
412806
413033
  await readFile49(target);
@@ -412870,8 +413097,8 @@ async function importMcpsRuntimeZip(zipBuffer) {
412870
413097
  continue;
412871
413098
  }
412872
413099
  const relativeTarget = [rootDir, ...rest].join("/");
412873
- const target = join119(dir, relativeTarget);
412874
- await mkdir35(join119(dir, rootDir, ...rest.slice(0, -1)), { recursive: true });
413100
+ const target = join120(dir, relativeTarget);
413101
+ await mkdir35(join120(dir, rootDir, ...rest.slice(0, -1)), { recursive: true });
412875
413102
  let existed = false;
412876
413103
  try {
412877
413104
  await readFile49(target);
@@ -413079,9 +413306,17 @@ init_wsSessionId();
413079
413306
  init_wsSessionOverrides();
413080
413307
  init_wsAgentWorkspace();
413081
413308
 
413309
+ // src/server/wsMcp/wsBrowserTypes.ts
413310
+ function isSessionGatewayData(data) {
413311
+ return data.kind === "session";
413312
+ }
413313
+
413082
413314
  // src/server/wsMcp/wsBrowserProtocol.ts
413083
413315
  import { randomUUID as randomUUID38 } from "crypto";
413084
413316
  function emitBootstrapSessionMeta(ws) {
413317
+ if (!isSessionGatewayData(ws.data)) {
413318
+ return;
413319
+ }
413085
413320
  const sid = ws.data.sessionId?.trim();
413086
413321
  if (!sid) {
413087
413322
  return;
@@ -413115,26 +413350,26 @@ function pushBrowserJson(ws, payload) {
413115
413350
 
413116
413351
  // src/server/wsMcp/staticAssets.ts
413117
413352
  import { existsSync as existsSync14 } from "fs";
413118
- import { join as join120, relative as relative21, resolve as resolve37 } from "path";
413353
+ import { join as join121, relative as relative21, resolve as resolve37 } from "path";
413119
413354
  import { stat as stat39 } from "fs/promises";
413120
413355
  var SAFE_A_DIST_SUBDIR = "safe-a";
413121
413356
  var WS_TEST_DIST_SUBDIR = "ws-test";
413122
413357
  function resolveSafeADistDir() {
413123
413358
  const fromDistDir = process.env.WS_DIST_DIR?.trim();
413124
- if (fromDistDir && existsSync14(join120(fromDistDir, "index.html"))) {
413359
+ if (fromDistDir && existsSync14(join121(fromDistDir, "index.html"))) {
413125
413360
  return fromDistDir;
413126
413361
  }
413127
413362
  const projectRoot = process.env.WS_PROJECT_ROOT?.trim();
413128
413363
  if (projectRoot) {
413129
- const candidate = join120(projectRoot, "dist", SAFE_A_DIST_SUBDIR);
413130
- if (existsSync14(join120(candidate, "index.html"))) {
413364
+ const candidate = join121(projectRoot, "dist", SAFE_A_DIST_SUBDIR);
413365
+ if (existsSync14(join121(candidate, "index.html"))) {
413131
413366
  return candidate;
413132
413367
  }
413133
413368
  }
413134
413369
  let dir = resolve37(import.meta.dir, "../..");
413135
413370
  for (let depth = 0;depth < 8; depth += 1) {
413136
- const safeADir = join120(dir, "dist", SAFE_A_DIST_SUBDIR);
413137
- if (existsSync14(join120(safeADir, "index.html"))) {
413371
+ const safeADir = join121(dir, "dist", SAFE_A_DIST_SUBDIR);
413372
+ if (existsSync14(join121(safeADir, "index.html"))) {
413138
413373
  return safeADir;
413139
413374
  }
413140
413375
  const parent = resolve37(dir, "..");
@@ -413143,24 +413378,24 @@ function resolveSafeADistDir() {
413143
413378
  }
413144
413379
  dir = parent;
413145
413380
  }
413146
- return join120(import.meta.dir, "../../..", "dist", SAFE_A_DIST_SUBDIR);
413381
+ return join121(import.meta.dir, "../../..", "dist", SAFE_A_DIST_SUBDIR);
413147
413382
  }
413148
413383
  function resolveWsTestDistDir() {
413149
413384
  const fromDir = process.env.WS_WS_TEST_DIR?.trim();
413150
- if (fromDir && existsSync14(join120(fromDir, "ws-test.html"))) {
413385
+ if (fromDir && existsSync14(join121(fromDir, "ws-test.html"))) {
413151
413386
  return fromDir;
413152
413387
  }
413153
413388
  const projectRoot = process.env.WS_PROJECT_ROOT?.trim();
413154
413389
  if (projectRoot) {
413155
- const candidate = join120(projectRoot, "dist", WS_TEST_DIST_SUBDIR);
413156
- if (existsSync14(join120(candidate, "ws-test.html"))) {
413390
+ const candidate = join121(projectRoot, "dist", WS_TEST_DIST_SUBDIR);
413391
+ if (existsSync14(join121(candidate, "ws-test.html"))) {
413157
413392
  return candidate;
413158
413393
  }
413159
413394
  }
413160
413395
  let dir = resolve37(import.meta.dir, "../..");
413161
413396
  for (let depth = 0;depth < 8; depth += 1) {
413162
- const wsTestDir = join120(dir, "dist", WS_TEST_DIST_SUBDIR);
413163
- if (existsSync14(join120(wsTestDir, "ws-test.html"))) {
413397
+ const wsTestDir = join121(dir, "dist", WS_TEST_DIST_SUBDIR);
413398
+ if (existsSync14(join121(wsTestDir, "ws-test.html"))) {
413164
413399
  return wsTestDir;
413165
413400
  }
413166
413401
  const parent = resolve37(dir, "..");
@@ -413169,7 +413404,7 @@ function resolveWsTestDistDir() {
413169
413404
  }
413170
413405
  dir = parent;
413171
413406
  }
413172
- return join120(import.meta.dir, "../../..", "dist", WS_TEST_DIST_SUBDIR);
413407
+ return join121(import.meta.dir, "../../..", "dist", WS_TEST_DIST_SUBDIR);
413173
413408
  }
413174
413409
  var safeADistDir = resolveSafeADistDir();
413175
413410
  var wsTestDistDir = resolveWsTestDistDir();
@@ -413221,7 +413456,7 @@ function decodeDistRel(rel) {
413221
413456
  return decoded;
413222
413457
  }
413223
413458
  function safeResolveDistAbs(decodedRel) {
413224
- const abs = resolve37(join120(safeADistDir, decodedRel));
413459
+ const abs = resolve37(join121(safeADistDir, decodedRel));
413225
413460
  const root3 = resolve37(safeADistDir);
413226
413461
  const relToRoot = relative21(root3, abs);
413227
413462
  if (relToRoot.startsWith("..") || relToRoot === "") {
@@ -413274,7 +413509,7 @@ async function resolvedDistAsset(pathname) {
413274
413509
  var SLASH_CMD_PATCH_JS = "slash-command-ui-patch.js";
413275
413510
  var SLASH_CMD_PATCH_CSS = "slash-command-ui-patch.css";
413276
413511
  function slashCommandPatchAssetPath(name3) {
413277
- return join120(safeADistDir, name3);
413512
+ return join121(safeADistDir, name3);
413278
413513
  }
413279
413514
  async function trySlashCommandUiPatchStatic(req, pathname) {
413280
413515
  if (req.method !== "GET" && req.method !== "HEAD")
@@ -413295,14 +413530,19 @@ async function trySlashCommandUiPatchStatic(req, pathname) {
413295
413530
  async function tryWsTestAssetStatic(req, pathname) {
413296
413531
  if (req.method !== "GET" && req.method !== "HEAD")
413297
413532
  return;
413298
- if (pathname !== "/ws-test.css" && pathname !== "/ws-test.js")
413533
+ let rel = null;
413534
+ if (pathname === "/ws-test.css" || pathname === "/ws-test.js") {
413535
+ rel = pathname.slice(1);
413536
+ } else if (pathname.startsWith("/vendor/")) {
413537
+ rel = pathname.slice(1);
413538
+ }
413539
+ if (!rel)
413299
413540
  return;
413300
- const fileName = pathname === "/ws-test.css" ? "ws-test.css" : "ws-test.js";
413301
- const abs = join120(wsTestDistDir, fileName);
413541
+ const abs = join121(wsTestDistDir, rel);
413302
413542
  if (!existsSync14(abs))
413303
413543
  return;
413304
413544
  const file2 = Bun.file(abs);
413305
- const mime = fileName.endsWith(".css") ? "text/css; charset=utf-8" : "application/javascript; charset=utf-8";
413545
+ const mime = rel.endsWith(".css") ? "text/css; charset=utf-8" : "application/javascript; charset=utf-8";
413306
413546
  return new Response(req.method === "HEAD" ? null : file2, {
413307
413547
  headers: { "content-type": mime }
413308
413548
  });
@@ -413355,7 +413595,7 @@ async function tryStaticHtmlResponse(pathname) {
413355
413595
  const fileName = STATIC_HTML_ROUTES[pathname];
413356
413596
  if (!fileName)
413357
413597
  return;
413358
- const abs = join120(wsTestDistDir, fileName);
413598
+ const abs = join121(wsTestDistDir, fileName);
413359
413599
  const file2 = Bun.file(abs);
413360
413600
  if (!await file2.exists())
413361
413601
  return;
@@ -413398,7 +413638,7 @@ function startWsMcpGateway(opts) {
413398
413638
  if (staticHtml !== undefined) {
413399
413639
  return staticHtml;
413400
413640
  }
413401
- if ((req.method === "GET" || req.method === "HEAD") && url3.pathname === wsDistHttpPrefix && existsSync15(join121(safeADistDir, "index.html"))) {
413641
+ if ((req.method === "GET" || req.method === "HEAD") && url3.pathname === wsDistHttpPrefix && existsSync15(join122(safeADistDir, "index.html"))) {
413402
413642
  return Response.redirect(new URL(`${wsDistHttpPrefix}/`, url3).href, 302);
413403
413643
  }
413404
413644
  const distRes = await tryDistStatic(req, url3.pathname);
@@ -413471,6 +413711,9 @@ function startWsMcpGateway(opts) {
413471
413711
  const repoRes = await handleRepoApi(req, url3);
413472
413712
  if (repoRes !== undefined)
413473
413713
  return repoRes;
413714
+ if (url3.pathname === "/ws/terminal") {
413715
+ return handleTerminalWsUpgrade(req, bunServer);
413716
+ }
413474
413717
  if (url3.pathname === "/ws") {
413475
413718
  return handleWsUpgrade(req, bunServer);
413476
413719
  }
@@ -413479,6 +413722,10 @@ function startWsMcpGateway(opts) {
413479
413722
  },
413480
413723
  websocket: {
413481
413724
  open(ws) {
413725
+ if (ws.data.kind === "terminal") {
413726
+ handleTerminalWsOpen(ws);
413727
+ return;
413728
+ }
413482
413729
  emitBootstrapSessionMeta(ws);
413483
413730
  const sid = ws.data.sessionId?.trim();
413484
413731
  if (sid) {
@@ -413487,9 +413734,17 @@ function startWsMcpGateway(opts) {
413487
413734
  hooks2.onControl({ type: "open", data: { ...ws.data } });
413488
413735
  },
413489
413736
  message(ws, message) {
413737
+ if (ws.data.kind === "terminal") {
413738
+ handleTerminalWsMessage(ws, message);
413739
+ return;
413740
+ }
413490
413741
  handleWsMessage(ws, message, hooks2, sessionSockets);
413491
413742
  },
413492
413743
  close(ws) {
413744
+ if (ws.data.kind === "terminal") {
413745
+ handleTerminalWsClose(ws);
413746
+ return;
413747
+ }
413493
413748
  const sid = ws.data.sessionId?.trim();
413494
413749
  if (sid) {
413495
413750
  sessionSockets.delete(sid);
@@ -413567,6 +413822,7 @@ async function handleWsUpgrade(req, server) {
413567
413822
  }
413568
413823
  const ok = server.upgrade(req, {
413569
413824
  data: {
413825
+ kind: "session",
413570
413826
  workspaceDir,
413571
413827
  sessionId,
413572
413828
  agent,
@@ -413582,6 +413838,9 @@ async function handleWsUpgrade(req, server) {
413582
413838
  return;
413583
413839
  }
413584
413840
  async function rebindBrowserWsSession(ws, sessionSockets, parsed) {
413841
+ if (!isSessionGatewayData(ws.data)) {
413842
+ return;
413843
+ }
413585
413844
  const rawAgent = typeof parsed.agent === "string" && parsed.agent.trim().length > 0 ? parsed.agent.trim() : ws.data.agent;
413586
413845
  const rawSid = typeof parsed.sessionId === "string" ? parsed.sessionId.trim() : "";
413587
413846
  const nextSid = rawSid.length > 0 ? rawSid : createWsUserSessionId();
@@ -413609,6 +413868,7 @@ async function rebindBrowserWsSession(ws, sessionSockets, parsed) {
413609
413868
  sessionSockets.delete(oldSid);
413610
413869
  }
413611
413870
  ws.data = {
413871
+ kind: "session",
413612
413872
  workspaceDir: r4.agentDir,
413613
413873
  sessionId: nextSid,
413614
413874
  agent: r4.agent,
@@ -413622,6 +413882,9 @@ async function rebindBrowserWsSession(ws, sessionSockets, parsed) {
413622
413882
  return oldSid;
413623
413883
  }
413624
413884
  async function handleWsMessage(ws, message, hooks2, sessionSockets) {
413885
+ if (!isSessionGatewayData(ws.data)) {
413886
+ return;
413887
+ }
413625
413888
  let parsed;
413626
413889
  try {
413627
413890
  parsed = typeof message === "string" ? JSON.parse(message) : message;