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