@couralabs/claudin 0.1.3 → 0.1.5

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 (2) hide show
  1. package/claudin.js +1587 -150
  2. package/package.json +2 -2
package/claudin.js CHANGED
@@ -6148,6 +6148,7 @@ var agentRequestSchemas = [
6148
6148
  object({ type: literal("agent.prompt.queue.requested"), agentSessionId, content }),
6149
6149
  object({ type: literal("agent.prompt.steer.requested"), agentSessionId, content }),
6150
6150
  object({ type: literal("agent.prompt.cancel.requested"), agentSessionId }),
6151
+ object({ type: literal("agent.task.stop.requested"), agentSessionId, taskId: string2() }),
6151
6152
  object({
6152
6153
  type: literal("agent.tool.approval.answered"),
6153
6154
  agentSessionId,
@@ -6161,7 +6162,6 @@ var agentRequestSchemas = [
6161
6162
  answers: record(string2(), string2())
6162
6163
  }),
6163
6164
  object({ type: literal("agent.model.set.requested"), agentSessionId, model: string2() }),
6164
- object({ type: literal("agent.model.cycle.requested"), agentSessionId }),
6165
6165
  object({
6166
6166
  type: literal("agent.permission_mode.set.requested"),
6167
6167
  agentSessionId,
@@ -6175,6 +6175,17 @@ var agentRequestSchemas = [
6175
6175
  object({ type: literal("agent.commands.requested"), agentSessionId }),
6176
6176
  object({ type: literal("agent.models.requested"), agentSessionId }),
6177
6177
  object({ type: literal("agent.mcp.status.requested"), agentSessionId }),
6178
+ object({
6179
+ type: literal("agent.mcp.login.requested"),
6180
+ agentSessionId,
6181
+ serverName: string2()
6182
+ }),
6183
+ object({
6184
+ type: literal("agent.mcp.callback.submitted"),
6185
+ agentSessionId,
6186
+ serverName: string2(),
6187
+ callbackUrl: string2()
6188
+ }),
6178
6189
  object({ type: literal("agent.usage.requested"), agentSessionId }),
6179
6190
  object({ type: literal("agent.rate_limit.requested"), agentSessionId }),
6180
6191
  object({ type: literal("agent.rate_limit.cached.requested") }),
@@ -6207,6 +6218,7 @@ var createSessionState = (sessionId) => ({
6207
6218
  models: [],
6208
6219
  sessionList: [],
6209
6220
  queuedTurns: 0,
6221
+ tasks: [],
6210
6222
  transcript: [],
6211
6223
  entryCounter: 0,
6212
6224
  now: Date.now(),
@@ -6217,7 +6229,8 @@ var createSessionState = (sessionId) => ({
6217
6229
  backgroundEditor: null,
6218
6230
  question: null,
6219
6231
  history: null,
6220
- diffViewer: null
6232
+ diffViewer: null,
6233
+ toast: null
6221
6234
  }
6222
6235
  });
6223
6236
 
@@ -6514,6 +6527,56 @@ function reduceTaskProgress(state, message) {
6514
6527
  return updateToolCall(state, toolUseId, (call) => ({ ...call, progress: summary }));
6515
6528
  }
6516
6529
 
6530
+ // packages/events/src/reducers/reduceTasks.ts
6531
+ var FINISHED_STATUSES = ["completed", "failed", "killed"];
6532
+ var isTaskMessage = (message) => message.type === "system" && ["task_started", "task_progress", "task_updated", "task_notification"].includes(message.subtype);
6533
+ var patchTask = (tasks, id, patch) => tasks.map((task) => task.id === id ? patch(task) : task);
6534
+ var startTask = (state, message) => {
6535
+ if (message.ambient || message.skip_transcript)
6536
+ return state.tasks;
6537
+ const task = {
6538
+ id: message.task_id,
6539
+ kind: message.subagent_type ?? message.task_type ?? "task",
6540
+ description: message.description,
6541
+ startedAt: state.now,
6542
+ tokens: 0,
6543
+ paused: false
6544
+ };
6545
+ return [...state.tasks.filter(({ id }) => id !== task.id), task];
6546
+ };
6547
+ var updateTask = (tasks, message) => {
6548
+ const { status, description } = message.patch;
6549
+ if (status && FINISHED_STATUSES.includes(status)) {
6550
+ return tasks.filter(({ id }) => id !== message.task_id);
6551
+ }
6552
+ return patchTask(tasks, message.task_id, (task) => ({
6553
+ ...task,
6554
+ description: description ?? task.description,
6555
+ paused: status ? status === "paused" : task.paused
6556
+ }));
6557
+ };
6558
+ var readTasks = (state, message) => {
6559
+ switch (message.subtype) {
6560
+ case "task_started":
6561
+ return startTask(state, message);
6562
+ case "task_progress":
6563
+ return patchTask(state.tasks, message.task_id, (task) => ({
6564
+ ...task,
6565
+ lastToolName: message.last_tool_name ?? task.lastToolName,
6566
+ summary: message.summary ?? task.summary,
6567
+ tokens: message.usage.total_tokens
6568
+ }));
6569
+ case "task_updated":
6570
+ return updateTask(state.tasks, message);
6571
+ case "task_notification":
6572
+ return state.tasks.filter(({ id }) => id !== message.task_id);
6573
+ }
6574
+ };
6575
+ var reduceTasks = (state, message) => ({
6576
+ ...state,
6577
+ tasks: readTasks(state, message)
6578
+ });
6579
+
6517
6580
  // packages/events/src/reducers/reduceToolResults.ts
6518
6581
  function applyResult(state, block) {
6519
6582
  if (block.type !== "tool_result" || !block.tool_use_id)
@@ -6531,10 +6594,10 @@ function reduceToolResults(state, message) {
6531
6594
 
6532
6595
  // packages/events/src/reducers/reduceAgentMessage.ts
6533
6596
  function reduceAgentMessage(state, message) {
6597
+ if (isTaskMessage(message))
6598
+ return reduceTaskMessage(reduceTasks(state, message), message);
6534
6599
  switch (message.type) {
6535
6600
  case "system":
6536
- if (message.subtype === "task_progress")
6537
- return reduceTaskProgress(state, message);
6538
6601
  if (message.subtype !== "init")
6539
6602
  return reduceNoticeMessage(state, message);
6540
6603
  return {
@@ -6560,6 +6623,15 @@ function reduceAgentMessage(state, message) {
6560
6623
  return reduceNoticeMessage(state, message);
6561
6624
  }
6562
6625
  }
6626
+ function reduceTaskMessage(state, message) {
6627
+ if (message.type === "system" && message.subtype === "task_progress") {
6628
+ return reduceTaskProgress(state, message);
6629
+ }
6630
+ if (message.type === "system" && message.subtype === "task_notification") {
6631
+ return reduceNoticeMessage(state, message);
6632
+ }
6633
+ return state;
6634
+ }
6563
6635
  function reduceNoticeMessage(state, message) {
6564
6636
  const text = describeSystemMessage(message);
6565
6637
  return text ? appendNotice(state, text) : state;
@@ -6632,7 +6704,7 @@ var applyLoadedBackground = (state, background = TRANSPARENT_BACKGROUND) => ({ .
6632
6704
  var applySavedBackground = (state, color) => appendNotice(closeBackgroundEditor({ ...state, background: color }), "Background color saved");
6633
6705
 
6634
6706
  // packages/events/src/reducers/reduceDiffViewer.ts
6635
- var NO_DIFFS_NOTICE = "No changes in the files this session edited";
6707
+ var NO_DIFFS_NOTICE = "No git changes or session edits to show";
6636
6708
  function openDiffViewer(state, files) {
6637
6709
  if (files.length === 0)
6638
6710
  return appendNotice(state, NO_DIFFS_NOTICE);
@@ -6651,7 +6723,10 @@ var closeDiffViewer = (state) => ({
6651
6723
  });
6652
6724
 
6653
6725
  // packages/events/src/reducers/reduceNotices.ts
6654
- var describeServers = (servers) => servers.length === 0 ? "No MCP servers configured" : `MCP servers: ${servers.map((s) => `${s.name} (${s.status})`).join(", ")}`;
6726
+ var LOGIN_HINT = "needs-auth: sign in with /mcp login <name>";
6727
+ var describeServer = ({ name, status }) => `${name} (${status === "needs-auth" ? LOGIN_HINT.replace("<name>", name) : status})`;
6728
+ var describeServers = (servers) => servers.length === 0 ? "No MCP servers configured" : `MCP servers: ${servers.map(describeServer).join(", ")}`;
6729
+ var describeLoginStarted = (serverName, authUrl) => `Signing in to ${serverName}. If the browser did not open, visit: ${authUrl}`;
6655
6730
  function reduceModelChanged(state, model) {
6656
6731
  const changed = { ...state, model };
6657
6732
  return appendNotice(changed, `Model set to ${readModelLabel(changed)}`);
@@ -6703,6 +6778,13 @@ function moveQuestionCursor(state, delta) {
6703
6778
  return state;
6704
6779
  return withDraft(state, { ...question, cursor: (question.cursor + delta + size) % size });
6705
6780
  }
6781
+ function setQuestionCursor(state, cursor) {
6782
+ const { question } = state.ui;
6783
+ const current = question ? readCurrentQuestion(question) : undefined;
6784
+ if (!question || !current || cursor < 0 || cursor > current.options.length)
6785
+ return state;
6786
+ return withDraft(state, { ...question, cursor });
6787
+ }
6706
6788
  function toggleQuestionPick(state) {
6707
6789
  const { question } = state.ui;
6708
6790
  const current = question ? readCurrentQuestion(question) : undefined;
@@ -6730,6 +6812,14 @@ function changeQuestionCustom(state, text) {
6730
6812
  return question ? withDraft(state, { ...question, custom: text }) : state;
6731
6813
  }
6732
6814
 
6815
+ // packages/events/src/reducers/reduceToast.ts
6816
+ var withToast = (state, toast) => ({
6817
+ ...state,
6818
+ ui: { ...state.ui, toast }
6819
+ });
6820
+ var postToast = (state, toast) => withToast(state, { id: toast.id, text: toast.text });
6821
+ var dismissToast = (state, id) => state.ui.toast?.id === id ? withToast(state, null) : state;
6822
+
6733
6823
  // packages/events/src/reducers/reduceUi.ts
6734
6824
  var FOCUS_ORDER = ["input", "scrollback"];
6735
6825
  function cycleFocus(state, direction) {
@@ -6817,6 +6907,8 @@ function reduceUi(state, event) {
6817
6907
  return adjustBackgroundValue(state, event.delta);
6818
6908
  case "ui.question.moved":
6819
6909
  return moveQuestionCursor(state, event.delta);
6910
+ case "ui.question.cursor.set":
6911
+ return setQuestionCursor(state, event.cursor);
6820
6912
  case "ui.question.toggled":
6821
6913
  return toggleQuestionPick(state);
6822
6914
  case "ui.question.custom.changed":
@@ -6824,9 +6916,14 @@ function reduceUi(state, event) {
6824
6916
  case "ui.question.recorded":
6825
6917
  return recordQuestionAnswer(state, event);
6826
6918
  case "ui.exit.requested":
6919
+ case "ui.title.set":
6827
6920
  return state;
6828
6921
  case "ui.notice.posted":
6829
6922
  return appendNotice(state, event.text);
6923
+ case "ui.toast.posted":
6924
+ return postToast(state, event);
6925
+ case "ui.toast.dismissed":
6926
+ return dismissToast(state, event.id);
6830
6927
  case "ui.clock.ticked":
6831
6928
  return { ...state, now: event.now };
6832
6929
  }
@@ -6847,7 +6944,8 @@ function restoreSession(state, sessionId, stored, notice) {
6847
6944
  return appendNotice({ ...adoptReplay(state, settled, sessionId), status: "idle", queuedTurns: 0 }, notice);
6848
6945
  }
6849
6946
  var syncSession = (state, sessionId, stored) => appendNotice(adoptReplay(state, replayEvents(sessionId, stored), sessionId), "Attached to the live session");
6850
- function openModelPicker(state, models) {
6947
+ function openModelPicker(state, allModels) {
6948
+ const models = allModels.filter((model) => model.value !== "default");
6851
6949
  const current = models.findIndex((model) => model.value === state.model);
6852
6950
  const picker = { kind: "model", selected: Math.max(current, 0) };
6853
6951
  return { ...state, models, ui: { ...state.ui, picker } };
@@ -6937,6 +7035,8 @@ function reduceSessionState(state, event) {
6937
7035
  return reduceModeChanged(state, event.mode);
6938
7036
  case "agent.mcp.status.received":
6939
7037
  return appendNotice(state, describeServers(event.servers));
7038
+ case "agent.mcp.login.started":
7039
+ return appendNotice(state, describeLoginStarted(event.serverName, event.authUrl));
6940
7040
  case "workspace.info.received":
6941
7041
  return { ...state, cwd: event.cwd, gitBranch: event.gitBranch, gitStats: event.gitStats };
6942
7042
  case "options.loaded":
@@ -7059,6 +7159,11 @@ var agentResponseSchemas = [
7059
7159
  type: literal("agent.mcp.status.received"),
7060
7160
  servers: sdkValue()
7061
7161
  }),
7162
+ object({
7163
+ type: literal("agent.mcp.login.started"),
7164
+ serverName: string2(),
7165
+ authUrl: string2()
7166
+ }),
7062
7167
  object({
7063
7168
  type: literal("agent.usage.received"),
7064
7169
  usage: sdkValue()
@@ -7156,6 +7261,9 @@ var PRIVATE_TYPES = new Set([
7156
7261
  "agent.commands.requested",
7157
7262
  "agent.mcp.status.requested",
7158
7263
  "agent.mcp.status.received",
7264
+ "agent.mcp.login.requested",
7265
+ "agent.mcp.callback.submitted",
7266
+ "agent.mcp.login.started",
7159
7267
  "agent.usage.requested",
7160
7268
  "agent.usage.received",
7161
7269
  "agent.rate_limit.requested",
@@ -7396,12 +7504,41 @@ import {
7396
7504
  getSessionMessages,
7397
7505
  query
7398
7506
  } from "@anthropic-ai/claude-agent-sdk";
7507
+
7508
+ // packages/agent/src/runtime/muteShadowedWarning.ts
7509
+ var SHADOWED_WARNING_CODE = "CLAUDE_SDK_CAN_USE_TOOL_SHADOWED";
7510
+ function readWarningCode(args) {
7511
+ const [first, second] = args;
7512
+ if (typeof first === "object" && first !== null)
7513
+ return first.code;
7514
+ return typeof first === "string" && typeof second === "string" ? second : undefined;
7515
+ }
7516
+ function muteShadowedWarning() {
7517
+ const original = process.emitWarning.bind(process);
7518
+ process.emitWarning = (warning, ...args) => {
7519
+ if (readWarningCode(args) === SHADOWED_WARNING_CODE)
7520
+ return;
7521
+ return original(warning, ...args);
7522
+ };
7523
+ }
7524
+
7525
+ // packages/agent/src/runtime/agentRuntime.ts
7526
+ muteShadowedWarning();
7399
7527
  var sdkRuntime = {
7400
- open: query,
7528
+ open: (params) => query(params),
7401
7529
  getInfo: getSessionInfo,
7402
7530
  getMessages: getSessionMessages,
7403
7531
  fork: forkSession
7404
7532
  };
7533
+ // packages/agent/src/runtime/buildUserMessage.ts
7534
+ var isSlashCommand = (content) => readPromptText(content).trimStart().startsWith("/");
7535
+ var buildUserMessage = (content, priority) => ({
7536
+ type: "user",
7537
+ message: { role: "user", content },
7538
+ parent_tool_use_id: null,
7539
+ priority,
7540
+ client_composed: isSlashCommand(content) ? undefined : true
7541
+ });
7405
7542
  // node_modules/.bun/p-defer@4.0.1/node_modules/p-defer/index.js
7406
7543
  function pDefer() {
7407
7544
  const deferred = {};
@@ -7684,6 +7821,846 @@ function _pushable(getNext, options) {
7684
7821
  };
7685
7822
  return pushable;
7686
7823
  }
7824
+ // packages/agent/src/mcp/waitForMcpLogin.ts
7825
+ var DEFAULT_LOGIN_WAIT = { intervalMs: 2000, timeoutMs: 180000 };
7826
+ async function waitForMcpLogin(fetchStatus, serverName, { intervalMs, timeoutMs } = DEFAULT_LOGIN_WAIT) {
7827
+ const deadline = Date.now() + timeoutMs;
7828
+ let servers = await fetchStatus();
7829
+ while (Date.now() < deadline && isAwaitingLogin(servers, serverName)) {
7830
+ await Bun.sleep(intervalMs);
7831
+ servers = await fetchStatus();
7832
+ }
7833
+ return servers;
7834
+ }
7835
+ var isAwaitingLogin = (servers, serverName) => servers.some((server) => server.name === serverName && server.status === "needs-auth");
7836
+
7837
+ // node_modules/.bun/open@11.0.4/node_modules/open/index.js
7838
+ import process9 from "process";
7839
+ import path2 from "path";
7840
+ import { fileURLToPath } from "url";
7841
+ import childProcess3 from "child_process";
7842
+ import fs5, { constants as fsConstants2 } from "fs/promises";
7843
+
7844
+ // node_modules/.bun/wsl-utils@1.0.1/node_modules/wsl-utils/index.js
7845
+ import path from "path";
7846
+ import { promisify as promisify2 } from "util";
7847
+ import childProcess2 from "child_process";
7848
+ import fs4, { constants as fsConstants } from "fs/promises";
7849
+
7850
+ // node_modules/.bun/is-wsl@3.1.1/node_modules/is-wsl/index.js
7851
+ import process2 from "process";
7852
+ import os from "os";
7853
+ import fs3 from "fs";
7854
+
7855
+ // node_modules/.bun/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
7856
+ import fs2 from "fs";
7857
+
7858
+ // node_modules/.bun/is-docker@3.0.0/node_modules/is-docker/index.js
7859
+ import fs from "fs";
7860
+ var isDockerCached;
7861
+ function hasDockerEnv() {
7862
+ try {
7863
+ fs.statSync("/.dockerenv");
7864
+ return true;
7865
+ } catch {
7866
+ return false;
7867
+ }
7868
+ }
7869
+ function hasDockerCGroup() {
7870
+ try {
7871
+ return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
7872
+ } catch {
7873
+ return false;
7874
+ }
7875
+ }
7876
+ function isDocker() {
7877
+ if (isDockerCached === undefined) {
7878
+ isDockerCached = hasDockerEnv() || hasDockerCGroup();
7879
+ }
7880
+ return isDockerCached;
7881
+ }
7882
+
7883
+ // node_modules/.bun/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
7884
+ var cachedResult;
7885
+ var hasContainerEnv = () => {
7886
+ try {
7887
+ fs2.statSync("/run/.containerenv");
7888
+ return true;
7889
+ } catch {
7890
+ return false;
7891
+ }
7892
+ };
7893
+ function isInsideContainer() {
7894
+ if (cachedResult === undefined) {
7895
+ cachedResult = hasContainerEnv() || isDocker();
7896
+ }
7897
+ return cachedResult;
7898
+ }
7899
+
7900
+ // node_modules/.bun/is-wsl@3.1.1/node_modules/is-wsl/index.js
7901
+ var isWsl = () => {
7902
+ if (process2.platform !== "linux") {
7903
+ return false;
7904
+ }
7905
+ if (os.release().toLowerCase().includes("microsoft")) {
7906
+ if (isInsideContainer()) {
7907
+ return false;
7908
+ }
7909
+ return true;
7910
+ }
7911
+ try {
7912
+ if (fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
7913
+ return !isInsideContainer();
7914
+ }
7915
+ } catch {}
7916
+ if (fs3.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs3.existsSync("/run/WSL")) {
7917
+ return !isInsideContainer();
7918
+ }
7919
+ return false;
7920
+ };
7921
+ var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
7922
+
7923
+ // node_modules/.bun/powershell-utils@0.2.1/node_modules/powershell-utils/index.js
7924
+ import process3 from "process";
7925
+ import { Buffer as Buffer2 } from "buffer";
7926
+ import { promisify } from "util";
7927
+ import childProcess from "child_process";
7928
+ var execFile = promisify(childProcess.execFile);
7929
+ var powerShellPath = () => `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
7930
+ var argumentsPrefix = [
7931
+ "-NoProfile",
7932
+ "-NonInteractive",
7933
+ "-ExecutionPolicy",
7934
+ "Bypass",
7935
+ "-EncodedCommand"
7936
+ ];
7937
+ var encodeCommand = (command) => Buffer2.from(command, "utf16le").toString("base64");
7938
+ var escapeArgument = (value) => `'${String(value).replaceAll(/['\u2018\u2019\u201A\u201B]/g, (match) => match + match)}'`;
7939
+ var createArguments = (command) => [...argumentsPrefix, encodeCommand(command)];
7940
+ var createExecFileOptions = (options) => ({
7941
+ encoding: "utf8",
7942
+ ...options,
7943
+ shell: false
7944
+ });
7945
+ var executePowerShell = async (command, options = {}) => {
7946
+ const {
7947
+ powerShellPath: psPath,
7948
+ ...execFileOptions
7949
+ } = options;
7950
+ return execFile(psPath ?? powerShellPath(), createArguments(command), createExecFileOptions(execFileOptions));
7951
+ };
7952
+ executePowerShell.argumentsPrefix = argumentsPrefix;
7953
+ executePowerShell.encodeCommand = encodeCommand;
7954
+ executePowerShell.escapeArgument = escapeArgument;
7955
+ executePowerShell.createArguments = createArguments;
7956
+
7957
+ // node_modules/.bun/wsl-utils@1.0.1/node_modules/wsl-utils/utilities.js
7958
+ function parseMountPointFromConfig(content) {
7959
+ for (const line of content.split(`
7960
+ `)) {
7961
+ if (/^\s*#/.test(line)) {
7962
+ continue;
7963
+ }
7964
+ const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
7965
+ if (!match) {
7966
+ continue;
7967
+ }
7968
+ return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
7969
+ }
7970
+ }
7971
+
7972
+ // node_modules/.bun/wsl-utils@1.0.1/node_modules/wsl-utils/index.js
7973
+ var execFile2 = promisify2(childProcess2.execFile);
7974
+ var wslDrivesMountPoint = (() => {
7975
+ const defaultMountPoint = "/mnt/";
7976
+ let mountPoint;
7977
+ return async function() {
7978
+ if (mountPoint) {
7979
+ return mountPoint;
7980
+ }
7981
+ const configFilePath = "/etc/wsl.conf";
7982
+ let isConfigFileExists = false;
7983
+ try {
7984
+ await fs4.access(configFilePath, fsConstants.F_OK);
7985
+ isConfigFileExists = true;
7986
+ } catch {}
7987
+ if (!isConfigFileExists) {
7988
+ return defaultMountPoint;
7989
+ }
7990
+ const configContent = await fs4.readFile(configFilePath, { encoding: "utf8" });
7991
+ const parsedMountPoint = parseMountPointFromConfig(configContent);
7992
+ if (parsedMountPoint === undefined) {
7993
+ return defaultMountPoint;
7994
+ }
7995
+ mountPoint = parsedMountPoint;
7996
+ mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
7997
+ return mountPoint;
7998
+ };
7999
+ })();
8000
+ var powerShellPathFromWsl = async () => {
8001
+ const mountPoint = await wslDrivesMountPoint();
8002
+ return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
8003
+ };
8004
+ var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
8005
+ var canAccessPowerShellPromise;
8006
+ var canAccessPowerShell = async () => {
8007
+ canAccessPowerShellPromise ??= (async () => {
8008
+ try {
8009
+ const psPath = await powerShellPath2();
8010
+ await fs4.access(psPath, fsConstants.X_OK);
8011
+ return true;
8012
+ } catch {
8013
+ return false;
8014
+ }
8015
+ })();
8016
+ return canAccessPowerShellPromise;
8017
+ };
8018
+ var wslDefaultBrowser = async () => {
8019
+ const psPath = await powerShellPath2();
8020
+ const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
8021
+ const { stdout } = await executePowerShell(command, {
8022
+ powerShellPath: psPath,
8023
+ cwd: path.dirname(psPath)
8024
+ });
8025
+ return stdout.trim();
8026
+ };
8027
+ var isUrl = (path2) => /^[a-z]+:\/\//i.test(path2);
8028
+ var convertPath = async (flag, path2) => {
8029
+ const wslpathArguments = path2.startsWith("-") ? [flag, "--", path2] : [flag, path2];
8030
+ try {
8031
+ const { stdout } = await execFile2("wslpath", wslpathArguments, { encoding: "utf8" });
8032
+ return stdout.replace(/\r?\n$/, "") || path2;
8033
+ } catch {
8034
+ return path2;
8035
+ }
8036
+ };
8037
+ var convertWslPathToWindows = async (paths) => {
8038
+ const isBatch = Array.isArray(paths);
8039
+ const pathArray = isBatch ? paths : [paths];
8040
+ const results = await Promise.all(pathArray.map((path2) => isUrl(path2) ? path2 : convertPath("-aw", path2)));
8041
+ return isBatch ? results : results[0];
8042
+ };
8043
+
8044
+ // node_modules/.bun/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
8045
+ function defineLazyProperty(object, propertyName, valueGetter) {
8046
+ const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
8047
+ Object.defineProperty(object, propertyName, {
8048
+ configurable: true,
8049
+ enumerable: true,
8050
+ get() {
8051
+ const result = valueGetter();
8052
+ define(result);
8053
+ return result;
8054
+ },
8055
+ set(value) {
8056
+ define(value);
8057
+ }
8058
+ });
8059
+ return object;
8060
+ }
8061
+
8062
+ // node_modules/.bun/default-browser@5.5.1/node_modules/default-browser/index.js
8063
+ import { promisify as promisify6 } from "util";
8064
+ import process7 from "process";
8065
+ import { execFile as execFile6 } from "child_process";
8066
+
8067
+ // node_modules/.bun/default-browser-id@5.0.1/node_modules/default-browser-id/index.js
8068
+ import { promisify as promisify3 } from "util";
8069
+ import process4 from "process";
8070
+ import { execFile as execFile3 } from "child_process";
8071
+ var execFileAsync = promisify3(execFile3);
8072
+ async function defaultBrowserId() {
8073
+ if (process4.platform !== "darwin") {
8074
+ throw new Error("macOS only");
8075
+ }
8076
+ const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
8077
+ const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
8078
+ const browserId = match?.groups.id ?? "com.apple.Safari";
8079
+ if (browserId === "com.apple.safari") {
8080
+ return "com.apple.Safari";
8081
+ }
8082
+ return browserId;
8083
+ }
8084
+
8085
+ // node_modules/.bun/run-applescript@7.1.0/node_modules/run-applescript/index.js
8086
+ import process5 from "process";
8087
+ import { promisify as promisify4 } from "util";
8088
+ import { execFile as execFile4, execFileSync } from "child_process";
8089
+ var execFileAsync2 = promisify4(execFile4);
8090
+ async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
8091
+ if (process5.platform !== "darwin") {
8092
+ throw new Error("macOS only");
8093
+ }
8094
+ const outputArguments = humanReadableOutput ? [] : ["-ss"];
8095
+ const execOptions = {};
8096
+ if (signal) {
8097
+ execOptions.signal = signal;
8098
+ }
8099
+ const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
8100
+ return stdout.trim();
8101
+ }
8102
+
8103
+ // node_modules/.bun/bundle-name@4.1.1/node_modules/bundle-name/index.js
8104
+ var bundleIdentifierPattern = /^[^\n\r"\\]+$/u;
8105
+ async function bundleName(bundleId) {
8106
+ if (typeof bundleId !== "string") {
8107
+ throw new TypeError("Expected a string bundle identifier");
8108
+ }
8109
+ if (!bundleIdentifierPattern.test(bundleId)) {
8110
+ throw new TypeError(`Invalid bundle identifier: ${JSON.stringify(bundleId)}`);
8111
+ }
8112
+ return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
8113
+ tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
8114
+ }
8115
+
8116
+ // node_modules/.bun/default-browser@5.5.1/node_modules/default-browser/windows.js
8117
+ import process6 from "process";
8118
+ import { promisify as promisify5 } from "util";
8119
+ import { execFile as execFile5 } from "child_process";
8120
+ var execFileAsync3 = promisify5(execFile5);
8121
+ var windowsBrowserProgIds = {
8122
+ MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
8123
+ MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
8124
+ MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
8125
+ AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
8126
+ ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
8127
+ ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
8128
+ ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
8129
+ ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
8130
+ BraveHTML: { name: "Brave", id: "com.brave.Browser" },
8131
+ BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
8132
+ BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
8133
+ BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
8134
+ FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
8135
+ OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
8136
+ VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
8137
+ "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
8138
+ };
8139
+ var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
8140
+
8141
+ class UnknownBrowserError extends Error {
8142
+ }
8143
+ async function defaultBrowser(_execFileAsync = execFileAsync3) {
8144
+ const regPath = `${process6.env.SYSTEMROOT ?? process6.env.windir ?? "C:\\Windows"}\\System32\\reg.exe`;
8145
+ const { stdout } = await _execFileAsync(regPath, [
8146
+ "QUERY",
8147
+ " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
8148
+ "/v",
8149
+ "ProgId"
8150
+ ]);
8151
+ const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
8152
+ if (!match) {
8153
+ throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
8154
+ }
8155
+ const { id } = match.groups;
8156
+ const dotIndex = id.lastIndexOf(".");
8157
+ const hyphenIndex = id.lastIndexOf("-");
8158
+ const baseIdByDot = dotIndex === -1 ? undefined : id.slice(0, dotIndex);
8159
+ const baseIdByHyphen = hyphenIndex === -1 ? undefined : id.slice(0, hyphenIndex);
8160
+ return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
8161
+ }
8162
+
8163
+ // node_modules/.bun/default-browser@5.5.1/node_modules/default-browser/index.js
8164
+ var execFileAsync4 = promisify6(execFile6);
8165
+ var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
8166
+ async function defaultBrowser2() {
8167
+ if (process7.platform === "darwin") {
8168
+ const id = await defaultBrowserId();
8169
+ const name = await bundleName(id);
8170
+ return { name, id };
8171
+ }
8172
+ if (process7.platform === "linux") {
8173
+ const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
8174
+ const id = stdout.trim();
8175
+ const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
8176
+ return { name, id };
8177
+ }
8178
+ if (process7.platform === "win32") {
8179
+ return defaultBrowser();
8180
+ }
8181
+ throw new Error("Only macOS, Linux, and Windows are supported");
8182
+ }
8183
+
8184
+ // node_modules/.bun/is-in-ssh@1.0.0/node_modules/is-in-ssh/index.js
8185
+ import process8 from "process";
8186
+ var isInSsh = Boolean(process8.env.SSH_CONNECTION || process8.env.SSH_CLIENT || process8.env.SSH_TTY);
8187
+ var is_in_ssh_default = isInSsh;
8188
+
8189
+ // node_modules/.bun/open@11.0.4/node_modules/open/index.js
8190
+ var fallbackAttemptSymbol = Symbol("fallbackAttempt");
8191
+ var __dirname2 = import.meta.url ? path2.dirname(fileURLToPath(import.meta.url)) : "";
8192
+ var localXdgOpenPath = path2.join(__dirname2, "xdg-open");
8193
+ var { platform, arch } = process9;
8194
+ var tryEachApp = async (apps, opener) => {
8195
+ if (apps.length === 0) {
8196
+ return;
8197
+ }
8198
+ const errors = [];
8199
+ for (const app of apps) {
8200
+ try {
8201
+ return await opener(app);
8202
+ } catch (error) {
8203
+ errors.push(error);
8204
+ }
8205
+ }
8206
+ throw new AggregateError(errors, "Failed to open in all supported apps");
8207
+ };
8208
+ var baseOpen = async (options) => {
8209
+ options = {
8210
+ wait: false,
8211
+ background: false,
8212
+ newInstance: false,
8213
+ allowNonzeroExitCode: false,
8214
+ ...options
8215
+ };
8216
+ const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
8217
+ delete options[fallbackAttemptSymbol];
8218
+ if (Array.isArray(options.app)) {
8219
+ return tryEachApp(options.app, (singleApp) => baseOpen({
8220
+ ...options,
8221
+ app: singleApp,
8222
+ [fallbackAttemptSymbol]: true
8223
+ }));
8224
+ }
8225
+ let { name: app, arguments: appArguments = [] } = options.app ?? {};
8226
+ appArguments = [...appArguments];
8227
+ if (Array.isArray(app)) {
8228
+ return tryEachApp(app, (appName) => baseOpen({
8229
+ ...options,
8230
+ app: {
8231
+ name: appName,
8232
+ arguments: appArguments
8233
+ },
8234
+ [fallbackAttemptSymbol]: true
8235
+ }));
8236
+ }
8237
+ if (app === "browser" || app === "browserPrivate") {
8238
+ const ids = {
8239
+ "com.google.chrome": "chrome",
8240
+ "google-chrome.desktop": "chrome",
8241
+ "com.brave.browser": "brave",
8242
+ "org.mozilla.firefox": "firefox",
8243
+ "firefox.desktop": "firefox",
8244
+ "com.microsoft.msedge": "edge",
8245
+ "com.microsoft.edge": "edge",
8246
+ "com.microsoft.edgemac": "edge",
8247
+ "microsoft-edge.desktop": "edge",
8248
+ "com.apple.safari": "safari"
8249
+ };
8250
+ const flags = {
8251
+ chrome: "--incognito",
8252
+ brave: "--incognito",
8253
+ firefox: "--private-window",
8254
+ edge: "--inPrivate"
8255
+ };
8256
+ let browser;
8257
+ if (is_wsl_default) {
8258
+ const progId = await wslDefaultBrowser();
8259
+ const browserInfo = _windowsBrowserProgIdMap.get(progId);
8260
+ browser = browserInfo ?? {};
8261
+ } else {
8262
+ browser = await defaultBrowser2();
8263
+ }
8264
+ const browserId = browser.id?.toLowerCase();
8265
+ if (Object.hasOwn(ids, browserId)) {
8266
+ const browserName = ids[browserId];
8267
+ if (app === "browserPrivate") {
8268
+ if (browserName === "safari") {
8269
+ throw new Error("Safari doesn't support opening in private mode via command line");
8270
+ }
8271
+ appArguments.push(flags[browserName]);
8272
+ }
8273
+ return baseOpen({
8274
+ ...options,
8275
+ app: {
8276
+ name: apps[browserName],
8277
+ arguments: appArguments
8278
+ }
8279
+ });
8280
+ }
8281
+ throw new Error(`${browser.name} is not supported as a default browser`);
8282
+ }
8283
+ let command;
8284
+ const cliArguments = [];
8285
+ const childProcessOptions = {};
8286
+ let shouldUseWindowsInWsl = false;
8287
+ if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
8288
+ shouldUseWindowsInWsl = await canAccessPowerShell();
8289
+ }
8290
+ if (platform === "darwin") {
8291
+ command = "open";
8292
+ if (options.wait) {
8293
+ cliArguments.push("--wait-apps");
8294
+ }
8295
+ if (options.background) {
8296
+ cliArguments.push("--background");
8297
+ }
8298
+ if (options.newInstance) {
8299
+ cliArguments.push("--new");
8300
+ }
8301
+ if (app) {
8302
+ cliArguments.push("-a", app);
8303
+ }
8304
+ } else if (platform === "win32" || shouldUseWindowsInWsl) {
8305
+ command = await powerShellPath2();
8306
+ cliArguments.push(...executePowerShell.argumentsPrefix);
8307
+ if (!is_wsl_default) {
8308
+ childProcessOptions.windowsVerbatimArguments = true;
8309
+ }
8310
+ if (is_wsl_default && options.target) {
8311
+ options.target = await convertWslPathToWindows(options.target);
8312
+ }
8313
+ const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
8314
+ if (options.wait) {
8315
+ encodedArguments.push("-Wait");
8316
+ }
8317
+ if (app) {
8318
+ encodedArguments.push(executePowerShell.escapeArgument(app));
8319
+ if (options.target) {
8320
+ appArguments.push(options.target);
8321
+ }
8322
+ } else if (options.target) {
8323
+ encodedArguments.push(executePowerShell.escapeArgument(options.target));
8324
+ }
8325
+ if (appArguments.length > 0) {
8326
+ appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
8327
+ encodedArguments.push("-ArgumentList", appArguments.join(","));
8328
+ }
8329
+ options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
8330
+ if (!options.wait) {
8331
+ childProcessOptions.stdio = "ignore";
8332
+ }
8333
+ if (is_wsl_default) {
8334
+ childProcessOptions.cwd = path2.dirname(command);
8335
+ }
8336
+ } else {
8337
+ if (app) {
8338
+ command = app;
8339
+ } else {
8340
+ const isBundled = !__dirname2 || __dirname2 === "/";
8341
+ let exeLocalXdgOpen = false;
8342
+ try {
8343
+ await fs5.access(localXdgOpenPath, fsConstants2.X_OK);
8344
+ exeLocalXdgOpen = true;
8345
+ } catch {}
8346
+ const useSystemXdgOpen = process9.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
8347
+ command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
8348
+ }
8349
+ if (appArguments.length > 0) {
8350
+ cliArguments.push(...appArguments);
8351
+ }
8352
+ if (!options.wait) {
8353
+ childProcessOptions.stdio = "ignore";
8354
+ childProcessOptions.detached = true;
8355
+ }
8356
+ }
8357
+ if (platform === "darwin" && appArguments.length > 0) {
8358
+ cliArguments.push("--args", ...appArguments);
8359
+ }
8360
+ if (options.target) {
8361
+ cliArguments.push(options.target);
8362
+ }
8363
+ const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
8364
+ if (options.wait) {
8365
+ return new Promise((resolve, reject) => {
8366
+ subprocess.once("error", reject);
8367
+ subprocess.once("close", (exitCode) => {
8368
+ if (!options.allowNonzeroExitCode && exitCode !== 0) {
8369
+ reject(new Error(`Exited with code ${exitCode}`));
8370
+ return;
8371
+ }
8372
+ resolve(subprocess);
8373
+ });
8374
+ });
8375
+ }
8376
+ if (isFallbackAttempt || platform === "win32" || shouldUseWindowsInWsl) {
8377
+ return new Promise((resolve, reject) => {
8378
+ subprocess.once("error", reject);
8379
+ subprocess.once("spawn", () => {
8380
+ subprocess.once("close", (exitCode) => {
8381
+ subprocess.off("error", reject);
8382
+ if (isFallbackAttempt && exitCode !== 0) {
8383
+ reject(new Error(`Exited with code ${exitCode}`));
8384
+ return;
8385
+ }
8386
+ subprocess.unref();
8387
+ resolve(subprocess);
8388
+ });
8389
+ });
8390
+ });
8391
+ }
8392
+ subprocess.unref();
8393
+ return new Promise((resolve, reject) => {
8394
+ subprocess.once("error", reject);
8395
+ subprocess.once("spawn", () => {
8396
+ subprocess.off("error", reject);
8397
+ resolve(subprocess);
8398
+ });
8399
+ });
8400
+ };
8401
+ var open2 = (target, options) => {
8402
+ if (typeof target !== "string") {
8403
+ throw new TypeError("Expected a `target`");
8404
+ }
8405
+ return baseOpen({
8406
+ ...options,
8407
+ target
8408
+ });
8409
+ };
8410
+ function detectArchBinary(binary) {
8411
+ if (typeof binary === "string" || Array.isArray(binary)) {
8412
+ return binary;
8413
+ }
8414
+ const { [arch]: archBinary } = binary;
8415
+ if (!archBinary) {
8416
+ throw new Error(`${arch} is not supported`);
8417
+ }
8418
+ return archBinary;
8419
+ }
8420
+ function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
8421
+ if (wsl && is_wsl_default) {
8422
+ return detectArchBinary(wsl);
8423
+ }
8424
+ if (!platformBinary) {
8425
+ throw new Error(`${platform} is not supported`);
8426
+ }
8427
+ return detectArchBinary(platformBinary);
8428
+ }
8429
+ var apps = {
8430
+ browser: "browser",
8431
+ browserPrivate: "browserPrivate"
8432
+ };
8433
+ defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
8434
+ darwin: "google chrome",
8435
+ win32: "chrome",
8436
+ linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
8437
+ }, {
8438
+ wsl: {
8439
+ ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
8440
+ x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
8441
+ }
8442
+ }));
8443
+ defineLazyProperty(apps, "brave", () => detectPlatformBinary({
8444
+ darwin: "brave browser",
8445
+ win32: "brave",
8446
+ linux: ["brave-browser", "brave"]
8447
+ }, {
8448
+ wsl: {
8449
+ ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
8450
+ x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
8451
+ }
8452
+ }));
8453
+ defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
8454
+ darwin: "firefox",
8455
+ win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
8456
+ linux: "firefox"
8457
+ }, {
8458
+ wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
8459
+ }));
8460
+ defineLazyProperty(apps, "edge", () => detectPlatformBinary({
8461
+ darwin: "microsoft edge",
8462
+ win32: "msedge",
8463
+ linux: ["microsoft-edge", "microsoft-edge-dev"]
8464
+ }, {
8465
+ wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
8466
+ }));
8467
+ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
8468
+ darwin: "Safari"
8469
+ }));
8470
+ var open_default = open2;
8471
+
8472
+ // packages/agent/src/system/openBrowser.ts
8473
+ var openBrowser = (url) => open_default(url).catch(() => {
8474
+ return;
8475
+ });
8476
+
8477
+ // packages/agent/src/permissions/sanitizeText.ts
8478
+ var isControlCode = (code) => code < 32 || code >= 127 && code <= 159;
8479
+ var sanitizeText = (text) => [...String(text ?? "")].map((char) => isControlCode(char.charCodeAt(0)) ? " " : char).join("");
8480
+
8481
+ // packages/agent/src/permissions/elicitationForm.ts
8482
+ var SKIP_LABEL = "Skip";
8483
+ var ACCEPT_LABEL = "Accept";
8484
+ var DECLINE_LABEL = "Decline";
8485
+ var YES_LABEL = "Yes";
8486
+ var NO_LABEL = "No";
8487
+ var isSchema = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
8488
+ var readList = (value) => Array.isArray(value) ? value : [];
8489
+ var toChoice = (entry) => {
8490
+ if (typeof entry === "string")
8491
+ return { value: entry, label: sanitizeText(entry) };
8492
+ if (!isSchema(entry) || typeof entry.const !== "string")
8493
+ return;
8494
+ const label = typeof entry.title === "string" ? entry.title : entry.const;
8495
+ return { value: entry.const, label: sanitizeText(label) };
8496
+ };
8497
+ var readChoices = (field) => {
8498
+ const source = isSchema(field.items) ? field.items : field;
8499
+ const entries = [...readList(source.oneOf), ...readList(source.anyOf), ...readList(source.enum)];
8500
+ return entries.flatMap((entry) => toChoice(entry) ?? []);
8501
+ };
8502
+ var readKind = (field, choices) => {
8503
+ if (field.type === "array")
8504
+ return "multi";
8505
+ if (choices.length > 0)
8506
+ return "choice";
8507
+ if (field.type === "boolean")
8508
+ return "boolean";
8509
+ return field.type === "number" || field.type === "integer" ? "number" : "text";
8510
+ };
8511
+ var readOptions = (kind, choices) => {
8512
+ const labelled = (labels) => labels.map((label) => ({ label, description: "" }));
8513
+ if (kind === "boolean")
8514
+ return labelled([YES_LABEL, NO_LABEL]);
8515
+ return labelled(choices.length > 0 ? choices.map(({ label }) => label) : [SKIP_LABEL]);
8516
+ };
8517
+ var buildQuestionText = (key, field, message) => {
8518
+ const title = sanitizeText(typeof field.title === "string" ? field.title : key);
8519
+ const description = typeof field.description === "string" ? ` (${sanitizeText(field.description)})` : "";
8520
+ return `${message}${title}${description}`;
8521
+ };
8522
+ var buildConfirmForm = (header, message) => ({
8523
+ fields: [],
8524
+ questions: [
8525
+ {
8526
+ header,
8527
+ question: message,
8528
+ options: [
8529
+ { label: ACCEPT_LABEL, description: "" },
8530
+ { label: DECLINE_LABEL, description: "" }
8531
+ ]
8532
+ }
8533
+ ]
8534
+ });
8535
+ function buildElicitationForm(serverName, message, requestedSchema) {
8536
+ const header = sanitizeText(serverName);
8537
+ const properties = isSchema(requestedSchema?.properties) ? requestedSchema.properties : {};
8538
+ const entries = Object.entries(properties).filter((entry) => isSchema(entry[1]));
8539
+ if (entries.length === 0)
8540
+ return buildConfirmForm(header, sanitizeText(message));
8541
+ const fields = [];
8542
+ const questions = [];
8543
+ for (const [key, field] of entries) {
8544
+ const choices = readChoices(field);
8545
+ const kind = readKind(field, choices);
8546
+ const intro = fields.length === 0 ? `${sanitizeText(message)} \u2014 ` : "";
8547
+ const question = buildQuestionText(key, field, intro);
8548
+ fields.push({ key, question, kind, choices });
8549
+ questions.push({
8550
+ header,
8551
+ question,
8552
+ multiSelect: kind === "multi",
8553
+ options: readOptions(kind, choices)
8554
+ });
8555
+ }
8556
+ return { fields, questions };
8557
+ }
8558
+ var readChoiceValue = (choices, label) => choices.find((choice) => choice.label === label)?.value ?? label;
8559
+ var readFieldValue = ({ kind, choices }, answer) => {
8560
+ if (kind === "boolean")
8561
+ return answer === YES_LABEL;
8562
+ if (kind === "number")
8563
+ return Number.isFinite(Number(answer)) ? Number(answer) : undefined;
8564
+ if (kind === "choice")
8565
+ return readChoiceValue(choices, answer);
8566
+ if (kind === "multi")
8567
+ return answer.split(", ").map((label) => readChoiceValue(choices, label));
8568
+ return answer;
8569
+ };
8570
+ function buildElicitationContent(form, answers) {
8571
+ const content = {};
8572
+ for (const field of form.fields) {
8573
+ const answer = answers[field.question]?.trim();
8574
+ if (!answer || answer === SKIP_LABEL)
8575
+ continue;
8576
+ const value = readFieldValue(field, answer);
8577
+ if (value !== undefined)
8578
+ content[field.key] = value;
8579
+ }
8580
+ return content;
8581
+ }
8582
+ var isConfirmAccepted = (form, answers) => form.fields.length > 0 || Object.values(answers).includes(ACCEPT_LABEL);
8583
+
8584
+ // packages/agent/src/permissions/elicitationGate.ts
8585
+ var ELICITATION_PREFIX = "elicitation:";
8586
+ var OPEN_BROWSER_LABEL = "Open in browser";
8587
+ var DECLINED = { action: "decline" };
8588
+ var isWebUrl = (url) => {
8589
+ try {
8590
+ return url !== undefined && /^https?:$/.test(new URL(url).protocol);
8591
+ } catch {
8592
+ return false;
8593
+ }
8594
+ };
8595
+ var buildUrlQuestion = ({ serverName, message, url }) => ({
8596
+ header: sanitizeText(serverName),
8597
+ question: `${sanitizeText(message)} ${sanitizeText(url)}`,
8598
+ options: [
8599
+ { label: OPEN_BROWSER_LABEL, description: "" },
8600
+ { label: "Decline", description: "" }
8601
+ ]
8602
+ });
8603
+
8604
+ class ElicitationGate {
8605
+ agentSessionId;
8606
+ openUrl;
8607
+ pending = new Map;
8608
+ emit = () => {};
8609
+ constructor(agentSessionId, openUrl = openBrowser) {
8610
+ this.agentSessionId = agentSessionId;
8611
+ this.openUrl = openUrl;
8612
+ }
8613
+ listen(emit) {
8614
+ this.emit = emit;
8615
+ }
8616
+ handle = async (request, { signal, requestId }) => {
8617
+ if (request.mode === "url") {
8618
+ if (!isWebUrl(request.url))
8619
+ return DECLINED;
8620
+ return this.open(requestId, signal, [buildUrlQuestion(request)], (answers) => this.acceptUrl(request.url, answers));
8621
+ }
8622
+ const form = buildElicitationForm(request.serverName, request.message, request.requestedSchema);
8623
+ return this.open(requestId, signal, form.questions, (answers) => this.acceptForm(form, answers));
8624
+ };
8625
+ answer(toolUseId, answers) {
8626
+ const pending = this.pending.get(toolUseId);
8627
+ if (!pending)
8628
+ return false;
8629
+ this.pending.delete(toolUseId);
8630
+ const answered = Object.keys(answers).length > 0;
8631
+ pending.settle(answered ? pending.accept(answers) : DECLINED);
8632
+ this.emit({ type: "agent.question.resolved", toolUseId, answered });
8633
+ return true;
8634
+ }
8635
+ rejectAll() {
8636
+ for (const id of [...this.pending.keys()])
8637
+ this.answer(id, {});
8638
+ }
8639
+ acceptUrl(url, answers) {
8640
+ if (!Object.values(answers).includes(OPEN_BROWSER_LABEL))
8641
+ return DECLINED;
8642
+ this.openUrl(url);
8643
+ return { action: "accept" };
8644
+ }
8645
+ acceptForm(form, answers) {
8646
+ if (!isConfirmAccepted(form, answers))
8647
+ return DECLINED;
8648
+ return { action: "accept", content: buildElicitationContent(form, answers) };
8649
+ }
8650
+ open(requestId, signal, questions, accept) {
8651
+ const toolUseId = `${ELICITATION_PREFIX}${requestId}`;
8652
+ return new Promise((settle) => {
8653
+ this.pending.set(toolUseId, { settle, accept });
8654
+ signal.addEventListener("abort", () => this.answer(toolUseId, {}), { once: true });
8655
+ this.emit({
8656
+ type: "agent.question.required",
8657
+ agentSessionId: this.agentSessionId,
8658
+ toolUseId,
8659
+ questions
8660
+ });
8661
+ });
8662
+ }
8663
+ }
7687
8664
 
7688
8665
  // packages/agent/src/permissions/permissionResults.ts
7689
8666
  var allowTool = (input) => ({
@@ -7800,7 +8777,87 @@ var ADHD_SYSTEM_PROMPT = `For the rest of this session, shape every response for
7800
8777
 
7801
8778
  Break these rules only when: the reader asks you to "explain" or "walk through" (go as long as the topic needs, still no preamble/closer); a destructive action is ahead (confirm first; safety beats brevity); you are in a debug spiral (name the assumption that might be wrong, ask one diagnostic question); or the request is genuinely ambiguous (ask one short clarifying question); or the harness's own system prompt requires something these rules ban (the harness wins; keep the shape).`;
7802
8779
 
7803
- // packages/agent/src/profile/agentProfile.ts
8780
+ // packages/agent/src/profile/codeReviewPrompt.ts
8781
+ var CODE_REVIEW_DESCRIPTION = "Reviews code changes since a commit, branch, or tag, or the uncommitted work, against the repo's coding standards and the originating spec. Use it to review a branch, a PR, or work in progress.";
8782
+ var CODE_REVIEW_PROMPT = `You are CodeReview. You review a diff along two separate axes and report them side by side. You are read-only: never edit files.
8783
+
8784
+ - Standards: does the code follow this repo's documented coding standards?
8785
+ - Spec: does the code match what the originating issue or spec asked for?
8786
+
8787
+ A change can pass one axis and fail the other. Never merge or rerank the two.
8788
+
8789
+ ## 1. Pin the fixed point
8790
+
8791
+ Use the commit, branch, tag, or ref you were given. If none was given, review the uncommitted work with \`git diff HEAD\`.
8792
+ Verify the ref with \`git rev-parse <ref>\` and capture the diff once with \`git diff <ref>...HEAD\`, plus \`git log <ref>..HEAD --oneline\`. If the ref is bad or the diff is empty, say so and stop.
8793
+
8794
+ ## 2. Find the spec
8795
+
8796
+ Look in this order:
8797
+ 1. Issue references in commit messages (#123, Closes #45).
8798
+ 2. A path you were given.
8799
+ 3. A spec or issue file under docs/, specs/, or .scratch/ matching the branch name or feature.
8800
+ If there is none, skip the Spec axis and say "no spec available".
8801
+
8802
+ ## 3. Find the standards
8803
+
8804
+ Collect every file that documents how code should be written: CLAUDE.md, CODING_STANDARDS.md, CONTRIBUTING.md, and similar. A documented repo standard always wins over the smell baseline.
8805
+
8806
+ Smell baseline, always a judgement call, never a hard violation (name it "possible <smell>"). Skip anything tooling already enforces.
8807
+ - Mysterious Name: a name that does not reveal what it does or holds.
8808
+ - Duplicated Code: the same logic shape in more than one hunk or file.
8809
+ - Feature Envy: a method that uses another object's data more than its own.
8810
+ - Data Clumps: the same few fields or params always travel together.
8811
+ - Primitive Obsession: a primitive standing in for a domain concept.
8812
+ - Repeated Switches: the same switch or if-cascade on one type recurs.
8813
+ - Shotgun Surgery: one logical change forces scattered edits across many files.
8814
+ - Divergent Change: one file is edited for several unrelated reasons.
8815
+ - Speculative Generality: abstraction or hooks for needs the spec does not have.
8816
+ - Message Chains: long a.b().c().d() navigation callers should not depend on.
8817
+ - Middle Man: a class or function that mostly delegates onward.
8818
+ - Refused Bequest: a subclass that ignores or overrides most of what it inherits.
8819
+
8820
+ ## 4. Report
8821
+
8822
+ Under \`## Standards\`: every place the diff breaks a documented standard (cite the file and rule), then any baseline smell (name it, quote the hunk). Separate hard violations from judgement calls.
8823
+ Under \`## Spec\`: requirements that are missing or partial, behaviour that was not asked for, and requirements that look implemented but wrong. Quote the spec line for each.
8824
+
8825
+ Every finding names its file path and line range as <path>:<from>:<to>. Keep each axis under 400 words.
8826
+ End with one line: findings per axis and the worst issue within each axis. Do not pick a winner across axes.`;
8827
+
8828
+ // packages/agent/src/profile/scoutPrompt.ts
8829
+ var SCOUT_DESCRIPTION = "Scans the codebase for specific information and returns concise, useful findings with file paths and line ranges. Use it before reading or searching many files yourself.";
8830
+ var SCOUT_PROMPT = `You are Scout. You scan the codebase to answer one exploration request. You are read-only: never edit, write, or run state-changing commands.
8831
+
8832
+ 1. Use Glob to find files, Grep to find content, Read to confirm. Read only the lines you need.
8833
+ 2. Answer the request directly. Report only what the request needs.
8834
+ 3. Every finding names its file path and line range as <path>:<from>:<to>, for example src/auth/login.ts:42:58. A single line is <path>:<line>:<line>.
8835
+ 4. Keep it concise: one line per finding, the most relevant first, at most 10 findings.
8836
+ 5. If nothing matches, say so and list what you searched.`;
8837
+
8838
+ // packages/agent/src/profile/subagents.ts
8839
+ var AGENT_SUBAGENTS = {
8840
+ Scout: {
8841
+ description: SCOUT_DESCRIPTION,
8842
+ prompt: SCOUT_PROMPT,
8843
+ tools: ["Glob", "Grep", "Read"],
8844
+ model: "haiku",
8845
+ effort: "medium"
8846
+ },
8847
+ CodeReview: {
8848
+ description: CODE_REVIEW_DESCRIPTION,
8849
+ prompt: CODE_REVIEW_PROMPT,
8850
+ tools: ["Bash", "Glob", "Grep", "Read"],
8851
+ model: "sonnet",
8852
+ effort: "medium"
8853
+ }
8854
+ };
8855
+ var SUBAGENT_GUIDANCE = `Prefer subagents over doing the work yourself. Use *Agent* with:
8856
+ - Scout: to scan the codebase for specific information. It returns file paths and line ranges (<path>:<from>:<to>). Use it before you search or read many files.
8857
+ - CodeReview: to review code changes against the repo's standards and spec.
8858
+ Run independent subagents in parallel.`;
8859
+
8860
+ // packages/agent/src/profile/agentTools.ts
7804
8861
  var AGENT_TOOLS = [
7805
8862
  "Bash",
7806
8863
  "Read",
@@ -7821,9 +8878,48 @@ var AGENT_TOOLS = [
7821
8878
  "Edit",
7822
8879
  "NotebookEdit"
7823
8880
  ];
8881
+ var AGENT_DISALLOWED_TOOLS = [
8882
+ "Agent(Explore)",
8883
+ "Agent(Plan)",
8884
+ "Agent(statusline-setup)"
8885
+ ];
8886
+
8887
+ // packages/agent/src/profile/toolGuidance.ts
8888
+ var TOOL_USAGE = {
8889
+ Bash: "run shell commands; never to read, search, or edit files",
8890
+ Read: "read files",
8891
+ Grep: "search file contents",
8892
+ Glob: "scan files by name pattern",
8893
+ WebSearch: "search the web",
8894
+ WebFetch: "fetch a URL",
8895
+ TaskStop: "stop a running background task",
8896
+ Agent: "delegate work to a subagent",
8897
+ TaskCreate: "create a task",
8898
+ TaskGet: "read one task",
8899
+ TaskList: "list tasks",
8900
+ TaskOutput: "read a background task's output",
8901
+ TaskUpdate: "update a task",
8902
+ TodoWrite: "track the steps of multi-step work",
8903
+ AskUserQuestion: "ask the user",
8904
+ Write: "create new files with content",
8905
+ Edit: "update files",
8906
+ NotebookEdit: "update notebook cells"
8907
+ };
8908
+ var TOOL_GUIDANCE = `Always use the dedicated tool, never a workaround:
8909
+ ${AGENT_TOOLS.map((tool) => `- Use *${tool}* to ${TOOL_USAGE[tool]}`).join(`
8910
+ `)}`;
8911
+
8912
+ // packages/agent/src/profile/agentSystemPrompt.ts
8913
+ var AGENT_SYSTEM_PROMPT = [ADHD_SYSTEM_PROMPT, TOOL_GUIDANCE, SUBAGENT_GUIDANCE].join(`
8914
+
8915
+ `);
8916
+
8917
+ // packages/agent/src/profile/agentProfile.ts
7824
8918
  var AGENT_PROFILE_OPTIONS = {
7825
8919
  tools: AGENT_TOOLS,
7826
- systemPrompt: ADHD_SYSTEM_PROMPT,
8920
+ disallowedTools: AGENT_DISALLOWED_TOOLS,
8921
+ systemPrompt: AGENT_SYSTEM_PROMPT,
8922
+ agents: AGENT_SUBAGENTS,
7827
8923
  enableFileCheckpointing: true,
7828
8924
  extraArgs: { "replay-user-messages": null },
7829
8925
  permissionMode: DEFAULT_PERMISSION_MODE,
@@ -7855,18 +8951,12 @@ var AGENT_PROFILE_OPTIONS = {
7855
8951
  includeHookEvents: true
7856
8952
  };
7857
8953
 
7858
- // packages/agent/src/runtime/buildUserMessage.ts
7859
- var isSlashCommand = (content) => readPromptText(content).trimStart().startsWith("/");
7860
- var buildUserMessage = (content, priority) => ({
7861
- type: "user",
7862
- message: { role: "user", content },
7863
- parent_tool_use_id: null,
7864
- priority,
7865
- client_composed: isSlashCommand(content) ? undefined : true
7866
- });
7867
-
7868
- // packages/agent/src/session/pickNextModel.ts
7869
- var pickNextModel = (models, current) => models[(models.findIndex((model) => model.value === current) + 1) % models.length]?.value;
8954
+ // packages/agent/src/session/readBackgroundTaskCount.ts
8955
+ function readBackgroundTaskCount(message, current) {
8956
+ if (message.type !== "system" || message.subtype !== "background_tasks_changed")
8957
+ return current;
8958
+ return message.tasks.length;
8959
+ }
7870
8960
 
7871
8961
  // packages/agent/src/session/agentSession.ts
7872
8962
  function requireRewind(result) {
@@ -7879,18 +8969,22 @@ class AgentSession {
7879
8969
  baseOptions;
7880
8970
  input = pushable({ objectMode: true });
7881
8971
  gate;
8972
+ elicitations;
7882
8973
  query;
7883
8974
  pendingTurns = 0;
8975
+ backgroundTaskCount = 0;
7884
8976
  pumping = false;
7885
8977
  constructor(agentSessionId, baseOptions, runtime) {
7886
8978
  this.baseOptions = baseOptions;
7887
8979
  this.gate = new PermissionGate(agentSessionId);
8980
+ this.elicitations = new ElicitationGate(agentSessionId);
7888
8981
  this.query = runtime.open({
7889
8982
  prompt: this.input,
7890
8983
  options: {
7891
8984
  ...baseOptions,
7892
8985
  ...AGENT_PROFILE_OPTIONS,
7893
- canUseTool: this.gate.canUseTool
8986
+ canUseTool: this.gate.canUseTool,
8987
+ onElicitation: this.elicitations.handle
7894
8988
  }
7895
8989
  });
7896
8990
  }
@@ -7907,35 +9001,33 @@ class AgentSession {
7907
9001
  return;
7908
9002
  this.pumping = true;
7909
9003
  const sink = pushable({ objectMode: true });
7910
- this.gate.listen((event) => sink.push(event));
9004
+ this.listenGates((event) => sink.push(event));
7911
9005
  this.pumpMessages(sink);
7912
9006
  try {
7913
9007
  yield* sink;
7914
9008
  } finally {
7915
9009
  this.pumping = false;
7916
- this.gate.listen(() => {});
9010
+ this.listenGates(() => {});
7917
9011
  }
7918
9012
  }
7919
9013
  answerApproval(toolUseId, decision) {
7920
9014
  this.gate.answerApproval(toolUseId, decision);
7921
9015
  }
7922
9016
  answerQuestion(toolUseId, answers) {
7923
- this.gate.answerQuestion(toolUseId, answers);
9017
+ if (!this.elicitations.answer(toolUseId, answers))
9018
+ this.gate.answerQuestion(toolUseId, answers);
7924
9019
  }
7925
9020
  async cancel() {
7926
- this.gate.rejectAll();
9021
+ this.rejectAllPrompts();
7927
9022
  await this.query.interrupt();
7928
9023
  }
9024
+ stopTask(taskId) {
9025
+ return this.query.stopTask(taskId);
9026
+ }
7929
9027
  async setModel(model) {
7930
9028
  await this.query.setModel(model);
7931
9029
  this.baseOptions = { ...this.baseOptions, model };
7932
9030
  }
7933
- async cycleModel() {
7934
- const next = pickNextModel(await this.fetchModels(), this.baseOptions.model);
7935
- if (next)
7936
- await this.setModel(next);
7937
- return next;
7938
- }
7939
9031
  setPermissionMode(mode) {
7940
9032
  return this.query.setPermissionMode(mode);
7941
9033
  }
@@ -7945,6 +9037,27 @@ class AgentSession {
7945
9037
  fetchMcpStatus() {
7946
9038
  return this.query.mcpServerStatus();
7947
9039
  }
9040
+ async startMcpLogin(serverName) {
9041
+ if (typeof this.query.mcpAuthenticate !== "function") {
9042
+ throw new Error("This Claude Agent SDK version does not support MCP login");
9043
+ }
9044
+ const { authUrl } = await this.query.mcpAuthenticate(serverName);
9045
+ if (!authUrl)
9046
+ throw new Error(`MCP server ${serverName} did not offer a login`);
9047
+ if (!/^https?:$/.test(new URL(authUrl).protocol)) {
9048
+ throw new Error(`MCP server ${serverName} offered an unsafe login link`);
9049
+ }
9050
+ return authUrl;
9051
+ }
9052
+ async submitMcpCallback(serverName, callbackUrl) {
9053
+ if (!/^https?:$/.test(new URL(callbackUrl).protocol)) {
9054
+ throw new Error("The callback must be an http(s) link");
9055
+ }
9056
+ await this.query.mcpSubmitOAuthCallbackUrl(serverName, callbackUrl);
9057
+ }
9058
+ awaitMcpLogin(serverName, wait) {
9059
+ return waitForMcpLogin(() => this.fetchMcpStatus(), serverName, wait);
9060
+ }
7948
9061
  fetchModels() {
7949
9062
  return this.query.supportedModels();
7950
9063
  }
@@ -7962,10 +9075,18 @@ class AgentSession {
7962
9075
  });
7963
9076
  }
7964
9077
  close() {
7965
- this.gate.rejectAll();
9078
+ this.rejectAllPrompts();
7966
9079
  this.input.end();
7967
9080
  this.query.close();
7968
9081
  }
9082
+ listenGates(emit) {
9083
+ this.gate.listen(emit);
9084
+ this.elicitations.listen(emit);
9085
+ }
9086
+ rejectAllPrompts() {
9087
+ this.gate.rejectAll();
9088
+ this.elicitations.rejectAll();
9089
+ }
7969
9090
  async pumpMessages(sink) {
7970
9091
  try {
7971
9092
  while (true) {
@@ -7973,10 +9094,11 @@ class AgentSession {
7973
9094
  if (done)
7974
9095
  break;
7975
9096
  sink.push({ type: "agent.message.received", message: value });
9097
+ this.backgroundTaskCount = readBackgroundTaskCount(value, this.backgroundTaskCount);
7976
9098
  if (value.type !== "result")
7977
9099
  continue;
7978
9100
  this.pendingTurns = Math.max(this.pendingTurns - 1, 0);
7979
- if (this.pendingTurns === 0)
9101
+ if (this.pendingTurns === 0 && this.backgroundTaskCount === 0)
7980
9102
  break;
7981
9103
  }
7982
9104
  sink.end();
@@ -8038,13 +9160,13 @@ class AgentSessionManager {
8038
9160
  import { homedir } from "os";
8039
9161
  import { join as join2 } from "path";
8040
9162
  var OPTIONS_PATH = join2(homedir(), ".claudin", "options.json");
8041
- async function readOptions(path) {
9163
+ async function readOptions2(path) {
8042
9164
  const stored = await Bun.file(path).json().catch(() => ({}));
8043
9165
  const parsed = optionsFileSchema.safeParse(stored);
8044
9166
  return parsed.success ? parsed.data : {};
8045
9167
  }
8046
9168
  async function saveBackground(path, background) {
8047
- await Bun.write(path, JSON.stringify({ ...await readOptions(path), background }, null, 2));
9169
+ await Bun.write(path, JSON.stringify({ ...await readOptions2(path), background }, null, 2));
8048
9170
  }
8049
9171
 
8050
9172
  // packages/daemon/src/workspace/resolvePath.ts
@@ -8254,6 +9376,9 @@ var agentHandlers = {
8254
9376
  await agents.requireSession(request.agentSessionId).cancel();
8255
9377
  yield { type: "agent.prompt.cancelled", agentSessionId: request.agentSessionId };
8256
9378
  },
9379
+ async* "agent.task.stop.requested"({ agents }, request) {
9380
+ await agents.requireSession(request.agentSessionId).stopTask(request.taskId);
9381
+ },
8257
9382
  async* "agent.tool.approval.answered"({ agents }, request) {
8258
9383
  agents.requireSession(request.agentSessionId).answerApproval(request.toolUseId, request.decision);
8259
9384
  },
@@ -8264,11 +9389,6 @@ var agentHandlers = {
8264
9389
  await agents.requireSession(request.agentSessionId).setModel(request.model);
8265
9390
  yield { type: "agent.model.changed", model: request.model };
8266
9391
  },
8267
- async* "agent.model.cycle.requested"({ agents }, request) {
8268
- const model = await agents.requireSession(request.agentSessionId).cycleModel();
8269
- if (model)
8270
- yield { type: "agent.model.changed", model };
8271
- },
8272
9392
  async* "agent.effort.set.requested"({ agents }, request) {
8273
9393
  await agents.requireSession(request.agentSessionId).setEffort(request.effort);
8274
9394
  yield { type: "agent.effort.changed", effort: request.effort };
@@ -8289,6 +9409,22 @@ var agentHandlers = {
8289
9409
  const servers = await agents.requireSession(request.agentSessionId).fetchMcpStatus();
8290
9410
  yield { type: "agent.mcp.status.received", servers };
8291
9411
  },
9412
+ async* "agent.mcp.login.requested"({ agents }, request) {
9413
+ const { serverName } = request;
9414
+ const session = agents.requireSession(request.agentSessionId);
9415
+ const authUrl = await session.startMcpLogin(serverName);
9416
+ yield { type: "agent.mcp.login.started", serverName, authUrl };
9417
+ await openBrowser(authUrl);
9418
+ const servers = await session.awaitMcpLogin(serverName);
9419
+ yield { type: "agent.mcp.status.received", servers };
9420
+ },
9421
+ async* "agent.mcp.callback.submitted"({ agents }, request) {
9422
+ const { serverName, callbackUrl } = request;
9423
+ const session = agents.requireSession(request.agentSessionId);
9424
+ await session.submitMcpCallback(serverName, callbackUrl);
9425
+ const servers = await session.awaitMcpLogin(serverName, { intervalMs: 500, timeoutMs: 1e4 });
9426
+ yield { type: "agent.mcp.status.received", servers };
9427
+ },
8292
9428
  async* "agent.usage.requested"({ agents }, request) {
8293
9429
  const { session } = await agents.requireSession(request.agentSessionId).fetchUsage();
8294
9430
  yield { type: "agent.usage.received", usage: session };
@@ -8319,7 +9455,7 @@ var agentHandlers = {
8319
9455
  // packages/daemon/src/handlers/optionsHandlers.ts
8320
9456
  var optionsHandlers = {
8321
9457
  async* "options.load.requested"({ optionsPath }) {
8322
- const { background } = await readOptions(optionsPath);
9458
+ const { background } = await readOptions2(optionsPath);
8323
9459
  yield { type: "options.loaded", background };
8324
9460
  },
8325
9461
  async* "options.background.save.requested"({ optionsPath }, request) {
@@ -8360,16 +9496,17 @@ var sessionHandlers = {
8360
9496
  };
8361
9497
 
8362
9498
  // packages/daemon/src/workspace/readFileDiffs.ts
8363
- import { relative } from "path";
9499
+ import { relative, resolve as resolve2 } from "path";
8364
9500
  var isTracked = async (cwd, path) => (await Bun.$`git ls-files --error-unmatch -- ${path}`.cwd(cwd).quiet().nothrow()).exitCode === 0;
8365
9501
  async function readPatch(cwd, path) {
8366
9502
  const command = await isTracked(cwd, path) ? Bun.$`git diff --no-color HEAD -- ${path}` : Bun.$`git diff --no-color --no-index -- /dev/null ${path}`;
8367
9503
  return (await command.cwd(cwd).quiet().nothrow()).text();
8368
9504
  }
8369
9505
  async function readFileDiff(cwd, path) {
8370
- const patch = await readPatch(cwd, path);
9506
+ const absolute = resolve2(cwd, path);
9507
+ const patch = await readPatch(cwd, absolute);
8371
9508
  return {
8372
- path: relative(cwd, path) || path,
9509
+ path: relative(cwd, absolute) || path,
8373
9510
  patch,
8374
9511
  additions: countPatchLines(patch, "+"),
8375
9512
  deletions: countPatchLines(patch, "-")
@@ -8380,6 +9517,17 @@ async function readFileDiffs(cwd, paths) {
8380
9517
  return diffs.filter(({ patch }) => patch.trim() !== "");
8381
9518
  }
8382
9519
 
9520
+ // packages/daemon/src/workspace/readGitChangedPaths.ts
9521
+ var readLines = async (cwd, command) => (await command.cwd(cwd).quiet().nothrow()).text().split(`
9522
+ `).filter(Boolean);
9523
+ async function readGitChangedPaths(cwd) {
9524
+ const [tracked, untracked] = await Promise.all([
9525
+ readLines(cwd, Bun.$`git diff --name-only --relative HEAD`),
9526
+ readLines(cwd, Bun.$`git ls-files --others --exclude-standard`)
9527
+ ]);
9528
+ return [...tracked, ...untracked];
9529
+ }
9530
+
8383
9531
  // node_modules/.bun/fuzzysort@4.0.2/node_modules/fuzzysort/fuzzysort.js
8384
9532
  function single(search, target) {
8385
9533
  if (!search || !target)
@@ -10007,7 +11155,9 @@ var workspaceHandlers = {
10007
11155
  yield { type: "workspace.cwd.changed", cwd, ...await readGitInfo(cwd) };
10008
11156
  },
10009
11157
  async* "workspace.diff.requested"({ cwd }, request) {
10010
- yield { type: "workspace.diff.received", files: await readFileDiffs(cwd, request.paths) };
11158
+ const changed = await readFileDiffs(cwd, await readGitChangedPaths(cwd));
11159
+ const files = changed.length > 0 ? changed : await readFileDiffs(cwd, request.paths);
11160
+ yield { type: "workspace.diff.received", files };
10011
11161
  }
10012
11162
  };
10013
11163
 
@@ -10060,7 +11210,11 @@ async function startDaemon(port = DEFAULT_PORT, context) {
10060
11210
  return server;
10061
11211
  }
10062
11212
  // apps/tui/src/startTui.ts
10063
- import { BoxRenderable as BoxRenderable15, createCliRenderer } from "@opentui/core";
11213
+ import {
11214
+ BoxRenderable as BoxRenderable18,
11215
+ createCliRenderer,
11216
+ createHostClipboard
11217
+ } from "@opentui/core";
10064
11218
 
10065
11219
  // apps/tui/src/components/backgroundPanel.ts
10066
11220
  import { BoxRenderable, StyledText, TextRenderable } from "@opentui/core";
@@ -17552,7 +18706,7 @@ var detectFiletype = (path) => FILETYPES[path.split(".").pop() ?? ""];
17552
18706
 
17553
18707
  // apps/tui/src/format/diffViewerChunks.ts
17554
18708
  import { bold as bold2, dim as dim2, fg as fg2 } from "@opentui/core";
17555
- var VIEWER_TITLE = "Session diffs";
18709
+ var VIEWER_TITLE = "Diffs";
17556
18710
  var VIEWER_HINT = "\u2190/\u2192 file \xB7 \u2191/\u2193 PgUp/PgDn scroll \xB7 Esc close";
17557
18711
  var buildFileChunks = (file, selected) => [
17558
18712
  selected ? bold2(fg2(Theme.fg.primary)(`\u276F ${file.path}`)) : fg2(Theme.fg.secondary)(file.path),
@@ -17802,7 +18956,9 @@ class ListPopover {
17802
18956
  // apps/tui/src/components/promptInput.ts
17803
18957
  import {
17804
18958
  BoxRenderable as BoxRenderable5,
18959
+ decodePasteBytes as decodePasteBytes2,
17805
18960
  SyntaxStyle,
18961
+ stripAnsiSequences,
17806
18962
  TextareaRenderable,
17807
18963
  TextRenderable as TextRenderable5
17808
18964
  } from "@opentui/core";
@@ -17989,6 +19145,10 @@ class PromptInput {
17989
19145
  event.preventDefault();
17990
19146
  this.textarea.insertText(placeholder);
17991
19147
  }
19148
+ insertPasted(content) {
19149
+ const placeholder = planPaste(content, this.attachments);
19150
+ this.textarea.insertText(placeholder ?? stripAnsiSequences(decodePasteBytes2(content.bytes)));
19151
+ }
17992
19152
  clear() {
17993
19153
  this.textarea.setText("");
17994
19154
  this.attachments.reset();
@@ -18823,6 +19983,7 @@ class ApprovalPanel {
18823
19983
  for (const { label, decision, color } of buildButtons()) {
18824
19984
  buttons.add(new TextRenderable9(renderer, {
18825
19985
  content: new StyledText8([bold4(fg9(color)(label))]),
19986
+ selectable: false,
18826
19987
  onMouseDown: () => onDecision(decision)
18827
19988
  }));
18828
19989
  }
@@ -18847,44 +20008,64 @@ import {
18847
20008
  var QUESTION_HINT = "\u2191/\u2193 select \xB7 Space toggle \xB7 Enter confirm \xB7 Esc dismiss";
18848
20009
  var CUSTOM_PLACEHOLDER = "type your own answer";
18849
20010
  var TEXT_CURSOR = "\u258F";
18850
- var buildRowChunks = (draft) => {
18851
- const current = readCurrentQuestion(draft);
18852
- if (!current)
18853
- return [];
18854
- const rows = [
18855
- ...current.options,
18856
- { label: OTHER_LABEL, description: "", custom: true }
20011
+ var buildRowChunks = (draft, multiSelect, { label, description, custom }, index) => {
20012
+ const focused = index === draft.cursor;
20013
+ const checked = custom ? draft.custom.trim() !== "" : draft.picks.includes(label);
20014
+ const marker = multiSelect ? checked ? QUESTION_GLYPHS.checked : QUESTION_GLYPHS.unchecked : "";
20015
+ const prefix = [focused ? QUESTION_GLYPHS.cursor : " ", marker].filter(Boolean).join(" ");
20016
+ const head = fg10(focused ? Theme.accent.brand : Theme.fg.primary)(`${prefix} ${label}`);
20017
+ if (!custom)
20018
+ return [head, fg10(Theme.fg.muted)(` ${description}`)];
20019
+ const typed = draft.custom ? [fg10(Theme.fg.primary)(draft.custom)] : focused ? [] : [fg10(Theme.fg.muted)(CUSTOM_PLACEHOLDER)];
20020
+ return [
20021
+ head,
20022
+ fg10(Theme.fg.muted)(": "),
20023
+ ...typed,
20024
+ ...focused ? [fg10(Theme.accent.brand)(TEXT_CURSOR)] : []
18857
20025
  ];
18858
- return rows.flatMap(({ label, description, custom }, index) => {
18859
- const focused = index === draft.cursor;
18860
- const checked = custom ? draft.custom.trim() !== "" : draft.picks.includes(label);
18861
- const marker = current.multiSelect ? checked ? QUESTION_GLYPHS.checked : QUESTION_GLYPHS.unchecked : "";
18862
- const prefix = [focused ? QUESTION_GLYPHS.cursor : " ", marker].filter(Boolean).join(" ");
18863
- const head = fg10(focused ? Theme.accent.brand : Theme.fg.primary)(`
18864
- ${prefix} ${label}`);
18865
- if (!custom)
18866
- return [head, fg10(Theme.fg.muted)(` ${description}`)];
18867
- const typed = draft.custom ? fg10(Theme.fg.primary)(draft.custom) : fg10(Theme.fg.muted)(CUSTOM_PLACEHOLDER);
18868
- return [
18869
- head,
18870
- fg10(Theme.fg.muted)(": "),
18871
- typed,
18872
- ...focused ? [fg10(Theme.accent.brand)(TEXT_CURSOR)] : []
18873
- ];
18874
- });
20026
+ };
20027
+ var listRows = (draft) => {
20028
+ const current = readCurrentQuestion(draft);
20029
+ return current ? [...current.options, { label: OTHER_LABEL, description: "", custom: true }] : [];
18875
20030
  };
18876
20031
 
18877
20032
  class QuestionPanel {
20033
+ renderer;
20034
+ onSelectRow;
18878
20035
  renderable;
18879
20036
  text;
18880
- constructor(renderer) {
20037
+ rows;
20038
+ hint;
20039
+ rowViews = [];
20040
+ constructor(renderer, onSelectRow) {
20041
+ this.renderer = renderer;
20042
+ this.onSelectRow = onSelectRow;
18881
20043
  this.renderable = new BoxRenderable9(renderer, {
18882
20044
  flexDirection: "column",
18883
20045
  marginTop: 1,
18884
20046
  flexShrink: 0
18885
20047
  });
18886
20048
  this.text = new TextRenderable10(renderer, { content: "" });
20049
+ this.rows = new BoxRenderable9(renderer, { flexDirection: "column" });
20050
+ this.hint = new TextRenderable10(renderer, {
20051
+ content: new StyledText9([dim4(fg10(Theme.fg.muted)(QUESTION_HINT))])
20052
+ });
18887
20053
  this.renderable.add(this.text);
20054
+ this.renderable.add(this.rows);
20055
+ this.renderable.add(this.hint);
20056
+ }
20057
+ readRowView(index) {
20058
+ const existing = this.rowViews[index];
20059
+ if (existing)
20060
+ return existing;
20061
+ const created = new TextRenderable10(this.renderer, {
20062
+ content: "",
20063
+ selectable: false,
20064
+ onMouseDown: () => this.onSelectRow(index)
20065
+ });
20066
+ this.rowViews.push(created);
20067
+ this.rows.add(created);
20068
+ return created;
18888
20069
  }
18889
20070
  update(draft) {
18890
20071
  const current = readCurrentQuestion(draft);
@@ -18893,11 +20074,17 @@ class QuestionPanel {
18893
20074
  const progress = draft.questions.length > 1 ? ` (${draft.index + 1}/${draft.questions.length})` : "";
18894
20075
  this.text.content = new StyledText9([
18895
20076
  bold5(fg10(Theme.status.warning)(`>>> ${current.header}${progress}: `)),
18896
- bold5(fg10(Theme.fg.primary)(current.question)),
18897
- ...buildRowChunks(draft),
18898
- dim4(fg10(Theme.fg.muted)(`
18899
- ${QUESTION_HINT}`))
20077
+ bold5(fg10(Theme.fg.primary)(current.question))
18900
20078
  ]);
20079
+ const rows = listRows(draft);
20080
+ rows.forEach((row, index) => {
20081
+ const view = this.readRowView(index);
20082
+ view.visible = true;
20083
+ view.content = new StyledText9(buildRowChunks(draft, current.multiSelect === true, row, index));
20084
+ });
20085
+ this.rowViews.slice(rows.length).forEach((view) => {
20086
+ view.visible = false;
20087
+ });
18901
20088
  }
18902
20089
  }
18903
20090
 
@@ -18935,15 +20122,25 @@ class ToolCallView {
18935
20122
  onMouseOver: () => this.setHovered(true),
18936
20123
  onMouseOut: () => this.setHovered(false)
18937
20124
  });
18938
- this.title = new TextRenderable11(renderer, { content: "", wrapMode: "none", flexShrink: 1 });
18939
- this.duration = new TextRenderable11(renderer, { content: "", flexShrink: 0, marginLeft: 2 });
20125
+ this.title = new TextRenderable11(renderer, {
20126
+ content: "",
20127
+ wrapMode: "none",
20128
+ flexShrink: 1,
20129
+ selectable: false
20130
+ });
20131
+ this.duration = new TextRenderable11(renderer, {
20132
+ content: "",
20133
+ flexShrink: 0,
20134
+ marginLeft: 2,
20135
+ selectable: false
20136
+ });
18940
20137
  header.add(this.title);
18941
20138
  header.add(this.duration);
18942
20139
  this.body = new BoxRenderable10(renderer, { flexDirection: "column", paddingLeft: 2 });
18943
20140
  this.command = new TextRenderable11(renderer, { content: "", fg: Theme.fg.secondary });
18944
20141
  this.output = new TextRenderable11(renderer, { content: "" });
18945
20142
  this.approval = new ApprovalPanel(renderer, (decision) => hooks.onDecision(decision, this.callId));
18946
- this.question = new QuestionPanel(renderer);
20143
+ this.question = new QuestionPanel(renderer, (index) => hooks.onSelectRow(index));
18947
20144
  this.body.add(this.command);
18948
20145
  this.body.add(this.output);
18949
20146
  this.renderable.add(header);
@@ -18994,7 +20191,7 @@ class ToolCallView {
18994
20191
  const glyph = call.expanded ? COLLAPSE_GLYPHS.expanded : COLLAPSE_GLYPHS.collapsed;
18995
20192
  const accent = this.hovered ? Theme.accent.brand : undefined;
18996
20193
  this.title.content = new StyledText10([
18997
- fg11(accent ?? toolColor(call.status))(`${glyph} `),
20194
+ fg11(accent ?? toolColor(call.status))(glyph),
18998
20195
  bold6(fg11(accent ?? Theme.fg.primary)(call.name)),
18999
20196
  fg11(Theme.fg.secondary)(` ${summarizeToolCall(call)}`),
19000
20197
  fg11(Theme.fg.muted)(stats)
@@ -19102,7 +20299,6 @@ class UserMessageView {
19102
20299
  return;
19103
20300
  this.entry = entry;
19104
20301
  this.text.content = new StyledText11([
19105
- bold7(fg12(Theme.accent.brand)("\u276F ")),
19106
20302
  bold7(fg12(Theme.fg.primary)(clipLines(entry.text, USER_LINES)))
19107
20303
  ]);
19108
20304
  this.clock.content = new StyledText11([fg12(Theme.fg.muted)(formatClock(entry.at))]);
@@ -19213,8 +20409,8 @@ var buildWindowChunks = (label, window, now) => {
19213
20409
  };
19214
20410
  function buildRateLimitChunks(limits, now) {
19215
20411
  const windows = [
19216
- ["\u2784", limits.fiveHour],
19217
- ["\u277C", limits.sevenDay]
20412
+ ["\uD83E\uDFF5h", limits.fiveHour],
20413
+ ["\uD83E\uDFF7d", limits.sevenDay]
19218
20414
  ];
19219
20415
  return windows.flatMap(([label, window], index) => window ? [
19220
20416
  ...index > 0 ? [fg13(Theme.border.separator)(SEPARATOR)] : [],
@@ -19342,6 +20538,7 @@ class StatusLine {
19342
20538
  content: "",
19343
20539
  wrapMode: "none",
19344
20540
  flexShrink: 0,
20541
+ selectable: false,
19345
20542
  onMouseDown: onStop
19346
20543
  });
19347
20544
  this.renderable.add(this.label);
@@ -19369,6 +20566,161 @@ class StatusLine {
19369
20566
  }
19370
20567
  }
19371
20568
 
20569
+ // apps/tui/src/components/taskPanel.ts
20570
+ import {
20571
+ BoxRenderable as BoxRenderable16,
20572
+ bold as bold10,
20573
+ dim as dim8,
20574
+ fg as fg17,
20575
+ StyledText as StyledText15,
20576
+ TextRenderable as TextRenderable16
20577
+ } from "@opentui/core";
20578
+
20579
+ // apps/tui/src/format/taskRows.ts
20580
+ var MAX_TASK_ROWS = 5;
20581
+ var readDetail = ({ summary, lastToolName, paused }) => {
20582
+ if (paused)
20583
+ return "Paused";
20584
+ return summary ?? lastToolName ?? "Starting...";
20585
+ };
20586
+ var buildTaskRow = (task, now) => ({
20587
+ taskId: task.id,
20588
+ kind: task.kind,
20589
+ title: task.description,
20590
+ stats: [formatDuration(Math.max(now - task.startedAt, 0)), `\u2193${formatTokenCount(task.tokens)}`].join(SEPARATOR).trim(),
20591
+ detail: readDetail(task)
20592
+ });
20593
+ var buildTaskRows = (tasks, now) => tasks.slice(0, MAX_TASK_ROWS).map((task) => buildTaskRow(task, now));
20594
+ var buildTaskHeader = (tasks) => `Tasks${SEPARATOR}${tasks.length} running`;
20595
+ var countHiddenTasks = (tasks) => Math.max(tasks.length - MAX_TASK_ROWS, 0);
20596
+
20597
+ // apps/tui/src/components/taskRowView.ts
20598
+ import {
20599
+ BoxRenderable as BoxRenderable15,
20600
+ bold as bold9,
20601
+ dim as dim7,
20602
+ fg as fg16,
20603
+ StyledText as StyledText14,
20604
+ TextRenderable as TextRenderable15
20605
+ } from "@opentui/core";
20606
+ var SPINNER_STEP_MS2 = 100;
20607
+
20608
+ class TaskRowView {
20609
+ renderable;
20610
+ title;
20611
+ stop;
20612
+ detail;
20613
+ taskId = "";
20614
+ constructor(renderer, onStop) {
20615
+ this.renderable = new BoxRenderable15(renderer, { flexShrink: 0, visible: false });
20616
+ const line = new BoxRenderable15(renderer, {
20617
+ flexDirection: "row",
20618
+ justifyContent: "space-between"
20619
+ });
20620
+ this.title = new TextRenderable15(renderer, { content: "", wrapMode: "none" });
20621
+ this.stop = new TextRenderable15(renderer, {
20622
+ content: "",
20623
+ wrapMode: "none",
20624
+ flexShrink: 0,
20625
+ selectable: false,
20626
+ onMouseDown: () => onStop(this.taskId)
20627
+ });
20628
+ this.detail = new TextRenderable15(renderer, { content: "", wrapMode: "none" });
20629
+ line.add(this.title);
20630
+ line.add(this.stop);
20631
+ this.renderable.add(line);
20632
+ this.renderable.add(this.detail);
20633
+ }
20634
+ update(row, now) {
20635
+ this.renderable.visible = row !== undefined;
20636
+ if (!row)
20637
+ return;
20638
+ this.taskId = row.taskId;
20639
+ const frame = SPINNER_FRAMES[Math.floor(now / SPINNER_STEP_MS2) % SPINNER_FRAMES.length];
20640
+ this.title.content = new StyledText14([
20641
+ fg16(Theme.status.success)(`${frame} `),
20642
+ bold9(fg16(Theme.fg.primary)(row.kind)),
20643
+ fg16(Theme.fg.secondary)(` ${row.title}`)
20644
+ ]);
20645
+ this.stop.content = new StyledText14([
20646
+ fg16(Theme.fg.muted)(`${row.stats} `),
20647
+ bold9(fg16(Theme.fg.secondary)("[stop]"))
20648
+ ]);
20649
+ this.detail.content = new StyledText14([dim7(fg16(Theme.fg.muted)(` \u2514 ${row.detail}`))]);
20650
+ }
20651
+ }
20652
+
20653
+ // apps/tui/src/components/taskPanel.ts
20654
+ class TaskPanel {
20655
+ renderable;
20656
+ header;
20657
+ rows;
20658
+ overflow;
20659
+ constructor(renderer, onStop) {
20660
+ this.renderable = new BoxRenderable16(renderer, {
20661
+ flexShrink: 0,
20662
+ paddingLeft: 2,
20663
+ paddingRight: 2,
20664
+ visible: false
20665
+ });
20666
+ this.header = new TextRenderable16(renderer, { content: "", wrapMode: "none" });
20667
+ this.overflow = new TextRenderable16(renderer, { content: "", wrapMode: "none" });
20668
+ this.rows = Array.from({ length: MAX_TASK_ROWS }, () => new TaskRowView(renderer, onStop));
20669
+ this.renderable.add(this.header);
20670
+ for (const row of this.rows)
20671
+ this.renderable.add(row.renderable);
20672
+ this.renderable.add(this.overflow);
20673
+ }
20674
+ update({ tasks, now }) {
20675
+ this.renderable.visible = tasks.length > 0;
20676
+ if (tasks.length === 0)
20677
+ return;
20678
+ const rows = buildTaskRows(tasks, now);
20679
+ this.header.content = new StyledText15([bold10(fg17(Theme.fg.secondary)(buildTaskHeader(tasks)))]);
20680
+ this.rows.forEach((view, index) => view.update(rows[index], now));
20681
+ const hidden = countHiddenTasks(tasks);
20682
+ this.overflow.content = hidden ? new StyledText15([dim8(fg17(Theme.fg.muted)(` +${hidden} more`))]) : "";
20683
+ }
20684
+ }
20685
+
20686
+ // apps/tui/src/components/toastView.ts
20687
+ import { BoxRenderable as BoxRenderable17, fg as fg18, StyledText as StyledText16, TextRenderable as TextRenderable17 } from "@opentui/core";
20688
+ var TOAST_ICON = "\u25CF";
20689
+
20690
+ class ToastView {
20691
+ renderable;
20692
+ text;
20693
+ toastId;
20694
+ constructor(renderer) {
20695
+ this.renderable = new BoxRenderable17(renderer, {
20696
+ position: "absolute",
20697
+ top: 1,
20698
+ right: 2,
20699
+ zIndex: 100,
20700
+ paddingLeft: 1,
20701
+ paddingRight: 1,
20702
+ border: true,
20703
+ borderStyle: "rounded",
20704
+ visible: false
20705
+ });
20706
+ this.text = new TextRenderable17(renderer, { content: "", wrapMode: "none", selectable: false });
20707
+ this.renderable.add(this.text);
20708
+ }
20709
+ update({ ui }) {
20710
+ const { toast } = ui;
20711
+ this.renderable.visible = toast !== null;
20712
+ if (!toast || toast.id === this.toastId)
20713
+ return;
20714
+ this.toastId = toast.id;
20715
+ this.renderable.borderColor = Theme.border.focus;
20716
+ this.renderable.backgroundColor = Theme.bg.surface;
20717
+ this.text.content = new StyledText16([
20718
+ fg18(Theme.status.success)(`${TOAST_ICON} `),
20719
+ fg18(Theme.fg.primary)(toast.text)
20720
+ ]);
20721
+ }
20722
+ }
20723
+
19372
20724
  // apps/tui/src/input/agentBusy.ts
19373
20725
  var isStatusBusy = (status) => status !== "idle" && status !== "error";
19374
20726
  var isAgentBusy = (store) => isStatusBusy(store.state.status);
@@ -19410,13 +20762,10 @@ var WORKFLOW_COMMANDS = {
19410
20762
  store.emit({ type: "ui.rewind.picker.opened" });
19411
20763
  }
19412
20764
  },
19413
- "/view-diffs": {
19414
- description: "Review the diffs of files this session edited",
20765
+ "/diffs": {
20766
+ description: "Review git changes, or this session's edits when there are none",
19415
20767
  run(store) {
19416
- const paths = listEditedFiles(store.state);
19417
- if (paths.length === 0)
19418
- return postNotice(store, "This session has not edited any files");
19419
- store.request({ type: "workspace.diff.requested", paths });
20768
+ store.request({ type: "workspace.diff.requested", paths: listEditedFiles(store.state) });
19420
20769
  }
19421
20770
  },
19422
20771
  "/export": {
@@ -19436,13 +20785,30 @@ var WORKFLOW_COMMANDS = {
19436
20785
  };
19437
20786
 
19438
20787
  // apps/tui/src/input/localCommands.ts
19439
- function cycleModel(store) {
19440
- requestAgent(store, { type: "agent.model.cycle.requested" });
20788
+ function openModelPicker2(store) {
20789
+ requestAgent(store, { type: "agent.models.requested" });
19441
20790
  }
19442
20791
  var QUIT_COMMAND = {
19443
20792
  description: "Exit the app (also /exit, /q, /leave)",
19444
20793
  run: (store) => store.emit({ type: "ui.exit.requested" })
19445
20794
  };
20795
+ var MCP_USAGE = "Usage: /mcp | /mcp login <name> | /mcp callback <name> <url>";
20796
+ function runMcpCommand(store, argument) {
20797
+ const [action, serverName, callbackUrl] = argument.trim().split(/\s+/);
20798
+ if (!action)
20799
+ return void requestAgent(store, { type: "agent.mcp.status.requested" });
20800
+ if (action === "login" && serverName) {
20801
+ return void requestAgent(store, { type: "agent.mcp.login.requested", serverName });
20802
+ }
20803
+ if (action === "callback" && serverName && callbackUrl) {
20804
+ return void requestAgent(store, {
20805
+ type: "agent.mcp.callback.submitted",
20806
+ serverName,
20807
+ callbackUrl
20808
+ });
20809
+ }
20810
+ store.emit({ type: "ui.notice.posted", text: MCP_USAGE });
20811
+ }
19446
20812
  var SLASH_ALIASES = {
19447
20813
  "/exit": "/quit",
19448
20814
  "/q": "/quit",
@@ -19468,7 +20834,7 @@ var SLASH_COMMANDS = {
19468
20834
  run(store, model) {
19469
20835
  if (model)
19470
20836
  return void requestAgent(store, { type: "agent.model.set.requested", model });
19471
- requestAgent(store, { type: "agent.models.requested" });
20837
+ openModelPicker2(store);
19472
20838
  }
19473
20839
  },
19474
20840
  "/theme": {
@@ -19522,10 +20888,8 @@ var SLASH_COMMANDS = {
19522
20888
  }
19523
20889
  },
19524
20890
  "/mcp": {
19525
- description: "List MCP servers",
19526
- run(store) {
19527
- requestAgent(store, { type: "agent.mcp.status.requested" });
19528
- }
20891
+ description: "List MCP servers, sign in with /mcp login <name>, or /mcp callback <name> <url>",
20892
+ run: runMcpCommand
19529
20893
  },
19530
20894
  "/clear": {
19531
20895
  description: "Start a fresh session",
@@ -19719,6 +21083,46 @@ function routeAutocompleteKey(key, store, accept) {
19719
21083
  return true;
19720
21084
  }
19721
21085
 
21086
+ // apps/tui/src/prompt/clipboardPaste.ts
21087
+ var PREFERRED_TYPES = ["image/png", "text/plain"];
21088
+ async function readClipboardPaste(clipboard) {
21089
+ const result = await clipboard.read({ preferredTypes: PREFERRED_TYPES });
21090
+ if (result.status !== "read")
21091
+ return;
21092
+ const { mimeType, bytes } = result.representation;
21093
+ if (bytes.length === 0)
21094
+ return;
21095
+ return { bytes, metadata: { mimeType, kind: mimeType.startsWith("text/") ? "text" : "binary" } };
21096
+ }
21097
+
21098
+ // apps/tui/src/input/toastActions.ts
21099
+ var TOAST_DURATION_MS = 2500;
21100
+ function showToast(store, text) {
21101
+ const id = crypto.randomUUID();
21102
+ store.emit({ type: "ui.toast.posted", id, text });
21103
+ setTimeout(() => store.emit({ type: "ui.toast.dismissed", id }), TOAST_DURATION_MS).unref();
21104
+ }
21105
+
21106
+ // apps/tui/src/input/clipboardActions.ts
21107
+ var UNAVAILABLE_NOTICE = "Clipboard unavailable, use your terminal's paste shortcut";
21108
+ var COPIED_TOAST = "Copied to clipboard";
21109
+ var COPY_FAILED_TOAST = "Could not copy to clipboard";
21110
+ async function pasteFromClipboard(store, input, clipboard) {
21111
+ const content = await readClipboardPaste(clipboard);
21112
+ if (content)
21113
+ input.insertPasted(content);
21114
+ else
21115
+ showToast(store, UNAVAILABLE_NOTICE);
21116
+ }
21117
+ async function copySelection(store, renderer, clipboard, selection) {
21118
+ const text = selection.getSelectedText();
21119
+ if (!text)
21120
+ return;
21121
+ const written = (await clipboard.writeText(text)).status === "written";
21122
+ const copied = written || renderer.copyToClipboardOSC52(text);
21123
+ showToast(store, copied ? COPIED_TOAST : COPY_FAILED_TOAST);
21124
+ }
21125
+
19722
21126
  // apps/tui/src/input/slashCommands.ts
19723
21127
  var parseSlashLine = (line) => {
19724
21128
  const [name = "", ...rest] = line.trim().split(/\s+/);
@@ -19771,6 +21175,9 @@ function answerApproval(store, decision, toolUseId) {
19771
21175
  if (target)
19772
21176
  requestAgent(store, { type: "agent.tool.approval.answered", toolUseId: target, decision });
19773
21177
  }
21178
+ function stopTask(store, taskId) {
21179
+ requestAgent(store, { type: "agent.task.stop.requested", taskId });
21180
+ }
19774
21181
  function cancelTurn(store) {
19775
21182
  requestAgent(store, { type: "agent.prompt.cancel.requested" });
19776
21183
  }
@@ -19898,7 +21305,7 @@ var routeExit = (key, { store, presses, exit }) => {
19898
21305
  return true;
19899
21306
  }
19900
21307
  presses.ctrlCAt = pressedAt;
19901
- store.emit({ type: "ui.notice.posted", text: EXIT_NOTICE });
21308
+ showToast(store, EXIT_NOTICE);
19902
21309
  return true;
19903
21310
  };
19904
21311
  var routeDoubleEscape = (key, { store, presses }) => {
@@ -19926,10 +21333,11 @@ var QUESTION_ACTIONS = {
19926
21333
  return: confirmQuestion,
19927
21334
  escape: dismissQuestion
19928
21335
  };
21336
+ var DELETE_CHARACTER = "\x7F";
19929
21337
  var readTypedText = (key) => {
19930
21338
  if (key.ctrl || key.meta)
19931
21339
  return;
19932
- return key.sequence.length === 1 && key.sequence >= " " ? key.sequence : undefined;
21340
+ return key.sequence.length === 1 && key.sequence >= " " && key.sequence !== DELETE_CHARACTER ? key.sequence : undefined;
19933
21341
  };
19934
21342
  function typeCustomAnswer(key, store) {
19935
21343
  const { question } = store.state.ui;
@@ -20014,10 +21422,10 @@ var routePicker = (key, { store }) => {
20014
21422
  }
20015
21423
  return true;
20016
21424
  };
20017
- var routeModelCycle = (key, { store }) => {
21425
+ var routeModelPicker = (key, { store }) => {
20018
21426
  if (key.name !== "tab" || !key.shift)
20019
21427
  return false;
20020
- cycleModel(store);
21428
+ openModelPicker2(store);
20021
21429
  return true;
20022
21430
  };
20023
21431
  var routeDelivery = (key, { store, submitInput }) => {
@@ -20027,6 +21435,14 @@ var routeDelivery = (key, { store, submitInput }) => {
20027
21435
  submitInput(delivery);
20028
21436
  return true;
20029
21437
  };
21438
+ var routePaste = (key, { store, pasteClipboard }) => {
21439
+ if (key.name !== "v" || !(key.ctrl || key.super))
21440
+ return false;
21441
+ if (store.state.ui.focus !== "input")
21442
+ return false;
21443
+ pasteClipboard();
21444
+ return true;
21445
+ };
20030
21446
  var ROUTES = [
20031
21447
  routeExit,
20032
21448
  routeApproval,
@@ -20034,8 +21450,9 @@ var ROUTES = [
20034
21450
  routeDiffViewer,
20035
21451
  routeBackgroundEditor,
20036
21452
  routePicker,
20037
- routeModelCycle,
21453
+ routeModelPicker,
20038
21454
  routeDelivery,
21455
+ routePaste,
20039
21456
  routeHistorySearch,
20040
21457
  routeCompletion,
20041
21458
  routeDoubleEscape,
@@ -20179,6 +21596,7 @@ class AppStore {
20179
21596
  machine = new EventMachine(createSessionState(""), reduceTimedEvent);
20180
21597
  peerEvents = new WeakSet;
20181
21598
  stopListening;
21599
+ closed = false;
20182
21600
  constructor(client) {
20183
21601
  this.client = client;
20184
21602
  this.stopListening = client.subscribe((event, peer) => this.receive(event, peer));
@@ -20196,7 +21614,8 @@ class AppStore {
20196
21614
  this.client.send(event);
20197
21615
  }
20198
21616
  emit(event) {
20199
- this.machine.send(event);
21617
+ if (!this.closed)
21618
+ this.machine.send(event);
20200
21619
  }
20201
21620
  subscribe(listener) {
20202
21621
  return this.machine.subscribe(() => listener(this.machine.state));
@@ -20208,6 +21627,7 @@ class AppStore {
20208
21627
  });
20209
21628
  }
20210
21629
  close() {
21630
+ this.closed = true;
20211
21631
  this.stopListening();
20212
21632
  this.client.close();
20213
21633
  }
@@ -20240,6 +21660,7 @@ var readShownBackground = ({ background, ui }) => ui.backgroundEditor?.color ??
20240
21660
  async function startTui(client, options = {}) {
20241
21661
  const activeRenderer = options.renderer ?? await createCliRenderer({ exitOnCtrlC: false, useMouse: true });
20242
21662
  const store = new AppStore(client);
21663
+ const clipboard = options.clipboard ?? createHostClipboard();
20243
21664
  let syntaxStyle = createSyntaxStyle(activeRenderer);
20244
21665
  let appliedTheme = readShownTheme(store.state);
20245
21666
  let appliedBackground = readShownBackground(store.state);
@@ -20247,13 +21668,16 @@ async function startTui(client, options = {}) {
20247
21668
  const infoBar = new SessionInfoBar(activeRenderer);
20248
21669
  const popover = new ListPopover(activeRenderer);
20249
21670
  const backgroundPanel = new BackgroundPanel(activeRenderer);
21671
+ const toastView = new ToastView(activeRenderer);
20250
21672
  const statusLine = new StatusLine(activeRenderer, () => cancelTurn(store));
21673
+ const taskPanel = new TaskPanel(activeRenderer, (taskId) => stopTask(store, taskId));
20251
21674
  const scrollback = new ScrollbackView(activeRenderer, {
20252
21675
  syntaxStyle,
20253
21676
  hooks: {
20254
21677
  syntaxStyle,
20255
21678
  onDecision: (decision, id) => answerApproval(store, decision, id),
20256
- onToggle: (callId) => store.emit({ type: "ui.tool.toggled", callId })
21679
+ onToggle: (callId) => store.emit({ type: "ui.tool.toggled", callId }),
21680
+ onSelectRow: (cursor) => store.emit({ type: "ui.question.cursor.set", cursor })
20257
21681
  }
20258
21682
  });
20259
21683
  const diffViewer = new DiffViewerPanel(activeRenderer, syntaxStyle);
@@ -20281,7 +21705,7 @@ async function startTui(client, options = {}) {
20281
21705
  saveDraft(text);
20282
21706
  }
20283
21707
  });
20284
- const root = new BoxRenderable15(activeRenderer, {
21708
+ const root = new BoxRenderable18(activeRenderer, {
20285
21709
  width: "100%",
20286
21710
  height: "100%",
20287
21711
  flexDirection: "column",
@@ -20292,6 +21716,7 @@ async function startTui(client, options = {}) {
20292
21716
  scrollback,
20293
21717
  diffViewer,
20294
21718
  statusLine,
21719
+ taskPanel,
20295
21720
  popover,
20296
21721
  backgroundPanel,
20297
21722
  input,
@@ -20300,7 +21725,11 @@ async function startTui(client, options = {}) {
20300
21725
  for (const part of parts)
20301
21726
  root.add(part.renderable);
20302
21727
  activeRenderer.root.add(root);
20303
- for (const part of [header, statusLine, popover, backgroundPanel, input, infoBar]) {
21728
+ activeRenderer.root.add(toastView.renderable);
21729
+ activeRenderer.on("selection", (selection) => {
21730
+ copySelection(store, activeRenderer, clipboard, selection);
21731
+ });
21732
+ for (const part of [header, statusLine, taskPanel, popover, backgroundPanel, input, infoBar]) {
20304
21733
  part.renderable.onMouseScroll = ({ scroll }) => {
20305
21734
  if (scroll?.direction === "up")
20306
21735
  scrollback.scrollByLines(-1);
@@ -20332,6 +21761,8 @@ async function startTui(client, options = {}) {
20332
21761
  syncTheme(state);
20333
21762
  header.update(state);
20334
21763
  statusLine.update(state);
21764
+ taskPanel.update(state);
21765
+ toastView.update(state);
20335
21766
  infoBar.update(state);
20336
21767
  scrollback.update(state);
20337
21768
  scrollback.renderable.visible = state.ui.diffViewer === null;
@@ -20356,7 +21787,10 @@ async function startTui(client, options = {}) {
20356
21787
  notifier.notify(event);
20357
21788
  if (event.type === "ui.exit.requested")
20358
21789
  activeRenderer.destroy();
21790
+ if (event.type === "ui.title.set")
21791
+ activeRenderer.setTerminalTitle(event.title);
20359
21792
  });
21793
+ store.emit({ type: "ui.title.set", title: "Claudin" });
20360
21794
  const editor = {
20361
21795
  read: () => input.text,
20362
21796
  replace: (text) => input.replaceText(text, text.length)
@@ -20370,6 +21804,7 @@ async function startTui(client, options = {}) {
20370
21804
  diffViewer,
20371
21805
  editor,
20372
21806
  acceptCompletion: () => acceptAutocomplete(store, input),
21807
+ pasteClipboard: () => void pasteFromClipboard(store, input, clipboard),
20373
21808
  submitInput,
20374
21809
  exit: () => activeRenderer.destroy()
20375
21810
  };
@@ -20377,7 +21812,8 @@ async function startTui(client, options = {}) {
20377
21812
  key.preventDefault();
20378
21813
  });
20379
21814
  const clock = setInterval(() => {
20380
- if (store.state.status !== "idle")
21815
+ const { status, tasks } = store.state;
21816
+ if (status !== "idle" || tasks.length > 0)
20381
21817
  store.emit({ type: "ui.clock.ticked", now: Date.now() });
20382
21818
  }, CLOCK_INTERVAL_MS);
20383
21819
  let lastRateLimitAt = Date.now();
@@ -20395,6 +21831,7 @@ async function startTui(client, options = {}) {
20395
21831
  clearInterval(rateLimitPoll);
20396
21832
  destroyed = true;
20397
21833
  historySaver.flush();
21834
+ clipboard.dispose();
20398
21835
  options.onExit?.(store.state.sessionId);
20399
21836
  store.close();
20400
21837
  });
@@ -20506,10 +21943,10 @@ function humanReadableArgName(arg) {
20506
21943
 
20507
21944
  // node_modules/.bun/commander@15.0.0/node_modules/commander/lib/command.js
20508
21945
  import { EventEmitter } from "events";
20509
- import childProcess from "child_process";
20510
- import path from "path";
20511
- import fs from "fs";
20512
- import process2 from "process";
21946
+ import childProcess4 from "child_process";
21947
+ import path3 from "path";
21948
+ import fs6 from "fs";
21949
+ import process10 from "process";
20513
21950
  import { stripVTControlCharacters as stripVTControlCharacters2 } from "util";
20514
21951
 
20515
21952
  // node_modules/.bun/commander@15.0.0/node_modules/commander/lib/help.js
@@ -21146,13 +22583,13 @@ class Command extends EventEmitter {
21146
22583
  this._showSuggestionAfterError = true;
21147
22584
  this._savedState = null;
21148
22585
  this._outputConfiguration = {
21149
- writeOut: (str) => process2.stdout.write(str),
21150
- writeErr: (str) => process2.stderr.write(str),
22586
+ writeOut: (str) => process10.stdout.write(str),
22587
+ writeErr: (str) => process10.stderr.write(str),
21151
22588
  outputError: (str, write) => write(str),
21152
- getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : undefined,
21153
- getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : undefined,
21154
- getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
21155
- getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
22589
+ getOutHelpWidth: () => process10.stdout.isTTY ? process10.stdout.columns : undefined,
22590
+ getErrHelpWidth: () => process10.stderr.isTTY ? process10.stderr.columns : undefined,
22591
+ getOutHasColors: () => useColor() ?? (process10.stdout.isTTY && process10.stdout.hasColors?.()),
22592
+ getErrHasColors: () => useColor() ?? (process10.stderr.isTTY && process10.stderr.hasColors?.()),
21156
22593
  stripColor: (str) => stripVTControlCharacters2(str)
21157
22594
  };
21158
22595
  this._hidden = false;
@@ -21360,7 +22797,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
21360
22797
  if (this._exitCallback) {
21361
22798
  this._exitCallback(new CommanderError(exitCode, code, message));
21362
22799
  }
21363
- process2.exit(exitCode);
22800
+ process10.exit(exitCode);
21364
22801
  }
21365
22802
  action(fn) {
21366
22803
  const listener = (args) => {
@@ -21552,16 +22989,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
21552
22989
  }
21553
22990
  parseOptions = parseOptions || {};
21554
22991
  if (argv === undefined && parseOptions.from === undefined) {
21555
- if (process2.versions?.electron) {
22992
+ if (process10.versions?.electron) {
21556
22993
  parseOptions.from = "electron";
21557
22994
  }
21558
- const execArgv = process2.execArgv ?? [];
22995
+ const execArgv = process10.execArgv ?? [];
21559
22996
  if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
21560
22997
  parseOptions.from = "eval";
21561
22998
  }
21562
22999
  }
21563
23000
  if (argv === undefined) {
21564
- argv = process2.argv;
23001
+ argv = process10.argv;
21565
23002
  }
21566
23003
  this.rawArgs = argv.slice();
21567
23004
  let userArgs;
@@ -21572,7 +23009,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
21572
23009
  userArgs = argv.slice(2);
21573
23010
  break;
21574
23011
  case "electron":
21575
- if (process2.defaultApp) {
23012
+ if (process10.defaultApp) {
21576
23013
  this._scriptPath = argv[1];
21577
23014
  userArgs = argv.slice(2);
21578
23015
  } else {
@@ -21638,7 +23075,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
21638
23075
  this.processedArgs = [];
21639
23076
  }
21640
23077
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
21641
- if (fs.existsSync(executableFile))
23078
+ if (fs6.existsSync(executableFile))
21642
23079
  return;
21643
23080
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
21644
23081
  const executableMissing = `'${executableFile}' does not exist
@@ -21651,12 +23088,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
21651
23088
  args = args.slice();
21652
23089
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
21653
23090
  function findFile(baseDir, baseName) {
21654
- const localBin = path.resolve(baseDir, baseName);
21655
- if (fs.existsSync(localBin))
23091
+ const localBin = path3.resolve(baseDir, baseName);
23092
+ if (fs6.existsSync(localBin))
21656
23093
  return localBin;
21657
- if (sourceExt.includes(path.extname(baseName)))
23094
+ if (sourceExt.includes(path3.extname(baseName)))
21658
23095
  return;
21659
- const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
23096
+ const foundExt = sourceExt.find((ext) => fs6.existsSync(`${localBin}${ext}`));
21660
23097
  if (foundExt)
21661
23098
  return `${localBin}${foundExt}`;
21662
23099
  return;
@@ -21668,42 +23105,42 @@ Expecting one of '${allowedValues.join("', '")}'`);
21668
23105
  if (this._scriptPath) {
21669
23106
  let resolvedScriptPath;
21670
23107
  try {
21671
- resolvedScriptPath = fs.realpathSync(this._scriptPath);
23108
+ resolvedScriptPath = fs6.realpathSync(this._scriptPath);
21672
23109
  } catch {
21673
23110
  resolvedScriptPath = this._scriptPath;
21674
23111
  }
21675
- executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
23112
+ executableDir = path3.resolve(path3.dirname(resolvedScriptPath), executableDir);
21676
23113
  }
21677
23114
  if (executableDir) {
21678
23115
  let localFile = findFile(executableDir, executableFile);
21679
23116
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
21680
- const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
23117
+ const legacyName = path3.basename(this._scriptPath, path3.extname(this._scriptPath));
21681
23118
  if (legacyName !== this._name) {
21682
23119
  localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
21683
23120
  }
21684
23121
  }
21685
23122
  executableFile = localFile || executableFile;
21686
23123
  }
21687
- const launchWithNode = sourceExt.includes(path.extname(executableFile));
23124
+ const launchWithNode = sourceExt.includes(path3.extname(executableFile));
21688
23125
  let proc;
21689
- if (process2.platform !== "win32") {
23126
+ if (process10.platform !== "win32") {
21690
23127
  if (launchWithNode) {
21691
23128
  args.unshift(executableFile);
21692
- args = incrementNodeInspectorPort(process2.execArgv).concat(args);
21693
- proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
23129
+ args = incrementNodeInspectorPort(process10.execArgv).concat(args);
23130
+ proc = childProcess4.spawn(process10.argv[0], args, { stdio: "inherit" });
21694
23131
  } else {
21695
- proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
23132
+ proc = childProcess4.spawn(executableFile, args, { stdio: "inherit" });
21696
23133
  }
21697
23134
  } else {
21698
23135
  this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
21699
23136
  args.unshift(executableFile);
21700
- args = incrementNodeInspectorPort(process2.execArgv).concat(args);
21701
- proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
23137
+ args = incrementNodeInspectorPort(process10.execArgv).concat(args);
23138
+ proc = childProcess4.spawn(process10.execPath, args, { stdio: "inherit" });
21702
23139
  }
21703
23140
  if (!proc.killed) {
21704
23141
  const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
21705
23142
  signals.forEach((signal) => {
21706
- process2.on(signal, () => {
23143
+ process10.on(signal, () => {
21707
23144
  if (proc.killed === false && proc.exitCode === null) {
21708
23145
  proc.kill(signal);
21709
23146
  }
@@ -21714,7 +23151,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
21714
23151
  proc.on("close", (code) => {
21715
23152
  code = code ?? 1;
21716
23153
  if (!exitCallback) {
21717
- process2.exit(code);
23154
+ process10.exit(code);
21718
23155
  } else {
21719
23156
  exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
21720
23157
  }
@@ -21726,7 +23163,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
21726
23163
  throw new Error(`'${executableFile}' not executable`);
21727
23164
  }
21728
23165
  if (!exitCallback) {
21729
- process2.exit(1);
23166
+ process10.exit(1);
21730
23167
  } else {
21731
23168
  const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
21732
23169
  wrappedError.nestedError = err;
@@ -22075,11 +23512,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
22075
23512
  }
22076
23513
  _parseOptionsEnv() {
22077
23514
  this.options.forEach((option) => {
22078
- if (option.envVar && option.envVar in process2.env) {
23515
+ if (option.envVar && option.envVar in process10.env) {
22079
23516
  const optionKey = option.attributeName();
22080
23517
  if (this.getOptionValue(optionKey) === undefined || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
22081
23518
  if (option.required || option.optional) {
22082
- this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
23519
+ this.emit(`optionEnv:${option.name()}`, process10.env[option.envVar]);
22083
23520
  } else {
22084
23521
  this.emit(`optionEnv:${option.name()}`);
22085
23522
  }
@@ -22275,13 +23712,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
22275
23712
  cmd.helpGroup(this._defaultCommandGroup);
22276
23713
  }
22277
23714
  nameFromFilename(filename) {
22278
- this._name = path.basename(filename, path.extname(filename));
23715
+ this._name = path3.basename(filename, path3.extname(filename));
22279
23716
  return this;
22280
23717
  }
22281
- executableDir(path2) {
22282
- if (path2 === undefined)
23718
+ executableDir(path) {
23719
+ if (path === undefined)
22283
23720
  return this._executableDir;
22284
- this._executableDir = path2;
23721
+ this._executableDir = path;
22285
23722
  return this;
22286
23723
  }
22287
23724
  helpInformation(contextOptions) {
@@ -22378,7 +23815,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
22378
23815
  }
22379
23816
  help(contextOptions) {
22380
23817
  this.outputHelp(contextOptions);
22381
- let exitCode = Number(process2.exitCode ?? 0);
23818
+ let exitCode = Number(process10.exitCode ?? 0);
22382
23819
  if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
22383
23820
  exitCode = 1;
22384
23821
  }
@@ -22444,9 +23881,9 @@ function incrementNodeInspectorPort(args) {
22444
23881
  });
22445
23882
  }
22446
23883
  function useColor() {
22447
- if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
23884
+ if (process10.env.NO_COLOR || process10.env.FORCE_COLOR === "0" || process10.env.FORCE_COLOR === "false")
22448
23885
  return false;
22449
- if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== undefined)
23886
+ if (process10.env.FORCE_COLOR || process10.env.CLICOLOR_FORCE !== undefined)
22450
23887
  return true;
22451
23888
  return;
22452
23889
  }