lupacode 0.2.4 → 1.0.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/dist/index.js +1450 -497
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -70792,9 +70792,6 @@ var SplitBorderChars = {
|
|
|
70792
70792
|
|
|
70793
70793
|
// src/providers/theme/index.tsx
|
|
70794
70794
|
var import_react18 = __toESM(require_react(), 1);
|
|
70795
|
-
import { mkdirSync, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
70796
|
-
import { homedir } from "os";
|
|
70797
|
-
import { join as join2 } from "path";
|
|
70798
70795
|
|
|
70799
70796
|
// src/theme.ts
|
|
70800
70797
|
var THEMES = [
|
|
@@ -70804,7 +70801,7 @@ var THEMES = [
|
|
|
70804
70801
|
primary: "#719cd6",
|
|
70805
70802
|
planMode: "#db9b59",
|
|
70806
70803
|
selectMode: "#b55c7a",
|
|
70807
|
-
thinking: "#
|
|
70804
|
+
thinking: "#9DDAF6",
|
|
70808
70805
|
success: "#81b29a",
|
|
70809
70806
|
error: "#c94f6d",
|
|
70810
70807
|
info: "#7dcfff",
|
|
@@ -70923,7 +70920,7 @@ var THEMES = [
|
|
|
70923
70920
|
primary: "#C4A7E7",
|
|
70924
70921
|
planMode: "#F6C177",
|
|
70925
70922
|
selectMode: "#9CCFD8",
|
|
70926
|
-
thinking: "#
|
|
70923
|
+
thinking: "#9CCFD8",
|
|
70927
70924
|
success: "#9CCFD8",
|
|
70928
70925
|
error: "#EB6F92",
|
|
70929
70926
|
info: "#C4A7E7",
|
|
@@ -71035,343 +71032,354 @@ var THEMES = [
|
|
|
71035
71032
|
thinkingBorder: "#22DA6E",
|
|
71036
71033
|
dimSeparator: "#5F7E97"
|
|
71037
71034
|
}
|
|
71038
|
-
}
|
|
71039
|
-
|
|
71040
|
-
|
|
71041
|
-
|
|
71042
|
-
|
|
71043
|
-
|
|
71044
|
-
|
|
71045
|
-
|
|
71046
|
-
|
|
71047
|
-
|
|
71048
|
-
|
|
71049
|
-
|
|
71050
|
-
|
|
71051
|
-
|
|
71052
|
-
|
|
71053
|
-
|
|
71054
|
-
return DEFAULT_THEME;
|
|
71055
|
-
}
|
|
71056
|
-
}
|
|
71057
|
-
function persistTheme(theme) {
|
|
71058
|
-
try {
|
|
71059
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
71060
|
-
writeFileSync2(THEME_PREFERENCES_PATH, JSON.stringify({ themeName: theme.name }, null, 2), "utf8");
|
|
71061
|
-
} catch {}
|
|
71062
|
-
}
|
|
71063
|
-
var ThemeContext = import_react18.createContext(null);
|
|
71064
|
-
function useTheme() {
|
|
71065
|
-
const value = import_react18.useContext(ThemeContext);
|
|
71066
|
-
if (!value) {
|
|
71067
|
-
throw new Error("useTheme must be used within a ThemeProvider");
|
|
71068
|
-
}
|
|
71069
|
-
return value;
|
|
71070
|
-
}
|
|
71071
|
-
function ThemeProvider({ children }) {
|
|
71072
|
-
const [currentTheme, setCurrentTheme] = import_react18.useState(getInitialTheme);
|
|
71073
|
-
const setTheme = import_react18.useCallback((theme) => {
|
|
71074
|
-
setCurrentTheme(theme);
|
|
71075
|
-
persistTheme(theme);
|
|
71076
|
-
}, []);
|
|
71077
|
-
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ThemeContext.Provider, {
|
|
71078
|
-
value: { colors: currentTheme.colors, currentTheme, setTheme },
|
|
71079
|
-
children
|
|
71080
|
-
}, undefined, false, undefined, this);
|
|
71081
|
-
}
|
|
71082
|
-
|
|
71083
|
-
// src/providers/toast/index.tsx
|
|
71084
|
-
var ToastContext = import_react19.createContext(null);
|
|
71085
|
-
function useToast() {
|
|
71086
|
-
const value = import_react19.useContext(ToastContext);
|
|
71087
|
-
if (!value) {
|
|
71088
|
-
throw new Error("useToast must be used within a ToastProvider");
|
|
71089
|
-
}
|
|
71090
|
-
return value;
|
|
71091
|
-
}
|
|
71092
|
-
function ToastProvider({ children }) {
|
|
71093
|
-
const [currentToast, setCurrentToast] = import_react19.useState(null);
|
|
71094
|
-
const timeoutHandleRef = import_react19.useRef(null);
|
|
71095
|
-
const clearCurrentTimeout = import_react19.useCallback(() => {
|
|
71096
|
-
if (timeoutHandleRef.current) {
|
|
71097
|
-
clearTimeout(timeoutHandleRef.current);
|
|
71098
|
-
timeoutHandleRef.current = null;
|
|
71035
|
+
},
|
|
71036
|
+
{
|
|
71037
|
+
name: "Everforest Dark",
|
|
71038
|
+
colors: {
|
|
71039
|
+
primary: "#7FBBB3",
|
|
71040
|
+
planMode: "#DBBC7F",
|
|
71041
|
+
selectMode: "#D699B6",
|
|
71042
|
+
thinking: "#A7C080",
|
|
71043
|
+
success: "#A7C080",
|
|
71044
|
+
error: "#E67E80",
|
|
71045
|
+
info: "#83C092",
|
|
71046
|
+
background: "#2D353B",
|
|
71047
|
+
surface: "#343F44",
|
|
71048
|
+
dialogSurface: "#3D484D",
|
|
71049
|
+
thinkingBorder: "#A7C080",
|
|
71050
|
+
dimSeparator: "#4F585E"
|
|
71099
71051
|
}
|
|
71100
|
-
},
|
|
71101
|
-
|
|
71102
|
-
|
|
71103
|
-
|
|
71104
|
-
|
|
71105
|
-
|
|
71106
|
-
|
|
71107
|
-
|
|
71108
|
-
|
|
71109
|
-
|
|
71110
|
-
|
|
71111
|
-
|
|
71112
|
-
|
|
71113
|
-
|
|
71114
|
-
|
|
71115
|
-
|
|
71116
|
-
children: [
|
|
71117
|
-
children,
|
|
71118
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(Toast, {
|
|
71119
|
-
currentToast
|
|
71120
|
-
}, undefined, false, undefined, this)
|
|
71121
|
-
]
|
|
71122
|
-
}, undefined, true, undefined, this);
|
|
71123
|
-
}
|
|
71124
|
-
function Toast({ currentToast }) {
|
|
71125
|
-
const { width } = useTerminalDimensions();
|
|
71126
|
-
const { colors } = useTheme();
|
|
71127
|
-
if (!currentToast) {
|
|
71128
|
-
return null;
|
|
71129
|
-
}
|
|
71130
|
-
const variantColors = {
|
|
71131
|
-
success: colors.success,
|
|
71132
|
-
error: colors.error,
|
|
71133
|
-
info: colors.info
|
|
71134
|
-
};
|
|
71135
|
-
const borderColor = currentToast.variant ? variantColors[currentToast.variant] : variantColors.info;
|
|
71136
|
-
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
71137
|
-
position: "absolute",
|
|
71138
|
-
justifyContent: "center",
|
|
71139
|
-
alignItems: "flex-start",
|
|
71140
|
-
top: 2,
|
|
71141
|
-
right: 2,
|
|
71142
|
-
width: Math.max(1, Math.min(60, width - 6)),
|
|
71143
|
-
paddingLeft: 2,
|
|
71144
|
-
paddingRight: 2,
|
|
71145
|
-
paddingTop: 1,
|
|
71146
|
-
paddingBottom: 1,
|
|
71147
|
-
backgroundColor: colors.surface,
|
|
71148
|
-
borderColor,
|
|
71149
|
-
border: ["left", "right"],
|
|
71150
|
-
customBorderChars: SplitBorderChars,
|
|
71151
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
71152
|
-
flexDirection: "column",
|
|
71153
|
-
gap: 1,
|
|
71154
|
-
width: "100%",
|
|
71155
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
71156
|
-
fg: "#E1E1E1",
|
|
71157
|
-
wrapMode: "word",
|
|
71158
|
-
width: "100%",
|
|
71159
|
-
children: currentToast.message
|
|
71160
|
-
}, undefined, false, undefined, this)
|
|
71161
|
-
}, undefined, false, undefined, this)
|
|
71162
|
-
}, undefined, false, undefined, this);
|
|
71163
|
-
}
|
|
71164
|
-
|
|
71165
|
-
// src/providers/dialog/index.tsx
|
|
71166
|
-
var import_react24 = __toESM(require_react(), 1);
|
|
71167
|
-
|
|
71168
|
-
// src/providers/keyboard-layer/index.tsx
|
|
71169
|
-
var import_react21 = __toESM(require_react(), 1);
|
|
71170
|
-
var KeyboardLayerContext = import_react21.createContext(null);
|
|
71171
|
-
function KeyboardLayerProvider({ children }) {
|
|
71172
|
-
const [stack, setStack] = import_react21.useState(["base"]);
|
|
71173
|
-
const stackRef = import_react21.useRef(stack);
|
|
71174
|
-
stackRef.current = stack;
|
|
71175
|
-
const responders = import_react21.useRef(new Map);
|
|
71176
|
-
const renderer = useRenderer();
|
|
71177
|
-
const push = import_react21.useCallback((id, responder) => {
|
|
71178
|
-
if (responder) {
|
|
71179
|
-
responders.current.set(id, responder);
|
|
71052
|
+
},
|
|
71053
|
+
{
|
|
71054
|
+
name: "Kanagawa Wave",
|
|
71055
|
+
colors: {
|
|
71056
|
+
primary: "#7E9CD8",
|
|
71057
|
+
planMode: "#E6C384",
|
|
71058
|
+
selectMode: "#957FB8",
|
|
71059
|
+
thinking: "#98BB6C",
|
|
71060
|
+
success: "#98BB6C",
|
|
71061
|
+
error: "#E46876",
|
|
71062
|
+
info: "#7FB4CA",
|
|
71063
|
+
background: "#1F1F28",
|
|
71064
|
+
surface: "#2A2A37",
|
|
71065
|
+
dialogSurface: "#363646",
|
|
71066
|
+
thinkingBorder: "#98BB6C",
|
|
71067
|
+
dimSeparator: "#54546D"
|
|
71180
71068
|
}
|
|
71181
|
-
|
|
71182
|
-
|
|
71183
|
-
|
|
71184
|
-
|
|
71185
|
-
|
|
71186
|
-
|
|
71187
|
-
|
|
71188
|
-
|
|
71189
|
-
|
|
71190
|
-
|
|
71191
|
-
|
|
71192
|
-
|
|
71193
|
-
|
|
71194
|
-
|
|
71195
|
-
|
|
71196
|
-
|
|
71197
|
-
responders.current.set(id, responder);
|
|
71198
|
-
} else {
|
|
71199
|
-
responders.current.delete(id);
|
|
71069
|
+
},
|
|
71070
|
+
{
|
|
71071
|
+
name: "Monokai Pro",
|
|
71072
|
+
colors: {
|
|
71073
|
+
primary: "#78DCE8",
|
|
71074
|
+
planMode: "#FFD866",
|
|
71075
|
+
selectMode: "#AB9DF2",
|
|
71076
|
+
thinking: "#A9DC76",
|
|
71077
|
+
success: "#A9DC76",
|
|
71078
|
+
error: "#FF6188",
|
|
71079
|
+
info: "#78DCE8",
|
|
71080
|
+
background: "#2D2A2E",
|
|
71081
|
+
surface: "#36333A",
|
|
71082
|
+
dialogSurface: "#403E41",
|
|
71083
|
+
thinkingBorder: "#A9DC76",
|
|
71084
|
+
dimSeparator: "#727072"
|
|
71200
71085
|
}
|
|
71201
|
-
},
|
|
71202
|
-
|
|
71203
|
-
|
|
71204
|
-
|
|
71205
|
-
|
|
71206
|
-
|
|
71207
|
-
|
|
71208
|
-
|
|
71209
|
-
|
|
71210
|
-
|
|
71211
|
-
|
|
71086
|
+
},
|
|
71087
|
+
{
|
|
71088
|
+
name: "Material Theme",
|
|
71089
|
+
colors: {
|
|
71090
|
+
primary: "#82AAFF",
|
|
71091
|
+
planMode: "#FFCB6B",
|
|
71092
|
+
selectMode: "#C792EA",
|
|
71093
|
+
thinking: "#C3E88D",
|
|
71094
|
+
success: "#C3E88D",
|
|
71095
|
+
error: "#F07178",
|
|
71096
|
+
info: "#89DDFF",
|
|
71097
|
+
background: "#263238",
|
|
71098
|
+
surface: "#2F3B43",
|
|
71099
|
+
dialogSurface: "#37474F",
|
|
71100
|
+
thinkingBorder: "#C3E88D",
|
|
71101
|
+
dimSeparator: "#546E7A"
|
|
71212
71102
|
}
|
|
71213
|
-
|
|
71214
|
-
|
|
71215
|
-
|
|
71216
|
-
|
|
71217
|
-
|
|
71218
|
-
|
|
71219
|
-
|
|
71220
|
-
|
|
71221
|
-
|
|
71222
|
-
|
|
71223
|
-
|
|
71224
|
-
|
|
71225
|
-
|
|
71226
|
-
|
|
71227
|
-
|
|
71228
|
-
|
|
71229
|
-
var import_react23 = __toESM(require_react(), 1);
|
|
71230
|
-
class ErrorBoundary2 extends import_react23.Component {
|
|
71231
|
-
constructor(props) {
|
|
71232
|
-
super(props);
|
|
71233
|
-
this.state = { error: null };
|
|
71234
|
-
}
|
|
71235
|
-
static getDerivedStateFromError(error) {
|
|
71236
|
-
return { error };
|
|
71237
|
-
}
|
|
71238
|
-
componentDidCatch(error, errorInfo) {
|
|
71239
|
-
console.error("[ErrorBoundary] Caught error:", error, errorInfo.componentStack);
|
|
71240
|
-
}
|
|
71241
|
-
render() {
|
|
71242
|
-
if (this.state.error) {
|
|
71243
|
-
console.error("[ErrorBoundary] Rendering fallback for:", this.state.error.message);
|
|
71244
|
-
return this.props.fallback ?? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
71245
|
-
flexDirection: "column",
|
|
71246
|
-
padding: 1,
|
|
71247
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
71248
|
-
children: [
|
|
71249
|
-
"Error: ",
|
|
71250
|
-
this.state.error.message
|
|
71251
|
-
]
|
|
71252
|
-
}, undefined, true, undefined, this)
|
|
71253
|
-
}, undefined, false, undefined, this);
|
|
71103
|
+
},
|
|
71104
|
+
{
|
|
71105
|
+
name: "Rose Pine Moon",
|
|
71106
|
+
colors: {
|
|
71107
|
+
primary: "#C4A7E7",
|
|
71108
|
+
planMode: "#F6C177",
|
|
71109
|
+
selectMode: "#9CCFD8",
|
|
71110
|
+
thinking: "#31748F",
|
|
71111
|
+
success: "#9CCFD8",
|
|
71112
|
+
error: "#EB6F92",
|
|
71113
|
+
info: "#C4A7E7",
|
|
71114
|
+
background: "#232136",
|
|
71115
|
+
surface: "#2A273F",
|
|
71116
|
+
dialogSurface: "#393552",
|
|
71117
|
+
thinkingBorder: "#31748F",
|
|
71118
|
+
dimSeparator: "#59546D"
|
|
71254
71119
|
}
|
|
71255
|
-
|
|
71256
|
-
|
|
71257
|
-
|
|
71258
|
-
|
|
71259
|
-
|
|
71260
|
-
|
|
71261
|
-
|
|
71262
|
-
|
|
71263
|
-
|
|
71264
|
-
|
|
71265
|
-
|
|
71266
|
-
|
|
71267
|
-
|
|
71268
|
-
|
|
71269
|
-
|
|
71270
|
-
|
|
71271
|
-
|
|
71272
|
-
|
|
71273
|
-
|
|
71274
|
-
|
|
71275
|
-
|
|
71276
|
-
|
|
71277
|
-
|
|
71278
|
-
|
|
71279
|
-
|
|
71280
|
-
|
|
71281
|
-
|
|
71282
|
-
|
|
71283
|
-
|
|
71284
|
-
|
|
71285
|
-
|
|
71286
|
-
|
|
71287
|
-
|
|
71288
|
-
|
|
71289
|
-
|
|
71290
|
-
|
|
71291
|
-
|
|
71292
|
-
|
|
71293
|
-
|
|
71294
|
-
|
|
71295
|
-
|
|
71296
|
-
|
|
71297
|
-
|
|
71298
|
-
|
|
71299
|
-
|
|
71300
|
-
|
|
71301
|
-
|
|
71302
|
-
|
|
71303
|
-
|
|
71304
|
-
|
|
71305
|
-
|
|
71120
|
+
},
|
|
71121
|
+
{
|
|
71122
|
+
name: "GitHub Dark",
|
|
71123
|
+
colors: {
|
|
71124
|
+
primary: "#58A6FF",
|
|
71125
|
+
planMode: "#E3B341",
|
|
71126
|
+
selectMode: "#A371F7",
|
|
71127
|
+
thinking: "#3FB950",
|
|
71128
|
+
success: "#3FB950",
|
|
71129
|
+
error: "#F85149",
|
|
71130
|
+
info: "#79C0FF",
|
|
71131
|
+
background: "#0D1117",
|
|
71132
|
+
surface: "#161B22",
|
|
71133
|
+
dialogSurface: "#21262D",
|
|
71134
|
+
thinkingBorder: "#3FB950",
|
|
71135
|
+
dimSeparator: "#30363D"
|
|
71136
|
+
}
|
|
71137
|
+
},
|
|
71138
|
+
{
|
|
71139
|
+
name: "SynthWave '84",
|
|
71140
|
+
colors: {
|
|
71141
|
+
primary: "#36F9F6",
|
|
71142
|
+
planMode: "#FFE347",
|
|
71143
|
+
selectMode: "#FF7EDB",
|
|
71144
|
+
thinking: "#72F1B8",
|
|
71145
|
+
success: "#72F1B8",
|
|
71146
|
+
error: "#FE4450",
|
|
71147
|
+
info: "#36F9F6",
|
|
71148
|
+
background: "#262335",
|
|
71149
|
+
surface: "#34294F",
|
|
71150
|
+
dialogSurface: "#433C68",
|
|
71151
|
+
thinkingBorder: "#72F1B8",
|
|
71152
|
+
dimSeparator: "#5B5478"
|
|
71153
|
+
}
|
|
71154
|
+
},
|
|
71155
|
+
{
|
|
71156
|
+
name: "Horizon",
|
|
71157
|
+
colors: {
|
|
71158
|
+
primary: "#26BBD9",
|
|
71159
|
+
planMode: "#FAC29A",
|
|
71160
|
+
selectMode: "#EE64AC",
|
|
71161
|
+
thinking: "#29D398",
|
|
71162
|
+
success: "#29D398",
|
|
71163
|
+
error: "#E95678",
|
|
71164
|
+
info: "#59E3E3",
|
|
71165
|
+
background: "#1C1E26",
|
|
71166
|
+
surface: "#232530",
|
|
71167
|
+
dialogSurface: "#2E303E",
|
|
71168
|
+
thinkingBorder: "#29D398",
|
|
71169
|
+
dimSeparator: "#6C6F93"
|
|
71170
|
+
}
|
|
71171
|
+
},
|
|
71172
|
+
{
|
|
71173
|
+
name: "Arctic Ice",
|
|
71174
|
+
colors: {
|
|
71175
|
+
primary: "#88C0D0",
|
|
71176
|
+
planMode: "#EBCB8B",
|
|
71177
|
+
selectMode: "#81A1C1",
|
|
71178
|
+
thinking: "#A3BE8C",
|
|
71179
|
+
success: "#A3BE8C",
|
|
71180
|
+
error: "#BF616A",
|
|
71181
|
+
info: "#5E81AC",
|
|
71182
|
+
background: "#242933",
|
|
71183
|
+
surface: "#2E3440",
|
|
71184
|
+
dialogSurface: "#3B4252",
|
|
71185
|
+
thinkingBorder: "#A3BE8C",
|
|
71186
|
+
dimSeparator: "#4C566A"
|
|
71187
|
+
}
|
|
71188
|
+
},
|
|
71189
|
+
{
|
|
71190
|
+
name: "Midnight Purple",
|
|
71191
|
+
colors: {
|
|
71192
|
+
primary: "#9D7DFF",
|
|
71193
|
+
planMode: "#F8C555",
|
|
71194
|
+
selectMode: "#B388FF",
|
|
71195
|
+
thinking: "#43D787",
|
|
71196
|
+
success: "#43D787",
|
|
71197
|
+
error: "#FF5D73",
|
|
71198
|
+
info: "#59C8FF",
|
|
71199
|
+
background: "#11111B",
|
|
71200
|
+
surface: "#1B1B2A",
|
|
71201
|
+
dialogSurface: "#25253A",
|
|
71202
|
+
thinkingBorder: "#43D787",
|
|
71203
|
+
dimSeparator: "#47475A"
|
|
71204
|
+
}
|
|
71205
|
+
},
|
|
71206
|
+
{
|
|
71207
|
+
name: "Poimandres",
|
|
71208
|
+
colors: {
|
|
71209
|
+
primary: "#89DDFF",
|
|
71210
|
+
planMode: "#FFE66D",
|
|
71211
|
+
selectMode: "#C792EA",
|
|
71212
|
+
thinking: "#5DE4C7",
|
|
71213
|
+
success: "#5DE4C7",
|
|
71214
|
+
error: "#D0679D",
|
|
71215
|
+
info: "#91B4D5",
|
|
71216
|
+
background: "#1B1E28",
|
|
71217
|
+
surface: "#222635",
|
|
71218
|
+
dialogSurface: "#2A3042",
|
|
71219
|
+
thinkingBorder: "#5DE4C7",
|
|
71220
|
+
dimSeparator: "#4F5B76"
|
|
71221
|
+
}
|
|
71222
|
+
},
|
|
71223
|
+
{
|
|
71224
|
+
name: "Vesper",
|
|
71225
|
+
colors: {
|
|
71226
|
+
primary: "#99FFE4",
|
|
71227
|
+
planMode: "#FFC799",
|
|
71228
|
+
selectMode: "#FCA7EA",
|
|
71229
|
+
thinking: "#A1EFD3",
|
|
71230
|
+
success: "#A1EFD3",
|
|
71231
|
+
error: "#F07178",
|
|
71232
|
+
info: "#8BD5FF",
|
|
71233
|
+
background: "#101010",
|
|
71234
|
+
surface: "#181818",
|
|
71235
|
+
dialogSurface: "#222222",
|
|
71236
|
+
thinkingBorder: "#A1EFD3",
|
|
71237
|
+
dimSeparator: "#3B3B3B"
|
|
71238
|
+
}
|
|
71239
|
+
},
|
|
71240
|
+
{
|
|
71241
|
+
name: "Oxocarbon",
|
|
71242
|
+
colors: {
|
|
71243
|
+
primary: "#78A9FF",
|
|
71244
|
+
planMode: "#FF7EB6",
|
|
71245
|
+
selectMode: "#BE95FF",
|
|
71246
|
+
thinking: "#42BE65",
|
|
71247
|
+
success: "#42BE65",
|
|
71248
|
+
error: "#EE5396",
|
|
71249
|
+
info: "#33B1FF",
|
|
71250
|
+
background: "#161616",
|
|
71251
|
+
surface: "#262626",
|
|
71252
|
+
dialogSurface: "#393939",
|
|
71253
|
+
thinkingBorder: "#42BE65",
|
|
71254
|
+
dimSeparator: "#525252"
|
|
71255
|
+
}
|
|
71256
|
+
},
|
|
71257
|
+
{
|
|
71258
|
+
name: "Flexoki Dark",
|
|
71259
|
+
colors: {
|
|
71260
|
+
primary: "#4385BE",
|
|
71261
|
+
planMode: "#DA702C",
|
|
71262
|
+
selectMode: "#8B7EC8",
|
|
71263
|
+
thinking: "#879A39",
|
|
71264
|
+
success: "#879A39",
|
|
71265
|
+
error: "#D14D41",
|
|
71266
|
+
info: "#3AA99F",
|
|
71267
|
+
background: "#100F0F",
|
|
71268
|
+
surface: "#1C1B1A",
|
|
71269
|
+
dialogSurface: "#282726",
|
|
71270
|
+
thinkingBorder: "#879A39",
|
|
71271
|
+
dimSeparator: "#575653"
|
|
71272
|
+
}
|
|
71273
|
+
},
|
|
71274
|
+
{
|
|
71275
|
+
name: "Dark Plus",
|
|
71276
|
+
colors: {
|
|
71277
|
+
primary: "#569CD6",
|
|
71278
|
+
planMode: "#DCDCAA",
|
|
71279
|
+
selectMode: "#C586C0",
|
|
71280
|
+
thinking: "#6A9955",
|
|
71281
|
+
success: "#6A9955",
|
|
71282
|
+
error: "#F44747",
|
|
71283
|
+
info: "#4FC1FF",
|
|
71284
|
+
background: "#1E1E1E",
|
|
71285
|
+
surface: "#252526",
|
|
71286
|
+
dialogSurface: "#2D2D30",
|
|
71287
|
+
thinkingBorder: "#6A9955",
|
|
71288
|
+
dimSeparator: "#3E3E42"
|
|
71289
|
+
}
|
|
71290
|
+
},
|
|
71291
|
+
{
|
|
71292
|
+
name: "Dark Modern",
|
|
71293
|
+
colors: {
|
|
71294
|
+
primary: "#4FC1FF",
|
|
71295
|
+
planMode: "#E5C07B",
|
|
71296
|
+
selectMode: "#C678DD",
|
|
71297
|
+
thinking: "#7EE787",
|
|
71298
|
+
success: "#7EE787",
|
|
71299
|
+
error: "#FF7B72",
|
|
71300
|
+
info: "#79C0FF",
|
|
71301
|
+
background: "#181818",
|
|
71302
|
+
surface: "#212121",
|
|
71303
|
+
dialogSurface: "#2B2B2B",
|
|
71304
|
+
thinkingBorder: "#7EE787",
|
|
71305
|
+
dimSeparator: "#444444"
|
|
71306
|
+
}
|
|
71307
|
+
},
|
|
71308
|
+
{
|
|
71309
|
+
name: "Dark+ (Default Dark)",
|
|
71310
|
+
colors: {
|
|
71311
|
+
primary: "#569CD6",
|
|
71312
|
+
planMode: "#DCDCAA",
|
|
71313
|
+
selectMode: "#C586C0",
|
|
71314
|
+
thinking: "#6A9955",
|
|
71315
|
+
success: "#6A9955",
|
|
71316
|
+
error: "#F44747",
|
|
71317
|
+
info: "#4FC1FF",
|
|
71318
|
+
background: "#1E1E1E",
|
|
71319
|
+
surface: "#252526",
|
|
71320
|
+
dialogSurface: "#2D2D30",
|
|
71321
|
+
thinkingBorder: "#6A9955",
|
|
71322
|
+
dimSeparator: "#3E3E42"
|
|
71323
|
+
}
|
|
71324
|
+
},
|
|
71325
|
+
{
|
|
71326
|
+
name: "Dark Modern",
|
|
71327
|
+
colors: {
|
|
71328
|
+
primary: "#75BEFF",
|
|
71329
|
+
planMode: "#E5C07B",
|
|
71330
|
+
selectMode: "#D2A8FF",
|
|
71331
|
+
thinking: "#7EE787",
|
|
71332
|
+
success: "#7EE787",
|
|
71333
|
+
error: "#FF7B72",
|
|
71334
|
+
info: "#79C0FF",
|
|
71335
|
+
background: "#181818",
|
|
71336
|
+
surface: "#202020",
|
|
71337
|
+
dialogSurface: "#2A2A2A",
|
|
71338
|
+
thinkingBorder: "#7EE787",
|
|
71339
|
+
dimSeparator: "#3F3F46"
|
|
71340
|
+
}
|
|
71341
|
+
},
|
|
71342
|
+
{
|
|
71343
|
+
name: "High Contrast Dark",
|
|
71344
|
+
colors: {
|
|
71345
|
+
primary: "#3B8EEA",
|
|
71346
|
+
planMode: "#FFCC00",
|
|
71347
|
+
selectMode: "#B180D7",
|
|
71348
|
+
thinking: "#89D185",
|
|
71349
|
+
success: "#89D185",
|
|
71350
|
+
error: "#F14C4C",
|
|
71351
|
+
info: "#75BEFF",
|
|
71352
|
+
background: "#000000",
|
|
71353
|
+
surface: "#0F0F0F",
|
|
71354
|
+
dialogSurface: "#1A1A1A",
|
|
71355
|
+
thinkingBorder: "#89D185",
|
|
71356
|
+
dimSeparator: "#6B6B6B"
|
|
71357
|
+
}
|
|
71358
|
+
},
|
|
71359
|
+
{
|
|
71360
|
+
name: "High Contrast Black",
|
|
71361
|
+
colors: {
|
|
71362
|
+
primary: "#3794FF",
|
|
71363
|
+
planMode: "#FFD700",
|
|
71364
|
+
selectMode: "#C586C0",
|
|
71365
|
+
thinking: "#00FF00",
|
|
71366
|
+
success: "#00FF00",
|
|
71367
|
+
error: "#FF5555",
|
|
71368
|
+
info: "#4FC1FF",
|
|
71369
|
+
background: "#000000",
|
|
71370
|
+
surface: "#111111",
|
|
71371
|
+
dialogSurface: "#1C1C1C",
|
|
71372
|
+
thinkingBorder: "#00FF00",
|
|
71373
|
+
dimSeparator: "#666666"
|
|
71306
71374
|
}
|
|
71307
|
-
});
|
|
71308
|
-
if (!currentDialog) {
|
|
71309
|
-
return null;
|
|
71310
71375
|
}
|
|
71311
|
-
|
|
71312
|
-
|
|
71313
|
-
position: "absolute",
|
|
71314
|
-
left: 0,
|
|
71315
|
-
top: 0,
|
|
71316
|
-
width: dimensions.width,
|
|
71317
|
-
height: dimensions.height,
|
|
71318
|
-
justifyContent: "center",
|
|
71319
|
-
alignItems: "center",
|
|
71320
|
-
backgroundColor: RGBA.fromInts(0, 0, 0, 150),
|
|
71321
|
-
zIndex: 100,
|
|
71322
|
-
onMouseDown: () => close(),
|
|
71323
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
71324
|
-
width: Math.min(60, dimensions.width - 4),
|
|
71325
|
-
height: "auto",
|
|
71326
|
-
backgroundColor: colors.dialogSurface,
|
|
71327
|
-
paddingX: 4,
|
|
71328
|
-
paddingY: 1,
|
|
71329
|
-
flexDirection: "column",
|
|
71330
|
-
gap: 1,
|
|
71331
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
71332
|
-
children: [
|
|
71333
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
71334
|
-
paddingBottom: 1,
|
|
71335
|
-
flexDirection: "row",
|
|
71336
|
-
alignItems: "center",
|
|
71337
|
-
justifyContent: "space-between",
|
|
71338
|
-
children: [
|
|
71339
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
71340
|
-
attributes: TextAttributes.BOLD,
|
|
71341
|
-
children: title
|
|
71342
|
-
}, undefined, false, undefined, this),
|
|
71343
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
71344
|
-
attributes: TextAttributes.DIM,
|
|
71345
|
-
onMouseDown: () => close(),
|
|
71346
|
-
children: "esc"
|
|
71347
|
-
}, undefined, false, undefined, this)
|
|
71348
|
-
]
|
|
71349
|
-
}, undefined, true, undefined, this),
|
|
71350
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
71351
|
-
flexGrow: 1,
|
|
71352
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
|
|
71353
|
-
children
|
|
71354
|
-
}, undefined, false, undefined, this)
|
|
71355
|
-
}, undefined, false, undefined, this)
|
|
71356
|
-
]
|
|
71357
|
-
}, undefined, true, undefined, this)
|
|
71358
|
-
}, undefined, false, undefined, this);
|
|
71359
|
-
}
|
|
71360
|
-
|
|
71361
|
-
// src/layouts/themed-root.tsx
|
|
71362
|
-
function ThemedRoot({ children }) {
|
|
71363
|
-
const { colors } = useTheme();
|
|
71364
|
-
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
71365
|
-
backgroundColor: colors.background,
|
|
71366
|
-
width: "100%",
|
|
71367
|
-
height: "100%",
|
|
71368
|
-
flexGrow: 1,
|
|
71369
|
-
children
|
|
71370
|
-
}, undefined, false, undefined, this);
|
|
71371
|
-
}
|
|
71376
|
+
];
|
|
71377
|
+
var DEFAULT_THEME = THEMES.find((t2) => t2.name === "Nightfox");
|
|
71372
71378
|
|
|
71373
|
-
// src/
|
|
71374
|
-
|
|
71379
|
+
// src/lib/config.ts
|
|
71380
|
+
import { mkdirSync, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
71381
|
+
import { homedir } from "os";
|
|
71382
|
+
import { join as join2 } from "path";
|
|
71375
71383
|
|
|
71376
71384
|
// ../../node_modules/zod/v4/classic/external.js
|
|
71377
71385
|
var exports_external = {};
|
|
@@ -93565,7 +93573,360 @@ function findDomain(id) {
|
|
|
93565
93573
|
return DOMAINS.find((d2) => d2.id === id);
|
|
93566
93574
|
}
|
|
93567
93575
|
var DEFAULT_DOMAIN_ID = "coding";
|
|
93576
|
+
// src/lib/config.ts
|
|
93577
|
+
var CONFIG_DIR = join2(homedir(), ".lupacode");
|
|
93578
|
+
var CONFIG_PATH = join2(CONFIG_DIR, "preferences.json");
|
|
93579
|
+
var DEFAULTS = {
|
|
93580
|
+
themeName: "Nightfox",
|
|
93581
|
+
mode: Mode.BUILD,
|
|
93582
|
+
model: DEFAULT_CHAT_MODEL_ID,
|
|
93583
|
+
domain: DEFAULT_DOMAIN_ID
|
|
93584
|
+
};
|
|
93585
|
+
function ensureDir() {
|
|
93586
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
93587
|
+
}
|
|
93588
|
+
function readPreferences() {
|
|
93589
|
+
try {
|
|
93590
|
+
return JSON.parse(readFileSync(CONFIG_PATH, "utf8"));
|
|
93591
|
+
} catch {
|
|
93592
|
+
return {};
|
|
93593
|
+
}
|
|
93594
|
+
}
|
|
93595
|
+
function writePreferences(prefs) {
|
|
93596
|
+
try {
|
|
93597
|
+
const current = readPreferences();
|
|
93598
|
+
ensureDir();
|
|
93599
|
+
writeFileSync2(CONFIG_PATH, JSON.stringify({ ...current, ...prefs }, null, 2), "utf8");
|
|
93600
|
+
} catch {}
|
|
93601
|
+
}
|
|
93602
|
+
|
|
93603
|
+
// ../../node_modules/@opentui/react/jsx-dev-runtime.js
|
|
93604
|
+
var import_jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
|
|
93605
|
+
|
|
93606
|
+
// src/providers/theme/index.tsx
|
|
93607
|
+
function getInitialTheme() {
|
|
93608
|
+
const prefs = readPreferences();
|
|
93609
|
+
const savedTheme = typeof prefs.themeName === "string" ? THEMES.find((t2) => t2.name === prefs.themeName) : undefined;
|
|
93610
|
+
return savedTheme ?? DEFAULT_THEME;
|
|
93611
|
+
}
|
|
93612
|
+
function persistTheme(theme) {
|
|
93613
|
+
writePreferences({ themeName: theme.name });
|
|
93614
|
+
}
|
|
93615
|
+
var ThemeContext = import_react18.createContext(null);
|
|
93616
|
+
function useTheme() {
|
|
93617
|
+
const value = import_react18.useContext(ThemeContext);
|
|
93618
|
+
if (!value) {
|
|
93619
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
93620
|
+
}
|
|
93621
|
+
return value;
|
|
93622
|
+
}
|
|
93623
|
+
function ThemeProvider({ children }) {
|
|
93624
|
+
const [currentTheme, setCurrentTheme] = import_react18.useState(getInitialTheme);
|
|
93625
|
+
const setTheme = import_react18.useCallback((theme) => {
|
|
93626
|
+
setCurrentTheme(theme);
|
|
93627
|
+
persistTheme(theme);
|
|
93628
|
+
}, []);
|
|
93629
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ThemeContext.Provider, {
|
|
93630
|
+
value: { colors: currentTheme.colors, currentTheme, setTheme },
|
|
93631
|
+
children
|
|
93632
|
+
}, undefined, false, undefined, this);
|
|
93633
|
+
}
|
|
93634
|
+
|
|
93635
|
+
// src/providers/toast/index.tsx
|
|
93636
|
+
var ToastContext = import_react19.createContext(null);
|
|
93637
|
+
function useToast() {
|
|
93638
|
+
const value = import_react19.useContext(ToastContext);
|
|
93639
|
+
if (!value) {
|
|
93640
|
+
throw new Error("useToast must be used within a ToastProvider");
|
|
93641
|
+
}
|
|
93642
|
+
return value;
|
|
93643
|
+
}
|
|
93644
|
+
function ToastProvider({ children }) {
|
|
93645
|
+
const [currentToast, setCurrentToast] = import_react19.useState(null);
|
|
93646
|
+
const timeoutHandleRef = import_react19.useRef(null);
|
|
93647
|
+
const clearCurrentTimeout = import_react19.useCallback(() => {
|
|
93648
|
+
if (timeoutHandleRef.current) {
|
|
93649
|
+
clearTimeout(timeoutHandleRef.current);
|
|
93650
|
+
timeoutHandleRef.current = null;
|
|
93651
|
+
}
|
|
93652
|
+
}, []);
|
|
93653
|
+
const show = import_react19.useCallback((options) => {
|
|
93654
|
+
const duration3 = options.duration ?? DEFAULT_DURATION;
|
|
93655
|
+
clearCurrentTimeout();
|
|
93656
|
+
setCurrentToast({
|
|
93657
|
+
variant: options.variant ?? "info",
|
|
93658
|
+
...options,
|
|
93659
|
+
duration: duration3
|
|
93660
|
+
});
|
|
93661
|
+
timeoutHandleRef.current = setTimeout(() => {
|
|
93662
|
+
setCurrentToast(null);
|
|
93663
|
+
}, duration3).unref();
|
|
93664
|
+
}, [clearCurrentTimeout]);
|
|
93665
|
+
const value = import_react19.useMemo(() => ({ show }), [show]);
|
|
93666
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContext.Provider, {
|
|
93667
|
+
value,
|
|
93668
|
+
children: [
|
|
93669
|
+
children,
|
|
93670
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(Toast, {
|
|
93671
|
+
currentToast
|
|
93672
|
+
}, undefined, false, undefined, this)
|
|
93673
|
+
]
|
|
93674
|
+
}, undefined, true, undefined, this);
|
|
93675
|
+
}
|
|
93676
|
+
function Toast({ currentToast }) {
|
|
93677
|
+
const { width } = useTerminalDimensions();
|
|
93678
|
+
const { colors } = useTheme();
|
|
93679
|
+
if (!currentToast) {
|
|
93680
|
+
return null;
|
|
93681
|
+
}
|
|
93682
|
+
const variantColors = {
|
|
93683
|
+
success: colors.success,
|
|
93684
|
+
error: colors.error,
|
|
93685
|
+
info: colors.info
|
|
93686
|
+
};
|
|
93687
|
+
const borderColor = currentToast.variant ? variantColors[currentToast.variant] : variantColors.info;
|
|
93688
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93689
|
+
position: "absolute",
|
|
93690
|
+
justifyContent: "center",
|
|
93691
|
+
alignItems: "flex-start",
|
|
93692
|
+
top: 2,
|
|
93693
|
+
right: 2,
|
|
93694
|
+
width: Math.max(1, Math.min(60, width - 6)),
|
|
93695
|
+
paddingLeft: 2,
|
|
93696
|
+
paddingRight: 2,
|
|
93697
|
+
paddingTop: 1,
|
|
93698
|
+
paddingBottom: 1,
|
|
93699
|
+
backgroundColor: colors.surface,
|
|
93700
|
+
borderColor,
|
|
93701
|
+
border: ["left", "right"],
|
|
93702
|
+
customBorderChars: SplitBorderChars,
|
|
93703
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93704
|
+
flexDirection: "column",
|
|
93705
|
+
gap: 1,
|
|
93706
|
+
width: "100%",
|
|
93707
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
93708
|
+
fg: "#E1E1E1",
|
|
93709
|
+
wrapMode: "word",
|
|
93710
|
+
width: "100%",
|
|
93711
|
+
children: currentToast.message
|
|
93712
|
+
}, undefined, false, undefined, this)
|
|
93713
|
+
}, undefined, false, undefined, this)
|
|
93714
|
+
}, undefined, false, undefined, this);
|
|
93715
|
+
}
|
|
93716
|
+
|
|
93717
|
+
// src/providers/dialog/index.tsx
|
|
93718
|
+
var import_react24 = __toESM(require_react(), 1);
|
|
93719
|
+
|
|
93720
|
+
// src/providers/keyboard-layer/index.tsx
|
|
93721
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
93722
|
+
var KeyboardLayerContext = import_react21.createContext(null);
|
|
93723
|
+
function KeyboardLayerProvider({ children }) {
|
|
93724
|
+
const [stack, setStack] = import_react21.useState(["base"]);
|
|
93725
|
+
const stackRef = import_react21.useRef(stack);
|
|
93726
|
+
stackRef.current = stack;
|
|
93727
|
+
const responders = import_react21.useRef(new Map);
|
|
93728
|
+
const renderer = useRenderer();
|
|
93729
|
+
const push = import_react21.useCallback((id, responder) => {
|
|
93730
|
+
if (responder) {
|
|
93731
|
+
responders.current.set(id, responder);
|
|
93732
|
+
}
|
|
93733
|
+
setStack((prev) => [...prev, id]);
|
|
93734
|
+
}, []);
|
|
93735
|
+
const pop = import_react21.useCallback((id) => {
|
|
93736
|
+
setStack((prev) => {
|
|
93737
|
+
const idx = prev.lastIndexOf(id);
|
|
93738
|
+
if (idx === -1)
|
|
93739
|
+
return prev;
|
|
93740
|
+
if (prev.indexOf(id) === idx) {
|
|
93741
|
+
responders.current.delete(id);
|
|
93742
|
+
}
|
|
93743
|
+
return prev.slice(0, idx);
|
|
93744
|
+
});
|
|
93745
|
+
}, []);
|
|
93746
|
+
const isTopLayer = import_react21.useCallback((id) => {
|
|
93747
|
+
return stack.length === 0 || stack[stack.length - 1] === id;
|
|
93748
|
+
}, [stack]);
|
|
93749
|
+
const setResponder = import_react21.useCallback((id, responder) => {
|
|
93750
|
+
if (responder) {
|
|
93751
|
+
responders.current.set(id, responder);
|
|
93752
|
+
} else {
|
|
93753
|
+
responders.current.delete(id);
|
|
93754
|
+
}
|
|
93755
|
+
}, []);
|
|
93756
|
+
useKeyboard((key) => {
|
|
93757
|
+
if (!key.ctrl || key.name !== "c")
|
|
93758
|
+
return;
|
|
93759
|
+
const currentStack = stackRef.current;
|
|
93760
|
+
for (let i = currentStack.length - 1;i >= 0; i--) {
|
|
93761
|
+
const layerId = currentStack[i];
|
|
93762
|
+
const responder = responders.current.get(layerId);
|
|
93763
|
+
if (responder && responder()) {
|
|
93764
|
+
return;
|
|
93765
|
+
}
|
|
93766
|
+
}
|
|
93767
|
+
renderer.destroy();
|
|
93768
|
+
});
|
|
93769
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(KeyboardLayerContext.Provider, {
|
|
93770
|
+
value: { push, pop, isTopLayer, setResponder },
|
|
93771
|
+
children
|
|
93772
|
+
}, undefined, false, undefined, this);
|
|
93773
|
+
}
|
|
93774
|
+
function useKeyboardLayer() {
|
|
93775
|
+
const context = import_react21.useContext(KeyboardLayerContext);
|
|
93776
|
+
if (!context) {
|
|
93777
|
+
throw new Error("useKeyboardLayer must be used within a KeyboardLayerProvider");
|
|
93778
|
+
}
|
|
93779
|
+
return context;
|
|
93780
|
+
}
|
|
93781
|
+
|
|
93782
|
+
// src/components/error-boundary.tsx
|
|
93783
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
93784
|
+
class ErrorBoundary2 extends import_react23.Component {
|
|
93785
|
+
constructor(props) {
|
|
93786
|
+
super(props);
|
|
93787
|
+
this.state = { error: null };
|
|
93788
|
+
}
|
|
93789
|
+
static getDerivedStateFromError(error51) {
|
|
93790
|
+
return { error: error51 };
|
|
93791
|
+
}
|
|
93792
|
+
componentDidCatch(error51, errorInfo) {
|
|
93793
|
+
console.error("[ErrorBoundary] Caught error:", error51, errorInfo.componentStack);
|
|
93794
|
+
}
|
|
93795
|
+
render() {
|
|
93796
|
+
if (this.state.error) {
|
|
93797
|
+
console.error("[ErrorBoundary] Rendering fallback for:", this.state.error.message);
|
|
93798
|
+
return this.props.fallback ?? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93799
|
+
flexDirection: "column",
|
|
93800
|
+
padding: 1,
|
|
93801
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
93802
|
+
children: [
|
|
93803
|
+
"Error: ",
|
|
93804
|
+
this.state.error.message
|
|
93805
|
+
]
|
|
93806
|
+
}, undefined, true, undefined, this)
|
|
93807
|
+
}, undefined, false, undefined, this);
|
|
93808
|
+
}
|
|
93809
|
+
return this.props.children;
|
|
93810
|
+
}
|
|
93811
|
+
}
|
|
93812
|
+
|
|
93813
|
+
// src/providers/dialog/index.tsx
|
|
93814
|
+
var DialogContext = import_react24.createContext(null);
|
|
93815
|
+
function useDialog() {
|
|
93816
|
+
const value = import_react24.useContext(DialogContext);
|
|
93817
|
+
if (!value) {
|
|
93818
|
+
throw new Error("useDialog must be used within a DialogProvider");
|
|
93819
|
+
}
|
|
93820
|
+
return value;
|
|
93821
|
+
}
|
|
93822
|
+
function DialogProvider({ children }) {
|
|
93823
|
+
const [dialogStack, setDialogStack] = import_react24.useState([]);
|
|
93824
|
+
const { push, pop } = useKeyboardLayer();
|
|
93825
|
+
const close = import_react24.useCallback(() => {
|
|
93826
|
+
setDialogStack((prev) => {
|
|
93827
|
+
const next = prev.slice(0, -1);
|
|
93828
|
+
pop("dialog");
|
|
93829
|
+
return next;
|
|
93830
|
+
});
|
|
93831
|
+
}, [pop]);
|
|
93832
|
+
const open = import_react24.useCallback((config2) => {
|
|
93833
|
+
setDialogStack((prev) => [...prev, config2]);
|
|
93834
|
+
push("dialog", () => {
|
|
93835
|
+
close();
|
|
93836
|
+
return true;
|
|
93837
|
+
});
|
|
93838
|
+
}, [push, close]);
|
|
93839
|
+
const value = {
|
|
93840
|
+
open,
|
|
93841
|
+
close
|
|
93842
|
+
};
|
|
93843
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogContext.Provider, {
|
|
93844
|
+
value,
|
|
93845
|
+
children: [
|
|
93846
|
+
children,
|
|
93847
|
+
dialogStack.map((config2, i) => /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(Dialog, {
|
|
93848
|
+
config: config2,
|
|
93849
|
+
close: i === dialogStack.length - 1 ? close : undefined,
|
|
93850
|
+
isBack: i < dialogStack.length - 1
|
|
93851
|
+
}, `dialog-${i}`, false, undefined, this))
|
|
93852
|
+
]
|
|
93853
|
+
}, undefined, true, undefined, this);
|
|
93854
|
+
}
|
|
93855
|
+
function Dialog({ config: config2, close, isBack = false }) {
|
|
93856
|
+
const { isTopLayer } = useKeyboardLayer();
|
|
93857
|
+
const dimensions = useTerminalDimensions();
|
|
93858
|
+
const { colors } = useTheme();
|
|
93859
|
+
useKeyboard((key) => {
|
|
93860
|
+
if (!close || !isTopLayer("dialog"))
|
|
93861
|
+
return;
|
|
93862
|
+
if (key.name === "escape") {
|
|
93863
|
+
close();
|
|
93864
|
+
}
|
|
93865
|
+
});
|
|
93866
|
+
const { title, children } = config2;
|
|
93867
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93868
|
+
position: "absolute",
|
|
93869
|
+
left: 0,
|
|
93870
|
+
top: 0,
|
|
93871
|
+
width: dimensions.width,
|
|
93872
|
+
height: dimensions.height,
|
|
93873
|
+
justifyContent: "center",
|
|
93874
|
+
alignItems: "center",
|
|
93875
|
+
backgroundColor: RGBA.fromInts(0, 0, 0, 150),
|
|
93876
|
+
zIndex: 100,
|
|
93877
|
+
onMouseDown: close,
|
|
93878
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93879
|
+
width: Math.min(60, dimensions.width - 4),
|
|
93880
|
+
height: "auto",
|
|
93881
|
+
backgroundColor: colors.dialogSurface,
|
|
93882
|
+
paddingX: 4,
|
|
93883
|
+
paddingY: 1,
|
|
93884
|
+
flexDirection: "column",
|
|
93885
|
+
gap: 1,
|
|
93886
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
93887
|
+
children: [
|
|
93888
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93889
|
+
paddingBottom: 1,
|
|
93890
|
+
flexDirection: "row",
|
|
93891
|
+
alignItems: "center",
|
|
93892
|
+
justifyContent: "space-between",
|
|
93893
|
+
children: [
|
|
93894
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
93895
|
+
attributes: TextAttributes.BOLD,
|
|
93896
|
+
children: title
|
|
93897
|
+
}, undefined, false, undefined, this),
|
|
93898
|
+
close && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
93899
|
+
attributes: TextAttributes.DIM,
|
|
93900
|
+
onMouseDown: close,
|
|
93901
|
+
children: isBack ? "back (esc)" : "esc"
|
|
93902
|
+
}, undefined, false, undefined, this)
|
|
93903
|
+
]
|
|
93904
|
+
}, undefined, true, undefined, this),
|
|
93905
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93906
|
+
flexGrow: 1,
|
|
93907
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
|
|
93908
|
+
children
|
|
93909
|
+
}, undefined, false, undefined, this)
|
|
93910
|
+
}, undefined, false, undefined, this)
|
|
93911
|
+
]
|
|
93912
|
+
}, undefined, true, undefined, this)
|
|
93913
|
+
}, undefined, false, undefined, this);
|
|
93914
|
+
}
|
|
93915
|
+
|
|
93916
|
+
// src/layouts/themed-root.tsx
|
|
93917
|
+
function ThemedRoot({ children }) {
|
|
93918
|
+
const { colors } = useTheme();
|
|
93919
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
93920
|
+
backgroundColor: colors.background,
|
|
93921
|
+
width: "100%",
|
|
93922
|
+
height: "100%",
|
|
93923
|
+
flexGrow: 1,
|
|
93924
|
+
children
|
|
93925
|
+
}, undefined, false, undefined, this);
|
|
93926
|
+
}
|
|
93927
|
+
|
|
93568
93928
|
// src/providers/prompt-config/index.tsx
|
|
93929
|
+
var import_react26 = __toESM(require_react(), 1);
|
|
93569
93930
|
var PromptConfigContext = import_react26.createContext(null);
|
|
93570
93931
|
function usePromptConfig() {
|
|
93571
93932
|
const value = import_react26.useContext(PromptConfigContext);
|
|
@@ -93574,12 +93935,32 @@ function usePromptConfig() {
|
|
|
93574
93935
|
}
|
|
93575
93936
|
return value;
|
|
93576
93937
|
}
|
|
93938
|
+
function getInitial(key, fallback) {
|
|
93939
|
+
const prefs = readPreferences();
|
|
93940
|
+
return prefs[key] !== undefined ? prefs[key] : fallback;
|
|
93941
|
+
}
|
|
93577
93942
|
function PromptConfigProvider({ children }) {
|
|
93578
|
-
const [mode,
|
|
93579
|
-
const [model,
|
|
93580
|
-
const [domain2,
|
|
93943
|
+
const [mode, setModeState] = import_react26.useState(() => getInitial("mode", Mode.BUILD));
|
|
93944
|
+
const [model, setModelState] = import_react26.useState(() => getInitial("model", DEFAULT_CHAT_MODEL_ID));
|
|
93945
|
+
const [domain2, setDomainState] = import_react26.useState(() => getInitial("domain", DEFAULT_DOMAIN_ID));
|
|
93946
|
+
const setMode = import_react26.useCallback((m2) => {
|
|
93947
|
+
setModeState(m2);
|
|
93948
|
+
writePreferences({ mode: m2 });
|
|
93949
|
+
}, []);
|
|
93950
|
+
const setModel = import_react26.useCallback((m2) => {
|
|
93951
|
+
setModelState(m2);
|
|
93952
|
+
writePreferences({ model: m2 });
|
|
93953
|
+
}, []);
|
|
93954
|
+
const setDomain = import_react26.useCallback((d2) => {
|
|
93955
|
+
setDomainState(d2);
|
|
93956
|
+
writePreferences({ domain: d2 });
|
|
93957
|
+
}, []);
|
|
93581
93958
|
const toggleMode = import_react26.useCallback(() => {
|
|
93582
|
-
|
|
93959
|
+
setModeState((m2) => {
|
|
93960
|
+
const next = m2 === Mode.BUILD ? Mode.PLAN : Mode.BUILD;
|
|
93961
|
+
writePreferences({ mode: next });
|
|
93962
|
+
return next;
|
|
93963
|
+
});
|
|
93583
93964
|
}, []);
|
|
93584
93965
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PromptConfigContext.Provider, {
|
|
93585
93966
|
value: {
|
|
@@ -93600,8 +93981,8 @@ function RootLayout() {
|
|
|
93600
93981
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ThemeProvider, {
|
|
93601
93982
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastProvider, {
|
|
93602
93983
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(KeyboardLayerProvider, {
|
|
93603
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
93604
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
93984
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PromptConfigProvider, {
|
|
93985
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogProvider, {
|
|
93605
93986
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ThemedRoot, {
|
|
93606
93987
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(Outlet, {}, undefined, false, undefined, this)
|
|
93607
93988
|
}, undefined, false, undefined, this)
|
|
@@ -93613,7 +93994,7 @@ function RootLayout() {
|
|
|
93613
93994
|
}
|
|
93614
93995
|
|
|
93615
93996
|
// src/screens/home.tsx
|
|
93616
|
-
var
|
|
93997
|
+
var import_react41 = __toESM(require_react(), 1);
|
|
93617
93998
|
|
|
93618
93999
|
// src/components/header.tsx
|
|
93619
94000
|
function Header() {
|
|
@@ -93641,7 +94022,7 @@ function Header() {
|
|
|
93641
94022
|
}
|
|
93642
94023
|
|
|
93643
94024
|
// src/components/input-bar.tsx
|
|
93644
|
-
var
|
|
94025
|
+
var import_react39 = __toESM(require_react(), 1);
|
|
93645
94026
|
import { readdir } from "fs/promises";
|
|
93646
94027
|
import { isAbsolute as isAbsolute3, relative, resolve as resolve5 } from "path";
|
|
93647
94028
|
|
|
@@ -93659,7 +94040,8 @@ function DialogSearchList({
|
|
|
93659
94040
|
renderItem,
|
|
93660
94041
|
getKey,
|
|
93661
94042
|
placeholder = "Search",
|
|
93662
|
-
emptyText = "No results"
|
|
94043
|
+
emptyText = "No results",
|
|
94044
|
+
onEndReached
|
|
93663
94045
|
}) {
|
|
93664
94046
|
const [selectedIndex, setSelectedIndex] = import_react27.useState(0);
|
|
93665
94047
|
const [searchValue, setSearchValue] = import_react27.useState("");
|
|
@@ -93667,6 +94049,26 @@ function DialogSearchList({
|
|
|
93667
94049
|
const scrollRef = import_react27.useRef(null);
|
|
93668
94050
|
const { isTopLayer } = useKeyboardLayer();
|
|
93669
94051
|
const { colors } = useTheme();
|
|
94052
|
+
const itemsRef = import_react27.useRef(items);
|
|
94053
|
+
itemsRef.current = items;
|
|
94054
|
+
const filterFnRef = import_react27.useRef(filterFn);
|
|
94055
|
+
filterFnRef.current = filterFn;
|
|
94056
|
+
const onSelectRef = import_react27.useRef(onSelect);
|
|
94057
|
+
onSelectRef.current = onSelect;
|
|
94058
|
+
const onHighlightRef = import_react27.useRef(onHighlight);
|
|
94059
|
+
onHighlightRef.current = onHighlight;
|
|
94060
|
+
const selectedIndexRef = import_react27.useRef(selectedIndex);
|
|
94061
|
+
selectedIndexRef.current = selectedIndex;
|
|
94062
|
+
const searchValueRef = import_react27.useRef(searchValue);
|
|
94063
|
+
searchValueRef.current = searchValue;
|
|
94064
|
+
const handleSubmit = import_react27.useCallback(() => {
|
|
94065
|
+
const text2 = inputRef.current?.value ?? "";
|
|
94066
|
+
const currentFiltered = text2 ? itemsRef.current.filter((item2) => filterFnRef.current(item2, text2)) : itemsRef.current;
|
|
94067
|
+
const item = currentFiltered[selectedIndexRef.current];
|
|
94068
|
+
if (item) {
|
|
94069
|
+
onSelectRef.current(item);
|
|
94070
|
+
}
|
|
94071
|
+
}, []);
|
|
93670
94072
|
const handleContentChange = import_react27.useCallback(() => {
|
|
93671
94073
|
const text2 = inputRef.current?.value ?? "";
|
|
93672
94074
|
setSearchValue(text2);
|
|
@@ -93694,8 +94096,8 @@ function DialogSearchList({
|
|
|
93694
94096
|
sb.scrollTo(newIndex);
|
|
93695
94097
|
}
|
|
93696
94098
|
const item = filtered[newIndex];
|
|
93697
|
-
if (item &&
|
|
93698
|
-
|
|
94099
|
+
if (item && onHighlightRef.current)
|
|
94100
|
+
onHighlightRef.current(item);
|
|
93699
94101
|
return newIndex;
|
|
93700
94102
|
});
|
|
93701
94103
|
} else if (key.name === "down") {
|
|
@@ -93710,8 +94112,11 @@ function DialogSearchList({
|
|
|
93710
94112
|
}
|
|
93711
94113
|
}
|
|
93712
94114
|
const item = filtered[newIndex];
|
|
93713
|
-
if (item &&
|
|
93714
|
-
|
|
94115
|
+
if (item && onHighlightRef.current)
|
|
94116
|
+
onHighlightRef.current(item);
|
|
94117
|
+
if (newIndex >= filtered.length - 2 && onEndReached) {
|
|
94118
|
+
onEndReached();
|
|
94119
|
+
}
|
|
93715
94120
|
return newIndex;
|
|
93716
94121
|
});
|
|
93717
94122
|
}
|
|
@@ -93724,7 +94129,8 @@ function DialogSearchList({
|
|
|
93724
94129
|
ref: inputRef,
|
|
93725
94130
|
placeholder,
|
|
93726
94131
|
focused: true,
|
|
93727
|
-
onContentChange: handleContentChange
|
|
94132
|
+
onContentChange: handleContentChange,
|
|
94133
|
+
onSubmit: handleSubmit
|
|
93728
94134
|
}, undefined, false, undefined, this),
|
|
93729
94135
|
filtered.length === 0 ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
93730
94136
|
attributes: TextAttributes.DIM,
|
|
@@ -93741,10 +94147,10 @@ function DialogSearchList({
|
|
|
93741
94147
|
backgroundColor: isSelected ? colors.selectMode : undefined,
|
|
93742
94148
|
onMouseMove: () => {
|
|
93743
94149
|
setSelectedIndex(i);
|
|
93744
|
-
if (
|
|
93745
|
-
|
|
94150
|
+
if (onHighlightRef.current)
|
|
94151
|
+
onHighlightRef.current(item);
|
|
93746
94152
|
},
|
|
93747
|
-
onMouseDown: () =>
|
|
94153
|
+
onMouseDown: () => onSelectRef.current(item),
|
|
93748
94154
|
children: renderItem(item, isSelected)
|
|
93749
94155
|
}, getKey(item), false, undefined, this);
|
|
93750
94156
|
})
|
|
@@ -93768,8 +94174,8 @@ var ThemeDialogContent = () => {
|
|
|
93768
94174
|
}, [setTheme]);
|
|
93769
94175
|
const handleSelect = import_react29.useCallback((theme) => {
|
|
93770
94176
|
confirmedRef.current = true;
|
|
93771
|
-
setTheme(theme);
|
|
93772
94177
|
dialog.close();
|
|
94178
|
+
setTheme(theme);
|
|
93773
94179
|
}, [setTheme, dialog]);
|
|
93774
94180
|
const handleHighlight = import_react29.useCallback((theme) => {
|
|
93775
94181
|
setTheme(theme);
|
|
@@ -94119,6 +94525,27 @@ function clearAuth() {
|
|
|
94119
94525
|
}
|
|
94120
94526
|
|
|
94121
94527
|
// src/lib/api-client.ts
|
|
94528
|
+
var RETRY_ATTEMPTS = 3;
|
|
94529
|
+
var RETRY_BASE_DELAY_MS = 1000;
|
|
94530
|
+
async function sleep2(ms) {
|
|
94531
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
94532
|
+
}
|
|
94533
|
+
async function withRetry(fn, options) {
|
|
94534
|
+
const maxAttempts = options?.attempts ?? RETRY_ATTEMPTS;
|
|
94535
|
+
let lastError;
|
|
94536
|
+
for (let attempt = 0;attempt < maxAttempts; attempt++) {
|
|
94537
|
+
try {
|
|
94538
|
+
return await fn(attempt);
|
|
94539
|
+
} catch (err) {
|
|
94540
|
+
lastError = err;
|
|
94541
|
+
if (attempt < maxAttempts - 1) {
|
|
94542
|
+
const delay = RETRY_BASE_DELAY_MS * Math.pow(2, attempt);
|
|
94543
|
+
await sleep2(delay);
|
|
94544
|
+
}
|
|
94545
|
+
}
|
|
94546
|
+
}
|
|
94547
|
+
throw lastError;
|
|
94548
|
+
}
|
|
94122
94549
|
var apiClient = hc(process.env.API_URL ?? "https://lupacodeserver-production.up.railway.app", {
|
|
94123
94550
|
fetch: async (input, init) => {
|
|
94124
94551
|
const headers = new Headers(init?.headers);
|
|
@@ -95577,44 +96004,126 @@ function cleanEscapedString(input) {
|
|
|
95577
96004
|
}
|
|
95578
96005
|
|
|
95579
96006
|
// src/components/dialogs/sessions-dialog.tsx
|
|
96007
|
+
var PAGE_SIZE = 20;
|
|
95580
96008
|
var SessionsDialogContent = () => {
|
|
95581
96009
|
const [sessions, setSessions] = import_react30.useState([]);
|
|
95582
96010
|
const [loading, setLoading] = import_react30.useState(true);
|
|
96011
|
+
const [hasMore, setHasMore] = import_react30.useState(false);
|
|
96012
|
+
const [cursor, setCursor] = import_react30.useState();
|
|
96013
|
+
const [highlightedSession, setHighlightedSession] = import_react30.useState(null);
|
|
96014
|
+
const [view, setView] = import_react30.useState({ type: "list" });
|
|
95583
96015
|
const { close } = useDialog();
|
|
95584
96016
|
const navigate = useNavigate();
|
|
95585
96017
|
const { show } = useToast();
|
|
95586
|
-
|
|
95587
|
-
|
|
95588
|
-
|
|
95589
|
-
|
|
95590
|
-
|
|
95591
|
-
|
|
95592
|
-
|
|
95593
|
-
|
|
95594
|
-
|
|
95595
|
-
|
|
95596
|
-
|
|
95597
|
-
|
|
95598
|
-
|
|
95599
|
-
|
|
95600
|
-
|
|
95601
|
-
|
|
95602
|
-
|
|
95603
|
-
|
|
95604
|
-
|
|
95605
|
-
|
|
95606
|
-
|
|
96018
|
+
const { isTopLayer } = useKeyboardLayer();
|
|
96019
|
+
const { colors } = useTheme();
|
|
96020
|
+
const fetchSessions = import_react30.useCallback(async (cursorVal) => {
|
|
96021
|
+
try {
|
|
96022
|
+
const params = new URLSearchParams;
|
|
96023
|
+
params.set("limit", String(PAGE_SIZE));
|
|
96024
|
+
if (cursorVal)
|
|
96025
|
+
params.set("cursor", cursorVal);
|
|
96026
|
+
const res = await apiClient.sessions.$get({ query: Object.fromEntries(params) });
|
|
96027
|
+
if (!res.ok) {
|
|
96028
|
+
throw new Error(await getErrorMessage2(res));
|
|
96029
|
+
}
|
|
96030
|
+
const raw = await res.json();
|
|
96031
|
+
let list;
|
|
96032
|
+
let more;
|
|
96033
|
+
if (Array.isArray(raw)) {
|
|
96034
|
+
list = raw;
|
|
96035
|
+
more = false;
|
|
96036
|
+
} else {
|
|
96037
|
+
const parsed = raw;
|
|
96038
|
+
list = parsed.sessions ?? [];
|
|
96039
|
+
more = parsed.hasMore ?? false;
|
|
95607
96040
|
}
|
|
95608
|
-
|
|
95609
|
-
|
|
95610
|
-
|
|
95611
|
-
|
|
95612
|
-
|
|
96041
|
+
if (cursorVal) {
|
|
96042
|
+
setSessions((prev) => [...prev, ...list]);
|
|
96043
|
+
} else {
|
|
96044
|
+
setSessions(list);
|
|
96045
|
+
}
|
|
96046
|
+
setHasMore(more);
|
|
96047
|
+
if (list.length > 0) {
|
|
96048
|
+
setCursor(list[list.length - 1].createdAt);
|
|
96049
|
+
}
|
|
96050
|
+
setLoading(false);
|
|
96051
|
+
} catch (error51) {
|
|
96052
|
+
show({
|
|
96053
|
+
variant: "error",
|
|
96054
|
+
message: error51 instanceof Error ? error51.message : "Failed to fetch sessions"
|
|
96055
|
+
});
|
|
96056
|
+
close();
|
|
96057
|
+
}
|
|
95613
96058
|
}, [close, show]);
|
|
96059
|
+
import_react30.useEffect(() => {
|
|
96060
|
+
fetchSessions();
|
|
96061
|
+
}, [fetchSessions]);
|
|
95614
96062
|
const handleSelect = import_react30.useCallback((session) => {
|
|
95615
96063
|
close();
|
|
95616
96064
|
navigate(`/sessions/${session.id}`);
|
|
95617
96065
|
}, [close, navigate]);
|
|
96066
|
+
const handleDelete = import_react30.useCallback(async (session) => {
|
|
96067
|
+
try {
|
|
96068
|
+
const res = await withRetry(() => apiClient.sessions[":id"].$delete({ param: { id: session.id } }));
|
|
96069
|
+
if (!res.ok)
|
|
96070
|
+
throw new Error(await getErrorMessage2(res));
|
|
96071
|
+
show({ variant: "success", message: "Session deleted" });
|
|
96072
|
+
setSessions((prev) => prev.filter((s) => s.id !== session.id));
|
|
96073
|
+
setView({ type: "list" });
|
|
96074
|
+
} catch (error51) {
|
|
96075
|
+
show({
|
|
96076
|
+
variant: "error",
|
|
96077
|
+
message: error51 instanceof Error ? error51.message : "Failed to delete session"
|
|
96078
|
+
});
|
|
96079
|
+
setView({ type: "list" });
|
|
96080
|
+
}
|
|
96081
|
+
}, [show]);
|
|
96082
|
+
const handleRename = import_react30.useCallback(async (session, newTitle) => {
|
|
96083
|
+
try {
|
|
96084
|
+
const res = await withRetry(() => apiClient.sessions[":id"].$patch({
|
|
96085
|
+
param: { id: session.id },
|
|
96086
|
+
json: { title: newTitle }
|
|
96087
|
+
}));
|
|
96088
|
+
if (!res.ok)
|
|
96089
|
+
throw new Error(await getErrorMessage2(res));
|
|
96090
|
+
show({ variant: "success", message: "Session renamed" });
|
|
96091
|
+
setSessions((prev) => prev.map((s) => s.id === session.id ? { ...s, title: newTitle } : s));
|
|
96092
|
+
setView({ type: "list" });
|
|
96093
|
+
} catch (error51) {
|
|
96094
|
+
show({
|
|
96095
|
+
variant: "error",
|
|
96096
|
+
message: error51 instanceof Error ? error51.message : "Failed to rename session"
|
|
96097
|
+
});
|
|
96098
|
+
setView({ type: "list" });
|
|
96099
|
+
}
|
|
96100
|
+
}, [show]);
|
|
96101
|
+
const handleLoadMore = import_react30.useCallback(async () => {
|
|
96102
|
+
if (hasMore && cursor) {
|
|
96103
|
+
await fetchSessions(cursor);
|
|
96104
|
+
}
|
|
96105
|
+
}, [hasMore, cursor, fetchSessions]);
|
|
96106
|
+
useKeyboard((key) => {
|
|
96107
|
+
if (!isTopLayer("dialog"))
|
|
96108
|
+
return;
|
|
96109
|
+
if (view.type === "list") {
|
|
96110
|
+
if (key.name === "d" && highlightedSession) {
|
|
96111
|
+
setView({ type: "confirm-delete", session: highlightedSession });
|
|
96112
|
+
} else if (key.name === "r" && highlightedSession) {
|
|
96113
|
+
setView({ type: "rename", session: highlightedSession });
|
|
96114
|
+
}
|
|
96115
|
+
} else if (view.type === "confirm-delete") {
|
|
96116
|
+
if (key.name === "y" || key.name === "enter") {
|
|
96117
|
+
handleDelete(view.session);
|
|
96118
|
+
} else if (key.name === "n" || key.name === "escape") {
|
|
96119
|
+
setView({ type: "list" });
|
|
96120
|
+
}
|
|
96121
|
+
} else if (view.type === "rename") {
|
|
96122
|
+
if (key.name === "escape") {
|
|
96123
|
+
setView({ type: "list" });
|
|
96124
|
+
}
|
|
96125
|
+
}
|
|
96126
|
+
});
|
|
95618
96127
|
if (loading) {
|
|
95619
96128
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
95620
96129
|
flexDirection: "column",
|
|
@@ -95633,35 +96142,94 @@ var SessionsDialogContent = () => {
|
|
|
95633
96142
|
}, undefined, false, undefined, this)
|
|
95634
96143
|
}, undefined, false, undefined, this);
|
|
95635
96144
|
}
|
|
95636
|
-
|
|
95637
|
-
|
|
95638
|
-
|
|
95639
|
-
|
|
95640
|
-
renderItem: (session, isSelected) => /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
96145
|
+
if (view.type === "confirm-delete") {
|
|
96146
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96147
|
+
flexDirection: "column",
|
|
96148
|
+
gap: 1,
|
|
95641
96149
|
children: [
|
|
95642
96150
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
95643
|
-
|
|
95644
|
-
|
|
95645
|
-
|
|
95646
|
-
|
|
96151
|
+
children: [
|
|
96152
|
+
'Delete "',
|
|
96153
|
+
view.session.title,
|
|
96154
|
+
'"?'
|
|
96155
|
+
]
|
|
96156
|
+
}, undefined, true, undefined, this),
|
|
95647
96157
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
95648
|
-
|
|
95649
|
-
|
|
96158
|
+
flexDirection: "row",
|
|
96159
|
+
gap: 2,
|
|
96160
|
+
children: [
|
|
96161
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96162
|
+
selectable: true,
|
|
96163
|
+
fg: colors.error,
|
|
96164
|
+
onMouseDown: () => handleDelete(view.session),
|
|
96165
|
+
children: "yes (y)"
|
|
96166
|
+
}, undefined, false, undefined, this),
|
|
96167
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96168
|
+
selectable: true,
|
|
96169
|
+
onMouseDown: () => setView({ type: "list" }),
|
|
96170
|
+
children: "no (n)"
|
|
96171
|
+
}, undefined, false, undefined, this)
|
|
96172
|
+
]
|
|
96173
|
+
}, undefined, true, undefined, this)
|
|
96174
|
+
]
|
|
96175
|
+
}, undefined, true, undefined, this);
|
|
96176
|
+
}
|
|
96177
|
+
if (view.type === "rename") {
|
|
96178
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96179
|
+
flexDirection: "column",
|
|
96180
|
+
gap: 1,
|
|
96181
|
+
children: [
|
|
95650
96182
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
95651
|
-
selectable: false,
|
|
95652
|
-
fg: isSelected ? "black" : undefined,
|
|
95653
96183
|
attributes: TextAttributes.DIM,
|
|
95654
|
-
children:
|
|
96184
|
+
children: "Rename session:"
|
|
96185
|
+
}, undefined, false, undefined, this),
|
|
96186
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
|
|
96187
|
+
focused: true,
|
|
96188
|
+
initialValue: view.session.title,
|
|
96189
|
+
onSubmit: (value) => {
|
|
96190
|
+
if (value.trim()) {
|
|
96191
|
+
handleRename(view.session, value.trim());
|
|
96192
|
+
}
|
|
96193
|
+
}
|
|
95655
96194
|
}, undefined, false, undefined, this)
|
|
95656
96195
|
]
|
|
95657
|
-
}, undefined, true, undefined, this)
|
|
95658
|
-
|
|
95659
|
-
|
|
95660
|
-
|
|
96196
|
+
}, undefined, true, undefined, this);
|
|
96197
|
+
}
|
|
96198
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96199
|
+
flexDirection: "column",
|
|
96200
|
+
gap: 1,
|
|
96201
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogSearchList, {
|
|
96202
|
+
items: sessions,
|
|
96203
|
+
onSelect: handleSelect,
|
|
96204
|
+
onHighlight: (s) => setHighlightedSession(s),
|
|
96205
|
+
filterFn: (s, query) => (s.title || "").toLowerCase().includes(query.toLowerCase()),
|
|
96206
|
+
renderItem: (session, isSelected) => /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
96207
|
+
children: [
|
|
96208
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96209
|
+
selectable: false,
|
|
96210
|
+
fg: isSelected ? "black" : "white",
|
|
96211
|
+
children: session.title
|
|
96212
|
+
}, undefined, false, undefined, this),
|
|
96213
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96214
|
+
flexGrow: 1
|
|
96215
|
+
}, undefined, false, undefined, this),
|
|
96216
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96217
|
+
selectable: false,
|
|
96218
|
+
fg: isSelected ? "black" : undefined,
|
|
96219
|
+
attributes: TextAttributes.DIM,
|
|
96220
|
+
children: format(new Date(session.createdAt), "hh:mm a")
|
|
96221
|
+
}, undefined, false, undefined, this)
|
|
96222
|
+
]
|
|
96223
|
+
}, undefined, true, undefined, this),
|
|
96224
|
+
getKey: (s) => s.id,
|
|
96225
|
+
placeholder: "Search sessions (r) rename (d) delete",
|
|
96226
|
+
emptyText: "No matching sessions",
|
|
96227
|
+
onEndReached: handleLoadMore
|
|
96228
|
+
}, undefined, false, undefined, this)
|
|
95661
96229
|
}, undefined, false, undefined, this);
|
|
95662
96230
|
};
|
|
95663
96231
|
// src/components/dialogs/agents-dialog.tsx
|
|
95664
|
-
var
|
|
96232
|
+
var import_react32 = __toESM(require_react(), 1);
|
|
95665
96233
|
var AVAILABLE_MODES = [Mode.BUILD, Mode.PLAN];
|
|
95666
96234
|
function getModeLabel(mode) {
|
|
95667
96235
|
return mode === Mode.PLAN ? "Plan" : "Build";
|
|
@@ -95671,9 +96239,9 @@ var AgentsDialogContent = ({
|
|
|
95671
96239
|
onSelectMode
|
|
95672
96240
|
}) => {
|
|
95673
96241
|
const dialog = useDialog();
|
|
95674
|
-
const handleSelect =
|
|
95675
|
-
onSelectMode(nextMode);
|
|
96242
|
+
const handleSelect = import_react32.useCallback((nextMode) => {
|
|
95676
96243
|
dialog.close();
|
|
96244
|
+
onSelectMode(nextMode);
|
|
95677
96245
|
}, [onSelectMode, dialog]);
|
|
95678
96246
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogSearchList, {
|
|
95679
96247
|
items: AVAILABLE_MODES,
|
|
@@ -95693,15 +96261,15 @@ var AgentsDialogContent = ({
|
|
|
95693
96261
|
}, undefined, false, undefined, this);
|
|
95694
96262
|
};
|
|
95695
96263
|
// src/components/dialogs/models-dialog.tsx
|
|
95696
|
-
var
|
|
96264
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
95697
96265
|
var ModelsDialogContent = ({
|
|
95698
96266
|
models,
|
|
95699
96267
|
onSelectModel
|
|
95700
96268
|
}) => {
|
|
95701
96269
|
const dialog = useDialog();
|
|
95702
|
-
const handleSelect =
|
|
95703
|
-
onSelectModel(model.id);
|
|
96270
|
+
const handleSelect = import_react33.useCallback((model) => {
|
|
95704
96271
|
dialog.close();
|
|
96272
|
+
onSelectModel(model.id);
|
|
95705
96273
|
}, [dialog, onSelectModel]);
|
|
95706
96274
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogSearchList, {
|
|
95707
96275
|
items: models,
|
|
@@ -95737,14 +96305,14 @@ var ModelsDialogContent = ({
|
|
|
95737
96305
|
}, undefined, false, undefined, this);
|
|
95738
96306
|
};
|
|
95739
96307
|
// src/components/dialogs/domains-dialog.tsx
|
|
95740
|
-
var
|
|
96308
|
+
var import_react34 = __toESM(require_react(), 1);
|
|
95741
96309
|
var DomainsDialogContent = ({
|
|
95742
96310
|
onSelectDomain
|
|
95743
96311
|
}) => {
|
|
95744
96312
|
const dialog = useDialog();
|
|
95745
|
-
const handleSelect =
|
|
95746
|
-
onSelectDomain(domain2.id);
|
|
96313
|
+
const handleSelect = import_react34.useCallback((domain2) => {
|
|
95747
96314
|
dialog.close();
|
|
96315
|
+
onSelectDomain(domain2.id);
|
|
95748
96316
|
}, [dialog, onSelectDomain]);
|
|
95749
96317
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogSearchList, {
|
|
95750
96318
|
items: [...DOMAINS],
|
|
@@ -95760,6 +96328,255 @@ var DomainsDialogContent = ({
|
|
|
95760
96328
|
emptyText: "No matching domains"
|
|
95761
96329
|
}, undefined, false, undefined, this);
|
|
95762
96330
|
};
|
|
96331
|
+
// src/components/dialogs/settings-dialog.tsx
|
|
96332
|
+
var import_react35 = __toESM(require_react(), 1);
|
|
96333
|
+
// package.json
|
|
96334
|
+
var package_default2 = {
|
|
96335
|
+
name: "lupacode",
|
|
96336
|
+
version: "1.0.0",
|
|
96337
|
+
description: "AI-powered terminal coding assistant",
|
|
96338
|
+
type: "module",
|
|
96339
|
+
bin: {
|
|
96340
|
+
lupacode: "bin/lupacode"
|
|
96341
|
+
},
|
|
96342
|
+
files: [
|
|
96343
|
+
"bin/",
|
|
96344
|
+
"dist/",
|
|
96345
|
+
"README.md"
|
|
96346
|
+
],
|
|
96347
|
+
scripts: {
|
|
96348
|
+
dev: "bun run --watch src/index.tsx",
|
|
96349
|
+
build: 'bun build src/index.tsx --outdir dist --target bun --external "@opentui/core-*"',
|
|
96350
|
+
prepublishOnly: "bun run build",
|
|
96351
|
+
typecheck: "tsc -p tsconfig.json --noEmit"
|
|
96352
|
+
},
|
|
96353
|
+
engines: {
|
|
96354
|
+
bun: ">=1.0.0"
|
|
96355
|
+
},
|
|
96356
|
+
devDependencies: {
|
|
96357
|
+
"@types/bun": "latest",
|
|
96358
|
+
"@types/react": "^19.2.17"
|
|
96359
|
+
},
|
|
96360
|
+
peerDependencies: {
|
|
96361
|
+
typescript: "^5"
|
|
96362
|
+
},
|
|
96363
|
+
peerDependenciesMeta: {
|
|
96364
|
+
typescript: {
|
|
96365
|
+
optional: true
|
|
96366
|
+
}
|
|
96367
|
+
},
|
|
96368
|
+
dependencies: {
|
|
96369
|
+
"@ai-sdk/react": "^4.0.4",
|
|
96370
|
+
"@opentui/core": "^0.3.4",
|
|
96371
|
+
"@opentui/react": "^0.3.4",
|
|
96372
|
+
ai: "^7.0.3",
|
|
96373
|
+
"date-fns": "^4.4.0",
|
|
96374
|
+
dotenv: "^16.4.7",
|
|
96375
|
+
hono: "^4.12.26",
|
|
96376
|
+
open: "^11.0.0",
|
|
96377
|
+
"opentui-spinner": "^0.0.7",
|
|
96378
|
+
"pretty-ms": "^9.3.0",
|
|
96379
|
+
react: "^19.2.6",
|
|
96380
|
+
"react-router": "^8.0.1",
|
|
96381
|
+
zod: "^4.4.3"
|
|
96382
|
+
}
|
|
96383
|
+
};
|
|
96384
|
+
|
|
96385
|
+
// src/lib/update-check.ts
|
|
96386
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
96387
|
+
import { homedir as homedir3 } from "os";
|
|
96388
|
+
import { join as join4 } from "path";
|
|
96389
|
+
var DIR = join4(homedir3(), ".lupacode");
|
|
96390
|
+
var FILE = join4(DIR, "update-check.json");
|
|
96391
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
96392
|
+
function readCache() {
|
|
96393
|
+
try {
|
|
96394
|
+
return JSON.parse(readFileSync3(FILE, "utf-8"));
|
|
96395
|
+
} catch {
|
|
96396
|
+
return null;
|
|
96397
|
+
}
|
|
96398
|
+
}
|
|
96399
|
+
function writeCache(data2) {
|
|
96400
|
+
if (!existsSync5(DIR)) {
|
|
96401
|
+
mkdirSync3(DIR, { mode: 448 });
|
|
96402
|
+
}
|
|
96403
|
+
writeFileSync4(FILE, JSON.stringify(data2));
|
|
96404
|
+
}
|
|
96405
|
+
var cachedLatest = null;
|
|
96406
|
+
var cachedCurrent = "0.0.0";
|
|
96407
|
+
function setCurrentVersion(v2) {
|
|
96408
|
+
cachedCurrent = v2;
|
|
96409
|
+
}
|
|
96410
|
+
function getLatestVersion() {
|
|
96411
|
+
return cachedLatest;
|
|
96412
|
+
}
|
|
96413
|
+
async function checkForUpdate(currentVersion) {
|
|
96414
|
+
cachedCurrent = currentVersion;
|
|
96415
|
+
const cache = readCache();
|
|
96416
|
+
if (cache && Date.now() - cache.checkedAt < CHECK_INTERVAL_MS) {
|
|
96417
|
+
cachedLatest = cache.latest;
|
|
96418
|
+
return cache.latest && cache.latest !== currentVersion ? cache.latest : null;
|
|
96419
|
+
}
|
|
96420
|
+
try {
|
|
96421
|
+
const res = await fetch("https://registry.npmjs.org/lupacode/latest");
|
|
96422
|
+
if (!res.ok)
|
|
96423
|
+
return null;
|
|
96424
|
+
const data2 = await res.json();
|
|
96425
|
+
const latest = data2.version;
|
|
96426
|
+
const result = { latest, checkedAt: Date.now() };
|
|
96427
|
+
writeCache(result);
|
|
96428
|
+
cachedLatest = latest;
|
|
96429
|
+
return latest !== currentVersion ? latest : null;
|
|
96430
|
+
} catch {
|
|
96431
|
+
return null;
|
|
96432
|
+
}
|
|
96433
|
+
}
|
|
96434
|
+
function hasUpdate() {
|
|
96435
|
+
return cachedLatest !== null && cachedLatest !== cachedCurrent;
|
|
96436
|
+
}
|
|
96437
|
+
|
|
96438
|
+
// src/components/dialogs/settings-dialog.tsx
|
|
96439
|
+
var ITEMS = ["theme", "mode", "model", "domain"];
|
|
96440
|
+
var SettingsDialogContent = () => {
|
|
96441
|
+
const dialog = useDialog();
|
|
96442
|
+
const { currentTheme, setTheme } = useTheme();
|
|
96443
|
+
const { mode, setMode, model, setModel, domain: domain2, setDomain } = usePromptConfig();
|
|
96444
|
+
const { isTopLayer } = useKeyboardLayer();
|
|
96445
|
+
const [selectedIndex, setSelectedIndex] = import_react35.useState(0);
|
|
96446
|
+
const selectedIndexRef = import_react35.useRef(0);
|
|
96447
|
+
const currentModel = findSupportedChatModel(model);
|
|
96448
|
+
const currentDomain = findDomain(domain2);
|
|
96449
|
+
const openDialogRef = import_react35.useRef(undefined);
|
|
96450
|
+
const openDialog = import_react35.useCallback((item) => {
|
|
96451
|
+
switch (item) {
|
|
96452
|
+
case "theme":
|
|
96453
|
+
dialog.open({ title: "Select Theme", children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ThemeDialogContent, {}, undefined, false, undefined, this) });
|
|
96454
|
+
break;
|
|
96455
|
+
case "mode":
|
|
96456
|
+
dialog.open({ title: "Select Mode", children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(AgentsDialogContent, {
|
|
96457
|
+
currentMode: mode,
|
|
96458
|
+
onSelectMode: setMode
|
|
96459
|
+
}, undefined, false, undefined, this) });
|
|
96460
|
+
break;
|
|
96461
|
+
case "model":
|
|
96462
|
+
dialog.open({ title: "Select Model", children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ModelsDialogContent, {
|
|
96463
|
+
models: SUPPORTED_CHAT_MODELS,
|
|
96464
|
+
onSelectModel: setModel
|
|
96465
|
+
}, undefined, false, undefined, this) });
|
|
96466
|
+
break;
|
|
96467
|
+
case "domain":
|
|
96468
|
+
dialog.open({ title: "Select Domain", children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DomainsDialogContent, {
|
|
96469
|
+
onSelectDomain: setDomain
|
|
96470
|
+
}, undefined, false, undefined, this) });
|
|
96471
|
+
break;
|
|
96472
|
+
}
|
|
96473
|
+
}, [dialog, mode, setMode, setModel, setDomain]);
|
|
96474
|
+
openDialogRef.current = openDialog;
|
|
96475
|
+
useKeyboard((key) => {
|
|
96476
|
+
if (!isTopLayer("dialog"))
|
|
96477
|
+
return;
|
|
96478
|
+
if (key.name === "down") {
|
|
96479
|
+
setSelectedIndex((i) => {
|
|
96480
|
+
const next = Math.min(ITEMS.length - 1, i + 1);
|
|
96481
|
+
selectedIndexRef.current = next;
|
|
96482
|
+
return next;
|
|
96483
|
+
});
|
|
96484
|
+
} else if (key.name === "up") {
|
|
96485
|
+
setSelectedIndex((i) => {
|
|
96486
|
+
const next = Math.max(0, i - 1);
|
|
96487
|
+
selectedIndexRef.current = next;
|
|
96488
|
+
return next;
|
|
96489
|
+
});
|
|
96490
|
+
} else if (key.name === "enter" || key.name === "return") {
|
|
96491
|
+
openDialogRef.current?.(ITEMS[selectedIndexRef.current]);
|
|
96492
|
+
}
|
|
96493
|
+
});
|
|
96494
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96495
|
+
flexDirection: "column",
|
|
96496
|
+
gap: 1,
|
|
96497
|
+
children: [
|
|
96498
|
+
ITEMS.map((item, i) => {
|
|
96499
|
+
const isSelected = i === selectedIndex;
|
|
96500
|
+
const bgColor = isSelected ? currentTheme.colors.selectMode : undefined;
|
|
96501
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96502
|
+
flexDirection: "row",
|
|
96503
|
+
justifyContent: "space-between",
|
|
96504
|
+
alignItems: "center",
|
|
96505
|
+
backgroundColor: bgColor,
|
|
96506
|
+
onMouseDown: () => openDialogRef.current?.(item),
|
|
96507
|
+
children: [
|
|
96508
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96509
|
+
selectable: false,
|
|
96510
|
+
fg: isSelected ? "black" : undefined,
|
|
96511
|
+
children: item.charAt(0).toUpperCase() + item.slice(1)
|
|
96512
|
+
}, undefined, false, undefined, this),
|
|
96513
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96514
|
+
flexDirection: "row",
|
|
96515
|
+
gap: 1,
|
|
96516
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96517
|
+
selectable: false,
|
|
96518
|
+
fg: isSelected ? "black" : currentTheme.colors.primary,
|
|
96519
|
+
children: [
|
|
96520
|
+
item === "theme" && currentTheme.name,
|
|
96521
|
+
item === "mode" && mode,
|
|
96522
|
+
item === "model" && (currentModel?.id ?? model),
|
|
96523
|
+
item === "domain" && (currentDomain?.name ?? domain2)
|
|
96524
|
+
]
|
|
96525
|
+
}, undefined, true, undefined, this)
|
|
96526
|
+
}, undefined, false, undefined, this)
|
|
96527
|
+
]
|
|
96528
|
+
}, item, true, undefined, this);
|
|
96529
|
+
}),
|
|
96530
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96531
|
+
paddingTop: 1,
|
|
96532
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96533
|
+
attributes: TextAttributes.DIM,
|
|
96534
|
+
children: [
|
|
96535
|
+
"v",
|
|
96536
|
+
package_default2.version,
|
|
96537
|
+
hasUpdate() ? ` \u2192 v${getLatestVersion()} available` : "",
|
|
96538
|
+
" | ",
|
|
96539
|
+
"LupaCode AI Coding Assistant"
|
|
96540
|
+
]
|
|
96541
|
+
}, undefined, true, undefined, this)
|
|
96542
|
+
}, undefined, false, undefined, this)
|
|
96543
|
+
]
|
|
96544
|
+
}, undefined, true, undefined, this);
|
|
96545
|
+
};
|
|
96546
|
+
// src/components/dialogs/keyboard-help-dialog.tsx
|
|
96547
|
+
var shortcuts = [
|
|
96548
|
+
{ key: "tab", description: "Toggle Build/Plan mode" },
|
|
96549
|
+
{ key: "ctrl+d", description: "Switch domain" },
|
|
96550
|
+
{ key: "ctrl+s", description: "Open settings" },
|
|
96551
|
+
{ key: "ctrl+r", description: "Regenerate last assistant response" },
|
|
96552
|
+
{ key: "e", description: "Edit last user message" },
|
|
96553
|
+
{ key: "escape", description: "Interrupt response / Cancel / Close dialog" }
|
|
96554
|
+
];
|
|
96555
|
+
var KeyboardHelpDialogContent = () => {
|
|
96556
|
+
const { colors } = useTheme();
|
|
96557
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96558
|
+
flexDirection: "column",
|
|
96559
|
+
gap: 1,
|
|
96560
|
+
children: shortcuts.map(({ key, description }) => /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96561
|
+
flexDirection: "row",
|
|
96562
|
+
gap: 2,
|
|
96563
|
+
children: [
|
|
96564
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
96565
|
+
width: 14,
|
|
96566
|
+
flexShrink: 0,
|
|
96567
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96568
|
+
fg: colors.primary,
|
|
96569
|
+
children: key
|
|
96570
|
+
}, undefined, false, undefined, this)
|
|
96571
|
+
}, undefined, false, undefined, this),
|
|
96572
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
96573
|
+
attributes: TextAttributes.DIM,
|
|
96574
|
+
children: description
|
|
96575
|
+
}, undefined, false, undefined, this)
|
|
96576
|
+
]
|
|
96577
|
+
}, key, true, undefined, this))
|
|
96578
|
+
}, undefined, false, undefined, this);
|
|
96579
|
+
};
|
|
95763
96580
|
// src/components/status-bar.tsx
|
|
95764
96581
|
function StatusBar() {
|
|
95765
96582
|
const { colors } = useTheme();
|
|
@@ -96703,15 +97520,15 @@ function CommandMenu({
|
|
|
96703
97520
|
}
|
|
96704
97521
|
|
|
96705
97522
|
// src/components/command-menu/use-command-menu.ts
|
|
96706
|
-
var
|
|
97523
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
96707
97524
|
function useCommandMenu() {
|
|
96708
|
-
const [textValue, setTextValue] =
|
|
96709
|
-
const [selectedIndex, setSelectedIndex] =
|
|
96710
|
-
const [showCommandMenu, setShowCommandMenu] =
|
|
96711
|
-
const scrollRef =
|
|
97525
|
+
const [textValue, setTextValue] = import_react37.useState("");
|
|
97526
|
+
const [selectedIndex, setSelectedIndex] = import_react37.useState(0);
|
|
97527
|
+
const [showCommandMenu, setShowCommandMenu] = import_react37.useState(false);
|
|
97528
|
+
const scrollRef = import_react37.useRef(null);
|
|
96712
97529
|
const { push, pop, isTopLayer } = useKeyboardLayer();
|
|
96713
97530
|
const commandQuery = showCommandMenu && textValue.startsWith("/") ? textValue.slice(1) : "";
|
|
96714
|
-
const filteredCommands =
|
|
97531
|
+
const filteredCommands = import_react37.useMemo(() => getFilteredCommands(commandQuery), [commandQuery]);
|
|
96715
97532
|
const close = () => {
|
|
96716
97533
|
setShowCommandMenu(false);
|
|
96717
97534
|
pop("command");
|
|
@@ -96724,13 +97541,15 @@ function useCommandMenu() {
|
|
|
96724
97541
|
scrollbox.scrollTo(0);
|
|
96725
97542
|
}
|
|
96726
97543
|
const prefix = text2.startsWith("/") ? text2.slice(1) : null;
|
|
96727
|
-
|
|
97544
|
+
const wasShowing = showCommandMenu;
|
|
97545
|
+
const shouldShow = prefix !== null && !prefix.includes(" ");
|
|
97546
|
+
if (shouldShow && !wasShowing) {
|
|
96728
97547
|
setShowCommandMenu(true);
|
|
96729
97548
|
push("command", () => {
|
|
96730
97549
|
close();
|
|
96731
97550
|
return true;
|
|
96732
97551
|
});
|
|
96733
|
-
} else {
|
|
97552
|
+
} else if (!shouldShow && wasShowing) {
|
|
96734
97553
|
close();
|
|
96735
97554
|
}
|
|
96736
97555
|
};
|
|
@@ -96968,19 +97787,19 @@ var TEXTAREA_KEY_BINDINGS = [
|
|
|
96968
97787
|
];
|
|
96969
97788
|
function InputBar({ onSubmit, disabled = false }) {
|
|
96970
97789
|
const { mode, toggleMode, setMode, setModel, domain: domain2, setDomain } = usePromptConfig();
|
|
96971
|
-
const textareaRef =
|
|
96972
|
-
const onSubmitRef =
|
|
96973
|
-
const activeMentionRef =
|
|
96974
|
-
const mentionScrollRef =
|
|
97790
|
+
const textareaRef = import_react39.useRef(null);
|
|
97791
|
+
const onSubmitRef = import_react39.useRef(() => {});
|
|
97792
|
+
const activeMentionRef = import_react39.useRef(null);
|
|
97793
|
+
const mentionScrollRef = import_react39.useRef(null);
|
|
96975
97794
|
const renderer = useRenderer();
|
|
96976
97795
|
const toast = useToast();
|
|
96977
97796
|
const navigate = useNavigate();
|
|
96978
97797
|
const dialog = useDialog();
|
|
96979
97798
|
const { colors } = useTheme();
|
|
96980
97799
|
const { isTopLayer, setResponder, push, pop } = useKeyboardLayer();
|
|
96981
|
-
const [activeMention, setActiveMention] =
|
|
96982
|
-
const [mentionCandidates, setMentionCandidates] =
|
|
96983
|
-
const [mentionSelectedIndex, setMentionSelectedIndex] =
|
|
97800
|
+
const [activeMention, setActiveMention] = import_react39.useState(null);
|
|
97801
|
+
const [mentionCandidates, setMentionCandidates] = import_react39.useState([]);
|
|
97802
|
+
const [mentionSelectedIndex, setMentionSelectedIndex] = import_react39.useState(0);
|
|
96984
97803
|
const {
|
|
96985
97804
|
showCommandMenu,
|
|
96986
97805
|
commandQuery,
|
|
@@ -96991,13 +97810,13 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
96991
97810
|
setSelectedIndex
|
|
96992
97811
|
} = useCommandMenu();
|
|
96993
97812
|
const showMentionMenu = activeMention !== null;
|
|
96994
|
-
const closeMentionMenu =
|
|
97813
|
+
const closeMentionMenu = import_react39.useCallback(() => {
|
|
96995
97814
|
activeMentionRef.current = null;
|
|
96996
97815
|
setActiveMention(null);
|
|
96997
97816
|
setMentionCandidates([]);
|
|
96998
97817
|
pop("mention");
|
|
96999
97818
|
}, [pop]);
|
|
97000
|
-
const syncMentionMenu =
|
|
97819
|
+
const syncMentionMenu = import_react39.useCallback((text2, cursorOffset) => {
|
|
97001
97820
|
const nextMention = findActiveMention(text2, cursorOffset);
|
|
97002
97821
|
const previousMention = activeMentionRef.current;
|
|
97003
97822
|
const mentionChanged = previousMention?.start !== nextMention?.start || previousMention?.end !== nextMention?.end || previousMention?.query !== nextMention?.query;
|
|
@@ -97007,18 +97826,20 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97007
97826
|
}
|
|
97008
97827
|
return;
|
|
97009
97828
|
}
|
|
97829
|
+
if (!previousMention) {
|
|
97830
|
+
push("mention", () => {
|
|
97831
|
+
closeMentionMenu();
|
|
97832
|
+
return true;
|
|
97833
|
+
});
|
|
97834
|
+
}
|
|
97010
97835
|
activeMentionRef.current = nextMention;
|
|
97011
97836
|
setActiveMention(nextMention);
|
|
97012
|
-
push("mention", () => {
|
|
97013
|
-
closeMentionMenu();
|
|
97014
|
-
return true;
|
|
97015
|
-
});
|
|
97016
97837
|
if (mentionChanged) {
|
|
97017
97838
|
setMentionSelectedIndex(0);
|
|
97018
97839
|
mentionScrollRef.current?.scrollTo(0);
|
|
97019
97840
|
}
|
|
97020
97841
|
}, [closeMentionMenu, push]);
|
|
97021
|
-
const handleTextareaContentChange =
|
|
97842
|
+
const handleTextareaContentChange = import_react39.useCallback(() => {
|
|
97022
97843
|
const textarea = textareaRef.current;
|
|
97023
97844
|
if (!textarea)
|
|
97024
97845
|
return;
|
|
@@ -97026,7 +97847,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97026
97847
|
handleContentChange(textarea.plainText);
|
|
97027
97848
|
syncMentionMenu(text2, textarea.cursorOffset);
|
|
97028
97849
|
}, [handleContentChange, syncMentionMenu]);
|
|
97029
|
-
const handleSubmit =
|
|
97850
|
+
const handleSubmit = import_react39.useCallback(() => {
|
|
97030
97851
|
if (disabled)
|
|
97031
97852
|
return;
|
|
97032
97853
|
const textarea = textareaRef.current;
|
|
@@ -97038,7 +97859,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97038
97859
|
onSubmit(text2);
|
|
97039
97860
|
textarea.setText("");
|
|
97040
97861
|
}, [disabled, onSubmit]);
|
|
97041
|
-
const handleMentionExecute =
|
|
97862
|
+
const handleMentionExecute = import_react39.useCallback((index) => {
|
|
97042
97863
|
const textarea = textareaRef.current;
|
|
97043
97864
|
const mention = activeMentionRef.current;
|
|
97044
97865
|
const candidate = mentionCandidates[index];
|
|
@@ -97050,13 +97871,13 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97050
97871
|
textarea.cursorOffset = mention.start + insertion.length + 1;
|
|
97051
97872
|
syncMentionMenu(nextText, textarea.cursorOffset);
|
|
97052
97873
|
}, [mentionCandidates, syncMentionMenu]);
|
|
97053
|
-
const handleTextareaCursorChange =
|
|
97874
|
+
const handleTextareaCursorChange = import_react39.useCallback(() => {
|
|
97054
97875
|
const textarea = textareaRef.current;
|
|
97055
97876
|
if (!textarea)
|
|
97056
97877
|
return;
|
|
97057
97878
|
syncMentionMenu(textarea.plainText, textarea.cursorOffset);
|
|
97058
97879
|
}, [syncMentionMenu]);
|
|
97059
|
-
const handleCommand =
|
|
97880
|
+
const handleCommand = import_react39.useCallback((command) => {
|
|
97060
97881
|
const textarea = textareaRef.current;
|
|
97061
97882
|
if (!textarea || !command)
|
|
97062
97883
|
return;
|
|
@@ -97076,11 +97897,11 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97076
97897
|
textarea.insertText(command.value + " ");
|
|
97077
97898
|
}
|
|
97078
97899
|
}, [renderer, toast, dialog, navigate, mode, setMode, setModel, setDomain]);
|
|
97079
|
-
const handleCommandExecute =
|
|
97900
|
+
const handleCommandExecute = import_react39.useCallback((index) => {
|
|
97080
97901
|
const command = resolveCommand(index);
|
|
97081
97902
|
handleCommand(command);
|
|
97082
97903
|
}, [resolveCommand, handleCommand]);
|
|
97083
|
-
|
|
97904
|
+
import_react39.useEffect(() => {
|
|
97084
97905
|
if (!activeMention) {
|
|
97085
97906
|
setMentionCandidates([]);
|
|
97086
97907
|
return;
|
|
@@ -97103,7 +97924,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97103
97924
|
ignore = true;
|
|
97104
97925
|
};
|
|
97105
97926
|
}, [activeMention]);
|
|
97106
|
-
|
|
97927
|
+
import_react39.useEffect(() => {
|
|
97107
97928
|
const textare = textareaRef.current;
|
|
97108
97929
|
if (!textare)
|
|
97109
97930
|
return;
|
|
@@ -97146,8 +97967,22 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97146
97967
|
}, undefined, false, undefined, this)
|
|
97147
97968
|
});
|
|
97148
97969
|
}
|
|
97970
|
+
if (key.name === "s" && key.ctrl) {
|
|
97971
|
+
key.preventDefault();
|
|
97972
|
+
dialog.open({
|
|
97973
|
+
title: "Settings",
|
|
97974
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(SettingsDialogContent, {}, undefined, false, undefined, this)
|
|
97975
|
+
});
|
|
97976
|
+
}
|
|
97977
|
+
if (key.name === "?" && !key.ctrl) {
|
|
97978
|
+
key.preventDefault();
|
|
97979
|
+
dialog.open({
|
|
97980
|
+
title: "Keyboard Shortcuts",
|
|
97981
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(KeyboardHelpDialogContent, {}, undefined, false, undefined, this)
|
|
97982
|
+
});
|
|
97983
|
+
}
|
|
97149
97984
|
});
|
|
97150
|
-
|
|
97985
|
+
import_react39.useEffect(() => {
|
|
97151
97986
|
setResponder("base", () => {
|
|
97152
97987
|
if (disabled)
|
|
97153
97988
|
return false;
|
|
@@ -97265,7 +98100,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97265
98100
|
function Home() {
|
|
97266
98101
|
const navigate = useNavigate();
|
|
97267
98102
|
const { mode, model, domain: domain2 } = usePromptConfig();
|
|
97268
|
-
const handleSubmit =
|
|
98103
|
+
const handleSubmit = import_react41.useCallback((text2) => {
|
|
97269
98104
|
navigate("/sessions/new", { state: { message: text2, mode, model, domain: domain2 } });
|
|
97270
98105
|
}, [navigate, mode, model, domain2]);
|
|
97271
98106
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -97289,27 +98124,51 @@ function Home() {
|
|
|
97289
98124
|
}, undefined, false, undefined, this),
|
|
97290
98125
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
97291
98126
|
flexDirection: "row",
|
|
97292
|
-
|
|
97293
|
-
|
|
97294
|
-
marginLeft: "auto",
|
|
98127
|
+
justifyContent: "space-between",
|
|
98128
|
+
width: "100%",
|
|
97295
98129
|
children: [
|
|
97296
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
97297
|
-
children: "tab"
|
|
97298
|
-
}, undefined, false, undefined, this),
|
|
97299
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
97300
|
-
attributes: TextAttributes.DIM,
|
|
97301
|
-
children: "agents"
|
|
97302
|
-
}, undefined, false, undefined, this),
|
|
97303
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
97304
|
-
children: "\xB7"
|
|
97305
|
-
}, undefined, false, undefined, this),
|
|
97306
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
97307
|
-
children: "ctrl+d"
|
|
97308
|
-
}, undefined, false, undefined, this),
|
|
97309
98130
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
97310
98131
|
attributes: TextAttributes.DIM,
|
|
97311
|
-
children:
|
|
97312
|
-
|
|
98132
|
+
children: [
|
|
98133
|
+
"v",
|
|
98134
|
+
package_default2.version,
|
|
98135
|
+
hasUpdate() ? ` \u2192 v${getLatestVersion() ?? ""} (npm i -g lupacode)` : ""
|
|
98136
|
+
]
|
|
98137
|
+
}, undefined, true, undefined, this),
|
|
98138
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
98139
|
+
flexDirection: "row",
|
|
98140
|
+
gap: 1,
|
|
98141
|
+
flexShrink: 0,
|
|
98142
|
+
children: [
|
|
98143
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98144
|
+
children: "tab"
|
|
98145
|
+
}, undefined, false, undefined, this),
|
|
98146
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98147
|
+
attributes: TextAttributes.DIM,
|
|
98148
|
+
children: "agents"
|
|
98149
|
+
}, undefined, false, undefined, this),
|
|
98150
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98151
|
+
children: "\xB7"
|
|
98152
|
+
}, undefined, false, undefined, this),
|
|
98153
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98154
|
+
children: "ctrl+d"
|
|
98155
|
+
}, undefined, false, undefined, this),
|
|
98156
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98157
|
+
attributes: TextAttributes.DIM,
|
|
98158
|
+
children: "domains"
|
|
98159
|
+
}, undefined, false, undefined, this),
|
|
98160
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98161
|
+
children: "\xB7"
|
|
98162
|
+
}, undefined, false, undefined, this),
|
|
98163
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98164
|
+
children: "ctrl+s"
|
|
98165
|
+
}, undefined, false, undefined, this),
|
|
98166
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98167
|
+
attributes: TextAttributes.DIM,
|
|
98168
|
+
children: "settings"
|
|
98169
|
+
}, undefined, false, undefined, this)
|
|
98170
|
+
]
|
|
98171
|
+
}, undefined, true, undefined, this)
|
|
97313
98172
|
]
|
|
97314
98173
|
}, undefined, true, undefined, this)
|
|
97315
98174
|
]
|
|
@@ -97319,7 +98178,7 @@ function Home() {
|
|
|
97319
98178
|
}
|
|
97320
98179
|
|
|
97321
98180
|
// src/screens/new-session.tsx
|
|
97322
|
-
var
|
|
98181
|
+
var import_react44 = __toESM(require_react(), 1);
|
|
97323
98182
|
|
|
97324
98183
|
// src/components/messages/error-message.tsx
|
|
97325
98184
|
function ErrorMessage({ message: message2 }) {
|
|
@@ -97510,6 +98369,7 @@ function prettyMilliseconds(milliseconds, options) {
|
|
|
97510
98369
|
}
|
|
97511
98370
|
|
|
97512
98371
|
// src/components/messages/bot-message.tsx
|
|
98372
|
+
var globalSyntaxStyle = SyntaxStyle.create();
|
|
97513
98373
|
function formatToolName(name23) {
|
|
97514
98374
|
return name23.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
|
|
97515
98375
|
}
|
|
@@ -97664,8 +98524,10 @@ function BotMessage({
|
|
|
97664
98524
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
97665
98525
|
paddingX: 3,
|
|
97666
98526
|
width: "100%",
|
|
97667
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("
|
|
97668
|
-
|
|
98527
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("markdown", {
|
|
98528
|
+
content: part.text,
|
|
98529
|
+
syntaxStyle: globalSyntaxStyle,
|
|
98530
|
+
conceal: true
|
|
97669
98531
|
}, undefined, false, undefined, this)
|
|
97670
98532
|
}, `text-${j2}`, false, undefined, this);
|
|
97671
98533
|
}
|
|
@@ -99749,17 +100611,27 @@ function SessionShell({
|
|
|
99749
100611
|
flexDirection: "row",
|
|
99750
100612
|
alignItems: "center",
|
|
99751
100613
|
gap: 2,
|
|
99752
|
-
children:
|
|
99753
|
-
|
|
99754
|
-
|
|
99755
|
-
|
|
99756
|
-
|
|
99757
|
-
|
|
99758
|
-
|
|
99759
|
-
|
|
99760
|
-
|
|
99761
|
-
|
|
99762
|
-
|
|
100614
|
+
children: [
|
|
100615
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
100616
|
+
attributes: TextAttributes.DIM,
|
|
100617
|
+
children: [
|
|
100618
|
+
"v",
|
|
100619
|
+
package_default2.version,
|
|
100620
|
+
hasUpdate() ? ` \u2192 v${getLatestVersion() ?? ""} (npm i -g lupacode)` : ""
|
|
100621
|
+
]
|
|
100622
|
+
}, undefined, true, undefined, this),
|
|
100623
|
+
loading ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
100624
|
+
children: [
|
|
100625
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(Spinner, {
|
|
100626
|
+
mode
|
|
100627
|
+
}, undefined, false, undefined, this),
|
|
100628
|
+
interruptible ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
100629
|
+
children: "esc to interrupt"
|
|
100630
|
+
}, undefined, false, undefined, this) : null
|
|
100631
|
+
]
|
|
100632
|
+
}, undefined, true, undefined, this) : null
|
|
100633
|
+
]
|
|
100634
|
+
}, undefined, true, undefined, this),
|
|
99763
100635
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99764
100636
|
flexDirection: "row",
|
|
99765
100637
|
gap: 1,
|
|
@@ -99782,6 +100654,16 @@ function SessionShell({
|
|
|
99782
100654
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99783
100655
|
attributes: TextAttributes.DIM,
|
|
99784
100656
|
children: "domains"
|
|
100657
|
+
}, undefined, false, undefined, this),
|
|
100658
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
100659
|
+
children: "\xB7"
|
|
100660
|
+
}, undefined, false, undefined, this),
|
|
100661
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
100662
|
+
children: "ctrl+s"
|
|
100663
|
+
}, undefined, false, undefined, this),
|
|
100664
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
100665
|
+
attributes: TextAttributes.DIM,
|
|
100666
|
+
children: "settings"
|
|
99785
100667
|
}, undefined, false, undefined, this)
|
|
99786
100668
|
]
|
|
99787
100669
|
}, undefined, true, undefined, this)
|
|
@@ -99802,17 +100684,17 @@ function NewSession() {
|
|
|
99802
100684
|
const navigate = useNavigate();
|
|
99803
100685
|
const location = useLocation();
|
|
99804
100686
|
const toast = useToast();
|
|
99805
|
-
const hasStartedRef =
|
|
99806
|
-
const state =
|
|
100687
|
+
const hasStartedRef = import_react44.useRef(false);
|
|
100688
|
+
const state = import_react44.useMemo(() => {
|
|
99807
100689
|
const parsed = newSessionStateSchema.safeParse(location.state);
|
|
99808
100690
|
return parsed.success ? parsed.data : null;
|
|
99809
100691
|
}, [location.state]);
|
|
99810
|
-
|
|
100692
|
+
import_react44.useEffect(() => {
|
|
99811
100693
|
if (!state?.message) {
|
|
99812
100694
|
navigate("/", { replace: true });
|
|
99813
100695
|
}
|
|
99814
100696
|
}, [state, navigate]);
|
|
99815
|
-
|
|
100697
|
+
import_react44.useEffect(() => {
|
|
99816
100698
|
if (!state || hasStartedRef.current)
|
|
99817
100699
|
return;
|
|
99818
100700
|
hasStartedRef.current = true;
|
|
@@ -99860,13 +100742,13 @@ function NewSession() {
|
|
|
99860
100742
|
}
|
|
99861
100743
|
|
|
99862
100744
|
// src/screens/sessions.tsx
|
|
99863
|
-
var
|
|
100745
|
+
var import_react53 = __toESM(require_react(), 1);
|
|
99864
100746
|
|
|
99865
100747
|
// src/hooks/use-chat.ts
|
|
99866
|
-
var
|
|
100748
|
+
var import_react51 = __toESM(require_react(), 1);
|
|
99867
100749
|
|
|
99868
100750
|
// ../../node_modules/@ai-sdk/react/dist/index.js
|
|
99869
|
-
var
|
|
100751
|
+
var import_react45 = __toESM(require_react(), 1);
|
|
99870
100752
|
|
|
99871
100753
|
// ../../node_modules/@ai-sdk/react/node_modules/@ai-sdk/provider/dist/index.js
|
|
99872
100754
|
var marker23 = "vercel.ai.error";
|
|
@@ -104619,11 +105501,11 @@ var AbstractChat = class {
|
|
|
104619
105501
|
|
|
104620
105502
|
// ../../node_modules/@ai-sdk/react/dist/index.js
|
|
104621
105503
|
var import_throttleit = __toESM(require_throttleit(), 1);
|
|
104622
|
-
var import_react43 = __toESM(require_react(), 1);
|
|
104623
|
-
var import_react44 = __toESM(require_react(), 1);
|
|
104624
|
-
var import_react45 = __toESM(require_react(), 1);
|
|
104625
105504
|
var import_react46 = __toESM(require_react(), 1);
|
|
104626
105505
|
var import_react47 = __toESM(require_react(), 1);
|
|
105506
|
+
var import_react48 = __toESM(require_react(), 1);
|
|
105507
|
+
var import_react49 = __toESM(require_react(), 1);
|
|
105508
|
+
var import_react50 = __toESM(require_react(), 1);
|
|
104627
105509
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
104628
105510
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
104629
105511
|
var __accessCheck = (obj, member, msg) => {
|
|
@@ -104760,7 +105642,7 @@ function useChat({
|
|
|
104760
105642
|
resume = false,
|
|
104761
105643
|
...options
|
|
104762
105644
|
} = {}) {
|
|
104763
|
-
const callbacksRef =
|
|
105645
|
+
const callbacksRef = import_react45.useRef(!("chat" in options) ? {
|
|
104764
105646
|
onToolCall: options.onToolCall,
|
|
104765
105647
|
onData: options.onData,
|
|
104766
105648
|
onFinish: options.onFinish,
|
|
@@ -104799,22 +105681,22 @@ function useChat({
|
|
|
104799
105681
|
return (_c = (_b17 = (_a29 = callbacksRef.current).sendAutomaticallyWhen) == null ? undefined : _b17.call(_a29, arg)) != null ? _c : false;
|
|
104800
105682
|
}
|
|
104801
105683
|
};
|
|
104802
|
-
const chatRef =
|
|
105684
|
+
const chatRef = import_react45.useRef("chat" in options ? options.chat : new Chat(optionsWithCallbacks));
|
|
104803
105685
|
const shouldRecreateChat = "chat" in options && options.chat !== chatRef.current || "id" in options && chatRef.current.id !== options.id;
|
|
104804
105686
|
if (shouldRecreateChat) {
|
|
104805
105687
|
chatRef.current = "chat" in options ? options.chat : new Chat(optionsWithCallbacks);
|
|
104806
105688
|
}
|
|
104807
|
-
const subscribeToMessages =
|
|
104808
|
-
const messages =
|
|
104809
|
-
const status =
|
|
104810
|
-
const error51 =
|
|
104811
|
-
const setMessages =
|
|
105689
|
+
const subscribeToMessages = import_react45.useCallback((update) => chatRef.current["~registerMessagesCallback"](update, throttleWaitMs), [throttleWaitMs, chatRef.current.id]);
|
|
105690
|
+
const messages = import_react45.useSyncExternalStore(subscribeToMessages, () => chatRef.current.messages, () => chatRef.current.messages);
|
|
105691
|
+
const status = import_react45.useSyncExternalStore(chatRef.current["~registerStatusCallback"], () => chatRef.current.status, () => chatRef.current.status);
|
|
105692
|
+
const error51 = import_react45.useSyncExternalStore(chatRef.current["~registerErrorCallback"], () => chatRef.current.error, () => chatRef.current.error);
|
|
105693
|
+
const setMessages = import_react45.useCallback((messagesParam) => {
|
|
104812
105694
|
if (typeof messagesParam === "function") {
|
|
104813
105695
|
messagesParam = messagesParam(chatRef.current.messages);
|
|
104814
105696
|
}
|
|
104815
105697
|
chatRef.current.messages = messagesParam;
|
|
104816
105698
|
}, [chatRef]);
|
|
104817
|
-
|
|
105699
|
+
import_react45.useEffect(() => {
|
|
104818
105700
|
if (resume) {
|
|
104819
105701
|
chatRef.current.resumeStream();
|
|
104820
105702
|
}
|
|
@@ -104838,7 +105720,7 @@ function useChat({
|
|
|
104838
105720
|
|
|
104839
105721
|
// src/lib/local-tools.ts
|
|
104840
105722
|
import { mkdir as mkdir2, readFile as readFile2, readdir as readdir2, stat, writeFile as writeFile2 } from "fs/promises";
|
|
104841
|
-
import { dirname as dirname2, isAbsolute as isAbsolute5, join as
|
|
105723
|
+
import { dirname as dirname2, isAbsolute as isAbsolute5, join as join5, relative as relative2, resolve as resolve7 } from "path";
|
|
104842
105724
|
var MAX_FILE_SIZE = 1e4;
|
|
104843
105725
|
var MAX_RESULTS = 200;
|
|
104844
105726
|
var MAX_MATCHES = 50;
|
|
@@ -104875,7 +105757,7 @@ async function executeLocalTool(toolName, input, mode) {
|
|
|
104875
105757
|
for (const entry of entries) {
|
|
104876
105758
|
if (entry.startsWith(".") || entry === "node_modules")
|
|
104877
105759
|
continue;
|
|
104878
|
-
const info = await stat(
|
|
105760
|
+
const info = await stat(join5(resolved, entry));
|
|
104879
105761
|
results.push({ name: entry, type: info.isDirectory() ? "directory" : "file" });
|
|
104880
105762
|
}
|
|
104881
105763
|
results.sort((a2, b2) => a2.type !== b2.type ? a2.type === "directory" ? -1 : 1 : a2.name.localeCompare(b2.name));
|
|
@@ -104993,7 +105875,7 @@ async function executeLocalTool(toolName, input, mode) {
|
|
|
104993
105875
|
|
|
104994
105876
|
// src/hooks/use-chat.ts
|
|
104995
105877
|
function useChat2(sessionId, initialMessages) {
|
|
104996
|
-
const transport =
|
|
105878
|
+
const transport = import_react51.useMemo(() => {
|
|
104997
105879
|
return new DefaultChatTransport({
|
|
104998
105880
|
api: apiClient.chat.$url().toString(),
|
|
104999
105881
|
headers() {
|
|
@@ -105051,6 +105933,9 @@ function useChat2(sessionId, initialMessages) {
|
|
|
105051
105933
|
}
|
|
105052
105934
|
});
|
|
105053
105935
|
},
|
|
105936
|
+
append: chat.append,
|
|
105937
|
+
setMessages: chat.setMessages,
|
|
105938
|
+
reload: chat.reload,
|
|
105054
105939
|
abort: chat.stop,
|
|
105055
105940
|
interrupt: chat.stop
|
|
105056
105941
|
};
|
|
@@ -105081,16 +105966,34 @@ function ChatMessage({ msg }) {
|
|
|
105081
105966
|
streaming: false
|
|
105082
105967
|
}, undefined, false, undefined, this);
|
|
105083
105968
|
}
|
|
105969
|
+
function EditMessageDialog({
|
|
105970
|
+
initialText,
|
|
105971
|
+
onResolve,
|
|
105972
|
+
onSubmit
|
|
105973
|
+
}) {
|
|
105974
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
105975
|
+
flexDirection: "column",
|
|
105976
|
+
gap: 1,
|
|
105977
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
|
|
105978
|
+
focused: true,
|
|
105979
|
+
initialValue: initialText,
|
|
105980
|
+
onContentChange: (v2) => onResolve(v2),
|
|
105981
|
+
onSubmit
|
|
105982
|
+
}, undefined, false, undefined, this)
|
|
105983
|
+
}, undefined, false, undefined, this);
|
|
105984
|
+
}
|
|
105084
105985
|
function SessionChat({
|
|
105085
105986
|
session,
|
|
105086
105987
|
initialPrompt
|
|
105087
105988
|
}) {
|
|
105088
|
-
const [initialMessages] =
|
|
105989
|
+
const [initialMessages] = import_react53.useState(() => session.messages);
|
|
105089
105990
|
const { mode, model, domain: domain2 } = usePromptConfig();
|
|
105090
105991
|
const { isTopLayer } = useKeyboardLayer();
|
|
105091
|
-
const { messages, status, submit, abort, interrupt, error: error51 } = useChat2(session.id, initialMessages);
|
|
105092
|
-
const hasSubmittedInitialPromptRef =
|
|
105093
|
-
|
|
105992
|
+
const { messages, status, submit, setMessages, reload, abort, interrupt, error: error51 } = useChat2(session.id, initialMessages);
|
|
105993
|
+
const hasSubmittedInitialPromptRef = import_react53.useRef(false);
|
|
105994
|
+
const toast = useToast();
|
|
105995
|
+
const dialog = useDialog();
|
|
105996
|
+
import_react53.useEffect(() => {
|
|
105094
105997
|
return () => {
|
|
105095
105998
|
abort();
|
|
105096
105999
|
};
|
|
@@ -105101,7 +106004,55 @@ function SessionChat({
|
|
|
105101
106004
|
interrupt();
|
|
105102
106005
|
}
|
|
105103
106006
|
});
|
|
105104
|
-
|
|
106007
|
+
useKeyboard((key) => {
|
|
106008
|
+
if (key.name === "r" && key.ctrl && isTopLayer("base") && status !== "streaming" && status !== "submitted") {
|
|
106009
|
+
const lastMsg = messages[messages.length - 1];
|
|
106010
|
+
if (lastMsg?.role === "assistant") {
|
|
106011
|
+
key.preventDefault();
|
|
106012
|
+
reload();
|
|
106013
|
+
}
|
|
106014
|
+
}
|
|
106015
|
+
});
|
|
106016
|
+
useKeyboard((key) => {
|
|
106017
|
+
if (key.name === "e" && !key.ctrl && isTopLayer("base") && status !== "streaming" && status !== "submitted") {
|
|
106018
|
+
const lastUserMsg = messages.findLast((m2) => m2.role === "user");
|
|
106019
|
+
if (!lastUserMsg)
|
|
106020
|
+
return;
|
|
106021
|
+
key.preventDefault();
|
|
106022
|
+
const currentText = lastUserMsg.parts.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
106023
|
+
let inputValue = currentText;
|
|
106024
|
+
dialog.open({
|
|
106025
|
+
title: "Edit message",
|
|
106026
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(EditMessageDialog, {
|
|
106027
|
+
initialText: currentText,
|
|
106028
|
+
onResolve: (text3) => {
|
|
106029
|
+
inputValue = text3;
|
|
106030
|
+
},
|
|
106031
|
+
onSubmit: () => {
|
|
106032
|
+
const idx = messages.findIndex((m2) => m2.id === lastUserMsg.id);
|
|
106033
|
+
if (idx === -1)
|
|
106034
|
+
return;
|
|
106035
|
+
const text3 = inputValue.trim();
|
|
106036
|
+
if (!text3)
|
|
106037
|
+
return;
|
|
106038
|
+
const truncated = messages.slice(0, idx);
|
|
106039
|
+
const editedMsg = {
|
|
106040
|
+
...messages[idx],
|
|
106041
|
+
parts: [{ type: "text", text: text3 }]
|
|
106042
|
+
};
|
|
106043
|
+
setMessages([...truncated, editedMsg]);
|
|
106044
|
+
submit({
|
|
106045
|
+
userText: text3,
|
|
106046
|
+
mode: editedMsg.metadata?.mode ?? mode,
|
|
106047
|
+
model: editedMsg.metadata?.model ?? model
|
|
106048
|
+
});
|
|
106049
|
+
dialog.close();
|
|
106050
|
+
}
|
|
106051
|
+
}, undefined, false, undefined, this)
|
|
106052
|
+
});
|
|
106053
|
+
}
|
|
106054
|
+
});
|
|
106055
|
+
import_react53.useEffect(() => {
|
|
105105
106056
|
if (!initialPrompt || hasSubmittedInitialPromptRef.current)
|
|
105106
106057
|
return;
|
|
105107
106058
|
hasSubmittedInitialPromptRef.current = true;
|
|
@@ -105130,12 +106081,12 @@ function Session() {
|
|
|
105130
106081
|
const location = useLocation();
|
|
105131
106082
|
const navigate = useNavigate();
|
|
105132
106083
|
const toast = useToast();
|
|
105133
|
-
const prefetched =
|
|
106084
|
+
const prefetched = import_react53.useMemo(() => {
|
|
105134
106085
|
const parsed = sessionLocationSchema.safeParse(location.state);
|
|
105135
106086
|
return parsed.success ? parsed.data : null;
|
|
105136
106087
|
}, [location.state]);
|
|
105137
|
-
const [session, setSession] =
|
|
105138
|
-
|
|
106088
|
+
const [session, setSession] = import_react53.useState(prefetched?.session ?? null);
|
|
106089
|
+
import_react53.useEffect(() => {
|
|
105139
106090
|
if (prefetched?.session)
|
|
105140
106091
|
return;
|
|
105141
106092
|
setSession(null);
|
|
@@ -105202,6 +106153,8 @@ function App() {
|
|
|
105202
106153
|
router
|
|
105203
106154
|
}, undefined, false, undefined, this);
|
|
105204
106155
|
}
|
|
106156
|
+
setCurrentVersion(package_default2.version);
|
|
106157
|
+
checkForUpdate(package_default2.version);
|
|
105205
106158
|
var renderer = await createCliRenderer({
|
|
105206
106159
|
targetFps: 60,
|
|
105207
106160
|
exitOnCtrlC: false
|