fss-link 1.4.0 โ 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -24
- package/bundle/fss-link.js +250 -60
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
-
**FSS Link** is a portable, scriptable agent that links tools, models, and knowledge into
|
|
15
|
+
**FSS Link** is a portable, scriptable agent that links tools, models, and knowledge into single-instance workflows. Install anywhere with Node.js, launch one agent at a time, feed it tasks, and watch it go.
|
|
16
16
|
|
|
17
17
|
- **Lightweight distribution** (~15 MB bundle, requires Node.js 20+)
|
|
18
|
-
- **
|
|
19
|
-
- **Portable Mini-RAG** indices that travel with your projects
|
|
18
|
+
- **Single-agent workflows** with structured prompts
|
|
19
|
+
- **Portable Mini-RAG** indices that travel with your projects (planned feature)
|
|
20
20
|
- **Local-first** with LM Studio/Ollama priority
|
|
21
21
|
- **Professional tools** built in TypeScript for seamless integration
|
|
22
22
|
|
|
23
23
|
## ๐ฏ Why "Link"?
|
|
24
24
|
|
|
25
|
-
Link connects thingsโtools, models, tasks, and knowledge. **FSS Link** is a lightweight distribution that runs wherever Node.js is installed. Start an agent, or spawn
|
|
25
|
+
Link connects thingsโtools, models, tasks, and knowledge. **FSS Link** is a lightweight distribution that runs wherever Node.js is installed. Start an agent, or spawn multiple agents with templated prompts (planned feature). Each project carries its own Mini-RAG index, so knowledge travels with the work.
|
|
26
26
|
|
|
27
27
|
## ๐ Quick Start
|
|
28
28
|
|
|
@@ -33,10 +33,7 @@ fss-link
|
|
|
33
33
|
# Single-shot task
|
|
34
34
|
fss-link run "Audit the repo for security keys and open PR fixes."
|
|
35
35
|
|
|
36
|
-
#
|
|
37
|
-
fss-link spawn --count 6 --template ./templates/regression.yml
|
|
38
|
-
|
|
39
|
-
# Portable RAG - indexes travel with projects
|
|
36
|
+
# Portable RAG - indexes travel with projects (planned feature)
|
|
40
37
|
cd project && fss-link rag index . && fss-link rag query "error handling"
|
|
41
38
|
```
|
|
42
39
|
|
|
@@ -98,10 +95,17 @@ FSS Link now features an intelligent **Welcome Back dialog** that appears when y
|
|
|
98
95
|
|
|
99
96
|
- **๐ Project Status Dashboard** - Git status, session history, momentum analysis
|
|
100
97
|
- **๐ Smart Context Generation** - Priority-based information filtering (7 levels)
|
|
101
|
-
- **โก Multi-Agent Awareness** - Universal session tracking across all agents
|
|
98
|
+
- **โก Multi-Agent Awareness** - Universal session tracking across all agents (planned feature)
|
|
102
99
|
- **๐ฏ Seamless Resumption** - Intelligent context population for continuing work
|
|
103
100
|
- **๐ Production Quality** - Comprehensive error handling, performance optimization
|
|
104
101
|
|
|
102
|
+
## ๐ External Directory Access
|
|
103
|
+
|
|
104
|
+
For accessing external directories like `/tmp`, user directories, or custom paths, see:
|
|
105
|
+
[External Directory Access Guide](./fss-docs/EXTERNAL-DIRECTORY-ACCESS.md)
|
|
106
|
+
|
|
107
|
+
This documentation explains how to configure FSS Link to securely access external directories through its folder trust system.
|
|
108
|
+
|
|
105
109
|
### ๐ **Node.js Version Requirements**
|
|
106
110
|
|
|
107
111
|
FSS Link requires **Node.js 20+**. If you have an older version, upgrade first:
|
|
@@ -153,7 +157,7 @@ Built-in semantic search that travels with your projects. No Python dependencies
|
|
|
153
157
|
- **Deep Semantic Search**: Find code by describing what it does, not just what it's called
|
|
154
158
|
- **Cross-Reference Analysis**: Discover how different parts of the system interact
|
|
155
159
|
- **Context-Aware Suggestions**: Get recommendations based on the entire project context
|
|
156
|
-
- **Portable Indices**: Knowledge travels with your projects
|
|
160
|
+
- **Portable Indices**: Knowledge travels with your projects (planned feature)
|
|
157
161
|
|
|
158
162
|
### ๐ **Enhanced Task Management**
|
|
159
163
|
Built on FSS Link's native TodoWrite tool with professional enhancements for complex development workflows.
|
|
@@ -161,7 +165,7 @@ Built on FSS Link's native TodoWrite tool with professional enhancements for com
|
|
|
161
165
|
- **Persistent Task Lists**: Never lose track of what needs to be done
|
|
162
166
|
- **Visual Progress Indicators**: Instantly see what's complete, in-progress, or pending
|
|
163
167
|
- **Intelligent Task Breakdown**: Automatically decompose complex features into actionable steps
|
|
164
|
-
- **Multi-Agent Coordination**: Tasks shared across multiple agent instances
|
|
168
|
+
- **Multi-Agent Coordination**: Tasks shared across multiple agent instances (planned feature)
|
|
165
169
|
|
|
166
170
|
### ๐ **Professional Web Research**
|
|
167
171
|
TypeScript-native web research tools eliminate context switching between development and external resources.
|
|
@@ -210,7 +214,7 @@ fss-link
|
|
|
210
214
|
# Launch with specific model
|
|
211
215
|
fss-link --model qwen/qwen3-4b-2507
|
|
212
216
|
|
|
213
|
-
# Launch with RAG index
|
|
217
|
+
# Launch with RAG index (planned feature)
|
|
214
218
|
fss-link --rag ./project-index
|
|
215
219
|
```
|
|
216
220
|
|
|
@@ -222,34 +226,34 @@ fss-link run "Analyse this codebase structure"
|
|
|
222
226
|
# With specific model
|
|
223
227
|
fss-link run "Review security patterns" --model qwen/qwen3-30b-a3b-2507
|
|
224
228
|
|
|
225
|
-
# With RAG context
|
|
229
|
+
# With RAG context (planned feature)
|
|
226
230
|
fss-link run "Find authentication bugs" --rag .
|
|
227
231
|
```
|
|
228
232
|
|
|
229
|
-
### **Multi-Agent Workflows**
|
|
233
|
+
### **Multi-Agent Workflows** (Planned Feature)
|
|
230
234
|
```bash
|
|
231
|
-
# Launch multiple agents with template
|
|
235
|
+
# Launch multiple agents with template (planned feature)
|
|
232
236
|
fss-link spawn --count 8 --template ./templates/build-test.yml
|
|
233
237
|
|
|
234
|
-
# Parallel code review
|
|
238
|
+
# Parallel code review (planned feature)
|
|
235
239
|
fss-link spawn --count 4 --template ./templates/code-review.yml --files src/
|
|
236
240
|
|
|
237
|
-
# Load-balanced task processing
|
|
241
|
+
# Load-balanced task processing (planned feature)
|
|
238
242
|
fss-link spawn --count 6 --template ./templates/regression-test.yml
|
|
239
243
|
```
|
|
240
244
|
|
|
241
|
-
### **RAG Operations**
|
|
245
|
+
### **RAG Operations** (Planned Feature)
|
|
242
246
|
```bash
|
|
243
|
-
# Index current directory
|
|
247
|
+
# Index current directory (planned feature)
|
|
244
248
|
fss-link rag index .
|
|
245
249
|
|
|
246
|
-
# Index with specific extensions
|
|
250
|
+
# Index with specific extensions (planned feature)
|
|
247
251
|
fss-link rag index . --extensions py,js,md
|
|
248
252
|
|
|
249
|
-
# Query with filters
|
|
253
|
+
# Query with filters (planned feature)
|
|
250
254
|
fss-link rag query "authentication logic" --topk 5
|
|
251
255
|
|
|
252
|
-
# Cross-reference search
|
|
256
|
+
# Cross-reference search (planned feature)
|
|
253
257
|
fss-link rag query "error handling patterns" --files py,js --recent
|
|
254
258
|
```
|
|
255
259
|
|
|
@@ -338,8 +342,8 @@ FSS Link builds on [QwenLM/fss-link](https://github.com/QwenLM/fss-link), which
|
|
|
338
342
|
|
|
339
343
|
<div align="center">
|
|
340
344
|
|
|
341
|
-
**FSS Link** - *Portable, scriptable,
|
|
345
|
+
**FSS Link** - *Portable, scriptable, single-instance AI agent*
|
|
342
346
|
|
|
343
347
|
[Documentation](./FSS-LINK-IMPLEMENTATION-GUIDE.md) โข [Installation Guide](./INSTALL.md) โข [Examples](./examples/)
|
|
344
348
|
|
|
345
|
-
</div>
|
|
349
|
+
</div>
|
package/bundle/fss-link.js
CHANGED
|
@@ -22379,7 +22379,7 @@ async function createContentGeneratorConfig(config, authType) {
|
|
|
22379
22379
|
async function createContentGenerator(config, gcConfig, sessionId2) {
|
|
22380
22380
|
if (DEBUG_CONTENT)
|
|
22381
22381
|
console.log(`\u{1F41B} DEBUG createContentGenerator: authType=${config.authType}, apiKey=${config.apiKey}, baseUrl=${config.baseUrl}`);
|
|
22382
|
-
const version = "1.4.
|
|
22382
|
+
const version = "1.4.1";
|
|
22383
22383
|
const userAgent = `FSS-Link/${version} (${process.platform}; ${process.arch})`;
|
|
22384
22384
|
const baseHeaders = {
|
|
22385
22385
|
"User-Agent": userAgent
|
|
@@ -90220,7 +90220,7 @@ import React31 from "react";
|
|
|
90220
90220
|
import { render as render2 } from "ink";
|
|
90221
90221
|
|
|
90222
90222
|
// packages/cli/src/ui/App.tsx
|
|
90223
|
-
import { useCallback as useCallback29, useEffect as
|
|
90223
|
+
import { useCallback as useCallback29, useEffect as useEffect44, useMemo as useMemo9, useState as useState48, useRef as useRef12 } from "react";
|
|
90224
90224
|
import {
|
|
90225
90225
|
Box as Box59,
|
|
90226
90226
|
measureElement,
|
|
@@ -96074,7 +96074,7 @@ async function getPackageJson() {
|
|
|
96074
96074
|
// packages/cli/src/utils/version.ts
|
|
96075
96075
|
async function getCliVersion() {
|
|
96076
96076
|
const pkgJson = await getPackageJson();
|
|
96077
|
-
return "1.4.
|
|
96077
|
+
return "1.4.1";
|
|
96078
96078
|
}
|
|
96079
96079
|
|
|
96080
96080
|
// packages/cli/src/ui/commands/aboutCommand.ts
|
|
@@ -96126,7 +96126,7 @@ import open4 from "open";
|
|
|
96126
96126
|
import process11 from "node:process";
|
|
96127
96127
|
|
|
96128
96128
|
// packages/cli/src/generated/git-commit.ts
|
|
96129
|
-
var GIT_COMMIT_INFO = "
|
|
96129
|
+
var GIT_COMMIT_INFO = "b055e021";
|
|
96130
96130
|
|
|
96131
96131
|
// packages/cli/src/ui/commands/bugCommand.ts
|
|
96132
96132
|
init_dist2();
|
|
@@ -120419,8 +120419,60 @@ function LMStudioModelPrompt({
|
|
|
120419
120419
|
|
|
120420
120420
|
// packages/cli/src/ui/components/AddCustomEndpointDialog.tsx
|
|
120421
120421
|
init_dist2();
|
|
120422
|
-
import { useState as useState33 } from "react";
|
|
120422
|
+
import { useState as useState33, useEffect as useEffect32 } from "react";
|
|
120423
120423
|
import { Box as Box19, Text as Text26, useInput as useInput4 } from "ink";
|
|
120424
|
+
|
|
120425
|
+
// packages/cli/src/utils/modelFetcher.ts
|
|
120426
|
+
async function fetchModelsFromCustomEndpoint(baseUrl, providerType, apiKey) {
|
|
120427
|
+
const normalizedBase = baseUrl.replace(/\/+$/, "");
|
|
120428
|
+
const url2 = `${normalizedBase}/models`;
|
|
120429
|
+
const headers = {
|
|
120430
|
+
"Accept": "application/json"
|
|
120431
|
+
};
|
|
120432
|
+
if (apiKey && apiKey.trim() !== "") {
|
|
120433
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
120434
|
+
}
|
|
120435
|
+
try {
|
|
120436
|
+
const controller = new AbortController();
|
|
120437
|
+
const timeoutId = setTimeout(() => controller.abort(), 1e4);
|
|
120438
|
+
const response = await fetch(url2, {
|
|
120439
|
+
headers,
|
|
120440
|
+
signal: controller.signal
|
|
120441
|
+
});
|
|
120442
|
+
clearTimeout(timeoutId);
|
|
120443
|
+
if (!response.ok) {
|
|
120444
|
+
if (response.status === 401 || response.status === 403) {
|
|
120445
|
+
throw new Error("Authentication failed - check API key");
|
|
120446
|
+
}
|
|
120447
|
+
if (response.status === 404) {
|
|
120448
|
+
throw new Error("Endpoint not found - verify URL includes /v1 suffix");
|
|
120449
|
+
}
|
|
120450
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
120451
|
+
}
|
|
120452
|
+
const json3 = await response.json();
|
|
120453
|
+
if (!json3.data || !Array.isArray(json3.data)) {
|
|
120454
|
+
throw new Error("Invalid response format - expected OpenAI-compatible /models endpoint");
|
|
120455
|
+
}
|
|
120456
|
+
if (json3.data.length === 0) {
|
|
120457
|
+
throw new Error("No models available on this endpoint");
|
|
120458
|
+
}
|
|
120459
|
+
return json3.data.map((m) => ({
|
|
120460
|
+
id: m.id,
|
|
120461
|
+
ownedBy: m.owned_by || "unknown",
|
|
120462
|
+
object: m.object
|
|
120463
|
+
}));
|
|
120464
|
+
} catch (error) {
|
|
120465
|
+
if (error instanceof Error) {
|
|
120466
|
+
if (error.name === "AbortError") {
|
|
120467
|
+
throw new Error("Connection timeout - endpoint took too long to respond");
|
|
120468
|
+
}
|
|
120469
|
+
throw error;
|
|
120470
|
+
}
|
|
120471
|
+
throw new Error(`Connection failed: ${String(error)}`);
|
|
120472
|
+
}
|
|
120473
|
+
}
|
|
120474
|
+
|
|
120475
|
+
// packages/cli/src/ui/components/AddCustomEndpointDialog.tsx
|
|
120424
120476
|
import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
120425
120477
|
function AddCustomEndpointDialog({
|
|
120426
120478
|
onSubmit,
|
|
@@ -120433,11 +120485,25 @@ function AddCustomEndpointDialog({
|
|
|
120433
120485
|
const [providerType, setProviderType] = useState33(null);
|
|
120434
120486
|
const [selectedProviderIndex, setSelectedProviderIndex] = useState33(0);
|
|
120435
120487
|
const [inputBuffer, setInputBuffer] = useState33("");
|
|
120488
|
+
const [availableModels, setAvailableModels] = useState33([]);
|
|
120489
|
+
const [selectedModelIndex, setSelectedModelIndex] = useState33(0);
|
|
120490
|
+
const [fetchError, setFetchError] = useState33(null);
|
|
120436
120491
|
const providerOptions = [
|
|
120437
120492
|
{ label: "OpenAI-compatible API", value: AuthType.USE_OPENAI },
|
|
120438
120493
|
{ label: "Ollama", value: AuthType.OLLAMA },
|
|
120439
120494
|
{ label: "LM Studio", value: AuthType.LM_STUDIO }
|
|
120440
120495
|
];
|
|
120496
|
+
useEffect32(() => {
|
|
120497
|
+
if (step === "model-fetch" && url2 && providerType) {
|
|
120498
|
+
fetchModelsFromCustomEndpoint(url2, providerType, apiKey || void 0).then((models) => {
|
|
120499
|
+
setAvailableModels(models);
|
|
120500
|
+
setFetchError(null);
|
|
120501
|
+
setStep("model-select");
|
|
120502
|
+
}).catch((err) => {
|
|
120503
|
+
setFetchError(err instanceof Error ? err.message : String(err));
|
|
120504
|
+
});
|
|
120505
|
+
}
|
|
120506
|
+
}, [step, url2, providerType, apiKey]);
|
|
120441
120507
|
useInput4((input, key) => {
|
|
120442
120508
|
if (key.escape) {
|
|
120443
120509
|
onCancel();
|
|
@@ -120459,6 +120525,32 @@ function AddCustomEndpointDialog({
|
|
|
120459
120525
|
}
|
|
120460
120526
|
return;
|
|
120461
120527
|
}
|
|
120528
|
+
if (step === "model-select") {
|
|
120529
|
+
if (key.upArrow && selectedModelIndex > 0) {
|
|
120530
|
+
setSelectedModelIndex(selectedModelIndex - 1);
|
|
120531
|
+
return;
|
|
120532
|
+
}
|
|
120533
|
+
if (key.downArrow && selectedModelIndex < availableModels.length - 1) {
|
|
120534
|
+
setSelectedModelIndex(selectedModelIndex + 1);
|
|
120535
|
+
return;
|
|
120536
|
+
}
|
|
120537
|
+
if (key.return) {
|
|
120538
|
+
if (availableModels.length > 0 && providerType) {
|
|
120539
|
+
const selectedModel = availableModels[selectedModelIndex];
|
|
120540
|
+
onSubmit(name2, url2, selectedModel.id, apiKey, providerType);
|
|
120541
|
+
}
|
|
120542
|
+
return;
|
|
120543
|
+
}
|
|
120544
|
+
return;
|
|
120545
|
+
}
|
|
120546
|
+
if (step === "model-fetch" && fetchError) {
|
|
120547
|
+
if (input === "r" || input === "R") {
|
|
120548
|
+
setFetchError(null);
|
|
120549
|
+
setStep("model-fetch");
|
|
120550
|
+
return;
|
|
120551
|
+
}
|
|
120552
|
+
return;
|
|
120553
|
+
}
|
|
120462
120554
|
if (key.return) {
|
|
120463
120555
|
if (step === "name") {
|
|
120464
120556
|
if (inputBuffer.trim()) {
|
|
@@ -120474,9 +120566,8 @@ function AddCustomEndpointDialog({
|
|
|
120474
120566
|
}
|
|
120475
120567
|
} else if (step === "apikey") {
|
|
120476
120568
|
setApiKey(inputBuffer.trim());
|
|
120477
|
-
|
|
120478
|
-
|
|
120479
|
-
}
|
|
120569
|
+
setInputBuffer("");
|
|
120570
|
+
setStep("model-fetch");
|
|
120480
120571
|
}
|
|
120481
120572
|
return;
|
|
120482
120573
|
}
|
|
@@ -120494,7 +120585,7 @@ function AddCustomEndpointDialog({
|
|
|
120494
120585
|
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120495
120586
|
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Step 1: Endpoint Name" }),
|
|
120496
120587
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Enter a friendly name for this endpoint:" }) }),
|
|
120497
|
-
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "
|
|
120588
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "RTX3090 Proxy" or "Inference Server"' }) }),
|
|
120498
120589
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120499
120590
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
|
|
120500
120591
|
inputBuffer,
|
|
@@ -120510,7 +120601,7 @@ function AddCustomEndpointDialog({
|
|
|
120510
120601
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 })
|
|
120511
120602
|
] }) }),
|
|
120512
120603
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Enter the base URL for this endpoint:" }) }),
|
|
120513
|
-
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "
|
|
120604
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "https://rtx3090.bobai.com.au/v1"' }) }),
|
|
120514
120605
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120515
120606
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
|
|
120516
120607
|
inputBuffer,
|
|
@@ -120559,12 +120650,94 @@ function AddCustomEndpointDialog({
|
|
|
120559
120650
|
")"
|
|
120560
120651
|
] }) }),
|
|
120561
120652
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Enter API key if required (leave empty if none):" }) }),
|
|
120653
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentYellow, children: "\u2139 External endpoints usually require authentication" }) }),
|
|
120562
120654
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120563
120655
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
|
|
120564
120656
|
"*".repeat(inputBuffer.length),
|
|
120565
120657
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentCyan, children: "\u258B" })
|
|
120566
120658
|
] }) }),
|
|
120567
|
-
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press Enter to
|
|
120659
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press Enter to fetch models, Esc to cancel" }) })
|
|
120660
|
+
] });
|
|
120661
|
+
case "model-fetch":
|
|
120662
|
+
if (fetchError) {
|
|
120663
|
+
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120664
|
+
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentRed, children: "Connection Failed" }),
|
|
120665
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120666
|
+
"Endpoint: ",
|
|
120667
|
+
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 }),
|
|
120668
|
+
" (",
|
|
120669
|
+
url2,
|
|
120670
|
+
")"
|
|
120671
|
+
] }) }),
|
|
120672
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { color: Colors.AccentRed, children: [
|
|
120673
|
+
"Error: ",
|
|
120674
|
+
fetchError
|
|
120675
|
+
] }) }),
|
|
120676
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentYellow, children: "Common issues:" }) }),
|
|
120677
|
+
/* @__PURE__ */ jsxs22(Box19, { marginLeft: 2, flexDirection: "column", children: [
|
|
120678
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 Incorrect URL (verify /v1 suffix)" }),
|
|
120679
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 API key required but not provided" }),
|
|
120680
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 Endpoint not accessible from this machine" }),
|
|
120681
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 Firewall blocking connection" })
|
|
120682
|
+
] }),
|
|
120683
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press R to retry, Esc to cancel" }) })
|
|
120684
|
+
] });
|
|
120685
|
+
}
|
|
120686
|
+
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120687
|
+
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Fetching Models..." }),
|
|
120688
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120689
|
+
"Connecting to ",
|
|
120690
|
+
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: url2 })
|
|
120691
|
+
] }) }),
|
|
120692
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Please wait..." }) })
|
|
120693
|
+
] });
|
|
120694
|
+
case "model-select":
|
|
120695
|
+
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120696
|
+
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Step 5: Select Model" }),
|
|
120697
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120698
|
+
"Endpoint: ",
|
|
120699
|
+
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 }),
|
|
120700
|
+
" (",
|
|
120701
|
+
url2,
|
|
120702
|
+
")"
|
|
120703
|
+
] }) }),
|
|
120704
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { color: Colors.AccentGreen, children: [
|
|
120705
|
+
"\u2713 Found ",
|
|
120706
|
+
availableModels.length,
|
|
120707
|
+
" available models"
|
|
120708
|
+
] }) }),
|
|
120709
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Choose a model to use:" }) }),
|
|
120710
|
+
/* @__PURE__ */ jsxs22(Box19, { marginTop: 1, flexDirection: "column", children: [
|
|
120711
|
+
availableModels.slice(0, 15).map((model, index) => {
|
|
120712
|
+
const isSelected = index === selectedModelIndex;
|
|
120713
|
+
const prefix = isSelected ? ">" : " ";
|
|
120714
|
+
return /* @__PURE__ */ jsxs22(
|
|
120715
|
+
Text26,
|
|
120716
|
+
{
|
|
120717
|
+
color: isSelected ? Colors.AccentBlue : Colors.Gray,
|
|
120718
|
+
bold: isSelected,
|
|
120719
|
+
children: [
|
|
120720
|
+
prefix,
|
|
120721
|
+
" ",
|
|
120722
|
+
model.id,
|
|
120723
|
+
" ",
|
|
120724
|
+
/* @__PURE__ */ jsxs22(Text26, { color: Colors.Gray, children: [
|
|
120725
|
+
"(",
|
|
120726
|
+
model.ownedBy,
|
|
120727
|
+
")"
|
|
120728
|
+
] })
|
|
120729
|
+
]
|
|
120730
|
+
},
|
|
120731
|
+
model.id
|
|
120732
|
+
);
|
|
120733
|
+
}),
|
|
120734
|
+
availableModels.length > 15 && /* @__PURE__ */ jsxs22(Text26, { color: Colors.Gray, children: [
|
|
120735
|
+
"... and ",
|
|
120736
|
+
availableModels.length - 15,
|
|
120737
|
+
" more models"
|
|
120738
|
+
] })
|
|
120739
|
+
] }),
|
|
120740
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "\u2191/\u2193 to navigate, Enter to confirm, Esc to cancel" }) })
|
|
120568
120741
|
] });
|
|
120569
120742
|
}
|
|
120570
120743
|
};
|
|
@@ -120588,7 +120761,7 @@ function AddCustomEndpointDialog({
|
|
|
120588
120761
|
init_modelManager();
|
|
120589
120762
|
|
|
120590
120763
|
// packages/cli/src/ui/components/OpenAIEndpointDialog.tsx
|
|
120591
|
-
import { useState as useState34, useEffect as
|
|
120764
|
+
import { useState as useState34, useEffect as useEffect33 } from "react";
|
|
120592
120765
|
import { Box as Box20, Text as Text27 } from "ink";
|
|
120593
120766
|
init_database();
|
|
120594
120767
|
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
@@ -120618,7 +120791,7 @@ function OpenAIEndpointDialog({
|
|
|
120618
120791
|
}) {
|
|
120619
120792
|
const [savedEndpoints, setSavedEndpoints] = useState34([]);
|
|
120620
120793
|
const [isLoading, setIsLoading] = useState34(true);
|
|
120621
|
-
|
|
120794
|
+
useEffect33(() => {
|
|
120622
120795
|
const loadEndpoints = async () => {
|
|
120623
120796
|
try {
|
|
120624
120797
|
const db = await getFSSLinkDatabase();
|
|
@@ -120827,7 +121000,7 @@ function AuthDialog({
|
|
|
120827
121000
|
setSelectedEndpoint(null);
|
|
120828
121001
|
setErrorMessage("OpenAI endpoint selection is required.");
|
|
120829
121002
|
};
|
|
120830
|
-
const handleCustomEndpointSubmit = async (name2, url2, apiKey, providerType) => {
|
|
121003
|
+
const handleCustomEndpointSubmit = async (name2, url2, model, apiKey, providerType) => {
|
|
120831
121004
|
const db = await getFSSLinkDatabase();
|
|
120832
121005
|
const endpointId = await db.saveCustomEndpoint(
|
|
120833
121006
|
null,
|
|
@@ -120839,14 +121012,31 @@ function AuthDialog({
|
|
|
120839
121012
|
await db.forceSave();
|
|
120840
121013
|
console.log(`\u{1F4BE} [AUTH-DIALOG] Custom endpoint saved: ${name2} (${url2})`);
|
|
120841
121014
|
setShowAddCustomEndpointDialog(false);
|
|
120842
|
-
|
|
120843
|
-
|
|
120844
|
-
|
|
120845
|
-
|
|
120846
|
-
|
|
120847
|
-
|
|
120848
|
-
|
|
121015
|
+
const modelManager = getModelManager();
|
|
121016
|
+
const modelId = await modelManager.configureModel(
|
|
121017
|
+
providerType,
|
|
121018
|
+
model,
|
|
121019
|
+
// โจ Use selected model from dialog
|
|
121020
|
+
url2,
|
|
121021
|
+
// โจ Use custom endpoint URL
|
|
121022
|
+
apiKey,
|
|
121023
|
+
`${name2}: ${model}`
|
|
121024
|
+
);
|
|
121025
|
+
if (endpointId && modelId) {
|
|
121026
|
+
await db.linkModelToEndpoint(modelId, endpointId);
|
|
121027
|
+
await db.saveCustomEndpoint(
|
|
121028
|
+
modelId,
|
|
121029
|
+
// Set provider_id to the model ID
|
|
121030
|
+
name2,
|
|
121031
|
+
url2,
|
|
121032
|
+
`Custom ${providerType} endpoint`,
|
|
121033
|
+
false
|
|
121034
|
+
);
|
|
121035
|
+
console.log(`\u{1F4BE} [AUTH-DIALOG] Linked custom_endpoints.provider_id=${modelId} for endpoint ${endpointId}`);
|
|
121036
|
+
await db.forceSave();
|
|
121037
|
+
console.log(`\u{1F4BE} [AUTH-DIALOG] Model ${modelId} linked to endpoint ${endpointId}`);
|
|
120849
121038
|
}
|
|
121039
|
+
onSelect(providerType, "User" /* User */);
|
|
120850
121040
|
};
|
|
120851
121041
|
const handleCustomEndpointCancel = () => {
|
|
120852
121042
|
setShowAddCustomEndpointDialog(false);
|
|
@@ -120947,7 +121137,7 @@ function AuthDialog({
|
|
|
120947
121137
|
}
|
|
120948
121138
|
|
|
120949
121139
|
// packages/cli/src/ui/components/ProviderEndpointSelectionDialog.tsx
|
|
120950
|
-
import { useState as useState36, useEffect as
|
|
121140
|
+
import { useState as useState36, useEffect as useEffect34 } from "react";
|
|
120951
121141
|
import { Box as Box22, Text as Text29, useInput as useInput5 } from "ink";
|
|
120952
121142
|
init_modelManager();
|
|
120953
121143
|
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
@@ -120961,7 +121151,7 @@ function ProviderEndpointSelectionDialog({
|
|
|
120961
121151
|
const [loading, setLoading] = useState36(true);
|
|
120962
121152
|
const [switching, setSwitching] = useState36(false);
|
|
120963
121153
|
const [error, setError] = useState36(null);
|
|
120964
|
-
|
|
121154
|
+
useEffect34(() => {
|
|
120965
121155
|
const loadEndpoints = async () => {
|
|
120966
121156
|
try {
|
|
120967
121157
|
const modelManager = getModelManager();
|
|
@@ -121205,7 +121395,7 @@ function ProviderEndpointSelectionDialog({
|
|
|
121205
121395
|
}
|
|
121206
121396
|
|
|
121207
121397
|
// packages/cli/src/ui/components/EnhancedModelSelectionDialog.tsx
|
|
121208
|
-
import { useState as useState37, useEffect as
|
|
121398
|
+
import { useState as useState37, useEffect as useEffect35 } from "react";
|
|
121209
121399
|
import { Box as Box23, Text as Text30, useInput as useInput6 } from "ink";
|
|
121210
121400
|
init_modelManager();
|
|
121211
121401
|
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
@@ -121256,7 +121446,7 @@ function EnhancedModelSelectionDialog({
|
|
|
121256
121446
|
setLoading(false);
|
|
121257
121447
|
}
|
|
121258
121448
|
};
|
|
121259
|
-
|
|
121449
|
+
useEffect35(() => {
|
|
121260
121450
|
loadModels();
|
|
121261
121451
|
}, [providerType, endpointUrl]);
|
|
121262
121452
|
useInput6((input, key) => {
|
|
@@ -121596,7 +121786,7 @@ var WelcomeBackDialog = ({
|
|
|
121596
121786
|
};
|
|
121597
121787
|
|
|
121598
121788
|
// packages/cli/src/ui/components/SearchEngineConfigDialog.tsx
|
|
121599
|
-
import { useState as useState38, useEffect as
|
|
121789
|
+
import { useState as useState38, useEffect as useEffect36 } from "react";
|
|
121600
121790
|
import { Box as Box25, Text as Text32, useInput as useInput7 } from "ink";
|
|
121601
121791
|
init_database();
|
|
121602
121792
|
import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
@@ -121609,7 +121799,7 @@ function SearchEngineConfigDialog({
|
|
|
121609
121799
|
const [currentField, setCurrentField] = useState38("braveApiKey");
|
|
121610
121800
|
const [isLoading, setIsLoading] = useState38(true);
|
|
121611
121801
|
const [isSaving, setIsSaving] = useState38(false);
|
|
121612
|
-
|
|
121802
|
+
useEffect36(() => {
|
|
121613
121803
|
const loadConfig = async () => {
|
|
121614
121804
|
console.log("[WEBSCRAPER-DEBUG] Loading existing API keys from database...");
|
|
121615
121805
|
const db = await getFSSLinkDatabase();
|
|
@@ -121629,7 +121819,7 @@ function SearchEngineConfigDialog({
|
|
|
121629
121819
|
};
|
|
121630
121820
|
loadConfig().catch(console.error);
|
|
121631
121821
|
}, []);
|
|
121632
|
-
|
|
121822
|
+
useEffect36(() => {
|
|
121633
121823
|
if (!isSaving) return;
|
|
121634
121824
|
const saveConfig = async () => {
|
|
121635
121825
|
try {
|
|
@@ -121853,7 +122043,7 @@ function SearchEngineConfigDialog({
|
|
|
121853
122043
|
}
|
|
121854
122044
|
|
|
121855
122045
|
// packages/cli/src/ui/components/AuthInProgress.tsx
|
|
121856
|
-
import { useState as useState39, useEffect as
|
|
122046
|
+
import { useState as useState39, useEffect as useEffect37 } from "react";
|
|
121857
122047
|
import { Box as Box26, Text as Text33 } from "ink";
|
|
121858
122048
|
import Spinner2 from "ink-spinner";
|
|
121859
122049
|
import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
@@ -121869,7 +122059,7 @@ function AuthInProgress({
|
|
|
121869
122059
|
},
|
|
121870
122060
|
{ isActive: true }
|
|
121871
122061
|
);
|
|
121872
|
-
|
|
122062
|
+
useEffect37(() => {
|
|
121873
122063
|
const timer = setTimeout(() => {
|
|
121874
122064
|
setTimedOut(true);
|
|
121875
122065
|
onTimeout();
|
|
@@ -125480,7 +125670,7 @@ function IdeIntegrationNudge({
|
|
|
125480
125670
|
}
|
|
125481
125671
|
|
|
125482
125672
|
// packages/cli/src/ui/hooks/useGitBranchName.ts
|
|
125483
|
-
import { useState as useState42, useEffect as
|
|
125673
|
+
import { useState as useState42, useEffect as useEffect38, useCallback as useCallback24 } from "react";
|
|
125484
125674
|
import { exec as exec6 } from "node:child_process";
|
|
125485
125675
|
import fs65 from "node:fs";
|
|
125486
125676
|
import fsPromises3 from "node:fs/promises";
|
|
@@ -125516,7 +125706,7 @@ function useGitBranchName(cwd3) {
|
|
|
125516
125706
|
),
|
|
125517
125707
|
[cwd3, setBranchName]
|
|
125518
125708
|
);
|
|
125519
|
-
|
|
125709
|
+
useEffect38(() => {
|
|
125520
125710
|
fetchBranchName();
|
|
125521
125711
|
const gitLogsHeadPath = path77.join(cwd3, ".git", "logs", "HEAD");
|
|
125522
125712
|
let watcher;
|
|
@@ -125540,14 +125730,14 @@ function useGitBranchName(cwd3) {
|
|
|
125540
125730
|
}
|
|
125541
125731
|
|
|
125542
125732
|
// packages/cli/src/ui/hooks/useBracketedPaste.ts
|
|
125543
|
-
import { useEffect as
|
|
125733
|
+
import { useEffect as useEffect39 } from "react";
|
|
125544
125734
|
var ENABLE_BRACKETED_PASTE = "\x1B[?2004h";
|
|
125545
125735
|
var DISABLE_BRACKETED_PASTE = "\x1B[?2004l";
|
|
125546
125736
|
var useBracketedPaste = () => {
|
|
125547
125737
|
const cleanup = () => {
|
|
125548
125738
|
process.stdout.write(DISABLE_BRACKETED_PASTE);
|
|
125549
125739
|
};
|
|
125550
|
-
|
|
125740
|
+
useEffect39(() => {
|
|
125551
125741
|
process.stdout.write(ENABLE_BRACKETED_PASTE);
|
|
125552
125742
|
process.on("exit", cleanup);
|
|
125553
125743
|
process.on("SIGINT", cleanup);
|
|
@@ -125567,7 +125757,7 @@ import {
|
|
|
125567
125757
|
createContext as createContext5,
|
|
125568
125758
|
useCallback as useCallback25,
|
|
125569
125759
|
useContext as useContext5,
|
|
125570
|
-
useEffect as
|
|
125760
|
+
useEffect as useEffect40,
|
|
125571
125761
|
useState as useState43
|
|
125572
125762
|
} from "react";
|
|
125573
125763
|
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
@@ -125581,7 +125771,7 @@ var VimModeProvider = ({
|
|
|
125581
125771
|
const [vimMode, setVimMode] = useState43(
|
|
125582
125772
|
initialVimEnabled ? "NORMAL" : "INSERT"
|
|
125583
125773
|
);
|
|
125584
|
-
|
|
125774
|
+
useEffect40(() => {
|
|
125585
125775
|
const enabled = settings.merged.vimMode ?? false;
|
|
125586
125776
|
setVimEnabled(enabled);
|
|
125587
125777
|
if (enabled) {
|
|
@@ -125614,7 +125804,7 @@ var useVimMode = () => {
|
|
|
125614
125804
|
};
|
|
125615
125805
|
|
|
125616
125806
|
// packages/cli/src/ui/hooks/vim.ts
|
|
125617
|
-
import { useCallback as useCallback26, useReducer as useReducer4, useEffect as
|
|
125807
|
+
import { useCallback as useCallback26, useReducer as useReducer4, useEffect as useEffect41 } from "react";
|
|
125618
125808
|
var DIGIT_MULTIPLIER = 10;
|
|
125619
125809
|
var DEFAULT_COUNT = 1;
|
|
125620
125810
|
var DIGIT_1_TO_9 = /^[1-9]$/;
|
|
@@ -125678,7 +125868,7 @@ var vimReducer = (state, action) => {
|
|
|
125678
125868
|
function useVim(buffer, onSubmit) {
|
|
125679
125869
|
const { vimEnabled, vimMode, setVimMode } = useVimMode();
|
|
125680
125870
|
const [state, dispatch] = useReducer4(vimReducer, initialVimState);
|
|
125681
|
-
|
|
125871
|
+
useEffect41(() => {
|
|
125682
125872
|
dispatch({ type: "SET_MODE", mode: vimMode });
|
|
125683
125873
|
}, [vimMode]);
|
|
125684
125874
|
const updateMode = useCallback26(
|
|
@@ -126474,12 +126664,12 @@ import { Box as Box56, Newline as Newline3, Text as Text61 } from "ink";
|
|
|
126474
126664
|
|
|
126475
126665
|
// packages/cli/src/ui/hooks/usePrivacySettings.ts
|
|
126476
126666
|
init_dist2();
|
|
126477
|
-
import { useState as useState45, useEffect as
|
|
126667
|
+
import { useState as useState45, useEffect as useEffect42, useCallback as useCallback27 } from "react";
|
|
126478
126668
|
var usePrivacySettings = (config) => {
|
|
126479
126669
|
const [privacyState, setPrivacyState] = useState45({
|
|
126480
126670
|
isLoading: true
|
|
126481
126671
|
});
|
|
126482
|
-
|
|
126672
|
+
useEffect42(() => {
|
|
126483
126673
|
const fetchInitialState = async () => {
|
|
126484
126674
|
setPrivacyState({
|
|
126485
126675
|
isLoading: true
|
|
@@ -126693,7 +126883,7 @@ function useSettingsCommand() {
|
|
|
126693
126883
|
}
|
|
126694
126884
|
|
|
126695
126885
|
// packages/cli/src/ui/components/SettingsDialog.tsx
|
|
126696
|
-
import React30, { useState as useState47, useEffect as
|
|
126886
|
+
import React30, { useState as useState47, useEffect as useEffect43 } from "react";
|
|
126697
126887
|
import { Box as Box58, Text as Text62 } from "ink";
|
|
126698
126888
|
init_settings();
|
|
126699
126889
|
import chalk2 from "chalk";
|
|
@@ -126725,7 +126915,7 @@ function SettingsDialog({
|
|
|
126725
126915
|
);
|
|
126726
126916
|
const [globalPendingChanges, setGlobalPendingChanges] = useState47(/* @__PURE__ */ new Map());
|
|
126727
126917
|
const [_restartRequiredSettings, setRestartRequiredSettings] = useState47(/* @__PURE__ */ new Set());
|
|
126728
|
-
|
|
126918
|
+
useEffect43(() => {
|
|
126729
126919
|
let updated = structuredClone(settings.forScope(selectedScope).settings);
|
|
126730
126920
|
const newModified = /* @__PURE__ */ new Set();
|
|
126731
126921
|
const newRestartRequired = /* @__PURE__ */ new Set();
|
|
@@ -126835,7 +127025,7 @@ function SettingsDialog({
|
|
|
126835
127025
|
const [editBuffer, setEditBuffer] = useState47("");
|
|
126836
127026
|
const [editCursorPos, setEditCursorPos] = useState47(0);
|
|
126837
127027
|
const [cursorVisible, setCursorVisible] = useState47(true);
|
|
126838
|
-
|
|
127028
|
+
useEffect43(() => {
|
|
126839
127029
|
if (!editingKey) {
|
|
126840
127030
|
setCursorVisible(true);
|
|
126841
127031
|
return;
|
|
@@ -127539,11 +127729,11 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127539
127729
|
const { history, addItem, clearItems, loadHistory } = useHistory();
|
|
127540
127730
|
const [idePromptAnswered, setIdePromptAnswered] = useState48(false);
|
|
127541
127731
|
const currentIDE = config.getIdeClient().getCurrentIde();
|
|
127542
|
-
|
|
127732
|
+
useEffect44(() => {
|
|
127543
127733
|
registerCleanup(() => config.getIdeClient().disconnect());
|
|
127544
127734
|
}, [config]);
|
|
127545
127735
|
const shouldShowIdePrompt = currentIDE && !config.getIdeMode() && !settings.merged.hasSeenIdeIntegrationNudge && !idePromptAnswered;
|
|
127546
|
-
|
|
127736
|
+
useEffect44(() => {
|
|
127547
127737
|
const cleanup = setUpdateHandler(addItem, setUpdateInfo);
|
|
127548
127738
|
return cleanup;
|
|
127549
127739
|
}, [addItem]);
|
|
@@ -127552,7 +127742,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127552
127742
|
handleNewMessage,
|
|
127553
127743
|
clearConsoleMessages: clearConsoleMessagesState
|
|
127554
127744
|
} = useConsoleMessages();
|
|
127555
|
-
|
|
127745
|
+
useEffect44(() => {
|
|
127556
127746
|
const consolePatcher = new ConsolePatcher({
|
|
127557
127747
|
onNewMessage: handleNewMessage,
|
|
127558
127748
|
debugMode: config.getDebugMode()
|
|
@@ -127575,7 +127765,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127575
127765
|
const [isSearchDialogOpen, setIsSearchDialogOpen] = useState48(false);
|
|
127576
127766
|
const [isAddCustomEndpointDialogOpen, setIsAddCustomEndpointDialogOpen] = useState48(false);
|
|
127577
127767
|
const [footerHeight, setFooterHeight] = useState48(0);
|
|
127578
|
-
|
|
127768
|
+
useEffect44(() => {
|
|
127579
127769
|
const initializeSearchEngineConfig = async () => {
|
|
127580
127770
|
const configProvider = SearchEngineConfigProvider.getInstance();
|
|
127581
127771
|
await configProvider.loadConfiguration();
|
|
@@ -127602,12 +127792,12 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127602
127792
|
const [ideContextState, setIdeContextState] = useState48();
|
|
127603
127793
|
const [showEscapePrompt, setShowEscapePrompt] = useState48(false);
|
|
127604
127794
|
const [isProcessing, setIsProcessing] = useState48(false);
|
|
127605
|
-
|
|
127795
|
+
useEffect44(() => {
|
|
127606
127796
|
const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
|
|
127607
127797
|
setIdeContextState(ideContext.getIdeContext());
|
|
127608
127798
|
return unsubscribe;
|
|
127609
127799
|
}, []);
|
|
127610
|
-
|
|
127800
|
+
useEffect44(() => {
|
|
127611
127801
|
const openDebugConsole = () => {
|
|
127612
127802
|
setShowErrorDetails(true);
|
|
127613
127803
|
setConstrainHeight(false);
|
|
@@ -127674,7 +127864,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127674
127864
|
handleRestart: handleWelcomeBackRestart,
|
|
127675
127865
|
handleCancel: handleWelcomeBackCancel
|
|
127676
127866
|
} = useWelcomeBack(settings);
|
|
127677
|
-
|
|
127867
|
+
useEffect44(() => {
|
|
127678
127868
|
if (settings.merged.selectedAuthType && !settings.merged.useExternalAuth) {
|
|
127679
127869
|
const error = validateAuthMethod(settings.merged.selectedAuthType);
|
|
127680
127870
|
if (error) {
|
|
@@ -127688,7 +127878,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127688
127878
|
openAuthDialog,
|
|
127689
127879
|
setAuthError
|
|
127690
127880
|
]);
|
|
127691
|
-
|
|
127881
|
+
useEffect44(() => {
|
|
127692
127882
|
if (!isAuthenticating) {
|
|
127693
127883
|
setUserTier(config.getGeminiClient()?.getUserTier());
|
|
127694
127884
|
}
|
|
@@ -127752,7 +127942,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127752
127942
|
console.error("Error refreshing memory:", error);
|
|
127753
127943
|
}
|
|
127754
127944
|
}, [config, addItem, settings.merged]);
|
|
127755
|
-
|
|
127945
|
+
useEffect44(() => {
|
|
127756
127946
|
const checkModelChange = () => {
|
|
127757
127947
|
const configModel = config.getModel();
|
|
127758
127948
|
if (configModel !== currentModel) {
|
|
@@ -127763,7 +127953,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127763
127953
|
const interval = setInterval(checkModelChange, 1e3);
|
|
127764
127954
|
return () => clearInterval(interval);
|
|
127765
127955
|
}, [config, currentModel]);
|
|
127766
|
-
|
|
127956
|
+
useEffect44(() => {
|
|
127767
127957
|
const flashFallbackHandler = async (currentModel2, fallbackModel, error) => {
|
|
127768
127958
|
let message;
|
|
127769
127959
|
if (config.getContentGeneratorConfig().authType === AuthType.LOGIN_WITH_GOOGLE) {
|
|
@@ -127922,7 +128112,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127922
128112
|
refreshStatic,
|
|
127923
128113
|
() => cancelHandlerRef.current()
|
|
127924
128114
|
);
|
|
127925
|
-
|
|
128115
|
+
useEffect44(() => {
|
|
127926
128116
|
if (contextToPopulate && !initialPromptSubmitted.current) {
|
|
127927
128117
|
submitQuery(contextToPopulate);
|
|
127928
128118
|
initialPromptSubmitted.current = true;
|
|
@@ -128057,13 +128247,13 @@ ${queuedText}` : queuedText;
|
|
|
128057
128247
|
useKeypress(handleGlobalKeypress, {
|
|
128058
128248
|
isActive: true
|
|
128059
128249
|
});
|
|
128060
|
-
|
|
128250
|
+
useEffect44(() => {
|
|
128061
128251
|
if (config) {
|
|
128062
128252
|
setGeminiMdFileCount(config.getGeminiMdFileCount());
|
|
128063
128253
|
}
|
|
128064
128254
|
}, [config, config.getGeminiMdFileCount]);
|
|
128065
128255
|
const logger6 = useLogger();
|
|
128066
|
-
|
|
128256
|
+
useEffect44(() => {
|
|
128067
128257
|
const fetchUserMessages = async () => {
|
|
128068
128258
|
const pastMessagesRaw = await logger6?.getPreviousUserMessages() || [];
|
|
128069
128259
|
const currentSessionUserMessages = history.filter(
|
|
@@ -128095,7 +128285,7 @@ ${queuedText}` : queuedText;
|
|
|
128095
128285
|
}, [clearItems, clearConsoleMessagesState, refreshStatic]);
|
|
128096
128286
|
const mainControlsRef = useRef12(null);
|
|
128097
128287
|
const pendingHistoryItemRef = useRef12(null);
|
|
128098
|
-
|
|
128288
|
+
useEffect44(() => {
|
|
128099
128289
|
if (mainControlsRef.current) {
|
|
128100
128290
|
const fullFooterMeasurement = measureElement(mainControlsRef.current);
|
|
128101
128291
|
setFooterHeight(fullFooterMeasurement.height);
|
|
@@ -128109,7 +128299,7 @@ ${queuedText}` : queuedText;
|
|
|
128109
128299
|
() => terminalHeight - footerHeight - staticExtraHeight,
|
|
128110
128300
|
[terminalHeight, footerHeight]
|
|
128111
128301
|
);
|
|
128112
|
-
|
|
128302
|
+
useEffect44(() => {
|
|
128113
128303
|
if (isInitialMount.current) {
|
|
128114
128304
|
isInitialMount.current = false;
|
|
128115
128305
|
return;
|
|
@@ -128122,7 +128312,7 @@ ${queuedText}` : queuedText;
|
|
|
128122
128312
|
clearTimeout(handler);
|
|
128123
128313
|
};
|
|
128124
128314
|
}, [terminalWidth, terminalHeight, refreshStatic]);
|
|
128125
|
-
|
|
128315
|
+
useEffect44(() => {
|
|
128126
128316
|
if (streamingState === "idle" /* Idle */ && staticNeedsRefresh) {
|
|
128127
128317
|
setStaticNeedsRefresh(false);
|
|
128128
128318
|
refreshStatic();
|
|
@@ -128144,7 +128334,7 @@ ${queuedText}` : queuedText;
|
|
|
128144
128334
|
}, [settings.merged.contextFileName]);
|
|
128145
128335
|
const initialPrompt = useMemo9(() => config.getQuestion(), [config]);
|
|
128146
128336
|
const geminiClient = config.getGeminiClient();
|
|
128147
|
-
|
|
128337
|
+
useEffect44(() => {
|
|
128148
128338
|
if (initialPrompt && !initialPromptSubmitted.current && !isAuthenticating && !isAuthDialogOpen && !shouldShowWelcomeBack && !isThemeDialogOpen && !isEditorDialogOpen && !isSearchDialogOpen && modelDialogState === "none" && !showPrivacyNotice && geminiClient?.isInitialized?.()) {
|
|
128149
128339
|
submitQuery(initialPrompt);
|
|
128150
128340
|
initialPromptSubmitted.current = true;
|