@couralabs/claudin 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claudin.js +1379 -144
- package/package.json +2 -2
package/claudin.js
CHANGED
|
@@ -6161,7 +6161,6 @@ var agentRequestSchemas = [
|
|
|
6161
6161
|
answers: record(string2(), string2())
|
|
6162
6162
|
}),
|
|
6163
6163
|
object({ type: literal("agent.model.set.requested"), agentSessionId, model: string2() }),
|
|
6164
|
-
object({ type: literal("agent.model.cycle.requested"), agentSessionId }),
|
|
6165
6164
|
object({
|
|
6166
6165
|
type: literal("agent.permission_mode.set.requested"),
|
|
6167
6166
|
agentSessionId,
|
|
@@ -6175,6 +6174,17 @@ var agentRequestSchemas = [
|
|
|
6175
6174
|
object({ type: literal("agent.commands.requested"), agentSessionId }),
|
|
6176
6175
|
object({ type: literal("agent.models.requested"), agentSessionId }),
|
|
6177
6176
|
object({ type: literal("agent.mcp.status.requested"), agentSessionId }),
|
|
6177
|
+
object({
|
|
6178
|
+
type: literal("agent.mcp.login.requested"),
|
|
6179
|
+
agentSessionId,
|
|
6180
|
+
serverName: string2()
|
|
6181
|
+
}),
|
|
6182
|
+
object({
|
|
6183
|
+
type: literal("agent.mcp.callback.submitted"),
|
|
6184
|
+
agentSessionId,
|
|
6185
|
+
serverName: string2(),
|
|
6186
|
+
callbackUrl: string2()
|
|
6187
|
+
}),
|
|
6178
6188
|
object({ type: literal("agent.usage.requested"), agentSessionId }),
|
|
6179
6189
|
object({ type: literal("agent.rate_limit.requested"), agentSessionId }),
|
|
6180
6190
|
object({ type: literal("agent.rate_limit.cached.requested") }),
|
|
@@ -6217,7 +6227,8 @@ var createSessionState = (sessionId) => ({
|
|
|
6217
6227
|
backgroundEditor: null,
|
|
6218
6228
|
question: null,
|
|
6219
6229
|
history: null,
|
|
6220
|
-
diffViewer: null
|
|
6230
|
+
diffViewer: null,
|
|
6231
|
+
toast: null
|
|
6221
6232
|
}
|
|
6222
6233
|
});
|
|
6223
6234
|
|
|
@@ -6632,7 +6643,7 @@ var applyLoadedBackground = (state, background = TRANSPARENT_BACKGROUND) => ({ .
|
|
|
6632
6643
|
var applySavedBackground = (state, color) => appendNotice(closeBackgroundEditor({ ...state, background: color }), "Background color saved");
|
|
6633
6644
|
|
|
6634
6645
|
// packages/events/src/reducers/reduceDiffViewer.ts
|
|
6635
|
-
var NO_DIFFS_NOTICE = "No changes
|
|
6646
|
+
var NO_DIFFS_NOTICE = "No git changes or session edits to show";
|
|
6636
6647
|
function openDiffViewer(state, files) {
|
|
6637
6648
|
if (files.length === 0)
|
|
6638
6649
|
return appendNotice(state, NO_DIFFS_NOTICE);
|
|
@@ -6651,7 +6662,10 @@ var closeDiffViewer = (state) => ({
|
|
|
6651
6662
|
});
|
|
6652
6663
|
|
|
6653
6664
|
// packages/events/src/reducers/reduceNotices.ts
|
|
6654
|
-
var
|
|
6665
|
+
var LOGIN_HINT = "needs-auth: sign in with /mcp login <name>";
|
|
6666
|
+
var describeServer = ({ name, status }) => `${name} (${status === "needs-auth" ? LOGIN_HINT.replace("<name>", name) : status})`;
|
|
6667
|
+
var describeServers = (servers) => servers.length === 0 ? "No MCP servers configured" : `MCP servers: ${servers.map(describeServer).join(", ")}`;
|
|
6668
|
+
var describeLoginStarted = (serverName, authUrl) => `Signing in to ${serverName}. If the browser did not open, visit: ${authUrl}`;
|
|
6655
6669
|
function reduceModelChanged(state, model) {
|
|
6656
6670
|
const changed = { ...state, model };
|
|
6657
6671
|
return appendNotice(changed, `Model set to ${readModelLabel(changed)}`);
|
|
@@ -6703,6 +6717,13 @@ function moveQuestionCursor(state, delta) {
|
|
|
6703
6717
|
return state;
|
|
6704
6718
|
return withDraft(state, { ...question, cursor: (question.cursor + delta + size) % size });
|
|
6705
6719
|
}
|
|
6720
|
+
function setQuestionCursor(state, cursor) {
|
|
6721
|
+
const { question } = state.ui;
|
|
6722
|
+
const current = question ? readCurrentQuestion(question) : undefined;
|
|
6723
|
+
if (!question || !current || cursor < 0 || cursor > current.options.length)
|
|
6724
|
+
return state;
|
|
6725
|
+
return withDraft(state, { ...question, cursor });
|
|
6726
|
+
}
|
|
6706
6727
|
function toggleQuestionPick(state) {
|
|
6707
6728
|
const { question } = state.ui;
|
|
6708
6729
|
const current = question ? readCurrentQuestion(question) : undefined;
|
|
@@ -6730,6 +6751,14 @@ function changeQuestionCustom(state, text) {
|
|
|
6730
6751
|
return question ? withDraft(state, { ...question, custom: text }) : state;
|
|
6731
6752
|
}
|
|
6732
6753
|
|
|
6754
|
+
// packages/events/src/reducers/reduceToast.ts
|
|
6755
|
+
var withToast = (state, toast) => ({
|
|
6756
|
+
...state,
|
|
6757
|
+
ui: { ...state.ui, toast }
|
|
6758
|
+
});
|
|
6759
|
+
var postToast = (state, toast) => withToast(state, { id: toast.id, text: toast.text });
|
|
6760
|
+
var dismissToast = (state, id) => state.ui.toast?.id === id ? withToast(state, null) : state;
|
|
6761
|
+
|
|
6733
6762
|
// packages/events/src/reducers/reduceUi.ts
|
|
6734
6763
|
var FOCUS_ORDER = ["input", "scrollback"];
|
|
6735
6764
|
function cycleFocus(state, direction) {
|
|
@@ -6817,6 +6846,8 @@ function reduceUi(state, event) {
|
|
|
6817
6846
|
return adjustBackgroundValue(state, event.delta);
|
|
6818
6847
|
case "ui.question.moved":
|
|
6819
6848
|
return moveQuestionCursor(state, event.delta);
|
|
6849
|
+
case "ui.question.cursor.set":
|
|
6850
|
+
return setQuestionCursor(state, event.cursor);
|
|
6820
6851
|
case "ui.question.toggled":
|
|
6821
6852
|
return toggleQuestionPick(state);
|
|
6822
6853
|
case "ui.question.custom.changed":
|
|
@@ -6827,6 +6858,10 @@ function reduceUi(state, event) {
|
|
|
6827
6858
|
return state;
|
|
6828
6859
|
case "ui.notice.posted":
|
|
6829
6860
|
return appendNotice(state, event.text);
|
|
6861
|
+
case "ui.toast.posted":
|
|
6862
|
+
return postToast(state, event);
|
|
6863
|
+
case "ui.toast.dismissed":
|
|
6864
|
+
return dismissToast(state, event.id);
|
|
6830
6865
|
case "ui.clock.ticked":
|
|
6831
6866
|
return { ...state, now: event.now };
|
|
6832
6867
|
}
|
|
@@ -6847,7 +6882,8 @@ function restoreSession(state, sessionId, stored, notice) {
|
|
|
6847
6882
|
return appendNotice({ ...adoptReplay(state, settled, sessionId), status: "idle", queuedTurns: 0 }, notice);
|
|
6848
6883
|
}
|
|
6849
6884
|
var syncSession = (state, sessionId, stored) => appendNotice(adoptReplay(state, replayEvents(sessionId, stored), sessionId), "Attached to the live session");
|
|
6850
|
-
function openModelPicker(state,
|
|
6885
|
+
function openModelPicker(state, allModels) {
|
|
6886
|
+
const models = allModels.filter((model) => model.value !== "default");
|
|
6851
6887
|
const current = models.findIndex((model) => model.value === state.model);
|
|
6852
6888
|
const picker = { kind: "model", selected: Math.max(current, 0) };
|
|
6853
6889
|
return { ...state, models, ui: { ...state.ui, picker } };
|
|
@@ -6937,6 +6973,8 @@ function reduceSessionState(state, event) {
|
|
|
6937
6973
|
return reduceModeChanged(state, event.mode);
|
|
6938
6974
|
case "agent.mcp.status.received":
|
|
6939
6975
|
return appendNotice(state, describeServers(event.servers));
|
|
6976
|
+
case "agent.mcp.login.started":
|
|
6977
|
+
return appendNotice(state, describeLoginStarted(event.serverName, event.authUrl));
|
|
6940
6978
|
case "workspace.info.received":
|
|
6941
6979
|
return { ...state, cwd: event.cwd, gitBranch: event.gitBranch, gitStats: event.gitStats };
|
|
6942
6980
|
case "options.loaded":
|
|
@@ -7059,6 +7097,11 @@ var agentResponseSchemas = [
|
|
|
7059
7097
|
type: literal("agent.mcp.status.received"),
|
|
7060
7098
|
servers: sdkValue()
|
|
7061
7099
|
}),
|
|
7100
|
+
object({
|
|
7101
|
+
type: literal("agent.mcp.login.started"),
|
|
7102
|
+
serverName: string2(),
|
|
7103
|
+
authUrl: string2()
|
|
7104
|
+
}),
|
|
7062
7105
|
object({
|
|
7063
7106
|
type: literal("agent.usage.received"),
|
|
7064
7107
|
usage: sdkValue()
|
|
@@ -7156,6 +7199,9 @@ var PRIVATE_TYPES = new Set([
|
|
|
7156
7199
|
"agent.commands.requested",
|
|
7157
7200
|
"agent.mcp.status.requested",
|
|
7158
7201
|
"agent.mcp.status.received",
|
|
7202
|
+
"agent.mcp.login.requested",
|
|
7203
|
+
"agent.mcp.callback.submitted",
|
|
7204
|
+
"agent.mcp.login.started",
|
|
7159
7205
|
"agent.usage.requested",
|
|
7160
7206
|
"agent.usage.received",
|
|
7161
7207
|
"agent.rate_limit.requested",
|
|
@@ -7396,12 +7442,41 @@ import {
|
|
|
7396
7442
|
getSessionMessages,
|
|
7397
7443
|
query
|
|
7398
7444
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
7445
|
+
|
|
7446
|
+
// packages/agent/src/runtime/muteShadowedWarning.ts
|
|
7447
|
+
var SHADOWED_WARNING_CODE = "CLAUDE_SDK_CAN_USE_TOOL_SHADOWED";
|
|
7448
|
+
function readWarningCode(args) {
|
|
7449
|
+
const [first, second] = args;
|
|
7450
|
+
if (typeof first === "object" && first !== null)
|
|
7451
|
+
return first.code;
|
|
7452
|
+
return typeof first === "string" && typeof second === "string" ? second : undefined;
|
|
7453
|
+
}
|
|
7454
|
+
function muteShadowedWarning() {
|
|
7455
|
+
const original = process.emitWarning.bind(process);
|
|
7456
|
+
process.emitWarning = (warning, ...args) => {
|
|
7457
|
+
if (readWarningCode(args) === SHADOWED_WARNING_CODE)
|
|
7458
|
+
return;
|
|
7459
|
+
return original(warning, ...args);
|
|
7460
|
+
};
|
|
7461
|
+
}
|
|
7462
|
+
|
|
7463
|
+
// packages/agent/src/runtime/agentRuntime.ts
|
|
7464
|
+
muteShadowedWarning();
|
|
7399
7465
|
var sdkRuntime = {
|
|
7400
|
-
open: query,
|
|
7466
|
+
open: (params) => query(params),
|
|
7401
7467
|
getInfo: getSessionInfo,
|
|
7402
7468
|
getMessages: getSessionMessages,
|
|
7403
7469
|
fork: forkSession
|
|
7404
7470
|
};
|
|
7471
|
+
// packages/agent/src/runtime/buildUserMessage.ts
|
|
7472
|
+
var isSlashCommand = (content) => readPromptText(content).trimStart().startsWith("/");
|
|
7473
|
+
var buildUserMessage = (content, priority) => ({
|
|
7474
|
+
type: "user",
|
|
7475
|
+
message: { role: "user", content },
|
|
7476
|
+
parent_tool_use_id: null,
|
|
7477
|
+
priority,
|
|
7478
|
+
client_composed: isSlashCommand(content) ? undefined : true
|
|
7479
|
+
});
|
|
7405
7480
|
// node_modules/.bun/p-defer@4.0.1/node_modules/p-defer/index.js
|
|
7406
7481
|
function pDefer() {
|
|
7407
7482
|
const deferred = {};
|
|
@@ -7684,6 +7759,846 @@ function _pushable(getNext, options) {
|
|
|
7684
7759
|
};
|
|
7685
7760
|
return pushable;
|
|
7686
7761
|
}
|
|
7762
|
+
// packages/agent/src/mcp/waitForMcpLogin.ts
|
|
7763
|
+
var DEFAULT_LOGIN_WAIT = { intervalMs: 2000, timeoutMs: 180000 };
|
|
7764
|
+
async function waitForMcpLogin(fetchStatus, serverName, { intervalMs, timeoutMs } = DEFAULT_LOGIN_WAIT) {
|
|
7765
|
+
const deadline = Date.now() + timeoutMs;
|
|
7766
|
+
let servers = await fetchStatus();
|
|
7767
|
+
while (Date.now() < deadline && isAwaitingLogin(servers, serverName)) {
|
|
7768
|
+
await Bun.sleep(intervalMs);
|
|
7769
|
+
servers = await fetchStatus();
|
|
7770
|
+
}
|
|
7771
|
+
return servers;
|
|
7772
|
+
}
|
|
7773
|
+
var isAwaitingLogin = (servers, serverName) => servers.some((server) => server.name === serverName && server.status === "needs-auth");
|
|
7774
|
+
|
|
7775
|
+
// node_modules/.bun/open@11.0.4/node_modules/open/index.js
|
|
7776
|
+
import process9 from "process";
|
|
7777
|
+
import path2 from "path";
|
|
7778
|
+
import { fileURLToPath } from "url";
|
|
7779
|
+
import childProcess3 from "child_process";
|
|
7780
|
+
import fs5, { constants as fsConstants2 } from "fs/promises";
|
|
7781
|
+
|
|
7782
|
+
// node_modules/.bun/wsl-utils@1.0.1/node_modules/wsl-utils/index.js
|
|
7783
|
+
import path from "path";
|
|
7784
|
+
import { promisify as promisify2 } from "util";
|
|
7785
|
+
import childProcess2 from "child_process";
|
|
7786
|
+
import fs4, { constants as fsConstants } from "fs/promises";
|
|
7787
|
+
|
|
7788
|
+
// node_modules/.bun/is-wsl@3.1.1/node_modules/is-wsl/index.js
|
|
7789
|
+
import process2 from "process";
|
|
7790
|
+
import os from "os";
|
|
7791
|
+
import fs3 from "fs";
|
|
7792
|
+
|
|
7793
|
+
// node_modules/.bun/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
7794
|
+
import fs2 from "fs";
|
|
7795
|
+
|
|
7796
|
+
// node_modules/.bun/is-docker@3.0.0/node_modules/is-docker/index.js
|
|
7797
|
+
import fs from "fs";
|
|
7798
|
+
var isDockerCached;
|
|
7799
|
+
function hasDockerEnv() {
|
|
7800
|
+
try {
|
|
7801
|
+
fs.statSync("/.dockerenv");
|
|
7802
|
+
return true;
|
|
7803
|
+
} catch {
|
|
7804
|
+
return false;
|
|
7805
|
+
}
|
|
7806
|
+
}
|
|
7807
|
+
function hasDockerCGroup() {
|
|
7808
|
+
try {
|
|
7809
|
+
return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
7810
|
+
} catch {
|
|
7811
|
+
return false;
|
|
7812
|
+
}
|
|
7813
|
+
}
|
|
7814
|
+
function isDocker() {
|
|
7815
|
+
if (isDockerCached === undefined) {
|
|
7816
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
7817
|
+
}
|
|
7818
|
+
return isDockerCached;
|
|
7819
|
+
}
|
|
7820
|
+
|
|
7821
|
+
// node_modules/.bun/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
7822
|
+
var cachedResult;
|
|
7823
|
+
var hasContainerEnv = () => {
|
|
7824
|
+
try {
|
|
7825
|
+
fs2.statSync("/run/.containerenv");
|
|
7826
|
+
return true;
|
|
7827
|
+
} catch {
|
|
7828
|
+
return false;
|
|
7829
|
+
}
|
|
7830
|
+
};
|
|
7831
|
+
function isInsideContainer() {
|
|
7832
|
+
if (cachedResult === undefined) {
|
|
7833
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
7834
|
+
}
|
|
7835
|
+
return cachedResult;
|
|
7836
|
+
}
|
|
7837
|
+
|
|
7838
|
+
// node_modules/.bun/is-wsl@3.1.1/node_modules/is-wsl/index.js
|
|
7839
|
+
var isWsl = () => {
|
|
7840
|
+
if (process2.platform !== "linux") {
|
|
7841
|
+
return false;
|
|
7842
|
+
}
|
|
7843
|
+
if (os.release().toLowerCase().includes("microsoft")) {
|
|
7844
|
+
if (isInsideContainer()) {
|
|
7845
|
+
return false;
|
|
7846
|
+
}
|
|
7847
|
+
return true;
|
|
7848
|
+
}
|
|
7849
|
+
try {
|
|
7850
|
+
if (fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
7851
|
+
return !isInsideContainer();
|
|
7852
|
+
}
|
|
7853
|
+
} catch {}
|
|
7854
|
+
if (fs3.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs3.existsSync("/run/WSL")) {
|
|
7855
|
+
return !isInsideContainer();
|
|
7856
|
+
}
|
|
7857
|
+
return false;
|
|
7858
|
+
};
|
|
7859
|
+
var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
7860
|
+
|
|
7861
|
+
// node_modules/.bun/powershell-utils@0.2.1/node_modules/powershell-utils/index.js
|
|
7862
|
+
import process3 from "process";
|
|
7863
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
7864
|
+
import { promisify } from "util";
|
|
7865
|
+
import childProcess from "child_process";
|
|
7866
|
+
var execFile = promisify(childProcess.execFile);
|
|
7867
|
+
var powerShellPath = () => `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
7868
|
+
var argumentsPrefix = [
|
|
7869
|
+
"-NoProfile",
|
|
7870
|
+
"-NonInteractive",
|
|
7871
|
+
"-ExecutionPolicy",
|
|
7872
|
+
"Bypass",
|
|
7873
|
+
"-EncodedCommand"
|
|
7874
|
+
];
|
|
7875
|
+
var encodeCommand = (command) => Buffer2.from(command, "utf16le").toString("base64");
|
|
7876
|
+
var escapeArgument = (value) => `'${String(value).replaceAll(/['\u2018\u2019\u201A\u201B]/g, (match) => match + match)}'`;
|
|
7877
|
+
var createArguments = (command) => [...argumentsPrefix, encodeCommand(command)];
|
|
7878
|
+
var createExecFileOptions = (options) => ({
|
|
7879
|
+
encoding: "utf8",
|
|
7880
|
+
...options,
|
|
7881
|
+
shell: false
|
|
7882
|
+
});
|
|
7883
|
+
var executePowerShell = async (command, options = {}) => {
|
|
7884
|
+
const {
|
|
7885
|
+
powerShellPath: psPath,
|
|
7886
|
+
...execFileOptions
|
|
7887
|
+
} = options;
|
|
7888
|
+
return execFile(psPath ?? powerShellPath(), createArguments(command), createExecFileOptions(execFileOptions));
|
|
7889
|
+
};
|
|
7890
|
+
executePowerShell.argumentsPrefix = argumentsPrefix;
|
|
7891
|
+
executePowerShell.encodeCommand = encodeCommand;
|
|
7892
|
+
executePowerShell.escapeArgument = escapeArgument;
|
|
7893
|
+
executePowerShell.createArguments = createArguments;
|
|
7894
|
+
|
|
7895
|
+
// node_modules/.bun/wsl-utils@1.0.1/node_modules/wsl-utils/utilities.js
|
|
7896
|
+
function parseMountPointFromConfig(content) {
|
|
7897
|
+
for (const line of content.split(`
|
|
7898
|
+
`)) {
|
|
7899
|
+
if (/^\s*#/.test(line)) {
|
|
7900
|
+
continue;
|
|
7901
|
+
}
|
|
7902
|
+
const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
|
|
7903
|
+
if (!match) {
|
|
7904
|
+
continue;
|
|
7905
|
+
}
|
|
7906
|
+
return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
|
|
7907
|
+
}
|
|
7908
|
+
}
|
|
7909
|
+
|
|
7910
|
+
// node_modules/.bun/wsl-utils@1.0.1/node_modules/wsl-utils/index.js
|
|
7911
|
+
var execFile2 = promisify2(childProcess2.execFile);
|
|
7912
|
+
var wslDrivesMountPoint = (() => {
|
|
7913
|
+
const defaultMountPoint = "/mnt/";
|
|
7914
|
+
let mountPoint;
|
|
7915
|
+
return async function() {
|
|
7916
|
+
if (mountPoint) {
|
|
7917
|
+
return mountPoint;
|
|
7918
|
+
}
|
|
7919
|
+
const configFilePath = "/etc/wsl.conf";
|
|
7920
|
+
let isConfigFileExists = false;
|
|
7921
|
+
try {
|
|
7922
|
+
await fs4.access(configFilePath, fsConstants.F_OK);
|
|
7923
|
+
isConfigFileExists = true;
|
|
7924
|
+
} catch {}
|
|
7925
|
+
if (!isConfigFileExists) {
|
|
7926
|
+
return defaultMountPoint;
|
|
7927
|
+
}
|
|
7928
|
+
const configContent = await fs4.readFile(configFilePath, { encoding: "utf8" });
|
|
7929
|
+
const parsedMountPoint = parseMountPointFromConfig(configContent);
|
|
7930
|
+
if (parsedMountPoint === undefined) {
|
|
7931
|
+
return defaultMountPoint;
|
|
7932
|
+
}
|
|
7933
|
+
mountPoint = parsedMountPoint;
|
|
7934
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
7935
|
+
return mountPoint;
|
|
7936
|
+
};
|
|
7937
|
+
})();
|
|
7938
|
+
var powerShellPathFromWsl = async () => {
|
|
7939
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
7940
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
7941
|
+
};
|
|
7942
|
+
var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
|
|
7943
|
+
var canAccessPowerShellPromise;
|
|
7944
|
+
var canAccessPowerShell = async () => {
|
|
7945
|
+
canAccessPowerShellPromise ??= (async () => {
|
|
7946
|
+
try {
|
|
7947
|
+
const psPath = await powerShellPath2();
|
|
7948
|
+
await fs4.access(psPath, fsConstants.X_OK);
|
|
7949
|
+
return true;
|
|
7950
|
+
} catch {
|
|
7951
|
+
return false;
|
|
7952
|
+
}
|
|
7953
|
+
})();
|
|
7954
|
+
return canAccessPowerShellPromise;
|
|
7955
|
+
};
|
|
7956
|
+
var wslDefaultBrowser = async () => {
|
|
7957
|
+
const psPath = await powerShellPath2();
|
|
7958
|
+
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
7959
|
+
const { stdout } = await executePowerShell(command, {
|
|
7960
|
+
powerShellPath: psPath,
|
|
7961
|
+
cwd: path.dirname(psPath)
|
|
7962
|
+
});
|
|
7963
|
+
return stdout.trim();
|
|
7964
|
+
};
|
|
7965
|
+
var isUrl = (path2) => /^[a-z]+:\/\//i.test(path2);
|
|
7966
|
+
var convertPath = async (flag, path2) => {
|
|
7967
|
+
const wslpathArguments = path2.startsWith("-") ? [flag, "--", path2] : [flag, path2];
|
|
7968
|
+
try {
|
|
7969
|
+
const { stdout } = await execFile2("wslpath", wslpathArguments, { encoding: "utf8" });
|
|
7970
|
+
return stdout.replace(/\r?\n$/, "") || path2;
|
|
7971
|
+
} catch {
|
|
7972
|
+
return path2;
|
|
7973
|
+
}
|
|
7974
|
+
};
|
|
7975
|
+
var convertWslPathToWindows = async (paths) => {
|
|
7976
|
+
const isBatch = Array.isArray(paths);
|
|
7977
|
+
const pathArray = isBatch ? paths : [paths];
|
|
7978
|
+
const results = await Promise.all(pathArray.map((path2) => isUrl(path2) ? path2 : convertPath("-aw", path2)));
|
|
7979
|
+
return isBatch ? results : results[0];
|
|
7980
|
+
};
|
|
7981
|
+
|
|
7982
|
+
// node_modules/.bun/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
|
|
7983
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
7984
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
7985
|
+
Object.defineProperty(object, propertyName, {
|
|
7986
|
+
configurable: true,
|
|
7987
|
+
enumerable: true,
|
|
7988
|
+
get() {
|
|
7989
|
+
const result = valueGetter();
|
|
7990
|
+
define(result);
|
|
7991
|
+
return result;
|
|
7992
|
+
},
|
|
7993
|
+
set(value) {
|
|
7994
|
+
define(value);
|
|
7995
|
+
}
|
|
7996
|
+
});
|
|
7997
|
+
return object;
|
|
7998
|
+
}
|
|
7999
|
+
|
|
8000
|
+
// node_modules/.bun/default-browser@5.5.1/node_modules/default-browser/index.js
|
|
8001
|
+
import { promisify as promisify6 } from "util";
|
|
8002
|
+
import process7 from "process";
|
|
8003
|
+
import { execFile as execFile6 } from "child_process";
|
|
8004
|
+
|
|
8005
|
+
// node_modules/.bun/default-browser-id@5.0.1/node_modules/default-browser-id/index.js
|
|
8006
|
+
import { promisify as promisify3 } from "util";
|
|
8007
|
+
import process4 from "process";
|
|
8008
|
+
import { execFile as execFile3 } from "child_process";
|
|
8009
|
+
var execFileAsync = promisify3(execFile3);
|
|
8010
|
+
async function defaultBrowserId() {
|
|
8011
|
+
if (process4.platform !== "darwin") {
|
|
8012
|
+
throw new Error("macOS only");
|
|
8013
|
+
}
|
|
8014
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
8015
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
8016
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
8017
|
+
if (browserId === "com.apple.safari") {
|
|
8018
|
+
return "com.apple.Safari";
|
|
8019
|
+
}
|
|
8020
|
+
return browserId;
|
|
8021
|
+
}
|
|
8022
|
+
|
|
8023
|
+
// node_modules/.bun/run-applescript@7.1.0/node_modules/run-applescript/index.js
|
|
8024
|
+
import process5 from "process";
|
|
8025
|
+
import { promisify as promisify4 } from "util";
|
|
8026
|
+
import { execFile as execFile4, execFileSync } from "child_process";
|
|
8027
|
+
var execFileAsync2 = promisify4(execFile4);
|
|
8028
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
8029
|
+
if (process5.platform !== "darwin") {
|
|
8030
|
+
throw new Error("macOS only");
|
|
8031
|
+
}
|
|
8032
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
8033
|
+
const execOptions = {};
|
|
8034
|
+
if (signal) {
|
|
8035
|
+
execOptions.signal = signal;
|
|
8036
|
+
}
|
|
8037
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
8038
|
+
return stdout.trim();
|
|
8039
|
+
}
|
|
8040
|
+
|
|
8041
|
+
// node_modules/.bun/bundle-name@4.1.1/node_modules/bundle-name/index.js
|
|
8042
|
+
var bundleIdentifierPattern = /^[^\n\r"\\]+$/u;
|
|
8043
|
+
async function bundleName(bundleId) {
|
|
8044
|
+
if (typeof bundleId !== "string") {
|
|
8045
|
+
throw new TypeError("Expected a string bundle identifier");
|
|
8046
|
+
}
|
|
8047
|
+
if (!bundleIdentifierPattern.test(bundleId)) {
|
|
8048
|
+
throw new TypeError(`Invalid bundle identifier: ${JSON.stringify(bundleId)}`);
|
|
8049
|
+
}
|
|
8050
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
8051
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
8052
|
+
}
|
|
8053
|
+
|
|
8054
|
+
// node_modules/.bun/default-browser@5.5.1/node_modules/default-browser/windows.js
|
|
8055
|
+
import process6 from "process";
|
|
8056
|
+
import { promisify as promisify5 } from "util";
|
|
8057
|
+
import { execFile as execFile5 } from "child_process";
|
|
8058
|
+
var execFileAsync3 = promisify5(execFile5);
|
|
8059
|
+
var windowsBrowserProgIds = {
|
|
8060
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
8061
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
8062
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
8063
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
8064
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
8065
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
8066
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
8067
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
8068
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
8069
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
8070
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
8071
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
8072
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
8073
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
8074
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
8075
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
8076
|
+
};
|
|
8077
|
+
var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
8078
|
+
|
|
8079
|
+
class UnknownBrowserError extends Error {
|
|
8080
|
+
}
|
|
8081
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
8082
|
+
const regPath = `${process6.env.SYSTEMROOT ?? process6.env.windir ?? "C:\\Windows"}\\System32\\reg.exe`;
|
|
8083
|
+
const { stdout } = await _execFileAsync(regPath, [
|
|
8084
|
+
"QUERY",
|
|
8085
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
8086
|
+
"/v",
|
|
8087
|
+
"ProgId"
|
|
8088
|
+
]);
|
|
8089
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
8090
|
+
if (!match) {
|
|
8091
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
8092
|
+
}
|
|
8093
|
+
const { id } = match.groups;
|
|
8094
|
+
const dotIndex = id.lastIndexOf(".");
|
|
8095
|
+
const hyphenIndex = id.lastIndexOf("-");
|
|
8096
|
+
const baseIdByDot = dotIndex === -1 ? undefined : id.slice(0, dotIndex);
|
|
8097
|
+
const baseIdByHyphen = hyphenIndex === -1 ? undefined : id.slice(0, hyphenIndex);
|
|
8098
|
+
return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
|
|
8099
|
+
}
|
|
8100
|
+
|
|
8101
|
+
// node_modules/.bun/default-browser@5.5.1/node_modules/default-browser/index.js
|
|
8102
|
+
var execFileAsync4 = promisify6(execFile6);
|
|
8103
|
+
var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
8104
|
+
async function defaultBrowser2() {
|
|
8105
|
+
if (process7.platform === "darwin") {
|
|
8106
|
+
const id = await defaultBrowserId();
|
|
8107
|
+
const name = await bundleName(id);
|
|
8108
|
+
return { name, id };
|
|
8109
|
+
}
|
|
8110
|
+
if (process7.platform === "linux") {
|
|
8111
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
8112
|
+
const id = stdout.trim();
|
|
8113
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
8114
|
+
return { name, id };
|
|
8115
|
+
}
|
|
8116
|
+
if (process7.platform === "win32") {
|
|
8117
|
+
return defaultBrowser();
|
|
8118
|
+
}
|
|
8119
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
8120
|
+
}
|
|
8121
|
+
|
|
8122
|
+
// node_modules/.bun/is-in-ssh@1.0.0/node_modules/is-in-ssh/index.js
|
|
8123
|
+
import process8 from "process";
|
|
8124
|
+
var isInSsh = Boolean(process8.env.SSH_CONNECTION || process8.env.SSH_CLIENT || process8.env.SSH_TTY);
|
|
8125
|
+
var is_in_ssh_default = isInSsh;
|
|
8126
|
+
|
|
8127
|
+
// node_modules/.bun/open@11.0.4/node_modules/open/index.js
|
|
8128
|
+
var fallbackAttemptSymbol = Symbol("fallbackAttempt");
|
|
8129
|
+
var __dirname2 = import.meta.url ? path2.dirname(fileURLToPath(import.meta.url)) : "";
|
|
8130
|
+
var localXdgOpenPath = path2.join(__dirname2, "xdg-open");
|
|
8131
|
+
var { platform, arch } = process9;
|
|
8132
|
+
var tryEachApp = async (apps, opener) => {
|
|
8133
|
+
if (apps.length === 0) {
|
|
8134
|
+
return;
|
|
8135
|
+
}
|
|
8136
|
+
const errors = [];
|
|
8137
|
+
for (const app of apps) {
|
|
8138
|
+
try {
|
|
8139
|
+
return await opener(app);
|
|
8140
|
+
} catch (error) {
|
|
8141
|
+
errors.push(error);
|
|
8142
|
+
}
|
|
8143
|
+
}
|
|
8144
|
+
throw new AggregateError(errors, "Failed to open in all supported apps");
|
|
8145
|
+
};
|
|
8146
|
+
var baseOpen = async (options) => {
|
|
8147
|
+
options = {
|
|
8148
|
+
wait: false,
|
|
8149
|
+
background: false,
|
|
8150
|
+
newInstance: false,
|
|
8151
|
+
allowNonzeroExitCode: false,
|
|
8152
|
+
...options
|
|
8153
|
+
};
|
|
8154
|
+
const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
|
|
8155
|
+
delete options[fallbackAttemptSymbol];
|
|
8156
|
+
if (Array.isArray(options.app)) {
|
|
8157
|
+
return tryEachApp(options.app, (singleApp) => baseOpen({
|
|
8158
|
+
...options,
|
|
8159
|
+
app: singleApp,
|
|
8160
|
+
[fallbackAttemptSymbol]: true
|
|
8161
|
+
}));
|
|
8162
|
+
}
|
|
8163
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
8164
|
+
appArguments = [...appArguments];
|
|
8165
|
+
if (Array.isArray(app)) {
|
|
8166
|
+
return tryEachApp(app, (appName) => baseOpen({
|
|
8167
|
+
...options,
|
|
8168
|
+
app: {
|
|
8169
|
+
name: appName,
|
|
8170
|
+
arguments: appArguments
|
|
8171
|
+
},
|
|
8172
|
+
[fallbackAttemptSymbol]: true
|
|
8173
|
+
}));
|
|
8174
|
+
}
|
|
8175
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
8176
|
+
const ids = {
|
|
8177
|
+
"com.google.chrome": "chrome",
|
|
8178
|
+
"google-chrome.desktop": "chrome",
|
|
8179
|
+
"com.brave.browser": "brave",
|
|
8180
|
+
"org.mozilla.firefox": "firefox",
|
|
8181
|
+
"firefox.desktop": "firefox",
|
|
8182
|
+
"com.microsoft.msedge": "edge",
|
|
8183
|
+
"com.microsoft.edge": "edge",
|
|
8184
|
+
"com.microsoft.edgemac": "edge",
|
|
8185
|
+
"microsoft-edge.desktop": "edge",
|
|
8186
|
+
"com.apple.safari": "safari"
|
|
8187
|
+
};
|
|
8188
|
+
const flags = {
|
|
8189
|
+
chrome: "--incognito",
|
|
8190
|
+
brave: "--incognito",
|
|
8191
|
+
firefox: "--private-window",
|
|
8192
|
+
edge: "--inPrivate"
|
|
8193
|
+
};
|
|
8194
|
+
let browser;
|
|
8195
|
+
if (is_wsl_default) {
|
|
8196
|
+
const progId = await wslDefaultBrowser();
|
|
8197
|
+
const browserInfo = _windowsBrowserProgIdMap.get(progId);
|
|
8198
|
+
browser = browserInfo ?? {};
|
|
8199
|
+
} else {
|
|
8200
|
+
browser = await defaultBrowser2();
|
|
8201
|
+
}
|
|
8202
|
+
const browserId = browser.id?.toLowerCase();
|
|
8203
|
+
if (Object.hasOwn(ids, browserId)) {
|
|
8204
|
+
const browserName = ids[browserId];
|
|
8205
|
+
if (app === "browserPrivate") {
|
|
8206
|
+
if (browserName === "safari") {
|
|
8207
|
+
throw new Error("Safari doesn't support opening in private mode via command line");
|
|
8208
|
+
}
|
|
8209
|
+
appArguments.push(flags[browserName]);
|
|
8210
|
+
}
|
|
8211
|
+
return baseOpen({
|
|
8212
|
+
...options,
|
|
8213
|
+
app: {
|
|
8214
|
+
name: apps[browserName],
|
|
8215
|
+
arguments: appArguments
|
|
8216
|
+
}
|
|
8217
|
+
});
|
|
8218
|
+
}
|
|
8219
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
8220
|
+
}
|
|
8221
|
+
let command;
|
|
8222
|
+
const cliArguments = [];
|
|
8223
|
+
const childProcessOptions = {};
|
|
8224
|
+
let shouldUseWindowsInWsl = false;
|
|
8225
|
+
if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
|
|
8226
|
+
shouldUseWindowsInWsl = await canAccessPowerShell();
|
|
8227
|
+
}
|
|
8228
|
+
if (platform === "darwin") {
|
|
8229
|
+
command = "open";
|
|
8230
|
+
if (options.wait) {
|
|
8231
|
+
cliArguments.push("--wait-apps");
|
|
8232
|
+
}
|
|
8233
|
+
if (options.background) {
|
|
8234
|
+
cliArguments.push("--background");
|
|
8235
|
+
}
|
|
8236
|
+
if (options.newInstance) {
|
|
8237
|
+
cliArguments.push("--new");
|
|
8238
|
+
}
|
|
8239
|
+
if (app) {
|
|
8240
|
+
cliArguments.push("-a", app);
|
|
8241
|
+
}
|
|
8242
|
+
} else if (platform === "win32" || shouldUseWindowsInWsl) {
|
|
8243
|
+
command = await powerShellPath2();
|
|
8244
|
+
cliArguments.push(...executePowerShell.argumentsPrefix);
|
|
8245
|
+
if (!is_wsl_default) {
|
|
8246
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
8247
|
+
}
|
|
8248
|
+
if (is_wsl_default && options.target) {
|
|
8249
|
+
options.target = await convertWslPathToWindows(options.target);
|
|
8250
|
+
}
|
|
8251
|
+
const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
|
|
8252
|
+
if (options.wait) {
|
|
8253
|
+
encodedArguments.push("-Wait");
|
|
8254
|
+
}
|
|
8255
|
+
if (app) {
|
|
8256
|
+
encodedArguments.push(executePowerShell.escapeArgument(app));
|
|
8257
|
+
if (options.target) {
|
|
8258
|
+
appArguments.push(options.target);
|
|
8259
|
+
}
|
|
8260
|
+
} else if (options.target) {
|
|
8261
|
+
encodedArguments.push(executePowerShell.escapeArgument(options.target));
|
|
8262
|
+
}
|
|
8263
|
+
if (appArguments.length > 0) {
|
|
8264
|
+
appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
|
|
8265
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
8266
|
+
}
|
|
8267
|
+
options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
|
|
8268
|
+
if (!options.wait) {
|
|
8269
|
+
childProcessOptions.stdio = "ignore";
|
|
8270
|
+
}
|
|
8271
|
+
if (is_wsl_default) {
|
|
8272
|
+
childProcessOptions.cwd = path2.dirname(command);
|
|
8273
|
+
}
|
|
8274
|
+
} else {
|
|
8275
|
+
if (app) {
|
|
8276
|
+
command = app;
|
|
8277
|
+
} else {
|
|
8278
|
+
const isBundled = !__dirname2 || __dirname2 === "/";
|
|
8279
|
+
let exeLocalXdgOpen = false;
|
|
8280
|
+
try {
|
|
8281
|
+
await fs5.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
8282
|
+
exeLocalXdgOpen = true;
|
|
8283
|
+
} catch {}
|
|
8284
|
+
const useSystemXdgOpen = process9.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
8285
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
8286
|
+
}
|
|
8287
|
+
if (appArguments.length > 0) {
|
|
8288
|
+
cliArguments.push(...appArguments);
|
|
8289
|
+
}
|
|
8290
|
+
if (!options.wait) {
|
|
8291
|
+
childProcessOptions.stdio = "ignore";
|
|
8292
|
+
childProcessOptions.detached = true;
|
|
8293
|
+
}
|
|
8294
|
+
}
|
|
8295
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
8296
|
+
cliArguments.push("--args", ...appArguments);
|
|
8297
|
+
}
|
|
8298
|
+
if (options.target) {
|
|
8299
|
+
cliArguments.push(options.target);
|
|
8300
|
+
}
|
|
8301
|
+
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
8302
|
+
if (options.wait) {
|
|
8303
|
+
return new Promise((resolve, reject) => {
|
|
8304
|
+
subprocess.once("error", reject);
|
|
8305
|
+
subprocess.once("close", (exitCode) => {
|
|
8306
|
+
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
8307
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
8308
|
+
return;
|
|
8309
|
+
}
|
|
8310
|
+
resolve(subprocess);
|
|
8311
|
+
});
|
|
8312
|
+
});
|
|
8313
|
+
}
|
|
8314
|
+
if (isFallbackAttempt || platform === "win32" || shouldUseWindowsInWsl) {
|
|
8315
|
+
return new Promise((resolve, reject) => {
|
|
8316
|
+
subprocess.once("error", reject);
|
|
8317
|
+
subprocess.once("spawn", () => {
|
|
8318
|
+
subprocess.once("close", (exitCode) => {
|
|
8319
|
+
subprocess.off("error", reject);
|
|
8320
|
+
if (isFallbackAttempt && exitCode !== 0) {
|
|
8321
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
8322
|
+
return;
|
|
8323
|
+
}
|
|
8324
|
+
subprocess.unref();
|
|
8325
|
+
resolve(subprocess);
|
|
8326
|
+
});
|
|
8327
|
+
});
|
|
8328
|
+
});
|
|
8329
|
+
}
|
|
8330
|
+
subprocess.unref();
|
|
8331
|
+
return new Promise((resolve, reject) => {
|
|
8332
|
+
subprocess.once("error", reject);
|
|
8333
|
+
subprocess.once("spawn", () => {
|
|
8334
|
+
subprocess.off("error", reject);
|
|
8335
|
+
resolve(subprocess);
|
|
8336
|
+
});
|
|
8337
|
+
});
|
|
8338
|
+
};
|
|
8339
|
+
var open2 = (target, options) => {
|
|
8340
|
+
if (typeof target !== "string") {
|
|
8341
|
+
throw new TypeError("Expected a `target`");
|
|
8342
|
+
}
|
|
8343
|
+
return baseOpen({
|
|
8344
|
+
...options,
|
|
8345
|
+
target
|
|
8346
|
+
});
|
|
8347
|
+
};
|
|
8348
|
+
function detectArchBinary(binary) {
|
|
8349
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
8350
|
+
return binary;
|
|
8351
|
+
}
|
|
8352
|
+
const { [arch]: archBinary } = binary;
|
|
8353
|
+
if (!archBinary) {
|
|
8354
|
+
throw new Error(`${arch} is not supported`);
|
|
8355
|
+
}
|
|
8356
|
+
return archBinary;
|
|
8357
|
+
}
|
|
8358
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
|
|
8359
|
+
if (wsl && is_wsl_default) {
|
|
8360
|
+
return detectArchBinary(wsl);
|
|
8361
|
+
}
|
|
8362
|
+
if (!platformBinary) {
|
|
8363
|
+
throw new Error(`${platform} is not supported`);
|
|
8364
|
+
}
|
|
8365
|
+
return detectArchBinary(platformBinary);
|
|
8366
|
+
}
|
|
8367
|
+
var apps = {
|
|
8368
|
+
browser: "browser",
|
|
8369
|
+
browserPrivate: "browserPrivate"
|
|
8370
|
+
};
|
|
8371
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
8372
|
+
darwin: "google chrome",
|
|
8373
|
+
win32: "chrome",
|
|
8374
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
|
|
8375
|
+
}, {
|
|
8376
|
+
wsl: {
|
|
8377
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
8378
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
8379
|
+
}
|
|
8380
|
+
}));
|
|
8381
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
8382
|
+
darwin: "brave browser",
|
|
8383
|
+
win32: "brave",
|
|
8384
|
+
linux: ["brave-browser", "brave"]
|
|
8385
|
+
}, {
|
|
8386
|
+
wsl: {
|
|
8387
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
8388
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
8389
|
+
}
|
|
8390
|
+
}));
|
|
8391
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
8392
|
+
darwin: "firefox",
|
|
8393
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
8394
|
+
linux: "firefox"
|
|
8395
|
+
}, {
|
|
8396
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
8397
|
+
}));
|
|
8398
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
8399
|
+
darwin: "microsoft edge",
|
|
8400
|
+
win32: "msedge",
|
|
8401
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
8402
|
+
}, {
|
|
8403
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
8404
|
+
}));
|
|
8405
|
+
defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
8406
|
+
darwin: "Safari"
|
|
8407
|
+
}));
|
|
8408
|
+
var open_default = open2;
|
|
8409
|
+
|
|
8410
|
+
// packages/agent/src/system/openBrowser.ts
|
|
8411
|
+
var openBrowser = (url) => open_default(url).catch(() => {
|
|
8412
|
+
return;
|
|
8413
|
+
});
|
|
8414
|
+
|
|
8415
|
+
// packages/agent/src/permissions/sanitizeText.ts
|
|
8416
|
+
var isControlCode = (code) => code < 32 || code >= 127 && code <= 159;
|
|
8417
|
+
var sanitizeText = (text) => [...String(text ?? "")].map((char) => isControlCode(char.charCodeAt(0)) ? " " : char).join("");
|
|
8418
|
+
|
|
8419
|
+
// packages/agent/src/permissions/elicitationForm.ts
|
|
8420
|
+
var SKIP_LABEL = "Skip";
|
|
8421
|
+
var ACCEPT_LABEL = "Accept";
|
|
8422
|
+
var DECLINE_LABEL = "Decline";
|
|
8423
|
+
var YES_LABEL = "Yes";
|
|
8424
|
+
var NO_LABEL = "No";
|
|
8425
|
+
var isSchema = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8426
|
+
var readList = (value) => Array.isArray(value) ? value : [];
|
|
8427
|
+
var toChoice = (entry) => {
|
|
8428
|
+
if (typeof entry === "string")
|
|
8429
|
+
return { value: entry, label: sanitizeText(entry) };
|
|
8430
|
+
if (!isSchema(entry) || typeof entry.const !== "string")
|
|
8431
|
+
return;
|
|
8432
|
+
const label = typeof entry.title === "string" ? entry.title : entry.const;
|
|
8433
|
+
return { value: entry.const, label: sanitizeText(label) };
|
|
8434
|
+
};
|
|
8435
|
+
var readChoices = (field) => {
|
|
8436
|
+
const source = isSchema(field.items) ? field.items : field;
|
|
8437
|
+
const entries = [...readList(source.oneOf), ...readList(source.anyOf), ...readList(source.enum)];
|
|
8438
|
+
return entries.flatMap((entry) => toChoice(entry) ?? []);
|
|
8439
|
+
};
|
|
8440
|
+
var readKind = (field, choices) => {
|
|
8441
|
+
if (field.type === "array")
|
|
8442
|
+
return "multi";
|
|
8443
|
+
if (choices.length > 0)
|
|
8444
|
+
return "choice";
|
|
8445
|
+
if (field.type === "boolean")
|
|
8446
|
+
return "boolean";
|
|
8447
|
+
return field.type === "number" || field.type === "integer" ? "number" : "text";
|
|
8448
|
+
};
|
|
8449
|
+
var readOptions = (kind, choices) => {
|
|
8450
|
+
const labelled = (labels) => labels.map((label) => ({ label, description: "" }));
|
|
8451
|
+
if (kind === "boolean")
|
|
8452
|
+
return labelled([YES_LABEL, NO_LABEL]);
|
|
8453
|
+
return labelled(choices.length > 0 ? choices.map(({ label }) => label) : [SKIP_LABEL]);
|
|
8454
|
+
};
|
|
8455
|
+
var buildQuestionText = (key, field, message) => {
|
|
8456
|
+
const title = sanitizeText(typeof field.title === "string" ? field.title : key);
|
|
8457
|
+
const description = typeof field.description === "string" ? ` (${sanitizeText(field.description)})` : "";
|
|
8458
|
+
return `${message}${title}${description}`;
|
|
8459
|
+
};
|
|
8460
|
+
var buildConfirmForm = (header, message) => ({
|
|
8461
|
+
fields: [],
|
|
8462
|
+
questions: [
|
|
8463
|
+
{
|
|
8464
|
+
header,
|
|
8465
|
+
question: message,
|
|
8466
|
+
options: [
|
|
8467
|
+
{ label: ACCEPT_LABEL, description: "" },
|
|
8468
|
+
{ label: DECLINE_LABEL, description: "" }
|
|
8469
|
+
]
|
|
8470
|
+
}
|
|
8471
|
+
]
|
|
8472
|
+
});
|
|
8473
|
+
function buildElicitationForm(serverName, message, requestedSchema) {
|
|
8474
|
+
const header = sanitizeText(serverName);
|
|
8475
|
+
const properties = isSchema(requestedSchema?.properties) ? requestedSchema.properties : {};
|
|
8476
|
+
const entries = Object.entries(properties).filter((entry) => isSchema(entry[1]));
|
|
8477
|
+
if (entries.length === 0)
|
|
8478
|
+
return buildConfirmForm(header, sanitizeText(message));
|
|
8479
|
+
const fields = [];
|
|
8480
|
+
const questions = [];
|
|
8481
|
+
for (const [key, field] of entries) {
|
|
8482
|
+
const choices = readChoices(field);
|
|
8483
|
+
const kind = readKind(field, choices);
|
|
8484
|
+
const intro = fields.length === 0 ? `${sanitizeText(message)} \u2014 ` : "";
|
|
8485
|
+
const question = buildQuestionText(key, field, intro);
|
|
8486
|
+
fields.push({ key, question, kind, choices });
|
|
8487
|
+
questions.push({
|
|
8488
|
+
header,
|
|
8489
|
+
question,
|
|
8490
|
+
multiSelect: kind === "multi",
|
|
8491
|
+
options: readOptions(kind, choices)
|
|
8492
|
+
});
|
|
8493
|
+
}
|
|
8494
|
+
return { fields, questions };
|
|
8495
|
+
}
|
|
8496
|
+
var readChoiceValue = (choices, label) => choices.find((choice) => choice.label === label)?.value ?? label;
|
|
8497
|
+
var readFieldValue = ({ kind, choices }, answer) => {
|
|
8498
|
+
if (kind === "boolean")
|
|
8499
|
+
return answer === YES_LABEL;
|
|
8500
|
+
if (kind === "number")
|
|
8501
|
+
return Number.isFinite(Number(answer)) ? Number(answer) : undefined;
|
|
8502
|
+
if (kind === "choice")
|
|
8503
|
+
return readChoiceValue(choices, answer);
|
|
8504
|
+
if (kind === "multi")
|
|
8505
|
+
return answer.split(", ").map((label) => readChoiceValue(choices, label));
|
|
8506
|
+
return answer;
|
|
8507
|
+
};
|
|
8508
|
+
function buildElicitationContent(form, answers) {
|
|
8509
|
+
const content = {};
|
|
8510
|
+
for (const field of form.fields) {
|
|
8511
|
+
const answer = answers[field.question]?.trim();
|
|
8512
|
+
if (!answer || answer === SKIP_LABEL)
|
|
8513
|
+
continue;
|
|
8514
|
+
const value = readFieldValue(field, answer);
|
|
8515
|
+
if (value !== undefined)
|
|
8516
|
+
content[field.key] = value;
|
|
8517
|
+
}
|
|
8518
|
+
return content;
|
|
8519
|
+
}
|
|
8520
|
+
var isConfirmAccepted = (form, answers) => form.fields.length > 0 || Object.values(answers).includes(ACCEPT_LABEL);
|
|
8521
|
+
|
|
8522
|
+
// packages/agent/src/permissions/elicitationGate.ts
|
|
8523
|
+
var ELICITATION_PREFIX = "elicitation:";
|
|
8524
|
+
var OPEN_BROWSER_LABEL = "Open in browser";
|
|
8525
|
+
var DECLINED = { action: "decline" };
|
|
8526
|
+
var isWebUrl = (url) => {
|
|
8527
|
+
try {
|
|
8528
|
+
return url !== undefined && /^https?:$/.test(new URL(url).protocol);
|
|
8529
|
+
} catch {
|
|
8530
|
+
return false;
|
|
8531
|
+
}
|
|
8532
|
+
};
|
|
8533
|
+
var buildUrlQuestion = ({ serverName, message, url }) => ({
|
|
8534
|
+
header: sanitizeText(serverName),
|
|
8535
|
+
question: `${sanitizeText(message)} ${sanitizeText(url)}`,
|
|
8536
|
+
options: [
|
|
8537
|
+
{ label: OPEN_BROWSER_LABEL, description: "" },
|
|
8538
|
+
{ label: "Decline", description: "" }
|
|
8539
|
+
]
|
|
8540
|
+
});
|
|
8541
|
+
|
|
8542
|
+
class ElicitationGate {
|
|
8543
|
+
agentSessionId;
|
|
8544
|
+
openUrl;
|
|
8545
|
+
pending = new Map;
|
|
8546
|
+
emit = () => {};
|
|
8547
|
+
constructor(agentSessionId, openUrl = openBrowser) {
|
|
8548
|
+
this.agentSessionId = agentSessionId;
|
|
8549
|
+
this.openUrl = openUrl;
|
|
8550
|
+
}
|
|
8551
|
+
listen(emit) {
|
|
8552
|
+
this.emit = emit;
|
|
8553
|
+
}
|
|
8554
|
+
handle = async (request, { signal, requestId }) => {
|
|
8555
|
+
if (request.mode === "url") {
|
|
8556
|
+
if (!isWebUrl(request.url))
|
|
8557
|
+
return DECLINED;
|
|
8558
|
+
return this.open(requestId, signal, [buildUrlQuestion(request)], (answers) => this.acceptUrl(request.url, answers));
|
|
8559
|
+
}
|
|
8560
|
+
const form = buildElicitationForm(request.serverName, request.message, request.requestedSchema);
|
|
8561
|
+
return this.open(requestId, signal, form.questions, (answers) => this.acceptForm(form, answers));
|
|
8562
|
+
};
|
|
8563
|
+
answer(toolUseId, answers) {
|
|
8564
|
+
const pending = this.pending.get(toolUseId);
|
|
8565
|
+
if (!pending)
|
|
8566
|
+
return false;
|
|
8567
|
+
this.pending.delete(toolUseId);
|
|
8568
|
+
const answered = Object.keys(answers).length > 0;
|
|
8569
|
+
pending.settle(answered ? pending.accept(answers) : DECLINED);
|
|
8570
|
+
this.emit({ type: "agent.question.resolved", toolUseId, answered });
|
|
8571
|
+
return true;
|
|
8572
|
+
}
|
|
8573
|
+
rejectAll() {
|
|
8574
|
+
for (const id of [...this.pending.keys()])
|
|
8575
|
+
this.answer(id, {});
|
|
8576
|
+
}
|
|
8577
|
+
acceptUrl(url, answers) {
|
|
8578
|
+
if (!Object.values(answers).includes(OPEN_BROWSER_LABEL))
|
|
8579
|
+
return DECLINED;
|
|
8580
|
+
this.openUrl(url);
|
|
8581
|
+
return { action: "accept" };
|
|
8582
|
+
}
|
|
8583
|
+
acceptForm(form, answers) {
|
|
8584
|
+
if (!isConfirmAccepted(form, answers))
|
|
8585
|
+
return DECLINED;
|
|
8586
|
+
return { action: "accept", content: buildElicitationContent(form, answers) };
|
|
8587
|
+
}
|
|
8588
|
+
open(requestId, signal, questions, accept) {
|
|
8589
|
+
const toolUseId = `${ELICITATION_PREFIX}${requestId}`;
|
|
8590
|
+
return new Promise((settle) => {
|
|
8591
|
+
this.pending.set(toolUseId, { settle, accept });
|
|
8592
|
+
signal.addEventListener("abort", () => this.answer(toolUseId, {}), { once: true });
|
|
8593
|
+
this.emit({
|
|
8594
|
+
type: "agent.question.required",
|
|
8595
|
+
agentSessionId: this.agentSessionId,
|
|
8596
|
+
toolUseId,
|
|
8597
|
+
questions
|
|
8598
|
+
});
|
|
8599
|
+
});
|
|
8600
|
+
}
|
|
8601
|
+
}
|
|
7687
8602
|
|
|
7688
8603
|
// packages/agent/src/permissions/permissionResults.ts
|
|
7689
8604
|
var allowTool = (input) => ({
|
|
@@ -7800,7 +8715,87 @@ var ADHD_SYSTEM_PROMPT = `For the rest of this session, shape every response for
|
|
|
7800
8715
|
|
|
7801
8716
|
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
8717
|
|
|
7803
|
-
// packages/agent/src/profile/
|
|
8718
|
+
// packages/agent/src/profile/codeReviewPrompt.ts
|
|
8719
|
+
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.";
|
|
8720
|
+
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.
|
|
8721
|
+
|
|
8722
|
+
- Standards: does the code follow this repo's documented coding standards?
|
|
8723
|
+
- Spec: does the code match what the originating issue or spec asked for?
|
|
8724
|
+
|
|
8725
|
+
A change can pass one axis and fail the other. Never merge or rerank the two.
|
|
8726
|
+
|
|
8727
|
+
## 1. Pin the fixed point
|
|
8728
|
+
|
|
8729
|
+
Use the commit, branch, tag, or ref you were given. If none was given, review the uncommitted work with \`git diff HEAD\`.
|
|
8730
|
+
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.
|
|
8731
|
+
|
|
8732
|
+
## 2. Find the spec
|
|
8733
|
+
|
|
8734
|
+
Look in this order:
|
|
8735
|
+
1. Issue references in commit messages (#123, Closes #45).
|
|
8736
|
+
2. A path you were given.
|
|
8737
|
+
3. A spec or issue file under docs/, specs/, or .scratch/ matching the branch name or feature.
|
|
8738
|
+
If there is none, skip the Spec axis and say "no spec available".
|
|
8739
|
+
|
|
8740
|
+
## 3. Find the standards
|
|
8741
|
+
|
|
8742
|
+
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.
|
|
8743
|
+
|
|
8744
|
+
Smell baseline, always a judgement call, never a hard violation (name it "possible <smell>"). Skip anything tooling already enforces.
|
|
8745
|
+
- Mysterious Name: a name that does not reveal what it does or holds.
|
|
8746
|
+
- Duplicated Code: the same logic shape in more than one hunk or file.
|
|
8747
|
+
- Feature Envy: a method that uses another object's data more than its own.
|
|
8748
|
+
- Data Clumps: the same few fields or params always travel together.
|
|
8749
|
+
- Primitive Obsession: a primitive standing in for a domain concept.
|
|
8750
|
+
- Repeated Switches: the same switch or if-cascade on one type recurs.
|
|
8751
|
+
- Shotgun Surgery: one logical change forces scattered edits across many files.
|
|
8752
|
+
- Divergent Change: one file is edited for several unrelated reasons.
|
|
8753
|
+
- Speculative Generality: abstraction or hooks for needs the spec does not have.
|
|
8754
|
+
- Message Chains: long a.b().c().d() navigation callers should not depend on.
|
|
8755
|
+
- Middle Man: a class or function that mostly delegates onward.
|
|
8756
|
+
- Refused Bequest: a subclass that ignores or overrides most of what it inherits.
|
|
8757
|
+
|
|
8758
|
+
## 4. Report
|
|
8759
|
+
|
|
8760
|
+
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.
|
|
8761
|
+
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.
|
|
8762
|
+
|
|
8763
|
+
Every finding names its file path and line range as <path>:<from>:<to>. Keep each axis under 400 words.
|
|
8764
|
+
End with one line: findings per axis and the worst issue within each axis. Do not pick a winner across axes.`;
|
|
8765
|
+
|
|
8766
|
+
// packages/agent/src/profile/scoutPrompt.ts
|
|
8767
|
+
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.";
|
|
8768
|
+
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.
|
|
8769
|
+
|
|
8770
|
+
1. Use Glob to find files, Grep to find content, Read to confirm. Read only the lines you need.
|
|
8771
|
+
2. Answer the request directly. Report only what the request needs.
|
|
8772
|
+
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>.
|
|
8773
|
+
4. Keep it concise: one line per finding, the most relevant first, at most 10 findings.
|
|
8774
|
+
5. If nothing matches, say so and list what you searched.`;
|
|
8775
|
+
|
|
8776
|
+
// packages/agent/src/profile/subagents.ts
|
|
8777
|
+
var AGENT_SUBAGENTS = {
|
|
8778
|
+
Scout: {
|
|
8779
|
+
description: SCOUT_DESCRIPTION,
|
|
8780
|
+
prompt: SCOUT_PROMPT,
|
|
8781
|
+
tools: ["Glob", "Grep", "Read"],
|
|
8782
|
+
model: "haiku",
|
|
8783
|
+
effort: "medium"
|
|
8784
|
+
},
|
|
8785
|
+
CodeReview: {
|
|
8786
|
+
description: CODE_REVIEW_DESCRIPTION,
|
|
8787
|
+
prompt: CODE_REVIEW_PROMPT,
|
|
8788
|
+
tools: ["Bash", "Glob", "Grep", "Read"],
|
|
8789
|
+
model: "sonnet",
|
|
8790
|
+
effort: "medium"
|
|
8791
|
+
}
|
|
8792
|
+
};
|
|
8793
|
+
var SUBAGENT_GUIDANCE = `Prefer subagents over doing the work yourself. Use *Agent* with:
|
|
8794
|
+
- 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.
|
|
8795
|
+
- CodeReview: to review code changes against the repo's standards and spec.
|
|
8796
|
+
Run independent subagents in parallel.`;
|
|
8797
|
+
|
|
8798
|
+
// packages/agent/src/profile/agentTools.ts
|
|
7804
8799
|
var AGENT_TOOLS = [
|
|
7805
8800
|
"Bash",
|
|
7806
8801
|
"Read",
|
|
@@ -7821,9 +8816,48 @@ var AGENT_TOOLS = [
|
|
|
7821
8816
|
"Edit",
|
|
7822
8817
|
"NotebookEdit"
|
|
7823
8818
|
];
|
|
8819
|
+
var AGENT_DISALLOWED_TOOLS = [
|
|
8820
|
+
"Agent(Explore)",
|
|
8821
|
+
"Agent(Plan)",
|
|
8822
|
+
"Agent(statusline-setup)"
|
|
8823
|
+
];
|
|
8824
|
+
|
|
8825
|
+
// packages/agent/src/profile/toolGuidance.ts
|
|
8826
|
+
var TOOL_USAGE = {
|
|
8827
|
+
Bash: "run shell commands; never to read, search, or edit files",
|
|
8828
|
+
Read: "read files",
|
|
8829
|
+
Grep: "search file contents",
|
|
8830
|
+
Glob: "scan files by name pattern",
|
|
8831
|
+
WebSearch: "search the web",
|
|
8832
|
+
WebFetch: "fetch a URL",
|
|
8833
|
+
TaskStop: "stop a running background task",
|
|
8834
|
+
Agent: "delegate work to a subagent",
|
|
8835
|
+
TaskCreate: "create a task",
|
|
8836
|
+
TaskGet: "read one task",
|
|
8837
|
+
TaskList: "list tasks",
|
|
8838
|
+
TaskOutput: "read a background task's output",
|
|
8839
|
+
TaskUpdate: "update a task",
|
|
8840
|
+
TodoWrite: "track the steps of multi-step work",
|
|
8841
|
+
AskUserQuestion: "ask the user",
|
|
8842
|
+
Write: "create new files with content",
|
|
8843
|
+
Edit: "update files",
|
|
8844
|
+
NotebookEdit: "update notebook cells"
|
|
8845
|
+
};
|
|
8846
|
+
var TOOL_GUIDANCE = `Always use the dedicated tool, never a workaround:
|
|
8847
|
+
${AGENT_TOOLS.map((tool) => `- Use *${tool}* to ${TOOL_USAGE[tool]}`).join(`
|
|
8848
|
+
`)}`;
|
|
8849
|
+
|
|
8850
|
+
// packages/agent/src/profile/agentSystemPrompt.ts
|
|
8851
|
+
var AGENT_SYSTEM_PROMPT = [ADHD_SYSTEM_PROMPT, TOOL_GUIDANCE, SUBAGENT_GUIDANCE].join(`
|
|
8852
|
+
|
|
8853
|
+
`);
|
|
8854
|
+
|
|
8855
|
+
// packages/agent/src/profile/agentProfile.ts
|
|
7824
8856
|
var AGENT_PROFILE_OPTIONS = {
|
|
7825
8857
|
tools: AGENT_TOOLS,
|
|
7826
|
-
|
|
8858
|
+
disallowedTools: AGENT_DISALLOWED_TOOLS,
|
|
8859
|
+
systemPrompt: AGENT_SYSTEM_PROMPT,
|
|
8860
|
+
agents: AGENT_SUBAGENTS,
|
|
7827
8861
|
enableFileCheckpointing: true,
|
|
7828
8862
|
extraArgs: { "replay-user-messages": null },
|
|
7829
8863
|
permissionMode: DEFAULT_PERMISSION_MODE,
|
|
@@ -7855,19 +8889,6 @@ var AGENT_PROFILE_OPTIONS = {
|
|
|
7855
8889
|
includeHookEvents: true
|
|
7856
8890
|
};
|
|
7857
8891
|
|
|
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;
|
|
7870
|
-
|
|
7871
8892
|
// packages/agent/src/session/agentSession.ts
|
|
7872
8893
|
function requireRewind(result) {
|
|
7873
8894
|
if (!result.canRewind)
|
|
@@ -7879,18 +8900,21 @@ class AgentSession {
|
|
|
7879
8900
|
baseOptions;
|
|
7880
8901
|
input = pushable({ objectMode: true });
|
|
7881
8902
|
gate;
|
|
8903
|
+
elicitations;
|
|
7882
8904
|
query;
|
|
7883
8905
|
pendingTurns = 0;
|
|
7884
8906
|
pumping = false;
|
|
7885
8907
|
constructor(agentSessionId, baseOptions, runtime) {
|
|
7886
8908
|
this.baseOptions = baseOptions;
|
|
7887
8909
|
this.gate = new PermissionGate(agentSessionId);
|
|
8910
|
+
this.elicitations = new ElicitationGate(agentSessionId);
|
|
7888
8911
|
this.query = runtime.open({
|
|
7889
8912
|
prompt: this.input,
|
|
7890
8913
|
options: {
|
|
7891
8914
|
...baseOptions,
|
|
7892
8915
|
...AGENT_PROFILE_OPTIONS,
|
|
7893
|
-
canUseTool: this.gate.canUseTool
|
|
8916
|
+
canUseTool: this.gate.canUseTool,
|
|
8917
|
+
onElicitation: this.elicitations.handle
|
|
7894
8918
|
}
|
|
7895
8919
|
});
|
|
7896
8920
|
}
|
|
@@ -7907,35 +8931,30 @@ class AgentSession {
|
|
|
7907
8931
|
return;
|
|
7908
8932
|
this.pumping = true;
|
|
7909
8933
|
const sink = pushable({ objectMode: true });
|
|
7910
|
-
this.
|
|
8934
|
+
this.listenGates((event) => sink.push(event));
|
|
7911
8935
|
this.pumpMessages(sink);
|
|
7912
8936
|
try {
|
|
7913
8937
|
yield* sink;
|
|
7914
8938
|
} finally {
|
|
7915
8939
|
this.pumping = false;
|
|
7916
|
-
this.
|
|
8940
|
+
this.listenGates(() => {});
|
|
7917
8941
|
}
|
|
7918
8942
|
}
|
|
7919
8943
|
answerApproval(toolUseId, decision) {
|
|
7920
8944
|
this.gate.answerApproval(toolUseId, decision);
|
|
7921
8945
|
}
|
|
7922
8946
|
answerQuestion(toolUseId, answers) {
|
|
7923
|
-
this.
|
|
8947
|
+
if (!this.elicitations.answer(toolUseId, answers))
|
|
8948
|
+
this.gate.answerQuestion(toolUseId, answers);
|
|
7924
8949
|
}
|
|
7925
8950
|
async cancel() {
|
|
7926
|
-
this.
|
|
8951
|
+
this.rejectAllPrompts();
|
|
7927
8952
|
await this.query.interrupt();
|
|
7928
8953
|
}
|
|
7929
8954
|
async setModel(model) {
|
|
7930
8955
|
await this.query.setModel(model);
|
|
7931
8956
|
this.baseOptions = { ...this.baseOptions, model };
|
|
7932
8957
|
}
|
|
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
8958
|
setPermissionMode(mode) {
|
|
7940
8959
|
return this.query.setPermissionMode(mode);
|
|
7941
8960
|
}
|
|
@@ -7945,6 +8964,27 @@ class AgentSession {
|
|
|
7945
8964
|
fetchMcpStatus() {
|
|
7946
8965
|
return this.query.mcpServerStatus();
|
|
7947
8966
|
}
|
|
8967
|
+
async startMcpLogin(serverName) {
|
|
8968
|
+
if (typeof this.query.mcpAuthenticate !== "function") {
|
|
8969
|
+
throw new Error("This Claude Agent SDK version does not support MCP login");
|
|
8970
|
+
}
|
|
8971
|
+
const { authUrl } = await this.query.mcpAuthenticate(serverName);
|
|
8972
|
+
if (!authUrl)
|
|
8973
|
+
throw new Error(`MCP server ${serverName} did not offer a login`);
|
|
8974
|
+
if (!/^https?:$/.test(new URL(authUrl).protocol)) {
|
|
8975
|
+
throw new Error(`MCP server ${serverName} offered an unsafe login link`);
|
|
8976
|
+
}
|
|
8977
|
+
return authUrl;
|
|
8978
|
+
}
|
|
8979
|
+
async submitMcpCallback(serverName, callbackUrl) {
|
|
8980
|
+
if (!/^https?:$/.test(new URL(callbackUrl).protocol)) {
|
|
8981
|
+
throw new Error("The callback must be an http(s) link");
|
|
8982
|
+
}
|
|
8983
|
+
await this.query.mcpSubmitOAuthCallbackUrl(serverName, callbackUrl);
|
|
8984
|
+
}
|
|
8985
|
+
awaitMcpLogin(serverName, wait) {
|
|
8986
|
+
return waitForMcpLogin(() => this.fetchMcpStatus(), serverName, wait);
|
|
8987
|
+
}
|
|
7948
8988
|
fetchModels() {
|
|
7949
8989
|
return this.query.supportedModels();
|
|
7950
8990
|
}
|
|
@@ -7962,10 +9002,18 @@ class AgentSession {
|
|
|
7962
9002
|
});
|
|
7963
9003
|
}
|
|
7964
9004
|
close() {
|
|
7965
|
-
this.
|
|
9005
|
+
this.rejectAllPrompts();
|
|
7966
9006
|
this.input.end();
|
|
7967
9007
|
this.query.close();
|
|
7968
9008
|
}
|
|
9009
|
+
listenGates(emit) {
|
|
9010
|
+
this.gate.listen(emit);
|
|
9011
|
+
this.elicitations.listen(emit);
|
|
9012
|
+
}
|
|
9013
|
+
rejectAllPrompts() {
|
|
9014
|
+
this.gate.rejectAll();
|
|
9015
|
+
this.elicitations.rejectAll();
|
|
9016
|
+
}
|
|
7969
9017
|
async pumpMessages(sink) {
|
|
7970
9018
|
try {
|
|
7971
9019
|
while (true) {
|
|
@@ -8038,13 +9086,13 @@ class AgentSessionManager {
|
|
|
8038
9086
|
import { homedir } from "os";
|
|
8039
9087
|
import { join as join2 } from "path";
|
|
8040
9088
|
var OPTIONS_PATH = join2(homedir(), ".claudin", "options.json");
|
|
8041
|
-
async function
|
|
9089
|
+
async function readOptions2(path) {
|
|
8042
9090
|
const stored = await Bun.file(path).json().catch(() => ({}));
|
|
8043
9091
|
const parsed = optionsFileSchema.safeParse(stored);
|
|
8044
9092
|
return parsed.success ? parsed.data : {};
|
|
8045
9093
|
}
|
|
8046
9094
|
async function saveBackground(path, background) {
|
|
8047
|
-
await Bun.write(path, JSON.stringify({ ...await
|
|
9095
|
+
await Bun.write(path, JSON.stringify({ ...await readOptions2(path), background }, null, 2));
|
|
8048
9096
|
}
|
|
8049
9097
|
|
|
8050
9098
|
// packages/daemon/src/workspace/resolvePath.ts
|
|
@@ -8264,11 +9312,6 @@ var agentHandlers = {
|
|
|
8264
9312
|
await agents.requireSession(request.agentSessionId).setModel(request.model);
|
|
8265
9313
|
yield { type: "agent.model.changed", model: request.model };
|
|
8266
9314
|
},
|
|
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
9315
|
async* "agent.effort.set.requested"({ agents }, request) {
|
|
8273
9316
|
await agents.requireSession(request.agentSessionId).setEffort(request.effort);
|
|
8274
9317
|
yield { type: "agent.effort.changed", effort: request.effort };
|
|
@@ -8289,6 +9332,22 @@ var agentHandlers = {
|
|
|
8289
9332
|
const servers = await agents.requireSession(request.agentSessionId).fetchMcpStatus();
|
|
8290
9333
|
yield { type: "agent.mcp.status.received", servers };
|
|
8291
9334
|
},
|
|
9335
|
+
async* "agent.mcp.login.requested"({ agents }, request) {
|
|
9336
|
+
const { serverName } = request;
|
|
9337
|
+
const session = agents.requireSession(request.agentSessionId);
|
|
9338
|
+
const authUrl = await session.startMcpLogin(serverName);
|
|
9339
|
+
yield { type: "agent.mcp.login.started", serverName, authUrl };
|
|
9340
|
+
await openBrowser(authUrl);
|
|
9341
|
+
const servers = await session.awaitMcpLogin(serverName);
|
|
9342
|
+
yield { type: "agent.mcp.status.received", servers };
|
|
9343
|
+
},
|
|
9344
|
+
async* "agent.mcp.callback.submitted"({ agents }, request) {
|
|
9345
|
+
const { serverName, callbackUrl } = request;
|
|
9346
|
+
const session = agents.requireSession(request.agentSessionId);
|
|
9347
|
+
await session.submitMcpCallback(serverName, callbackUrl);
|
|
9348
|
+
const servers = await session.awaitMcpLogin(serverName, { intervalMs: 500, timeoutMs: 1e4 });
|
|
9349
|
+
yield { type: "agent.mcp.status.received", servers };
|
|
9350
|
+
},
|
|
8292
9351
|
async* "agent.usage.requested"({ agents }, request) {
|
|
8293
9352
|
const { session } = await agents.requireSession(request.agentSessionId).fetchUsage();
|
|
8294
9353
|
yield { type: "agent.usage.received", usage: session };
|
|
@@ -8319,7 +9378,7 @@ var agentHandlers = {
|
|
|
8319
9378
|
// packages/daemon/src/handlers/optionsHandlers.ts
|
|
8320
9379
|
var optionsHandlers = {
|
|
8321
9380
|
async* "options.load.requested"({ optionsPath }) {
|
|
8322
|
-
const { background } = await
|
|
9381
|
+
const { background } = await readOptions2(optionsPath);
|
|
8323
9382
|
yield { type: "options.loaded", background };
|
|
8324
9383
|
},
|
|
8325
9384
|
async* "options.background.save.requested"({ optionsPath }, request) {
|
|
@@ -8360,16 +9419,17 @@ var sessionHandlers = {
|
|
|
8360
9419
|
};
|
|
8361
9420
|
|
|
8362
9421
|
// packages/daemon/src/workspace/readFileDiffs.ts
|
|
8363
|
-
import { relative } from "path";
|
|
9422
|
+
import { relative, resolve as resolve2 } from "path";
|
|
8364
9423
|
var isTracked = async (cwd, path) => (await Bun.$`git ls-files --error-unmatch -- ${path}`.cwd(cwd).quiet().nothrow()).exitCode === 0;
|
|
8365
9424
|
async function readPatch(cwd, path) {
|
|
8366
9425
|
const command = await isTracked(cwd, path) ? Bun.$`git diff --no-color HEAD -- ${path}` : Bun.$`git diff --no-color --no-index -- /dev/null ${path}`;
|
|
8367
9426
|
return (await command.cwd(cwd).quiet().nothrow()).text();
|
|
8368
9427
|
}
|
|
8369
9428
|
async function readFileDiff(cwd, path) {
|
|
8370
|
-
const
|
|
9429
|
+
const absolute = resolve2(cwd, path);
|
|
9430
|
+
const patch = await readPatch(cwd, absolute);
|
|
8371
9431
|
return {
|
|
8372
|
-
path: relative(cwd,
|
|
9432
|
+
path: relative(cwd, absolute) || path,
|
|
8373
9433
|
patch,
|
|
8374
9434
|
additions: countPatchLines(patch, "+"),
|
|
8375
9435
|
deletions: countPatchLines(patch, "-")
|
|
@@ -8380,6 +9440,17 @@ async function readFileDiffs(cwd, paths) {
|
|
|
8380
9440
|
return diffs.filter(({ patch }) => patch.trim() !== "");
|
|
8381
9441
|
}
|
|
8382
9442
|
|
|
9443
|
+
// packages/daemon/src/workspace/readGitChangedPaths.ts
|
|
9444
|
+
var readLines = async (cwd, command) => (await command.cwd(cwd).quiet().nothrow()).text().split(`
|
|
9445
|
+
`).filter(Boolean);
|
|
9446
|
+
async function readGitChangedPaths(cwd) {
|
|
9447
|
+
const [tracked, untracked] = await Promise.all([
|
|
9448
|
+
readLines(cwd, Bun.$`git diff --name-only --relative HEAD`),
|
|
9449
|
+
readLines(cwd, Bun.$`git ls-files --others --exclude-standard`)
|
|
9450
|
+
]);
|
|
9451
|
+
return [...tracked, ...untracked];
|
|
9452
|
+
}
|
|
9453
|
+
|
|
8383
9454
|
// node_modules/.bun/fuzzysort@4.0.2/node_modules/fuzzysort/fuzzysort.js
|
|
8384
9455
|
function single(search, target) {
|
|
8385
9456
|
if (!search || !target)
|
|
@@ -10007,7 +11078,9 @@ var workspaceHandlers = {
|
|
|
10007
11078
|
yield { type: "workspace.cwd.changed", cwd, ...await readGitInfo(cwd) };
|
|
10008
11079
|
},
|
|
10009
11080
|
async* "workspace.diff.requested"({ cwd }, request) {
|
|
10010
|
-
|
|
11081
|
+
const changed = await readFileDiffs(cwd, await readGitChangedPaths(cwd));
|
|
11082
|
+
const files = changed.length > 0 ? changed : await readFileDiffs(cwd, request.paths);
|
|
11083
|
+
yield { type: "workspace.diff.received", files };
|
|
10011
11084
|
}
|
|
10012
11085
|
};
|
|
10013
11086
|
|
|
@@ -10060,7 +11133,11 @@ async function startDaemon(port = DEFAULT_PORT, context) {
|
|
|
10060
11133
|
return server;
|
|
10061
11134
|
}
|
|
10062
11135
|
// apps/tui/src/startTui.ts
|
|
10063
|
-
import {
|
|
11136
|
+
import {
|
|
11137
|
+
BoxRenderable as BoxRenderable16,
|
|
11138
|
+
createCliRenderer,
|
|
11139
|
+
createHostClipboard
|
|
11140
|
+
} from "@opentui/core";
|
|
10064
11141
|
|
|
10065
11142
|
// apps/tui/src/components/backgroundPanel.ts
|
|
10066
11143
|
import { BoxRenderable, StyledText, TextRenderable } from "@opentui/core";
|
|
@@ -17552,7 +18629,7 @@ var detectFiletype = (path) => FILETYPES[path.split(".").pop() ?? ""];
|
|
|
17552
18629
|
|
|
17553
18630
|
// apps/tui/src/format/diffViewerChunks.ts
|
|
17554
18631
|
import { bold as bold2, dim as dim2, fg as fg2 } from "@opentui/core";
|
|
17555
|
-
var VIEWER_TITLE = "
|
|
18632
|
+
var VIEWER_TITLE = "Diffs";
|
|
17556
18633
|
var VIEWER_HINT = "\u2190/\u2192 file \xB7 \u2191/\u2193 PgUp/PgDn scroll \xB7 Esc close";
|
|
17557
18634
|
var buildFileChunks = (file, selected) => [
|
|
17558
18635
|
selected ? bold2(fg2(Theme.fg.primary)(`\u276F ${file.path}`)) : fg2(Theme.fg.secondary)(file.path),
|
|
@@ -17802,7 +18879,9 @@ class ListPopover {
|
|
|
17802
18879
|
// apps/tui/src/components/promptInput.ts
|
|
17803
18880
|
import {
|
|
17804
18881
|
BoxRenderable as BoxRenderable5,
|
|
18882
|
+
decodePasteBytes as decodePasteBytes2,
|
|
17805
18883
|
SyntaxStyle,
|
|
18884
|
+
stripAnsiSequences,
|
|
17806
18885
|
TextareaRenderable,
|
|
17807
18886
|
TextRenderable as TextRenderable5
|
|
17808
18887
|
} from "@opentui/core";
|
|
@@ -17989,6 +19068,10 @@ class PromptInput {
|
|
|
17989
19068
|
event.preventDefault();
|
|
17990
19069
|
this.textarea.insertText(placeholder);
|
|
17991
19070
|
}
|
|
19071
|
+
insertPasted(content) {
|
|
19072
|
+
const placeholder = planPaste(content, this.attachments);
|
|
19073
|
+
this.textarea.insertText(placeholder ?? stripAnsiSequences(decodePasteBytes2(content.bytes)));
|
|
19074
|
+
}
|
|
17992
19075
|
clear() {
|
|
17993
19076
|
this.textarea.setText("");
|
|
17994
19077
|
this.attachments.reset();
|
|
@@ -18823,6 +19906,7 @@ class ApprovalPanel {
|
|
|
18823
19906
|
for (const { label, decision, color } of buildButtons()) {
|
|
18824
19907
|
buttons.add(new TextRenderable9(renderer, {
|
|
18825
19908
|
content: new StyledText8([bold4(fg9(color)(label))]),
|
|
19909
|
+
selectable: false,
|
|
18826
19910
|
onMouseDown: () => onDecision(decision)
|
|
18827
19911
|
}));
|
|
18828
19912
|
}
|
|
@@ -18847,44 +19931,64 @@ import {
|
|
|
18847
19931
|
var QUESTION_HINT = "\u2191/\u2193 select \xB7 Space toggle \xB7 Enter confirm \xB7 Esc dismiss";
|
|
18848
19932
|
var CUSTOM_PLACEHOLDER = "type your own answer";
|
|
18849
19933
|
var TEXT_CURSOR = "\u258F";
|
|
18850
|
-
var buildRowChunks = (draft) => {
|
|
18851
|
-
const
|
|
18852
|
-
|
|
18853
|
-
|
|
18854
|
-
const
|
|
18855
|
-
|
|
18856
|
-
|
|
19934
|
+
var buildRowChunks = (draft, multiSelect, { label, description, custom }, index) => {
|
|
19935
|
+
const focused = index === draft.cursor;
|
|
19936
|
+
const checked = custom ? draft.custom.trim() !== "" : draft.picks.includes(label);
|
|
19937
|
+
const marker = multiSelect ? checked ? QUESTION_GLYPHS.checked : QUESTION_GLYPHS.unchecked : "";
|
|
19938
|
+
const prefix = [focused ? QUESTION_GLYPHS.cursor : " ", marker].filter(Boolean).join(" ");
|
|
19939
|
+
const head = fg10(focused ? Theme.accent.brand : Theme.fg.primary)(`${prefix} ${label}`);
|
|
19940
|
+
if (!custom)
|
|
19941
|
+
return [head, fg10(Theme.fg.muted)(` ${description}`)];
|
|
19942
|
+
const typed = draft.custom ? [fg10(Theme.fg.primary)(draft.custom)] : focused ? [] : [fg10(Theme.fg.muted)(CUSTOM_PLACEHOLDER)];
|
|
19943
|
+
return [
|
|
19944
|
+
head,
|
|
19945
|
+
fg10(Theme.fg.muted)(": "),
|
|
19946
|
+
...typed,
|
|
19947
|
+
...focused ? [fg10(Theme.accent.brand)(TEXT_CURSOR)] : []
|
|
18857
19948
|
];
|
|
18858
|
-
|
|
18859
|
-
|
|
18860
|
-
|
|
18861
|
-
|
|
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
|
-
});
|
|
19949
|
+
};
|
|
19950
|
+
var listRows = (draft) => {
|
|
19951
|
+
const current = readCurrentQuestion(draft);
|
|
19952
|
+
return current ? [...current.options, { label: OTHER_LABEL, description: "", custom: true }] : [];
|
|
18875
19953
|
};
|
|
18876
19954
|
|
|
18877
19955
|
class QuestionPanel {
|
|
19956
|
+
renderer;
|
|
19957
|
+
onSelectRow;
|
|
18878
19958
|
renderable;
|
|
18879
19959
|
text;
|
|
18880
|
-
|
|
19960
|
+
rows;
|
|
19961
|
+
hint;
|
|
19962
|
+
rowViews = [];
|
|
19963
|
+
constructor(renderer, onSelectRow) {
|
|
19964
|
+
this.renderer = renderer;
|
|
19965
|
+
this.onSelectRow = onSelectRow;
|
|
18881
19966
|
this.renderable = new BoxRenderable9(renderer, {
|
|
18882
19967
|
flexDirection: "column",
|
|
18883
19968
|
marginTop: 1,
|
|
18884
19969
|
flexShrink: 0
|
|
18885
19970
|
});
|
|
18886
19971
|
this.text = new TextRenderable10(renderer, { content: "" });
|
|
19972
|
+
this.rows = new BoxRenderable9(renderer, { flexDirection: "column" });
|
|
19973
|
+
this.hint = new TextRenderable10(renderer, {
|
|
19974
|
+
content: new StyledText9([dim4(fg10(Theme.fg.muted)(QUESTION_HINT))])
|
|
19975
|
+
});
|
|
18887
19976
|
this.renderable.add(this.text);
|
|
19977
|
+
this.renderable.add(this.rows);
|
|
19978
|
+
this.renderable.add(this.hint);
|
|
19979
|
+
}
|
|
19980
|
+
readRowView(index) {
|
|
19981
|
+
const existing = this.rowViews[index];
|
|
19982
|
+
if (existing)
|
|
19983
|
+
return existing;
|
|
19984
|
+
const created = new TextRenderable10(this.renderer, {
|
|
19985
|
+
content: "",
|
|
19986
|
+
selectable: false,
|
|
19987
|
+
onMouseDown: () => this.onSelectRow(index)
|
|
19988
|
+
});
|
|
19989
|
+
this.rowViews.push(created);
|
|
19990
|
+
this.rows.add(created);
|
|
19991
|
+
return created;
|
|
18888
19992
|
}
|
|
18889
19993
|
update(draft) {
|
|
18890
19994
|
const current = readCurrentQuestion(draft);
|
|
@@ -18893,11 +19997,17 @@ class QuestionPanel {
|
|
|
18893
19997
|
const progress = draft.questions.length > 1 ? ` (${draft.index + 1}/${draft.questions.length})` : "";
|
|
18894
19998
|
this.text.content = new StyledText9([
|
|
18895
19999
|
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}`))
|
|
20000
|
+
bold5(fg10(Theme.fg.primary)(current.question))
|
|
18900
20001
|
]);
|
|
20002
|
+
const rows = listRows(draft);
|
|
20003
|
+
rows.forEach((row, index) => {
|
|
20004
|
+
const view = this.readRowView(index);
|
|
20005
|
+
view.visible = true;
|
|
20006
|
+
view.content = new StyledText9(buildRowChunks(draft, current.multiSelect === true, row, index));
|
|
20007
|
+
});
|
|
20008
|
+
this.rowViews.slice(rows.length).forEach((view) => {
|
|
20009
|
+
view.visible = false;
|
|
20010
|
+
});
|
|
18901
20011
|
}
|
|
18902
20012
|
}
|
|
18903
20013
|
|
|
@@ -18935,15 +20045,25 @@ class ToolCallView {
|
|
|
18935
20045
|
onMouseOver: () => this.setHovered(true),
|
|
18936
20046
|
onMouseOut: () => this.setHovered(false)
|
|
18937
20047
|
});
|
|
18938
|
-
this.title = new TextRenderable11(renderer, {
|
|
18939
|
-
|
|
20048
|
+
this.title = new TextRenderable11(renderer, {
|
|
20049
|
+
content: "",
|
|
20050
|
+
wrapMode: "none",
|
|
20051
|
+
flexShrink: 1,
|
|
20052
|
+
selectable: false
|
|
20053
|
+
});
|
|
20054
|
+
this.duration = new TextRenderable11(renderer, {
|
|
20055
|
+
content: "",
|
|
20056
|
+
flexShrink: 0,
|
|
20057
|
+
marginLeft: 2,
|
|
20058
|
+
selectable: false
|
|
20059
|
+
});
|
|
18940
20060
|
header.add(this.title);
|
|
18941
20061
|
header.add(this.duration);
|
|
18942
20062
|
this.body = new BoxRenderable10(renderer, { flexDirection: "column", paddingLeft: 2 });
|
|
18943
20063
|
this.command = new TextRenderable11(renderer, { content: "", fg: Theme.fg.secondary });
|
|
18944
20064
|
this.output = new TextRenderable11(renderer, { content: "" });
|
|
18945
20065
|
this.approval = new ApprovalPanel(renderer, (decision) => hooks.onDecision(decision, this.callId));
|
|
18946
|
-
this.question = new QuestionPanel(renderer);
|
|
20066
|
+
this.question = new QuestionPanel(renderer, (index) => hooks.onSelectRow(index));
|
|
18947
20067
|
this.body.add(this.command);
|
|
18948
20068
|
this.body.add(this.output);
|
|
18949
20069
|
this.renderable.add(header);
|
|
@@ -19213,8 +20333,8 @@ var buildWindowChunks = (label, window, now) => {
|
|
|
19213
20333
|
};
|
|
19214
20334
|
function buildRateLimitChunks(limits, now) {
|
|
19215
20335
|
const windows = [
|
|
19216
|
-
["\
|
|
19217
|
-
["\
|
|
20336
|
+
["\uD83E\uDFF5h", limits.fiveHour],
|
|
20337
|
+
["\uD83E\uDFF7d", limits.sevenDay]
|
|
19218
20338
|
];
|
|
19219
20339
|
return windows.flatMap(([label, window], index) => window ? [
|
|
19220
20340
|
...index > 0 ? [fg13(Theme.border.separator)(SEPARATOR)] : [],
|
|
@@ -19342,6 +20462,7 @@ class StatusLine {
|
|
|
19342
20462
|
content: "",
|
|
19343
20463
|
wrapMode: "none",
|
|
19344
20464
|
flexShrink: 0,
|
|
20465
|
+
selectable: false,
|
|
19345
20466
|
onMouseDown: onStop
|
|
19346
20467
|
});
|
|
19347
20468
|
this.renderable.add(this.label);
|
|
@@ -19369,6 +20490,44 @@ class StatusLine {
|
|
|
19369
20490
|
}
|
|
19370
20491
|
}
|
|
19371
20492
|
|
|
20493
|
+
// apps/tui/src/components/toastView.ts
|
|
20494
|
+
import { BoxRenderable as BoxRenderable15, fg as fg16, StyledText as StyledText14, TextRenderable as TextRenderable15 } from "@opentui/core";
|
|
20495
|
+
var TOAST_ICON = "\u25CF";
|
|
20496
|
+
|
|
20497
|
+
class ToastView {
|
|
20498
|
+
renderable;
|
|
20499
|
+
text;
|
|
20500
|
+
toastId;
|
|
20501
|
+
constructor(renderer) {
|
|
20502
|
+
this.renderable = new BoxRenderable15(renderer, {
|
|
20503
|
+
position: "absolute",
|
|
20504
|
+
top: 1,
|
|
20505
|
+
right: 2,
|
|
20506
|
+
zIndex: 100,
|
|
20507
|
+
paddingLeft: 1,
|
|
20508
|
+
paddingRight: 1,
|
|
20509
|
+
border: true,
|
|
20510
|
+
borderStyle: "rounded",
|
|
20511
|
+
visible: false
|
|
20512
|
+
});
|
|
20513
|
+
this.text = new TextRenderable15(renderer, { content: "", wrapMode: "none", selectable: false });
|
|
20514
|
+
this.renderable.add(this.text);
|
|
20515
|
+
}
|
|
20516
|
+
update({ ui }) {
|
|
20517
|
+
const { toast } = ui;
|
|
20518
|
+
this.renderable.visible = toast !== null;
|
|
20519
|
+
if (!toast || toast.id === this.toastId)
|
|
20520
|
+
return;
|
|
20521
|
+
this.toastId = toast.id;
|
|
20522
|
+
this.renderable.borderColor = Theme.border.focus;
|
|
20523
|
+
this.renderable.backgroundColor = Theme.bg.surface;
|
|
20524
|
+
this.text.content = new StyledText14([
|
|
20525
|
+
fg16(Theme.status.success)(`${TOAST_ICON} `),
|
|
20526
|
+
fg16(Theme.fg.primary)(toast.text)
|
|
20527
|
+
]);
|
|
20528
|
+
}
|
|
20529
|
+
}
|
|
20530
|
+
|
|
19372
20531
|
// apps/tui/src/input/agentBusy.ts
|
|
19373
20532
|
var isStatusBusy = (status) => status !== "idle" && status !== "error";
|
|
19374
20533
|
var isAgentBusy = (store) => isStatusBusy(store.state.status);
|
|
@@ -19410,13 +20569,10 @@ var WORKFLOW_COMMANDS = {
|
|
|
19410
20569
|
store.emit({ type: "ui.rewind.picker.opened" });
|
|
19411
20570
|
}
|
|
19412
20571
|
},
|
|
19413
|
-
"/
|
|
19414
|
-
description: "Review
|
|
20572
|
+
"/diffs": {
|
|
20573
|
+
description: "Review git changes, or this session's edits when there are none",
|
|
19415
20574
|
run(store) {
|
|
19416
|
-
|
|
19417
|
-
if (paths.length === 0)
|
|
19418
|
-
return postNotice(store, "This session has not edited any files");
|
|
19419
|
-
store.request({ type: "workspace.diff.requested", paths });
|
|
20575
|
+
store.request({ type: "workspace.diff.requested", paths: listEditedFiles(store.state) });
|
|
19420
20576
|
}
|
|
19421
20577
|
},
|
|
19422
20578
|
"/export": {
|
|
@@ -19436,13 +20592,30 @@ var WORKFLOW_COMMANDS = {
|
|
|
19436
20592
|
};
|
|
19437
20593
|
|
|
19438
20594
|
// apps/tui/src/input/localCommands.ts
|
|
19439
|
-
function
|
|
19440
|
-
requestAgent(store, { type: "agent.
|
|
20595
|
+
function openModelPicker2(store) {
|
|
20596
|
+
requestAgent(store, { type: "agent.models.requested" });
|
|
19441
20597
|
}
|
|
19442
20598
|
var QUIT_COMMAND = {
|
|
19443
20599
|
description: "Exit the app (also /exit, /q, /leave)",
|
|
19444
20600
|
run: (store) => store.emit({ type: "ui.exit.requested" })
|
|
19445
20601
|
};
|
|
20602
|
+
var MCP_USAGE = "Usage: /mcp | /mcp login <name> | /mcp callback <name> <url>";
|
|
20603
|
+
function runMcpCommand(store, argument) {
|
|
20604
|
+
const [action, serverName, callbackUrl] = argument.trim().split(/\s+/);
|
|
20605
|
+
if (!action)
|
|
20606
|
+
return void requestAgent(store, { type: "agent.mcp.status.requested" });
|
|
20607
|
+
if (action === "login" && serverName) {
|
|
20608
|
+
return void requestAgent(store, { type: "agent.mcp.login.requested", serverName });
|
|
20609
|
+
}
|
|
20610
|
+
if (action === "callback" && serverName && callbackUrl) {
|
|
20611
|
+
return void requestAgent(store, {
|
|
20612
|
+
type: "agent.mcp.callback.submitted",
|
|
20613
|
+
serverName,
|
|
20614
|
+
callbackUrl
|
|
20615
|
+
});
|
|
20616
|
+
}
|
|
20617
|
+
store.emit({ type: "ui.notice.posted", text: MCP_USAGE });
|
|
20618
|
+
}
|
|
19446
20619
|
var SLASH_ALIASES = {
|
|
19447
20620
|
"/exit": "/quit",
|
|
19448
20621
|
"/q": "/quit",
|
|
@@ -19468,7 +20641,7 @@ var SLASH_COMMANDS = {
|
|
|
19468
20641
|
run(store, model) {
|
|
19469
20642
|
if (model)
|
|
19470
20643
|
return void requestAgent(store, { type: "agent.model.set.requested", model });
|
|
19471
|
-
|
|
20644
|
+
openModelPicker2(store);
|
|
19472
20645
|
}
|
|
19473
20646
|
},
|
|
19474
20647
|
"/theme": {
|
|
@@ -19522,10 +20695,8 @@ var SLASH_COMMANDS = {
|
|
|
19522
20695
|
}
|
|
19523
20696
|
},
|
|
19524
20697
|
"/mcp": {
|
|
19525
|
-
description: "List MCP servers",
|
|
19526
|
-
run
|
|
19527
|
-
requestAgent(store, { type: "agent.mcp.status.requested" });
|
|
19528
|
-
}
|
|
20698
|
+
description: "List MCP servers, sign in with /mcp login <name>, or /mcp callback <name> <url>",
|
|
20699
|
+
run: runMcpCommand
|
|
19529
20700
|
},
|
|
19530
20701
|
"/clear": {
|
|
19531
20702
|
description: "Start a fresh session",
|
|
@@ -19719,6 +20890,46 @@ function routeAutocompleteKey(key, store, accept) {
|
|
|
19719
20890
|
return true;
|
|
19720
20891
|
}
|
|
19721
20892
|
|
|
20893
|
+
// apps/tui/src/prompt/clipboardPaste.ts
|
|
20894
|
+
var PREFERRED_TYPES = ["image/png", "text/plain"];
|
|
20895
|
+
async function readClipboardPaste(clipboard) {
|
|
20896
|
+
const result = await clipboard.read({ preferredTypes: PREFERRED_TYPES });
|
|
20897
|
+
if (result.status !== "read")
|
|
20898
|
+
return;
|
|
20899
|
+
const { mimeType, bytes } = result.representation;
|
|
20900
|
+
if (bytes.length === 0)
|
|
20901
|
+
return;
|
|
20902
|
+
return { bytes, metadata: { mimeType, kind: mimeType.startsWith("text/") ? "text" : "binary" } };
|
|
20903
|
+
}
|
|
20904
|
+
|
|
20905
|
+
// apps/tui/src/input/toastActions.ts
|
|
20906
|
+
var TOAST_DURATION_MS = 2500;
|
|
20907
|
+
function showToast(store, text) {
|
|
20908
|
+
const id = crypto.randomUUID();
|
|
20909
|
+
store.emit({ type: "ui.toast.posted", id, text });
|
|
20910
|
+
setTimeout(() => store.emit({ type: "ui.toast.dismissed", id }), TOAST_DURATION_MS).unref();
|
|
20911
|
+
}
|
|
20912
|
+
|
|
20913
|
+
// apps/tui/src/input/clipboardActions.ts
|
|
20914
|
+
var UNAVAILABLE_NOTICE = "Clipboard unavailable, use your terminal's paste shortcut";
|
|
20915
|
+
var COPIED_TOAST = "Copied to clipboard";
|
|
20916
|
+
var COPY_FAILED_TOAST = "Could not copy to clipboard";
|
|
20917
|
+
async function pasteFromClipboard(store, input, clipboard) {
|
|
20918
|
+
const content = await readClipboardPaste(clipboard);
|
|
20919
|
+
if (content)
|
|
20920
|
+
input.insertPasted(content);
|
|
20921
|
+
else
|
|
20922
|
+
showToast(store, UNAVAILABLE_NOTICE);
|
|
20923
|
+
}
|
|
20924
|
+
async function copySelection(store, renderer, clipboard, selection) {
|
|
20925
|
+
const text = selection.getSelectedText();
|
|
20926
|
+
if (!text)
|
|
20927
|
+
return;
|
|
20928
|
+
const written = (await clipboard.writeText(text)).status === "written";
|
|
20929
|
+
const copied = written || renderer.copyToClipboardOSC52(text);
|
|
20930
|
+
showToast(store, copied ? COPIED_TOAST : COPY_FAILED_TOAST);
|
|
20931
|
+
}
|
|
20932
|
+
|
|
19722
20933
|
// apps/tui/src/input/slashCommands.ts
|
|
19723
20934
|
var parseSlashLine = (line) => {
|
|
19724
20935
|
const [name = "", ...rest] = line.trim().split(/\s+/);
|
|
@@ -19898,7 +21109,7 @@ var routeExit = (key, { store, presses, exit }) => {
|
|
|
19898
21109
|
return true;
|
|
19899
21110
|
}
|
|
19900
21111
|
presses.ctrlCAt = pressedAt;
|
|
19901
|
-
store
|
|
21112
|
+
showToast(store, EXIT_NOTICE);
|
|
19902
21113
|
return true;
|
|
19903
21114
|
};
|
|
19904
21115
|
var routeDoubleEscape = (key, { store, presses }) => {
|
|
@@ -19926,10 +21137,11 @@ var QUESTION_ACTIONS = {
|
|
|
19926
21137
|
return: confirmQuestion,
|
|
19927
21138
|
escape: dismissQuestion
|
|
19928
21139
|
};
|
|
21140
|
+
var DELETE_CHARACTER = "\x7F";
|
|
19929
21141
|
var readTypedText = (key) => {
|
|
19930
21142
|
if (key.ctrl || key.meta)
|
|
19931
21143
|
return;
|
|
19932
|
-
return key.sequence.length === 1 && key.sequence >= " " ? key.sequence : undefined;
|
|
21144
|
+
return key.sequence.length === 1 && key.sequence >= " " && key.sequence !== DELETE_CHARACTER ? key.sequence : undefined;
|
|
19933
21145
|
};
|
|
19934
21146
|
function typeCustomAnswer(key, store) {
|
|
19935
21147
|
const { question } = store.state.ui;
|
|
@@ -20014,10 +21226,10 @@ var routePicker = (key, { store }) => {
|
|
|
20014
21226
|
}
|
|
20015
21227
|
return true;
|
|
20016
21228
|
};
|
|
20017
|
-
var
|
|
21229
|
+
var routeModelPicker = (key, { store }) => {
|
|
20018
21230
|
if (key.name !== "tab" || !key.shift)
|
|
20019
21231
|
return false;
|
|
20020
|
-
|
|
21232
|
+
openModelPicker2(store);
|
|
20021
21233
|
return true;
|
|
20022
21234
|
};
|
|
20023
21235
|
var routeDelivery = (key, { store, submitInput }) => {
|
|
@@ -20027,6 +21239,14 @@ var routeDelivery = (key, { store, submitInput }) => {
|
|
|
20027
21239
|
submitInput(delivery);
|
|
20028
21240
|
return true;
|
|
20029
21241
|
};
|
|
21242
|
+
var routePaste = (key, { store, pasteClipboard }) => {
|
|
21243
|
+
if (key.name !== "v" || !(key.ctrl || key.super))
|
|
21244
|
+
return false;
|
|
21245
|
+
if (store.state.ui.focus !== "input")
|
|
21246
|
+
return false;
|
|
21247
|
+
pasteClipboard();
|
|
21248
|
+
return true;
|
|
21249
|
+
};
|
|
20030
21250
|
var ROUTES = [
|
|
20031
21251
|
routeExit,
|
|
20032
21252
|
routeApproval,
|
|
@@ -20034,8 +21254,9 @@ var ROUTES = [
|
|
|
20034
21254
|
routeDiffViewer,
|
|
20035
21255
|
routeBackgroundEditor,
|
|
20036
21256
|
routePicker,
|
|
20037
|
-
|
|
21257
|
+
routeModelPicker,
|
|
20038
21258
|
routeDelivery,
|
|
21259
|
+
routePaste,
|
|
20039
21260
|
routeHistorySearch,
|
|
20040
21261
|
routeCompletion,
|
|
20041
21262
|
routeDoubleEscape,
|
|
@@ -20179,6 +21400,7 @@ class AppStore {
|
|
|
20179
21400
|
machine = new EventMachine(createSessionState(""), reduceTimedEvent);
|
|
20180
21401
|
peerEvents = new WeakSet;
|
|
20181
21402
|
stopListening;
|
|
21403
|
+
closed = false;
|
|
20182
21404
|
constructor(client) {
|
|
20183
21405
|
this.client = client;
|
|
20184
21406
|
this.stopListening = client.subscribe((event, peer) => this.receive(event, peer));
|
|
@@ -20196,7 +21418,8 @@ class AppStore {
|
|
|
20196
21418
|
this.client.send(event);
|
|
20197
21419
|
}
|
|
20198
21420
|
emit(event) {
|
|
20199
|
-
this.
|
|
21421
|
+
if (!this.closed)
|
|
21422
|
+
this.machine.send(event);
|
|
20200
21423
|
}
|
|
20201
21424
|
subscribe(listener) {
|
|
20202
21425
|
return this.machine.subscribe(() => listener(this.machine.state));
|
|
@@ -20208,6 +21431,7 @@ class AppStore {
|
|
|
20208
21431
|
});
|
|
20209
21432
|
}
|
|
20210
21433
|
close() {
|
|
21434
|
+
this.closed = true;
|
|
20211
21435
|
this.stopListening();
|
|
20212
21436
|
this.client.close();
|
|
20213
21437
|
}
|
|
@@ -20239,7 +21463,9 @@ var readShownTheme = ({ theme, ui }) => (ui.picker?.kind === "theme" ? THEME_NAM
|
|
|
20239
21463
|
var readShownBackground = ({ background, ui }) => ui.backgroundEditor?.color ?? background;
|
|
20240
21464
|
async function startTui(client, options = {}) {
|
|
20241
21465
|
const activeRenderer = options.renderer ?? await createCliRenderer({ exitOnCtrlC: false, useMouse: true });
|
|
21466
|
+
activeRenderer.setTerminalTitle("Claudin");
|
|
20242
21467
|
const store = new AppStore(client);
|
|
21468
|
+
const clipboard = options.clipboard ?? createHostClipboard();
|
|
20243
21469
|
let syntaxStyle = createSyntaxStyle(activeRenderer);
|
|
20244
21470
|
let appliedTheme = readShownTheme(store.state);
|
|
20245
21471
|
let appliedBackground = readShownBackground(store.state);
|
|
@@ -20247,13 +21473,15 @@ async function startTui(client, options = {}) {
|
|
|
20247
21473
|
const infoBar = new SessionInfoBar(activeRenderer);
|
|
20248
21474
|
const popover = new ListPopover(activeRenderer);
|
|
20249
21475
|
const backgroundPanel = new BackgroundPanel(activeRenderer);
|
|
21476
|
+
const toastView = new ToastView(activeRenderer);
|
|
20250
21477
|
const statusLine = new StatusLine(activeRenderer, () => cancelTurn(store));
|
|
20251
21478
|
const scrollback = new ScrollbackView(activeRenderer, {
|
|
20252
21479
|
syntaxStyle,
|
|
20253
21480
|
hooks: {
|
|
20254
21481
|
syntaxStyle,
|
|
20255
21482
|
onDecision: (decision, id) => answerApproval(store, decision, id),
|
|
20256
|
-
onToggle: (callId) => store.emit({ type: "ui.tool.toggled", callId })
|
|
21483
|
+
onToggle: (callId) => store.emit({ type: "ui.tool.toggled", callId }),
|
|
21484
|
+
onSelectRow: (cursor) => store.emit({ type: "ui.question.cursor.set", cursor })
|
|
20257
21485
|
}
|
|
20258
21486
|
});
|
|
20259
21487
|
const diffViewer = new DiffViewerPanel(activeRenderer, syntaxStyle);
|
|
@@ -20281,7 +21509,7 @@ async function startTui(client, options = {}) {
|
|
|
20281
21509
|
saveDraft(text);
|
|
20282
21510
|
}
|
|
20283
21511
|
});
|
|
20284
|
-
const root = new
|
|
21512
|
+
const root = new BoxRenderable16(activeRenderer, {
|
|
20285
21513
|
width: "100%",
|
|
20286
21514
|
height: "100%",
|
|
20287
21515
|
flexDirection: "column",
|
|
@@ -20300,6 +21528,10 @@ async function startTui(client, options = {}) {
|
|
|
20300
21528
|
for (const part of parts)
|
|
20301
21529
|
root.add(part.renderable);
|
|
20302
21530
|
activeRenderer.root.add(root);
|
|
21531
|
+
activeRenderer.root.add(toastView.renderable);
|
|
21532
|
+
activeRenderer.on("selection", (selection) => {
|
|
21533
|
+
copySelection(store, activeRenderer, clipboard, selection);
|
|
21534
|
+
});
|
|
20303
21535
|
for (const part of [header, statusLine, popover, backgroundPanel, input, infoBar]) {
|
|
20304
21536
|
part.renderable.onMouseScroll = ({ scroll }) => {
|
|
20305
21537
|
if (scroll?.direction === "up")
|
|
@@ -20332,6 +21564,7 @@ async function startTui(client, options = {}) {
|
|
|
20332
21564
|
syncTheme(state);
|
|
20333
21565
|
header.update(state);
|
|
20334
21566
|
statusLine.update(state);
|
|
21567
|
+
toastView.update(state);
|
|
20335
21568
|
infoBar.update(state);
|
|
20336
21569
|
scrollback.update(state);
|
|
20337
21570
|
scrollback.renderable.visible = state.ui.diffViewer === null;
|
|
@@ -20370,6 +21603,7 @@ async function startTui(client, options = {}) {
|
|
|
20370
21603
|
diffViewer,
|
|
20371
21604
|
editor,
|
|
20372
21605
|
acceptCompletion: () => acceptAutocomplete(store, input),
|
|
21606
|
+
pasteClipboard: () => void pasteFromClipboard(store, input, clipboard),
|
|
20373
21607
|
submitInput,
|
|
20374
21608
|
exit: () => activeRenderer.destroy()
|
|
20375
21609
|
};
|
|
@@ -20395,6 +21629,7 @@ async function startTui(client, options = {}) {
|
|
|
20395
21629
|
clearInterval(rateLimitPoll);
|
|
20396
21630
|
destroyed = true;
|
|
20397
21631
|
historySaver.flush();
|
|
21632
|
+
clipboard.dispose();
|
|
20398
21633
|
options.onExit?.(store.state.sessionId);
|
|
20399
21634
|
store.close();
|
|
20400
21635
|
});
|
|
@@ -20506,10 +21741,10 @@ function humanReadableArgName(arg) {
|
|
|
20506
21741
|
|
|
20507
21742
|
// node_modules/.bun/commander@15.0.0/node_modules/commander/lib/command.js
|
|
20508
21743
|
import { EventEmitter } from "events";
|
|
20509
|
-
import
|
|
20510
|
-
import
|
|
20511
|
-
import
|
|
20512
|
-
import
|
|
21744
|
+
import childProcess4 from "child_process";
|
|
21745
|
+
import path3 from "path";
|
|
21746
|
+
import fs6 from "fs";
|
|
21747
|
+
import process10 from "process";
|
|
20513
21748
|
import { stripVTControlCharacters as stripVTControlCharacters2 } from "util";
|
|
20514
21749
|
|
|
20515
21750
|
// node_modules/.bun/commander@15.0.0/node_modules/commander/lib/help.js
|
|
@@ -21146,13 +22381,13 @@ class Command extends EventEmitter {
|
|
|
21146
22381
|
this._showSuggestionAfterError = true;
|
|
21147
22382
|
this._savedState = null;
|
|
21148
22383
|
this._outputConfiguration = {
|
|
21149
|
-
writeOut: (str) =>
|
|
21150
|
-
writeErr: (str) =>
|
|
22384
|
+
writeOut: (str) => process10.stdout.write(str),
|
|
22385
|
+
writeErr: (str) => process10.stderr.write(str),
|
|
21151
22386
|
outputError: (str, write) => write(str),
|
|
21152
|
-
getOutHelpWidth: () =>
|
|
21153
|
-
getErrHelpWidth: () =>
|
|
21154
|
-
getOutHasColors: () => useColor() ?? (
|
|
21155
|
-
getErrHasColors: () => useColor() ?? (
|
|
22387
|
+
getOutHelpWidth: () => process10.stdout.isTTY ? process10.stdout.columns : undefined,
|
|
22388
|
+
getErrHelpWidth: () => process10.stderr.isTTY ? process10.stderr.columns : undefined,
|
|
22389
|
+
getOutHasColors: () => useColor() ?? (process10.stdout.isTTY && process10.stdout.hasColors?.()),
|
|
22390
|
+
getErrHasColors: () => useColor() ?? (process10.stderr.isTTY && process10.stderr.hasColors?.()),
|
|
21156
22391
|
stripColor: (str) => stripVTControlCharacters2(str)
|
|
21157
22392
|
};
|
|
21158
22393
|
this._hidden = false;
|
|
@@ -21360,7 +22595,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21360
22595
|
if (this._exitCallback) {
|
|
21361
22596
|
this._exitCallback(new CommanderError(exitCode, code, message));
|
|
21362
22597
|
}
|
|
21363
|
-
|
|
22598
|
+
process10.exit(exitCode);
|
|
21364
22599
|
}
|
|
21365
22600
|
action(fn) {
|
|
21366
22601
|
const listener = (args) => {
|
|
@@ -21552,16 +22787,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21552
22787
|
}
|
|
21553
22788
|
parseOptions = parseOptions || {};
|
|
21554
22789
|
if (argv === undefined && parseOptions.from === undefined) {
|
|
21555
|
-
if (
|
|
22790
|
+
if (process10.versions?.electron) {
|
|
21556
22791
|
parseOptions.from = "electron";
|
|
21557
22792
|
}
|
|
21558
|
-
const execArgv =
|
|
22793
|
+
const execArgv = process10.execArgv ?? [];
|
|
21559
22794
|
if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
|
|
21560
22795
|
parseOptions.from = "eval";
|
|
21561
22796
|
}
|
|
21562
22797
|
}
|
|
21563
22798
|
if (argv === undefined) {
|
|
21564
|
-
argv =
|
|
22799
|
+
argv = process10.argv;
|
|
21565
22800
|
}
|
|
21566
22801
|
this.rawArgs = argv.slice();
|
|
21567
22802
|
let userArgs;
|
|
@@ -21572,7 +22807,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21572
22807
|
userArgs = argv.slice(2);
|
|
21573
22808
|
break;
|
|
21574
22809
|
case "electron":
|
|
21575
|
-
if (
|
|
22810
|
+
if (process10.defaultApp) {
|
|
21576
22811
|
this._scriptPath = argv[1];
|
|
21577
22812
|
userArgs = argv.slice(2);
|
|
21578
22813
|
} else {
|
|
@@ -21638,7 +22873,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21638
22873
|
this.processedArgs = [];
|
|
21639
22874
|
}
|
|
21640
22875
|
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
21641
|
-
if (
|
|
22876
|
+
if (fs6.existsSync(executableFile))
|
|
21642
22877
|
return;
|
|
21643
22878
|
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
22879
|
const executableMissing = `'${executableFile}' does not exist
|
|
@@ -21651,12 +22886,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21651
22886
|
args = args.slice();
|
|
21652
22887
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
21653
22888
|
function findFile(baseDir, baseName) {
|
|
21654
|
-
const localBin =
|
|
21655
|
-
if (
|
|
22889
|
+
const localBin = path3.resolve(baseDir, baseName);
|
|
22890
|
+
if (fs6.existsSync(localBin))
|
|
21656
22891
|
return localBin;
|
|
21657
|
-
if (sourceExt.includes(
|
|
22892
|
+
if (sourceExt.includes(path3.extname(baseName)))
|
|
21658
22893
|
return;
|
|
21659
|
-
const foundExt = sourceExt.find((ext) =>
|
|
22894
|
+
const foundExt = sourceExt.find((ext) => fs6.existsSync(`${localBin}${ext}`));
|
|
21660
22895
|
if (foundExt)
|
|
21661
22896
|
return `${localBin}${foundExt}`;
|
|
21662
22897
|
return;
|
|
@@ -21668,42 +22903,42 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21668
22903
|
if (this._scriptPath) {
|
|
21669
22904
|
let resolvedScriptPath;
|
|
21670
22905
|
try {
|
|
21671
|
-
resolvedScriptPath =
|
|
22906
|
+
resolvedScriptPath = fs6.realpathSync(this._scriptPath);
|
|
21672
22907
|
} catch {
|
|
21673
22908
|
resolvedScriptPath = this._scriptPath;
|
|
21674
22909
|
}
|
|
21675
|
-
executableDir =
|
|
22910
|
+
executableDir = path3.resolve(path3.dirname(resolvedScriptPath), executableDir);
|
|
21676
22911
|
}
|
|
21677
22912
|
if (executableDir) {
|
|
21678
22913
|
let localFile = findFile(executableDir, executableFile);
|
|
21679
22914
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
21680
|
-
const legacyName =
|
|
22915
|
+
const legacyName = path3.basename(this._scriptPath, path3.extname(this._scriptPath));
|
|
21681
22916
|
if (legacyName !== this._name) {
|
|
21682
22917
|
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
|
21683
22918
|
}
|
|
21684
22919
|
}
|
|
21685
22920
|
executableFile = localFile || executableFile;
|
|
21686
22921
|
}
|
|
21687
|
-
const launchWithNode = sourceExt.includes(
|
|
22922
|
+
const launchWithNode = sourceExt.includes(path3.extname(executableFile));
|
|
21688
22923
|
let proc;
|
|
21689
|
-
if (
|
|
22924
|
+
if (process10.platform !== "win32") {
|
|
21690
22925
|
if (launchWithNode) {
|
|
21691
22926
|
args.unshift(executableFile);
|
|
21692
|
-
args = incrementNodeInspectorPort(
|
|
21693
|
-
proc =
|
|
22927
|
+
args = incrementNodeInspectorPort(process10.execArgv).concat(args);
|
|
22928
|
+
proc = childProcess4.spawn(process10.argv[0], args, { stdio: "inherit" });
|
|
21694
22929
|
} else {
|
|
21695
|
-
proc =
|
|
22930
|
+
proc = childProcess4.spawn(executableFile, args, { stdio: "inherit" });
|
|
21696
22931
|
}
|
|
21697
22932
|
} else {
|
|
21698
22933
|
this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
|
|
21699
22934
|
args.unshift(executableFile);
|
|
21700
|
-
args = incrementNodeInspectorPort(
|
|
21701
|
-
proc =
|
|
22935
|
+
args = incrementNodeInspectorPort(process10.execArgv).concat(args);
|
|
22936
|
+
proc = childProcess4.spawn(process10.execPath, args, { stdio: "inherit" });
|
|
21702
22937
|
}
|
|
21703
22938
|
if (!proc.killed) {
|
|
21704
22939
|
const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
|
|
21705
22940
|
signals.forEach((signal) => {
|
|
21706
|
-
|
|
22941
|
+
process10.on(signal, () => {
|
|
21707
22942
|
if (proc.killed === false && proc.exitCode === null) {
|
|
21708
22943
|
proc.kill(signal);
|
|
21709
22944
|
}
|
|
@@ -21714,7 +22949,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21714
22949
|
proc.on("close", (code) => {
|
|
21715
22950
|
code = code ?? 1;
|
|
21716
22951
|
if (!exitCallback) {
|
|
21717
|
-
|
|
22952
|
+
process10.exit(code);
|
|
21718
22953
|
} else {
|
|
21719
22954
|
exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
|
|
21720
22955
|
}
|
|
@@ -21726,7 +22961,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
21726
22961
|
throw new Error(`'${executableFile}' not executable`);
|
|
21727
22962
|
}
|
|
21728
22963
|
if (!exitCallback) {
|
|
21729
|
-
|
|
22964
|
+
process10.exit(1);
|
|
21730
22965
|
} else {
|
|
21731
22966
|
const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
|
|
21732
22967
|
wrappedError.nestedError = err;
|
|
@@ -22075,11 +23310,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
22075
23310
|
}
|
|
22076
23311
|
_parseOptionsEnv() {
|
|
22077
23312
|
this.options.forEach((option) => {
|
|
22078
|
-
if (option.envVar && option.envVar in
|
|
23313
|
+
if (option.envVar && option.envVar in process10.env) {
|
|
22079
23314
|
const optionKey = option.attributeName();
|
|
22080
23315
|
if (this.getOptionValue(optionKey) === undefined || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
|
|
22081
23316
|
if (option.required || option.optional) {
|
|
22082
|
-
this.emit(`optionEnv:${option.name()}`,
|
|
23317
|
+
this.emit(`optionEnv:${option.name()}`, process10.env[option.envVar]);
|
|
22083
23318
|
} else {
|
|
22084
23319
|
this.emit(`optionEnv:${option.name()}`);
|
|
22085
23320
|
}
|
|
@@ -22275,13 +23510,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
22275
23510
|
cmd.helpGroup(this._defaultCommandGroup);
|
|
22276
23511
|
}
|
|
22277
23512
|
nameFromFilename(filename) {
|
|
22278
|
-
this._name =
|
|
23513
|
+
this._name = path3.basename(filename, path3.extname(filename));
|
|
22279
23514
|
return this;
|
|
22280
23515
|
}
|
|
22281
|
-
executableDir(
|
|
22282
|
-
if (
|
|
23516
|
+
executableDir(path) {
|
|
23517
|
+
if (path === undefined)
|
|
22283
23518
|
return this._executableDir;
|
|
22284
|
-
this._executableDir =
|
|
23519
|
+
this._executableDir = path;
|
|
22285
23520
|
return this;
|
|
22286
23521
|
}
|
|
22287
23522
|
helpInformation(contextOptions) {
|
|
@@ -22378,7 +23613,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
22378
23613
|
}
|
|
22379
23614
|
help(contextOptions) {
|
|
22380
23615
|
this.outputHelp(contextOptions);
|
|
22381
|
-
let exitCode = Number(
|
|
23616
|
+
let exitCode = Number(process10.exitCode ?? 0);
|
|
22382
23617
|
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
|
|
22383
23618
|
exitCode = 1;
|
|
22384
23619
|
}
|
|
@@ -22444,9 +23679,9 @@ function incrementNodeInspectorPort(args) {
|
|
|
22444
23679
|
});
|
|
22445
23680
|
}
|
|
22446
23681
|
function useColor() {
|
|
22447
|
-
if (
|
|
23682
|
+
if (process10.env.NO_COLOR || process10.env.FORCE_COLOR === "0" || process10.env.FORCE_COLOR === "false")
|
|
22448
23683
|
return false;
|
|
22449
|
-
if (
|
|
23684
|
+
if (process10.env.FORCE_COLOR || process10.env.CLICOLOR_FORCE !== undefined)
|
|
22450
23685
|
return true;
|
|
22451
23686
|
return;
|
|
22452
23687
|
}
|