steward-cli 0.15.0 → 0.17.0
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/cli.js +1453 -528
- package/dist/steward +4 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -42222,6 +42222,40 @@ function stringWidth(input, options = {}) {
|
|
|
42222
42222
|
// src/tui/engine/cell-layout.ts
|
|
42223
42223
|
import { appendFileSync } from "node:fs";
|
|
42224
42224
|
|
|
42225
|
+
// src/theme/figures.ts
|
|
42226
|
+
var figures = {
|
|
42227
|
+
blackCircle: "●",
|
|
42228
|
+
bullet: "·",
|
|
42229
|
+
bulletSmall: "∙",
|
|
42230
|
+
teardropAsterisk: "✻",
|
|
42231
|
+
asterisk: "*",
|
|
42232
|
+
threeDots: "∴",
|
|
42233
|
+
treeBranch: "└",
|
|
42234
|
+
treeVertical: "│",
|
|
42235
|
+
pointer: ">",
|
|
42236
|
+
pointerBold: "❯",
|
|
42237
|
+
pointerSmall: "›",
|
|
42238
|
+
tick: "✔",
|
|
42239
|
+
cross: "✖",
|
|
42240
|
+
warning: "⚠",
|
|
42241
|
+
info: "ℹ",
|
|
42242
|
+
ellipsis: "…",
|
|
42243
|
+
arrowUp: "↑",
|
|
42244
|
+
arrowDown: "↓",
|
|
42245
|
+
arrowLeft: "←",
|
|
42246
|
+
arrowRight: "→",
|
|
42247
|
+
blockquoteBar: "▎",
|
|
42248
|
+
horizontalLine: "─",
|
|
42249
|
+
heavyHorizontal: "━",
|
|
42250
|
+
dashedLine: "╌",
|
|
42251
|
+
effortLow: "○",
|
|
42252
|
+
effortMedium: "◐",
|
|
42253
|
+
effortHigh: "●",
|
|
42254
|
+
effortMax: "◉",
|
|
42255
|
+
sliderPointer: "▲",
|
|
42256
|
+
sliderDivider: "┆",
|
|
42257
|
+
spinnerFrames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
|
42258
|
+
};
|
|
42225
42259
|
// node_modules/chalk/source/utilities.js
|
|
42226
42260
|
function stringReplaceAll(string, substring, postfix) {
|
|
42227
42261
|
let index = string.indexOf(substring);
|
|
@@ -42770,80 +42804,420 @@ var chalk = createChalk();
|
|
|
42770
42804
|
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
42771
42805
|
var source_default = chalk;
|
|
42772
42806
|
|
|
42773
|
-
// src/theme/
|
|
42774
|
-
|
|
42775
|
-
|
|
42776
|
-
|
|
42777
|
-
|
|
42778
|
-
|
|
42779
|
-
|
|
42780
|
-
|
|
42781
|
-
|
|
42782
|
-
|
|
42783
|
-
|
|
42784
|
-
|
|
42785
|
-
|
|
42786
|
-
|
|
42787
|
-
|
|
42788
|
-
|
|
42789
|
-
|
|
42790
|
-
|
|
42791
|
-
|
|
42792
|
-
|
|
42793
|
-
|
|
42794
|
-
|
|
42795
|
-
|
|
42796
|
-
|
|
42797
|
-
|
|
42798
|
-
|
|
42799
|
-
|
|
42800
|
-
|
|
42801
|
-
|
|
42802
|
-
|
|
42803
|
-
|
|
42804
|
-
|
|
42805
|
-
|
|
42806
|
-
|
|
42807
|
-
|
|
42808
|
-
|
|
42807
|
+
// src/theme/apply.ts
|
|
42808
|
+
function resolveThemeColor(color, isBg = false) {
|
|
42809
|
+
if (!color || color === "default" || color === "none" || color === "transparent" || color === "ansi(reset)" || color === "ansi(default)") {
|
|
42810
|
+
return (s) => s;
|
|
42811
|
+
}
|
|
42812
|
+
if (color === "dim" || color === "ansi(dim)") {
|
|
42813
|
+
return isBg ? (s) => s : (s) => source_default.dim(s);
|
|
42814
|
+
}
|
|
42815
|
+
if (color.startsWith("ansi(") && color.endsWith(")")) {
|
|
42816
|
+
const name = color.slice(5, -1).trim();
|
|
42817
|
+
if (name === "reset" || name === "none" || name === "transparent" || name === "default") {
|
|
42818
|
+
return (s) => s;
|
|
42819
|
+
}
|
|
42820
|
+
if (name === "dim") {
|
|
42821
|
+
return isBg ? (s) => s : (s) => source_default.dim(s);
|
|
42822
|
+
}
|
|
42823
|
+
if (isBg && !name.startsWith("bg")) {
|
|
42824
|
+
const bgName = `bg${name.charAt(0).toUpperCase()}${name.slice(1)}`;
|
|
42825
|
+
const fn = source_default[bgName];
|
|
42826
|
+
if (typeof fn === "function")
|
|
42827
|
+
return fn;
|
|
42828
|
+
}
|
|
42829
|
+
const fn = source_default[name];
|
|
42830
|
+
if (typeof fn === "function")
|
|
42831
|
+
return fn;
|
|
42832
|
+
return (s) => s;
|
|
42833
|
+
}
|
|
42834
|
+
if (color.startsWith("rgb(")) {
|
|
42835
|
+
const match = color.match(/\d+/g);
|
|
42836
|
+
if (match && match.length >= 3) {
|
|
42837
|
+
const [r, g, b] = [Number(match[0]), Number(match[1]), Number(match[2])];
|
|
42838
|
+
return isBg ? source_default.bgRgb(r, g, b) : source_default.rgb(r, g, b);
|
|
42839
|
+
}
|
|
42840
|
+
}
|
|
42841
|
+
if (color.startsWith("#")) {
|
|
42842
|
+
return isBg ? source_default.bgHex(color) : source_default.hex(color);
|
|
42843
|
+
}
|
|
42844
|
+
return (s) => s;
|
|
42845
|
+
}
|
|
42846
|
+
|
|
42847
|
+
// src/theme/style.ts
|
|
42848
|
+
var _themeVersion = 0;
|
|
42849
|
+
function themeVersion() {
|
|
42850
|
+
return _themeVersion;
|
|
42851
|
+
}
|
|
42852
|
+
function bumpThemeVersion() {
|
|
42853
|
+
_themeVersion++;
|
|
42854
|
+
}
|
|
42855
|
+
var colorCache = new Map;
|
|
42856
|
+
var cachedVersion = -1;
|
|
42857
|
+
function getCachedColor(token, isBg) {
|
|
42858
|
+
if (source_default.level === 0) {
|
|
42859
|
+
return (s) => s;
|
|
42860
|
+
}
|
|
42861
|
+
const v = _themeVersion;
|
|
42862
|
+
if (v !== cachedVersion) {
|
|
42863
|
+
colorCache.clear();
|
|
42864
|
+
cachedVersion = v;
|
|
42865
|
+
}
|
|
42866
|
+
const key = `${isBg ? "bg:" : "fg:"}${token}`;
|
|
42867
|
+
let fn = colorCache.get(key);
|
|
42868
|
+
if (!fn) {
|
|
42869
|
+
const theme = getTheme();
|
|
42870
|
+
const colorStr = theme[token];
|
|
42871
|
+
fn = resolveThemeColor(colorStr ?? (isBg ? "default" : "default"), isBg);
|
|
42872
|
+
colorCache.set(key, fn);
|
|
42873
|
+
}
|
|
42874
|
+
return fn;
|
|
42875
|
+
}
|
|
42876
|
+
var c = new Proxy({}, {
|
|
42877
|
+
get(_target, prop) {
|
|
42878
|
+
return (s) => getCachedColor(prop, false)(s);
|
|
42879
|
+
}
|
|
42880
|
+
});
|
|
42881
|
+
var bg = new Proxy({}, {
|
|
42882
|
+
get(_target, prop) {
|
|
42883
|
+
return (s) => getCachedColor(prop, true)(s);
|
|
42884
|
+
}
|
|
42885
|
+
});
|
|
42886
|
+
var bold = (s) => source_default.level === 0 ? s : source_default.bold(s);
|
|
42887
|
+
var italic = (s) => source_default.level === 0 ? s : source_default.italic(s);
|
|
42888
|
+
var underline = (s) => source_default.level === 0 ? s : source_default.underline(s);
|
|
42889
|
+
var strikethrough = (s) => source_default.level === 0 ? s : source_default.strikethrough(s);
|
|
42890
|
+
|
|
42809
42891
|
// src/theme/colors.ts
|
|
42810
42892
|
var darkTheme = {
|
|
42893
|
+
text: "rgb(255,255,255)",
|
|
42894
|
+
muted: "rgb(110,110,110)",
|
|
42895
|
+
subtle: "rgb(80,80,80)",
|
|
42811
42896
|
brand: "rgb(215,119,87)",
|
|
42812
|
-
|
|
42813
|
-
permission: "rgb(177,185,249)",
|
|
42814
|
-
permissionDim: "rgb(93,100,128)",
|
|
42815
|
-
permissionShimmer: "rgb(207,215,255)",
|
|
42816
|
-
lavenderHeader: "rgb(129,136,165)",
|
|
42817
|
-
lavenderLight: "rgb(183,184,228)",
|
|
42818
|
-
bashPink: "rgb(253,93,177)",
|
|
42897
|
+
info: "rgb(123,165,218)",
|
|
42819
42898
|
success: "rgb(78,186,101)",
|
|
42820
|
-
error: "rgb(255,107,128)",
|
|
42821
42899
|
warning: "rgb(255,193,7)",
|
|
42822
|
-
|
|
42823
|
-
|
|
42824
|
-
|
|
42825
|
-
|
|
42826
|
-
text: "rgb(255,255,255)",
|
|
42827
|
-
textMuted: "rgb(110,110,110)",
|
|
42828
|
-
subtle: "rgb(80,80,80)",
|
|
42829
|
-
inactive: "rgb(153,153,153)",
|
|
42900
|
+
error: "rgb(255,107,128)",
|
|
42901
|
+
permission: "rgb(177,185,249)",
|
|
42902
|
+
selected: "rgb(177,185,249)",
|
|
42903
|
+
current: "rgb(255,193,7)",
|
|
42830
42904
|
promptBorder: "rgb(136,136,136)",
|
|
42831
|
-
|
|
42905
|
+
rule: "rgb(129,136,165)",
|
|
42832
42906
|
userChevron: "rgb(82,82,82)",
|
|
42833
|
-
|
|
42834
|
-
|
|
42835
|
-
|
|
42836
|
-
|
|
42837
|
-
|
|
42838
|
-
|
|
42839
|
-
|
|
42907
|
+
userBg: "rgb(55,55,55)",
|
|
42908
|
+
diffAddBg: "rgb(19,54,14)",
|
|
42909
|
+
diffDelBg: "rgb(54,5,9)",
|
|
42910
|
+
diffAddFg: "rgb(126,231,135)",
|
|
42911
|
+
diffDelFg: "rgb(255,123,114)",
|
|
42912
|
+
syntax: {
|
|
42913
|
+
keyword: "#ff7b72",
|
|
42914
|
+
string: "#a5d6ff",
|
|
42915
|
+
number: "#79c0ff",
|
|
42916
|
+
literal: "#79c0ff",
|
|
42917
|
+
comment: "#8b949e",
|
|
42918
|
+
function: "#d2a8ff",
|
|
42919
|
+
type: "#ffa657",
|
|
42920
|
+
variable: "#ffa657",
|
|
42921
|
+
tag: "#7ee787",
|
|
42922
|
+
attr: "#79c0ff",
|
|
42923
|
+
meta: "#79c0ff",
|
|
42924
|
+
addition: "#7ee787",
|
|
42925
|
+
deletion: "#ffa198",
|
|
42926
|
+
default: "#c9d1d9"
|
|
42927
|
+
}
|
|
42840
42928
|
};
|
|
42929
|
+
var lightTheme = {
|
|
42930
|
+
text: "default",
|
|
42931
|
+
muted: "rgb(120,120,120)",
|
|
42932
|
+
subtle: "rgb(175,175,175)",
|
|
42933
|
+
brand: "rgb(215,119,87)",
|
|
42934
|
+
info: "rgb(40,100,180)",
|
|
42935
|
+
success: "rgb(44,122,57)",
|
|
42936
|
+
warning: "rgb(150,108,30)",
|
|
42937
|
+
error: "rgb(171,43,63)",
|
|
42938
|
+
permission: "rgb(87,105,247)",
|
|
42939
|
+
selected: "rgb(87,105,247)",
|
|
42940
|
+
current: "rgb(150,108,30)",
|
|
42941
|
+
promptBorder: "rgb(153,153,153)",
|
|
42942
|
+
rule: "rgb(120,130,160)",
|
|
42943
|
+
userChevron: "rgb(160,160,160)",
|
|
42944
|
+
userBg: "rgb(240,240,240)",
|
|
42945
|
+
diffAddBg: "rgb(220,245,220)",
|
|
42946
|
+
diffDelBg: "rgb(255,230,230)",
|
|
42947
|
+
diffAddFg: "rgb(30,120,40)",
|
|
42948
|
+
diffDelFg: "rgb(180,40,40)",
|
|
42949
|
+
syntax: {
|
|
42950
|
+
keyword: "#d73a49",
|
|
42951
|
+
string: "#032f62",
|
|
42952
|
+
number: "#005cc5",
|
|
42953
|
+
literal: "#005cc5",
|
|
42954
|
+
comment: "#6a737d",
|
|
42955
|
+
function: "#6f42c1",
|
|
42956
|
+
type: "#e36209",
|
|
42957
|
+
variable: "#e36209",
|
|
42958
|
+
tag: "#22863a",
|
|
42959
|
+
attr: "#005cc5",
|
|
42960
|
+
meta: "#005cc5",
|
|
42961
|
+
addition: "#22863a",
|
|
42962
|
+
deletion: "#b31d28",
|
|
42963
|
+
default: "default"
|
|
42964
|
+
}
|
|
42965
|
+
};
|
|
42966
|
+
var draculaTheme = {
|
|
42967
|
+
text: "rgb(248,248,242)",
|
|
42968
|
+
muted: "rgb(98,114,164)",
|
|
42969
|
+
subtle: "rgb(68,71,90)",
|
|
42970
|
+
brand: "rgb(255,184,108)",
|
|
42971
|
+
info: "rgb(139,233,253)",
|
|
42972
|
+
success: "rgb(80,250,123)",
|
|
42973
|
+
warning: "rgb(255,184,108)",
|
|
42974
|
+
error: "rgb(255,85,85)",
|
|
42975
|
+
permission: "rgb(189,147,249)",
|
|
42976
|
+
selected: "rgb(189,147,249)",
|
|
42977
|
+
current: "rgb(255,184,108)",
|
|
42978
|
+
promptBorder: "rgb(98,114,164)",
|
|
42979
|
+
rule: "rgb(189,147,249)",
|
|
42980
|
+
userChevron: "rgb(98,114,164)",
|
|
42981
|
+
userBg: "rgb(68,71,90)",
|
|
42982
|
+
diffAddBg: "rgb(12,38,18)",
|
|
42983
|
+
diffDelBg: "rgb(45,15,15)",
|
|
42984
|
+
diffAddFg: "rgb(80,250,123)",
|
|
42985
|
+
diffDelFg: "rgb(255,85,85)",
|
|
42986
|
+
syntax: {
|
|
42987
|
+
keyword: "rgb(255,121,198)",
|
|
42988
|
+
string: "rgb(241,250,140)",
|
|
42989
|
+
number: "rgb(189,147,249)",
|
|
42990
|
+
literal: "rgb(189,147,249)",
|
|
42991
|
+
comment: "rgb(98,114,164)",
|
|
42992
|
+
function: "rgb(80,250,123)",
|
|
42993
|
+
type: "rgb(139,233,253)",
|
|
42994
|
+
variable: "rgb(255,184,108)",
|
|
42995
|
+
tag: "rgb(255,121,198)",
|
|
42996
|
+
attr: "rgb(80,250,123)",
|
|
42997
|
+
meta: "rgb(255,121,198)",
|
|
42998
|
+
addition: "rgb(80,250,123)",
|
|
42999
|
+
deletion: "rgb(255,85,85)",
|
|
43000
|
+
default: "rgb(248,248,242)"
|
|
43001
|
+
}
|
|
43002
|
+
};
|
|
43003
|
+
var darkAnsiTheme = {
|
|
43004
|
+
text: "default",
|
|
43005
|
+
muted: "dim",
|
|
43006
|
+
subtle: "dim",
|
|
43007
|
+
brand: "ansi(yellow)",
|
|
43008
|
+
info: "ansi(cyan)",
|
|
43009
|
+
success: "ansi(green)",
|
|
43010
|
+
warning: "ansi(yellow)",
|
|
43011
|
+
error: "ansi(red)",
|
|
43012
|
+
permission: "ansi(blue)",
|
|
43013
|
+
selected: "ansi(blue)",
|
|
43014
|
+
current: "ansi(yellow)",
|
|
43015
|
+
promptBorder: "dim",
|
|
43016
|
+
rule: "dim",
|
|
43017
|
+
userChevron: "dim",
|
|
43018
|
+
userBg: "ansi(bgBlackBright)",
|
|
43019
|
+
diffAddBg: "default",
|
|
43020
|
+
diffDelBg: "default",
|
|
43021
|
+
diffAddFg: "ansi(green)",
|
|
43022
|
+
diffDelFg: "ansi(red)",
|
|
43023
|
+
syntax: {
|
|
43024
|
+
keyword: "ansi(red)",
|
|
43025
|
+
string: "ansi(cyan)",
|
|
43026
|
+
number: "ansi(cyan)",
|
|
43027
|
+
literal: "ansi(cyan)",
|
|
43028
|
+
comment: "ansi(gray)",
|
|
43029
|
+
function: "ansi(magenta)",
|
|
43030
|
+
type: "ansi(yellow)",
|
|
43031
|
+
variable: "ansi(yellow)",
|
|
43032
|
+
tag: "ansi(green)",
|
|
43033
|
+
attr: "ansi(cyan)",
|
|
43034
|
+
meta: "ansi(blue)",
|
|
43035
|
+
addition: "ansi(green)",
|
|
43036
|
+
deletion: "ansi(red)",
|
|
43037
|
+
default: "ansi(white)"
|
|
43038
|
+
}
|
|
43039
|
+
};
|
|
43040
|
+
var lightAnsiTheme = {
|
|
43041
|
+
text: "default",
|
|
43042
|
+
muted: "dim",
|
|
43043
|
+
subtle: "dim",
|
|
43044
|
+
brand: "ansi(yellow)",
|
|
43045
|
+
info: "ansi(blue)",
|
|
43046
|
+
success: "ansi(green)",
|
|
43047
|
+
warning: "ansi(yellow)",
|
|
43048
|
+
error: "ansi(red)",
|
|
43049
|
+
permission: "ansi(blue)",
|
|
43050
|
+
selected: "ansi(blue)",
|
|
43051
|
+
current: "ansi(yellow)",
|
|
43052
|
+
promptBorder: "dim",
|
|
43053
|
+
rule: "dim",
|
|
43054
|
+
userChevron: "dim",
|
|
43055
|
+
userBg: "ansi(bgWhiteBright)",
|
|
43056
|
+
diffAddBg: "default",
|
|
43057
|
+
diffDelBg: "default",
|
|
43058
|
+
diffAddFg: "ansi(green)",
|
|
43059
|
+
diffDelFg: "ansi(red)",
|
|
43060
|
+
syntax: {
|
|
43061
|
+
keyword: "ansi(red)",
|
|
43062
|
+
string: "ansi(blue)",
|
|
43063
|
+
number: "ansi(blue)",
|
|
43064
|
+
literal: "ansi(blue)",
|
|
43065
|
+
comment: "ansi(gray)",
|
|
43066
|
+
function: "ansi(magenta)",
|
|
43067
|
+
type: "ansi(yellow)",
|
|
43068
|
+
variable: "ansi(yellow)",
|
|
43069
|
+
tag: "ansi(green)",
|
|
43070
|
+
attr: "ansi(blue)",
|
|
43071
|
+
meta: "ansi(blue)",
|
|
43072
|
+
addition: "ansi(green)",
|
|
43073
|
+
deletion: "ansi(red)",
|
|
43074
|
+
default: "default"
|
|
43075
|
+
}
|
|
43076
|
+
};
|
|
43077
|
+
var builtInThemes = [
|
|
43078
|
+
{
|
|
43079
|
+
name: "dark",
|
|
43080
|
+
label: "Dark (Default)",
|
|
43081
|
+
description: "Default dark theme with terracotta and purple accents",
|
|
43082
|
+
theme: darkTheme,
|
|
43083
|
+
source: "built-in"
|
|
43084
|
+
},
|
|
43085
|
+
{
|
|
43086
|
+
name: "light",
|
|
43087
|
+
label: "Light",
|
|
43088
|
+
description: "Clean light palette optimized for light backgrounds",
|
|
43089
|
+
theme: lightTheme,
|
|
43090
|
+
source: "built-in"
|
|
43091
|
+
},
|
|
43092
|
+
{
|
|
43093
|
+
name: "dracula",
|
|
43094
|
+
label: "Dracula",
|
|
43095
|
+
description: "Official gothic-inspired vampire color scheme",
|
|
43096
|
+
theme: draculaTheme,
|
|
43097
|
+
source: "built-in"
|
|
43098
|
+
},
|
|
43099
|
+
{
|
|
43100
|
+
name: "dark-ansi",
|
|
43101
|
+
label: "Dark ANSI",
|
|
43102
|
+
description: "16-color ANSI palette respecting your terminal theme",
|
|
43103
|
+
theme: darkAnsiTheme,
|
|
43104
|
+
source: "built-in"
|
|
43105
|
+
},
|
|
43106
|
+
{
|
|
43107
|
+
name: "light-ansi",
|
|
43108
|
+
label: "Light ANSI",
|
|
43109
|
+
description: "16-color ANSI light palette respecting terminal colors",
|
|
43110
|
+
theme: lightAnsiTheme,
|
|
43111
|
+
source: "built-in"
|
|
43112
|
+
}
|
|
43113
|
+
];
|
|
43114
|
+
var registry = new Map;
|
|
43115
|
+
for (const t of builtInThemes) {
|
|
43116
|
+
registry.set(t.name, t);
|
|
43117
|
+
}
|
|
43118
|
+
var activeThemeId = "dark";
|
|
43119
|
+
function listThemes() {
|
|
43120
|
+
return Array.from(registry.values());
|
|
43121
|
+
}
|
|
43122
|
+
function findTheme(query) {
|
|
43123
|
+
const q = query.trim().toLowerCase().replace(/^["']|["']$/g, "");
|
|
43124
|
+
if (!q)
|
|
43125
|
+
return;
|
|
43126
|
+
return listThemes().find((t) => t.name.toLowerCase() === q || t.label.toLowerCase() === q || t.label.toLowerCase().startsWith(q));
|
|
43127
|
+
}
|
|
43128
|
+
function setActiveTheme(name) {
|
|
43129
|
+
if (registry.has(name)) {
|
|
43130
|
+
activeThemeId = name;
|
|
43131
|
+
bumpThemeVersion();
|
|
43132
|
+
return true;
|
|
43133
|
+
}
|
|
43134
|
+
activeThemeId = "dark";
|
|
43135
|
+
bumpThemeVersion();
|
|
43136
|
+
return false;
|
|
43137
|
+
}
|
|
43138
|
+
function getActiveThemeName() {
|
|
43139
|
+
return activeThemeId;
|
|
43140
|
+
}
|
|
42841
43141
|
function getTheme() {
|
|
42842
|
-
return darkTheme;
|
|
43142
|
+
return registry.get(activeThemeId)?.theme ?? darkTheme;
|
|
42843
43143
|
}
|
|
42844
43144
|
// src/theme/logo.ts
|
|
42845
43145
|
var LOGO_LINES = [" ▄▄▄▄▄ ", "▀▙███▟▀", " ▝ ▘ "];
|
|
42846
|
-
|
|
43146
|
+
// src/theme/syntax.ts
|
|
43147
|
+
function buildHighlightTheme(theme) {
|
|
43148
|
+
const syn = theme.syntax;
|
|
43149
|
+
const kw = resolveThemeColor(syn.keyword);
|
|
43150
|
+
const str = resolveThemeColor(syn.string);
|
|
43151
|
+
const num = resolveThemeColor(syn.number);
|
|
43152
|
+
const lit = resolveThemeColor(syn.literal);
|
|
43153
|
+
const com = resolveThemeColor(syn.comment);
|
|
43154
|
+
const fn = resolveThemeColor(syn.function);
|
|
43155
|
+
const typ = resolveThemeColor(syn.type);
|
|
43156
|
+
const vr = resolveThemeColor(syn.variable);
|
|
43157
|
+
const tg = resolveThemeColor(syn.tag);
|
|
43158
|
+
const at = resolveThemeColor(syn.attr);
|
|
43159
|
+
const mt = resolveThemeColor(syn.meta);
|
|
43160
|
+
const add = resolveThemeColor(syn.addition);
|
|
43161
|
+
const del = resolveThemeColor(syn.deletion);
|
|
43162
|
+
const def = resolveThemeColor(syn.default);
|
|
43163
|
+
return {
|
|
43164
|
+
keyword: kw,
|
|
43165
|
+
built_in: typ,
|
|
43166
|
+
type: typ,
|
|
43167
|
+
literal: lit,
|
|
43168
|
+
number: num,
|
|
43169
|
+
regexp: tg,
|
|
43170
|
+
string: str,
|
|
43171
|
+
subst: def,
|
|
43172
|
+
symbol: tg,
|
|
43173
|
+
class: typ,
|
|
43174
|
+
function: fn,
|
|
43175
|
+
title: fn,
|
|
43176
|
+
params: def,
|
|
43177
|
+
comment: (s) => com(italic(s)),
|
|
43178
|
+
doctag: kw,
|
|
43179
|
+
meta: mt,
|
|
43180
|
+
"meta-keyword": kw,
|
|
43181
|
+
"meta-string": str,
|
|
43182
|
+
section: (s) => mt(bold(s)),
|
|
43183
|
+
tag: tg,
|
|
43184
|
+
name: tg,
|
|
43185
|
+
"builtin-name": typ,
|
|
43186
|
+
attr: at,
|
|
43187
|
+
attribute: at,
|
|
43188
|
+
variable: vr,
|
|
43189
|
+
bullet: vr,
|
|
43190
|
+
code: def,
|
|
43191
|
+
emphasis: (s) => italic(s),
|
|
43192
|
+
strong: (s) => bold(s),
|
|
43193
|
+
formula: tg,
|
|
43194
|
+
link: (s) => str(underline(s)),
|
|
43195
|
+
quote: com,
|
|
43196
|
+
"selector-tag": tg,
|
|
43197
|
+
"selector-id": (s) => mt(bold(s)),
|
|
43198
|
+
"selector-class": at,
|
|
43199
|
+
"selector-attr": at,
|
|
43200
|
+
"selector-pseudo": at,
|
|
43201
|
+
"template-tag": tg,
|
|
43202
|
+
"template-variable": vr,
|
|
43203
|
+
addition: add,
|
|
43204
|
+
deletion: del,
|
|
43205
|
+
default: def
|
|
43206
|
+
};
|
|
43207
|
+
}
|
|
43208
|
+
var cachedHighlightTheme = null;
|
|
43209
|
+
var cachedHighlightVersion = -1;
|
|
43210
|
+
function getHighlightTheme() {
|
|
43211
|
+
if (source_default.level === 0) {
|
|
43212
|
+
return { default: (s) => s };
|
|
43213
|
+
}
|
|
43214
|
+
const v = themeVersion();
|
|
43215
|
+
if (!cachedHighlightTheme || v !== cachedHighlightVersion) {
|
|
43216
|
+
cachedHighlightTheme = buildHighlightTheme(getTheme());
|
|
43217
|
+
cachedHighlightVersion = v;
|
|
43218
|
+
}
|
|
43219
|
+
return cachedHighlightTheme;
|
|
43220
|
+
}
|
|
42847
43221
|
// node_modules/marked/lib/marked.esm.js
|
|
42848
43222
|
function A() {
|
|
42849
43223
|
return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
|
|
@@ -44221,19 +44595,89 @@ var an = f.parseInline;
|
|
|
44221
44595
|
var un = b.parse;
|
|
44222
44596
|
var pn = x.lex;
|
|
44223
44597
|
|
|
44224
|
-
// src/utils/
|
|
44598
|
+
// src/utils/highlight.ts
|
|
44225
44599
|
var import_cli_highlight = __toESM(require_dist(), 1);
|
|
44226
|
-
|
|
44227
|
-
|
|
44228
|
-
|
|
44229
|
-
|
|
44230
|
-
|
|
44231
|
-
|
|
44232
|
-
|
|
44600
|
+
import { extname, basename } from "node:path";
|
|
44601
|
+
var EXTENSION_MAP = {
|
|
44602
|
+
".ts": "typescript",
|
|
44603
|
+
".tsx": "typescript",
|
|
44604
|
+
".js": "javascript",
|
|
44605
|
+
".jsx": "javascript",
|
|
44606
|
+
".mjs": "javascript",
|
|
44607
|
+
".cjs": "javascript",
|
|
44608
|
+
".json": "json",
|
|
44609
|
+
".py": "python",
|
|
44610
|
+
".rb": "ruby",
|
|
44611
|
+
".go": "go",
|
|
44612
|
+
".rs": "rust",
|
|
44613
|
+
".sh": "bash",
|
|
44614
|
+
".bash": "bash",
|
|
44615
|
+
".zsh": "bash",
|
|
44616
|
+
".html": "html",
|
|
44617
|
+
".htm": "html",
|
|
44618
|
+
".css": "css",
|
|
44619
|
+
".scss": "scss",
|
|
44620
|
+
".less": "less",
|
|
44621
|
+
".md": "markdown",
|
|
44622
|
+
".markdown": "markdown",
|
|
44623
|
+
".yaml": "yaml",
|
|
44624
|
+
".yml": "yaml",
|
|
44625
|
+
".toml": "ini",
|
|
44626
|
+
".sql": "sql",
|
|
44627
|
+
".c": "c",
|
|
44628
|
+
".h": "c",
|
|
44629
|
+
".cpp": "cpp",
|
|
44630
|
+
".hpp": "cpp",
|
|
44631
|
+
".cc": "cpp",
|
|
44632
|
+
".java": "java",
|
|
44633
|
+
".php": "php",
|
|
44634
|
+
".xml": "xml",
|
|
44635
|
+
".svg": "xml"
|
|
44636
|
+
};
|
|
44637
|
+
var FILENAME_MAP = {
|
|
44638
|
+
dockerfile: "dockerfile",
|
|
44639
|
+
makefile: "makefile",
|
|
44640
|
+
cmakelists: "cmake"
|
|
44641
|
+
};
|
|
44642
|
+
function detectLanguageFromPath(filePath) {
|
|
44643
|
+
if (!filePath)
|
|
44644
|
+
return;
|
|
44645
|
+
const name = basename(filePath).toLowerCase();
|
|
44646
|
+
if (FILENAME_MAP[name])
|
|
44647
|
+
return FILENAME_MAP[name];
|
|
44648
|
+
const ext = extname(filePath).toLowerCase();
|
|
44649
|
+
if (ext && EXTENSION_MAP[ext]) {
|
|
44650
|
+
return EXTENSION_MAP[ext];
|
|
44651
|
+
}
|
|
44652
|
+
if (ext && import_cli_highlight.supportsLanguage(ext.slice(1))) {
|
|
44653
|
+
return ext.slice(1);
|
|
44654
|
+
}
|
|
44655
|
+
return;
|
|
44656
|
+
}
|
|
44657
|
+
function highlightCode(code, options) {
|
|
44658
|
+
if (!code)
|
|
44659
|
+
return "";
|
|
44660
|
+
const lang = options?.language ?? detectLanguageFromPath(options?.filePath);
|
|
44661
|
+
try {
|
|
44662
|
+
if (lang && import_cli_highlight.supportsLanguage(lang)) {
|
|
44663
|
+
return import_cli_highlight.highlight(code, {
|
|
44664
|
+
language: lang,
|
|
44665
|
+
ignoreIllegals: true,
|
|
44666
|
+
theme: getHighlightTheme()
|
|
44667
|
+
});
|
|
44233
44668
|
}
|
|
44669
|
+
return import_cli_highlight.highlight(code, {
|
|
44670
|
+
ignoreIllegals: true,
|
|
44671
|
+
theme: getHighlightTheme()
|
|
44672
|
+
});
|
|
44673
|
+
} catch {
|
|
44674
|
+
return code;
|
|
44234
44675
|
}
|
|
44235
|
-
return source_default.hex(color);
|
|
44236
44676
|
}
|
|
44677
|
+
|
|
44678
|
+
// src/utils/markdown.ts
|
|
44679
|
+
var EOL = `
|
|
44680
|
+
`;
|
|
44237
44681
|
var markedConfigured = false;
|
|
44238
44682
|
function configureMarked() {
|
|
44239
44683
|
if (markedConfigured)
|
|
@@ -44260,53 +44704,47 @@ function padAligned(content, contentWidth, columnWidth, align) {
|
|
|
44260
44704
|
return content + " ".repeat(padding);
|
|
44261
44705
|
}
|
|
44262
44706
|
function formatToken(token, listDepth = 0, orderedListNumber = null, parent = null) {
|
|
44263
|
-
const theme = getTheme();
|
|
44264
44707
|
switch (token.type) {
|
|
44265
44708
|
case "blockquote": {
|
|
44266
44709
|
const inner = (token.tokens ?? []).map((t) => formatToken(t, 0, null, null)).join("");
|
|
44267
|
-
const bar =
|
|
44268
|
-
return inner.split(EOL).map((line) => stripAnsi(line).trim() ? `${bar} ${
|
|
44710
|
+
const bar = c.subtle("│");
|
|
44711
|
+
return inner.split(EOL).map((line) => stripAnsi(line).trim() ? `${bar} ${italic(line)}` : line).join(EOL);
|
|
44269
44712
|
}
|
|
44270
44713
|
case "code": {
|
|
44271
44714
|
const code = token;
|
|
44272
|
-
|
|
44273
|
-
|
|
44274
|
-
try {
|
|
44275
|
-
highlighted = import_cli_highlight.highlight(code.text, { language: code.lang, ignoreIllegals: true });
|
|
44276
|
-
} catch {}
|
|
44277
|
-
}
|
|
44278
|
-
const gutter = themeColor(theme.subtle)("│");
|
|
44715
|
+
const highlighted = highlightCode(code.text, { language: code.lang });
|
|
44716
|
+
const gutter = c.subtle("│");
|
|
44279
44717
|
const lines = highlighted.split(EOL);
|
|
44280
44718
|
const formatted = lines.map((line) => ` ${gutter} ${line}`).join(EOL);
|
|
44281
44719
|
return formatted + EOL + EOL;
|
|
44282
44720
|
}
|
|
44283
44721
|
case "codespan": {
|
|
44284
|
-
return
|
|
44722
|
+
return c.permission(token.text);
|
|
44285
44723
|
}
|
|
44286
44724
|
case "em": {
|
|
44287
|
-
return
|
|
44725
|
+
return italic((token.tokens ?? []).map((t) => formatToken(t, 0, null, parent)).join(""));
|
|
44288
44726
|
}
|
|
44289
44727
|
case "strong": {
|
|
44290
|
-
return
|
|
44728
|
+
return bold((token.tokens ?? []).map((t) => formatToken(t, 0, null, parent)).join(""));
|
|
44291
44729
|
}
|
|
44292
44730
|
case "heading": {
|
|
44293
44731
|
const heading = token;
|
|
44294
44732
|
const text = (heading.tokens ?? []).map((t) => formatToken(t, 0, null, null)).join("");
|
|
44295
44733
|
if (heading.depth === 1) {
|
|
44296
|
-
return
|
|
44734
|
+
return underline(bold(c.brand(text))) + EOL + EOL;
|
|
44297
44735
|
}
|
|
44298
44736
|
if (heading.depth === 2) {
|
|
44299
|
-
return
|
|
44737
|
+
return bold(c.brand(text)) + EOL + EOL;
|
|
44300
44738
|
}
|
|
44301
|
-
return
|
|
44739
|
+
return bold(text) + EOL + EOL;
|
|
44302
44740
|
}
|
|
44303
44741
|
case "hr": {
|
|
44304
|
-
return
|
|
44742
|
+
return c.rule("─".repeat(40)) + EOL + EOL;
|
|
44305
44743
|
}
|
|
44306
44744
|
case "link": {
|
|
44307
44745
|
const link = token;
|
|
44308
44746
|
const linkText = (link.tokens ?? []).map((t) => formatToken(t, 0, null, link)).join("");
|
|
44309
|
-
return linkText ? `${
|
|
44747
|
+
return linkText ? `${c.info(linkText)} (${c.muted(link.href)})` : link.href;
|
|
44310
44748
|
}
|
|
44311
44749
|
case "list": {
|
|
44312
44750
|
const list = token;
|
|
@@ -44320,7 +44758,7 @@ function formatToken(token, listDepth = 0, orderedListNumber = null, parent = nu
|
|
|
44320
44758
|
const listTokens = item.tokens?.filter((t) => t.type === "list") ?? [];
|
|
44321
44759
|
const mainContent = nonListTokens.map((t) => formatToken(t, listDepth + 1, orderedListNumber, token)).join("").trim();
|
|
44322
44760
|
const nestedLists = listTokens.map((t) => formatToken(t, listDepth + 1, null, token)).join("");
|
|
44323
|
-
return `${indent}${
|
|
44761
|
+
return `${indent}${c.brand(prefix)} ${mainContent}${EOL}${nestedLists}`;
|
|
44324
44762
|
}
|
|
44325
44763
|
case "paragraph": {
|
|
44326
44764
|
return (token.tokens ?? []).map((t) => formatToken(t, 0, null, null)).join("") + EOL + EOL;
|
|
@@ -44345,7 +44783,7 @@ function formatToken(token, listDepth = 0, orderedListNumber = null, parent = nu
|
|
|
44345
44783
|
const plain = stripAnsi(raw);
|
|
44346
44784
|
const align = isHeader ? "center" : tableToken.align?.[i] ?? "left";
|
|
44347
44785
|
const padded = padAligned(raw, stringWidth(plain), w, align);
|
|
44348
|
-
return isHeader ? ` ${
|
|
44786
|
+
return isHeader ? ` ${bold(padded)} ` : ` ${padded} `;
|
|
44349
44787
|
});
|
|
44350
44788
|
return D("│") + parts.join(D("│")) + D("│");
|
|
44351
44789
|
};
|
|
@@ -44358,7 +44796,7 @@ function formatToken(token, listDepth = 0, orderedListNumber = null, parent = nu
|
|
|
44358
44796
|
}
|
|
44359
44797
|
return Math.max(maxWidth, 3);
|
|
44360
44798
|
});
|
|
44361
|
-
const D =
|
|
44799
|
+
const D = (s) => c.subtle(s);
|
|
44362
44800
|
const hbar = (w) => "─".repeat(w + 2);
|
|
44363
44801
|
const topBorder = D("┌") + columnWidths.map((w) => D(hbar(w))).join(D("┬")) + D("┐");
|
|
44364
44802
|
const midBorder = D("├") + columnWidths.map((w) => D(hbar(w))).join(D("┼")) + D("┤");
|
|
@@ -44390,23 +44828,11 @@ function applyMarkdown(content) {
|
|
|
44390
44828
|
}
|
|
44391
44829
|
|
|
44392
44830
|
// src/tui/utils/format.ts
|
|
44393
|
-
function
|
|
44394
|
-
|
|
44395
|
-
const match = color.match(/\d+/g);
|
|
44396
|
-
if (match && match.length >= 3) {
|
|
44397
|
-
return source_default.rgb(Number(match[0]), Number(match[1]), Number(match[2]));
|
|
44398
|
-
}
|
|
44399
|
-
}
|
|
44400
|
-
return source_default.hex(color);
|
|
44831
|
+
function themeColor(color) {
|
|
44832
|
+
return resolveThemeColor(color, false);
|
|
44401
44833
|
}
|
|
44402
|
-
function
|
|
44403
|
-
|
|
44404
|
-
const match = color.match(/\d+/g);
|
|
44405
|
-
if (match && match.length >= 3) {
|
|
44406
|
-
return source_default.bgRgb(Number(match[0]), Number(match[1]), Number(match[2]));
|
|
44407
|
-
}
|
|
44408
|
-
}
|
|
44409
|
-
return source_default.bgHex(color);
|
|
44834
|
+
function visibleWidth(text) {
|
|
44835
|
+
return stringWidth(stripAnsi(text));
|
|
44410
44836
|
}
|
|
44411
44837
|
function formatMarkdown(md) {
|
|
44412
44838
|
return applyMarkdown(md);
|
|
@@ -44503,17 +44929,16 @@ function truncateToWidth(styledText, maxWidth) {
|
|
|
44503
44929
|
return result.includes("\x1B") && !result.endsWith("\x1B[0m") ? result + "\x1B[0m" : result;
|
|
44504
44930
|
}
|
|
44505
44931
|
function getStatusBullet(status, pulse = false) {
|
|
44506
|
-
const theme = getTheme();
|
|
44507
44932
|
if (status === "completed") {
|
|
44508
|
-
return
|
|
44933
|
+
return c.success(figures.blackCircle);
|
|
44509
44934
|
}
|
|
44510
44935
|
if (status === "failed") {
|
|
44511
|
-
return
|
|
44936
|
+
return c.error(figures.blackCircle);
|
|
44512
44937
|
}
|
|
44513
44938
|
if (pulse) {
|
|
44514
|
-
return
|
|
44939
|
+
return bold(c.text(figures.blackCircle));
|
|
44515
44940
|
}
|
|
44516
|
-
return
|
|
44941
|
+
return c.muted(figures.blackCircle);
|
|
44517
44942
|
}
|
|
44518
44943
|
|
|
44519
44944
|
// src/tui/engine/cell-layout.ts
|
|
@@ -45210,6 +45635,75 @@ class StateRenderer {
|
|
|
45210
45635
|
}
|
|
45211
45636
|
}
|
|
45212
45637
|
|
|
45638
|
+
// src/tui/utils/tool-detail.ts
|
|
45639
|
+
function renderToolDetail(detail) {
|
|
45640
|
+
if (detail.kind === "text") {
|
|
45641
|
+
return detail.text.split(`
|
|
45642
|
+
`).map((l) => c.muted(l)).join(`
|
|
45643
|
+
`);
|
|
45644
|
+
}
|
|
45645
|
+
if (detail.kind === "code") {
|
|
45646
|
+
const highlighted = highlightCode(detail.text, { filePath: detail.filePath });
|
|
45647
|
+
const contentLines = highlighted.split(/\r?\n/);
|
|
45648
|
+
if (contentLines.length === 0 || contentLines.length === 1 && !contentLines[0]) {
|
|
45649
|
+
return "";
|
|
45650
|
+
}
|
|
45651
|
+
const cap = 50;
|
|
45652
|
+
const shown = contentLines.slice(0, cap);
|
|
45653
|
+
const padWidth = String(contentLines.length).length;
|
|
45654
|
+
const lines = shown.map((l, i) => `${c.muted(String(i + 1).padStart(padWidth))} ${l}`);
|
|
45655
|
+
if (contentLines.length > cap) {
|
|
45656
|
+
lines.push(c.muted(` … (${contentLines.length - cap} more lines)`));
|
|
45657
|
+
}
|
|
45658
|
+
return lines.join(`
|
|
45659
|
+
`);
|
|
45660
|
+
}
|
|
45661
|
+
if (detail.kind === "diff") {
|
|
45662
|
+
let maxLineNum = 1;
|
|
45663
|
+
for (const hunk of detail.hunks) {
|
|
45664
|
+
for (const line of hunk.lines) {
|
|
45665
|
+
if (line.oldLineNumber)
|
|
45666
|
+
maxLineNum = Math.max(maxLineNum, line.oldLineNumber);
|
|
45667
|
+
if (line.newLineNumber)
|
|
45668
|
+
maxLineNum = Math.max(maxLineNum, line.newLineNumber);
|
|
45669
|
+
}
|
|
45670
|
+
}
|
|
45671
|
+
const padWidth = Math.max(1, String(maxLineNum).length);
|
|
45672
|
+
const diffLines = [];
|
|
45673
|
+
const cap = 30;
|
|
45674
|
+
let count = 0;
|
|
45675
|
+
let overflow = 0;
|
|
45676
|
+
for (const hunk of detail.hunks) {
|
|
45677
|
+
for (const line of hunk.lines) {
|
|
45678
|
+
if (count >= cap) {
|
|
45679
|
+
overflow++;
|
|
45680
|
+
continue;
|
|
45681
|
+
}
|
|
45682
|
+
count++;
|
|
45683
|
+
if (line.kind === "deletion") {
|
|
45684
|
+
const numStr = String(line.oldLineNumber ?? "").padStart(padWidth, " ");
|
|
45685
|
+
const body = line.spans ? "-" + line.spans.map((s) => s.kind === "deletion" ? bold(s.text) : s.text).join("") : `-${line.text}`;
|
|
45686
|
+
diffLines.push(bg.diffDelBg(c.diffDelFg(`${numStr} ${body}`)));
|
|
45687
|
+
} else if (line.kind === "addition") {
|
|
45688
|
+
const numStr = String(line.newLineNumber ?? "").padStart(padWidth, " ");
|
|
45689
|
+
const body = line.spans ? "+" + line.spans.map((s) => s.kind === "addition" ? bold(s.text) : s.text).join("") : `+${line.text}`;
|
|
45690
|
+
diffLines.push(bg.diffAddBg(c.diffAddFg(`${numStr} ${body}`)));
|
|
45691
|
+
} else {
|
|
45692
|
+
const numStr = String(line.newLineNumber ?? line.oldLineNumber ?? "").padStart(padWidth, " ");
|
|
45693
|
+
const highlightedContext = highlightCode(line.text, { filePath: detail.filePath });
|
|
45694
|
+
diffLines.push(`${c.muted(`${numStr} `)} ${highlightedContext}`);
|
|
45695
|
+
}
|
|
45696
|
+
}
|
|
45697
|
+
}
|
|
45698
|
+
if (overflow > 0) {
|
|
45699
|
+
diffLines.push(c.muted(` … (${overflow} more lines)`));
|
|
45700
|
+
}
|
|
45701
|
+
return diffLines.join(`
|
|
45702
|
+
`);
|
|
45703
|
+
}
|
|
45704
|
+
return "";
|
|
45705
|
+
}
|
|
45706
|
+
|
|
45213
45707
|
// src/session/logs/store.ts
|
|
45214
45708
|
import {
|
|
45215
45709
|
appendFileSync as appendFileSync2,
|
|
@@ -45233,7 +45727,6 @@ import {
|
|
|
45233
45727
|
readdirSync,
|
|
45234
45728
|
readFileSync,
|
|
45235
45729
|
renameSync,
|
|
45236
|
-
rmSync,
|
|
45237
45730
|
unlinkSync,
|
|
45238
45731
|
writeFileSync,
|
|
45239
45732
|
writeSync
|
|
@@ -48900,10 +49393,10 @@ class $ZodRegistry {
|
|
|
48900
49393
|
return this._map.has(schema);
|
|
48901
49394
|
}
|
|
48902
49395
|
}
|
|
48903
|
-
function
|
|
49396
|
+
function registry2() {
|
|
48904
49397
|
return new $ZodRegistry;
|
|
48905
49398
|
}
|
|
48906
|
-
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry =
|
|
49399
|
+
(_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry2());
|
|
48907
49400
|
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
48908
49401
|
// node_modules/zod/v4/core/api.js
|
|
48909
49402
|
function _string(Class, params) {
|
|
@@ -52317,9 +52810,7 @@ function buildSessionPresentationProjection(events) {
|
|
|
52317
52810
|
|
|
52318
52811
|
// src/tui/utils/message-formatter.ts
|
|
52319
52812
|
function formatUserMessage(content, targetWidth) {
|
|
52320
|
-
const theme = getTheme();
|
|
52321
52813
|
const termCols = typeof targetWidth === "number" && targetWidth > 0 ? targetWidth : process.stdout.columns || 80;
|
|
52322
|
-
const bg = themeBgColor(theme.userCardBg);
|
|
52323
52814
|
const pointer = `${figures.pointerBold} `;
|
|
52324
52815
|
const prefix = pointer;
|
|
52325
52816
|
const availableTextWidth = Math.max(10, termCols - 2);
|
|
@@ -52333,22 +52824,20 @@ function formatUserMessage(content, targetWidth) {
|
|
|
52333
52824
|
for (const segment of wrappedSegments) {
|
|
52334
52825
|
const p = isFirstRow ? prefix : " ";
|
|
52335
52826
|
isFirstRow = false;
|
|
52336
|
-
const visibleLen =
|
|
52827
|
+
const visibleLen = visibleWidth(p) + visibleWidth(segment);
|
|
52337
52828
|
const padLen = Math.max(0, termCols - visibleLen);
|
|
52338
|
-
const pStyled =
|
|
52339
|
-
const textStyled =
|
|
52340
|
-
const fullRow = bg(`${pStyled}${textStyled}${" ".repeat(padLen)}`);
|
|
52829
|
+
const pStyled = c.userChevron(p);
|
|
52830
|
+
const textStyled = c.text(segment);
|
|
52831
|
+
const fullRow = bg.userBg(`${pStyled}${textStyled}${" ".repeat(padLen)}`);
|
|
52341
52832
|
lines.push(fullRow);
|
|
52342
52833
|
}
|
|
52343
52834
|
}
|
|
52344
52835
|
return lines;
|
|
52345
52836
|
}
|
|
52346
52837
|
function formatSystemMessage(content) {
|
|
52347
|
-
const theme = getTheme();
|
|
52348
|
-
const infoColor = themeColor2(theme.permission);
|
|
52349
52838
|
const rawLines = content.split(`
|
|
52350
52839
|
`);
|
|
52351
|
-
return rawLines.map((l, i) => i === 0 ? ` ${
|
|
52840
|
+
return rawLines.map((l, i) => i === 0 ? ` ${c.muted("└ ")}${c.permission(l)}` : ` ${c.permission(l)}`);
|
|
52352
52841
|
}
|
|
52353
52842
|
function formatAssistantMessage(content) {
|
|
52354
52843
|
const lines = [];
|
|
@@ -52373,7 +52862,7 @@ function formatAssistantMessage(content) {
|
|
|
52373
52862
|
continue;
|
|
52374
52863
|
}
|
|
52375
52864
|
if (i === 0) {
|
|
52376
|
-
const bullet =
|
|
52865
|
+
const bullet = c.text(`${figures.blackCircle} `);
|
|
52377
52866
|
lines.push(`${bullet}${l}`);
|
|
52378
52867
|
} else {
|
|
52379
52868
|
lines.push(` ${l}`);
|
|
@@ -52385,7 +52874,6 @@ function formatAssistantMessage(content) {
|
|
|
52385
52874
|
}
|
|
52386
52875
|
function formatToolStatus(options) {
|
|
52387
52876
|
const { toolName, displayName, icon, argsSummary, status, error, targetWidth } = options;
|
|
52388
|
-
const theme = getTheme();
|
|
52389
52877
|
const fullTermWidth = typeof targetWidth === "number" && targetWidth > 0 ? targetWidth : process.stdout.columns || 80;
|
|
52390
52878
|
const bullet = getStatusBullet(status);
|
|
52391
52879
|
const dispName = displayName ?? icon ?? toolName;
|
|
@@ -52394,26 +52882,40 @@ function formatToolStatus(options) {
|
|
|
52394
52882
|
const truncatedArg = cleanFirstLine.length > maxArgLen ? truncateMiddle(cleanFirstLine, maxArgLen) : cleanFirstLine;
|
|
52395
52883
|
let mainLine = `${bullet} ${dispName}`;
|
|
52396
52884
|
if (truncatedArg) {
|
|
52397
|
-
mainLine += `${
|
|
52885
|
+
mainLine += `${c.muted("(")}${c.muted(truncatedArg)}${c.muted(")")}`;
|
|
52398
52886
|
} else {
|
|
52399
|
-
mainLine += `${
|
|
52887
|
+
mainLine += `${c.muted("()")}`;
|
|
52400
52888
|
}
|
|
52401
52889
|
const lines = [mainLine];
|
|
52402
|
-
|
|
52403
|
-
|
|
52404
|
-
|
|
52405
|
-
|
|
52890
|
+
const summaryVal = options.summary ?? options.toolOutput;
|
|
52891
|
+
if (status === "completed" && summaryVal) {
|
|
52892
|
+
let headline = "";
|
|
52893
|
+
let detailText = "";
|
|
52894
|
+
if (typeof summaryVal === "string") {
|
|
52895
|
+
const outputLines = summaryVal.trim().split(`
|
|
52896
|
+
`);
|
|
52897
|
+
headline = outputLines[0]?.trim() ?? "";
|
|
52898
|
+
detailText = outputLines.slice(1).join(`
|
|
52406
52899
|
`);
|
|
52407
|
-
|
|
52900
|
+
} else {
|
|
52901
|
+
headline = summaryVal.headline;
|
|
52902
|
+
if (summaryVal.detail) {
|
|
52903
|
+
detailText = renderToolDetail(summaryVal.detail);
|
|
52904
|
+
}
|
|
52905
|
+
}
|
|
52906
|
+
if (headline) {
|
|
52408
52907
|
const maxOutLen = Math.max(10, fullTermWidth - 6);
|
|
52409
|
-
const truncatedSummary =
|
|
52410
|
-
lines.push(` ${
|
|
52411
|
-
|
|
52412
|
-
|
|
52413
|
-
|
|
52414
|
-
const
|
|
52415
|
-
const
|
|
52416
|
-
|
|
52908
|
+
const truncatedSummary = headline.length > maxOutLen ? `${headline.slice(0, maxOutLen - 1)}…` : headline;
|
|
52909
|
+
lines.push(` ${c.muted("└ ")}${c.text(truncatedSummary)}`);
|
|
52910
|
+
if (detailText) {
|
|
52911
|
+
const detailLines = detailText.split(`
|
|
52912
|
+
`);
|
|
52913
|
+
const maxContentWidth = Math.max(30, Math.min(fullTermWidth - 4, Math.floor(fullTermWidth * 0.85)));
|
|
52914
|
+
for (const rawLine of detailLines) {
|
|
52915
|
+
const prefixed = ` ${rawLine}`;
|
|
52916
|
+
const wrapped = wrapVisualLine(prefixed, maxContentWidth, " ");
|
|
52917
|
+
lines.push(...wrapped);
|
|
52918
|
+
}
|
|
52417
52919
|
}
|
|
52418
52920
|
}
|
|
52419
52921
|
}
|
|
@@ -52423,25 +52925,23 @@ function formatToolStatus(options) {
|
|
|
52423
52925
|
`)[0]?.trim() || rawError;
|
|
52424
52926
|
const maxErrLen = Math.max(10, fullTermWidth - 6);
|
|
52425
52927
|
const truncatedErr = firstLineErr.length > maxErrLen ? `${firstLineErr.slice(0, maxErrLen - 1)}…` : firstLineErr;
|
|
52426
|
-
lines.push(` ${
|
|
52928
|
+
lines.push(` ${c.muted("└ ")}${c.error(truncatedErr)}`);
|
|
52427
52929
|
}
|
|
52428
52930
|
return lines;
|
|
52429
52931
|
}
|
|
52430
52932
|
function formatErrorBadge(error, retryInfo) {
|
|
52431
|
-
const
|
|
52432
|
-
const
|
|
52433
|
-
const ast = errColor(figures.asterisk);
|
|
52434
|
-
const midDot = source_default.dim(` ${figures.bullet} `);
|
|
52933
|
+
const ast = c.error(figures.asterisk);
|
|
52934
|
+
const midDot = c.muted(` ${figures.bullet} `);
|
|
52435
52935
|
let msg = error.shortMessage;
|
|
52436
52936
|
if (retryInfo) {
|
|
52437
|
-
const retryStr =
|
|
52438
|
-
msg = `${
|
|
52937
|
+
const retryStr = c.muted(`Retrying in ${retryInfo.countdownSec}s · attempt ${retryInfo.attempt}/${retryInfo.maxAttempts}`);
|
|
52938
|
+
msg = `${c.error(error.shortMessage)}${midDot}${retryStr}`;
|
|
52439
52939
|
} else {
|
|
52440
|
-
msg =
|
|
52940
|
+
msg = c.error(error.shortMessage);
|
|
52441
52941
|
}
|
|
52442
52942
|
const lines = [`${ast} ${msg}`];
|
|
52443
52943
|
if (error.suggestedAction) {
|
|
52444
|
-
lines.push(` ${
|
|
52944
|
+
lines.push(` ${c.muted("└ ")}${c.muted(error.suggestedAction)}`);
|
|
52445
52945
|
}
|
|
52446
52946
|
return lines;
|
|
52447
52947
|
}
|
|
@@ -52449,8 +52949,8 @@ function formatTurnStatus(durationMs, timestamp = new Date, verb) {
|
|
|
52449
52949
|
const selectedVerb = verb ?? chooseTurnStatusVerb();
|
|
52450
52950
|
const sec = Math.max(1, Math.round(durationMs / 1000));
|
|
52451
52951
|
const timeStr = timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
52452
|
-
const midDot =
|
|
52453
|
-
return `${
|
|
52952
|
+
const midDot = c.muted(` ${figures.bullet} `);
|
|
52953
|
+
return `${c.muted(`${figures.asterisk} ${selectedVerb} for ${sec}s`)}${midDot}${c.muted(`done ${timeStr}`)}`;
|
|
52454
52954
|
}
|
|
52455
52955
|
|
|
52456
52956
|
// src/tui/engine/HistoryLayoutCache.ts
|
|
@@ -53347,6 +53847,18 @@ function saveVoiceLanguage(languageTag) {
|
|
|
53347
53847
|
voiceLanguage: languageTag.trim()
|
|
53348
53848
|
});
|
|
53349
53849
|
}
|
|
53850
|
+
function getSavedTheme() {
|
|
53851
|
+
const settings = loadSettings();
|
|
53852
|
+
if (settings.theme && typeof settings.theme === "string") {
|
|
53853
|
+
return settings.theme;
|
|
53854
|
+
}
|
|
53855
|
+
return;
|
|
53856
|
+
}
|
|
53857
|
+
function saveThemeSelection(name) {
|
|
53858
|
+
saveSettings({
|
|
53859
|
+
theme: name
|
|
53860
|
+
});
|
|
53861
|
+
}
|
|
53350
53862
|
function normalizeFolderPath(inputPath) {
|
|
53351
53863
|
let absolute = resolve(inputPath);
|
|
53352
53864
|
try {
|
|
@@ -53387,6 +53899,18 @@ function trustFolder(absolutePath) {
|
|
|
53387
53899
|
}
|
|
53388
53900
|
});
|
|
53389
53901
|
}
|
|
53902
|
+
function getSavedMode() {
|
|
53903
|
+
const settings = loadSettings();
|
|
53904
|
+
if (settings.mode && typeof settings.mode === "string" && ["normal", "chat", "review", "build"].includes(settings.mode)) {
|
|
53905
|
+
return settings.mode;
|
|
53906
|
+
}
|
|
53907
|
+
return;
|
|
53908
|
+
}
|
|
53909
|
+
function saveModeSelection(name) {
|
|
53910
|
+
saveSettings({
|
|
53911
|
+
mode: name
|
|
53912
|
+
});
|
|
53913
|
+
}
|
|
53390
53914
|
|
|
53391
53915
|
// src/services/checkpoint/path.ts
|
|
53392
53916
|
function computeWorkspaceHash(workspaceRoot) {
|
|
@@ -53616,6 +54140,25 @@ async function saveCheckpointManifest(workspaceHash, sessionId, manifest) {
|
|
|
53616
54140
|
atomicWriteJson(targetPath, manifest);
|
|
53617
54141
|
});
|
|
53618
54142
|
}
|
|
54143
|
+
function loadPendingJournal(workspaceHash, sessionId) {
|
|
54144
|
+
const targetPath = getPendingJournalPath(workspaceHash, sessionId);
|
|
54145
|
+
if (!existsSync6(targetPath)) {
|
|
54146
|
+
return null;
|
|
54147
|
+
}
|
|
54148
|
+
try {
|
|
54149
|
+
const raw = readFileSync5(targetPath, "utf-8");
|
|
54150
|
+
const parsed = JSON.parse(raw);
|
|
54151
|
+
const result = PendingJournalSchema.safeParse(parsed);
|
|
54152
|
+
if (result.success) {
|
|
54153
|
+
return result.data;
|
|
54154
|
+
}
|
|
54155
|
+
quarantineCheckpointFile(targetPath);
|
|
54156
|
+
return null;
|
|
54157
|
+
} catch {
|
|
54158
|
+
quarantineCheckpointFile(targetPath);
|
|
54159
|
+
return null;
|
|
54160
|
+
}
|
|
54161
|
+
}
|
|
53619
54162
|
async function savePendingJournal(workspaceHash, sessionId, journal) {
|
|
53620
54163
|
const key = `${workspaceHash}:${sessionId}`;
|
|
53621
54164
|
await storeSerializer.run(key, () => {
|
|
@@ -53805,7 +54348,7 @@ class MutationCheckpointTracker {
|
|
|
53805
54348
|
};
|
|
53806
54349
|
await savePendingJournal(this.workspaceHash, this.sessionId, journal);
|
|
53807
54350
|
}
|
|
53808
|
-
async commitTurn(turnId,
|
|
54351
|
+
async commitTurn(turnId, _turnStatus = "complete") {
|
|
53809
54352
|
if (this.activeTurnId !== turnId) {
|
|
53810
54353
|
return;
|
|
53811
54354
|
}
|
|
@@ -54088,6 +54631,30 @@ async function executeRewind(options) {
|
|
|
54088
54631
|
releaseLocks();
|
|
54089
54632
|
}
|
|
54090
54633
|
}
|
|
54634
|
+
async function recoverPendingCheckpoint(workspaceRoot, sessionId) {
|
|
54635
|
+
const workspaceHash = computeWorkspaceHash(workspaceRoot);
|
|
54636
|
+
const journal = loadPendingJournal(workspaceHash, sessionId);
|
|
54637
|
+
if (!journal)
|
|
54638
|
+
return;
|
|
54639
|
+
if (journal.kind === "rewind") {
|
|
54640
|
+
if (journal.phase === "files-restored" || journal.phase === "files-pending") {
|
|
54641
|
+
for (const file of journal.files) {
|
|
54642
|
+
if (file.post) {
|
|
54643
|
+
const absPath = resolve3(workspaceRoot, file.relativePath);
|
|
54644
|
+
try {
|
|
54645
|
+
restoreFileStateToDisk(workspaceHash, absPath, file.post);
|
|
54646
|
+
} catch {}
|
|
54647
|
+
}
|
|
54648
|
+
}
|
|
54649
|
+
}
|
|
54650
|
+
await deletePendingJournal(workspaceHash, sessionId);
|
|
54651
|
+
} else {
|
|
54652
|
+
const committedFiles = journal.files.filter((f) => f.mutationCommitted);
|
|
54653
|
+
if (committedFiles.length === 0) {
|
|
54654
|
+
await deletePendingJournal(workspaceHash, sessionId);
|
|
54655
|
+
}
|
|
54656
|
+
}
|
|
54657
|
+
}
|
|
54091
54658
|
// node_modules/@ai-sdk/provider/dist/index.js
|
|
54092
54659
|
var marker = "vercel.ai.error";
|
|
54093
54660
|
var symbol = Symbol.for(marker);
|
|
@@ -70934,6 +71501,72 @@ var originalGenerateCallId6 = createIdGenerator({
|
|
|
70934
71501
|
});
|
|
70935
71502
|
var defaultDownload2 = createDownload();
|
|
70936
71503
|
|
|
71504
|
+
// src/engine/mode.ts
|
|
71505
|
+
var MODES = {
|
|
71506
|
+
normal: {
|
|
71507
|
+
name: "normal",
|
|
71508
|
+
label: "Normal",
|
|
71509
|
+
description: "All tools with file and bash permission prompts",
|
|
71510
|
+
color: "text",
|
|
71511
|
+
allows: ["read", "write", "exec"],
|
|
71512
|
+
autoApproveFiles: false
|
|
71513
|
+
},
|
|
71514
|
+
chat: {
|
|
71515
|
+
name: "chat",
|
|
71516
|
+
label: "Chat",
|
|
71517
|
+
description: "Conversation only — no tool access",
|
|
71518
|
+
color: "info",
|
|
71519
|
+
allows: [],
|
|
71520
|
+
autoApproveFiles: false
|
|
71521
|
+
},
|
|
71522
|
+
review: {
|
|
71523
|
+
name: "review",
|
|
71524
|
+
label: "Review",
|
|
71525
|
+
description: "Read-only tools only — cannot modify files or run commands",
|
|
71526
|
+
color: "warning",
|
|
71527
|
+
allows: ["read"],
|
|
71528
|
+
autoApproveFiles: false
|
|
71529
|
+
},
|
|
71530
|
+
build: {
|
|
71531
|
+
name: "build",
|
|
71532
|
+
label: "Build",
|
|
71533
|
+
description: "All tools, file mutations auto-approved, bash still prompts",
|
|
71534
|
+
color: "success",
|
|
71535
|
+
allows: ["read", "write", "exec"],
|
|
71536
|
+
autoApproveFiles: true
|
|
71537
|
+
}
|
|
71538
|
+
};
|
|
71539
|
+
var isAllowed = (m, a) => {
|
|
71540
|
+
const modeMeta = MODES[m];
|
|
71541
|
+
if (!modeMeta)
|
|
71542
|
+
return false;
|
|
71543
|
+
return modeMeta.allows.includes(a);
|
|
71544
|
+
};
|
|
71545
|
+
var MODE_ORDER = ["normal", "chat", "review", "build"];
|
|
71546
|
+
var activeMode = "normal";
|
|
71547
|
+
function getActiveMode() {
|
|
71548
|
+
return activeMode;
|
|
71549
|
+
}
|
|
71550
|
+
function setActiveMode(name) {
|
|
71551
|
+
if (name in MODES) {
|
|
71552
|
+
activeMode = name;
|
|
71553
|
+
}
|
|
71554
|
+
}
|
|
71555
|
+
function cycleMode() {
|
|
71556
|
+
const idx = MODE_ORDER.indexOf(activeMode);
|
|
71557
|
+
activeMode = MODE_ORDER[(idx + 1) % MODE_ORDER.length];
|
|
71558
|
+
return activeMode;
|
|
71559
|
+
}
|
|
71560
|
+
function listModes() {
|
|
71561
|
+
return Object.values(MODES);
|
|
71562
|
+
}
|
|
71563
|
+
function findMode(query) {
|
|
71564
|
+
const q = query.trim().toLowerCase();
|
|
71565
|
+
if (!q)
|
|
71566
|
+
return;
|
|
71567
|
+
return listModes().find((m) => m.name === q || m.label.toLowerCase() === q || m.label.toLowerCase().startsWith(q));
|
|
71568
|
+
}
|
|
71569
|
+
|
|
70937
71570
|
// src/tools/catalog.ts
|
|
70938
71571
|
class ToolCatalog {
|
|
70939
71572
|
tools = new Map;
|
|
@@ -70952,11 +71585,19 @@ class ToolCatalog {
|
|
|
70952
71585
|
}
|
|
70953
71586
|
toAISDKTools(context) {
|
|
70954
71587
|
const aiTools = {};
|
|
71588
|
+
const mode = context.mode ?? "normal";
|
|
70955
71589
|
for (const [name, def] of this.tools.entries()) {
|
|
71590
|
+
if (!isAllowed(mode, def.access)) {
|
|
71591
|
+
continue;
|
|
71592
|
+
}
|
|
70956
71593
|
aiTools[name] = tool({
|
|
70957
71594
|
description: def.description,
|
|
70958
71595
|
inputSchema: def.parameters,
|
|
70959
71596
|
execute: async (args) => {
|
|
71597
|
+
if (!isAllowed(mode, def.access)) {
|
|
71598
|
+
const modeLabel = MODES[mode]?.label ?? mode;
|
|
71599
|
+
throw new Error(`Tool "${name}" is not available in ${modeLabel} mode.`);
|
|
71600
|
+
}
|
|
70960
71601
|
return def.execute(args, context);
|
|
70961
71602
|
}
|
|
70962
71603
|
});
|
|
@@ -71025,6 +71666,7 @@ function isBinaryBuffer(buffer) {
|
|
|
71025
71666
|
var readFileTool = {
|
|
71026
71667
|
name: "read_file",
|
|
71027
71668
|
displayName: "Read",
|
|
71669
|
+
access: "read",
|
|
71028
71670
|
description: "Reads the contents of a file. Supports reading specific line ranges via offset and limit. Read is read-only and does not mutate or checkpoint.",
|
|
71029
71671
|
parameters: readFileInputSchema,
|
|
71030
71672
|
confirmationPolicy: "never",
|
|
@@ -71141,6 +71783,7 @@ var writeFileInputSchema = object({
|
|
|
71141
71783
|
var writeFileTool = {
|
|
71142
71784
|
name: "write_file",
|
|
71143
71785
|
displayName: "Write",
|
|
71786
|
+
access: "write",
|
|
71144
71787
|
description: "Writes or creates a whole file in the workspace. Automatically creates parent directories if needed. Every write mutation participates in checkpointing for /rewind.",
|
|
71145
71788
|
parameters: writeFileInputSchema,
|
|
71146
71789
|
confirmationPolicy: "never",
|
|
@@ -71148,20 +71791,16 @@ var writeFileTool = {
|
|
|
71148
71791
|
const lines = result?.linesWritten ?? 0;
|
|
71149
71792
|
const filePath = args.file_path;
|
|
71150
71793
|
const isNew = result?.isNew ?? true;
|
|
71151
|
-
const
|
|
71152
|
-
|
|
71153
|
-
|
|
71154
|
-
|
|
71155
|
-
|
|
71156
|
-
|
|
71157
|
-
|
|
71158
|
-
|
|
71159
|
-
|
|
71160
|
-
|
|
71161
|
-
const overflow = contentLines.length > cap ? `
|
|
71162
|
-
… (${contentLines.length - cap} more lines)` : "";
|
|
71163
|
-
return `${summary}
|
|
71164
|
-
${detail}${overflow}`;
|
|
71794
|
+
const headline = isNew ? `Created ${filePath} (${lines} line${lines === 1 ? "" : "s"})` : `Wrote ${lines} line${lines === 1 ? "" : "s"} to ${filePath}`;
|
|
71795
|
+
return {
|
|
71796
|
+
headline,
|
|
71797
|
+
detail: {
|
|
71798
|
+
kind: "code",
|
|
71799
|
+
filePath: args.file_path,
|
|
71800
|
+
text: args.content,
|
|
71801
|
+
totalLines: lines
|
|
71802
|
+
}
|
|
71803
|
+
};
|
|
71165
71804
|
},
|
|
71166
71805
|
execute: async (args, context) => {
|
|
71167
71806
|
const { absolutePath: targetPath, relativePath } = resolveDirectMutationPath(context.cwd, args.file_path);
|
|
@@ -71492,61 +72131,25 @@ function countOccurrences(content, substring) {
|
|
|
71492
72131
|
var editFileTool = {
|
|
71493
72132
|
name: "edit_file",
|
|
71494
72133
|
displayName: "Edit",
|
|
72134
|
+
access: "write",
|
|
71495
72135
|
description: "Performs exact string replacements in an existing file. Every edit mutation participates in checkpointing for /rewind.",
|
|
71496
72136
|
parameters: editFileInputSchema,
|
|
71497
72137
|
confirmationPolicy: "never",
|
|
71498
72138
|
summarize: (args, result) => {
|
|
71499
72139
|
const added = result?.addedLines ?? 0;
|
|
71500
72140
|
const removed = result?.removedLines ?? 0;
|
|
71501
|
-
const
|
|
72141
|
+
const headline = `Added ${added} line${added === 1 ? "" : "s"}, removed ${removed} line${removed === 1 ? "" : "s"}`;
|
|
71502
72142
|
if (added === 0 && removed === 0)
|
|
71503
|
-
return
|
|
72143
|
+
return { headline };
|
|
71504
72144
|
const diff = buildUnifiedDiff(args.old_string, args.new_string, 2);
|
|
71505
|
-
|
|
71506
|
-
|
|
71507
|
-
|
|
71508
|
-
|
|
71509
|
-
|
|
71510
|
-
|
|
71511
|
-
for (const line of hunk.lines) {
|
|
71512
|
-
if (line.oldLineNumber)
|
|
71513
|
-
maxLineNum = Math.max(maxLineNum, line.oldLineNumber);
|
|
71514
|
-
if (line.newLineNumber)
|
|
71515
|
-
maxLineNum = Math.max(maxLineNum, line.newLineNumber);
|
|
71516
|
-
}
|
|
71517
|
-
}
|
|
71518
|
-
const padWidth = Math.max(1, String(maxLineNum).length);
|
|
71519
|
-
const diffLines = [];
|
|
71520
|
-
const cap = 30;
|
|
71521
|
-
let count = 0;
|
|
71522
|
-
let overflow = 0;
|
|
71523
|
-
for (const hunk of diff.hunks) {
|
|
71524
|
-
for (const line of hunk.lines) {
|
|
71525
|
-
if (count >= cap) {
|
|
71526
|
-
overflow++;
|
|
71527
|
-
continue;
|
|
71528
|
-
}
|
|
71529
|
-
count++;
|
|
71530
|
-
if (line.kind === "deletion") {
|
|
71531
|
-
const numStr = String(line.oldLineNumber ?? "").padStart(padWidth, " ");
|
|
71532
|
-
const body = line.spans ? "-" + line.spans.map((s) => s.kind === "deletion" ? source_default.bold(s.text) : s.text).join("") : `-${line.text}`;
|
|
71533
|
-
diffLines.push(deleteStyle(`${numStr} ${body}`));
|
|
71534
|
-
} else if (line.kind === "addition") {
|
|
71535
|
-
const numStr = String(line.newLineNumber ?? "").padStart(padWidth, " ");
|
|
71536
|
-
const body = line.spans ? "+" + line.spans.map((s) => s.kind === "addition" ? source_default.bold(s.text) : s.text).join("") : `+${line.text}`;
|
|
71537
|
-
diffLines.push(addStyle(`${numStr} ${body}`));
|
|
71538
|
-
} else {
|
|
71539
|
-
const numStr = String(line.newLineNumber ?? line.oldLineNumber ?? "").padStart(padWidth, " ");
|
|
71540
|
-
diffLines.push(contextStyle(`${numStr} ${line.text}`));
|
|
71541
|
-
}
|
|
72145
|
+
return {
|
|
72146
|
+
headline,
|
|
72147
|
+
detail: {
|
|
72148
|
+
kind: "diff",
|
|
72149
|
+
filePath: args.file_path,
|
|
72150
|
+
hunks: diff.hunks
|
|
71542
72151
|
}
|
|
71543
|
-
}
|
|
71544
|
-
if (overflow > 0) {
|
|
71545
|
-
diffLines.push(source_default.dim(` … (${overflow} more lines)`));
|
|
71546
|
-
}
|
|
71547
|
-
return diffLines.length > 0 ? `${summary}
|
|
71548
|
-
${diffLines.join(`
|
|
71549
|
-
`)}` : summary;
|
|
72152
|
+
};
|
|
71550
72153
|
},
|
|
71551
72154
|
execute: async (args, context) => {
|
|
71552
72155
|
const { absolutePath: targetPath, relativePath } = resolveDirectMutationPath(context.cwd, args.file_path);
|
|
@@ -71688,6 +72291,7 @@ function walkDir(dir, baseDir, matcher, results, limit) {
|
|
|
71688
72291
|
var globTool = {
|
|
71689
72292
|
name: "glob",
|
|
71690
72293
|
displayName: "Glob",
|
|
72294
|
+
access: "read",
|
|
71691
72295
|
description: "Finds files matching a glob pattern or file name in the workspace. Read-only search capability with bounded results.",
|
|
71692
72296
|
parameters: globInputSchema,
|
|
71693
72297
|
confirmationPolicy: "never",
|
|
@@ -71791,6 +72395,7 @@ function searchInDir(dir, baseDir, regex, fileFilter, results, filesWithMatches,
|
|
|
71791
72395
|
var grepTool = {
|
|
71792
72396
|
name: "grep",
|
|
71793
72397
|
displayName: "Grep",
|
|
72398
|
+
access: "read",
|
|
71794
72399
|
description: "Searches for text or regex patterns across files in the workspace. Read-only content search with structured match positions.",
|
|
71795
72400
|
parameters: grepInputSchema,
|
|
71796
72401
|
confirmationPolicy: "never",
|
|
@@ -71870,6 +72475,7 @@ var listDirInputSchema = object({
|
|
|
71870
72475
|
var listDirTool = {
|
|
71871
72476
|
name: "list_dir",
|
|
71872
72477
|
displayName: "List",
|
|
72478
|
+
access: "read",
|
|
71873
72479
|
description: "Lists files and folders in a specified directory. Read-only operation.",
|
|
71874
72480
|
parameters: listDirInputSchema,
|
|
71875
72481
|
confirmationPolicy: "never",
|
|
@@ -71930,6 +72536,7 @@ var sleepInputSchema = object({
|
|
|
71930
72536
|
var sleepTool = {
|
|
71931
72537
|
name: "sleep",
|
|
71932
72538
|
displayName: "Sleep",
|
|
72539
|
+
access: "read",
|
|
71933
72540
|
description: "Pauses current agent execution temporarily (between 1 and 300 seconds). Read-only and cancellable.",
|
|
71934
72541
|
parameters: sleepInputSchema,
|
|
71935
72542
|
confirmationPolicy: "never",
|
|
@@ -72099,7 +72706,7 @@ class ShellExecution {
|
|
|
72099
72706
|
};
|
|
72100
72707
|
child.stdout?.on("data", (chunk) => handleChunk(chunk, false));
|
|
72101
72708
|
child.stderr?.on("data", (chunk) => handleChunk(chunk, true));
|
|
72102
|
-
const onExit = (code,
|
|
72709
|
+
const onExit = (code, _signal) => {
|
|
72103
72710
|
if (!this.isRunning)
|
|
72104
72711
|
return;
|
|
72105
72712
|
this.endedAt = new Date().toISOString();
|
|
@@ -72555,6 +73162,7 @@ var bashInputSchema = object({
|
|
|
72555
73162
|
var bashTool = {
|
|
72556
73163
|
name: "bash",
|
|
72557
73164
|
displayName: "Bash",
|
|
73165
|
+
access: "exec",
|
|
72558
73166
|
description: "Executes a command in the platform shell. An explanation of what the command does and why it is needed is MANDATORY. Commands that exceed the foreground limit (~12s) automatically continue as background shell tasks. Use task_read, task_send_input, and task_kill to manage background tasks. Note: Bash commands are NOT tracked by the file checkpoint system (/rewind).",
|
|
72559
73167
|
parameters: bashInputSchema,
|
|
72560
73168
|
confirmationPolicy: "never",
|
|
@@ -72627,6 +73235,7 @@ var taskReadInputSchema = object({
|
|
|
72627
73235
|
var taskReadTool = {
|
|
72628
73236
|
name: "task_read",
|
|
72629
73237
|
displayName: "Task Read",
|
|
73238
|
+
access: "read",
|
|
72630
73239
|
description: "Reads current status, exit code, and recent bounded output snapshot of a background shell task. Non-blocking.",
|
|
72631
73240
|
parameters: taskReadInputSchema,
|
|
72632
73241
|
confirmationPolicy: "never",
|
|
@@ -72661,6 +73270,7 @@ function normalizeStdinInput(rawInput, appendNewline = true) {
|
|
|
72661
73270
|
var taskSendInputTool = {
|
|
72662
73271
|
name: "task_send_input",
|
|
72663
73272
|
displayName: "Task Send Input",
|
|
73273
|
+
access: "exec",
|
|
72664
73274
|
description: "Writes input text to the standard input (stdin) of a running background shell task. Automatically appends a newline unless append_newline is set to false.",
|
|
72665
73275
|
parameters: taskSendInputSchema,
|
|
72666
73276
|
confirmationPolicy: "never",
|
|
@@ -72684,6 +73294,7 @@ var taskKillInputSchema = object({
|
|
|
72684
73294
|
var taskKillTool = {
|
|
72685
73295
|
name: "task_kill",
|
|
72686
73296
|
displayName: "Task Kill",
|
|
73297
|
+
access: "exec",
|
|
72687
73298
|
description: "Terminates a running background shell task and its descendant process tree.",
|
|
72688
73299
|
parameters: taskKillInputSchema,
|
|
72689
73300
|
confirmationPolicy: "never",
|
|
@@ -72703,6 +73314,7 @@ var taskListInputSchema = object({});
|
|
|
72703
73314
|
var taskListTool = {
|
|
72704
73315
|
name: "task_list",
|
|
72705
73316
|
displayName: "Task List",
|
|
73317
|
+
access: "read",
|
|
72706
73318
|
description: "Lists all currently tracked background shell tasks along with their IDs, statuses, commands, and exit codes.",
|
|
72707
73319
|
parameters: taskListInputSchema,
|
|
72708
73320
|
confirmationPolicy: "never",
|
|
@@ -72724,7 +73336,7 @@ var taskListTool = {
|
|
|
72724
73336
|
// package.json
|
|
72725
73337
|
var package_default = {
|
|
72726
73338
|
name: "steward-cli",
|
|
72727
|
-
version: "0.
|
|
73339
|
+
version: "0.17.0",
|
|
72728
73340
|
description: "Interactive AI engineering assistant for the terminal with human-in-the-loop control across local and frontier models.",
|
|
72729
73341
|
author: "sapirrior",
|
|
72730
73342
|
license: "MIT",
|
|
@@ -72786,6 +73398,7 @@ function cleanHtmlContent(html) {
|
|
|
72786
73398
|
var webFetchTool = {
|
|
72787
73399
|
name: "web_fetch",
|
|
72788
73400
|
displayName: "Web",
|
|
73401
|
+
access: "read",
|
|
72789
73402
|
description: "Fetches text and documentation content from a public web URL. Automatically cleans HTML markup into readable text.",
|
|
72790
73403
|
parameters: webFetchInputSchema,
|
|
72791
73404
|
confirmationPolicy: "never",
|
|
@@ -72917,6 +73530,7 @@ async function searchDuckDuckGoDirect(query, limit, signal) {
|
|
|
72917
73530
|
var webSearchTool = {
|
|
72918
73531
|
name: "web_search",
|
|
72919
73532
|
displayName: "Web Search",
|
|
73533
|
+
access: "read",
|
|
72920
73534
|
description: "Searches the web directly for up-to-date information, documentation, package releases, and technical answers. Returns structured search results with titles, clean URLs, and snippets.",
|
|
72921
73535
|
parameters: webSearchInputSchema,
|
|
72922
73536
|
confirmationPolicy: "never",
|
|
@@ -73301,6 +73915,7 @@ var todoWriteTool = {
|
|
|
73301
73915
|
name: "todo_write",
|
|
73302
73916
|
displayName: "TodoWrite",
|
|
73303
73917
|
icon: "\uD83D\uDCDD",
|
|
73918
|
+
access: "write",
|
|
73304
73919
|
description: "Initializes or replaces the current session todo list with 2 to 10 items. Use this to establish or replace the multi-step execution plan for the session.",
|
|
73305
73920
|
parameters: todoWriteParamsSchema,
|
|
73306
73921
|
summarizeArgs(args) {
|
|
@@ -73362,6 +73977,7 @@ var todoUpdateTool = {
|
|
|
73362
73977
|
name: "todo_update",
|
|
73363
73978
|
displayName: "TodoUpdate",
|
|
73364
73979
|
icon: "✓",
|
|
73980
|
+
access: "write",
|
|
73365
73981
|
description: "Updates a single todo item status or description in the current session. Cannot create new items or update multiple items at once.",
|
|
73366
73982
|
parameters: todoUpdateParamsSchema,
|
|
73367
73983
|
summarizeArgs(args) {
|
|
@@ -73427,6 +74043,7 @@ var todoReadTool = {
|
|
|
73427
74043
|
name: "todo_read",
|
|
73428
74044
|
displayName: "TodoRead",
|
|
73429
74045
|
icon: "\uD83D\uDCCB",
|
|
74046
|
+
access: "read",
|
|
73430
74047
|
description: "Reads the current session todo list without modifying it. Returns an empty result if no todos have been established yet.",
|
|
73431
74048
|
parameters: todoReadParamsSchema,
|
|
73432
74049
|
summarizeArgs() {
|
|
@@ -73612,6 +74229,7 @@ var skillListTool = {
|
|
|
73612
74229
|
name: "skill_list",
|
|
73613
74230
|
displayName: "SkillList",
|
|
73614
74231
|
icon: "\uD83D\uDCA1",
|
|
74232
|
+
access: "read",
|
|
73615
74233
|
description: "Discovers and lists all available specialized skills and their descriptions. Use this when you need specialized domain knowledge or workflows.",
|
|
73616
74234
|
parameters: skillListParamsSchema,
|
|
73617
74235
|
summarizeArgs() {
|
|
@@ -73644,6 +74262,7 @@ var skillReadTool = {
|
|
|
73644
74262
|
name: "skill_read",
|
|
73645
74263
|
displayName: "SkillRead",
|
|
73646
74264
|
icon: "\uD83D\uDCD6",
|
|
74265
|
+
access: "read",
|
|
73647
74266
|
description: "Loads and reads the instructions (SKILL.md) or a relative resource file of a specialized skill by name. Use this when a task requires specialized guidelines.",
|
|
73648
74267
|
parameters: skillReadParamsSchema,
|
|
73649
74268
|
summarizeArgs(args) {
|
|
@@ -73662,6 +74281,108 @@ var skillReadTool = {
|
|
|
73662
74281
|
return `SkillRead: ${target}${len}`;
|
|
73663
74282
|
}
|
|
73664
74283
|
};
|
|
74284
|
+
// src/tools/summary.ts
|
|
74285
|
+
function summarizeToolResult(toolDef, args, result, isError = false) {
|
|
74286
|
+
if (isError)
|
|
74287
|
+
return;
|
|
74288
|
+
if (!toolDef) {
|
|
74289
|
+
if (typeof result === "string") {
|
|
74290
|
+
const firstLine = result.split(`
|
|
74291
|
+
`)[0]?.trim();
|
|
74292
|
+
return firstLine ? { headline: firstLine } : undefined;
|
|
74293
|
+
}
|
|
74294
|
+
if (result && typeof result === "object" && typeof result.message === "string") {
|
|
74295
|
+
return { headline: result.message };
|
|
74296
|
+
}
|
|
74297
|
+
return;
|
|
74298
|
+
}
|
|
74299
|
+
if (toolDef.summarize) {
|
|
74300
|
+
const sum = toolDef.summarize(args, result);
|
|
74301
|
+
if (typeof sum === "string") {
|
|
74302
|
+
const [headline, ...rest] = sum.split(`
|
|
74303
|
+
`);
|
|
74304
|
+
return {
|
|
74305
|
+
headline: headline ?? "",
|
|
74306
|
+
detail: rest.length > 0 ? { kind: "text", text: rest.join(`
|
|
74307
|
+
`) } : undefined
|
|
74308
|
+
};
|
|
74309
|
+
}
|
|
74310
|
+
return sum;
|
|
74311
|
+
}
|
|
74312
|
+
if (typeof result === "string") {
|
|
74313
|
+
const firstLine = result.split(`
|
|
74314
|
+
`)[0]?.trim();
|
|
74315
|
+
return { headline: firstLine || toolDef.displayName };
|
|
74316
|
+
}
|
|
74317
|
+
if (result && typeof result === "object" && typeof result.message === "string") {
|
|
74318
|
+
return { headline: result.message };
|
|
74319
|
+
}
|
|
74320
|
+
return { headline: toolDef.displayName };
|
|
74321
|
+
}
|
|
74322
|
+
function formatPlainToolSummary(summary) {
|
|
74323
|
+
if (!summary)
|
|
74324
|
+
return;
|
|
74325
|
+
if (!summary.detail)
|
|
74326
|
+
return summary.headline;
|
|
74327
|
+
if (summary.detail.kind === "text") {
|
|
74328
|
+
return `${summary.headline}
|
|
74329
|
+
${summary.detail.text}`;
|
|
74330
|
+
}
|
|
74331
|
+
if (summary.detail.kind === "code") {
|
|
74332
|
+
const lines = summary.detail.text.split(/\r?\n/);
|
|
74333
|
+
const cap = 50;
|
|
74334
|
+
const shown = lines.slice(0, cap);
|
|
74335
|
+
const padWidth = String(lines.length).length;
|
|
74336
|
+
const detail = shown.map((l, i) => `${String(i + 1).padStart(padWidth)} ${l}`).join(`
|
|
74337
|
+
`);
|
|
74338
|
+
const overflow = lines.length > cap ? `
|
|
74339
|
+
… (${lines.length - cap} more lines)` : "";
|
|
74340
|
+
return `${summary.headline}
|
|
74341
|
+
${detail}${overflow}`;
|
|
74342
|
+
}
|
|
74343
|
+
if (summary.detail.kind === "diff") {
|
|
74344
|
+
const diffLines = [];
|
|
74345
|
+
let maxLineNum = 1;
|
|
74346
|
+
for (const hunk of summary.detail.hunks) {
|
|
74347
|
+
for (const line of hunk.lines) {
|
|
74348
|
+
if (line.oldLineNumber)
|
|
74349
|
+
maxLineNum = Math.max(maxLineNum, line.oldLineNumber);
|
|
74350
|
+
if (line.newLineNumber)
|
|
74351
|
+
maxLineNum = Math.max(maxLineNum, line.newLineNumber);
|
|
74352
|
+
}
|
|
74353
|
+
}
|
|
74354
|
+
const padWidth = Math.max(1, String(maxLineNum).length);
|
|
74355
|
+
const cap = 30;
|
|
74356
|
+
let count = 0;
|
|
74357
|
+
let overflow = 0;
|
|
74358
|
+
for (const hunk of summary.detail.hunks) {
|
|
74359
|
+
for (const line of hunk.lines) {
|
|
74360
|
+
if (count >= cap) {
|
|
74361
|
+
overflow++;
|
|
74362
|
+
continue;
|
|
74363
|
+
}
|
|
74364
|
+
count++;
|
|
74365
|
+
if (line.kind === "deletion") {
|
|
74366
|
+
const numStr = String(line.oldLineNumber ?? "").padStart(padWidth, " ");
|
|
74367
|
+
diffLines.push(`${numStr} -${line.text}`);
|
|
74368
|
+
} else if (line.kind === "addition") {
|
|
74369
|
+
const numStr = String(line.newLineNumber ?? "").padStart(padWidth, " ");
|
|
74370
|
+
diffLines.push(`${numStr} +${line.text}`);
|
|
74371
|
+
} else {
|
|
74372
|
+
const numStr = String(line.newLineNumber ?? line.oldLineNumber ?? "").padStart(padWidth, " ");
|
|
74373
|
+
diffLines.push(`${numStr} ${line.text}`);
|
|
74374
|
+
}
|
|
74375
|
+
}
|
|
74376
|
+
}
|
|
74377
|
+
if (overflow > 0) {
|
|
74378
|
+
diffLines.push(` … (${overflow} more lines)`);
|
|
74379
|
+
}
|
|
74380
|
+
return diffLines.length > 0 ? `${summary.headline}
|
|
74381
|
+
${diffLines.join(`
|
|
74382
|
+
`)}` : summary.headline;
|
|
74383
|
+
}
|
|
74384
|
+
return summary.headline;
|
|
74385
|
+
}
|
|
73665
74386
|
|
|
73666
74387
|
// src/tools/index.ts
|
|
73667
74388
|
var builtInTools = [
|
|
@@ -89031,7 +89752,7 @@ function inferDocMediaType(uriOrName) {
|
|
|
89031
89752
|
}
|
|
89032
89753
|
return "application/octet-stream";
|
|
89033
89754
|
}
|
|
89034
|
-
function
|
|
89755
|
+
function basename2(uriOrName) {
|
|
89035
89756
|
const parts = uriOrName.split("/");
|
|
89036
89757
|
const last = parts[parts.length - 1];
|
|
89037
89758
|
return last && last.length > 0 ? last : undefined;
|
|
@@ -89069,7 +89790,7 @@ function annotationToSource({
|
|
|
89069
89790
|
...fileCitation.file_name != null ? { title: fileCitation.file_name } : {}
|
|
89070
89791
|
};
|
|
89071
89792
|
}
|
|
89072
|
-
const filename = (_c = fileCitation.file_name) != null ? _c :
|
|
89793
|
+
const filename = (_c = fileCitation.file_name) != null ? _c : basename2(uri);
|
|
89073
89794
|
const mediaType = inferDocMediaType(uri);
|
|
89074
89795
|
return {
|
|
89075
89796
|
type: "source",
|
|
@@ -89172,7 +89893,7 @@ function builtinToolResultToSources({
|
|
|
89172
89893
|
});
|
|
89173
89894
|
continue;
|
|
89174
89895
|
}
|
|
89175
|
-
const filename = (_h = entry.file_name) != null ? _h :
|
|
89896
|
+
const filename = (_h = entry.file_name) != null ? _h : basename2(uri);
|
|
89176
89897
|
const mediaType = inferDocMediaType(uri);
|
|
89177
89898
|
sources.push({
|
|
89178
89899
|
type: "source",
|
|
@@ -117680,8 +118401,7 @@ var PROVIDER_REGISTRY = {
|
|
|
117680
118401
|
envVar: "DEEPSEEK_API_KEY",
|
|
117681
118402
|
apiKey: (c) => c.deepseekApiKey,
|
|
117682
118403
|
defaultModel: "deepseek-chat",
|
|
117683
|
-
create: (apiKey) => createDeepSeek({ apiKey })
|
|
117684
|
-
isTaggedReasoning: () => true
|
|
118404
|
+
create: (apiKey) => createDeepSeek({ apiKey })
|
|
117685
118405
|
},
|
|
117686
118406
|
openrouter: {
|
|
117687
118407
|
name: "openrouter",
|
|
@@ -117696,8 +118416,7 @@ var PROVIDER_REGISTRY = {
|
|
|
117696
118416
|
"HTTP-Referer": "https://github.com/sapirrior/steward",
|
|
117697
118417
|
"X-Title": "steward"
|
|
117698
118418
|
}
|
|
117699
|
-
})
|
|
117700
|
-
isTaggedReasoning: (modelId) => isTaggedReasoningModel(modelId)
|
|
118419
|
+
})
|
|
117701
118420
|
},
|
|
117702
118421
|
custom: {
|
|
117703
118422
|
name: "custom",
|
|
@@ -117708,20 +118427,9 @@ var PROVIDER_REGISTRY = {
|
|
|
117708
118427
|
name: "custom",
|
|
117709
118428
|
baseURL: cfg.custom.baseURL,
|
|
117710
118429
|
apiKey: cfg.custom.apiKey
|
|
117711
|
-
})
|
|
117712
|
-
isTaggedReasoning: (modelId) => isTaggedReasoningModel(modelId)
|
|
118430
|
+
})
|
|
117713
118431
|
}
|
|
117714
118432
|
};
|
|
117715
|
-
var DEFAULT_MODELS_BY_PROVIDER = {
|
|
117716
|
-
gemini: PROVIDER_REGISTRY.gemini.defaultModel,
|
|
117717
|
-
anthropic: PROVIDER_REGISTRY.anthropic.defaultModel,
|
|
117718
|
-
openai: PROVIDER_REGISTRY.openai.defaultModel,
|
|
117719
|
-
xai: PROVIDER_REGISTRY.xai.defaultModel,
|
|
117720
|
-
mistral: PROVIDER_REGISTRY.mistral.defaultModel,
|
|
117721
|
-
deepseek: PROVIDER_REGISTRY.deepseek.defaultModel,
|
|
117722
|
-
openrouter: PROVIDER_REGISTRY.openrouter.defaultModel,
|
|
117723
|
-
custom: PROVIDER_REGISTRY.custom.defaultModel
|
|
117724
|
-
};
|
|
117725
118433
|
var DEFAULT_REASONING_EFFORT = "provider-default";
|
|
117726
118434
|
var REASONING_EFFORT_MAP = {
|
|
117727
118435
|
0: "provider-default",
|
|
@@ -117731,13 +118439,6 @@ var REASONING_EFFORT_MAP = {
|
|
|
117731
118439
|
4: "medium",
|
|
117732
118440
|
5: "high",
|
|
117733
118441
|
6: "xhigh",
|
|
117734
|
-
"0": "provider-default",
|
|
117735
|
-
"1": "none",
|
|
117736
|
-
"2": "minimal",
|
|
117737
|
-
"3": "low",
|
|
117738
|
-
"4": "medium",
|
|
117739
|
-
"5": "high",
|
|
117740
|
-
"6": "xhigh",
|
|
117741
118442
|
default: "provider-default",
|
|
117742
118443
|
"provider-default": "provider-default",
|
|
117743
118444
|
none: "none",
|
|
@@ -117784,7 +118485,7 @@ function resolveActiveModelSelection(requested, config = getEnvConfig()) {
|
|
|
117784
118485
|
if (!hasProviderConfig(requested.provider, config)) {
|
|
117785
118486
|
throw new Error(`Provider "${requested.provider}" was requested, but its credentials are not configured in the environment.`);
|
|
117786
118487
|
}
|
|
117787
|
-
const modelId = requested.provider === "custom" ? config.custom.modelName ||
|
|
118488
|
+
const modelId = requested.provider === "custom" ? config.custom.modelName || PROVIDER_REGISTRY.custom.defaultModel : PROVIDER_REGISTRY[requested.provider].defaultModel;
|
|
117788
118489
|
return {
|
|
117789
118490
|
provider: requested.provider,
|
|
117790
118491
|
modelId,
|
|
@@ -117814,7 +118515,7 @@ function resolveActiveModelSelection(requested, config = getEnvConfig()) {
|
|
|
117814
118515
|
}
|
|
117815
118516
|
for (const provider of PROVIDER_SELECTION_PRIORITY) {
|
|
117816
118517
|
if (available.includes(provider)) {
|
|
117817
|
-
const modelId = provider === "custom" ? config.custom.modelName ||
|
|
118518
|
+
const modelId = provider === "custom" ? config.custom.modelName || PROVIDER_REGISTRY.custom.defaultModel : PROVIDER_REGISTRY[provider].defaultModel;
|
|
117818
118519
|
return {
|
|
117819
118520
|
provider,
|
|
117820
118521
|
modelId,
|
|
@@ -117825,7 +118526,7 @@ function resolveActiveModelSelection(requested, config = getEnvConfig()) {
|
|
|
117825
118526
|
const fallbackProvider = available[0];
|
|
117826
118527
|
return {
|
|
117827
118528
|
provider: fallbackProvider,
|
|
117828
|
-
modelId:
|
|
118529
|
+
modelId: PROVIDER_REGISTRY[fallbackProvider].defaultModel,
|
|
117829
118530
|
effort
|
|
117830
118531
|
};
|
|
117831
118532
|
}
|
|
@@ -117839,15 +118540,7 @@ function createModelInstance(selection, config = getEnvConfig()) {
|
|
|
117839
118540
|
throw new Error(`${descriptor.envVar} is not configured in the environment.`);
|
|
117840
118541
|
}
|
|
117841
118542
|
const modelId = selection.provider === "custom" ? config.custom.modelName || selection.modelId : selection.modelId;
|
|
117842
|
-
|
|
117843
|
-
return applyModelMiddlewarePipeline(baseModel, selection, descriptor);
|
|
117844
|
-
}
|
|
117845
|
-
function applyModelMiddlewarePipeline(model, _selection, _descriptor) {
|
|
117846
|
-
return model;
|
|
117847
|
-
}
|
|
117848
|
-
function isTaggedReasoningModel(modelId) {
|
|
117849
|
-
const lower = modelId.toLowerCase();
|
|
117850
|
-
return lower.startsWith("deepseek-r1") || lower.includes("/deepseek-r1") || lower.includes("deepseek-reasoner") || lower === "r1" || lower.endsWith("-r1") || lower.startsWith("qwq") || lower.includes("qwen") && lower.includes("think");
|
|
118543
|
+
return descriptor.create(apiKey, config)(modelId);
|
|
117851
118544
|
}
|
|
117852
118545
|
function inferProviderFromModelId(modelId) {
|
|
117853
118546
|
const lower = modelId.toLowerCase();
|
|
@@ -117933,6 +118626,30 @@ ${options.userRules.map((rule) => `- ${rule}`).join(`
|
|
|
117933
118626
|
${options.extraInstructions}
|
|
117934
118627
|
</additional_instructions>`;
|
|
117935
118628
|
}
|
|
118629
|
+
if (options.chatMode && options.chatMode !== "normal") {
|
|
118630
|
+
const meta = MODES[options.chatMode];
|
|
118631
|
+
if (meta) {
|
|
118632
|
+
if (options.chatMode === "chat") {
|
|
118633
|
+
prompt += `
|
|
118634
|
+
|
|
118635
|
+
<operating_mode>
|
|
118636
|
+
Mode: CHAT — You have no tool access. Respond conversationally only. Do not attempt to call any tools.
|
|
118637
|
+
</operating_mode>`;
|
|
118638
|
+
} else if (options.chatMode === "review") {
|
|
118639
|
+
prompt += `
|
|
118640
|
+
|
|
118641
|
+
<operating_mode>
|
|
118642
|
+
Mode: REVIEW — You may only use read-only tools. Any attempt to write files, run commands, or mutate state will be blocked.
|
|
118643
|
+
</operating_mode>`;
|
|
118644
|
+
} else if (options.chatMode === "build") {
|
|
118645
|
+
prompt += `
|
|
118646
|
+
|
|
118647
|
+
<operating_mode>
|
|
118648
|
+
Mode: BUILD — You have full tool access. File writes and edits are automatically approved without user confirmation — act decisively and make changes directly. Bash commands still require user approval.
|
|
118649
|
+
</operating_mode>`;
|
|
118650
|
+
}
|
|
118651
|
+
}
|
|
118652
|
+
}
|
|
117936
118653
|
return prompt;
|
|
117937
118654
|
}
|
|
117938
118655
|
|
|
@@ -118083,14 +118800,17 @@ class AgentSession {
|
|
|
118083
118800
|
lockManager: globalMutationLockManager
|
|
118084
118801
|
});
|
|
118085
118802
|
await tracker.beginTurn(turnId, this.sessionData.turns.length + 1);
|
|
118803
|
+
const mode = getActiveMode();
|
|
118804
|
+
const effectiveFilePermission = MODES[mode]?.autoApproveFiles ? async (_req) => ({ allowed: true }) : options.requestFilePermission;
|
|
118086
118805
|
const toolContext = {
|
|
118087
118806
|
cwd,
|
|
118807
|
+
mode,
|
|
118088
118808
|
sessionId: this.sessionData.id,
|
|
118089
118809
|
abortSignal: this.activeAbortController.signal,
|
|
118090
118810
|
checkpointTracker: tracker,
|
|
118091
118811
|
mutationLocks: globalMutationLockManager,
|
|
118092
118812
|
requestBashPermission: options.requestBashPermission,
|
|
118093
|
-
requestFilePermission:
|
|
118813
|
+
requestFilePermission: effectiveFilePermission,
|
|
118094
118814
|
shellTasks: this.shellTasks
|
|
118095
118815
|
};
|
|
118096
118816
|
let activeTools;
|
|
@@ -118103,7 +118823,8 @@ class AgentSession {
|
|
|
118103
118823
|
}
|
|
118104
118824
|
const instructions = buildSystemPrompt({
|
|
118105
118825
|
cwd,
|
|
118106
|
-
extraInstructions: options.extraInstructions
|
|
118826
|
+
extraInstructions: options.extraInstructions,
|
|
118827
|
+
chatMode: mode
|
|
118107
118828
|
});
|
|
118108
118829
|
const wrappedOnEvent = (event) => {
|
|
118109
118830
|
if (event.type === "tool-call") {
|
|
@@ -118119,7 +118840,8 @@ class AgentSession {
|
|
|
118119
118840
|
});
|
|
118120
118841
|
} else if (event.type === "tool-result") {
|
|
118121
118842
|
const toolDef = defaultToolCatalog.get(event.toolResult.name);
|
|
118122
|
-
const
|
|
118843
|
+
const summaryObj = summarizeToolResult(toolDef, event.toolResult.args, event.toolResult.result, event.toolResult.isError);
|
|
118844
|
+
const outputSummary = formatPlainToolSummary(summaryObj);
|
|
118123
118845
|
const errorMessage = event.toolResult.isError ? typeof event.toolResult.result === "object" && event.toolResult.result !== null ? event.toolResult.result.message ?? JSON.stringify(event.toolResult.result) : String(event.toolResult.result) : undefined;
|
|
118124
118846
|
const status = event.toolResult.isError ? "failed" : "completed";
|
|
118125
118847
|
this.sessionLogWriter?.append({
|
|
@@ -118852,6 +119574,84 @@ var skillsCommand = {
|
|
|
118852
119574
|
}
|
|
118853
119575
|
};
|
|
118854
119576
|
|
|
119577
|
+
// src/commands/theme/index.ts
|
|
119578
|
+
var themeCommand = {
|
|
119579
|
+
name: "theme",
|
|
119580
|
+
description: "View or switch the active UI color theme with interactive theme picker",
|
|
119581
|
+
usage: "/theme [theme_name]",
|
|
119582
|
+
async execute(args, _context) {
|
|
119583
|
+
if (args.length === 0) {
|
|
119584
|
+
return {
|
|
119585
|
+
handled: true,
|
|
119586
|
+
data: {
|
|
119587
|
+
showThemePicker: true,
|
|
119588
|
+
themes: listThemes(),
|
|
119589
|
+
current: getActiveThemeName()
|
|
119590
|
+
}
|
|
119591
|
+
};
|
|
119592
|
+
}
|
|
119593
|
+
const matched = findTheme(args.join(" "));
|
|
119594
|
+
if (!matched) {
|
|
119595
|
+
const validNames = listThemes().map((t) => t.name).join(", ");
|
|
119596
|
+
return {
|
|
119597
|
+
handled: true,
|
|
119598
|
+
message: `Theme "${args.join(" ")}" was not found.
|
|
119599
|
+
Available themes: ${validNames}.
|
|
119600
|
+
Type "/theme" to open the interactive theme picker.`
|
|
119601
|
+
};
|
|
119602
|
+
}
|
|
119603
|
+
setActiveTheme(matched.name);
|
|
119604
|
+
saveThemeSelection(matched.name);
|
|
119605
|
+
return {
|
|
119606
|
+
handled: true,
|
|
119607
|
+
message: `Active theme switched to ${matched.label} and saved to ~/.steward/settings.json.`,
|
|
119608
|
+
data: { selected: matched, themeSwitched: true }
|
|
119609
|
+
};
|
|
119610
|
+
}
|
|
119611
|
+
};
|
|
119612
|
+
|
|
119613
|
+
// src/commands/mode/index.ts
|
|
119614
|
+
var modeCommand = {
|
|
119615
|
+
name: "mode",
|
|
119616
|
+
aliases: [],
|
|
119617
|
+
description: "Switch or view the current chat mode",
|
|
119618
|
+
execute: async (args) => {
|
|
119619
|
+
if (args.length === 0) {
|
|
119620
|
+
const current = getActiveMode();
|
|
119621
|
+
const currentMeta = listModes().find((m) => m.name === current);
|
|
119622
|
+
const modeList = listModes().map((m) => ` - ${m.label} (${m.name}): ${m.description}`).join(`
|
|
119623
|
+
`);
|
|
119624
|
+
return {
|
|
119625
|
+
handled: true,
|
|
119626
|
+
message: `Current mode: ${currentMeta?.label ?? current}
|
|
119627
|
+
|
|
119628
|
+
Available modes:
|
|
119629
|
+
${modeList}
|
|
119630
|
+
|
|
119631
|
+
Use "/mode <name>" or press Ctrl+B to cycle modes.`
|
|
119632
|
+
};
|
|
119633
|
+
}
|
|
119634
|
+
const query = args.join(" ");
|
|
119635
|
+
const matched = findMode(query);
|
|
119636
|
+
if (matched) {
|
|
119637
|
+
setActiveMode(matched.name);
|
|
119638
|
+
saveModeSelection(matched.name);
|
|
119639
|
+
return {
|
|
119640
|
+
handled: true,
|
|
119641
|
+
message: `Switched to ${matched.label} mode. ${matched.description}.`,
|
|
119642
|
+
data: {
|
|
119643
|
+
modeSwitched: true,
|
|
119644
|
+
selectedMode: matched
|
|
119645
|
+
}
|
|
119646
|
+
};
|
|
119647
|
+
}
|
|
119648
|
+
return {
|
|
119649
|
+
handled: true,
|
|
119650
|
+
message: `Unknown mode "${query}". Valid modes are: ${listModes().map((m) => m.label).join(", ")}.`
|
|
119651
|
+
};
|
|
119652
|
+
}
|
|
119653
|
+
};
|
|
119654
|
+
|
|
118855
119655
|
// src/commands/registry.ts
|
|
118856
119656
|
class CommandRegistry {
|
|
118857
119657
|
commands = new Map;
|
|
@@ -118894,6 +119694,8 @@ var builtInCommands = [
|
|
|
118894
119694
|
rewindCommand,
|
|
118895
119695
|
modelCommand,
|
|
118896
119696
|
effortCommand,
|
|
119697
|
+
themeCommand,
|
|
119698
|
+
modeCommand,
|
|
118897
119699
|
clearCommand,
|
|
118898
119700
|
exitCommand,
|
|
118899
119701
|
quitCommand,
|
|
@@ -118999,27 +119801,25 @@ class TextElement {
|
|
|
118999
119801
|
const effWidth = Math.max(1, maxW);
|
|
119000
119802
|
let styled = rawContent;
|
|
119001
119803
|
if (this.props.bold)
|
|
119002
|
-
styled =
|
|
119003
|
-
if (this.props.dim)
|
|
119004
|
-
styled = source_default.dim(styled);
|
|
119804
|
+
styled = bold(styled);
|
|
119005
119805
|
if (this.props.italic)
|
|
119006
|
-
styled =
|
|
119806
|
+
styled = italic(styled);
|
|
119007
119807
|
if (this.props.underline)
|
|
119008
|
-
styled =
|
|
119808
|
+
styled = underline(styled);
|
|
119009
119809
|
if (this.props.strikethrough)
|
|
119010
|
-
styled =
|
|
119810
|
+
styled = strikethrough(styled);
|
|
119011
119811
|
if (this.props.color) {
|
|
119012
119812
|
if (typeof this.props.color === "function") {
|
|
119013
119813
|
styled = this.props.color(styled);
|
|
119014
|
-
} else {
|
|
119015
|
-
styled =
|
|
119814
|
+
} else if (this.props.color in c) {
|
|
119815
|
+
styled = c[this.props.color](styled);
|
|
119016
119816
|
}
|
|
119017
119817
|
}
|
|
119018
119818
|
if (this.props.bgColor) {
|
|
119019
119819
|
if (typeof this.props.bgColor === "function") {
|
|
119020
119820
|
styled = this.props.bgColor(styled);
|
|
119021
|
-
} else {
|
|
119022
|
-
styled =
|
|
119821
|
+
} else if (this.props.bgColor in bg) {
|
|
119822
|
+
styled = bg[this.props.bgColor](styled);
|
|
119023
119823
|
}
|
|
119024
119824
|
}
|
|
119025
119825
|
const isWrappable = this.props.wrap ?? true;
|
|
@@ -119196,7 +119996,7 @@ class BoxElement {
|
|
|
119196
119996
|
applyBorders(lines, totalWidth, border) {
|
|
119197
119997
|
if (border === "none")
|
|
119198
119998
|
return lines;
|
|
119199
|
-
const colorFn = typeof this.props.borderColor === "function" ? this.props.borderColor : this.props.borderColor ?
|
|
119999
|
+
const colorFn = typeof this.props.borderColor === "function" ? this.props.borderColor : this.props.borderColor ? themeColor(this.props.borderColor) : (s) => s;
|
|
119200
120000
|
if (border === "top-bottom") {
|
|
119201
120001
|
const rule = colorFn(figures.horizontalLine.repeat(totalWidth));
|
|
119202
120002
|
return [rule, ...lines, rule];
|
|
@@ -119223,34 +120023,30 @@ function Box(props, children) {
|
|
|
119223
120023
|
}
|
|
119224
120024
|
// src/tui/primitives/widgets/ModalBox.ts
|
|
119225
120025
|
function renderModalBox(options) {
|
|
119226
|
-
const theme = getTheme();
|
|
119227
120026
|
const termWidth = options.width ?? process.stdout.columns ?? 80;
|
|
119228
120027
|
const maxCols = Math.max(1, termWidth);
|
|
119229
120028
|
const dividerWidth = Math.max(1, termWidth);
|
|
119230
|
-
const lavHeader = themeColor2(theme.lavenderHeader);
|
|
119231
|
-
const infoColor = themeColor2(theme.info);
|
|
119232
|
-
const dashRule = themeColor2(theme.dashedRule);
|
|
119233
120029
|
const elements = [];
|
|
119234
|
-
elements.push(Text(
|
|
120030
|
+
elements.push(Text(c.rule(figures.horizontalLine.repeat(dividerWidth)), { clip: true }));
|
|
119235
120031
|
if (options.subtitle) {
|
|
119236
120032
|
elements.push(Box({ direction: "row", justify: "space-between", width: maxCols }, [
|
|
119237
|
-
Text(options.title, { color:
|
|
119238
|
-
Text(options.subtitle, {
|
|
120033
|
+
Text(options.title, { color: "info" }),
|
|
120034
|
+
Text(options.subtitle, { color: "muted" })
|
|
119239
120035
|
]));
|
|
119240
120036
|
} else {
|
|
119241
|
-
elements.push(Text(options.title, { color:
|
|
120037
|
+
elements.push(Text(options.title, { color: "permission" }));
|
|
119242
120038
|
}
|
|
119243
120039
|
if (options.queryInput) {
|
|
119244
|
-
const pointer =
|
|
119245
|
-
const queryDisplay = options.queryInput.query ?
|
|
120040
|
+
const pointer = c.info(`${figures.pointer} `);
|
|
120041
|
+
const queryDisplay = options.queryInput.query ? c.text(options.queryInput.query) : c.muted(options.queryInput.placeholder);
|
|
119246
120042
|
elements.push(Text(`${pointer}${queryDisplay}`));
|
|
119247
|
-
elements.push(Text(
|
|
120043
|
+
elements.push(Text(c.rule(figures.horizontalLine.repeat(dividerWidth)), { clip: true }));
|
|
119248
120044
|
}
|
|
119249
120045
|
for (const child of options.content) {
|
|
119250
120046
|
elements.push(child);
|
|
119251
120047
|
}
|
|
119252
120048
|
if (options.footer) {
|
|
119253
|
-
elements.push(Text(
|
|
120049
|
+
elements.push(Text(italic(c.muted(options.footer))));
|
|
119254
120050
|
}
|
|
119255
120051
|
const modalBox = Box({ direction: "column", width: maxCols, clip: true }, elements);
|
|
119256
120052
|
return modalBox.render(maxCols);
|
|
@@ -119367,6 +120163,8 @@ function parseKeyInput(chunk) {
|
|
|
119367
120163
|
const str = typeof chunk === "string" ? chunk : chunk.toString();
|
|
119368
120164
|
if (str === "\x03")
|
|
119369
120165
|
return { type: "ctrl-c", raw: str };
|
|
120166
|
+
if (str === "\x02")
|
|
120167
|
+
return { type: "ctrl-b", raw: str };
|
|
119370
120168
|
if (str === "\x14")
|
|
119371
120169
|
return { type: "ctrl-t", raw: str };
|
|
119372
120170
|
if (str === "\x1B[5~")
|
|
@@ -119491,12 +120289,10 @@ class Header extends Component {
|
|
|
119491
120289
|
return rawPath;
|
|
119492
120290
|
}
|
|
119493
120291
|
render(_width) {
|
|
119494
|
-
const theme = getTheme();
|
|
119495
120292
|
const version = this.props.version ?? DEFAULT_VERSION;
|
|
119496
|
-
const
|
|
119497
|
-
const
|
|
119498
|
-
const
|
|
119499
|
-
const logoL2 = brandColor(LOGO_LINES[2] ?? "");
|
|
120293
|
+
const logoL0 = c.brand(LOGO_LINES[0] ?? "");
|
|
120294
|
+
const logoL1 = c.brand(LOGO_LINES[1] ?? "");
|
|
120295
|
+
const logoL2 = c.brand(LOGO_LINES[2] ?? "");
|
|
119500
120296
|
const modelObj = this.props.model ?? { provider: "anthropic", modelId: "claude-3-7-sonnet" };
|
|
119501
120297
|
const modelTag = `${modelObj.provider}/${modelObj.modelId}`;
|
|
119502
120298
|
const cwdFormatted = this.formatCwd(this.props.cwd ?? process.cwd());
|
|
@@ -119508,17 +120304,17 @@ class Header extends Component {
|
|
|
119508
120304
|
/* @__PURE__ */ jsx(Text, {
|
|
119509
120305
|
wrap: false,
|
|
119510
120306
|
clip: false,
|
|
119511
|
-
children: `${logoL0} ${
|
|
120307
|
+
children: `${logoL0} ${bold(c.text("Steward"))} ${c.muted(`v${version}`)}`
|
|
119512
120308
|
}),
|
|
119513
120309
|
/* @__PURE__ */ jsx(Text, {
|
|
119514
120310
|
wrap: false,
|
|
119515
120311
|
clip: false,
|
|
119516
|
-
children: `${logoL1} ${
|
|
120312
|
+
children: `${logoL1} ${c.muted(modelTag)} ${c.muted("·")} ${c.muted("API Usage Billing")}`
|
|
119517
120313
|
}),
|
|
119518
120314
|
/* @__PURE__ */ jsx(Text, {
|
|
119519
120315
|
wrap: false,
|
|
119520
120316
|
clip: false,
|
|
119521
|
-
children: `${logoL2} ${
|
|
120317
|
+
children: `${logoL2} ${c.muted(cwdFormatted)}`
|
|
119522
120318
|
}),
|
|
119523
120319
|
/* @__PURE__ */ jsx(Text, {
|
|
119524
120320
|
wrap: false,
|
|
@@ -119532,17 +120328,6 @@ class Header extends Component {
|
|
|
119532
120328
|
}
|
|
119533
120329
|
|
|
119534
120330
|
// src/tui/components/StatusBar.tsx
|
|
119535
|
-
function formatTokens(n) {
|
|
119536
|
-
if (n < 0)
|
|
119537
|
-
return "0";
|
|
119538
|
-
if (n >= 1e9)
|
|
119539
|
-
return `${(n / 1e9).toFixed(1)}B`;
|
|
119540
|
-
if (n >= 1e6)
|
|
119541
|
-
return `${(n / 1e6).toFixed(1)}M`;
|
|
119542
|
-
if (n >= 1000)
|
|
119543
|
-
return `${(n / 1000).toFixed(1)}K`;
|
|
119544
|
-
return `${n}`;
|
|
119545
|
-
}
|
|
119546
120331
|
function formatVoiceDuration(sec) {
|
|
119547
120332
|
const m = Math.floor(sec / 60).toString().padStart(2, "0");
|
|
119548
120333
|
const s = (sec % 60).toString().padStart(2, "0");
|
|
@@ -119558,8 +120343,8 @@ class StatusBar extends Component {
|
|
|
119558
120343
|
constructor(props) {
|
|
119559
120344
|
super(props);
|
|
119560
120345
|
this.state = {
|
|
120346
|
+
chatMode: props.chatMode ?? getActiveMode(),
|
|
119561
120347
|
model: props.model,
|
|
119562
|
-
usage: props.usage,
|
|
119563
120348
|
isBusy: props.isBusy,
|
|
119564
120349
|
exitPending: props.exitPending,
|
|
119565
120350
|
warning: props.warning,
|
|
@@ -119568,6 +120353,9 @@ class StatusBar extends Component {
|
|
|
119568
120353
|
updateStatus: props.updateStatus
|
|
119569
120354
|
};
|
|
119570
120355
|
}
|
|
120356
|
+
setMode(mode) {
|
|
120357
|
+
this.setState({ chatMode: mode });
|
|
120358
|
+
}
|
|
119571
120359
|
update(partial) {
|
|
119572
120360
|
this.setState(partial);
|
|
119573
120361
|
}
|
|
@@ -119631,61 +120419,61 @@ class StatusBar extends Component {
|
|
|
119631
120419
|
}
|
|
119632
120420
|
}
|
|
119633
120421
|
render(width) {
|
|
119634
|
-
const theme = getTheme();
|
|
119635
120422
|
const termWidth = width ?? process.stdout.columns ?? 80;
|
|
119636
120423
|
const maxCols = Math.max(1, termWidth);
|
|
119637
120424
|
const {
|
|
119638
120425
|
model,
|
|
119639
|
-
usage,
|
|
119640
120426
|
isBusy,
|
|
119641
120427
|
exitPending,
|
|
119642
120428
|
warning,
|
|
119643
120429
|
voiceState,
|
|
119644
120430
|
voiceDurationSec,
|
|
119645
|
-
updateStatus
|
|
120431
|
+
updateStatus,
|
|
120432
|
+
chatMode
|
|
119646
120433
|
} = this.state;
|
|
119647
120434
|
let left = "";
|
|
119648
120435
|
if (warning) {
|
|
119649
|
-
left =
|
|
120436
|
+
left = c.warning(warning);
|
|
119650
120437
|
} else if (voiceState && voiceState !== "idle") {
|
|
119651
120438
|
if (voiceState === "connecting") {
|
|
119652
|
-
left = `${
|
|
120439
|
+
left = `${bold(c.text("Connecting..."))} ${c.muted("Ctrl+T to stop")}`;
|
|
119653
120440
|
} else if (voiceState === "recording") {
|
|
119654
120441
|
const timeStr = formatVoiceDuration(voiceDurationSec ?? 0);
|
|
119655
|
-
left = `${
|
|
120442
|
+
left = `${bold(c.text(`Recording... ${timeStr}`))} ${c.muted("Ctrl+T to stop")}`;
|
|
119656
120443
|
} else if (voiceState === "finishing") {
|
|
119657
|
-
left =
|
|
120444
|
+
left = bold(c.text("Finishing..."));
|
|
119658
120445
|
}
|
|
119659
120446
|
} else if (exitPending) {
|
|
119660
|
-
|
|
119661
|
-
left = `${errColor("▸ ")}${source_default.dim("Press ")}${errColor("Ctrl+C")}${source_default.dim(" again to exit")}`;
|
|
120447
|
+
left = `${c.error("▸ ")}${c.muted("Press ")}${c.error("Ctrl+C")}${c.muted(" again to exit")}`;
|
|
119662
120448
|
} else if (updateStatus && updateStatus.state !== "idle") {
|
|
119663
120449
|
if (updateStatus.state === "checking") {
|
|
119664
|
-
left =
|
|
120450
|
+
left = c.text(updateStatus.message ?? "Checking for updates...");
|
|
119665
120451
|
} else if (updateStatus.state === "available") {
|
|
119666
|
-
left =
|
|
120452
|
+
left = c.text(updateStatus.message ?? `Update v${updateStatus.version ?? ""} is available`);
|
|
119667
120453
|
} else if (updateStatus.state === "no-updates") {
|
|
119668
|
-
left =
|
|
120454
|
+
left = c.text(updateStatus.message ?? "Steward is up to date");
|
|
119669
120455
|
} else if (updateStatus.state === "error" && updateStatus.message) {
|
|
119670
|
-
left =
|
|
120456
|
+
left = c.error(updateStatus.message);
|
|
119671
120457
|
} else if (isBusy) {
|
|
119672
|
-
left =
|
|
120458
|
+
left = c.muted("esc to interrupt");
|
|
119673
120459
|
} else {
|
|
119674
|
-
left =
|
|
120460
|
+
left = c.muted("? for shortcuts");
|
|
119675
120461
|
}
|
|
119676
120462
|
} else if (isBusy) {
|
|
119677
|
-
left =
|
|
120463
|
+
left = c.muted("esc to interrupt");
|
|
119678
120464
|
} else {
|
|
119679
|
-
left =
|
|
120465
|
+
left = c.muted("? for shortcuts");
|
|
119680
120466
|
}
|
|
120467
|
+
const mode = chatMode ?? "normal";
|
|
120468
|
+
const modeMeta = MODES[mode];
|
|
120469
|
+
const modeColorKey = modeMeta?.color ?? "text";
|
|
120470
|
+
const modeLabel = modeMeta?.label ?? mode;
|
|
119681
120471
|
const parts = [];
|
|
119682
|
-
|
|
119683
|
-
parts.push(`${formatTokens(usage.totalTokens)} tokens`);
|
|
119684
|
-
}
|
|
120472
|
+
parts.push(c[modeColorKey](modeLabel));
|
|
119685
120473
|
const effort = model?.effort ?? "provider-default";
|
|
119686
120474
|
const effortDisplay = effort === "provider-default" ? "default" : effort;
|
|
119687
|
-
parts.push(effortDisplay);
|
|
119688
|
-
const right = parts.length > 0 ?
|
|
120475
|
+
parts.push(c.muted(effortDisplay));
|
|
120476
|
+
const right = parts.length > 0 ? parts.join(c.muted(` ${figures.bullet} `)) : "";
|
|
119689
120477
|
const element = /* @__PURE__ */ jsxs(Box, {
|
|
119690
120478
|
direction: "row",
|
|
119691
120479
|
justify: "space-between",
|
|
@@ -119805,9 +120593,9 @@ class StreamingView extends Component {
|
|
|
119805
120593
|
if (targetArg) {
|
|
119806
120594
|
const maxArgLen = Math.max(10, maxCols - toolName.length - 8);
|
|
119807
120595
|
const truncatedArg = targetArg.length > maxArgLen ? truncateMiddle(targetArg, maxArgLen) : targetArg;
|
|
119808
|
-
line += `${
|
|
120596
|
+
line += `${c.muted("(")}${c.muted(truncatedArg)}${c.muted(")")}`;
|
|
119809
120597
|
} else {
|
|
119810
|
-
line += `${
|
|
120598
|
+
line += `${c.muted("()")}`;
|
|
119811
120599
|
}
|
|
119812
120600
|
lines.push(line);
|
|
119813
120601
|
if (activeTool.recentLines && activeTool.recentLines.length > 0) {
|
|
@@ -119815,16 +120603,16 @@ class StreamingView extends Component {
|
|
|
119815
120603
|
const maxLogLen = Math.max(10, maxCols - 6);
|
|
119816
120604
|
for (let i = 0;i < toShow.length; i++) {
|
|
119817
120605
|
const l = toShow[i] ?? "";
|
|
119818
|
-
const p = i === 0 ? ` ${
|
|
120606
|
+
const p = i === 0 ? ` ${c.muted("└ ")}` : " ";
|
|
119819
120607
|
const truncatedLog = l.length > maxLogLen ? `${l.slice(0, maxLogLen - 1)}…` : l;
|
|
119820
|
-
lines.push(`${p}${
|
|
120608
|
+
lines.push(`${p}${c.muted(truncatedLog)}`);
|
|
119821
120609
|
}
|
|
119822
120610
|
} else {
|
|
119823
|
-
lines.push(` ${
|
|
120611
|
+
lines.push(` ${c.muted("└ Running...")}`);
|
|
119824
120612
|
}
|
|
119825
120613
|
} else if (isThinking && !text) {
|
|
119826
120614
|
const bullet = getStatusBullet("running", pulseFrame % 2 === 0);
|
|
119827
|
-
lines.push(`${bullet} ${
|
|
120615
|
+
lines.push(`${bullet} ${bold(c.text("Thinking.."))}`);
|
|
119828
120616
|
const elapsedMs = thinkingStartTime ? performance.now() - thinkingStartTime : pulseFrame * 120;
|
|
119829
120617
|
let subText = "wait...";
|
|
119830
120618
|
if (elapsedMs < 2000) {
|
|
@@ -119836,7 +120624,7 @@ class StreamingView extends Component {
|
|
|
119836
120624
|
} else {
|
|
119837
120625
|
subText = "taking a bit time...";
|
|
119838
120626
|
}
|
|
119839
|
-
lines.push(` ${
|
|
120627
|
+
lines.push(` ${c.muted("└ ")}${c.muted(subText)}`);
|
|
119840
120628
|
}
|
|
119841
120629
|
if (text) {
|
|
119842
120630
|
if (lines.length > 0)
|
|
@@ -119863,7 +120651,7 @@ class StreamingView extends Component {
|
|
|
119863
120651
|
continue;
|
|
119864
120652
|
}
|
|
119865
120653
|
if (i === 0) {
|
|
119866
|
-
const bullet =
|
|
120654
|
+
const bullet = c.text(`${figures.blackCircle} `);
|
|
119867
120655
|
lines.push(`${bullet}${l}`);
|
|
119868
120656
|
} else {
|
|
119869
120657
|
lines.push(` ${l}`);
|
|
@@ -120079,7 +120867,7 @@ class PromptInput extends Component {
|
|
|
120079
120867
|
return true;
|
|
120080
120868
|
}
|
|
120081
120869
|
const isSlashMode = this.state.value.startsWith("/") && !this.state.value.includes(" ");
|
|
120082
|
-
const matchingCommands = isSlashMode ? defaultCommandRegistry.getAll().filter((
|
|
120870
|
+
const matchingCommands = isSlashMode ? defaultCommandRegistry.getAll().filter((c2) => `/${c2.name}`.toLowerCase().startsWith(this.state.value.toLowerCase())) : [];
|
|
120083
120871
|
if (action.type === "newline") {
|
|
120084
120872
|
const before = this.state.value.slice(0, this.state.cursorPos);
|
|
120085
120873
|
const after = this.state.value.slice(this.state.cursorPos);
|
|
@@ -120343,7 +121131,6 @@ ${after}`, this.state.cursorPos);
|
|
|
120343
121131
|
return this.renderWithCursor(width).lines;
|
|
120344
121132
|
}
|
|
120345
121133
|
renderWithCursor(width) {
|
|
120346
|
-
const theme = getTheme();
|
|
120347
121134
|
const termWidth = width ?? process.stdout.columns ?? 80;
|
|
120348
121135
|
const maxCols = Math.max(1, termWidth);
|
|
120349
121136
|
const dividerWidth = maxCols;
|
|
@@ -120364,12 +121151,12 @@ ${after}`, this.state.cursorPos);
|
|
|
120364
121151
|
const lines = [];
|
|
120365
121152
|
let cursor = null;
|
|
120366
121153
|
if (escPending) {
|
|
120367
|
-
lines.push(
|
|
121154
|
+
lines.push(c.permission("Press Esc again to clear"));
|
|
120368
121155
|
}
|
|
120369
|
-
const borderColor = disabled ?
|
|
121156
|
+
const borderColor = disabled ? c.subtle : c.promptBorder;
|
|
120370
121157
|
if (disabled) {
|
|
120371
121158
|
lines.push(borderColor(figures.horizontalLine.repeat(dividerWidth)));
|
|
120372
|
-
lines.push(truncateToWidth(` ${
|
|
121159
|
+
lines.push(truncateToWidth(` ${c.muted("Esc to stop")}`, maxCols));
|
|
120373
121160
|
lines.push(borderColor(figures.horizontalLine.repeat(dividerWidth)));
|
|
120374
121161
|
return { lines, cursor: null };
|
|
120375
121162
|
}
|
|
@@ -120378,22 +121165,19 @@ ${after}`, this.state.cursorPos);
|
|
|
120378
121165
|
const leftDashes = borderColor(figures.horizontalLine.repeat(4));
|
|
120379
121166
|
const rightLen = Math.max(0, maxCols - (4 + histText.length));
|
|
120380
121167
|
const rightDashes = borderColor(figures.horizontalLine.repeat(rightLen));
|
|
120381
|
-
lines.push(`${leftDashes}${
|
|
121168
|
+
lines.push(`${leftDashes}${c.text(histText)}${rightDashes}`);
|
|
120382
121169
|
} else {
|
|
120383
121170
|
lines.push(borderColor(figures.horizontalLine.repeat(dividerWidth)));
|
|
120384
121171
|
}
|
|
120385
121172
|
const displayData = voiceMode !== "idle" && voiceTranscript ? insertTextAtAnchor(value, voiceAnchor, voiceTranscript) : { value, cursorPos };
|
|
120386
121173
|
const effectiveValue = displayData.value;
|
|
120387
121174
|
const effectiveCursorPos = displayData.cursorPos;
|
|
120388
|
-
const chevColor = themeColor2(theme.userChevron);
|
|
120389
|
-
const pointer = chevColor(`${figures.pointerBold} `);
|
|
120390
|
-
const prefixLen = 2;
|
|
120391
121175
|
if (effectiveValue.length === 0) {
|
|
120392
121176
|
cursor = {
|
|
120393
121177
|
logicalLineIndex: lines.length,
|
|
120394
|
-
characterOffsetWithinLine:
|
|
121178
|
+
characterOffsetWithinLine: 0
|
|
120395
121179
|
};
|
|
120396
|
-
lines.push(truncateToWidth(
|
|
121180
|
+
lines.push(truncateToWidth(c.muted("Type your message..."), maxCols));
|
|
120397
121181
|
} else {
|
|
120398
121182
|
const vLines = effectiveValue.split(`
|
|
120399
121183
|
`);
|
|
@@ -120406,37 +121190,35 @@ ${after}`, this.state.cursorPos);
|
|
|
120406
121190
|
if (cursor === null && effectiveCursorPos >= currentOffset && (effectiveCursorPos <= lineEndOffset || isLast)) {
|
|
120407
121191
|
cursor = {
|
|
120408
121192
|
logicalLineIndex: lines.length,
|
|
120409
|
-
characterOffsetWithinLine:
|
|
121193
|
+
characterOffsetWithinLine: effectiveCursorPos - currentOffset
|
|
120410
121194
|
};
|
|
120411
121195
|
}
|
|
120412
|
-
|
|
120413
|
-
lines.push(`${p}${source_default.white(l)}`);
|
|
121196
|
+
lines.push(c.text(l));
|
|
120414
121197
|
currentOffset = lineEndOffset + 1;
|
|
120415
121198
|
}
|
|
120416
121199
|
}
|
|
120417
121200
|
lines.push(borderColor(figures.horizontalLine.repeat(dividerWidth)));
|
|
120418
121201
|
const isSlashMode = voiceMode === "idle" && effectiveValue.startsWith("/") && !effectiveValue.includes(" ");
|
|
120419
|
-
const matchingCommands = isSlashMode ? defaultCommandRegistry.getAll().filter((
|
|
121202
|
+
const matchingCommands = isSlashMode ? defaultCommandRegistry.getAll().filter((cmd) => `/${cmd.name}`.toLowerCase().startsWith(effectiveValue.toLowerCase())) : [];
|
|
120420
121203
|
if (isSlashMode && matchingCommands.length > 0 && effectiveValue !== `/${matchingCommands[0]?.name} `) {
|
|
120421
121204
|
for (let i = 0;i < matchingCommands.length; i++) {
|
|
120422
121205
|
const cmd = matchingCommands[i];
|
|
120423
121206
|
const isSelected = i === paletteIdx;
|
|
120424
121207
|
const namePadded = `/${cmd.name}`.padEnd(18);
|
|
120425
121208
|
if (isSelected) {
|
|
120426
|
-
lines.push(truncateToWidth(`${
|
|
121209
|
+
lines.push(truncateToWidth(`${bold(c.text(namePadded))}${bold(c.text(cmd.description))}`, maxCols));
|
|
120427
121210
|
} else {
|
|
120428
|
-
lines.push(truncateToWidth(`${
|
|
121211
|
+
lines.push(truncateToWidth(`${c.muted(namePadded)}${c.muted(cmd.description)}`, maxCols));
|
|
120429
121212
|
}
|
|
120430
121213
|
}
|
|
120431
121214
|
}
|
|
120432
121215
|
if (voiceMode === "idle" && fileMatches.length > 0) {
|
|
120433
|
-
|
|
120434
|
-
lines.push(source_default.dim("Matching files (@):"));
|
|
121216
|
+
lines.push(c.muted("Matching files (@):"));
|
|
120435
121217
|
for (let i = 0;i < fileMatches.length; i++) {
|
|
120436
121218
|
const f = fileMatches[i];
|
|
120437
121219
|
const isSelected = i === fileSelectIdx;
|
|
120438
|
-
const p = isSelected ?
|
|
120439
|
-
const fileText = isSelected ?
|
|
121220
|
+
const p = isSelected ? c.info(`${figures.pointerBold} `) : " ";
|
|
121221
|
+
const fileText = isSelected ? c.info(f) : c.muted(f);
|
|
120440
121222
|
lines.push(truncateToWidth(`${p}${fileText}`, maxCols));
|
|
120441
121223
|
}
|
|
120442
121224
|
}
|
|
@@ -120493,19 +121275,14 @@ class TrustGate extends Component {
|
|
|
120493
121275
|
}
|
|
120494
121276
|
}
|
|
120495
121277
|
render(width) {
|
|
120496
|
-
const theme = getTheme();
|
|
120497
121278
|
const termWidth = width ?? process.stdout.columns ?? 80;
|
|
120498
121279
|
const maxCols = Math.max(1, termWidth);
|
|
120499
|
-
const warnColor = themeColor2(theme.warning);
|
|
120500
|
-
const permColor = themeColor2(theme.permission);
|
|
120501
|
-
const mutedColor = themeColor2(theme.textMuted);
|
|
120502
|
-
const dimGuideColor = themeColor2(theme.inactive);
|
|
120503
121280
|
const { selectedIndex } = this.state;
|
|
120504
121281
|
const isYesSelected = selectedIndex === 0;
|
|
120505
121282
|
const isNoSelected = selectedIndex === 1;
|
|
120506
121283
|
const pointer = figures.pointerBold ?? "❯";
|
|
120507
|
-
const yesOptionText = isYesSelected ? `${
|
|
120508
|
-
const noOptionText = isNoSelected ? `${
|
|
121284
|
+
const yesOptionText = isYesSelected ? `${c.permission(pointer)} ${bold(c.permission("1. Yes, I trust this folder"))}` : ` ${c.text("1. Yes, I trust this folder")}`;
|
|
121285
|
+
const noOptionText = isNoSelected ? `${c.permission(pointer)} ${bold(c.permission("2. No, exit"))}` : ` ${c.text("2. No, exit")}`;
|
|
120509
121286
|
const safetyCheckText = "You should only proceed if you trust this workspace. Accessing untrusted workspaces may allow malicious code in the repository to compromise security or mislead the assistant.";
|
|
120510
121287
|
const capabilityText = "Steward can read files and execute commands to investigate, build, and debug with your explicit permission. Pre-mutation checkpoints ensure every edit is reversible via /rewind.";
|
|
120511
121288
|
const element = /* @__PURE__ */ jsxs(Box, {
|
|
@@ -120517,7 +121294,7 @@ class TrustGate extends Component {
|
|
|
120517
121294
|
/* @__PURE__ */ jsx(Text, {
|
|
120518
121295
|
wrap: false,
|
|
120519
121296
|
clip: false,
|
|
120520
|
-
children:
|
|
121297
|
+
children: bold(c.warning("Accessing workspace:"))
|
|
120521
121298
|
}),
|
|
120522
121299
|
/* @__PURE__ */ jsx(Text, {
|
|
120523
121300
|
wrap: false,
|
|
@@ -120527,7 +121304,7 @@ class TrustGate extends Component {
|
|
|
120527
121304
|
/* @__PURE__ */ jsx(Text, {
|
|
120528
121305
|
wrap: false,
|
|
120529
121306
|
clip: false,
|
|
120530
|
-
children:
|
|
121307
|
+
children: bold(c.text(this.props.cwd))
|
|
120531
121308
|
}),
|
|
120532
121309
|
/* @__PURE__ */ jsx(Text, {
|
|
120533
121310
|
wrap: false,
|
|
@@ -120536,7 +121313,7 @@ class TrustGate extends Component {
|
|
|
120536
121313
|
}),
|
|
120537
121314
|
/* @__PURE__ */ jsx(Text, {
|
|
120538
121315
|
wrap: true,
|
|
120539
|
-
children:
|
|
121316
|
+
children: c.text(safetyCheckText)
|
|
120540
121317
|
}),
|
|
120541
121318
|
/* @__PURE__ */ jsx(Text, {
|
|
120542
121319
|
wrap: false,
|
|
@@ -120545,7 +121322,7 @@ class TrustGate extends Component {
|
|
|
120545
121322
|
}),
|
|
120546
121323
|
/* @__PURE__ */ jsx(Text, {
|
|
120547
121324
|
wrap: true,
|
|
120548
|
-
children:
|
|
121325
|
+
children: c.text(capabilityText)
|
|
120549
121326
|
}),
|
|
120550
121327
|
/* @__PURE__ */ jsx(Text, {
|
|
120551
121328
|
wrap: false,
|
|
@@ -120555,7 +121332,7 @@ class TrustGate extends Component {
|
|
|
120555
121332
|
/* @__PURE__ */ jsx(Text, {
|
|
120556
121333
|
wrap: false,
|
|
120557
121334
|
clip: false,
|
|
120558
|
-
children:
|
|
121335
|
+
children: c.muted("Security guide")
|
|
120559
121336
|
}),
|
|
120560
121337
|
/* @__PURE__ */ jsx(Text, {
|
|
120561
121338
|
wrap: false,
|
|
@@ -120580,7 +121357,7 @@ class TrustGate extends Component {
|
|
|
120580
121357
|
/* @__PURE__ */ jsx(Text, {
|
|
120581
121358
|
wrap: false,
|
|
120582
121359
|
clip: false,
|
|
120583
|
-
children:
|
|
121360
|
+
children: italic(c.muted("Enter to confirm · Esc to cancel"))
|
|
120584
121361
|
})
|
|
120585
121362
|
]
|
|
120586
121363
|
});
|
|
@@ -120605,12 +121382,9 @@ class ModelPicker extends SelectList {
|
|
|
120605
121382
|
onSelect: props.onSelect,
|
|
120606
121383
|
onCancel: props.onCancel,
|
|
120607
121384
|
renderItem: (m, isSelected, maxCols) => {
|
|
120608
|
-
const theme = getTheme();
|
|
120609
|
-
const selColor = themeColor2(theme.permission);
|
|
120610
|
-
const yellowColor = themeColor2(theme.warning);
|
|
120611
121385
|
const isCurrent = m.provider === props.currentModel.provider && m.model_id === props.currentModel.modelId;
|
|
120612
|
-
const pointer = isSelected ?
|
|
120613
|
-
const activeBadge = isCurrent ?
|
|
121386
|
+
const pointer = isSelected ? c.selected(`${figures.pointer} `) : " ";
|
|
121387
|
+
const activeBadge = isCurrent ? bold(c.current(" (active)")) : "";
|
|
120614
121388
|
const providerName = m.provider.toUpperCase();
|
|
120615
121389
|
const caps = m.capabilities?.reasoning ? "reasoning" : "chat";
|
|
120616
121390
|
const meta = `${providerName} • ${caps}`;
|
|
@@ -120619,14 +121393,14 @@ class ModelPicker extends SelectList {
|
|
|
120619
121393
|
width: maxCols,
|
|
120620
121394
|
children: [
|
|
120621
121395
|
/* @__PURE__ */ jsx(Text, {
|
|
120622
|
-
color: isSelected ?
|
|
121396
|
+
color: isSelected ? "selected" : isCurrent ? "current" : "text",
|
|
120623
121397
|
wrap: false,
|
|
120624
121398
|
clip: true,
|
|
120625
121399
|
ellipsis: true,
|
|
120626
121400
|
children: `${pointer}${m.model_id}${activeBadge}`
|
|
120627
121401
|
}),
|
|
120628
121402
|
/* @__PURE__ */ jsx(Text, {
|
|
120629
|
-
|
|
121403
|
+
color: "muted",
|
|
120630
121404
|
wrap: false,
|
|
120631
121405
|
clip: true,
|
|
120632
121406
|
ellipsis: true,
|
|
@@ -120639,6 +121413,60 @@ class ModelPicker extends SelectList {
|
|
|
120639
121413
|
}
|
|
120640
121414
|
}
|
|
120641
121415
|
|
|
121416
|
+
// src/tui/components/docks/ThemePicker.tsx
|
|
121417
|
+
class ThemePicker extends SelectList {
|
|
121418
|
+
wrap = false;
|
|
121419
|
+
clip = true;
|
|
121420
|
+
ellipsis = false;
|
|
121421
|
+
constructor(props) {
|
|
121422
|
+
const currentMeta = props.themes.find((t) => t.name === props.currentTheme);
|
|
121423
|
+
const subtitle = currentMeta ? `Current: ${currentMeta.label}` : `Current: ${props.currentTheme}`;
|
|
121424
|
+
super({
|
|
121425
|
+
items: props.themes,
|
|
121426
|
+
title: "Select Theme",
|
|
121427
|
+
subtitle,
|
|
121428
|
+
placeholder: "Type to filter themes…",
|
|
121429
|
+
emptyMessage: " No themes matching query.",
|
|
121430
|
+
maxVisible: 4,
|
|
121431
|
+
searchFilter: (t, q) => t.name.toLowerCase().includes(q) || t.label.toLowerCase().includes(q) || t.description.toLowerCase().includes(q),
|
|
121432
|
+
onSelect: props.onSelect,
|
|
121433
|
+
onCancel: props.onCancel,
|
|
121434
|
+
renderItem: (t, isSelected, maxCols) => {
|
|
121435
|
+
const isCurrent = t.name === props.currentTheme;
|
|
121436
|
+
const pointer = isSelected ? c.selected(`${figures.pointer} `) : " ";
|
|
121437
|
+
const activeBadge = isCurrent ? bold(c.current(" (active)")) : "";
|
|
121438
|
+
const tBrand = resolveThemeColor(t.theme.brand, false)(figures.blackCircle);
|
|
121439
|
+
const tSuccess = resolveThemeColor(t.theme.success, false)(figures.blackCircle);
|
|
121440
|
+
const tWarning = resolveThemeColor(t.theme.warning, false)(figures.blackCircle);
|
|
121441
|
+
const tError = resolveThemeColor(t.theme.error, false)(figures.blackCircle);
|
|
121442
|
+
const tInfo = resolveThemeColor(t.theme.info, false)(figures.blackCircle);
|
|
121443
|
+
const tPerm = resolveThemeColor(t.theme.permission, false)(figures.blackCircle);
|
|
121444
|
+
const swatches = ` ${tBrand} ${tSuccess} ${tWarning} ${tError} ${tInfo} ${tPerm} ${t.description}`;
|
|
121445
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
121446
|
+
direction: "column",
|
|
121447
|
+
width: maxCols,
|
|
121448
|
+
children: [
|
|
121449
|
+
/* @__PURE__ */ jsx(Text, {
|
|
121450
|
+
color: isSelected ? "selected" : isCurrent ? "current" : "text",
|
|
121451
|
+
wrap: false,
|
|
121452
|
+
clip: true,
|
|
121453
|
+
ellipsis: true,
|
|
121454
|
+
children: `${pointer}${t.label}${activeBadge}`
|
|
121455
|
+
}),
|
|
121456
|
+
/* @__PURE__ */ jsx(Text, {
|
|
121457
|
+
color: "muted",
|
|
121458
|
+
wrap: false,
|
|
121459
|
+
clip: true,
|
|
121460
|
+
ellipsis: true,
|
|
121461
|
+
children: swatches
|
|
121462
|
+
})
|
|
121463
|
+
]
|
|
121464
|
+
});
|
|
121465
|
+
}
|
|
121466
|
+
});
|
|
121467
|
+
}
|
|
121468
|
+
}
|
|
121469
|
+
|
|
120642
121470
|
// src/tui/components/docks/SessionMenu.tsx
|
|
120643
121471
|
class SessionMenu extends SelectList {
|
|
120644
121472
|
wrap = false;
|
|
@@ -120661,11 +121489,9 @@ class SessionMenu extends SelectList {
|
|
|
120661
121489
|
onSelect: props.onSelect,
|
|
120662
121490
|
onCancel: props.onCancel,
|
|
120663
121491
|
renderItem: (s, isSelected, maxCols) => {
|
|
120664
|
-
const theme = getTheme();
|
|
120665
|
-
const selColor = themeColor2(theme.permission);
|
|
120666
121492
|
const rawTitle = s.name || s.turns?.[0]?.userPrompt || "Untitled Session";
|
|
120667
121493
|
const cleanTitle = rawTitle.replace(/\s+/g, " ").trim();
|
|
120668
|
-
const pointer = isSelected ?
|
|
121494
|
+
const pointer = isSelected ? c.selected(`${figures.pointer} `) : " ";
|
|
120669
121495
|
const shortId = s.id.slice(0, 8);
|
|
120670
121496
|
const dateStr = s.date ? s.date.split("T")[0] : "";
|
|
120671
121497
|
const turnsCount = s.turns?.length ?? 0;
|
|
@@ -120680,14 +121506,14 @@ class SessionMenu extends SelectList {
|
|
|
120680
121506
|
width: maxCols,
|
|
120681
121507
|
children: [
|
|
120682
121508
|
/* @__PURE__ */ jsx(Text, {
|
|
120683
|
-
color: isSelected ?
|
|
121509
|
+
color: isSelected ? "selected" : "text",
|
|
120684
121510
|
wrap: false,
|
|
120685
121511
|
clip: true,
|
|
120686
121512
|
ellipsis: true,
|
|
120687
121513
|
children: `${pointer}${cleanTitle}`
|
|
120688
121514
|
}),
|
|
120689
121515
|
/* @__PURE__ */ jsx(Text, {
|
|
120690
|
-
|
|
121516
|
+
color: "muted",
|
|
120691
121517
|
wrap: false,
|
|
120692
121518
|
clip: true,
|
|
120693
121519
|
ellipsis: true,
|
|
@@ -120731,18 +121557,20 @@ class ShortcutsMenu extends Component {
|
|
|
120731
121557
|
{ key: "/", desc: "Commands" },
|
|
120732
121558
|
{ key: "@", desc: "Mention files" },
|
|
120733
121559
|
{ key: "?", desc: "Shortcuts menu" },
|
|
121560
|
+
{ key: "Ctrl+B", desc: "Switch mode" },
|
|
120734
121561
|
{ key: "Esc Esc", desc: "Clear input" }
|
|
120735
121562
|
];
|
|
120736
121563
|
const rightCol = [
|
|
120737
121564
|
{ key: "Shift+Enter", desc: "Newline" },
|
|
120738
121565
|
{ key: "Ctrl+C", desc: "Abort / exit" },
|
|
120739
121566
|
{ key: "PgUp/PgDn", desc: "Scroll history" },
|
|
120740
|
-
{ key: "↑ / ↓", desc: "History navigation" }
|
|
121567
|
+
{ key: "↑ / ↓", desc: "History navigation" },
|
|
121568
|
+
{ key: "Ctrl+T", desc: "Voice dictation" }
|
|
120741
121569
|
];
|
|
120742
121570
|
const rows = leftCol.map((left, i) => {
|
|
120743
121571
|
const right = rightCol[i];
|
|
120744
|
-
const leftFormatted = ` ${
|
|
120745
|
-
const rightFormatted = `${
|
|
121572
|
+
const leftFormatted = ` ${c.text(left.key.padEnd(11))} ${c.muted(left.desc.padEnd(18))}`;
|
|
121573
|
+
const rightFormatted = `${c.text(right.key.padEnd(13))} ${c.muted(right.desc)}`;
|
|
120746
121574
|
return /* @__PURE__ */ jsxs(Box, {
|
|
120747
121575
|
direction: "row",
|
|
120748
121576
|
justify: "start",
|
|
@@ -120835,12 +121663,8 @@ class EffortPicker extends Component {
|
|
|
120835
121663
|
}
|
|
120836
121664
|
}
|
|
120837
121665
|
render(width) {
|
|
120838
|
-
const theme = getTheme();
|
|
120839
121666
|
const termWidth = width ?? process.stdout.columns ?? 80;
|
|
120840
121667
|
const maxCols = Math.max(1, termWidth);
|
|
120841
|
-
const permColor = themeColor2(theme.permission);
|
|
120842
|
-
const infoColor = themeColor2(theme.info);
|
|
120843
|
-
const trackColor = themeColor2(theme.promptBorder);
|
|
120844
121668
|
const { selectedIndex } = this.state;
|
|
120845
121669
|
const activeOption = EFFORT_OPTIONS[selectedIndex] ?? EFFORT_OPTIONS[0];
|
|
120846
121670
|
const leftPad = 4;
|
|
@@ -120850,24 +121674,23 @@ class EffortPicker extends Component {
|
|
|
120850
121674
|
const fasterText = "Faster";
|
|
120851
121675
|
const smarterText = "Smarter";
|
|
120852
121676
|
const spectrumGap = Math.max(1, totalSliderCols - (fasterText.length + smarterText.length));
|
|
120853
|
-
const spectrumRow = `${" ".repeat(leftPad)}${
|
|
120854
|
-
const yellowColor = themeColor2(theme.warning);
|
|
121677
|
+
const spectrumRow = `${" ".repeat(leftPad)}${bold(c.info(fasterText))}${" ".repeat(spectrumGap)}${bold(c.permission(smarterText))}`;
|
|
120855
121678
|
let trackChars = "";
|
|
120856
121679
|
for (let i = 0;i < EFFORT_OPTIONS.length; i++) {
|
|
120857
121680
|
const isSelected = i === selectedIndex;
|
|
120858
121681
|
const opt = EFFORT_OPTIONS[i];
|
|
120859
121682
|
const isCurrent = opt.id === this.props.currentEffort;
|
|
120860
|
-
const pointerColor = isCurrent ?
|
|
121683
|
+
const pointerColor = isCurrent ? c.current : c.permission;
|
|
120861
121684
|
const slotCenter = Math.floor(colWidth / 2);
|
|
120862
|
-
for (let
|
|
120863
|
-
if (
|
|
121685
|
+
for (let ch = 0;ch < colWidth; ch++) {
|
|
121686
|
+
if (ch === slotCenter) {
|
|
120864
121687
|
if (isSelected) {
|
|
120865
121688
|
trackChars += pointerColor(figures.sliderPointer ?? "▲");
|
|
120866
121689
|
} else {
|
|
120867
|
-
trackChars +=
|
|
121690
|
+
trackChars += c.promptBorder(figures.horizontalLine);
|
|
120868
121691
|
}
|
|
120869
121692
|
} else {
|
|
120870
|
-
trackChars +=
|
|
121693
|
+
trackChars += c.promptBorder(figures.horizontalLine);
|
|
120871
121694
|
}
|
|
120872
121695
|
}
|
|
120873
121696
|
}
|
|
@@ -120879,13 +121702,13 @@ class EffortPicker extends Component {
|
|
|
120879
121702
|
const isCurrent = opt.id === this.props.currentEffort;
|
|
120880
121703
|
let labelText = opt.label;
|
|
120881
121704
|
if (isSelected && isCurrent) {
|
|
120882
|
-
labelText =
|
|
121705
|
+
labelText = bold(c.current(labelText));
|
|
120883
121706
|
} else if (isSelected) {
|
|
120884
|
-
labelText =
|
|
121707
|
+
labelText = bold(c.permission(labelText));
|
|
120885
121708
|
} else if (isCurrent) {
|
|
120886
|
-
labelText =
|
|
121709
|
+
labelText = bold(c.current(labelText));
|
|
120887
121710
|
} else {
|
|
120888
|
-
labelText =
|
|
121711
|
+
labelText = c.text(labelText);
|
|
120889
121712
|
}
|
|
120890
121713
|
const textLen = opt.label.length;
|
|
120891
121714
|
const padLeft = Math.floor((colWidth - textLen) / 2);
|
|
@@ -120893,7 +121716,7 @@ class EffortPicker extends Component {
|
|
|
120893
121716
|
labelCols += `${" ".repeat(Math.max(0, padLeft))}${labelText}${" ".repeat(Math.max(0, padRight))}`;
|
|
120894
121717
|
}
|
|
120895
121718
|
const labelsRow = `${" ".repeat(leftPad)}${labelCols}`;
|
|
120896
|
-
const descText = ` ${
|
|
121719
|
+
const descText = ` ${bold(c.text(activeOption.description))}`;
|
|
120897
121720
|
const contentElements = [
|
|
120898
121721
|
/* @__PURE__ */ jsxs(Box, {
|
|
120899
121722
|
direction: "column",
|
|
@@ -121044,30 +121867,28 @@ class RewindMenu extends SelectList {
|
|
|
121044
121867
|
onSelect: props.onSelect,
|
|
121045
121868
|
onCancel: props.onCancel,
|
|
121046
121869
|
renderItem: (item, isSelected, maxCols) => {
|
|
121047
|
-
const
|
|
121048
|
-
const selColor = themeColor2(theme.permission);
|
|
121049
|
-
const pointer = isSelected ? selColor(`${figures.pointer} `) : " ";
|
|
121870
|
+
const pointer = isSelected ? c.selected(`${figures.pointer} `) : " ";
|
|
121050
121871
|
let summaryText;
|
|
121051
121872
|
if (item.hasCodeChanges) {
|
|
121052
|
-
const filePart =
|
|
121873
|
+
const filePart = c.muted(`${item.changedFileCount} file${item.changedFileCount !== 1 ? "s" : ""} changed`);
|
|
121053
121874
|
const diffBadges = [];
|
|
121054
121875
|
if (item.addedLines > 0) {
|
|
121055
|
-
diffBadges.push(
|
|
121876
|
+
diffBadges.push(c.diffAddFg(`+${item.addedLines}`));
|
|
121056
121877
|
}
|
|
121057
121878
|
if (item.deletedLines > 0) {
|
|
121058
|
-
diffBadges.push(
|
|
121879
|
+
diffBadges.push(c.diffDelFg(`-${item.deletedLines}`));
|
|
121059
121880
|
}
|
|
121060
121881
|
const diffStr = diffBadges.length > 0 ? ` ${diffBadges.join(" ")}` : "";
|
|
121061
121882
|
summaryText = ` ${filePart}${diffStr}`;
|
|
121062
121883
|
} else {
|
|
121063
|
-
summaryText = ` ${
|
|
121884
|
+
summaryText = ` ${c.muted("No code changes")}`;
|
|
121064
121885
|
}
|
|
121065
121886
|
return /* @__PURE__ */ jsxs(Box, {
|
|
121066
121887
|
direction: "column",
|
|
121067
121888
|
width: maxCols,
|
|
121068
121889
|
children: [
|
|
121069
121890
|
/* @__PURE__ */ jsx(Text, {
|
|
121070
|
-
color: isSelected ?
|
|
121891
|
+
color: isSelected ? "selected" : "text",
|
|
121071
121892
|
wrap: false,
|
|
121072
121893
|
clip: true,
|
|
121073
121894
|
ellipsis: true,
|
|
@@ -121168,18 +121989,14 @@ class BashPermissionDock extends Component {
|
|
|
121168
121989
|
return Math.max(0, renderedCmdLines.length - maxVisibleReviewLines);
|
|
121169
121990
|
}
|
|
121170
121991
|
render(width) {
|
|
121171
|
-
const theme = getTheme();
|
|
121172
121992
|
const termWidth = width ?? process.stdout.columns ?? 80;
|
|
121173
121993
|
const maxCols = Math.max(1, termWidth);
|
|
121174
|
-
const dividerColor = themeColor2(theme.dividerRule);
|
|
121175
|
-
const permColor = themeColor2(theme.permission);
|
|
121176
|
-
const mutedColor = themeColor2(theme.textMuted);
|
|
121177
121994
|
const { mode, selectedIndex, scrollOffset } = this.state;
|
|
121178
121995
|
const { command, explanation } = this.props;
|
|
121179
121996
|
const pointer = figures.pointerBold ?? "❯";
|
|
121180
121997
|
const isYesSelected = selectedIndex === 0;
|
|
121181
121998
|
const isNoSelected = selectedIndex === 1;
|
|
121182
|
-
const divider =
|
|
121999
|
+
const divider = c.rule(figures.horizontalLine.repeat(maxCols));
|
|
121183
122000
|
if (mode === "REVIEW") {
|
|
121184
122001
|
const cmdText = new Text(command, { wrap: true, clip: false });
|
|
121185
122002
|
const renderedCmdLines = cmdText.render(maxCols);
|
|
@@ -121207,7 +122024,7 @@ class BashPermissionDock extends Component {
|
|
|
121207
122024
|
/* @__PURE__ */ jsx(Text, {
|
|
121208
122025
|
wrap: false,
|
|
121209
122026
|
clip: false,
|
|
121210
|
-
children:
|
|
122027
|
+
children: bold(c.text("Bash command (review)"))
|
|
121211
122028
|
}),
|
|
121212
122029
|
/* @__PURE__ */ jsx(Text, {
|
|
121213
122030
|
wrap: false,
|
|
@@ -121217,7 +122034,7 @@ class BashPermissionDock extends Component {
|
|
|
121217
122034
|
visibleCmdLines.map((line) => /* @__PURE__ */ jsx(Text, {
|
|
121218
122035
|
wrap: false,
|
|
121219
122036
|
clip: false,
|
|
121220
|
-
children: ` ${
|
|
122037
|
+
children: ` ${c.text(line)}`
|
|
121221
122038
|
})),
|
|
121222
122039
|
/* @__PURE__ */ jsx(Text, {
|
|
121223
122040
|
wrap: false,
|
|
@@ -121227,7 +122044,7 @@ class BashPermissionDock extends Component {
|
|
|
121227
122044
|
/* @__PURE__ */ jsx(Text, {
|
|
121228
122045
|
wrap: false,
|
|
121229
122046
|
clip: false,
|
|
121230
|
-
children:
|
|
122047
|
+
children: italic(c.muted("↑/↓ scroll · Esc / f to return"))
|
|
121231
122048
|
})
|
|
121232
122049
|
]
|
|
121233
122050
|
});
|
|
@@ -121237,8 +122054,8 @@ class BashPermissionDock extends Component {
|
|
|
121237
122054
|
const renderedCmdLines = cmdText.render(Math.max(10, maxCols - 4));
|
|
121238
122055
|
const previewLines = renderedCmdLines.slice(0, 3);
|
|
121239
122056
|
const hiddenCount = Math.max(0, renderedCmdLines.length - 3);
|
|
121240
|
-
const yesOptionText = isYesSelected ? `${
|
|
121241
|
-
const noOptionText = isNoSelected ? `${
|
|
122057
|
+
const yesOptionText = isYesSelected ? `${c.permission(pointer)} ${bold(c.permission("1. Yes"))}` : ` ${c.text("1. Yes")}`;
|
|
122058
|
+
const noOptionText = isNoSelected ? `${c.permission(pointer)} ${bold(c.permission("2. No"))}` : ` ${c.text("2. No")}`;
|
|
121242
122059
|
const element = /* @__PURE__ */ jsxs(Box, {
|
|
121243
122060
|
direction: "column",
|
|
121244
122061
|
width: maxCols,
|
|
@@ -121258,7 +122075,7 @@ class BashPermissionDock extends Component {
|
|
|
121258
122075
|
/* @__PURE__ */ jsx(Text, {
|
|
121259
122076
|
wrap: false,
|
|
121260
122077
|
clip: false,
|
|
121261
|
-
children:
|
|
122078
|
+
children: bold(c.text("Bash command"))
|
|
121262
122079
|
}),
|
|
121263
122080
|
/* @__PURE__ */ jsx(Text, {
|
|
121264
122081
|
wrap: false,
|
|
@@ -121268,12 +122085,12 @@ class BashPermissionDock extends Component {
|
|
|
121268
122085
|
previewLines.map((line) => /* @__PURE__ */ jsx(Text, {
|
|
121269
122086
|
wrap: false,
|
|
121270
122087
|
clip: false,
|
|
121271
|
-
children: ` ${
|
|
122088
|
+
children: ` ${c.text(line)}`
|
|
121272
122089
|
})),
|
|
121273
122090
|
hiddenCount > 0 && /* @__PURE__ */ jsx(Text, {
|
|
121274
122091
|
wrap: false,
|
|
121275
122092
|
clip: false,
|
|
121276
|
-
children: ` ${
|
|
122093
|
+
children: ` ${c.muted(`(+${hiddenCount} hidden)`)}`
|
|
121277
122094
|
}),
|
|
121278
122095
|
/* @__PURE__ */ jsx(Text, {
|
|
121279
122096
|
wrap: false,
|
|
@@ -121282,7 +122099,7 @@ class BashPermissionDock extends Component {
|
|
|
121282
122099
|
}),
|
|
121283
122100
|
/* @__PURE__ */ jsx(Text, {
|
|
121284
122101
|
wrap: true,
|
|
121285
|
-
children: ` ${
|
|
122102
|
+
children: ` ${c.muted(explanation)}`
|
|
121286
122103
|
}),
|
|
121287
122104
|
/* @__PURE__ */ jsx(Text, {
|
|
121288
122105
|
wrap: false,
|
|
@@ -121292,7 +122109,7 @@ class BashPermissionDock extends Component {
|
|
|
121292
122109
|
/* @__PURE__ */ jsx(Text, {
|
|
121293
122110
|
wrap: false,
|
|
121294
122111
|
clip: false,
|
|
121295
|
-
children:
|
|
122112
|
+
children: c.text("Do you want to proceed?")
|
|
121296
122113
|
}),
|
|
121297
122114
|
/* @__PURE__ */ jsx(Text, {
|
|
121298
122115
|
wrap: false,
|
|
@@ -121317,7 +122134,7 @@ class BashPermissionDock extends Component {
|
|
|
121317
122134
|
/* @__PURE__ */ jsx(Text, {
|
|
121318
122135
|
wrap: false,
|
|
121319
122136
|
clip: false,
|
|
121320
|
-
children:
|
|
122137
|
+
children: italic(c.muted("Esc to cancel · f to review"))
|
|
121321
122138
|
})
|
|
121322
122139
|
]
|
|
121323
122140
|
});
|
|
@@ -121406,15 +122223,11 @@ class FilePermissionDock extends Component {
|
|
|
121406
122223
|
return Math.max(0, allContentRows.length - maxVisibleReviewLines);
|
|
121407
122224
|
}
|
|
121408
122225
|
renderContentRows(maxCols) {
|
|
121409
|
-
const theme = getTheme();
|
|
121410
122226
|
const { request } = this.props;
|
|
121411
122227
|
const { kind, before, after } = request;
|
|
121412
|
-
const diffAdd = themeColor2(theme.diffAddFG);
|
|
121413
|
-
const diffAddBg = themeBgColor(theme.diffAddBG);
|
|
121414
|
-
const diffDelete = themeColor2(theme.diffDeleteFG);
|
|
121415
|
-
const diffDeleteBg = themeBgColor(theme.diffDeleteBG);
|
|
121416
122228
|
if (kind === "create" || kind === "overwrite") {
|
|
121417
|
-
const
|
|
122229
|
+
const highlighted = highlightCode(after, { filePath: request.filePath });
|
|
122230
|
+
const rawLines = highlighted.split(/\r?\n/);
|
|
121418
122231
|
const lines = after === "" ? [] : rawLines;
|
|
121419
122232
|
const maxLineNum = Math.max(1, lines.length);
|
|
121420
122233
|
const gutterWidth = Math.max(2, String(maxLineNum).length);
|
|
@@ -121422,9 +122235,9 @@ class FilePermissionDock extends Component {
|
|
|
121422
122235
|
for (let i = 0;i < lines.length; i++) {
|
|
121423
122236
|
const lineNum = i + 1;
|
|
121424
122237
|
const lineNumStr = String(lineNum).padStart(gutterWidth, " ");
|
|
121425
|
-
const firstPrefix = ` ${
|
|
122238
|
+
const firstPrefix = ` ${c.muted(lineNumStr)} `;
|
|
121426
122239
|
const contPrefix = ` ${" ".repeat(gutterWidth)} `;
|
|
121427
|
-
const wrapped = prefixedBlock(firstPrefix,
|
|
122240
|
+
const wrapped = prefixedBlock(firstPrefix, lines[i] ?? "", {
|
|
121428
122241
|
continuationPrefix: contPrefix,
|
|
121429
122242
|
width: maxCols
|
|
121430
122243
|
});
|
|
@@ -121448,32 +122261,33 @@ class FilePermissionDock extends Component {
|
|
|
121448
122261
|
for (const line of hunk.lines) {
|
|
121449
122262
|
if (line.kind === "deletion") {
|
|
121450
122263
|
const numStr = String(line.oldLineNumber ?? "").padStart(gutterWidth, " ");
|
|
121451
|
-
const firstPrefix = ` ${
|
|
122264
|
+
const firstPrefix = ` ${c.muted(numStr)} `;
|
|
121452
122265
|
const contPrefix = ` ${" ".repeat(gutterWidth)} `;
|
|
121453
|
-
const bodyText = line.spans ?
|
|
122266
|
+
const bodyText = line.spans ? c.diffDelFg("-") + line.spans.map((s) => s.kind === "deletion" ? bold(c.diffDelFg(s.text)) : c.diffDelFg(s.text)).join("") : c.diffDelFg(`-${line.text}`);
|
|
121454
122267
|
const wrapped = prefixedBlock(firstPrefix, bodyText, {
|
|
121455
122268
|
continuationPrefix: contPrefix,
|
|
121456
122269
|
width: maxCols,
|
|
121457
|
-
bg:
|
|
122270
|
+
bg: bg.diffDelBg
|
|
121458
122271
|
});
|
|
121459
122272
|
renderedRows.push(...wrapped);
|
|
121460
122273
|
} else if (line.kind === "addition") {
|
|
121461
122274
|
const numStr = String(line.newLineNumber ?? "").padStart(gutterWidth, " ");
|
|
121462
|
-
const firstPrefix = ` ${
|
|
122275
|
+
const firstPrefix = ` ${c.muted(numStr)} `;
|
|
121463
122276
|
const contPrefix = ` ${" ".repeat(gutterWidth)} `;
|
|
121464
|
-
const bodyText = line.spans ?
|
|
122277
|
+
const bodyText = line.spans ? c.diffAddFg("+") + line.spans.map((s) => s.kind === "addition" ? bold(c.diffAddFg(s.text)) : c.diffAddFg(s.text)).join("") : c.diffAddFg(`+${line.text}`);
|
|
121465
122278
|
const wrapped = prefixedBlock(firstPrefix, bodyText, {
|
|
121466
122279
|
continuationPrefix: contPrefix,
|
|
121467
122280
|
width: maxCols,
|
|
121468
|
-
bg: diffAddBg
|
|
122281
|
+
bg: bg.diffAddBg
|
|
121469
122282
|
});
|
|
121470
122283
|
renderedRows.push(...wrapped);
|
|
121471
122284
|
} else {
|
|
121472
122285
|
const lineNum = line.newLineNumber ?? line.oldLineNumber ?? "";
|
|
121473
122286
|
const numStr = String(lineNum).padStart(gutterWidth, " ");
|
|
121474
|
-
const firstPrefix = ` ${
|
|
122287
|
+
const firstPrefix = ` ${c.muted(numStr)} `;
|
|
121475
122288
|
const contPrefix = ` ${" ".repeat(gutterWidth)} `;
|
|
121476
|
-
const
|
|
122289
|
+
const highlightedLine = highlightCode(line.text, { filePath: request.filePath });
|
|
122290
|
+
const wrapped = prefixedBlock(firstPrefix, highlightedLine, {
|
|
121477
122291
|
continuationPrefix: contPrefix,
|
|
121478
122292
|
width: maxCols
|
|
121479
122293
|
});
|
|
@@ -121484,19 +122298,15 @@ class FilePermissionDock extends Component {
|
|
|
121484
122298
|
return renderedRows;
|
|
121485
122299
|
}
|
|
121486
122300
|
render(width) {
|
|
121487
|
-
const theme = getTheme();
|
|
121488
122301
|
const termWidth = width ?? process.stdout.columns ?? 80;
|
|
121489
122302
|
const maxCols = Math.max(1, termWidth);
|
|
121490
|
-
const dividerColor = themeColor2(theme.dividerRule);
|
|
121491
|
-
const permColor = themeColor2(theme.permission);
|
|
121492
|
-
const mutedColor = themeColor2(theme.textMuted);
|
|
121493
122303
|
const { mode, selectedIndex, scrollOffset } = this.state;
|
|
121494
122304
|
const { request } = this.props;
|
|
121495
122305
|
const { kind, filePath } = request;
|
|
121496
122306
|
const pointer = figures.pointerBold ?? "❯";
|
|
121497
122307
|
const isYesSelected = selectedIndex === 0;
|
|
121498
122308
|
const isNoSelected = selectedIndex === 1;
|
|
121499
|
-
const divider =
|
|
122309
|
+
const divider = c.rule(figures.horizontalLine.repeat(maxCols));
|
|
121500
122310
|
let title = "Edit file";
|
|
121501
122311
|
let question = `Do you want to make this edit to ${filePath}?`;
|
|
121502
122312
|
if (kind === "create") {
|
|
@@ -121532,12 +122342,12 @@ class FilePermissionDock extends Component {
|
|
|
121532
122342
|
/* @__PURE__ */ jsx(Text, {
|
|
121533
122343
|
wrap: false,
|
|
121534
122344
|
clip: false,
|
|
121535
|
-
children:
|
|
122345
|
+
children: bold(c.text(`${title} (review)`))
|
|
121536
122346
|
}),
|
|
121537
122347
|
/* @__PURE__ */ jsx(Text, {
|
|
121538
122348
|
wrap: false,
|
|
121539
122349
|
clip: false,
|
|
121540
|
-
children: ` ${
|
|
122350
|
+
children: ` ${c.muted(filePath)}`
|
|
121541
122351
|
}),
|
|
121542
122352
|
/* @__PURE__ */ jsx(Text, {
|
|
121543
122353
|
wrap: false,
|
|
@@ -121557,7 +122367,7 @@ class FilePermissionDock extends Component {
|
|
|
121557
122367
|
/* @__PURE__ */ jsx(Text, {
|
|
121558
122368
|
wrap: false,
|
|
121559
122369
|
clip: false,
|
|
121560
|
-
children:
|
|
122370
|
+
children: italic(c.muted("↑/↓ scroll · Esc / f to return"))
|
|
121561
122371
|
})
|
|
121562
122372
|
]
|
|
121563
122373
|
});
|
|
@@ -121565,8 +122375,8 @@ class FilePermissionDock extends Component {
|
|
|
121565
122375
|
}
|
|
121566
122376
|
const previewRows = allContentRows.slice(0, 10);
|
|
121567
122377
|
const hiddenCount = Math.max(0, allContentRows.length - 10);
|
|
121568
|
-
const yesOptionText = isYesSelected ? `${
|
|
121569
|
-
const noOptionText = isNoSelected ? `${
|
|
122378
|
+
const yesOptionText = isYesSelected ? `${c.permission(pointer)} ${bold(c.permission("1. Yes"))}` : ` ${c.text("1. Yes")}`;
|
|
122379
|
+
const noOptionText = isNoSelected ? `${c.permission(pointer)} ${bold(c.permission("2. No"))}` : ` ${c.text("2. No")}`;
|
|
121570
122380
|
const element = /* @__PURE__ */ jsxs(Box, {
|
|
121571
122381
|
direction: "column",
|
|
121572
122382
|
width: maxCols,
|
|
@@ -121586,12 +122396,12 @@ class FilePermissionDock extends Component {
|
|
|
121586
122396
|
/* @__PURE__ */ jsx(Text, {
|
|
121587
122397
|
wrap: false,
|
|
121588
122398
|
clip: false,
|
|
121589
|
-
children:
|
|
122399
|
+
children: bold(c.text(title))
|
|
121590
122400
|
}),
|
|
121591
122401
|
/* @__PURE__ */ jsx(Text, {
|
|
121592
122402
|
wrap: false,
|
|
121593
122403
|
clip: false,
|
|
121594
|
-
children: ` ${
|
|
122404
|
+
children: ` ${c.muted(filePath)}`
|
|
121595
122405
|
}),
|
|
121596
122406
|
/* @__PURE__ */ jsx(Text, {
|
|
121597
122407
|
wrap: false,
|
|
@@ -121606,7 +122416,7 @@ class FilePermissionDock extends Component {
|
|
|
121606
122416
|
hiddenCount > 0 && /* @__PURE__ */ jsx(Text, {
|
|
121607
122417
|
wrap: false,
|
|
121608
122418
|
clip: false,
|
|
121609
|
-
children: ` ${
|
|
122419
|
+
children: ` ${c.muted(`(+${hiddenCount} hidden)`)}`
|
|
121610
122420
|
}),
|
|
121611
122421
|
/* @__PURE__ */ jsx(Text, {
|
|
121612
122422
|
wrap: false,
|
|
@@ -121616,7 +122426,7 @@ class FilePermissionDock extends Component {
|
|
|
121616
122426
|
/* @__PURE__ */ jsx(Text, {
|
|
121617
122427
|
wrap: false,
|
|
121618
122428
|
clip: false,
|
|
121619
|
-
children:
|
|
122429
|
+
children: c.text(question)
|
|
121620
122430
|
}),
|
|
121621
122431
|
/* @__PURE__ */ jsx(Text, {
|
|
121622
122432
|
wrap: false,
|
|
@@ -121641,7 +122451,7 @@ class FilePermissionDock extends Component {
|
|
|
121641
122451
|
/* @__PURE__ */ jsx(Text, {
|
|
121642
122452
|
wrap: false,
|
|
121643
122453
|
clip: false,
|
|
121644
|
-
children:
|
|
122454
|
+
children: italic(c.muted("Esc to cancel · f to review"))
|
|
121645
122455
|
})
|
|
121646
122456
|
]
|
|
121647
122457
|
});
|
|
@@ -121780,6 +122590,67 @@ class PermissionQueue {
|
|
|
121780
122590
|
}
|
|
121781
122591
|
}
|
|
121782
122592
|
}
|
|
122593
|
+
|
|
122594
|
+
// src/tui/utils/transcript.ts
|
|
122595
|
+
function formatTurnFooter(engine, turnPresentationEnd) {
|
|
122596
|
+
if (!turnPresentationEnd)
|
|
122597
|
+
return;
|
|
122598
|
+
if (turnPresentationEnd.status === "complete") {
|
|
122599
|
+
engine.commit("system", [
|
|
122600
|
+
"",
|
|
122601
|
+
formatTurnStatus(turnPresentationEnd.durationMs, new Date(turnPresentationEnd.finishedAt), turnPresentationEnd.statusVerb)
|
|
122602
|
+
]);
|
|
122603
|
+
if (turnPresentationEnd.stopReason === "step-limit") {
|
|
122604
|
+
engine.commit("system", formatSystemMessage("Step budget reached. Generation stopped early."));
|
|
122605
|
+
}
|
|
122606
|
+
} else if ((turnPresentationEnd.status === "errored" || turnPresentationEnd.status === "interrupted") && turnPresentationEnd.errorMessage) {
|
|
122607
|
+
const structured = classifyError(new Error(turnPresentationEnd.errorMessage));
|
|
122608
|
+
engine.commit("system", formatErrorBadge(structured));
|
|
122609
|
+
}
|
|
122610
|
+
}
|
|
122611
|
+
function renderTranscript(engine, sessionData, header) {
|
|
122612
|
+
engine.clearAll();
|
|
122613
|
+
engine.commit("header", header.render());
|
|
122614
|
+
const log = loadSessionLog(sessionData.date, sessionData.id);
|
|
122615
|
+
const projection = log ? buildSessionPresentationProjection(log.events) : null;
|
|
122616
|
+
const items = rehydrateSessionHistory(sessionData, projection);
|
|
122617
|
+
let currentTurnId = undefined;
|
|
122618
|
+
for (const item of items) {
|
|
122619
|
+
if (item.turnId && item.turnId !== currentTurnId) {
|
|
122620
|
+
if (currentTurnId && projection) {
|
|
122621
|
+
const prevTurnPresentation = projection.turns.get(currentTurnId)?.end;
|
|
122622
|
+
formatTurnFooter(engine, prevTurnPresentation);
|
|
122623
|
+
}
|
|
122624
|
+
currentTurnId = item.turnId;
|
|
122625
|
+
}
|
|
122626
|
+
if (item.type === "user") {
|
|
122627
|
+
engine.commitPrompt(item.content);
|
|
122628
|
+
} else if (item.type === "system") {
|
|
122629
|
+
engine.commit("system", formatSystemMessage(item.content));
|
|
122630
|
+
} else if (item.type === "tool" && item.toolData) {
|
|
122631
|
+
const toolData = item.toolData;
|
|
122632
|
+
engine.commit("tool-result", (w) => formatToolStatus({
|
|
122633
|
+
toolName: toolData.toolName,
|
|
122634
|
+
displayName: toolData.displayName,
|
|
122635
|
+
icon: toolData.icon,
|
|
122636
|
+
argsSummary: toolData.argsSummary,
|
|
122637
|
+
status: toolData.status,
|
|
122638
|
+
durationMs: toolData.durationMs,
|
|
122639
|
+
error: toolData.error,
|
|
122640
|
+
toolOutput: toolData.toolOutput,
|
|
122641
|
+
targetWidth: w
|
|
122642
|
+
}), { hangingIndent: 2 });
|
|
122643
|
+
} else if (item.type === "assistant") {
|
|
122644
|
+
engine.commit("assistant-message", formatAssistantMessage(item.content), {
|
|
122645
|
+
hangingIndent: 2
|
|
122646
|
+
});
|
|
122647
|
+
}
|
|
122648
|
+
}
|
|
122649
|
+
if (currentTurnId && projection) {
|
|
122650
|
+
const lastTurnPresentation = projection.turns.get(currentTurnId)?.end;
|
|
122651
|
+
formatTurnFooter(engine, lastTurnPresentation);
|
|
122652
|
+
}
|
|
122653
|
+
}
|
|
121783
122654
|
// src/voice/model.ts
|
|
121784
122655
|
var VOICE_MODEL_ID = "gemini-3.5-transcribe-live";
|
|
121785
122656
|
// src/voice/errors.ts
|
|
@@ -121878,7 +122749,7 @@ async function defaultCheckParec() {
|
|
|
121878
122749
|
}
|
|
121879
122750
|
async function checkVoicePrerequisites(options = {}) {
|
|
121880
122751
|
const config = options.config ?? getEnvConfig();
|
|
121881
|
-
const checkRecorder = options.checkParecFn ??
|
|
122752
|
+
const checkRecorder = options.checkParecFn ?? defaultCheckParec;
|
|
121882
122753
|
const hasGemini = hasProviderConfig("gemini", config);
|
|
121883
122754
|
const geminiApiKey = config.geminiApiKey;
|
|
121884
122755
|
if (!hasGemini || !geminiApiKey) {
|
|
@@ -122835,7 +123706,6 @@ class TUIApp {
|
|
|
122835
123706
|
});
|
|
122836
123707
|
this.statusBar = new StatusBar({
|
|
122837
123708
|
model,
|
|
122838
|
-
usage: this.session.session.totalUsage,
|
|
122839
123709
|
isBusy: false
|
|
122840
123710
|
});
|
|
122841
123711
|
this.voiceController = new VoiceController({
|
|
@@ -123020,6 +123890,18 @@ class TUIApp {
|
|
|
123020
123890
|
}, 1500);
|
|
123021
123891
|
return true;
|
|
123022
123892
|
}
|
|
123893
|
+
if (action.type === "ctrl-b") {
|
|
123894
|
+
if (this.activeModal)
|
|
123895
|
+
return true;
|
|
123896
|
+
if (this.session.isBusy || this.isBusy) {
|
|
123897
|
+
this.statusBar.showWarning("Cannot change mode while Steward is generating");
|
|
123898
|
+
return true;
|
|
123899
|
+
}
|
|
123900
|
+
const newMode = cycleMode();
|
|
123901
|
+
saveModeSelection(newMode);
|
|
123902
|
+
this.statusBar.setMode(newMode);
|
|
123903
|
+
return true;
|
|
123904
|
+
}
|
|
123023
123905
|
if (action.type === "ctrl-t") {
|
|
123024
123906
|
if (this.activeModal) {
|
|
123025
123907
|
return true;
|
|
@@ -123095,76 +123977,41 @@ class TUIApp {
|
|
|
123095
123977
|
this.engine.mount(picker, { kind: "dock" });
|
|
123096
123978
|
this.engine.mount(this.statusBar);
|
|
123097
123979
|
}
|
|
123980
|
+
openThemePicker(themes) {
|
|
123981
|
+
if (this.activeModal)
|
|
123982
|
+
this.closeModal();
|
|
123983
|
+
this.engine.unmount(this.promptInput);
|
|
123984
|
+
this.engine.unmount(this.statusBar);
|
|
123985
|
+
const currentTheme = getActiveThemeName();
|
|
123986
|
+
const picker = new ThemePicker({
|
|
123987
|
+
themes,
|
|
123988
|
+
currentTheme,
|
|
123989
|
+
onSelect: (selected) => {
|
|
123990
|
+
setActiveTheme(selected.name);
|
|
123991
|
+
saveThemeSelection(selected.name);
|
|
123992
|
+
renderTranscript(this.engine, this.session.session, this.header);
|
|
123993
|
+
this.engine.mount(this.streamingView);
|
|
123994
|
+
this.engine.mount(this.promptInput, { keepCursorVisible: true, kind: "input" });
|
|
123995
|
+
this.engine.mount(this.statusBar);
|
|
123996
|
+
this.engine.requestFrame(true);
|
|
123997
|
+
this.engine.commit("system", formatSystemMessage(`Theme switched to ${selected.label}.`));
|
|
123998
|
+
this.closeModal();
|
|
123999
|
+
},
|
|
124000
|
+
onCancel: () => this.closeModal()
|
|
124001
|
+
});
|
|
124002
|
+
this.activeModal = picker;
|
|
124003
|
+
this.engine.mount(picker, { kind: "dock" });
|
|
124004
|
+
this.engine.mount(this.statusBar);
|
|
124005
|
+
}
|
|
123098
124006
|
switchToSession(selected) {
|
|
123099
124007
|
this.permissionQueue.clear();
|
|
124008
|
+
recoverPendingCheckpoint(this.cwd, selected.id).catch(() => {});
|
|
123100
124009
|
this.session.shutdown().catch(() => {});
|
|
123101
124010
|
this.session = AgentSession.resume(selected);
|
|
123102
124011
|
const model = this.session.getModel();
|
|
123103
124012
|
this.header.props.model = model;
|
|
123104
|
-
this.statusBar.update({ model
|
|
123105
|
-
this.engine.
|
|
123106
|
-
this.engine.commit("header", this.header.render());
|
|
123107
|
-
const log = loadSessionLog(selected.date, selected.id);
|
|
123108
|
-
const projection = log ? buildSessionPresentationProjection(log.events) : null;
|
|
123109
|
-
const items = rehydrateSessionHistory(selected, projection);
|
|
123110
|
-
let currentTurnId = undefined;
|
|
123111
|
-
for (const item of items) {
|
|
123112
|
-
if (item.turnId && item.turnId !== currentTurnId) {
|
|
123113
|
-
if (currentTurnId && projection) {
|
|
123114
|
-
const prevTurnPresentation = projection.turns.get(currentTurnId)?.end;
|
|
123115
|
-
if (prevTurnPresentation && prevTurnPresentation.status === "complete") {
|
|
123116
|
-
this.engine.commit("system", [
|
|
123117
|
-
"",
|
|
123118
|
-
formatTurnStatus(prevTurnPresentation.durationMs, new Date(prevTurnPresentation.finishedAt), prevTurnPresentation.statusVerb)
|
|
123119
|
-
]);
|
|
123120
|
-
if (prevTurnPresentation.stopReason === "step-limit") {
|
|
123121
|
-
this.engine.commit("system", formatSystemMessage("Step budget reached. Generation stopped early."));
|
|
123122
|
-
}
|
|
123123
|
-
} else if (prevTurnPresentation && (prevTurnPresentation.status === "errored" || prevTurnPresentation.status === "interrupted") && prevTurnPresentation.errorMessage) {
|
|
123124
|
-
const structured = classifyError(new Error(prevTurnPresentation.errorMessage));
|
|
123125
|
-
this.engine.commit("system", formatErrorBadge(structured));
|
|
123126
|
-
}
|
|
123127
|
-
}
|
|
123128
|
-
currentTurnId = item.turnId;
|
|
123129
|
-
}
|
|
123130
|
-
if (item.type === "user") {
|
|
123131
|
-
this.engine.commitPrompt(item.content);
|
|
123132
|
-
} else if (item.type === "system") {
|
|
123133
|
-
this.engine.commit("system", formatSystemMessage(item.content));
|
|
123134
|
-
} else if (item.type === "tool" && item.toolData) {
|
|
123135
|
-
const toolData = item.toolData;
|
|
123136
|
-
this.engine.commit("tool-result", (w) => formatToolStatus({
|
|
123137
|
-
toolName: toolData.toolName,
|
|
123138
|
-
displayName: toolData.displayName,
|
|
123139
|
-
icon: toolData.icon,
|
|
123140
|
-
argsSummary: toolData.argsSummary,
|
|
123141
|
-
status: toolData.status,
|
|
123142
|
-
durationMs: toolData.durationMs,
|
|
123143
|
-
error: toolData.error,
|
|
123144
|
-
toolOutput: toolData.toolOutput,
|
|
123145
|
-
targetWidth: w
|
|
123146
|
-
}), { hangingIndent: 2 });
|
|
123147
|
-
} else if (item.type === "assistant") {
|
|
123148
|
-
this.engine.commit("assistant-message", formatAssistantMessage(item.content), {
|
|
123149
|
-
hangingIndent: 2
|
|
123150
|
-
});
|
|
123151
|
-
}
|
|
123152
|
-
}
|
|
123153
|
-
if (currentTurnId && projection) {
|
|
123154
|
-
const lastTurnPresentation = projection.turns.get(currentTurnId)?.end;
|
|
123155
|
-
if (lastTurnPresentation && lastTurnPresentation.status === "complete") {
|
|
123156
|
-
this.engine.commit("system", [
|
|
123157
|
-
"",
|
|
123158
|
-
formatTurnStatus(lastTurnPresentation.durationMs, new Date(lastTurnPresentation.finishedAt), lastTurnPresentation.statusVerb)
|
|
123159
|
-
]);
|
|
123160
|
-
if (lastTurnPresentation.stopReason === "step-limit") {
|
|
123161
|
-
this.engine.commit("system", formatSystemMessage("Step budget reached. Generation stopped early."));
|
|
123162
|
-
}
|
|
123163
|
-
} else if (lastTurnPresentation && (lastTurnPresentation.status === "errored" || lastTurnPresentation.status === "interrupted") && lastTurnPresentation.errorMessage) {
|
|
123164
|
-
const structured = classifyError(new Error(lastTurnPresentation.errorMessage));
|
|
123165
|
-
this.engine.commit("system", formatErrorBadge(structured));
|
|
123166
|
-
}
|
|
123167
|
-
}
|
|
124013
|
+
this.statusBar.update({ model });
|
|
124014
|
+
renderTranscript(this.engine, selected, this.header);
|
|
123168
124015
|
this.engine.mount(this.streamingView);
|
|
123169
124016
|
this.engine.mount(this.promptInput, { keepCursorVisible: true, kind: "input" });
|
|
123170
124017
|
this.engine.mount(this.statusBar);
|
|
@@ -123273,6 +124120,18 @@ class TUIApp {
|
|
|
123273
124120
|
this.openModelPicker(cmdResult.data.models ?? []);
|
|
123274
124121
|
return;
|
|
123275
124122
|
}
|
|
124123
|
+
if (cmdResult.data?.showThemePicker) {
|
|
124124
|
+
this.openThemePicker(cmdResult.data.themes ?? listThemes());
|
|
124125
|
+
return;
|
|
124126
|
+
}
|
|
124127
|
+
if (cmdResult.data?.themeSwitched) {
|
|
124128
|
+
for (const comp of this.engine.components)
|
|
124129
|
+
comp.markDirty();
|
|
124130
|
+
this.engine.requestFrame(true);
|
|
124131
|
+
}
|
|
124132
|
+
if (cmdResult.data?.modeSwitched && cmdResult.data?.selectedMode) {
|
|
124133
|
+
this.statusBar.setMode(cmdResult.data.selectedMode.name);
|
|
124134
|
+
}
|
|
123276
124135
|
if (cmdResult.data?.showEffortPicker) {
|
|
123277
124136
|
this.openEffortPicker();
|
|
123278
124137
|
return;
|
|
@@ -123293,8 +124152,7 @@ class TUIApp {
|
|
|
123293
124152
|
const updatedModel = this.session.getModel();
|
|
123294
124153
|
this.header.props.model = updatedModel;
|
|
123295
124154
|
this.statusBar.update({
|
|
123296
|
-
model: updatedModel
|
|
123297
|
-
usage: this.session.session.totalUsage
|
|
124155
|
+
model: updatedModel
|
|
123298
124156
|
});
|
|
123299
124157
|
return;
|
|
123300
124158
|
}
|
|
@@ -123350,7 +124208,7 @@ class TUIApp {
|
|
|
123350
124208
|
const argsSummary = JSON.stringify(event.toolResult.args);
|
|
123351
124209
|
const status = event.toolResult.isError ? "failed" : "completed";
|
|
123352
124210
|
const error = event.toolResult.isError ? typeof event.toolResult.result === "object" && event.toolResult.result !== null ? event.toolResult.result.message ?? JSON.stringify(event.toolResult.result) : String(event.toolResult.result) : undefined;
|
|
123353
|
-
const
|
|
124211
|
+
const summary = summarizeToolResult(toolDef, event.toolResult.args, event.toolResult.result, event.toolResult.isError);
|
|
123354
124212
|
this.engine.commit("tool-result", (w) => formatToolStatus({
|
|
123355
124213
|
toolName,
|
|
123356
124214
|
displayName,
|
|
@@ -123359,7 +124217,7 @@ class TUIApp {
|
|
|
123359
124217
|
status,
|
|
123360
124218
|
durationMs,
|
|
123361
124219
|
error,
|
|
123362
|
-
|
|
124220
|
+
summary,
|
|
123363
124221
|
targetWidth: w
|
|
123364
124222
|
}), { hangingIndent: 2 });
|
|
123365
124223
|
this.streamingView.setThinking(true);
|
|
@@ -123381,9 +124239,6 @@ class TUIApp {
|
|
|
123381
124239
|
"",
|
|
123382
124240
|
formatTurnStatus(totalDurationMs, finishedAt, event.summary.statusVerb)
|
|
123383
124241
|
]);
|
|
123384
|
-
this.statusBar.update({
|
|
123385
|
-
usage: this.session.session.totalUsage
|
|
123386
|
-
});
|
|
123387
124242
|
if (event.summary.stopReason === "step-limit") {
|
|
123388
124243
|
this.engine.commit("system", formatSystemMessage("Step budget reached. Generation stopped early."));
|
|
123389
124244
|
}
|
|
@@ -123413,9 +124268,6 @@ class TUIApp {
|
|
|
123413
124268
|
this.closeModal();
|
|
123414
124269
|
}
|
|
123415
124270
|
this.setBusy(false);
|
|
123416
|
-
this.statusBar.update({
|
|
123417
|
-
usage: this.session.session.totalUsage
|
|
123418
|
-
});
|
|
123419
124271
|
}
|
|
123420
124272
|
}
|
|
123421
124273
|
setBusy(busy) {
|
|
@@ -123469,10 +124321,35 @@ function parseCliArgs(args) {
|
|
|
123469
124321
|
rawArgs: args
|
|
123470
124322
|
};
|
|
123471
124323
|
}
|
|
124324
|
+
if (target === "theme" || target === "ui.theme" || target === "ui-theme" || target === "color") {
|
|
124325
|
+
const value = subArgs.slice(1).join(" ").trim() || undefined;
|
|
124326
|
+
return {
|
|
124327
|
+
command: "config",
|
|
124328
|
+
configArgs: { target: "theme", value },
|
|
124329
|
+
rawArgs: args
|
|
124330
|
+
};
|
|
124331
|
+
}
|
|
124332
|
+
if (target === "model" || target === "ai.model" || target === "ai-model") {
|
|
124333
|
+
const value = subArgs.slice(1).join(" ").trim() || undefined;
|
|
124334
|
+
return {
|
|
124335
|
+
command: "config",
|
|
124336
|
+
configArgs: { target: "model", value },
|
|
124337
|
+
rawArgs: args
|
|
124338
|
+
};
|
|
124339
|
+
}
|
|
124340
|
+
if (target === "mode" || target === "ui.mode" || target === "ui-mode") {
|
|
124341
|
+
const value = subArgs.slice(1).join(" ").trim() || undefined;
|
|
124342
|
+
return {
|
|
124343
|
+
command: "config",
|
|
124344
|
+
configArgs: { target: "mode", value },
|
|
124345
|
+
rawArgs: args
|
|
124346
|
+
};
|
|
124347
|
+
}
|
|
123472
124348
|
console.error(`Error: Unknown configuration target "${target}".
|
|
123473
124349
|
` + `Usage:
|
|
123474
|
-
` + ` steward --config
|
|
123475
|
-
` + ` steward --config voice <lang>
|
|
124350
|
+
` + ` steward --config View all current configurations
|
|
124351
|
+
` + ` steward --config voice <lang> Configure preferred voice language
|
|
124352
|
+
` + ` steward --config theme <name> Configure UI color theme`);
|
|
123476
124353
|
process.exit(1);
|
|
123477
124354
|
}
|
|
123478
124355
|
const unrecognized = args[0];
|
|
@@ -123566,9 +124443,13 @@ function handleConfigCommand(configArgs) {
|
|
|
123566
124443
|
const voiceDisplay = voiceLang ? `${getLanguageDisplayName(voiceLang)} (${voiceLang})` : "auto-detect (default)";
|
|
123567
124444
|
const savedModel = getSavedModel();
|
|
123568
124445
|
const modelDisplay = savedModel ? `${savedModel.provider}:${savedModel.modelId} (effort: ${savedModel.effort ?? "provider-default"})` : "not configured (using environment priority)";
|
|
124446
|
+
const savedTheme = getSavedTheme() ?? "dark (default)";
|
|
124447
|
+
const savedMode = getSavedMode() ?? "normal (default)";
|
|
123569
124448
|
console.log(`Steward Configuration (${settingsPath}):`);
|
|
124449
|
+
console.log(` UI Theme: ${savedTheme}`);
|
|
123570
124450
|
console.log(` Voice Language: ${voiceDisplay}`);
|
|
123571
124451
|
console.log(` Saved Model: ${modelDisplay}`);
|
|
124452
|
+
console.log(` Chat Mode: ${savedMode}`);
|
|
123572
124453
|
process.exit(0);
|
|
123573
124454
|
}
|
|
123574
124455
|
if (configArgs.target === "voice") {
|
|
@@ -123601,6 +124482,48 @@ function handleConfigCommand(configArgs) {
|
|
|
123601
124482
|
console.log(`✓ Voice language configured: ${resolved.name} (${resolved.tag})`);
|
|
123602
124483
|
process.exit(0);
|
|
123603
124484
|
}
|
|
124485
|
+
if (configArgs.target === "mode") {
|
|
124486
|
+
const rawMode = configArgs.value?.trim();
|
|
124487
|
+
const allModes = listModes();
|
|
124488
|
+
if (!rawMode) {
|
|
124489
|
+
const current = getSavedMode() ?? "normal";
|
|
124490
|
+
const currentMeta = findMode(current);
|
|
124491
|
+
console.log(`Current chat mode: ${currentMeta?.label ?? current} (${current})`);
|
|
124492
|
+
process.exit(0);
|
|
124493
|
+
}
|
|
124494
|
+
const matched = findMode(rawMode);
|
|
124495
|
+
if (!matched) {
|
|
124496
|
+
console.error(`Error: Unknown mode "${rawMode}".
|
|
124497
|
+
` + `Available modes:
|
|
124498
|
+
` + allModes.map((m) => ` steward --config mode ${m.name.padEnd(10)} (${m.label})`).join(`
|
|
124499
|
+
`));
|
|
124500
|
+
process.exit(1);
|
|
124501
|
+
}
|
|
124502
|
+
saveModeSelection(matched.name);
|
|
124503
|
+
console.log(`✓ Chat mode configured: ${matched.label} (${matched.name})`);
|
|
124504
|
+
process.exit(0);
|
|
124505
|
+
}
|
|
124506
|
+
if (configArgs.target === "theme") {
|
|
124507
|
+
const rawTheme = configArgs.value?.trim();
|
|
124508
|
+
const allThemes = listThemes();
|
|
124509
|
+
if (!rawTheme) {
|
|
124510
|
+
const current = getSavedTheme() ?? "dark";
|
|
124511
|
+
const currentMeta = findTheme(current);
|
|
124512
|
+
console.log(`Current UI theme: ${currentMeta?.label ?? current} (${current})`);
|
|
124513
|
+
process.exit(0);
|
|
124514
|
+
}
|
|
124515
|
+
const matched = findTheme(rawTheme);
|
|
124516
|
+
if (!matched) {
|
|
124517
|
+
console.error(`Error: Unknown theme "${rawTheme}".
|
|
124518
|
+
` + `Available themes:
|
|
124519
|
+
` + allThemes.map((t) => ` steward --config theme ${t.name.padEnd(18)} (${t.label})`).join(`
|
|
124520
|
+
`));
|
|
124521
|
+
process.exit(1);
|
|
124522
|
+
}
|
|
124523
|
+
saveThemeSelection(matched.name);
|
|
124524
|
+
console.log(`✓ UI theme configured: ${matched.label} (${matched.name})`);
|
|
124525
|
+
process.exit(0);
|
|
124526
|
+
}
|
|
123604
124527
|
}
|
|
123605
124528
|
|
|
123606
124529
|
// src/cli/commands/version/index.ts
|
|
@@ -123654,6 +124577,8 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
123654
124577
|
return;
|
|
123655
124578
|
}
|
|
123656
124579
|
try {
|
|
124580
|
+
setActiveTheme(getSavedTheme() ?? "dark");
|
|
124581
|
+
setActiveMode(getSavedMode() ?? "normal");
|
|
123657
124582
|
const session = new AgentSession;
|
|
123658
124583
|
const app = new TUIApp({
|
|
123659
124584
|
version: VERSION16,
|