negotium 0.22.8 → 0.23.1
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/README.md +1 -1
- package/dist/agent-helpers.js +2 -2
- package/dist/agent-helpers.js.map +2 -2
- package/dist/{chunk-5czvhd0g.js → chunk-w6xavjz2.js} +2 -2
- package/dist/{chunk-5czvhd0g.js.map → chunk-w6xavjz2.js.map} +2 -2
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +2 -2
- package/dist/main.js +1174 -120
- package/dist/main.js.map +11 -10
- package/dist/mcp-factories.js +2 -2
- package/dist/mcp-factories.js.map +2 -2
- package/dist/registry.js +1 -1
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +3 -2
package/dist/main.js
CHANGED
|
@@ -6559,7 +6559,7 @@ var exports_version = {};
|
|
|
6559
6559
|
__export(exports_version, {
|
|
6560
6560
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
|
|
6561
6561
|
});
|
|
6562
|
-
var NEGOTIUM_VERSION = "0.
|
|
6562
|
+
var NEGOTIUM_VERSION = "0.23.1";
|
|
6563
6563
|
|
|
6564
6564
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
6565
6565
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -41575,6 +41575,15 @@ function commandSuggestions(input) {
|
|
|
41575
41575
|
const normalized = token.toLowerCase();
|
|
41576
41576
|
return TERMINAL_COMMANDS.filter((command) => command.name.startsWith(normalized));
|
|
41577
41577
|
}
|
|
41578
|
+
function isKnownTerminalCommand(text3) {
|
|
41579
|
+
if (!text3.startsWith("/"))
|
|
41580
|
+
return false;
|
|
41581
|
+
const firstLine = text3.split(`
|
|
41582
|
+
`, 1)[0] ?? "";
|
|
41583
|
+
const [token = ""] = firstLine.slice(1).trim().split(/\s+/);
|
|
41584
|
+
const normalized = token.toLowerCase();
|
|
41585
|
+
return TERMINAL_COMMANDS.some((command) => command.name === normalized);
|
|
41586
|
+
}
|
|
41578
41587
|
function completeCommand(input, index) {
|
|
41579
41588
|
const suggestions = commandSuggestions(input);
|
|
41580
41589
|
if (suggestions.length === 0)
|
|
@@ -41929,7 +41938,14 @@ function createInitialState(userId) {
|
|
|
41929
41938
|
decisionGraphOffset: { x: 0, y: 0 },
|
|
41930
41939
|
decisionGraphSpacing: DEFAULT_DECISION_GRAPH_SPACING,
|
|
41931
41940
|
askChoiceIndex: 0,
|
|
41932
|
-
|
|
41941
|
+
taskPanelScrollOffset: 0,
|
|
41942
|
+
topicsPanelEnabled: true,
|
|
41943
|
+
topicsPanelScrollOffset: 0,
|
|
41944
|
+
sidePanelWidth: SIDE_PANEL_WIDTH_DEFAULT,
|
|
41945
|
+
terminalPaneOpen: false,
|
|
41946
|
+
terminalPaneFocused: false,
|
|
41947
|
+
terminalPaneWidth: null,
|
|
41948
|
+
topicsPanelSort: "activity",
|
|
41933
41949
|
overlay: null,
|
|
41934
41950
|
topicPickerRoot: false,
|
|
41935
41951
|
vaultEntries: [],
|
|
@@ -41941,8 +41957,45 @@ function createInitialState(userId) {
|
|
|
41941
41957
|
vaultRequestSubmitting: false
|
|
41942
41958
|
};
|
|
41943
41959
|
}
|
|
41944
|
-
function
|
|
41945
|
-
return { ...state,
|
|
41960
|
+
function toggleTopicsPanel(state) {
|
|
41961
|
+
return { ...state, topicsPanelEnabled: !state.topicsPanelEnabled };
|
|
41962
|
+
}
|
|
41963
|
+
function cycleTopicsPanelSort(state) {
|
|
41964
|
+
return { ...state, topicsPanelSort: state.topicsPanelSort === "activity" ? "name" : "activity" };
|
|
41965
|
+
}
|
|
41966
|
+
function openTerminalPane(state) {
|
|
41967
|
+
return { ...state, terminalPaneOpen: true, terminalPaneFocused: true };
|
|
41968
|
+
}
|
|
41969
|
+
function closeTerminalPane(state) {
|
|
41970
|
+
return { ...state, terminalPaneOpen: false, terminalPaneFocused: false };
|
|
41971
|
+
}
|
|
41972
|
+
function focusTerminalPane(state, focused) {
|
|
41973
|
+
const next = focused && state.terminalPaneOpen;
|
|
41974
|
+
return next === state.terminalPaneFocused ? state : { ...state, terminalPaneFocused: next };
|
|
41975
|
+
}
|
|
41976
|
+
function setTerminalPaneWidth(state, width, maxWidth) {
|
|
41977
|
+
const next = Math.max(TERMINAL_PANE_WIDTH_MIN, Math.min(Math.round(width), maxWidth));
|
|
41978
|
+
return next === state.terminalPaneWidth ? state : { ...state, terminalPaneWidth: next };
|
|
41979
|
+
}
|
|
41980
|
+
function setSidePanelWidth(state, width, maxWidth) {
|
|
41981
|
+
const next = Math.min(SIDE_PANEL_WIDTH_MAX, Math.max(SIDE_PANEL_WIDTH_MIN, Math.min(Math.round(width), maxWidth)));
|
|
41982
|
+
return next === state.sidePanelWidth ? state : { ...state, sidePanelWidth: next };
|
|
41983
|
+
}
|
|
41984
|
+
function scrollTopicsPanel(state, delta, maxOffset) {
|
|
41985
|
+
const next = Math.min(maxOffset, Math.max(0, state.topicsPanelScrollOffset + delta));
|
|
41986
|
+
return next === state.topicsPanelScrollOffset ? state : { ...state, topicsPanelScrollOffset: next };
|
|
41987
|
+
}
|
|
41988
|
+
function scrollTaskPanel(state, delta, maxOffset) {
|
|
41989
|
+
const next = Math.min(maxOffset, Math.max(0, state.taskPanelScrollOffset + delta));
|
|
41990
|
+
return next === state.taskPanelScrollOffset ? state : { ...state, taskPanelScrollOffset: next };
|
|
41991
|
+
}
|
|
41992
|
+
function setTopicsPanelScrollOffset(state, offset, maxOffset) {
|
|
41993
|
+
const next = Math.min(maxOffset, Math.max(0, offset));
|
|
41994
|
+
return next === state.topicsPanelScrollOffset ? state : { ...state, topicsPanelScrollOffset: next };
|
|
41995
|
+
}
|
|
41996
|
+
function setTaskPanelScrollOffset(state, offset, maxOffset) {
|
|
41997
|
+
const next = Math.min(maxOffset, Math.max(0, offset));
|
|
41998
|
+
return next === state.taskPanelScrollOffset ? state : { ...state, taskPanelScrollOffset: next };
|
|
41946
41999
|
}
|
|
41947
42000
|
function activeTopic(state) {
|
|
41948
42001
|
return state.topics.find((topic) => topic.id === state.activeTopicId) ?? null;
|
|
@@ -41959,6 +42012,16 @@ function setTopicUsage(state, usage) {
|
|
|
41959
42012
|
function activeQuestion(state) {
|
|
41960
42013
|
return activeMessages(state).slice().reverse().find((message2) => message2.kind === "ask_user_question" && message2.askUserQuestion && !message2.askUserQuestion.expired && !message2.askUserQuestion.selectedLabel) ?? null;
|
|
41961
42014
|
}
|
|
42015
|
+
function blockedQuestionText(state, topicId) {
|
|
42016
|
+
const messages = state.messages[topicId] ?? [];
|
|
42017
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
42018
|
+
const message2 = messages[index];
|
|
42019
|
+
if (message2.kind === "ask_user_question" && message2.askUserQuestion && !message2.askUserQuestion.expired && !message2.askUserQuestion.selectedLabel) {
|
|
42020
|
+
return message2.askUserQuestion.question;
|
|
42021
|
+
}
|
|
42022
|
+
}
|
|
42023
|
+
return;
|
|
42024
|
+
}
|
|
41962
42025
|
function activeVaultRequest(state) {
|
|
41963
42026
|
return activeMessages(state).find((message2) => message2.kind === "vault_secret_request" && message2.vaultSecretRequest?.status === "pending") ?? null;
|
|
41964
42027
|
}
|
|
@@ -42062,12 +42125,43 @@ function visibleTopicPickerIds(state) {
|
|
|
42062
42125
|
function visibleBackgroundSessions(state) {
|
|
42063
42126
|
return state.backgroundSessions.filter((session) => topicPickerQueryMatches(session.title, state.topicFilter));
|
|
42064
42127
|
}
|
|
42128
|
+
function topicRank(state, topic) {
|
|
42129
|
+
if (blockedQuestionText(state, topic.id) !== undefined)
|
|
42130
|
+
return 0;
|
|
42131
|
+
if (state.activity[topic.id]?.running)
|
|
42132
|
+
return 1;
|
|
42133
|
+
return 2;
|
|
42134
|
+
}
|
|
42135
|
+
function groupTopicsIntoUnits(entries) {
|
|
42136
|
+
const units = [];
|
|
42137
|
+
for (const entry of entries) {
|
|
42138
|
+
const last = units.at(-1);
|
|
42139
|
+
if (entry.topic.isSubagent && last)
|
|
42140
|
+
last.push(entry);
|
|
42141
|
+
else
|
|
42142
|
+
units.push([entry]);
|
|
42143
|
+
}
|
|
42144
|
+
return units;
|
|
42145
|
+
}
|
|
42146
|
+
function sortedTopicEntries(state, entries) {
|
|
42147
|
+
const units = groupTopicsIntoUnits(entries);
|
|
42148
|
+
if (state.topicsPanelSort === "name") {
|
|
42149
|
+
return units.slice().sort((a, b) => (a[0]?.topic.title ?? "").localeCompare(b[0]?.topic.title ?? "")).flat();
|
|
42150
|
+
}
|
|
42151
|
+
return units.map((unit, order) => ({
|
|
42152
|
+
unit,
|
|
42153
|
+
order,
|
|
42154
|
+
rank: Math.min(...unit.map(({ topic }) => topicRank(state, topic)))
|
|
42155
|
+
})).sort((a, b) => a.rank - b.rank || a.order - b.order).flatMap(({ unit }) => unit);
|
|
42156
|
+
}
|
|
42065
42157
|
function topicPickerItems(state) {
|
|
42066
42158
|
const visible = visibleTopicPickerIds(state);
|
|
42067
42159
|
const indexedTopics = state.topics.map((topic, index) => ({ topic, index })).filter(({ topic }) => visible.has(topic.id));
|
|
42160
|
+
const managerEntries = sortedTopicEntries(state, indexedTopics.filter(({ topic }) => topic.kind === "manager"));
|
|
42161
|
+
const regularEntries = sortedTopicEntries(state, indexedTopics.filter(({ topic }) => topic.kind !== "manager"));
|
|
42068
42162
|
return [
|
|
42069
|
-
...
|
|
42070
|
-
...
|
|
42163
|
+
...managerEntries.map(({ topic, index }) => ({ kind: "topic", id: topic.id, index })),
|
|
42164
|
+
...regularEntries.map(({ topic, index }) => ({ kind: "topic", id: topic.id, index })),
|
|
42071
42165
|
...visibleBackgroundSessions(state).map((session) => ({
|
|
42072
42166
|
kind: "background",
|
|
42073
42167
|
id: session.id
|
|
@@ -42359,6 +42453,22 @@ function failedToolText(text3) {
|
|
|
42359
42453
|
return [title, ...mapped].join(`
|
|
42360
42454
|
`);
|
|
42361
42455
|
}
|
|
42456
|
+
function appendToolOutput(text3, content) {
|
|
42457
|
+
if (!content.trim())
|
|
42458
|
+
return text3;
|
|
42459
|
+
const [title = "Tool"] = text3.split(`
|
|
42460
|
+
`);
|
|
42461
|
+
if (TOOL_OUTPUT_EXCLUDED_PREFIXES.some((prefix) => title.startsWith(prefix)))
|
|
42462
|
+
return text3;
|
|
42463
|
+
if (text3.includes(`
|
|
42464
|
+
`))
|
|
42465
|
+
return text3;
|
|
42466
|
+
const lines = content.replace(/\r\n?/g, `
|
|
42467
|
+
`).replace(/\n+$/, "").split(`
|
|
42468
|
+
`);
|
|
42469
|
+
return [title, ...lines].join(`
|
|
42470
|
+
`);
|
|
42471
|
+
}
|
|
42362
42472
|
function toolMessageId(status, toolUseId) {
|
|
42363
42473
|
return `terminal-tool:${String(status.queryId ?? "query")}:${toolUseId}`;
|
|
42364
42474
|
}
|
|
@@ -42458,14 +42568,17 @@ function applyAiStatus(state, topicId, raw, createdAt) {
|
|
|
42458
42568
|
return state;
|
|
42459
42569
|
const id = String(status.toolUseId ?? "");
|
|
42460
42570
|
const failed = status.isError === true;
|
|
42461
|
-
const
|
|
42571
|
+
const content = String(status.content ?? "");
|
|
42572
|
+
const tools = current3.tools.map((tool) => tool.id === id ? { ...tool, output: content, status: failed ? "error" : "done" } : tool);
|
|
42462
42573
|
const withActivity = setActivity(state, topicId, { ...liveCurrent, tools });
|
|
42463
42574
|
const messageId = toolMessageId(status, id);
|
|
42464
42575
|
const existing = (withActivity.messages[topicId] ?? []).find((message2) => message2.id === messageId);
|
|
42576
|
+
const withOutput = existing ? appendToolOutput(existing.text, content) : undefined;
|
|
42577
|
+
const nextText = failed && (!existing || withOutput === existing.text) ? failedToolText(existing?.text ?? "") : withOutput;
|
|
42465
42578
|
return patchMessage(withActivity, topicId, messageId, {
|
|
42466
42579
|
editedAt: createdAt ?? new Date().toISOString(),
|
|
42467
42580
|
toolResult: failed ? "error" : "ok",
|
|
42468
|
-
...
|
|
42581
|
+
...nextText !== undefined ? { text: nextText } : {}
|
|
42469
42582
|
});
|
|
42470
42583
|
}
|
|
42471
42584
|
if (kind === "tool_status") {
|
|
@@ -42498,11 +42611,18 @@ function applyRuntimeEvent(state, event) {
|
|
|
42498
42611
|
}
|
|
42499
42612
|
return state;
|
|
42500
42613
|
}
|
|
42501
|
-
var NO_TOPIC_PICKER_SELECTION = -1;
|
|
42614
|
+
var SIDE_PANEL_WIDTH_DEFAULT = 36, SIDE_PANEL_WIDTH_MIN = 22, SIDE_PANEL_WIDTH_MAX = 64, TERMINAL_PANE_WIDTH_MIN = 30, NO_TOPIC_PICKER_SELECTION = -1, TOOL_OUTPUT_EXCLUDED_PREFIXES;
|
|
42502
42615
|
var init_state2 = __esm(async () => {
|
|
42503
42616
|
init_decision_graph();
|
|
42504
42617
|
init_subagent_graph();
|
|
42505
42618
|
await init_src();
|
|
42619
|
+
TOOL_OUTPUT_EXCLUDED_PREFIXES = [
|
|
42620
|
+
"Edit \xB7 ",
|
|
42621
|
+
"Write \xB7 ",
|
|
42622
|
+
"Delete \xB7 ",
|
|
42623
|
+
"Ask session \xB7 ",
|
|
42624
|
+
"Tell session \xB7 "
|
|
42625
|
+
];
|
|
42506
42626
|
});
|
|
42507
42627
|
|
|
42508
42628
|
// ../../adapters/terminal/src/context-usage.ts
|
|
@@ -43615,7 +43735,6 @@ function toolMessageLines(message2, width) {
|
|
|
43615
43735
|
`);
|
|
43616
43736
|
const failed = message2.toolResult === "error";
|
|
43617
43737
|
const done = failed || Boolean(message2.editedAt);
|
|
43618
|
-
const fileMutation = /^(?:Edit|Write|Delete) \u00B7 /.test(title);
|
|
43619
43738
|
const wrapWidth = Math.max(4, width - 6);
|
|
43620
43739
|
const marker = failed ? "!" : done ? "\u2713" : "\u25CF";
|
|
43621
43740
|
const headerText = ` ${marker} ${title}`;
|
|
@@ -43631,14 +43750,8 @@ function toolMessageLines(message2, width) {
|
|
|
43631
43750
|
{ text: ")" }
|
|
43632
43751
|
] : [{ text: headerText, fg: headerColor }]
|
|
43633
43752
|
});
|
|
43634
|
-
if (!fileMutation) {
|
|
43635
|
-
return [
|
|
43636
|
-
header,
|
|
43637
|
-
...details.slice(0, 2).flatMap((detail) => wrapText(detail, wrapWidth).slice(0, 1).map((text3) => line(` ${text3}`, { fg: toolDetailColor(detail), dim: !failed })))
|
|
43638
|
-
];
|
|
43639
|
-
}
|
|
43640
43753
|
const wrapped = details.flatMap((detail) => wrapText(detail, wrapWidth).map((text3) => ({ detail, text: text3 })));
|
|
43641
|
-
const visible = wrapped.slice(0,
|
|
43754
|
+
const visible = wrapped.slice(0, TOOL_PREVIEW_MAX_LINES);
|
|
43642
43755
|
const hidden = wrapped.length - visible.length;
|
|
43643
43756
|
return [
|
|
43644
43757
|
header,
|
|
@@ -43743,50 +43856,269 @@ function taskLines(state, width) {
|
|
|
43743
43856
|
const visibleTasks = tasks3.slice(0, INLINE_TASK_LIMIT);
|
|
43744
43857
|
const hidden = tasks3.length - visibleTasks.length;
|
|
43745
43858
|
return [
|
|
43746
|
-
line(" \u25EB Tasks \xB7 Ctrl-
|
|
43859
|
+
line(" \u25EB Tasks \xB7 Ctrl-P sidebar", { fg: theme.amber, bold: true }),
|
|
43747
43860
|
...visibleTasks.flatMap((task) => wrapText(task.trimStart(), Math.max(4, width - 6)).map((text3) => line(` ${text3}`, { fg: theme.muted }))),
|
|
43748
43861
|
...hidden > 0 ? [line(` +${hidden} more`, { fg: theme.muted, dim: true })] : [],
|
|
43749
43862
|
line("")
|
|
43750
43863
|
];
|
|
43751
43864
|
}
|
|
43865
|
+
function maxSidePanelWidth(columns) {
|
|
43866
|
+
return Math.max(SIDE_PANEL_WIDTH_MIN, columns - SIDE_PANEL_GAP - CONVERSATION_MIN_WIDTH);
|
|
43867
|
+
}
|
|
43752
43868
|
function terminalBodyLayout(state, width) {
|
|
43753
|
-
const
|
|
43869
|
+
const terminalReserve = state.terminalPaneOpen ? TERMINAL_PANE_WIDTH_MIN + TERMINAL_PANE_GAP : 0;
|
|
43870
|
+
const wideEnough = width - terminalReserve >= SIDE_PANEL_MIN_WIDTH && state.topicsPanelEnabled && (!state.overlay || state.overlay === "background-session") && !state.creatingTopic;
|
|
43871
|
+
const showTaskPanel = wideEnough && taskItems(state).length > 0;
|
|
43872
|
+
const showTopicsPanel = wideEnough && (state.topics.length > 1 || visibleBackgroundSessions(state).length > 0);
|
|
43873
|
+
const showSide = showTaskPanel || showTopicsPanel;
|
|
43874
|
+
const maxSideWidth = maxSidePanelWidth(width) - terminalReserve;
|
|
43875
|
+
const sideWidth = showSide ? Math.min(SIDE_PANEL_WIDTH_MAX, Math.max(SIDE_PANEL_WIDTH_MIN, state.sidePanelWidth), maxSideWidth) : 0;
|
|
43876
|
+
const afterSide = showSide ? width - sideWidth - SIDE_PANEL_GAP : width;
|
|
43877
|
+
const maxTerminalWidth = afterSide - TERMINAL_PANE_GAP - CONVERSATION_MIN_WIDTH;
|
|
43878
|
+
const terminalWidth = state.terminalPaneOpen && maxTerminalWidth >= TERMINAL_PANE_WIDTH_MIN ? Math.min(maxTerminalWidth, Math.max(TERMINAL_PANE_WIDTH_MIN, state.terminalPaneWidth ?? Math.floor(afterSide * 0.32))) : 0;
|
|
43754
43879
|
return {
|
|
43755
|
-
conversationWidth:
|
|
43756
|
-
|
|
43757
|
-
|
|
43758
|
-
|
|
43880
|
+
conversationWidth: terminalWidth > 0 ? afterSide - terminalWidth - TERMINAL_PANE_GAP : afterSide,
|
|
43881
|
+
sideWidth,
|
|
43882
|
+
showTaskPanel,
|
|
43883
|
+
showTopicsPanel,
|
|
43884
|
+
terminalWidth,
|
|
43885
|
+
maxTerminalWidth: Math.max(TERMINAL_PANE_WIDTH_MIN, maxTerminalWidth)
|
|
43886
|
+
};
|
|
43887
|
+
}
|
|
43888
|
+
function maxTerminalPaneWidth(state, columns) {
|
|
43889
|
+
return terminalBodyLayout(state, Math.max(1, columns)).maxTerminalWidth;
|
|
43890
|
+
}
|
|
43891
|
+
function topicStatusIndicator(state, topic, animationFrame) {
|
|
43892
|
+
const blockedText = blockedQuestionText(state, topic.id);
|
|
43893
|
+
if (blockedText !== undefined)
|
|
43894
|
+
return { icon: "?", fg: theme.amber, blockedText };
|
|
43895
|
+
if (state.activity[topic.id]?.running) {
|
|
43896
|
+
return { icon: workingFrame(animationFrame), fg: theme.green };
|
|
43897
|
+
}
|
|
43898
|
+
return { icon: "\u25CB", fg: theme.muted };
|
|
43899
|
+
}
|
|
43900
|
+
function topicPanelRowLines(state, topic, topicIndex, animationFrame) {
|
|
43901
|
+
const selected = topic.id === state.activeTopicId;
|
|
43902
|
+
const hovered = !selected && topic.id === state.sidePanelHoverTopicId;
|
|
43903
|
+
const status = topicStatusIndicator(state, topic, animationFrame);
|
|
43904
|
+
const childPrefix = subagentTreePrefix(topic, state.topics);
|
|
43905
|
+
const bg2 = selected || hovered ? theme.selected : theme.canvas;
|
|
43906
|
+
const header = line(` ${selected ? "\u203A" : " "} ${childPrefix}${status.icon} ${topic.title}`, {
|
|
43907
|
+
fg: selected ? theme.text : status.fg,
|
|
43908
|
+
bg: bg2,
|
|
43909
|
+
bold: selected,
|
|
43910
|
+
pickerTarget: { topicIndex }
|
|
43911
|
+
});
|
|
43912
|
+
if (status.blockedText === undefined)
|
|
43913
|
+
return [header];
|
|
43914
|
+
return [
|
|
43915
|
+
header,
|
|
43916
|
+
line(` ${status.blockedText}`, {
|
|
43917
|
+
fg: theme.amber,
|
|
43918
|
+
bg: bg2,
|
|
43919
|
+
pickerTarget: { topicIndex }
|
|
43920
|
+
})
|
|
43921
|
+
];
|
|
43759
43922
|
}
|
|
43760
|
-
function
|
|
43923
|
+
function topicPanelGroupLines(state, label, entries, animationFrame) {
|
|
43924
|
+
if (entries.length === 0)
|
|
43925
|
+
return [];
|
|
43926
|
+
return [
|
|
43927
|
+
line(` ${label}`, { fg: theme.cyan, dim: true, bold: true, bg: theme.canvas }),
|
|
43928
|
+
...sortedTopicEntries(state, entries).flatMap(({ topic, topicIndex }) => topicPanelRowLines(state, topic, topicIndex, animationFrame))
|
|
43929
|
+
];
|
|
43930
|
+
}
|
|
43931
|
+
function topicsPanelRows(state, animationFrame) {
|
|
43932
|
+
const indexed = state.topics.map((topic, topicIndex) => ({ topic, topicIndex }));
|
|
43933
|
+
const managerEntries = indexed.filter(({ topic }) => topic.kind === "manager");
|
|
43934
|
+
const regularEntries = indexed.filter(({ topic }) => topic.kind !== "manager");
|
|
43935
|
+
const topicRows = [
|
|
43936
|
+
...topicPanelGroupLines(state, "manager", managerEntries, animationFrame),
|
|
43937
|
+
...topicPanelGroupLines(state, "topics", regularEntries, animationFrame)
|
|
43938
|
+
];
|
|
43939
|
+
const sessionRows = ["cron", "memory", "compact"].flatMap((kind) => {
|
|
43940
|
+
const matching = visibleBackgroundSessions(state).filter((session) => session.kind === kind);
|
|
43941
|
+
if (matching.length === 0)
|
|
43942
|
+
return [];
|
|
43943
|
+
return [
|
|
43944
|
+
line(` ${kind}`, { fg: theme.cyan, dim: true, bold: true, bg: theme.canvas }),
|
|
43945
|
+
...matching.map((session) => {
|
|
43946
|
+
const hovered = session.id === state.sidePanelHoverBackgroundSessionId;
|
|
43947
|
+
return line(` ${session.active ? workingFrame(animationFrame) : "\u25CB"} ${session.title}`, {
|
|
43948
|
+
fg: hovered ? theme.text : session.active ? theme.green : theme.muted,
|
|
43949
|
+
bg: hovered ? theme.selected : theme.canvas,
|
|
43950
|
+
pickerTarget: { backgroundSessionId: session.id }
|
|
43951
|
+
});
|
|
43952
|
+
})
|
|
43953
|
+
];
|
|
43954
|
+
});
|
|
43955
|
+
return [...topicRows, ...sessionRows];
|
|
43956
|
+
}
|
|
43957
|
+
function taskPanelRows(state, width) {
|
|
43761
43958
|
const items = taskItems(state);
|
|
43762
|
-
|
|
43959
|
+
return items.flatMap((task) => {
|
|
43763
43960
|
const completed = /^\s*(?:\[x\]|\u2612|\u2713|\u2705)/i.test(task);
|
|
43764
|
-
return wrapText(task.trimStart(), Math.max(4, width -
|
|
43961
|
+
return wrapText(task.trimStart(), Math.max(4, width - 2)).map((text3) => line(` ${text3}`, {
|
|
43765
43962
|
fg: completed ? theme.muted : theme.text,
|
|
43766
|
-
dim: completed
|
|
43963
|
+
dim: completed,
|
|
43964
|
+
bg: theme.canvas
|
|
43767
43965
|
}));
|
|
43768
43966
|
});
|
|
43769
|
-
|
|
43770
|
-
|
|
43771
|
-
|
|
43772
|
-
|
|
43773
|
-
|
|
43774
|
-
|
|
43775
|
-
|
|
43776
|
-
|
|
43777
|
-
|
|
43778
|
-
|
|
43779
|
-
|
|
43780
|
-
|
|
43781
|
-
|
|
43782
|
-
|
|
43783
|
-
|
|
43967
|
+
}
|
|
43968
|
+
function panelHeaderHeight(sectionHeight) {
|
|
43969
|
+
return Math.min(2, sectionHeight);
|
|
43970
|
+
}
|
|
43971
|
+
function panelContentHeight(sectionHeight) {
|
|
43972
|
+
return Math.max(0, sectionHeight - panelHeaderHeight(sectionHeight));
|
|
43973
|
+
}
|
|
43974
|
+
function scrollbarThumb(totalRows, viewportRows, offset) {
|
|
43975
|
+
if (viewportRows <= 0 || totalRows <= 0)
|
|
43976
|
+
return { top: 0, len: 0 };
|
|
43977
|
+
const len = Math.max(1, Math.min(viewportRows, Math.round(viewportRows * viewportRows / totalRows)));
|
|
43978
|
+
const maxThumbTop = Math.max(0, viewportRows - len);
|
|
43979
|
+
const maxOffset = Math.max(1, totalRows - viewportRows);
|
|
43980
|
+
const top = maxThumbTop === 0 ? 0 : Math.round(Math.min(offset, maxOffset) * maxThumbTop / maxOffset);
|
|
43981
|
+
return { top, len };
|
|
43982
|
+
}
|
|
43983
|
+
function scrollOffsetFromDragRow(totalRows, viewportRows, trackRow, grabRowOffset) {
|
|
43984
|
+
if (viewportRows <= 0 || totalRows <= 0)
|
|
43985
|
+
return 0;
|
|
43986
|
+
const { len } = scrollbarThumb(totalRows, viewportRows, 0);
|
|
43987
|
+
const maxThumbTop = Math.max(0, viewportRows - len);
|
|
43988
|
+
if (maxThumbTop === 0)
|
|
43989
|
+
return 0;
|
|
43990
|
+
const clampedRow = Math.max(0, Math.min(trackRow, viewportRows - 1));
|
|
43991
|
+
const desiredTop = Math.min(maxThumbTop, Math.max(0, clampedRow - grabRowOffset));
|
|
43992
|
+
const maxOffset = Math.max(0, totalRows - viewportRows);
|
|
43993
|
+
return Math.round(desiredTop * maxOffset / maxThumbTop);
|
|
43994
|
+
}
|
|
43995
|
+
function scrollbarCell(totalRows, viewportRows, offset, rowIndex, accent) {
|
|
43996
|
+
const thumb = scrollbarThumb(totalRows, viewportRows, offset);
|
|
43997
|
+
const isThumb = rowIndex >= thumb.top && rowIndex < thumb.top + thumb.len;
|
|
43998
|
+
return paint(isThumb ? "\u2590" : "\u2595", { fg: isThumb ? accent : theme.muted, bg: theme.canvas });
|
|
43999
|
+
}
|
|
44000
|
+
function renderPanelSection(label, rows, width, height, scrollOffset, accent) {
|
|
44001
|
+
if (height <= 0 || width <= 0)
|
|
44002
|
+
return { lines: [], rowTargets: [] };
|
|
44003
|
+
const headerHeight = panelHeaderHeight(height);
|
|
44004
|
+
const contentHeight = panelContentHeight(height);
|
|
44005
|
+
const overflow = rows.length > contentHeight;
|
|
44006
|
+
const textWidth = overflow ? Math.max(1, width - 1) : width;
|
|
44007
|
+
const clampedOffset = Math.max(0, Math.min(scrollOffset, Math.max(0, rows.length - contentHeight)));
|
|
44008
|
+
const visible = rows.slice(clampedOffset, clampedOffset + contentHeight);
|
|
44009
|
+
const lines = [];
|
|
44010
|
+
if (headerHeight >= 1)
|
|
44011
|
+
lines.push(paint("\u2500".repeat(width), { fg: theme.border, bg: theme.canvas }));
|
|
44012
|
+
if (headerHeight >= 2) {
|
|
44013
|
+
lines.push(paint(fit(` ${label}`, width), { fg: accent, bg: theme.canvas, bold: true }));
|
|
44014
|
+
}
|
|
44015
|
+
const rowTargets = [];
|
|
44016
|
+
for (let index = 0;index < contentHeight; index += 1) {
|
|
44017
|
+
const item = visible[index];
|
|
44018
|
+
const text3 = paint(fit(item?.text ?? "", textWidth), {
|
|
44019
|
+
fg: item?.fg ?? theme.text,
|
|
44020
|
+
bg: item?.bg ?? theme.canvas,
|
|
44021
|
+
bold: item?.bold,
|
|
44022
|
+
dim: item?.dim
|
|
44023
|
+
});
|
|
44024
|
+
const scrollCell = overflow ? scrollbarCell(rows.length, contentHeight, clampedOffset, index, accent) : "";
|
|
44025
|
+
lines.push(`${text3}${scrollCell}`);
|
|
44026
|
+
if (item?.pickerTarget)
|
|
44027
|
+
rowTargets.push({ y: headerHeight + index, pickerTarget: item.pickerTarget });
|
|
44028
|
+
}
|
|
44029
|
+
return {
|
|
44030
|
+
lines,
|
|
44031
|
+
rowTargets,
|
|
44032
|
+
track: overflow ? { x: width - 1, viewportRows: contentHeight, rowCount: rows.length } : undefined
|
|
44033
|
+
};
|
|
44034
|
+
}
|
|
44035
|
+
function sidePanelSectionHeights(layout, bodyHeight) {
|
|
44036
|
+
if (layout.showTopicsPanel && layout.showTaskPanel) {
|
|
44037
|
+
const topicsHeight = Math.max(3, Math.floor(bodyHeight / 2));
|
|
44038
|
+
return { topicsHeight, taskHeight: Math.max(0, bodyHeight - topicsHeight) };
|
|
44039
|
+
}
|
|
44040
|
+
if (layout.showTopicsPanel)
|
|
44041
|
+
return { topicsHeight: bodyHeight, taskHeight: 0 };
|
|
44042
|
+
if (layout.showTaskPanel)
|
|
44043
|
+
return { topicsHeight: 0, taskHeight: bodyHeight };
|
|
44044
|
+
return { topicsHeight: 0, taskHeight: 0 };
|
|
44045
|
+
}
|
|
44046
|
+
function renderSideColumn(state, layout, bodyHeight, animationFrame) {
|
|
44047
|
+
const { showTaskPanel, showTopicsPanel, sideWidth } = layout;
|
|
44048
|
+
if (!showTaskPanel && !showTopicsPanel)
|
|
44049
|
+
return { lines: [], targets: [], tracks: [] };
|
|
44050
|
+
const { topicsHeight, taskHeight } = sidePanelSectionHeights(layout, bodyHeight);
|
|
44051
|
+
const sections = [];
|
|
44052
|
+
if (showTopicsPanel) {
|
|
44053
|
+
sections.push({
|
|
44054
|
+
panel: "topics",
|
|
44055
|
+
label: state.topicsPanelSort === "activity" ? "ACTIVITY \xB7 name" : "activity \xB7 NAME",
|
|
44056
|
+
rows: topicsPanelRows(state, animationFrame),
|
|
44057
|
+
accent: theme.accent,
|
|
44058
|
+
height: topicsHeight,
|
|
44059
|
+
offset: 0,
|
|
44060
|
+
scrollOffset: state.topicsPanelScrollOffset
|
|
44061
|
+
});
|
|
44062
|
+
}
|
|
44063
|
+
if (showTaskPanel) {
|
|
44064
|
+
sections.push({
|
|
44065
|
+
panel: "tasks",
|
|
44066
|
+
label: "tasks",
|
|
44067
|
+
rows: taskPanelRows(state, sideWidth),
|
|
44068
|
+
accent: theme.taskBorder,
|
|
44069
|
+
height: taskHeight,
|
|
44070
|
+
offset: showTopicsPanel ? topicsHeight : 0,
|
|
44071
|
+
scrollOffset: state.taskPanelScrollOffset
|
|
44072
|
+
});
|
|
44073
|
+
}
|
|
44074
|
+
const lines = [];
|
|
44075
|
+
const targets = [];
|
|
44076
|
+
const tracks = [];
|
|
44077
|
+
for (const section of sections) {
|
|
44078
|
+
const result = renderPanelSection(section.label, section.rows, sideWidth, section.height, section.scrollOffset, section.accent);
|
|
44079
|
+
lines.push(...result.lines);
|
|
44080
|
+
for (const target of result.rowTargets) {
|
|
44081
|
+
targets.push({ y: section.offset + target.y, pickerTarget: target.pickerTarget });
|
|
44082
|
+
}
|
|
44083
|
+
if (result.track) {
|
|
44084
|
+
tracks.push({
|
|
44085
|
+
panel: section.panel,
|
|
44086
|
+
x: result.track.x,
|
|
44087
|
+
yStart: section.offset + panelHeaderHeight(section.height),
|
|
44088
|
+
viewportRows: result.track.viewportRows,
|
|
44089
|
+
rowCount: result.track.rowCount
|
|
44090
|
+
});
|
|
43784
44091
|
}
|
|
43785
|
-
rows.push(...group);
|
|
43786
|
-
shown += 1;
|
|
43787
44092
|
}
|
|
43788
|
-
|
|
43789
|
-
|
|
44093
|
+
while (lines.length < bodyHeight)
|
|
44094
|
+
lines.push(paint(" ".repeat(sideWidth), { bg: theme.canvas }));
|
|
44095
|
+
return { lines: lines.slice(0, bodyHeight), targets, tracks };
|
|
44096
|
+
}
|
|
44097
|
+
function maxTopicsPanelScrollOffset(state, columns, rows) {
|
|
44098
|
+
const width = Math.max(1, columns);
|
|
44099
|
+
const height = Math.max(14, rows);
|
|
44100
|
+
if (state.overlay)
|
|
44101
|
+
return 0;
|
|
44102
|
+
const layout = terminalBodyLayout(state, width);
|
|
44103
|
+
if (!layout.showTopicsPanel)
|
|
44104
|
+
return 0;
|
|
44105
|
+
const bodyHeight = Math.max(3, height - footerLines(state, width).length - decisionPane(state, width).length - vaultRequestPane(state, width).length - composerPane(state, layout.conversationWidth).lines.length);
|
|
44106
|
+
const { topicsHeight } = sidePanelSectionHeights(layout, bodyHeight);
|
|
44107
|
+
const viewport = panelContentHeight(topicsHeight);
|
|
44108
|
+
return Math.max(0, topicsPanelRows(state, 0).length - viewport);
|
|
44109
|
+
}
|
|
44110
|
+
function maxTaskPanelScrollOffset(state, columns, rows) {
|
|
44111
|
+
const width = Math.max(1, columns);
|
|
44112
|
+
const height = Math.max(14, rows);
|
|
44113
|
+
if (state.overlay)
|
|
44114
|
+
return 0;
|
|
44115
|
+
const layout = terminalBodyLayout(state, width);
|
|
44116
|
+
if (!layout.showTaskPanel)
|
|
44117
|
+
return 0;
|
|
44118
|
+
const bodyHeight = Math.max(3, height - footerLines(state, width).length - decisionPane(state, width).length - vaultRequestPane(state, width).length - composerPane(state, layout.conversationWidth).lines.length);
|
|
44119
|
+
const { taskHeight } = sidePanelSectionHeights(layout, bodyHeight);
|
|
44120
|
+
const viewport = panelContentHeight(taskHeight);
|
|
44121
|
+
return Math.max(0, taskPanelRows(state, layout.sideWidth).length - viewport);
|
|
43790
44122
|
}
|
|
43791
44123
|
function helpLines() {
|
|
43792
44124
|
return [
|
|
@@ -43796,7 +44128,10 @@ function helpLines() {
|
|
|
43796
44128
|
line(" \u2190 \u2192 move \xB7 Ctrl/Alt-\u2190 \u2192 move by word \xB7 \u2191 \u2193 history"),
|
|
43797
44129
|
line(" Alt-Backspace delete word \xB7 Ctrl-U clear before cursor"),
|
|
43798
44130
|
line(" Cmd-Backspace works when forwarded \xB7 Ctrl-W/K aliases"),
|
|
43799
|
-
line(" Mouse wheel / PgUp/PgDn scroll \xB7 Ctrl-E load older
|
|
44131
|
+
line(" Mouse wheel / PgUp/PgDn scroll \xB7 Ctrl-E load older"),
|
|
44132
|
+
line(" Ctrl-P topics + tasks panel \xB7 click/hover a row to switch \xB7 drag scrollbar"),
|
|
44133
|
+
line(" Ctrl-R sort topics panel (activity / name) \xB7 drag a \u2502 divider to resize"),
|
|
44134
|
+
line(" Ctrl-T open/close a shell on the right (closing ends it) \xB7 click it to type"),
|
|
43800
44135
|
line(" Ctrl-O topics \xB7 Ctrl-G subagents \xB7 Ctrl-D decisions \xB7 Ctrl-X abort"),
|
|
43801
44136
|
line(" In topics: type to filter \xB7 Ctrl-N new \xB7 Ctrl-D delete"),
|
|
43802
44137
|
line(" Esc/Ctrl-C stop active turn \xB7 Ctrl-C twice when idle to quit"),
|
|
@@ -43948,8 +44283,8 @@ function topicOverlayCursor(state, width, bodyHeight) {
|
|
|
43948
44283
|
function topicOverlayLines(state, width, height, animationFrame = 0) {
|
|
43949
44284
|
const visibleIds = visibleTopicPickerIds(state);
|
|
43950
44285
|
const indexedTopics = state.topics.map((topic, topicIndex) => ({ topic, topicIndex })).filter(({ topic }) => visibleIds.has(topic.id));
|
|
43951
|
-
const managerTopics = indexedTopics.filter(({ topic }) => topic.kind === "manager");
|
|
43952
|
-
const regularTopics = indexedTopics.filter(({ topic }) => topic.kind !== "manager");
|
|
44286
|
+
const managerTopics = sortedTopicEntries(state, indexedTopics.filter(({ topic }) => topic.kind === "manager"));
|
|
44287
|
+
const regularTopics = sortedTopicEntries(state, indexedTopics.filter(({ topic }) => topic.kind !== "manager"));
|
|
43953
44288
|
const entries = [];
|
|
43954
44289
|
for (const [label, topics] of [
|
|
43955
44290
|
["Manager", managerTopics],
|
|
@@ -43997,30 +44332,48 @@ function topicOverlayLines(state, width, height, animationFrame = 0) {
|
|
|
43997
44332
|
query2.length > 0 ? line(`${TOPIC_FILTER_LABEL}${safeText(query2)}`, { fg: theme.cyan, bold: true }) : line(""),
|
|
43998
44333
|
...entries.length === 0 ? [
|
|
43999
44334
|
line(query2.length > 0 ? ` No topics match \u201C${safeText(query2)}\u201D \xB7 Esc clears the filter` : " No topics yet \xB7 Press Ctrl-N to create one", { fg: theme.muted })
|
|
44000
|
-
] : entries.slice(start, start + visibleCount).
|
|
44335
|
+
] : entries.slice(start, start + visibleCount).flatMap((entry) => {
|
|
44001
44336
|
if (entry.kind === "heading") {
|
|
44002
|
-
return line(` ${entry.label}`, { fg: theme.cyan, bold: true });
|
|
44337
|
+
return [line(` ${entry.label}`, { fg: theme.cyan, bold: true })];
|
|
44003
44338
|
}
|
|
44004
44339
|
if (entry.kind === "separator") {
|
|
44005
|
-
return line(` ${"\u2500".repeat(Math.max(1, width - 4))}`, { fg: theme.border });
|
|
44340
|
+
return [line(` ${"\u2500".repeat(Math.max(1, width - 4))}`, { fg: theme.border })];
|
|
44006
44341
|
}
|
|
44007
44342
|
if (entry.kind === "background") {
|
|
44008
44343
|
const selected2 = entry.sessionId === state.topicPickerBackgroundId;
|
|
44009
|
-
return
|
|
44010
|
-
|
|
44011
|
-
|
|
44012
|
-
|
|
44013
|
-
|
|
44344
|
+
return [
|
|
44345
|
+
line(` ${selected2 ? "\u203A" : " "} ${entry.active ? workingFrame(animationFrame) : "\u25CB"} ${entry.label} \xB7 ${entry.status}`, {
|
|
44346
|
+
fg: selected2 ? theme.text : entry.active ? theme.green : theme.muted,
|
|
44347
|
+
bg: selected2 ? theme.selected : theme.canvas,
|
|
44348
|
+
bold: selected2,
|
|
44349
|
+
pickerTarget: { backgroundSessionId: entry.sessionId }
|
|
44350
|
+
})
|
|
44351
|
+
];
|
|
44014
44352
|
}
|
|
44015
44353
|
const { topic, topicIndex } = entry;
|
|
44016
44354
|
const selected = topicIndex === state.topicPickerIndex;
|
|
44017
|
-
const
|
|
44355
|
+
const status = topicStatusIndicator(state, topic, animationFrame);
|
|
44018
44356
|
const childPrefix = subagentTreePrefix(topic, state.topics);
|
|
44019
|
-
|
|
44020
|
-
|
|
44021
|
-
|
|
44022
|
-
|
|
44357
|
+
const bg2 = selected ? theme.selected : theme.canvas;
|
|
44358
|
+
const header = line(` ${selected ? "\u203A" : " "} ${childPrefix}${status.icon} ${topic.title} \xB7 ${topic.agent ?? "no agent"} \xB7 ${effectiveTopicModel(topic)} \xB7 ${effectiveTopicEffort(topic)}`, {
|
|
44359
|
+
fg: selected ? theme.text : status.fg,
|
|
44360
|
+
bg: bg2,
|
|
44361
|
+
bold: selected,
|
|
44362
|
+
pickerTarget: { topicIndex }
|
|
44023
44363
|
});
|
|
44364
|
+
const running = state.activity[topic.id]?.running;
|
|
44365
|
+
const subtitle = status.blockedText ?? (running ? activityDetail(state.activity[topic.id]?.status) : undefined);
|
|
44366
|
+
if (!subtitle)
|
|
44367
|
+
return [header];
|
|
44368
|
+
return [
|
|
44369
|
+
header,
|
|
44370
|
+
line(` ${subtitle}`, {
|
|
44371
|
+
fg: status.blockedText !== undefined ? theme.amber : theme.muted,
|
|
44372
|
+
dim: status.blockedText === undefined,
|
|
44373
|
+
bg: bg2,
|
|
44374
|
+
pickerTarget: { topicIndex }
|
|
44375
|
+
})
|
|
44376
|
+
];
|
|
44024
44377
|
})
|
|
44025
44378
|
];
|
|
44026
44379
|
}
|
|
@@ -44366,6 +44719,16 @@ function conversationViewport(lineCount, height, requestedOffset) {
|
|
|
44366
44719
|
offset: Math.min(maxOffset, Math.max(0, requestedOffset))
|
|
44367
44720
|
};
|
|
44368
44721
|
}
|
|
44722
|
+
function popupPaneWidth(width) {
|
|
44723
|
+
return Math.max(0, Math.min(POPUP_PANE_MAX_WIDTH, width - 4));
|
|
44724
|
+
}
|
|
44725
|
+
function centerPaneRows(rows, boxWidth, totalWidth) {
|
|
44726
|
+
const left = Math.max(0, Math.floor((totalWidth - boxWidth) / 2));
|
|
44727
|
+
const right = Math.max(0, totalWidth - boxWidth - left);
|
|
44728
|
+
const leftPad = left > 0 ? paint(" ".repeat(left), { bg: theme.canvas }) : "";
|
|
44729
|
+
const rightPad = right > 0 ? paint(" ".repeat(right), { bg: theme.canvas }) : "";
|
|
44730
|
+
return rows.map((row) => `${leftPad}${row}${rightPad}`);
|
|
44731
|
+
}
|
|
44369
44732
|
function decisionPane(state, width) {
|
|
44370
44733
|
if (state.overlay)
|
|
44371
44734
|
return [];
|
|
@@ -44376,6 +44739,7 @@ function decisionPane(state, width) {
|
|
|
44376
44739
|
if (!ask || !question?.choices.length)
|
|
44377
44740
|
return [];
|
|
44378
44741
|
const selected = Math.min(state.askChoiceIndex, question.choices.length - 1);
|
|
44742
|
+
const boxWidth = popupPaneWidth(width);
|
|
44379
44743
|
const content = [
|
|
44380
44744
|
line(` ${question.question}`, { bold: true }),
|
|
44381
44745
|
...question.choices.map((choice, index) => line(` ${index === selected ? "\u25CF" : "\u25CB"} ${choice.label}${choice.description ? ` \u2014 ${choice.description}` : ""}`, {
|
|
@@ -44384,7 +44748,8 @@ function decisionPane(state, width) {
|
|
|
44384
44748
|
bold: index === selected
|
|
44385
44749
|
}))
|
|
44386
44750
|
];
|
|
44387
|
-
|
|
44751
|
+
const rows = framePane("decision required \xB7 \u2191\u2193 select \xB7 Enter confirm", content, boxWidth, Math.min(8, Math.max(4, content.length + 2)), { active: true, accent: theme.amber });
|
|
44752
|
+
return centerPaneRows(rows, boxWidth, width);
|
|
44388
44753
|
}
|
|
44389
44754
|
function vaultRequestPane(state, width) {
|
|
44390
44755
|
if (state.overlay)
|
|
@@ -44393,15 +44758,17 @@ function vaultRequestPane(state, width) {
|
|
|
44393
44758
|
if (!request)
|
|
44394
44759
|
return [];
|
|
44395
44760
|
const declining = state.vaultRequestMode === "confirm-decline";
|
|
44761
|
+
const boxWidth = popupPaneWidth(width);
|
|
44396
44762
|
const content = [
|
|
44397
44763
|
line(` ${request.key}`, { bold: true }),
|
|
44398
|
-
...request.description ? wrapText(request.description, Math.max(4,
|
|
44764
|
+
...request.description ? wrapText(request.description, Math.max(4, boxWidth - 6)).map((text3) => line(` ${text3}`, { fg: theme.muted })) : [],
|
|
44399
44765
|
declining ? line(" Decline this request? y / n", { fg: theme.red, bold: true }) : line(" Enter save to Vault \xB7 Esc clear / decline \xB7 Alt-Enter newline", {
|
|
44400
44766
|
fg: theme.subtle
|
|
44401
44767
|
}),
|
|
44402
44768
|
...state.vaultRequestNotice ? [line(` ! ${state.vaultRequestNotice}`, { fg: theme.amber })] : []
|
|
44403
44769
|
];
|
|
44404
|
-
|
|
44770
|
+
const rows = framePane(`secret requested by ${state.aiName} \xB7 never shown to the agent${state.vaultRequestSubmitting ? ` \xB7 ${workingFrame(0)} saving` : ""}`, content, boxWidth, Math.min(8, Math.max(4, content.length + 2)), { active: true, accent: theme.accent });
|
|
44771
|
+
return centerPaneRows(rows, boxWidth, width);
|
|
44405
44772
|
}
|
|
44406
44773
|
function wrapLineWithCursor(value, codePointColumn, width) {
|
|
44407
44774
|
const chars = Array.from(safeText(value));
|
|
@@ -44475,8 +44842,25 @@ function inputVisualLines(state, width) {
|
|
|
44475
44842
|
}
|
|
44476
44843
|
return { lines: result, cursorLine, cursorColumn };
|
|
44477
44844
|
}
|
|
44845
|
+
function shiftLines(lines, marginWidth) {
|
|
44846
|
+
if (marginWidth <= 0)
|
|
44847
|
+
return lines;
|
|
44848
|
+
const margin = paint(" ".repeat(marginWidth), { bg: theme.canvas });
|
|
44849
|
+
return lines.map((row) => `${margin}${row}`);
|
|
44850
|
+
}
|
|
44851
|
+
function shiftComposerPane(pane, marginWidth) {
|
|
44852
|
+
if (marginWidth <= 0)
|
|
44853
|
+
return pane;
|
|
44854
|
+
return {
|
|
44855
|
+
lines: shiftLines(pane.lines, marginWidth),
|
|
44856
|
+
cursor: { x: pane.cursor.x + marginWidth, y: pane.cursor.y }
|
|
44857
|
+
};
|
|
44858
|
+
}
|
|
44859
|
+
function shortcutHint(width) {
|
|
44860
|
+
return SHORTCUT_HINTS.find((hint) => displayWidth(hint) + 2 <= width) ?? SHORTCUT_HINTS[2];
|
|
44861
|
+
}
|
|
44478
44862
|
function composerPane(state, width) {
|
|
44479
|
-
const title = state.creatingTopic ? "new topic \xB7 type a name \xB7 Enter create" : state.overlay === "vault" ? state.vaultMode === "list" ? "Vault command \xB7 Enter run \xB7 Esc close" : `${state.vaultMode === "key" ? "key" : state.vaultMode === "value" ? "secret value" : "description"} \xB7 Enter continue \xB7 Esc cancel` :
|
|
44863
|
+
const title = state.creatingTopic ? "new topic \xB7 type a name \xB7 Enter create" : state.overlay === "vault" ? state.vaultMode === "list" ? "Vault command \xB7 Enter run \xB7 Esc close" : `${state.vaultMode === "key" ? "key" : state.vaultMode === "value" ? "secret value" : "description"} \xB7 Enter continue \xB7 Esc cancel` : shortcutHint(width);
|
|
44480
44864
|
const visual = inputVisualLines(state, width);
|
|
44481
44865
|
let inputStart = Math.max(0, visual.lines.length - 5);
|
|
44482
44866
|
if (visual.cursorLine < inputStart)
|
|
@@ -44715,43 +45099,173 @@ function renderBody(lines, width, height) {
|
|
|
44715
45099
|
function renderApp(state, columns, rows, animationFrame = 0, nowMs = terminalNowMs()) {
|
|
44716
45100
|
return renderAppFrame(state, columns, rows, animationFrame, nowMs).frame;
|
|
44717
45101
|
}
|
|
44718
|
-
function renderAppFrame(state, columns, rows, animationFrame = 0, nowMs = terminalNowMs()) {
|
|
45102
|
+
function renderAppFrame(state, columns, rows, animationFrame = 0, nowMs = terminalNowMs(), extras = {}) {
|
|
44719
45103
|
const width = Math.max(1, columns);
|
|
44720
45104
|
const height = Math.max(14, rows);
|
|
44721
|
-
const
|
|
44722
|
-
const
|
|
45105
|
+
const layout = terminalBodyLayout(state, width);
|
|
45106
|
+
const conversationXStart = layout.sideWidth > 0 ? layout.sideWidth + SIDE_PANEL_GAP + 1 : 1;
|
|
45107
|
+
const footer = shiftLines(footerLines(state, layout.conversationWidth), conversationXStart - 1);
|
|
45108
|
+
const decision = shiftLines([
|
|
45109
|
+
...decisionPane(state, layout.conversationWidth),
|
|
45110
|
+
...vaultRequestPane(state, layout.conversationWidth)
|
|
45111
|
+
], conversationXStart - 1);
|
|
44723
45112
|
const hideComposer = state.overlay === "background-session" || state.overlay === "topics" || state.overlay === "subagents" || state.overlay === "decisions" || state.overlay === "vault" && state.vaultMode === "confirm-delete";
|
|
44724
|
-
const composer = hideComposer ? { lines: [], cursor: null } : composerPane(state,
|
|
45113
|
+
const composer = hideComposer ? { lines: [], cursor: null } : shiftComposerPane(composerPane(state, layout.conversationWidth), conversationXStart - 1);
|
|
44725
45114
|
const bodyHeight = Math.max(3, height - footer.length - decision.length - composer.lines.length);
|
|
44726
|
-
const
|
|
44727
|
-
const conversation = conversationLines(state, layout.conversationWidth, bodyHeight, animationFrame, nowMs, !layout.showTaskSidebar);
|
|
45115
|
+
const conversation = conversationLines(state, layout.conversationWidth, bodyHeight, animationFrame, nowMs, !layout.showTaskPanel);
|
|
44728
45116
|
const conversationBody = renderBody(conversation, layout.conversationWidth, bodyHeight);
|
|
44729
|
-
const
|
|
44730
|
-
|
|
44731
|
-
|
|
44732
|
-
|
|
44733
|
-
const gap = paint(" ".repeat(TASK_SIDEBAR_GAP), { bg: theme.canvas });
|
|
44734
|
-
return conversationBody.map((row, index) => `${row}${gap}${taskPane[index] ?? ""}`);
|
|
45117
|
+
const sideColumn = layout.showTaskPanel || layout.showTopicsPanel ? renderSideColumn(state, layout, bodyHeight, animationFrame) : null;
|
|
45118
|
+
const body = sideColumn?.lines.length ? (() => {
|
|
45119
|
+
const gap = paint("\u2502".repeat(SIDE_PANEL_GAP), { fg: theme.border, bg: theme.canvas });
|
|
45120
|
+
return sideColumn.lines.map((row, index) => `${row}${gap}${conversationBody[index] ?? ""}`);
|
|
44735
45121
|
})() : conversationBody;
|
|
44736
45122
|
const codeCopyTargets = conversation.flatMap((item, index) => {
|
|
44737
45123
|
if (item.codeCopy === undefined || index >= bodyHeight)
|
|
44738
45124
|
return [];
|
|
44739
45125
|
const trimmed = item.text.trimEnd();
|
|
44740
45126
|
const leading = trimmed.length - trimmed.trimStart().length;
|
|
44741
|
-
const xStart = displayWidth(trimmed.slice(0, leading))
|
|
44742
|
-
const xEnd = Math.min(displayWidth(trimmed),
|
|
45127
|
+
const xStart = conversationXStart + displayWidth(trimmed.slice(0, leading));
|
|
45128
|
+
const xEnd = Math.min(conversationXStart - 1 + displayWidth(trimmed), width);
|
|
44743
45129
|
return xEnd >= xStart ? [{ xStart, xEnd, y: index + 1, text: item.codeCopy }] : [];
|
|
44744
45130
|
});
|
|
45131
|
+
const overlayTargets = conversation.flatMap((item, index) => {
|
|
45132
|
+
if (!item.pickerTarget || index >= bodyHeight)
|
|
45133
|
+
return [];
|
|
45134
|
+
return [{ xStart: 1, xEnd: layout.conversationWidth, y: index + 1, ...item.pickerTarget }];
|
|
45135
|
+
});
|
|
45136
|
+
const sidePanelTargets = (sideColumn?.targets ?? []).map((target) => ({
|
|
45137
|
+
xStart: 1,
|
|
45138
|
+
xEnd: layout.sideWidth,
|
|
45139
|
+
y: target.y + 1,
|
|
45140
|
+
...target.pickerTarget
|
|
45141
|
+
}));
|
|
45142
|
+
const topicPickerTargets = [...overlayTargets, ...sidePanelTargets];
|
|
45143
|
+
const sidePanelTracks = (sideColumn?.tracks ?? []).map((track) => ({
|
|
45144
|
+
...track,
|
|
45145
|
+
x: 1 + track.x,
|
|
45146
|
+
yStart: track.yStart + 1
|
|
45147
|
+
}));
|
|
45148
|
+
const sideColumnBounds = sideColumn ? (() => {
|
|
45149
|
+
const { topicsHeight, taskHeight } = sidePanelSectionHeights(layout, bodyHeight);
|
|
45150
|
+
const sections = [];
|
|
45151
|
+
let offset = 0;
|
|
45152
|
+
if (layout.showTopicsPanel) {
|
|
45153
|
+
sections.push({ panel: "topics", yStart: offset + 1, yEnd: offset + topicsHeight });
|
|
45154
|
+
offset += topicsHeight;
|
|
45155
|
+
}
|
|
45156
|
+
if (layout.showTaskPanel) {
|
|
45157
|
+
sections.push({ panel: "tasks", yStart: offset + 1, yEnd: offset + taskHeight });
|
|
45158
|
+
}
|
|
45159
|
+
return { xStart: 1, xEnd: layout.sideWidth, sections };
|
|
45160
|
+
})() : null;
|
|
45161
|
+
const sidePanelResizeHandle = sideColumn ? {
|
|
45162
|
+
xStart: Math.max(1, layout.sideWidth),
|
|
45163
|
+
xEnd: layout.sideWidth + SIDE_PANEL_GAP,
|
|
45164
|
+
yStart: 1,
|
|
45165
|
+
yEnd: bodyHeight
|
|
45166
|
+
} : null;
|
|
44745
45167
|
const cursorY = composer.cursor ? body.length + decision.length + composer.cursor.y : Number.POSITIVE_INFINITY;
|
|
44746
45168
|
const overlayCursor = topicOverlayCursor(state, layout.conversationWidth, body.length);
|
|
44747
|
-
const
|
|
45169
|
+
const leftRows = [...body, ...decision, ...composer.lines, ...footer].slice(0, height);
|
|
45170
|
+
let terminalPane = null;
|
|
45171
|
+
let frameRows = leftRows;
|
|
45172
|
+
if (layout.terminalWidth > 0) {
|
|
45173
|
+
const leftWidth = width - layout.terminalWidth - TERMINAL_PANE_GAP;
|
|
45174
|
+
const shellRows = shellPaneRows(extras.shell ?? null, layout.terminalWidth, leftRows.length);
|
|
45175
|
+
const divider = paint("\u2502".repeat(TERMINAL_PANE_GAP), {
|
|
45176
|
+
fg: state.terminalPaneFocused ? theme.borderActive : theme.border,
|
|
45177
|
+
bg: theme.canvas
|
|
45178
|
+
});
|
|
45179
|
+
frameRows = leftRows.map((row, index) => `${padToWidth(row, leftWidth)}${divider}${shellRows[index] ?? ""}`);
|
|
45180
|
+
terminalPane = {
|
|
45181
|
+
xStart: leftWidth + TERMINAL_PANE_GAP + 1,
|
|
45182
|
+
xEnd: width,
|
|
45183
|
+
yStart: 1,
|
|
45184
|
+
yEnd: leftRows.length,
|
|
45185
|
+
dividerX: leftWidth + 1,
|
|
45186
|
+
cols: layout.terminalWidth,
|
|
45187
|
+
rows: leftRows.length
|
|
45188
|
+
};
|
|
45189
|
+
}
|
|
45190
|
+
const shellCursor = terminalPane && state.terminalPaneFocused && extras.shell?.cursor ? {
|
|
45191
|
+
x: terminalPane.xStart + extras.shell.cursor.x,
|
|
45192
|
+
y: terminalPane.yStart + extras.shell.cursor.y
|
|
45193
|
+
} : null;
|
|
45194
|
+
const cursor = state.terminalPaneFocused && terminalPane ? shellCursor : composer.cursor && cursorY <= height ? { x: Math.min(composer.cursor.x, width), y: cursorY } : overlayCursor && overlayCursor.y <= height ? overlayCursor : null;
|
|
44748
45195
|
return {
|
|
44749
|
-
frame: linkifyUrls(
|
|
45196
|
+
frame: linkifyUrls(frameRows.join(`
|
|
44750
45197
|
`)),
|
|
44751
45198
|
cursor,
|
|
44752
|
-
codeCopyTargets
|
|
45199
|
+
codeCopyTargets,
|
|
45200
|
+
topicPickerTargets,
|
|
45201
|
+
sidePanelTracks,
|
|
45202
|
+
sideColumnBounds,
|
|
45203
|
+
sidePanelResizeHandle,
|
|
45204
|
+
conversationBounds: {
|
|
45205
|
+
xStart: conversationXStart,
|
|
45206
|
+
xEnd: conversationXStart + layout.conversationWidth - 1
|
|
45207
|
+
},
|
|
45208
|
+
terminalPane
|
|
44753
45209
|
};
|
|
44754
45210
|
}
|
|
45211
|
+
function padToWidth(row, width) {
|
|
45212
|
+
const visible = displayWidth(stripAnsi(row));
|
|
45213
|
+
return visible >= width ? row : `${row}${paint(" ".repeat(width - visible), { bg: theme.canvas })}`;
|
|
45214
|
+
}
|
|
45215
|
+
function shellColorCode(color, background, fallback) {
|
|
45216
|
+
if (color.kind === "rgb")
|
|
45217
|
+
return background ? bg(color.rgb) : fg(color.rgb);
|
|
45218
|
+
if (color.kind === "palette") {
|
|
45219
|
+
const index = color.index;
|
|
45220
|
+
if (index < 8)
|
|
45221
|
+
return `${ESC}${(background ? 40 : 30) + index}m`;
|
|
45222
|
+
if (index < 16)
|
|
45223
|
+
return `${ESC}${(background ? 100 : 90) + index - 8}m`;
|
|
45224
|
+
return `${ESC}${background ? 48 : 38};5;${index}m`;
|
|
45225
|
+
}
|
|
45226
|
+
return background ? bg(fallback) : fg(fallback);
|
|
45227
|
+
}
|
|
45228
|
+
function paintShellRun(run) {
|
|
45229
|
+
if (colorDepth === "none")
|
|
45230
|
+
return run.text;
|
|
45231
|
+
const fgColor = run.inverse ? run.bg : run.fg;
|
|
45232
|
+
const bgColor = run.inverse ? run.fg : run.bg;
|
|
45233
|
+
const fgFallback = run.inverse ? theme.canvas : theme.text;
|
|
45234
|
+
const bgFallback = run.inverse ? theme.text : theme.canvas;
|
|
45235
|
+
return `${shellColorCode(fgColor, false, fgFallback)}${shellColorCode(bgColor, true, bgFallback)}${run.bold ? `${ESC}1m` : ""}${run.dim ? `${ESC}2m` : ""}${run.italic ? `${ESC}3m` : ""}${run.underline ? `${ESC}4m` : ""}${run.text}${RESET}`;
|
|
45236
|
+
}
|
|
45237
|
+
function shellPaneRows(snapshot, width, height) {
|
|
45238
|
+
const rows = [];
|
|
45239
|
+
for (let index = 0;index < height; index += 1) {
|
|
45240
|
+
const runs = snapshot?.lines[index];
|
|
45241
|
+
if (!runs) {
|
|
45242
|
+
const text3 = !snapshot && index === 0 ? fit(" starting shell\u2026", width) : " ".repeat(width);
|
|
45243
|
+
rows.push(paint(text3, { fg: theme.muted, bg: theme.canvas }));
|
|
45244
|
+
continue;
|
|
45245
|
+
}
|
|
45246
|
+
let used = 0;
|
|
45247
|
+
let row = "";
|
|
45248
|
+
for (const run of runs) {
|
|
45249
|
+
if (used >= width)
|
|
45250
|
+
break;
|
|
45251
|
+
if (used + run.width > width) {
|
|
45252
|
+
row += paintShellRun({
|
|
45253
|
+
...run,
|
|
45254
|
+
text: sliceWidth(run.text, width - used),
|
|
45255
|
+
width: width - used
|
|
45256
|
+
});
|
|
45257
|
+
used = width;
|
|
45258
|
+
break;
|
|
45259
|
+
}
|
|
45260
|
+
row += paintShellRun(run);
|
|
45261
|
+
used += run.width;
|
|
45262
|
+
}
|
|
45263
|
+
if (used < width)
|
|
45264
|
+
row += paint(" ".repeat(width - used), { bg: theme.canvas });
|
|
45265
|
+
rows.push(row);
|
|
45266
|
+
}
|
|
45267
|
+
return rows;
|
|
45268
|
+
}
|
|
44755
45269
|
function maxConversationScrollOffset(state, columns, rows) {
|
|
44756
45270
|
const width = Math.max(1, columns);
|
|
44757
45271
|
const height = Math.max(14, rows);
|
|
@@ -44761,9 +45275,9 @@ function maxConversationScrollOffset(state, columns, rows) {
|
|
|
44761
45275
|
}
|
|
44762
45276
|
if (state.overlay)
|
|
44763
45277
|
return 0;
|
|
44764
|
-
const bodyHeight = Math.max(3, height - footerLines(state, width).length - decisionPane(state, width).length - vaultRequestPane(state, width).length - composerPane(state, width).lines.length);
|
|
44765
45278
|
const layout = terminalBodyLayout(state, width);
|
|
44766
|
-
const
|
|
45279
|
+
const bodyHeight = Math.max(3, height - footerLines(state, width).length - decisionPane(state, width).length - vaultRequestPane(state, width).length - composerPane(state, layout.conversationWidth).lines.length);
|
|
45280
|
+
const lineCount = conversationContentLines(state, layout.conversationWidth, 0, terminalNowMs(), !layout.showTaskPanel).length;
|
|
44767
45281
|
return conversationViewport(lineCount, bodyHeight, state.scrollOffset).maxOffset;
|
|
44768
45282
|
}
|
|
44769
45283
|
function preserveConversationScrollAnchor(previous, next, columns, rows) {
|
|
@@ -44801,7 +45315,7 @@ var theme, WORKING_FRAMES, CODE_COPY_MARKER = "\u29C9", WORKING_FRAME_INTERVAL_M
|
|
|
44801
45315
|
default:
|
|
44802
45316
|
return `${ESC}48;2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
|
|
44803
45317
|
}
|
|
44804
|
-
}, BARE_URL_PATTERN, URL_TRAILING_PUNCTUATION, RENDERED_TAB_WIDTH = 4, CIRCLED_DIGIT_START = 9312, CIRCLED_DIGIT_END = 9331, CIRCLED_ZERO = 9450, isWrapSpace = (character) => character === " " || character === "\t", isWideBreak = (character) => runeWidth(character) === 2, NO_ROW_START, NO_ROW_END, WRAP_MIN_WIDTH = 2, FRAME_MIN_INNER_WIDTH = 4, FRAME_TITLE_MIN_INNER_WIDTH = 8, TABLE_MAX_WIDTH_FRACTION = 0.92, TABLE_MIN_COL_WIDTH = 4,
|
|
45318
|
+
}, BARE_URL_PATTERN, URL_TRAILING_PUNCTUATION, RENDERED_TAB_WIDTH = 4, CIRCLED_DIGIT_START = 9312, CIRCLED_DIGIT_END = 9331, CIRCLED_ZERO = 9450, isWrapSpace = (character) => character === " " || character === "\t", isWideBreak = (character) => runeWidth(character) === 2, NO_ROW_START, NO_ROW_END, WRAP_MIN_WIDTH = 2, FRAME_MIN_INNER_WIDTH = 4, FRAME_TITLE_MIN_INNER_WIDTH = 8, TABLE_MAX_WIDTH_FRACTION = 0.92, TABLE_MIN_COL_WIDTH = 4, TOOL_PREVIEW_MAX_LINES = 12, messageLayoutCache, INLINE_TASK_LIMIT = 5, SIDE_PANEL_MIN_WIDTH = 110, SIDE_PANEL_GAP = 1, CONVERSATION_MIN_WIDTH = 60, TERMINAL_PANE_GAP = 1, TOPIC_FILTER_ROW_INDEX = 2, TOPIC_FILTER_LABEL = " Filter: ", POPUP_PANE_MAX_WIDTH = 72, COMPOSER_GUTTER = 4, COMPOSER_RIGHT_MARGIN = 1, COMPOSER_MIN_CONTENT_WIDTH = 4, SHORTCUT_HINTS, NOTICE_STYLE;
|
|
44805
45319
|
var init_render = __esm(async () => {
|
|
44806
45320
|
init_color_depth();
|
|
44807
45321
|
init_commands();
|
|
@@ -44842,6 +45356,11 @@ var init_render = __esm(async () => {
|
|
|
44842
45356
|
NO_ROW_START = new Set(Array.from(".,;:!?)]}>\xBB\u201D\u2019\u3001\u3002\uFF0C\uFF0E\uFF01\uFF1F\uFF1A\uFF1B\uFF09\uFF3D\uFF5D\u3009\u300B\u300D\u300F\u3011\u3015\u30FB\u2026\u30FC"));
|
|
44843
45357
|
NO_ROW_END = new Set(Array.from("([{<\xAB\u201C\u2018\uFF08\uFF3B\uFF5B\u3008\u300A\u300C\u300E\u3010\u3014"));
|
|
44844
45358
|
messageLayoutCache = new WeakMap;
|
|
45359
|
+
SHORTCUT_HINTS = [
|
|
45360
|
+
"Ctrl-O topics \xB7 Ctrl-P panel \xB7 Ctrl-T terminal \xB7 Ctrl-G subagents \xB7 Ctrl-D decisions",
|
|
45361
|
+
"Ctrl-O topics \xB7 Ctrl-P panel \xB7 Ctrl-T term \xB7 Ctrl-G agents \xB7 Ctrl-D decisions",
|
|
45362
|
+
"^O topics \xB7 ^P panel \xB7 ^T term \xB7 ^G agents \xB7 ^D decisions"
|
|
45363
|
+
];
|
|
44845
45364
|
NOTICE_STYLE = {
|
|
44846
45365
|
info: { glyph: "\xB7", fg: theme.muted },
|
|
44847
45366
|
success: { glyph: "\u2713", fg: theme.green },
|
|
@@ -45059,6 +45578,7 @@ function consumeMouseInput(raw) {
|
|
|
45059
45578
|
let scrollDelta = 0;
|
|
45060
45579
|
let horizontalScrollDelta = 0;
|
|
45061
45580
|
const events = [];
|
|
45581
|
+
const wheelEvents = [];
|
|
45062
45582
|
const input = raw.replace(SGR_MOUSE_PATTERN, (_sequence, rawButton, rawX, rawY, suffix) => {
|
|
45063
45583
|
const button = Number.parseInt(rawButton, 10);
|
|
45064
45584
|
if (Number.isFinite(button) && (button & 64) !== 0) {
|
|
@@ -45068,6 +45588,10 @@ function consumeMouseInput(raw) {
|
|
|
45068
45588
|
horizontalScrollDelta += delta;
|
|
45069
45589
|
else
|
|
45070
45590
|
scrollDelta += delta;
|
|
45591
|
+
const x = Number.parseInt(rawX, 10);
|
|
45592
|
+
const y = Number.parseInt(rawY, 10);
|
|
45593
|
+
if (Number.isFinite(x) && Number.isFinite(y))
|
|
45594
|
+
wheelEvents.push({ x, y, delta, horizontal });
|
|
45071
45595
|
} else {
|
|
45072
45596
|
const x = Number.parseInt(rawX, 10);
|
|
45073
45597
|
const y = Number.parseInt(rawY, 10);
|
|
@@ -45082,11 +45606,14 @@ function consumeMouseInput(raw) {
|
|
|
45082
45606
|
}
|
|
45083
45607
|
return "";
|
|
45084
45608
|
});
|
|
45085
|
-
return { input, scrollDelta, horizontalScrollDelta, events };
|
|
45609
|
+
return { input, scrollDelta, horizontalScrollDelta, events, wheelEvents };
|
|
45086
45610
|
}
|
|
45087
45611
|
function codeCopyTargetAt(targets, point) {
|
|
45088
45612
|
return targets.find((target) => target.y === point.y && point.x >= target.xStart && point.x <= target.xEnd);
|
|
45089
45613
|
}
|
|
45614
|
+
function topicPickerTargetAt(targets, point) {
|
|
45615
|
+
return targets.find((target) => target.y === point.y && point.x >= target.xStart && point.x <= target.xEnd);
|
|
45616
|
+
}
|
|
45090
45617
|
function escapeStopsActiveTurn(state) {
|
|
45091
45618
|
if (state.overlay || state.creatingTopic)
|
|
45092
45619
|
return false;
|
|
@@ -46254,12 +46781,16 @@ function columnSlice(value, from2, to) {
|
|
|
46254
46781
|
}
|
|
46255
46782
|
function screenSelectionText(lines, selection) {
|
|
46256
46783
|
const [start, end] = ordered(selection);
|
|
46784
|
+
const clipFrom = selection.paneClip ? selection.paneClip.xStart - 1 : 0;
|
|
46785
|
+
const clipTo = selection.paneClip ? selection.paneClip.xEnd : Number.POSITIVE_INFINITY;
|
|
46257
46786
|
const selected = [];
|
|
46258
46787
|
for (let row = start.y;row <= end.y; row += 1) {
|
|
46259
46788
|
const value = lines[row - 1] ?? "";
|
|
46260
|
-
const
|
|
46261
|
-
const
|
|
46262
|
-
|
|
46789
|
+
const rowFrom = row === start.y ? Math.max(0, start.x - 1) : 0;
|
|
46790
|
+
const rowTo = row === end.y ? Math.max(rowFrom, end.x) : Number.POSITIVE_INFINITY;
|
|
46791
|
+
const from2 = Math.max(rowFrom, clipFrom);
|
|
46792
|
+
const to = Math.min(rowTo, clipTo);
|
|
46793
|
+
selected.push(to > from2 ? columnSlice(value, from2, to).trimEnd() : "");
|
|
46263
46794
|
}
|
|
46264
46795
|
return selected.join(`
|
|
46265
46796
|
`).replace(/\n+$/, "");
|
|
@@ -46300,14 +46831,18 @@ function highlightRow(value, from2, to) {
|
|
|
46300
46831
|
}
|
|
46301
46832
|
function highlightScreenSelection(frame, selection) {
|
|
46302
46833
|
const [start, end] = ordered(selection);
|
|
46834
|
+
const clipFrom = selection.paneClip ? selection.paneClip.xStart - 1 : 0;
|
|
46835
|
+
const clipTo = selection.paneClip ? selection.paneClip.xEnd : Number.POSITIVE_INFINITY;
|
|
46303
46836
|
return frame.split(`
|
|
46304
46837
|
`).map((line2, index) => {
|
|
46305
46838
|
const row = index + 1;
|
|
46306
46839
|
if (row < start.y || row > end.y)
|
|
46307
46840
|
return line2;
|
|
46308
|
-
const
|
|
46309
|
-
const
|
|
46310
|
-
|
|
46841
|
+
const rowFrom = row === start.y ? Math.max(0, start.x - 1) : 0;
|
|
46842
|
+
const rowTo = row === end.y ? Math.max(rowFrom, end.x) : Number.POSITIVE_INFINITY;
|
|
46843
|
+
const from2 = Math.max(rowFrom, clipFrom);
|
|
46844
|
+
const to = Math.min(rowTo, clipTo);
|
|
46845
|
+
return to > from2 ? highlightRow(line2, from2, to) : line2;
|
|
46311
46846
|
}).join(`
|
|
46312
46847
|
`);
|
|
46313
46848
|
}
|
|
@@ -46317,6 +46852,210 @@ var init_selection = __esm(() => {
|
|
|
46317
46852
|
ANSI_PATTERN = new RegExp("\\u001b\\]8;[^\\u0007\\u001b]*(?:\\u0007|\\u001b\\\\)|\\u001b\\[[0-?]*[ -/]*[@-~]", "y");
|
|
46318
46853
|
});
|
|
46319
46854
|
|
|
46855
|
+
// ../../adapters/terminal/src/shell-pane.ts
|
|
46856
|
+
import xterm from "@xterm/headless";
|
|
46857
|
+
function ptySupport() {
|
|
46858
|
+
const candidate = globalThis.Bun?.Terminal;
|
|
46859
|
+
return typeof candidate === "function" ? candidate : null;
|
|
46860
|
+
}
|
|
46861
|
+
function cellColor(isDefault, isPalette, isRgb, value) {
|
|
46862
|
+
if (isDefault)
|
|
46863
|
+
return DEFAULT_COLOR;
|
|
46864
|
+
if (isPalette)
|
|
46865
|
+
return { kind: "palette", index: value };
|
|
46866
|
+
if (isRgb) {
|
|
46867
|
+
return {
|
|
46868
|
+
kind: "rgb",
|
|
46869
|
+
rgb: [value >> 16 & 255, value >> 8 & 255, value & 255]
|
|
46870
|
+
};
|
|
46871
|
+
}
|
|
46872
|
+
return DEFAULT_COLOR;
|
|
46873
|
+
}
|
|
46874
|
+
function sameColor(a, b) {
|
|
46875
|
+
if (a.kind !== b.kind)
|
|
46876
|
+
return false;
|
|
46877
|
+
if (a.kind === "palette" && b.kind === "palette")
|
|
46878
|
+
return a.index === b.index;
|
|
46879
|
+
if (a.kind === "rgb" && b.kind === "rgb") {
|
|
46880
|
+
return a.rgb[0] === b.rgb[0] && a.rgb[1] === b.rgb[1] && a.rgb[2] === b.rgb[2];
|
|
46881
|
+
}
|
|
46882
|
+
return true;
|
|
46883
|
+
}
|
|
46884
|
+
function sameStyle(a, b) {
|
|
46885
|
+
return sameColor(a.fg, b.fg) && sameColor(a.bg, b.bg) && a.bold === b.bold && a.dim === b.dim && a.italic === b.italic && a.underline === b.underline && a.inverse === b.inverse;
|
|
46886
|
+
}
|
|
46887
|
+
function blankRun(width) {
|
|
46888
|
+
return {
|
|
46889
|
+
text: " ".repeat(width),
|
|
46890
|
+
width,
|
|
46891
|
+
fg: DEFAULT_COLOR,
|
|
46892
|
+
bg: DEFAULT_COLOR,
|
|
46893
|
+
bold: false,
|
|
46894
|
+
dim: false,
|
|
46895
|
+
italic: false,
|
|
46896
|
+
underline: false,
|
|
46897
|
+
inverse: false
|
|
46898
|
+
};
|
|
46899
|
+
}
|
|
46900
|
+
function shellPastePayload(text3, bracketed) {
|
|
46901
|
+
const safe = text3.replaceAll("\x1B[201~", "");
|
|
46902
|
+
return bracketed ? `\x1B[200~${safe}\x1B[201~` : safe;
|
|
46903
|
+
}
|
|
46904
|
+
|
|
46905
|
+
class ShellPane {
|
|
46906
|
+
#xterm;
|
|
46907
|
+
#pty;
|
|
46908
|
+
#process;
|
|
46909
|
+
#cols;
|
|
46910
|
+
#rows;
|
|
46911
|
+
#disposed = false;
|
|
46912
|
+
constructor(options) {
|
|
46913
|
+
const Pty = ptySupport();
|
|
46914
|
+
if (!Pty)
|
|
46915
|
+
throw new Error("the shell pane needs Bun >= 1.3.5 (Bun.Terminal)");
|
|
46916
|
+
this.#cols = Math.max(2, options.cols);
|
|
46917
|
+
this.#rows = Math.max(1, options.rows);
|
|
46918
|
+
const Terminal = xterm.Terminal;
|
|
46919
|
+
this.#xterm = new Terminal({
|
|
46920
|
+
cols: this.#cols,
|
|
46921
|
+
rows: this.#rows,
|
|
46922
|
+
scrollback: 5000,
|
|
46923
|
+
allowProposedApi: true
|
|
46924
|
+
});
|
|
46925
|
+
this.#pty = new Pty({
|
|
46926
|
+
cols: this.#cols,
|
|
46927
|
+
rows: this.#rows,
|
|
46928
|
+
data: (_terminal, data) => {
|
|
46929
|
+
if (this.#disposed)
|
|
46930
|
+
return;
|
|
46931
|
+
this.#xterm.write(data, options.onChange);
|
|
46932
|
+
}
|
|
46933
|
+
});
|
|
46934
|
+
this.#xterm.onData((data) => {
|
|
46935
|
+
if (!this.#disposed)
|
|
46936
|
+
this.#pty.write(data);
|
|
46937
|
+
});
|
|
46938
|
+
const shell2 = options.shell || process.env.SHELL || "/bin/zsh";
|
|
46939
|
+
const env = { ...options.env ?? process.env };
|
|
46940
|
+
env.TERM = "xterm-256color";
|
|
46941
|
+
env.COLORTERM = "truecolor";
|
|
46942
|
+
delete env.TERM_SESSION_ID;
|
|
46943
|
+
const spawn9 = globalThis.Bun.spawn;
|
|
46944
|
+
this.#process = spawn9([shell2, "-l"], {
|
|
46945
|
+
cwd: options.cwd ?? process.cwd(),
|
|
46946
|
+
env,
|
|
46947
|
+
terminal: this.#pty
|
|
46948
|
+
});
|
|
46949
|
+
this.#process.exited.then((code) => {
|
|
46950
|
+
if (this.#disposed)
|
|
46951
|
+
return;
|
|
46952
|
+
this.dispose();
|
|
46953
|
+
options.onExit(code);
|
|
46954
|
+
});
|
|
46955
|
+
}
|
|
46956
|
+
get cols() {
|
|
46957
|
+
return this.#cols;
|
|
46958
|
+
}
|
|
46959
|
+
get rows() {
|
|
46960
|
+
return this.#rows;
|
|
46961
|
+
}
|
|
46962
|
+
get disposed() {
|
|
46963
|
+
return this.#disposed;
|
|
46964
|
+
}
|
|
46965
|
+
write(data) {
|
|
46966
|
+
if (this.#disposed || !data)
|
|
46967
|
+
return;
|
|
46968
|
+
this.#xterm.scrollToBottom();
|
|
46969
|
+
this.#pty.write(data);
|
|
46970
|
+
}
|
|
46971
|
+
paste(text3) {
|
|
46972
|
+
this.write(shellPastePayload(text3, this.#xterm.modes.bracketedPasteMode));
|
|
46973
|
+
}
|
|
46974
|
+
scroll(delta) {
|
|
46975
|
+
if (this.#disposed || delta === 0)
|
|
46976
|
+
return;
|
|
46977
|
+
this.#xterm.scrollLines(-delta);
|
|
46978
|
+
}
|
|
46979
|
+
resize(cols, rows) {
|
|
46980
|
+
const nextCols = Math.max(2, cols);
|
|
46981
|
+
const nextRows = Math.max(1, rows);
|
|
46982
|
+
if (this.#disposed || nextCols === this.#cols && nextRows === this.#rows)
|
|
46983
|
+
return;
|
|
46984
|
+
this.#cols = nextCols;
|
|
46985
|
+
this.#rows = nextRows;
|
|
46986
|
+
this.#xterm.resize(nextCols, nextRows);
|
|
46987
|
+
this.#pty.resize(nextCols, nextRows);
|
|
46988
|
+
}
|
|
46989
|
+
snapshot() {
|
|
46990
|
+
const buffer = this.#xterm.buffer.active;
|
|
46991
|
+
const lines = [];
|
|
46992
|
+
let reusable;
|
|
46993
|
+
for (let y = 0;y < this.#rows; y += 1) {
|
|
46994
|
+
const line2 = buffer.getLine(buffer.viewportY + y);
|
|
46995
|
+
const runs = [];
|
|
46996
|
+
let used = 0;
|
|
46997
|
+
if (line2) {
|
|
46998
|
+
for (let x = 0;x < this.#cols; x += 1) {
|
|
46999
|
+
const cell = line2.getCell(x, reusable);
|
|
47000
|
+
if (!cell)
|
|
47001
|
+
break;
|
|
47002
|
+
reusable = cell;
|
|
47003
|
+
const width = cell.getWidth();
|
|
47004
|
+
if (width === 0)
|
|
47005
|
+
continue;
|
|
47006
|
+
if (used + width > this.#cols)
|
|
47007
|
+
break;
|
|
47008
|
+
const style = {
|
|
47009
|
+
fg: cellColor(cell.isFgDefault(), cell.isFgPalette(), cell.isFgRGB(), cell.getFgColor()),
|
|
47010
|
+
bg: cellColor(cell.isBgDefault(), cell.isBgPalette(), cell.isBgRGB(), cell.getBgColor()),
|
|
47011
|
+
bold: cell.isBold() !== 0,
|
|
47012
|
+
dim: cell.isDim() !== 0,
|
|
47013
|
+
italic: cell.isItalic() !== 0,
|
|
47014
|
+
underline: cell.isUnderline() !== 0,
|
|
47015
|
+
inverse: cell.isInverse() !== 0
|
|
47016
|
+
};
|
|
47017
|
+
const text3 = cell.getChars() || " ";
|
|
47018
|
+
const last = runs[runs.length - 1];
|
|
47019
|
+
if (last && sameStyle(last, style)) {
|
|
47020
|
+
last.text += text3;
|
|
47021
|
+
last.width += width;
|
|
47022
|
+
} else {
|
|
47023
|
+
runs.push({ text: text3, width, ...style });
|
|
47024
|
+
}
|
|
47025
|
+
used += width;
|
|
47026
|
+
}
|
|
47027
|
+
}
|
|
47028
|
+
if (used < this.#cols)
|
|
47029
|
+
runs.push(blankRun(this.#cols - used));
|
|
47030
|
+
lines.push(runs);
|
|
47031
|
+
}
|
|
47032
|
+
const atLiveScreen = buffer.viewportY === buffer.baseY;
|
|
47033
|
+
const hidden = this.#xterm._core?.coreService?.isCursorHidden;
|
|
47034
|
+
return {
|
|
47035
|
+
cols: this.#cols,
|
|
47036
|
+
rows: this.#rows,
|
|
47037
|
+
lines,
|
|
47038
|
+
cursor: atLiveScreen && !hidden ? { x: Math.min(buffer.cursorX, this.#cols - 1), y: buffer.cursorY } : null
|
|
47039
|
+
};
|
|
47040
|
+
}
|
|
47041
|
+
dispose() {
|
|
47042
|
+
if (this.#disposed)
|
|
47043
|
+
return;
|
|
47044
|
+
this.#disposed = true;
|
|
47045
|
+
try {
|
|
47046
|
+
this.#process.kill();
|
|
47047
|
+
} catch {}
|
|
47048
|
+
try {
|
|
47049
|
+
this.#pty.close();
|
|
47050
|
+
} catch {}
|
|
47051
|
+
this.#xterm.dispose();
|
|
47052
|
+
}
|
|
47053
|
+
}
|
|
47054
|
+
var DEFAULT_COLOR;
|
|
47055
|
+
var init_shell_pane = __esm(() => {
|
|
47056
|
+
DEFAULT_COLOR = { kind: "default" };
|
|
47057
|
+
});
|
|
47058
|
+
|
|
46320
47059
|
// ../../adapters/terminal/src/terminal-restore.ts
|
|
46321
47060
|
import { writeSync } from "fs";
|
|
46322
47061
|
function isRetryable(error2) {
|
|
@@ -46790,6 +47529,7 @@ class InputHistory {
|
|
|
46790
47529
|
}
|
|
46791
47530
|
|
|
46792
47531
|
// ../../adapters/terminal/src/app.ts
|
|
47532
|
+
import { hostname as hostname2 } from "os";
|
|
46793
47533
|
function kittyKeyboardEnabled(env = process.env) {
|
|
46794
47534
|
const value = env.NEGOTIUM_TUI_DISABLE_KITTY_KEYBOARD;
|
|
46795
47535
|
return value !== "1" && value !== "true" && value !== "yes";
|
|
@@ -46808,18 +47548,20 @@ function canvasFill(depth2) {
|
|
|
46808
47548
|
return `\x1B[48;2;${CANVAS_RGB[0]};${CANVAS_RGB[1]};${CANVAS_RGB[2]}m`;
|
|
46809
47549
|
}
|
|
46810
47550
|
}
|
|
46811
|
-
function
|
|
47551
|
+
function workingDirectoryReport(cwd, host2 = hostname2()) {
|
|
47552
|
+
const path = cwd.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
47553
|
+
return `\x1B]7;file://${host2}${path}\x07`;
|
|
47554
|
+
}
|
|
47555
|
+
function altScreenSequences(env = process.env, savedDepth, cwd = process.cwd()) {
|
|
46812
47556
|
const push = kittyKeyboardEnabled(env) ? KITTY_KEYBOARD_PUSH : "";
|
|
46813
47557
|
const pop = kittyKeyboardEnabled(env) ? KITTY_KEYBOARD_POP : "";
|
|
46814
47558
|
const depth2 = detectColorDepth({ env, isTty: true, savedDepth });
|
|
46815
|
-
const colored = depth2 !== "none";
|
|
46816
|
-
const setBackground = colored ? "\x1B]11;#0a0b0f\x07" : "";
|
|
46817
47559
|
const fillCanvas = canvasFill(depth2);
|
|
46818
|
-
const
|
|
46819
|
-
const modeResets = "\x1B[0m\x1B[?7h\x1B[?1l\x1B[?1006l\x1B[?
|
|
47560
|
+
const reportCwd = workingDirectoryReport(cwd);
|
|
47561
|
+
const modeResets = "\x1B[0m\x1B[?7h\x1B[?1l\x1B[?1006l\x1B[?1003l\x1B[?2004l\x1B[?25h\x1B[?1049l";
|
|
46820
47562
|
return {
|
|
46821
|
-
enter: `${
|
|
46822
|
-
exit: `${END_SYNCHRONIZED_UPDATE}${pop}${modeResets}${
|
|
47563
|
+
enter: `${reportCwd}\x1B[?1049h${fillCanvas}\x1B[2J\x1B[H\x1B[?25l\x1B[?2004h\x1B[?1003h\x1B[?1006h\x1B[?1l${push}`,
|
|
47564
|
+
exit: `${END_SYNCHRONIZED_UPDATE}${pop}${modeResets}${reportCwd}`,
|
|
46823
47565
|
abortEnter: `${END_SYNCHRONIZED_UPDATE}${modeResets}`
|
|
46824
47566
|
};
|
|
46825
47567
|
}
|
|
@@ -46858,9 +47600,19 @@ class TerminalApp {
|
|
|
46858
47600
|
#messageHistory = new Map;
|
|
46859
47601
|
#queuedRuntimeEvents = new Map;
|
|
46860
47602
|
#selection = null;
|
|
47603
|
+
#selectionDragging = false;
|
|
46861
47604
|
#subagentGraphDragPoint = null;
|
|
46862
47605
|
#plainFrameLines = [];
|
|
46863
47606
|
#codeCopyTargets = [];
|
|
47607
|
+
#topicPickerTargets = [];
|
|
47608
|
+
#sidePanelTracks = [];
|
|
47609
|
+
#sideColumnBounds = null;
|
|
47610
|
+
#sidePanelResizeHandle = null;
|
|
47611
|
+
#sidePanelDrag = null;
|
|
47612
|
+
#sidePanelResizeDrag = null;
|
|
47613
|
+
#shell = null;
|
|
47614
|
+
#terminalPane = null;
|
|
47615
|
+
#conversationBounds = null;
|
|
46864
47616
|
#lastInterruptAt = 0;
|
|
46865
47617
|
#subagentGraphGeneration = 0;
|
|
46866
47618
|
#subagentGraphAbortController = null;
|
|
@@ -46981,8 +47733,9 @@ class TerminalApp {
|
|
|
46981
47733
|
}
|
|
46982
47734
|
}
|
|
46983
47735
|
#handleRuntimeEvent(event) {
|
|
46984
|
-
if (runtimeEventInvalidatesSelection(this.#state, event))
|
|
47736
|
+
if (!this.#selectionDragging && runtimeEventInvalidatesSelection(this.#state, event)) {
|
|
46985
47737
|
this.#selection = null;
|
|
47738
|
+
}
|
|
46986
47739
|
if (this.#messageLoadGeneration.has(event.topicId) && runtimeEventWaitsForMessageLoad(event)) {
|
|
46987
47740
|
const queued = this.#queuedRuntimeEvents.get(event.topicId) ?? [];
|
|
46988
47741
|
queued.push(event);
|
|
@@ -47234,8 +47987,19 @@ class TerminalApp {
|
|
|
47234
47987
|
#render() {
|
|
47235
47988
|
const columns = process.stdout.columns ?? 100;
|
|
47236
47989
|
const rows = process.stdout.rows ?? 30;
|
|
47237
|
-
const rendered = renderAppFrame(this.#state, columns, rows, this.#animationFrame
|
|
47990
|
+
const rendered = renderAppFrame(this.#state, columns, rows, this.#animationFrame, undefined, {
|
|
47991
|
+
shell: this.#shell?.snapshot() ?? null
|
|
47992
|
+
});
|
|
47238
47993
|
this.#codeCopyTargets = rendered.codeCopyTargets;
|
|
47994
|
+
this.#topicPickerTargets = rendered.topicPickerTargets;
|
|
47995
|
+
this.#sidePanelTracks = rendered.sidePanelTracks;
|
|
47996
|
+
this.#sideColumnBounds = rendered.sideColumnBounds;
|
|
47997
|
+
this.#sidePanelResizeHandle = rendered.sidePanelResizeHandle;
|
|
47998
|
+
this.#terminalPane = rendered.terminalPane;
|
|
47999
|
+
this.#conversationBounds = rendered.conversationBounds;
|
|
48000
|
+
if (this.#shell && rendered.terminalPane) {
|
|
48001
|
+
this.#shell.resize(rendered.terminalPane.cols, rendered.terminalPane.rows);
|
|
48002
|
+
}
|
|
47239
48003
|
const baseFrame = rendered.frame;
|
|
47240
48004
|
this.#plainFrameLines = stripAnsi(baseFrame).split(`
|
|
47241
48005
|
`);
|
|
@@ -47602,6 +48366,10 @@ class TerminalApp {
|
|
|
47602
48366
|
}
|
|
47603
48367
|
#commitPaste(payload) {
|
|
47604
48368
|
this.#selection = null;
|
|
48369
|
+
if (this.#state.terminalPaneFocused && this.#shell) {
|
|
48370
|
+
this.#shell.paste(payload);
|
|
48371
|
+
return;
|
|
48372
|
+
}
|
|
47605
48373
|
if (this.#state.overlay === "topics") {
|
|
47606
48374
|
const filterText = topicFilterPasteText(payload);
|
|
47607
48375
|
if (filterText) {
|
|
@@ -47623,24 +48391,41 @@ class TerminalApp {
|
|
|
47623
48391
|
}
|
|
47624
48392
|
#handleKeySegment(segment) {
|
|
47625
48393
|
const mouse = consumeMouseInput(segment);
|
|
47626
|
-
|
|
48394
|
+
const { scrollDelta, horizontalScrollDelta } = this.#routeWheelEvents(mouse.wheelEvents);
|
|
48395
|
+
if (horizontalScrollDelta !== 0 && (this.#state.overlay === "subagents" || this.#state.overlay === "decisions")) {
|
|
47627
48396
|
this.#selection = null;
|
|
47628
|
-
this.#panActiveGraph(-
|
|
48397
|
+
this.#panActiveGraph(-horizontalScrollDelta, 0);
|
|
47629
48398
|
}
|
|
47630
|
-
if (
|
|
48399
|
+
if (scrollDelta !== 0) {
|
|
47631
48400
|
this.#selection = null;
|
|
47632
|
-
this.#scroll(
|
|
48401
|
+
this.#scroll(scrollDelta);
|
|
47633
48402
|
}
|
|
47634
48403
|
for (const event of mouse.events) {
|
|
47635
48404
|
if (this.#state.overlay === "subagents" || this.#state.overlay === "decisions") {
|
|
47636
48405
|
this.#handleGraphMouse(event);
|
|
47637
|
-
|
|
47638
|
-
|
|
48406
|
+
continue;
|
|
48407
|
+
}
|
|
48408
|
+
if (this.#handleSidePanelResizeDrag(event))
|
|
48409
|
+
continue;
|
|
48410
|
+
this.#focusPaneUnderPress(event);
|
|
48411
|
+
if (this.#handleSidePanelScrollbarDrag(event))
|
|
48412
|
+
continue;
|
|
48413
|
+
if (this.#handlePickableRowMouse(event))
|
|
48414
|
+
continue;
|
|
48415
|
+
this.#handleMouseSelection(event);
|
|
47639
48416
|
}
|
|
47640
48417
|
const chunk = normalizeKeySequences(mouse.input);
|
|
47641
48418
|
if (!chunk)
|
|
47642
48419
|
return;
|
|
47643
48420
|
this.#selection = null;
|
|
48421
|
+
if (chunk === TERMINAL_PANE_KEY) {
|
|
48422
|
+
this.#toggleTerminalPane();
|
|
48423
|
+
return;
|
|
48424
|
+
}
|
|
48425
|
+
if (this.#state.terminalPaneFocused && this.#shell) {
|
|
48426
|
+
this.#shell.write(chunk);
|
|
48427
|
+
return;
|
|
48428
|
+
}
|
|
47644
48429
|
if (chunk === "\x03") {
|
|
47645
48430
|
this.#handleInterrupt();
|
|
47646
48431
|
return;
|
|
@@ -47674,10 +48459,17 @@ class TerminalApp {
|
|
|
47674
48459
|
this.#toggleDecisionGraph();
|
|
47675
48460
|
return;
|
|
47676
48461
|
}
|
|
47677
|
-
if (chunk === "\
|
|
48462
|
+
if (chunk === "\x10") {
|
|
48463
|
+
if (editingVaultSecret)
|
|
48464
|
+
return;
|
|
48465
|
+
this.#state = toggleTopicsPanel(this.#state);
|
|
48466
|
+
this.#queueRender();
|
|
48467
|
+
return;
|
|
48468
|
+
}
|
|
48469
|
+
if (chunk === "\x12") {
|
|
47678
48470
|
if (editingVaultSecret)
|
|
47679
48471
|
return;
|
|
47680
|
-
this.#state =
|
|
48472
|
+
this.#state = cycleTopicsPanelSort(this.#state);
|
|
47681
48473
|
this.#queueRender();
|
|
47682
48474
|
return;
|
|
47683
48475
|
}
|
|
@@ -48099,7 +48891,7 @@ class TerminalApp {
|
|
|
48099
48891
|
notice: undefined,
|
|
48100
48892
|
noticeLevel: undefined
|
|
48101
48893
|
};
|
|
48102
|
-
if (text3
|
|
48894
|
+
if (isKnownTerminalCommand(text3)) {
|
|
48103
48895
|
await this.#runCommand(text3);
|
|
48104
48896
|
return;
|
|
48105
48897
|
}
|
|
@@ -48815,24 +49607,283 @@ class TerminalApp {
|
|
|
48815
49607
|
}
|
|
48816
49608
|
this.#queueRender();
|
|
48817
49609
|
}
|
|
49610
|
+
#routeWheelEvents(events) {
|
|
49611
|
+
let scrollDelta = 0;
|
|
49612
|
+
let horizontalScrollDelta = 0;
|
|
49613
|
+
if (events.length === 0)
|
|
49614
|
+
return { scrollDelta, horizontalScrollDelta };
|
|
49615
|
+
const bounds = this.#sideColumnBounds;
|
|
49616
|
+
const pane = this.#terminalPane;
|
|
49617
|
+
let touchedPanel = false;
|
|
49618
|
+
for (const event of events) {
|
|
49619
|
+
if (pane && this.#shell && event.x >= pane.xStart && event.x <= pane.xEnd && !event.horizontal) {
|
|
49620
|
+
this.#shell.scroll(event.delta);
|
|
49621
|
+
touchedPanel = true;
|
|
49622
|
+
continue;
|
|
49623
|
+
}
|
|
49624
|
+
const section = bounds && event.x >= bounds.xStart && event.x <= bounds.xEnd ? bounds.sections.find((s) => event.y >= s.yStart && event.y <= s.yEnd) : undefined;
|
|
49625
|
+
if (!section) {
|
|
49626
|
+
if (event.horizontal)
|
|
49627
|
+
horizontalScrollDelta += event.delta;
|
|
49628
|
+
else
|
|
49629
|
+
scrollDelta += event.delta;
|
|
49630
|
+
continue;
|
|
49631
|
+
}
|
|
49632
|
+
touchedPanel = true;
|
|
49633
|
+
const columns = process.stdout.columns ?? 100;
|
|
49634
|
+
const rows = process.stdout.rows ?? 30;
|
|
49635
|
+
this.#state = section.panel === "topics" ? scrollTopicsPanel(this.#state, -event.delta, maxTopicsPanelScrollOffset(this.#state, columns, rows)) : scrollTaskPanel(this.#state, -event.delta, maxTaskPanelScrollOffset(this.#state, columns, rows));
|
|
49636
|
+
}
|
|
49637
|
+
if (touchedPanel)
|
|
49638
|
+
this.#queueRender();
|
|
49639
|
+
return { scrollDelta, horizontalScrollDelta };
|
|
49640
|
+
}
|
|
49641
|
+
#toggleTerminalPane() {
|
|
49642
|
+
if (this.#state.terminalPaneOpen) {
|
|
49643
|
+
const shell2 = this.#shell;
|
|
49644
|
+
this.#shell = null;
|
|
49645
|
+
shell2?.dispose();
|
|
49646
|
+
this.#state = closeTerminalPane(this.#state);
|
|
49647
|
+
this.#queueRender();
|
|
49648
|
+
return;
|
|
49649
|
+
}
|
|
49650
|
+
if (!this.#shell) {
|
|
49651
|
+
if (!ptySupport()) {
|
|
49652
|
+
this.#state = {
|
|
49653
|
+
...this.#state,
|
|
49654
|
+
notice: "Shell pane needs Bun >= 1.3.5 (bun upgrade)",
|
|
49655
|
+
noticeLevel: "warn"
|
|
49656
|
+
};
|
|
49657
|
+
this.#queueRender();
|
|
49658
|
+
return;
|
|
49659
|
+
}
|
|
49660
|
+
try {
|
|
49661
|
+
const columns2 = process.stdout.columns ?? 100;
|
|
49662
|
+
const rows = process.stdout.rows ?? 30;
|
|
49663
|
+
const shell2 = new ShellPane({
|
|
49664
|
+
cols: Math.max(30, Math.floor(columns2 * 0.3)),
|
|
49665
|
+
rows: Math.max(1, rows),
|
|
49666
|
+
cwd: process.cwd(),
|
|
49667
|
+
onChange: () => this.#queueRender(),
|
|
49668
|
+
onExit: () => {
|
|
49669
|
+
if (this.#shell !== shell2)
|
|
49670
|
+
return;
|
|
49671
|
+
this.#shell = null;
|
|
49672
|
+
this.#state = {
|
|
49673
|
+
...closeTerminalPane(this.#state),
|
|
49674
|
+
notice: "Shell exited",
|
|
49675
|
+
noticeLevel: "info"
|
|
49676
|
+
};
|
|
49677
|
+
this.#queueRender();
|
|
49678
|
+
}
|
|
49679
|
+
});
|
|
49680
|
+
this.#shell = shell2;
|
|
49681
|
+
} catch (error2) {
|
|
49682
|
+
this.#state = {
|
|
49683
|
+
...this.#state,
|
|
49684
|
+
notice: `Shell pane failed: ${error2 instanceof Error ? error2.message : String(error2)}`,
|
|
49685
|
+
noticeLevel: "error"
|
|
49686
|
+
};
|
|
49687
|
+
this.#queueRender();
|
|
49688
|
+
return;
|
|
49689
|
+
}
|
|
49690
|
+
}
|
|
49691
|
+
this.#state = openTerminalPane(this.#state);
|
|
49692
|
+
const columns = process.stdout.columns ?? 100;
|
|
49693
|
+
if (maxTerminalPaneWidth(this.#state, columns) < 30 || columns < 92) {
|
|
49694
|
+
this.#state = {
|
|
49695
|
+
...this.#state,
|
|
49696
|
+
notice: "Window too narrow for the shell pane \u2014 widen it to see the pane",
|
|
49697
|
+
noticeLevel: "warn"
|
|
49698
|
+
};
|
|
49699
|
+
}
|
|
49700
|
+
this.#queueRender();
|
|
49701
|
+
}
|
|
49702
|
+
#focusPaneUnderPress(event) {
|
|
49703
|
+
if (event.kind !== "press" || (event.button & 3) !== 0)
|
|
49704
|
+
return;
|
|
49705
|
+
const pane = this.#terminalPane;
|
|
49706
|
+
const inside = !!pane && event.x >= pane.xStart && event.x <= pane.xEnd;
|
|
49707
|
+
const next = focusTerminalPane(this.#state, inside && !!this.#shell);
|
|
49708
|
+
if (next !== this.#state) {
|
|
49709
|
+
this.#state = next;
|
|
49710
|
+
this.#queueRender();
|
|
49711
|
+
}
|
|
49712
|
+
}
|
|
49713
|
+
#handleSidePanelResizeDrag(event) {
|
|
49714
|
+
if (event.kind === "press" && (event.button & 3) === 0) {
|
|
49715
|
+
const pane = this.#terminalPane;
|
|
49716
|
+
if (pane && event.x === pane.dividerX && event.y >= pane.yStart && event.y <= pane.yEnd) {
|
|
49717
|
+
this.#sidePanelResizeDrag = { target: "terminal", startX: event.x, startWidth: pane.cols };
|
|
49718
|
+
return true;
|
|
49719
|
+
}
|
|
49720
|
+
const handle = this.#sidePanelResizeHandle;
|
|
49721
|
+
if (!handle || event.x < handle.xStart || event.x > handle.xEnd || event.y < handle.yStart || event.y > handle.yEnd) {
|
|
49722
|
+
this.#sidePanelResizeDrag = null;
|
|
49723
|
+
return false;
|
|
49724
|
+
}
|
|
49725
|
+
this.#sidePanelResizeDrag = {
|
|
49726
|
+
target: "side",
|
|
49727
|
+
startX: event.x,
|
|
49728
|
+
startWidth: this.#state.sidePanelWidth
|
|
49729
|
+
};
|
|
49730
|
+
return true;
|
|
49731
|
+
}
|
|
49732
|
+
const drag = this.#sidePanelResizeDrag;
|
|
49733
|
+
if (!drag)
|
|
49734
|
+
return false;
|
|
49735
|
+
if (event.kind === "release") {
|
|
49736
|
+
this.#sidePanelResizeDrag = null;
|
|
49737
|
+
return true;
|
|
49738
|
+
}
|
|
49739
|
+
const columns = process.stdout.columns ?? 100;
|
|
49740
|
+
if (drag.target === "terminal") {
|
|
49741
|
+
const nextWidth2 = drag.startWidth - (event.x - drag.startX);
|
|
49742
|
+
this.#state = setTerminalPaneWidth(this.#state, nextWidth2, maxTerminalPaneWidth(this.#state, columns));
|
|
49743
|
+
this.#queueRender();
|
|
49744
|
+
return true;
|
|
49745
|
+
}
|
|
49746
|
+
const nextWidth = drag.startWidth + (event.x - drag.startX);
|
|
49747
|
+
this.#state = setSidePanelWidth(this.#state, nextWidth, maxSidePanelWidth(columns));
|
|
49748
|
+
this.#queueRender();
|
|
49749
|
+
return true;
|
|
49750
|
+
}
|
|
49751
|
+
#handleSidePanelScrollbarDrag(event) {
|
|
49752
|
+
if (event.kind === "press" && (event.button & 3) === 0) {
|
|
49753
|
+
const track2 = this.#sidePanelTracks.find((t) => event.x === t.x && event.y >= t.yStart && event.y < t.yStart + t.viewportRows);
|
|
49754
|
+
if (!track2) {
|
|
49755
|
+
this.#sidePanelDrag = null;
|
|
49756
|
+
return false;
|
|
49757
|
+
}
|
|
49758
|
+
const current3 = track2.panel === "topics" ? this.#state.topicsPanelScrollOffset : this.#state.taskPanelScrollOffset;
|
|
49759
|
+
const thumb = scrollbarThumb(track2.rowCount, track2.viewportRows, current3);
|
|
49760
|
+
this.#sidePanelDrag = {
|
|
49761
|
+
panel: track2.panel,
|
|
49762
|
+
track: track2,
|
|
49763
|
+
grabRowOffset: event.y - (track2.yStart + thumb.top)
|
|
49764
|
+
};
|
|
49765
|
+
return true;
|
|
49766
|
+
}
|
|
49767
|
+
const drag = this.#sidePanelDrag;
|
|
49768
|
+
if (!drag)
|
|
49769
|
+
return false;
|
|
49770
|
+
if (event.kind === "release") {
|
|
49771
|
+
this.#sidePanelDrag = null;
|
|
49772
|
+
return true;
|
|
49773
|
+
}
|
|
49774
|
+
const { track, grabRowOffset, panel } = drag;
|
|
49775
|
+
const offset = scrollOffsetFromDragRow(track.rowCount, track.viewportRows, event.y - track.yStart, grabRowOffset);
|
|
49776
|
+
const columns = process.stdout.columns ?? 100;
|
|
49777
|
+
const rows = process.stdout.rows ?? 30;
|
|
49778
|
+
this.#state = panel === "topics" ? setTopicsPanelScrollOffset(this.#state, offset, maxTopicsPanelScrollOffset(this.#state, columns, rows)) : setTaskPanelScrollOffset(this.#state, offset, maxTaskPanelScrollOffset(this.#state, columns, rows));
|
|
49779
|
+
this.#queueRender();
|
|
49780
|
+
return true;
|
|
49781
|
+
}
|
|
49782
|
+
#handlePickableRowMouse(event) {
|
|
49783
|
+
const inOverlay = this.#state.overlay === "topics";
|
|
49784
|
+
const hovering = event.kind === "drag" && (event.button & 3) === 3;
|
|
49785
|
+
const isClick = event.kind === "press" && (event.button & 3) === 0;
|
|
49786
|
+
if (!inOverlay && !hovering && !isClick)
|
|
49787
|
+
return false;
|
|
49788
|
+
const target = topicPickerTargetAt(this.#topicPickerTargets, { x: event.x, y: event.y });
|
|
49789
|
+
if (inOverlay) {
|
|
49790
|
+
if (!target)
|
|
49791
|
+
return true;
|
|
49792
|
+
const highlighted = this.#highlightPickedTarget(target);
|
|
49793
|
+
if (!hovering && highlighted)
|
|
49794
|
+
this.#selectPickedTopic();
|
|
49795
|
+
return true;
|
|
49796
|
+
}
|
|
49797
|
+
if (target?.backgroundSessionId !== undefined) {
|
|
49798
|
+
const sessionId = target.backgroundSessionId;
|
|
49799
|
+
if (hovering) {
|
|
49800
|
+
this.#setSidePanelHover(undefined, sessionId);
|
|
49801
|
+
return true;
|
|
49802
|
+
}
|
|
49803
|
+
this.#setSidePanelHover(undefined, undefined);
|
|
49804
|
+
this.#state = {
|
|
49805
|
+
...this.#state,
|
|
49806
|
+
overlay: "background-session",
|
|
49807
|
+
topicPickerBackgroundId: sessionId,
|
|
49808
|
+
backgroundScrollOffset: 0,
|
|
49809
|
+
notice: undefined,
|
|
49810
|
+
noticeLevel: undefined
|
|
49811
|
+
};
|
|
49812
|
+
this.#queueRender();
|
|
49813
|
+
return true;
|
|
49814
|
+
}
|
|
49815
|
+
if (target?.topicIndex === undefined) {
|
|
49816
|
+
this.#setSidePanelHover(undefined, undefined);
|
|
49817
|
+
return false;
|
|
49818
|
+
}
|
|
49819
|
+
const topic = this.#state.topics[target.topicIndex];
|
|
49820
|
+
if (!topic)
|
|
49821
|
+
return false;
|
|
49822
|
+
if (hovering) {
|
|
49823
|
+
this.#setSidePanelHover(topic.id, undefined);
|
|
49824
|
+
return true;
|
|
49825
|
+
}
|
|
49826
|
+
this.#setSidePanelHover(undefined, undefined);
|
|
49827
|
+
if (topic.id !== this.#state.activeTopicId)
|
|
49828
|
+
this.#activateTopic(topic.id);
|
|
49829
|
+
return true;
|
|
49830
|
+
}
|
|
49831
|
+
#setSidePanelHover(topicId, backgroundSessionId) {
|
|
49832
|
+
if (this.#state.sidePanelHoverTopicId === topicId && this.#state.sidePanelHoverBackgroundSessionId === backgroundSessionId) {
|
|
49833
|
+
return;
|
|
49834
|
+
}
|
|
49835
|
+
this.#state = {
|
|
49836
|
+
...this.#state,
|
|
49837
|
+
sidePanelHoverTopicId: topicId,
|
|
49838
|
+
sidePanelHoverBackgroundSessionId: backgroundSessionId
|
|
49839
|
+
};
|
|
49840
|
+
this.#queueRender();
|
|
49841
|
+
}
|
|
49842
|
+
#highlightPickedTarget(target) {
|
|
49843
|
+
if (target.backgroundSessionId !== undefined) {
|
|
49844
|
+
if (this.#state.topicPickerBackgroundId === target.backgroundSessionId)
|
|
49845
|
+
return true;
|
|
49846
|
+
this.#state = { ...this.#state, topicPickerBackgroundId: target.backgroundSessionId };
|
|
49847
|
+
} else if (target.topicIndex !== undefined) {
|
|
49848
|
+
if (!this.#state.topicPickerBackgroundId && this.#state.topicPickerIndex === target.topicIndex) {
|
|
49849
|
+
return true;
|
|
49850
|
+
}
|
|
49851
|
+
this.#state = {
|
|
49852
|
+
...this.#state,
|
|
49853
|
+
topicPickerIndex: target.topicIndex,
|
|
49854
|
+
topicPickerBackgroundId: undefined
|
|
49855
|
+
};
|
|
49856
|
+
} else {
|
|
49857
|
+
return false;
|
|
49858
|
+
}
|
|
49859
|
+
this.#queueRender();
|
|
49860
|
+
return true;
|
|
49861
|
+
}
|
|
48818
49862
|
#handleMouseSelection(event) {
|
|
48819
49863
|
if ((event.button & 3) !== 0 && event.kind !== "release")
|
|
48820
49864
|
return;
|
|
48821
|
-
const point = { x: event.x, y: event.y };
|
|
48822
49865
|
if (event.kind === "press") {
|
|
49866
|
+
const point = { x: event.x, y: event.y };
|
|
48823
49867
|
const codeTarget = codeCopyTargetAt(this.#codeCopyTargets, point);
|
|
48824
49868
|
if (codeTarget) {
|
|
48825
49869
|
this.#selection = null;
|
|
48826
49870
|
this.#copyCodeBlock(codeTarget.text);
|
|
48827
49871
|
return;
|
|
48828
49872
|
}
|
|
48829
|
-
|
|
49873
|
+
const bounds = this.#sideColumnBounds;
|
|
49874
|
+
const pane = this.#terminalPane;
|
|
49875
|
+
const conversation = this.#conversationBounds;
|
|
49876
|
+
const paneClip = bounds && point.x >= bounds.xStart && point.x <= bounds.xEnd ? { xStart: bounds.xStart, xEnd: bounds.xEnd } : pane && point.x >= pane.xStart && point.x <= pane.xEnd ? { xStart: pane.xStart, xEnd: pane.xEnd } : (bounds || pane) && conversation ? { xStart: conversation.xStart, xEnd: conversation.xEnd } : undefined;
|
|
49877
|
+
this.#selection = { anchor: point, focus: point, paneClip };
|
|
49878
|
+
this.#selectionDragging = true;
|
|
48830
49879
|
this.#queueRender();
|
|
48831
49880
|
return;
|
|
48832
49881
|
}
|
|
49882
|
+
if (event.kind === "release")
|
|
49883
|
+
this.#selectionDragging = false;
|
|
48833
49884
|
if (!this.#selection)
|
|
48834
49885
|
return;
|
|
48835
|
-
this.#selection = { ...this.#selection, focus:
|
|
49886
|
+
this.#selection = { ...this.#selection, focus: { x: event.x, y: event.y } };
|
|
48836
49887
|
if (event.kind === "drag") {
|
|
48837
49888
|
this.#queueRender();
|
|
48838
49889
|
return;
|
|
@@ -49073,6 +50124,8 @@ class TerminalApp {
|
|
|
49073
50124
|
this.#finishRun = null;
|
|
49074
50125
|
}
|
|
49075
50126
|
async#cleanup(clientStartAttempted, uiActive) {
|
|
50127
|
+
this.#shell?.dispose();
|
|
50128
|
+
this.#shell = null;
|
|
49076
50129
|
this.#subagentGraphGeneration += 1;
|
|
49077
50130
|
this.#subagentGraphAbortController?.abort();
|
|
49078
50131
|
this.#subagentGraphAbortController = null;
|
|
@@ -49114,7 +50167,7 @@ class TerminalApp {
|
|
|
49114
50167
|
await this.#client.stop();
|
|
49115
50168
|
}
|
|
49116
50169
|
}
|
|
49117
|
-
var KITTY_KEYBOARD_PUSH = "\x1B[>1u", KITTY_KEYBOARD_POP = "\x1B[<u", CANVAS_RGB, ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, ABORT_ENTER_ALT_SCREEN, NEW_TOPIC_KEY = "\x0E", DELETE_TOPIC_KEY = "\x04", FILTER_BACKSPACE_KEYS, CONFIRM_KEYS, CANCEL_KEYS, INPUT_CARRY_FLUSH_MS = 15;
|
|
50170
|
+
var KITTY_KEYBOARD_PUSH = "\x1B[>1u", KITTY_KEYBOARD_POP = "\x1B[<u", CANVAS_RGB, ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, ABORT_ENTER_ALT_SCREEN, NEW_TOPIC_KEY = "\x0E", DELETE_TOPIC_KEY = "\x04", TERMINAL_PANE_KEY = "\x14", FILTER_BACKSPACE_KEYS, CONFIRM_KEYS, CANCEL_KEYS, INPUT_CARRY_FLUSH_MS = 15;
|
|
49118
50171
|
var init_app = __esm(async () => {
|
|
49119
50172
|
init_color_depth();
|
|
49120
50173
|
init_commands();
|
|
@@ -49122,6 +50175,7 @@ var init_app = __esm(async () => {
|
|
|
49122
50175
|
init_path_suggest();
|
|
49123
50176
|
init_screen_renderer();
|
|
49124
50177
|
init_selection();
|
|
50178
|
+
init_shell_pane();
|
|
49125
50179
|
init_subagent_graph();
|
|
49126
50180
|
init_terminal_restore();
|
|
49127
50181
|
await __promiseAll([
|
|
@@ -52518,8 +53572,8 @@ var init_canonical_mcp_bridge = __esm(async () => {
|
|
|
52518
53572
|
});
|
|
52519
53573
|
|
|
52520
53574
|
// ../../adapters/otium/src/secure-transport.ts
|
|
52521
|
-
function isLoopbackHostname(
|
|
52522
|
-
const normalized =
|
|
53575
|
+
function isLoopbackHostname(hostname3) {
|
|
53576
|
+
const normalized = hostname3.toLowerCase();
|
|
52523
53577
|
if (normalized === "localhost" || normalized === "::1" || normalized === "[::1]")
|
|
52524
53578
|
return true;
|
|
52525
53579
|
const octets = normalized.split(".");
|
|
@@ -55727,7 +56781,7 @@ __export(exports_join_cli, {
|
|
|
55727
56781
|
localNodeNameDefault: () => localNodeNameDefault,
|
|
55728
56782
|
joinCommand: () => joinCommand
|
|
55729
56783
|
});
|
|
55730
|
-
import { hostname as
|
|
56784
|
+
import { hostname as hostname3 } from "os";
|
|
55731
56785
|
function option2(args, name) {
|
|
55732
56786
|
const index = args.indexOf(`--${name}`);
|
|
55733
56787
|
return index >= 0 ? args[index + 1]?.trim() : undefined;
|
|
@@ -55749,7 +56803,7 @@ function localNodeNameDefault() {
|
|
|
55749
56803
|
if (normalized)
|
|
55750
56804
|
return normalized;
|
|
55751
56805
|
}
|
|
55752
|
-
return normalizeNodeNameCandidate(
|
|
56806
|
+
return normalizeNodeNameCandidate(hostname3());
|
|
55753
56807
|
}
|
|
55754
56808
|
async function confirmEnrollment(message2) {
|
|
55755
56809
|
if (!process.stdin.isTTY)
|
|
@@ -59178,4 +60232,4 @@ switch (command) {
|
|
|
59178
60232
|
}
|
|
59179
60233
|
}
|
|
59180
60234
|
|
|
59181
|
-
//# debugId=
|
|
60235
|
+
//# debugId=3A2E1C01E70CD8A864756E2164756E21
|