@butlerw/vellum 0.1.16 → 0.1.17
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/dist/index.mjs +216 -146
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import OpenAI from 'openai';
|
|
|
17
17
|
import { ThinkingLevel, GoogleGenAI } from '@google/genai';
|
|
18
18
|
import { Writable, Readable } from 'stream';
|
|
19
19
|
import * as fs30 from 'fs';
|
|
20
|
-
import fs30__default, { existsSync, stat as stat$1, unwatchFile, watchFile, promises, readFileSync, writeFileSync, watch as watch$1,
|
|
20
|
+
import fs30__default, { existsSync, stat as stat$1, unwatchFile, watchFile, promises, mkdirSync, readFileSync, writeFileSync, watch as watch$1, readdirSync, statSync, copyFileSync, rmSync, createWriteStream } from 'fs';
|
|
21
21
|
import * as os16 from 'os';
|
|
22
22
|
import os16__default, { type as type$1, homedir, platform, tmpdir, arch, hostname, release } from 'os';
|
|
23
23
|
import * as util from 'util';
|
|
@@ -35,7 +35,7 @@ import { WebSocketClientTransport } from '@modelcontextprotocol/sdk/client/webso
|
|
|
35
35
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
36
36
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
37
37
|
import { Command } from 'commander';
|
|
38
|
-
import { Text, Box, useInput,
|
|
38
|
+
import { Text, Box, useInput, render, measureElement, useApp, useStdout, useStdin } from 'ink';
|
|
39
39
|
import React6, { createContext, memo, useMemo, useState, useRef, useEffect, useCallback, forwardRef, startTransition, useContext, useImperativeHandle, useId, useReducer, useLayoutEffect, Component } from 'react';
|
|
40
40
|
import { confirm, select, input } from '@inquirer/prompts';
|
|
41
41
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -19513,9 +19513,9 @@ var init_handler = __esm({
|
|
|
19513
19513
|
if (this.fsw.closed) {
|
|
19514
19514
|
return;
|
|
19515
19515
|
}
|
|
19516
|
-
const
|
|
19516
|
+
const dirname53 = sp2.dirname(file);
|
|
19517
19517
|
const basename26 = sp2.basename(file);
|
|
19518
|
-
const parent = this.fsw._getWatchedDir(
|
|
19518
|
+
const parent = this.fsw._getWatchedDir(dirname53);
|
|
19519
19519
|
let prevStats = stats;
|
|
19520
19520
|
if (parent.has(basename26))
|
|
19521
19521
|
return;
|
|
@@ -19542,7 +19542,7 @@ var init_handler = __esm({
|
|
|
19542
19542
|
prevStats = newStats2;
|
|
19543
19543
|
}
|
|
19544
19544
|
} catch (error2) {
|
|
19545
|
-
this.fsw._remove(
|
|
19545
|
+
this.fsw._remove(dirname53, basename26);
|
|
19546
19546
|
}
|
|
19547
19547
|
} else if (parent.has(basename26)) {
|
|
19548
19548
|
const at = newStats.atimeMs;
|
|
@@ -167829,9 +167829,9 @@ var NodeFsHandler2 = class {
|
|
|
167829
167829
|
if (this.fsw.closed) {
|
|
167830
167830
|
return;
|
|
167831
167831
|
}
|
|
167832
|
-
const
|
|
167832
|
+
const dirname53 = sp2.dirname(file);
|
|
167833
167833
|
const basename26 = sp2.basename(file);
|
|
167834
|
-
const parent = this.fsw._getWatchedDir(
|
|
167834
|
+
const parent = this.fsw._getWatchedDir(dirname53);
|
|
167835
167835
|
let prevStats = stats;
|
|
167836
167836
|
if (parent.has(basename26))
|
|
167837
167837
|
return;
|
|
@@ -167858,7 +167858,7 @@ var NodeFsHandler2 = class {
|
|
|
167858
167858
|
prevStats = newStats2;
|
|
167859
167859
|
}
|
|
167860
167860
|
} catch (error2) {
|
|
167861
|
-
this.fsw._remove(
|
|
167861
|
+
this.fsw._remove(dirname53, basename26);
|
|
167862
167862
|
}
|
|
167863
167863
|
} else if (parent.has(basename26)) {
|
|
167864
167864
|
const at = newStats.atimeMs;
|
|
@@ -172704,8 +172704,10 @@ var EN_TRANSLATIONS = {
|
|
|
172704
172704
|
thinking: "Thinking...",
|
|
172705
172705
|
generating: "Generating...",
|
|
172706
172706
|
user: "You",
|
|
172707
|
-
assistant: "
|
|
172707
|
+
assistant: "Vellum",
|
|
172708
172708
|
system: "System",
|
|
172709
|
+
tool: "Tool",
|
|
172710
|
+
unknown: "Unknown",
|
|
172709
172711
|
error: "Error",
|
|
172710
172712
|
empty: "No messages yet",
|
|
172711
172713
|
copied: "Copied to clipboard",
|
|
@@ -172899,8 +172901,10 @@ var ZH_TRANSLATIONS = {
|
|
|
172899
172901
|
thinking: "\u601D\u8003\u4E2D...",
|
|
172900
172902
|
generating: "\u751F\u6210\u4E2D...",
|
|
172901
172903
|
user: "\u4F60",
|
|
172902
|
-
assistant: "
|
|
172904
|
+
assistant: "Vellum",
|
|
172903
172905
|
system: "\u7CFB\u7EDF",
|
|
172906
|
+
tool: "\u5DE5\u5177",
|
|
172907
|
+
unknown: "\u672A\u77E5",
|
|
172904
172908
|
error: "\u9519\u8BEF",
|
|
172905
172909
|
empty: "\u6682\u65E0\u6D88\u606F",
|
|
172906
172910
|
copied: "\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F",
|
|
@@ -189538,7 +189542,7 @@ init_esm_shims();
|
|
|
189538
189542
|
|
|
189539
189543
|
// src/version.ts
|
|
189540
189544
|
init_esm_shims();
|
|
189541
|
-
var version = "0.1.
|
|
189545
|
+
var version = "0.1.17" ;
|
|
189542
189546
|
|
|
189543
189547
|
// src/tui/components/Banner/ShimmerText.tsx
|
|
189544
189548
|
init_esm_shims();
|
|
@@ -191786,9 +191790,72 @@ init_esm_shims();
|
|
|
191786
191790
|
|
|
191787
191791
|
// src/tui/hooks/useInputHistory.ts
|
|
191788
191792
|
init_esm_shims();
|
|
191793
|
+
var VELLUM_DIR2 = join(homedir(), ".vellum");
|
|
191794
|
+
var HISTORY_FILE = join(VELLUM_DIR2, "input-history.json");
|
|
191795
|
+
function isLocalStorageAvailable() {
|
|
191796
|
+
try {
|
|
191797
|
+
if (typeof globalThis.localStorage === "undefined") {
|
|
191798
|
+
return false;
|
|
191799
|
+
}
|
|
191800
|
+
const testKey = "__vellum_storage_test__";
|
|
191801
|
+
globalThis.localStorage.setItem(testKey, "test");
|
|
191802
|
+
globalThis.localStorage.removeItem(testKey);
|
|
191803
|
+
return true;
|
|
191804
|
+
} catch {
|
|
191805
|
+
return false;
|
|
191806
|
+
}
|
|
191807
|
+
}
|
|
191808
|
+
var cachedBackend = null;
|
|
191809
|
+
function getStorageBackend() {
|
|
191810
|
+
if (cachedBackend !== null) {
|
|
191811
|
+
return cachedBackend;
|
|
191812
|
+
}
|
|
191813
|
+
if (isLocalStorageAvailable()) {
|
|
191814
|
+
cachedBackend = "localStorage";
|
|
191815
|
+
return cachedBackend;
|
|
191816
|
+
}
|
|
191817
|
+
try {
|
|
191818
|
+
if (!existsSync(VELLUM_DIR2)) {
|
|
191819
|
+
mkdirSync(VELLUM_DIR2, { recursive: true });
|
|
191820
|
+
}
|
|
191821
|
+
cachedBackend = "file";
|
|
191822
|
+
return cachedBackend;
|
|
191823
|
+
} catch {
|
|
191824
|
+
cachedBackend = "none";
|
|
191825
|
+
return cachedBackend;
|
|
191826
|
+
}
|
|
191827
|
+
}
|
|
191828
|
+
function readHistoryFile() {
|
|
191829
|
+
try {
|
|
191830
|
+
if (!existsSync(HISTORY_FILE)) {
|
|
191831
|
+
return {};
|
|
191832
|
+
}
|
|
191833
|
+
const content = readFileSync(HISTORY_FILE, "utf-8");
|
|
191834
|
+
const parsed = JSON.parse(content);
|
|
191835
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
191836
|
+
return parsed;
|
|
191837
|
+
}
|
|
191838
|
+
return {};
|
|
191839
|
+
} catch {
|
|
191840
|
+
return {};
|
|
191841
|
+
}
|
|
191842
|
+
}
|
|
191843
|
+
function writeHistoryFile(data) {
|
|
191844
|
+
try {
|
|
191845
|
+
const dir = dirname(HISTORY_FILE);
|
|
191846
|
+
if (!existsSync(dir)) {
|
|
191847
|
+
mkdirSync(dir, { recursive: true });
|
|
191848
|
+
}
|
|
191849
|
+
writeFileSync(HISTORY_FILE, JSON.stringify(data, null, 2), "utf-8");
|
|
191850
|
+
return true;
|
|
191851
|
+
} catch {
|
|
191852
|
+
return false;
|
|
191853
|
+
}
|
|
191854
|
+
}
|
|
191789
191855
|
function loadFromStorage(key) {
|
|
191856
|
+
const backend = getStorageBackend();
|
|
191790
191857
|
try {
|
|
191791
|
-
if (
|
|
191858
|
+
if (backend === "localStorage") {
|
|
191792
191859
|
const stored = globalThis.localStorage.getItem(key);
|
|
191793
191860
|
if (stored) {
|
|
191794
191861
|
const parsed = JSON.parse(stored);
|
|
@@ -191796,15 +191863,26 @@ function loadFromStorage(key) {
|
|
|
191796
191863
|
return parsed.filter((item) => typeof item === "string");
|
|
191797
191864
|
}
|
|
191798
191865
|
}
|
|
191866
|
+
} else if (backend === "file") {
|
|
191867
|
+
const historyData = readHistoryFile();
|
|
191868
|
+
const entries = historyData[key];
|
|
191869
|
+
if (Array.isArray(entries)) {
|
|
191870
|
+
return entries.filter((item) => typeof item === "string");
|
|
191871
|
+
}
|
|
191799
191872
|
}
|
|
191800
191873
|
} catch {
|
|
191801
191874
|
}
|
|
191802
191875
|
return [];
|
|
191803
191876
|
}
|
|
191804
191877
|
function saveToStorage(key, history2) {
|
|
191878
|
+
const backend = getStorageBackend();
|
|
191805
191879
|
try {
|
|
191806
|
-
if (
|
|
191880
|
+
if (backend === "localStorage") {
|
|
191807
191881
|
globalThis.localStorage.setItem(key, JSON.stringify(history2));
|
|
191882
|
+
} else if (backend === "file") {
|
|
191883
|
+
const historyData = readHistoryFile();
|
|
191884
|
+
historyData[key] = history2;
|
|
191885
|
+
writeHistoryFile(historyData);
|
|
191808
191886
|
}
|
|
191809
191887
|
} catch {
|
|
191810
191888
|
}
|
|
@@ -199975,33 +200053,52 @@ var DEFAULT_STATIC_MULTIPLIER = 1.2;
|
|
|
199975
200053
|
var DEFAULT_VIRTUAL_MULTIPLIER = 5;
|
|
199976
200054
|
var DEFAULT_MIN_WINDOW_SIZE = 10;
|
|
199977
200055
|
var DEFAULT_MAX_WINDOW_SIZE_RATIO = 0.8;
|
|
200056
|
+
var DEFAULT_MESSAGE_COUNT_THRESHOLD = 50;
|
|
200057
|
+
var DEFAULT_MESSAGE_COUNT_HYSTERESIS = 10;
|
|
199978
200058
|
function useModeController(input3) {
|
|
199979
|
-
const { availableHeight, totalContentHeight, config = {} } = input3;
|
|
200059
|
+
const { availableHeight, totalContentHeight, config = {}, messageCount = 0 } = input3;
|
|
199980
200060
|
const {
|
|
199981
200061
|
staticMultiplier = DEFAULT_STATIC_MULTIPLIER,
|
|
199982
200062
|
virtualMultiplier = DEFAULT_VIRTUAL_MULTIPLIER,
|
|
199983
200063
|
forceMode,
|
|
199984
200064
|
minWindowSize = DEFAULT_MIN_WINDOW_SIZE,
|
|
199985
|
-
maxWindowSizeRatio = DEFAULT_MAX_WINDOW_SIZE_RATIO
|
|
200065
|
+
maxWindowSizeRatio = DEFAULT_MAX_WINDOW_SIZE_RATIO,
|
|
200066
|
+
messageCountThreshold = DEFAULT_MESSAGE_COUNT_THRESHOLD,
|
|
200067
|
+
messageCountHysteresis = DEFAULT_MESSAGE_COUNT_HYSTERESIS
|
|
199986
200068
|
} = config;
|
|
200069
|
+
const wasVirtualizedByCountRef = useRef(false);
|
|
199987
200070
|
return useMemo(() => {
|
|
199988
200071
|
const staticThreshold = Math.max(1, availableHeight * staticMultiplier);
|
|
199989
200072
|
const virtualThreshold = Math.max(1, availableHeight * virtualMultiplier);
|
|
199990
200073
|
const windowSize = Math.max(minWindowSize, Math.floor(availableHeight * maxWindowSizeRatio));
|
|
199991
200074
|
const isAutoMode = !forceMode;
|
|
199992
200075
|
if (forceMode) {
|
|
200076
|
+
wasVirtualizedByCountRef.current = false;
|
|
199993
200077
|
return {
|
|
199994
200078
|
mode: forceMode,
|
|
199995
200079
|
windowSize,
|
|
199996
200080
|
modeReason: "forced",
|
|
199997
200081
|
staticThreshold,
|
|
199998
200082
|
virtualThreshold,
|
|
199999
|
-
isAutoMode
|
|
200083
|
+
isAutoMode,
|
|
200084
|
+
messageCountThreshold,
|
|
200085
|
+
virtualizedByMessageCount: false
|
|
200000
200086
|
};
|
|
200001
200087
|
}
|
|
200088
|
+
let virtualizedByMessageCount = false;
|
|
200089
|
+
const exitThreshold = messageCountThreshold - messageCountHysteresis;
|
|
200090
|
+
if (wasVirtualizedByCountRef.current) {
|
|
200091
|
+
virtualizedByMessageCount = messageCount >= exitThreshold;
|
|
200092
|
+
} else {
|
|
200093
|
+
virtualizedByMessageCount = messageCount >= messageCountThreshold;
|
|
200094
|
+
}
|
|
200095
|
+
wasVirtualizedByCountRef.current = virtualizedByMessageCount;
|
|
200002
200096
|
let mode;
|
|
200003
200097
|
let modeReason;
|
|
200004
|
-
if (
|
|
200098
|
+
if (virtualizedByMessageCount) {
|
|
200099
|
+
mode = "virtualized";
|
|
200100
|
+
modeReason = "content-very-large";
|
|
200101
|
+
} else if (totalContentHeight <= staticThreshold) {
|
|
200005
200102
|
mode = "static";
|
|
200006
200103
|
modeReason = "content-fits";
|
|
200007
200104
|
} else if (totalContentHeight <= virtualThreshold) {
|
|
@@ -200017,7 +200114,9 @@ function useModeController(input3) {
|
|
|
200017
200114
|
modeReason,
|
|
200018
200115
|
staticThreshold,
|
|
200019
200116
|
virtualThreshold,
|
|
200020
|
-
isAutoMode
|
|
200117
|
+
isAutoMode,
|
|
200118
|
+
messageCountThreshold,
|
|
200119
|
+
virtualizedByMessageCount
|
|
200021
200120
|
};
|
|
200022
200121
|
}, [
|
|
200023
200122
|
availableHeight,
|
|
@@ -200026,7 +200125,10 @@ function useModeController(input3) {
|
|
|
200026
200125
|
virtualMultiplier,
|
|
200027
200126
|
forceMode,
|
|
200028
200127
|
minWindowSize,
|
|
200029
|
-
maxWindowSizeRatio
|
|
200128
|
+
maxWindowSizeRatio,
|
|
200129
|
+
messageCount,
|
|
200130
|
+
messageCountThreshold,
|
|
200131
|
+
messageCountHysteresis
|
|
200030
200132
|
]);
|
|
200031
200133
|
}
|
|
200032
200134
|
|
|
@@ -200753,18 +200855,18 @@ function getRoleIcon(role) {
|
|
|
200753
200855
|
return icons2.info;
|
|
200754
200856
|
}
|
|
200755
200857
|
}
|
|
200756
|
-
function getRoleLabel(role) {
|
|
200858
|
+
function getRoleLabel(role, t) {
|
|
200757
200859
|
switch (role) {
|
|
200758
200860
|
case "user":
|
|
200759
|
-
return "
|
|
200861
|
+
return t("messages.user");
|
|
200760
200862
|
case "assistant":
|
|
200761
|
-
return "
|
|
200863
|
+
return t("messages.assistant");
|
|
200762
200864
|
case "system":
|
|
200763
|
-
return "
|
|
200865
|
+
return t("messages.system");
|
|
200764
200866
|
case "tool":
|
|
200765
|
-
return "
|
|
200867
|
+
return t("messages.tool");
|
|
200766
200868
|
default:
|
|
200767
|
-
return "
|
|
200869
|
+
return t("messages.unknown");
|
|
200768
200870
|
}
|
|
200769
200871
|
}
|
|
200770
200872
|
function estimateMessageHeightLegacy(message2, width, includeToolCalls) {
|
|
@@ -200898,8 +201000,9 @@ var MessageItem = memo(function MessageItem2({
|
|
|
200898
201000
|
thinkingToggleHint,
|
|
200899
201001
|
onThinkingHeightChange
|
|
200900
201002
|
}) {
|
|
201003
|
+
const { t } = useTUITranslation();
|
|
200901
201004
|
const icon = getRoleIcon(message2.role);
|
|
200902
|
-
const label = getRoleLabel(message2.role);
|
|
201005
|
+
const label = getRoleLabel(message2.role, t);
|
|
200903
201006
|
const timestamp2 = formatTimestamp2(message2.timestamp);
|
|
200904
201007
|
const hasThinking = message2.thinking && message2.thinking.length > 0;
|
|
200905
201008
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
@@ -201006,10 +201109,18 @@ var MessageList = memo(function MessageList2({
|
|
|
201006
201109
|
0
|
|
201007
201110
|
);
|
|
201008
201111
|
}, [messages, estimatedContentWidth]);
|
|
201009
|
-
const {
|
|
201112
|
+
const {
|
|
201113
|
+
mode,
|
|
201114
|
+
windowSize,
|
|
201115
|
+
modeReason,
|
|
201116
|
+
staticThreshold,
|
|
201117
|
+
virtualThreshold,
|
|
201118
|
+
virtualizedByMessageCount
|
|
201119
|
+
} = useModeController({
|
|
201010
201120
|
availableHeight,
|
|
201011
201121
|
totalContentHeight,
|
|
201012
|
-
config: modeConfig
|
|
201122
|
+
config: modeConfig,
|
|
201123
|
+
messageCount: messages.length
|
|
201013
201124
|
});
|
|
201014
201125
|
const toolGroupCallIds = useMemo(() => {
|
|
201015
201126
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -201042,6 +201153,7 @@ var MessageList = memo(function MessageList2({
|
|
|
201042
201153
|
);
|
|
201043
201154
|
const isStaticOutputMode = process.env.VELLUM_STATIC_OUTPUT === "1";
|
|
201044
201155
|
const shouldConstrainHeight = !isStaticOutputMode && (useAltBuffer || (process.stdout.isTTY ?? false));
|
|
201156
|
+
const allowStaticRendering = false;
|
|
201045
201157
|
const virtualizedListRef = useRef(null);
|
|
201046
201158
|
const expectedScrollTopRef = useRef(null);
|
|
201047
201159
|
const isApplyingControllerScrollRef = useRef(false);
|
|
@@ -201085,13 +201197,13 @@ var MessageList = memo(function MessageList2({
|
|
|
201085
201197
|
const base = computedMaxHeight ?? availableHeight ?? 20;
|
|
201086
201198
|
return Math.max(MIN_SCROLL_VIEWPORT, Math.max(0, base - thinkingIndicatorHeight));
|
|
201087
201199
|
}, [computedMaxHeight, availableHeight, thinkingIndicatorHeight]);
|
|
201088
|
-
|
|
201200
|
+
useMemo(() => {
|
|
201089
201201
|
if (pendingMessage?.thinking && pendingMessage.isStreaming && !pendingMessage.isThinkingComplete) {
|
|
201090
201202
|
return true;
|
|
201091
201203
|
}
|
|
201092
201204
|
return false;
|
|
201093
201205
|
}, [pendingMessage?.thinking, pendingMessage?.isStreaming, pendingMessage?.isThinkingComplete]);
|
|
201094
|
-
const useStaticRendering =
|
|
201206
|
+
const useStaticRendering = allowStaticRendering;
|
|
201095
201207
|
const prevMessageLengthRef = useRef(messages.length);
|
|
201096
201208
|
const [scrollState, scrollActions] = useScrollController({
|
|
201097
201209
|
viewportHeight: scrollViewportHeight,
|
|
@@ -201143,6 +201255,7 @@ var MessageList = memo(function MessageList2({
|
|
|
201143
201255
|
useStaticRendering,
|
|
201144
201256
|
useVirtualizedListInternal,
|
|
201145
201257
|
messageCount: messages.length,
|
|
201258
|
+
virtualizedByMessageCount,
|
|
201146
201259
|
adaptive
|
|
201147
201260
|
});
|
|
201148
201261
|
}
|
|
@@ -201158,6 +201271,7 @@ var MessageList = memo(function MessageList2({
|
|
|
201158
201271
|
useStaticRendering,
|
|
201159
201272
|
useVirtualizedListInternal,
|
|
201160
201273
|
messages.length,
|
|
201274
|
+
virtualizedByMessageCount,
|
|
201161
201275
|
adaptive
|
|
201162
201276
|
]);
|
|
201163
201277
|
const [scrollOffset, setScrollOffset] = useState(0);
|
|
@@ -201535,7 +201649,7 @@ var MessageList = memo(function MessageList2({
|
|
|
201535
201649
|
]
|
|
201536
201650
|
);
|
|
201537
201651
|
const keyExtractor = useCallback((item) => item.id, []);
|
|
201538
|
-
|
|
201652
|
+
pendingMessage ? getThinkingToggleInfo(pendingMessage) : null;
|
|
201539
201653
|
const handleStickingChange = useCallback(
|
|
201540
201654
|
(isSticking) => {
|
|
201541
201655
|
setUserScrolledUp(!isSticking);
|
|
@@ -201758,89 +201872,6 @@ var MessageList = memo(function MessageList2({
|
|
|
201758
201872
|
!enableScroll && userScrolledUp && autoScroll && /* @__PURE__ */ jsx(Box, { justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { color: mutedColor, italic: true, children: "Auto-scroll paused (scroll to bottom to resume)" }) })
|
|
201759
201873
|
] });
|
|
201760
201874
|
}
|
|
201761
|
-
if (useStaticRendering && historyMessages) {
|
|
201762
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
201763
|
-
!enableScroll && showScrollUp && /* @__PURE__ */ jsx(Box, { justifyContent: "center", borderBottom: true, borderColor, children: /* @__PURE__ */ jsxs(Text, { color: mutedColor, children: [
|
|
201764
|
-
"\u2191 ",
|
|
201765
|
-
scrollOffset,
|
|
201766
|
-
" more above \u2191"
|
|
201767
|
-
] }) }),
|
|
201768
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
201769
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
201770
|
-
/* @__PURE__ */ jsx(Static, { items: historyMessages, children: (message2) => {
|
|
201771
|
-
const thinkingToggle = getThinkingToggleInfo(message2);
|
|
201772
|
-
return /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(
|
|
201773
|
-
MessageItem,
|
|
201774
|
-
{
|
|
201775
|
-
message: message2,
|
|
201776
|
-
roleColor: roleColors[message2.role],
|
|
201777
|
-
mutedColor,
|
|
201778
|
-
accentColor,
|
|
201779
|
-
thinkingColor,
|
|
201780
|
-
successColor,
|
|
201781
|
-
errorColor,
|
|
201782
|
-
showToolCalls: shouldRenderInlineToolCalls(message2),
|
|
201783
|
-
thinkingDisplayMode,
|
|
201784
|
-
thinkingToggleSignal: thinkingToggle.signal,
|
|
201785
|
-
thinkingToggleHint: thinkingToggle.hint
|
|
201786
|
-
}
|
|
201787
|
-
) }, message2.id);
|
|
201788
|
-
} }),
|
|
201789
|
-
pendingMessage && /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(
|
|
201790
|
-
MessageItem,
|
|
201791
|
-
{
|
|
201792
|
-
message: pendingMessage,
|
|
201793
|
-
roleColor: roleColors[pendingMessage.role],
|
|
201794
|
-
mutedColor,
|
|
201795
|
-
accentColor,
|
|
201796
|
-
thinkingColor,
|
|
201797
|
-
successColor,
|
|
201798
|
-
errorColor,
|
|
201799
|
-
showToolCalls: shouldRenderInlineToolCalls(pendingMessage),
|
|
201800
|
-
thinkingDisplayMode,
|
|
201801
|
-
thinkingToggleSignal: pendingThinkingToggle?.signal,
|
|
201802
|
-
thinkingToggleHint: pendingThinkingToggle?.hint
|
|
201803
|
-
}
|
|
201804
|
-
) })
|
|
201805
|
-
] }),
|
|
201806
|
-
enableScroll && /* @__PURE__ */ jsx(
|
|
201807
|
-
ScrollIndicator,
|
|
201808
|
-
{
|
|
201809
|
-
totalHeight: scrollState.totalHeight,
|
|
201810
|
-
offsetFromBottom: scrollState.offsetFromBottom,
|
|
201811
|
-
viewportHeight: scrollState.viewportHeight,
|
|
201812
|
-
thumbColor: animatedThumbColor,
|
|
201813
|
-
trackColor: animatedTrackColor
|
|
201814
|
-
}
|
|
201815
|
-
)
|
|
201816
|
-
] }),
|
|
201817
|
-
showThinkingIndicator && /* @__PURE__ */ jsx(ThinkingIndicator, {}),
|
|
201818
|
-
messageSeparation.streamingMessages.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingX: 1, children: messageSeparation.streamingMessages.map((msg) => /* @__PURE__ */ jsx(
|
|
201819
|
-
StreamingMessageItem,
|
|
201820
|
-
{
|
|
201821
|
-
id: msg.id,
|
|
201822
|
-
content: msg.content,
|
|
201823
|
-
meta: msg.meta,
|
|
201824
|
-
onComplete: messageSeparation.markComplete
|
|
201825
|
-
},
|
|
201826
|
-
msg.id
|
|
201827
|
-
)) }),
|
|
201828
|
-
bannerState.isVisible && /* @__PURE__ */ jsx(
|
|
201829
|
-
NewMessagesBanner,
|
|
201830
|
-
{
|
|
201831
|
-
unreadCount: scrollState.newMessageCount,
|
|
201832
|
-
isAtBottom: isAtBottomForBanner,
|
|
201833
|
-
onJumpToBottom: scrollActions.scrollToBottom
|
|
201834
|
-
}
|
|
201835
|
-
),
|
|
201836
|
-
!enableScroll && showScrollDown && /* @__PURE__ */ jsx(Box, { justifyContent: "center", borderTop: true, borderColor, children: /* @__PURE__ */ jsxs(Text, { color: mutedColor, children: [
|
|
201837
|
-
"\u2193 ",
|
|
201838
|
-
messages.length - scrollOffset - (computedMaxHeight ?? 0),
|
|
201839
|
-
" more below \u2193"
|
|
201840
|
-
] }) }),
|
|
201841
|
-
!enableScroll && userScrolledUp && autoScroll && /* @__PURE__ */ jsx(Box, { justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { color: mutedColor, italic: true, children: "Auto-scroll paused (scroll to bottom to resume)" }) })
|
|
201842
|
-
] });
|
|
201843
|
-
}
|
|
201844
201875
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, justifyContent: "flex-end", children: [
|
|
201845
201876
|
!enableScroll && showScrollUp && /* @__PURE__ */ jsx(Box, { justifyContent: "center", borderBottom: true, borderColor, children: /* @__PURE__ */ jsxs(Text, { color: mutedColor, children: [
|
|
201846
201877
|
"\u2191 ",
|
|
@@ -208218,9 +208249,6 @@ function useProviderStatus(options = {}) {
|
|
|
208218
208249
|
};
|
|
208219
208250
|
}
|
|
208220
208251
|
|
|
208221
|
-
// src/tui/hooks/useScrollEventBatcher.ts
|
|
208222
|
-
init_esm_shims();
|
|
208223
|
-
|
|
208224
208252
|
// src/tui/hooks/useSmoothScroll.ts
|
|
208225
208253
|
init_esm_shims();
|
|
208226
208254
|
|
|
@@ -214321,6 +214349,48 @@ function renderSidebarContent({
|
|
|
214321
214349
|
/* @__PURE__ */ jsx(SystemStatusPanel, { compact: false, persistence })
|
|
214322
214350
|
] });
|
|
214323
214351
|
}
|
|
214352
|
+
function useOverlayPositioning() {
|
|
214353
|
+
const { width, isNarrow } = useTerminalDimensions();
|
|
214354
|
+
if (isNarrow) {
|
|
214355
|
+
return {
|
|
214356
|
+
margins: {
|
|
214357
|
+
standard: { top: 2, left: 1 },
|
|
214358
|
+
compact: { top: 1, left: 1 },
|
|
214359
|
+
loading: { top: 2, left: 1 }
|
|
214360
|
+
},
|
|
214361
|
+
loadingMinWidth: Math.min(36, width - 4),
|
|
214362
|
+
// Leave 4 cols for border+padding
|
|
214363
|
+
isNarrow: true,
|
|
214364
|
+
width
|
|
214365
|
+
};
|
|
214366
|
+
}
|
|
214367
|
+
if (width <= 120) {
|
|
214368
|
+
const t = (width - 80) / 40;
|
|
214369
|
+
const standardLeft = Math.round(2 + t * 8);
|
|
214370
|
+
const compactLeft = Math.round(1 + t * 4);
|
|
214371
|
+
const loadingLeft = Math.round(2 + t * 6);
|
|
214372
|
+
return {
|
|
214373
|
+
margins: {
|
|
214374
|
+
standard: { top: Math.round(3 + t * 2), left: standardLeft },
|
|
214375
|
+
compact: { top: Math.round(2 + t * 1), left: compactLeft },
|
|
214376
|
+
loading: { top: Math.round(2 + t * 2), left: loadingLeft }
|
|
214377
|
+
},
|
|
214378
|
+
loadingMinWidth: Math.min(40, width - standardLeft * 2 - 4),
|
|
214379
|
+
isNarrow: false,
|
|
214380
|
+
width
|
|
214381
|
+
};
|
|
214382
|
+
}
|
|
214383
|
+
return {
|
|
214384
|
+
margins: {
|
|
214385
|
+
standard: { top: 5, left: 10 },
|
|
214386
|
+
compact: { top: 3, left: 5 },
|
|
214387
|
+
loading: { top: 4, left: 8 }
|
|
214388
|
+
},
|
|
214389
|
+
loadingMinWidth: 40,
|
|
214390
|
+
isNarrow: false,
|
|
214391
|
+
width
|
|
214392
|
+
};
|
|
214393
|
+
}
|
|
214324
214394
|
function AppOverlays({
|
|
214325
214395
|
activeApproval,
|
|
214326
214396
|
activeRiskLevel,
|
|
@@ -214356,6 +214426,7 @@ function AppOverlays({
|
|
|
214356
214426
|
themeContext,
|
|
214357
214427
|
updateAvailable
|
|
214358
214428
|
}) {
|
|
214429
|
+
const { margins, loadingMinWidth, isNarrow } = useOverlayPositioning();
|
|
214359
214430
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
214360
214431
|
updateAvailable && /* @__PURE__ */ jsx(
|
|
214361
214432
|
UpdateBanner,
|
|
@@ -214371,18 +214442,18 @@ function AppOverlays({
|
|
|
214371
214442
|
Box,
|
|
214372
214443
|
{
|
|
214373
214444
|
position: "absolute",
|
|
214374
|
-
marginTop:
|
|
214375
|
-
marginLeft:
|
|
214445
|
+
marginTop: margins.standard.top,
|
|
214446
|
+
marginLeft: margins.standard.left,
|
|
214376
214447
|
borderStyle: "round",
|
|
214377
214448
|
borderColor: themeContext.theme.colors.info,
|
|
214378
|
-
padding: 1,
|
|
214449
|
+
padding: isNarrow ? 0 : 1,
|
|
214379
214450
|
children: /* @__PURE__ */ jsx(
|
|
214380
214451
|
ModeSelector,
|
|
214381
214452
|
{
|
|
214382
214453
|
currentMode: currentMode2,
|
|
214383
214454
|
onSelect: handleModeSelect,
|
|
214384
214455
|
isActive: showModeSelector,
|
|
214385
|
-
showDescriptions:
|
|
214456
|
+
showDescriptions: !isNarrow
|
|
214386
214457
|
}
|
|
214387
214458
|
)
|
|
214388
214459
|
}
|
|
@@ -214391,11 +214462,11 @@ function AppOverlays({
|
|
|
214391
214462
|
Box,
|
|
214392
214463
|
{
|
|
214393
214464
|
position: "absolute",
|
|
214394
|
-
marginTop:
|
|
214395
|
-
marginLeft:
|
|
214465
|
+
marginTop: margins.compact.top,
|
|
214466
|
+
marginLeft: margins.compact.left,
|
|
214396
214467
|
borderStyle: "round",
|
|
214397
214468
|
borderColor: themeContext.theme.colors.primary,
|
|
214398
|
-
padding: 1,
|
|
214469
|
+
padding: isNarrow ? 0 : 1,
|
|
214399
214470
|
children: /* @__PURE__ */ jsx(
|
|
214400
214471
|
SessionPicker,
|
|
214401
214472
|
{
|
|
@@ -214413,11 +214484,11 @@ function AppOverlays({
|
|
|
214413
214484
|
Box,
|
|
214414
214485
|
{
|
|
214415
214486
|
position: "absolute",
|
|
214416
|
-
marginTop:
|
|
214417
|
-
marginLeft:
|
|
214487
|
+
marginTop: margins.standard.top,
|
|
214488
|
+
marginLeft: margins.standard.left,
|
|
214418
214489
|
borderStyle: "double",
|
|
214419
214490
|
borderColor: themeContext.theme.colors.warning,
|
|
214420
|
-
padding: 1,
|
|
214491
|
+
padding: isNarrow ? 0 : 1,
|
|
214421
214492
|
children: /* @__PURE__ */ jsx(
|
|
214422
214493
|
PermissionDialog,
|
|
214423
214494
|
{
|
|
@@ -214435,11 +214506,11 @@ function AppOverlays({
|
|
|
214435
214506
|
Box,
|
|
214436
214507
|
{
|
|
214437
214508
|
position: "absolute",
|
|
214438
|
-
marginTop:
|
|
214439
|
-
marginLeft:
|
|
214509
|
+
marginTop: margins.standard.top,
|
|
214510
|
+
marginLeft: margins.standard.left,
|
|
214440
214511
|
borderStyle: "round",
|
|
214441
214512
|
borderColor: themeContext.theme.colors.success,
|
|
214442
|
-
padding: 1,
|
|
214513
|
+
padding: isNarrow ? 0 : 1,
|
|
214443
214514
|
children: /* @__PURE__ */ jsx(
|
|
214444
214515
|
ModelSelector,
|
|
214445
214516
|
{
|
|
@@ -214447,7 +214518,7 @@ function AppOverlays({
|
|
|
214447
214518
|
currentProvider,
|
|
214448
214519
|
onSelect: handleModelSelect,
|
|
214449
214520
|
isActive: showModelSelector,
|
|
214450
|
-
showDetails:
|
|
214521
|
+
showDetails: !isNarrow
|
|
214451
214522
|
}
|
|
214452
214523
|
)
|
|
214453
214524
|
}
|
|
@@ -214456,13 +214527,13 @@ function AppOverlays({
|
|
|
214456
214527
|
Box,
|
|
214457
214528
|
{
|
|
214458
214529
|
position: "absolute",
|
|
214459
|
-
marginTop:
|
|
214460
|
-
marginLeft:
|
|
214530
|
+
marginTop: margins.loading.top,
|
|
214531
|
+
marginLeft: margins.loading.left,
|
|
214461
214532
|
borderStyle: "round",
|
|
214462
214533
|
borderColor: themeContext.theme.colors.warning,
|
|
214463
|
-
padding: 1,
|
|
214534
|
+
padding: isNarrow ? 0 : 1,
|
|
214464
214535
|
flexDirection: "column",
|
|
214465
|
-
minWidth:
|
|
214536
|
+
minWidth: loadingMinWidth,
|
|
214466
214537
|
children: [
|
|
214467
214538
|
/* @__PURE__ */ jsx(LoadingIndicator, { message: pendingOperation.message }),
|
|
214468
214539
|
pendingOperation.cancel && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press Esc to cancel" })
|
|
@@ -214473,11 +214544,11 @@ function AppOverlays({
|
|
|
214473
214544
|
Box,
|
|
214474
214545
|
{
|
|
214475
214546
|
position: "absolute",
|
|
214476
|
-
marginTop:
|
|
214477
|
-
marginLeft:
|
|
214547
|
+
marginTop: margins.standard.top,
|
|
214548
|
+
marginLeft: margins.standard.left,
|
|
214478
214549
|
borderStyle: "round",
|
|
214479
214550
|
borderColor: themeContext.theme.colors.info,
|
|
214480
|
-
padding: 1,
|
|
214551
|
+
padding: isNarrow ? 0 : 1,
|
|
214481
214552
|
children: /* @__PURE__ */ jsx(
|
|
214482
214553
|
HotkeyHelpModal,
|
|
214483
214554
|
{
|
|
@@ -214492,11 +214563,11 @@ function AppOverlays({
|
|
|
214492
214563
|
Box,
|
|
214493
214564
|
{
|
|
214494
214565
|
position: "absolute",
|
|
214495
|
-
marginTop:
|
|
214496
|
-
marginLeft:
|
|
214566
|
+
marginTop: margins.compact.top,
|
|
214567
|
+
marginLeft: margins.compact.left,
|
|
214497
214568
|
borderStyle: "double",
|
|
214498
214569
|
borderColor: themeContext.theme.colors.warning,
|
|
214499
|
-
padding: 1,
|
|
214570
|
+
padding: isNarrow ? 0 : 1,
|
|
214500
214571
|
children: /* @__PURE__ */ jsx(
|
|
214501
214572
|
ApprovalQueue,
|
|
214502
214573
|
{
|
|
@@ -214514,11 +214585,11 @@ function AppOverlays({
|
|
|
214514
214585
|
Box,
|
|
214515
214586
|
{
|
|
214516
214587
|
position: "absolute",
|
|
214517
|
-
marginTop:
|
|
214518
|
-
marginLeft:
|
|
214588
|
+
marginTop: margins.compact.top,
|
|
214589
|
+
marginLeft: margins.compact.left,
|
|
214519
214590
|
borderStyle: "double",
|
|
214520
214591
|
borderColor: themeContext.theme.colors.info,
|
|
214521
|
-
padding: 1,
|
|
214592
|
+
padding: isNarrow ? 0 : 1,
|
|
214522
214593
|
children: /* @__PURE__ */ jsx(
|
|
214523
214594
|
CheckpointDiffView,
|
|
214524
214595
|
{
|
|
@@ -214784,10 +214855,9 @@ function AppContentView({
|
|
|
214784
214855
|
MessageList,
|
|
214785
214856
|
{
|
|
214786
214857
|
messages,
|
|
214787
|
-
historyMessages: messages.filter((m) => !m.isStreaming),
|
|
214788
214858
|
pendingMessage,
|
|
214789
214859
|
isLoading,
|
|
214790
|
-
|
|
214860
|
+
adaptive: true,
|
|
214791
214861
|
estimatedItemHeight: 4,
|
|
214792
214862
|
scrollKeyMode: commandInputFocused ? "page" : "all",
|
|
214793
214863
|
forceFollowOnInput: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@butlerw/vellum",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Next-generation AI coding assistant CLI",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -57,9 +57,9 @@
|
|
|
57
57
|
"tsx": "^4.21.0",
|
|
58
58
|
"typescript": "^5.9.3",
|
|
59
59
|
"@vellum/core": "0.1.14",
|
|
60
|
-
"@vellum/lsp": "0.1.0",
|
|
61
60
|
"@vellum/mcp": "0.1.2",
|
|
62
61
|
"@vellum/plugin": "0.1.2",
|
|
62
|
+
"@vellum/lsp": "0.1.0",
|
|
63
63
|
"@vellum/provider": "0.1.0",
|
|
64
64
|
"@vellum/sandbox": "0.1.0",
|
|
65
65
|
"@vellum/shared": "0.1.0"
|