fss-link 1.4.0 โ 1.4.2
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 +289 -91
- package/package.json +2 -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.2";
|
|
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.2";
|
|
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 = "607be21d";
|
|
96130
96130
|
|
|
96131
96131
|
// packages/cli/src/ui/commands/bugCommand.ts
|
|
96132
96132
|
init_dist2();
|
|
@@ -120419,8 +120419,61 @@ 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
|
+
import TextInput from "ink-text-input";
|
|
120425
|
+
|
|
120426
|
+
// packages/cli/src/utils/modelFetcher.ts
|
|
120427
|
+
async function fetchModelsFromCustomEndpoint(baseUrl, providerType, apiKey) {
|
|
120428
|
+
const normalizedBase = baseUrl.replace(/\/+$/, "");
|
|
120429
|
+
const url2 = `${normalizedBase}/models`;
|
|
120430
|
+
const headers = {
|
|
120431
|
+
"Accept": "application/json"
|
|
120432
|
+
};
|
|
120433
|
+
if (apiKey && apiKey.trim() !== "") {
|
|
120434
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
120435
|
+
}
|
|
120436
|
+
try {
|
|
120437
|
+
const controller = new AbortController();
|
|
120438
|
+
const timeoutId = setTimeout(() => controller.abort(), 1e4);
|
|
120439
|
+
const response = await fetch(url2, {
|
|
120440
|
+
headers,
|
|
120441
|
+
signal: controller.signal
|
|
120442
|
+
});
|
|
120443
|
+
clearTimeout(timeoutId);
|
|
120444
|
+
if (!response.ok) {
|
|
120445
|
+
if (response.status === 401 || response.status === 403) {
|
|
120446
|
+
throw new Error("Authentication failed - check API key");
|
|
120447
|
+
}
|
|
120448
|
+
if (response.status === 404) {
|
|
120449
|
+
throw new Error("Endpoint not found - verify URL includes /v1 suffix");
|
|
120450
|
+
}
|
|
120451
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
120452
|
+
}
|
|
120453
|
+
const json3 = await response.json();
|
|
120454
|
+
if (!json3.data || !Array.isArray(json3.data)) {
|
|
120455
|
+
throw new Error("Invalid response format - expected OpenAI-compatible /models endpoint");
|
|
120456
|
+
}
|
|
120457
|
+
if (json3.data.length === 0) {
|
|
120458
|
+
throw new Error("No models available on this endpoint");
|
|
120459
|
+
}
|
|
120460
|
+
return json3.data.map((m) => ({
|
|
120461
|
+
id: m.id,
|
|
120462
|
+
ownedBy: m.owned_by || "unknown",
|
|
120463
|
+
object: m.object
|
|
120464
|
+
}));
|
|
120465
|
+
} catch (error) {
|
|
120466
|
+
if (error instanceof Error) {
|
|
120467
|
+
if (error.name === "AbortError") {
|
|
120468
|
+
throw new Error("Connection timeout - endpoint took too long to respond");
|
|
120469
|
+
}
|
|
120470
|
+
throw error;
|
|
120471
|
+
}
|
|
120472
|
+
throw new Error(`Connection failed: ${String(error)}`);
|
|
120473
|
+
}
|
|
120474
|
+
}
|
|
120475
|
+
|
|
120476
|
+
// packages/cli/src/ui/components/AddCustomEndpointDialog.tsx
|
|
120424
120477
|
import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
120425
120478
|
function AddCustomEndpointDialog({
|
|
120426
120479
|
onSubmit,
|
|
@@ -120432,12 +120485,25 @@ function AddCustomEndpointDialog({
|
|
|
120432
120485
|
const [apiKey, setApiKey] = useState33("");
|
|
120433
120486
|
const [providerType, setProviderType] = useState33(null);
|
|
120434
120487
|
const [selectedProviderIndex, setSelectedProviderIndex] = useState33(0);
|
|
120435
|
-
const [
|
|
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,47 +120525,67 @@ function AddCustomEndpointDialog({
|
|
|
120459
120525
|
}
|
|
120460
120526
|
return;
|
|
120461
120527
|
}
|
|
120462
|
-
if (
|
|
120463
|
-
if (
|
|
120464
|
-
|
|
120465
|
-
|
|
120466
|
-
|
|
120467
|
-
|
|
120468
|
-
|
|
120469
|
-
|
|
120470
|
-
|
|
120471
|
-
|
|
120472
|
-
|
|
120473
|
-
|
|
120474
|
-
|
|
120475
|
-
} else if (step === "apikey") {
|
|
120476
|
-
setApiKey(inputBuffer.trim());
|
|
120477
|
-
if (providerType) {
|
|
120478
|
-
onSubmit(name2, url2, inputBuffer.trim(), providerType);
|
|
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);
|
|
120479
120541
|
}
|
|
120542
|
+
return;
|
|
120480
120543
|
}
|
|
120481
120544
|
return;
|
|
120482
120545
|
}
|
|
120483
|
-
if (
|
|
120484
|
-
|
|
120546
|
+
if (step === "model-fetch" && fetchError) {
|
|
120547
|
+
if (input === "r" || input === "R") {
|
|
120548
|
+
setFetchError(null);
|
|
120549
|
+
setStep("model-fetch");
|
|
120550
|
+
return;
|
|
120551
|
+
}
|
|
120485
120552
|
return;
|
|
120486
120553
|
}
|
|
120487
|
-
if (input && !key.ctrl && !key.meta) {
|
|
120488
|
-
setInputBuffer(inputBuffer + input);
|
|
120489
|
-
}
|
|
120490
120554
|
});
|
|
120555
|
+
const handleNameSubmit = (value) => {
|
|
120556
|
+
if (value.trim()) {
|
|
120557
|
+
setName(value.trim());
|
|
120558
|
+
setStep("url");
|
|
120559
|
+
}
|
|
120560
|
+
};
|
|
120561
|
+
const handleUrlSubmit = (value) => {
|
|
120562
|
+
if (value.trim()) {
|
|
120563
|
+
setUrl(value.trim());
|
|
120564
|
+
setStep("provider");
|
|
120565
|
+
}
|
|
120566
|
+
};
|
|
120567
|
+
const handleApiKeySubmit = (value) => {
|
|
120568
|
+
setApiKey(value.trim());
|
|
120569
|
+
setStep("model-fetch");
|
|
120570
|
+
};
|
|
120491
120571
|
const renderStep = () => {
|
|
120492
120572
|
switch (step) {
|
|
120493
120573
|
case "name":
|
|
120494
120574
|
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120495
120575
|
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Step 1: Endpoint Name" }),
|
|
120496
120576
|
/* @__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: "
|
|
120498
|
-
/* @__PURE__ */
|
|
120577
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "RTX3090 Proxy" or "Inference Server"' }) }),
|
|
120578
|
+
/* @__PURE__ */ jsxs22(Box19, { marginTop: 1, children: [
|
|
120499
120579
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
|
|
120500
|
-
|
|
120501
|
-
|
|
120502
|
-
|
|
120580
|
+
/* @__PURE__ */ jsx24(
|
|
120581
|
+
TextInput,
|
|
120582
|
+
{
|
|
120583
|
+
value: name2,
|
|
120584
|
+
onChange: setName,
|
|
120585
|
+
onSubmit: handleNameSubmit
|
|
120586
|
+
}
|
|
120587
|
+
)
|
|
120588
|
+
] }),
|
|
120503
120589
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press Enter to continue, Esc to cancel" }) })
|
|
120504
120590
|
] });
|
|
120505
120591
|
case "url":
|
|
@@ -120510,12 +120596,18 @@ function AddCustomEndpointDialog({
|
|
|
120510
120596
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 })
|
|
120511
120597
|
] }) }),
|
|
120512
120598
|
/* @__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: "
|
|
120514
|
-
/* @__PURE__ */
|
|
120599
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "https://rtx3090.bobai.com.au/v1"' }) }),
|
|
120600
|
+
/* @__PURE__ */ jsxs22(Box19, { marginTop: 1, children: [
|
|
120515
120601
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
|
|
120516
|
-
|
|
120517
|
-
|
|
120518
|
-
|
|
120602
|
+
/* @__PURE__ */ jsx24(
|
|
120603
|
+
TextInput,
|
|
120604
|
+
{
|
|
120605
|
+
value: url2,
|
|
120606
|
+
onChange: setUrl,
|
|
120607
|
+
onSubmit: handleUrlSubmit
|
|
120608
|
+
}
|
|
120609
|
+
)
|
|
120610
|
+
] }),
|
|
120519
120611
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press Enter to continue, Esc to cancel" }) })
|
|
120520
120612
|
] });
|
|
120521
120613
|
case "provider":
|
|
@@ -120559,12 +120651,101 @@ function AddCustomEndpointDialog({
|
|
|
120559
120651
|
")"
|
|
120560
120652
|
] }) }),
|
|
120561
120653
|
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Enter API key if required (leave empty if none):" }) }),
|
|
120562
|
-
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */
|
|
120654
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentYellow, children: "\u2139 External endpoints usually require authentication" }) }),
|
|
120655
|
+
/* @__PURE__ */ jsxs22(Box19, { marginTop: 1, children: [
|
|
120563
120656
|
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
|
|
120564
|
-
|
|
120565
|
-
|
|
120657
|
+
/* @__PURE__ */ jsx24(
|
|
120658
|
+
TextInput,
|
|
120659
|
+
{
|
|
120660
|
+
value: apiKey,
|
|
120661
|
+
onChange: setApiKey,
|
|
120662
|
+
onSubmit: handleApiKeySubmit,
|
|
120663
|
+
mask: "*"
|
|
120664
|
+
}
|
|
120665
|
+
)
|
|
120666
|
+
] }),
|
|
120667
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press Enter to fetch models, Esc to cancel" }) })
|
|
120668
|
+
] });
|
|
120669
|
+
case "model-fetch":
|
|
120670
|
+
if (fetchError) {
|
|
120671
|
+
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120672
|
+
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentRed, children: "Connection Failed" }),
|
|
120673
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120674
|
+
"Endpoint: ",
|
|
120675
|
+
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 }),
|
|
120676
|
+
" (",
|
|
120677
|
+
url2,
|
|
120678
|
+
")"
|
|
120679
|
+
] }) }),
|
|
120680
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { color: Colors.AccentRed, children: [
|
|
120681
|
+
"Error: ",
|
|
120682
|
+
fetchError
|
|
120683
|
+
] }) }),
|
|
120684
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentYellow, children: "Common issues:" }) }),
|
|
120685
|
+
/* @__PURE__ */ jsxs22(Box19, { marginLeft: 2, flexDirection: "column", children: [
|
|
120686
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 Incorrect URL (verify /v1 suffix)" }),
|
|
120687
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 API key required but not provided" }),
|
|
120688
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 Endpoint not accessible from this machine" }),
|
|
120689
|
+
/* @__PURE__ */ jsx24(Text26, { children: "\u2022 Firewall blocking connection" })
|
|
120690
|
+
] }),
|
|
120691
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press R to retry, Esc to cancel" }) })
|
|
120692
|
+
] });
|
|
120693
|
+
}
|
|
120694
|
+
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120695
|
+
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Fetching Models..." }),
|
|
120696
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120697
|
+
"Connecting to ",
|
|
120698
|
+
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: url2 })
|
|
120566
120699
|
] }) }),
|
|
120567
|
-
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "
|
|
120700
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Please wait..." }) })
|
|
120701
|
+
] });
|
|
120702
|
+
case "model-select":
|
|
120703
|
+
return /* @__PURE__ */ jsxs22(Fragment4, { children: [
|
|
120704
|
+
/* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Step 5: Select Model" }),
|
|
120705
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
|
|
120706
|
+
"Endpoint: ",
|
|
120707
|
+
/* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 }),
|
|
120708
|
+
" (",
|
|
120709
|
+
url2,
|
|
120710
|
+
")"
|
|
120711
|
+
] }) }),
|
|
120712
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { color: Colors.AccentGreen, children: [
|
|
120713
|
+
"\u2713 Found ",
|
|
120714
|
+
availableModels.length,
|
|
120715
|
+
" available models"
|
|
120716
|
+
] }) }),
|
|
120717
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Choose a model to use:" }) }),
|
|
120718
|
+
/* @__PURE__ */ jsxs22(Box19, { marginTop: 1, flexDirection: "column", children: [
|
|
120719
|
+
availableModels.slice(0, 15).map((model, index) => {
|
|
120720
|
+
const isSelected = index === selectedModelIndex;
|
|
120721
|
+
const prefix = isSelected ? ">" : " ";
|
|
120722
|
+
return /* @__PURE__ */ jsxs22(
|
|
120723
|
+
Text26,
|
|
120724
|
+
{
|
|
120725
|
+
color: isSelected ? Colors.AccentBlue : Colors.Gray,
|
|
120726
|
+
bold: isSelected,
|
|
120727
|
+
children: [
|
|
120728
|
+
prefix,
|
|
120729
|
+
" ",
|
|
120730
|
+
model.id,
|
|
120731
|
+
" ",
|
|
120732
|
+
/* @__PURE__ */ jsxs22(Text26, { color: Colors.Gray, children: [
|
|
120733
|
+
"(",
|
|
120734
|
+
model.ownedBy,
|
|
120735
|
+
")"
|
|
120736
|
+
] })
|
|
120737
|
+
]
|
|
120738
|
+
},
|
|
120739
|
+
model.id
|
|
120740
|
+
);
|
|
120741
|
+
}),
|
|
120742
|
+
availableModels.length > 15 && /* @__PURE__ */ jsxs22(Text26, { color: Colors.Gray, children: [
|
|
120743
|
+
"... and ",
|
|
120744
|
+
availableModels.length - 15,
|
|
120745
|
+
" more models"
|
|
120746
|
+
] })
|
|
120747
|
+
] }),
|
|
120748
|
+
/* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "\u2191/\u2193 to navigate, Enter to confirm, Esc to cancel" }) })
|
|
120568
120749
|
] });
|
|
120569
120750
|
}
|
|
120570
120751
|
};
|
|
@@ -120588,7 +120769,7 @@ function AddCustomEndpointDialog({
|
|
|
120588
120769
|
init_modelManager();
|
|
120589
120770
|
|
|
120590
120771
|
// packages/cli/src/ui/components/OpenAIEndpointDialog.tsx
|
|
120591
|
-
import { useState as useState34, useEffect as
|
|
120772
|
+
import { useState as useState34, useEffect as useEffect33 } from "react";
|
|
120592
120773
|
import { Box as Box20, Text as Text27 } from "ink";
|
|
120593
120774
|
init_database();
|
|
120594
120775
|
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
@@ -120618,7 +120799,7 @@ function OpenAIEndpointDialog({
|
|
|
120618
120799
|
}) {
|
|
120619
120800
|
const [savedEndpoints, setSavedEndpoints] = useState34([]);
|
|
120620
120801
|
const [isLoading, setIsLoading] = useState34(true);
|
|
120621
|
-
|
|
120802
|
+
useEffect33(() => {
|
|
120622
120803
|
const loadEndpoints = async () => {
|
|
120623
120804
|
try {
|
|
120624
120805
|
const db = await getFSSLinkDatabase();
|
|
@@ -120827,7 +121008,7 @@ function AuthDialog({
|
|
|
120827
121008
|
setSelectedEndpoint(null);
|
|
120828
121009
|
setErrorMessage("OpenAI endpoint selection is required.");
|
|
120829
121010
|
};
|
|
120830
|
-
const handleCustomEndpointSubmit = async (name2, url2, apiKey, providerType) => {
|
|
121011
|
+
const handleCustomEndpointSubmit = async (name2, url2, model, apiKey, providerType) => {
|
|
120831
121012
|
const db = await getFSSLinkDatabase();
|
|
120832
121013
|
const endpointId = await db.saveCustomEndpoint(
|
|
120833
121014
|
null,
|
|
@@ -120839,14 +121020,31 @@ function AuthDialog({
|
|
|
120839
121020
|
await db.forceSave();
|
|
120840
121021
|
console.log(`\u{1F4BE} [AUTH-DIALOG] Custom endpoint saved: ${name2} (${url2})`);
|
|
120841
121022
|
setShowAddCustomEndpointDialog(false);
|
|
120842
|
-
|
|
120843
|
-
|
|
120844
|
-
|
|
120845
|
-
|
|
120846
|
-
|
|
120847
|
-
|
|
120848
|
-
|
|
121023
|
+
const modelManager = getModelManager();
|
|
121024
|
+
const modelId = await modelManager.configureModel(
|
|
121025
|
+
providerType,
|
|
121026
|
+
model,
|
|
121027
|
+
// โจ Use selected model from dialog
|
|
121028
|
+
url2,
|
|
121029
|
+
// โจ Use custom endpoint URL
|
|
121030
|
+
apiKey,
|
|
121031
|
+
`${name2}: ${model}`
|
|
121032
|
+
);
|
|
121033
|
+
if (endpointId && modelId) {
|
|
121034
|
+
await db.linkModelToEndpoint(modelId, endpointId);
|
|
121035
|
+
await db.saveCustomEndpoint(
|
|
121036
|
+
modelId,
|
|
121037
|
+
// Set provider_id to the model ID
|
|
121038
|
+
name2,
|
|
121039
|
+
url2,
|
|
121040
|
+
`Custom ${providerType} endpoint`,
|
|
121041
|
+
false
|
|
121042
|
+
);
|
|
121043
|
+
console.log(`\u{1F4BE} [AUTH-DIALOG] Linked custom_endpoints.provider_id=${modelId} for endpoint ${endpointId}`);
|
|
121044
|
+
await db.forceSave();
|
|
121045
|
+
console.log(`\u{1F4BE} [AUTH-DIALOG] Model ${modelId} linked to endpoint ${endpointId}`);
|
|
120849
121046
|
}
|
|
121047
|
+
onSelect(providerType, "User" /* User */);
|
|
120850
121048
|
};
|
|
120851
121049
|
const handleCustomEndpointCancel = () => {
|
|
120852
121050
|
setShowAddCustomEndpointDialog(false);
|
|
@@ -120947,7 +121145,7 @@ function AuthDialog({
|
|
|
120947
121145
|
}
|
|
120948
121146
|
|
|
120949
121147
|
// packages/cli/src/ui/components/ProviderEndpointSelectionDialog.tsx
|
|
120950
|
-
import { useState as useState36, useEffect as
|
|
121148
|
+
import { useState as useState36, useEffect as useEffect34 } from "react";
|
|
120951
121149
|
import { Box as Box22, Text as Text29, useInput as useInput5 } from "ink";
|
|
120952
121150
|
init_modelManager();
|
|
120953
121151
|
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
@@ -120961,7 +121159,7 @@ function ProviderEndpointSelectionDialog({
|
|
|
120961
121159
|
const [loading, setLoading] = useState36(true);
|
|
120962
121160
|
const [switching, setSwitching] = useState36(false);
|
|
120963
121161
|
const [error, setError] = useState36(null);
|
|
120964
|
-
|
|
121162
|
+
useEffect34(() => {
|
|
120965
121163
|
const loadEndpoints = async () => {
|
|
120966
121164
|
try {
|
|
120967
121165
|
const modelManager = getModelManager();
|
|
@@ -121205,7 +121403,7 @@ function ProviderEndpointSelectionDialog({
|
|
|
121205
121403
|
}
|
|
121206
121404
|
|
|
121207
121405
|
// packages/cli/src/ui/components/EnhancedModelSelectionDialog.tsx
|
|
121208
|
-
import { useState as useState37, useEffect as
|
|
121406
|
+
import { useState as useState37, useEffect as useEffect35 } from "react";
|
|
121209
121407
|
import { Box as Box23, Text as Text30, useInput as useInput6 } from "ink";
|
|
121210
121408
|
init_modelManager();
|
|
121211
121409
|
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
@@ -121256,7 +121454,7 @@ function EnhancedModelSelectionDialog({
|
|
|
121256
121454
|
setLoading(false);
|
|
121257
121455
|
}
|
|
121258
121456
|
};
|
|
121259
|
-
|
|
121457
|
+
useEffect35(() => {
|
|
121260
121458
|
loadModels();
|
|
121261
121459
|
}, [providerType, endpointUrl]);
|
|
121262
121460
|
useInput6((input, key) => {
|
|
@@ -121596,7 +121794,7 @@ var WelcomeBackDialog = ({
|
|
|
121596
121794
|
};
|
|
121597
121795
|
|
|
121598
121796
|
// packages/cli/src/ui/components/SearchEngineConfigDialog.tsx
|
|
121599
|
-
import { useState as useState38, useEffect as
|
|
121797
|
+
import { useState as useState38, useEffect as useEffect36 } from "react";
|
|
121600
121798
|
import { Box as Box25, Text as Text32, useInput as useInput7 } from "ink";
|
|
121601
121799
|
init_database();
|
|
121602
121800
|
import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
@@ -121609,7 +121807,7 @@ function SearchEngineConfigDialog({
|
|
|
121609
121807
|
const [currentField, setCurrentField] = useState38("braveApiKey");
|
|
121610
121808
|
const [isLoading, setIsLoading] = useState38(true);
|
|
121611
121809
|
const [isSaving, setIsSaving] = useState38(false);
|
|
121612
|
-
|
|
121810
|
+
useEffect36(() => {
|
|
121613
121811
|
const loadConfig = async () => {
|
|
121614
121812
|
console.log("[WEBSCRAPER-DEBUG] Loading existing API keys from database...");
|
|
121615
121813
|
const db = await getFSSLinkDatabase();
|
|
@@ -121629,7 +121827,7 @@ function SearchEngineConfigDialog({
|
|
|
121629
121827
|
};
|
|
121630
121828
|
loadConfig().catch(console.error);
|
|
121631
121829
|
}, []);
|
|
121632
|
-
|
|
121830
|
+
useEffect36(() => {
|
|
121633
121831
|
if (!isSaving) return;
|
|
121634
121832
|
const saveConfig = async () => {
|
|
121635
121833
|
try {
|
|
@@ -121853,7 +122051,7 @@ function SearchEngineConfigDialog({
|
|
|
121853
122051
|
}
|
|
121854
122052
|
|
|
121855
122053
|
// packages/cli/src/ui/components/AuthInProgress.tsx
|
|
121856
|
-
import { useState as useState39, useEffect as
|
|
122054
|
+
import { useState as useState39, useEffect as useEffect37 } from "react";
|
|
121857
122055
|
import { Box as Box26, Text as Text33 } from "ink";
|
|
121858
122056
|
import Spinner2 from "ink-spinner";
|
|
121859
122057
|
import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
@@ -121869,7 +122067,7 @@ function AuthInProgress({
|
|
|
121869
122067
|
},
|
|
121870
122068
|
{ isActive: true }
|
|
121871
122069
|
);
|
|
121872
|
-
|
|
122070
|
+
useEffect37(() => {
|
|
121873
122071
|
const timer = setTimeout(() => {
|
|
121874
122072
|
setTimedOut(true);
|
|
121875
122073
|
onTimeout();
|
|
@@ -125480,7 +125678,7 @@ function IdeIntegrationNudge({
|
|
|
125480
125678
|
}
|
|
125481
125679
|
|
|
125482
125680
|
// packages/cli/src/ui/hooks/useGitBranchName.ts
|
|
125483
|
-
import { useState as useState42, useEffect as
|
|
125681
|
+
import { useState as useState42, useEffect as useEffect38, useCallback as useCallback24 } from "react";
|
|
125484
125682
|
import { exec as exec6 } from "node:child_process";
|
|
125485
125683
|
import fs65 from "node:fs";
|
|
125486
125684
|
import fsPromises3 from "node:fs/promises";
|
|
@@ -125516,7 +125714,7 @@ function useGitBranchName(cwd3) {
|
|
|
125516
125714
|
),
|
|
125517
125715
|
[cwd3, setBranchName]
|
|
125518
125716
|
);
|
|
125519
|
-
|
|
125717
|
+
useEffect38(() => {
|
|
125520
125718
|
fetchBranchName();
|
|
125521
125719
|
const gitLogsHeadPath = path77.join(cwd3, ".git", "logs", "HEAD");
|
|
125522
125720
|
let watcher;
|
|
@@ -125540,14 +125738,14 @@ function useGitBranchName(cwd3) {
|
|
|
125540
125738
|
}
|
|
125541
125739
|
|
|
125542
125740
|
// packages/cli/src/ui/hooks/useBracketedPaste.ts
|
|
125543
|
-
import { useEffect as
|
|
125741
|
+
import { useEffect as useEffect39 } from "react";
|
|
125544
125742
|
var ENABLE_BRACKETED_PASTE = "\x1B[?2004h";
|
|
125545
125743
|
var DISABLE_BRACKETED_PASTE = "\x1B[?2004l";
|
|
125546
125744
|
var useBracketedPaste = () => {
|
|
125547
125745
|
const cleanup = () => {
|
|
125548
125746
|
process.stdout.write(DISABLE_BRACKETED_PASTE);
|
|
125549
125747
|
};
|
|
125550
|
-
|
|
125748
|
+
useEffect39(() => {
|
|
125551
125749
|
process.stdout.write(ENABLE_BRACKETED_PASTE);
|
|
125552
125750
|
process.on("exit", cleanup);
|
|
125553
125751
|
process.on("SIGINT", cleanup);
|
|
@@ -125567,7 +125765,7 @@ import {
|
|
|
125567
125765
|
createContext as createContext5,
|
|
125568
125766
|
useCallback as useCallback25,
|
|
125569
125767
|
useContext as useContext5,
|
|
125570
|
-
useEffect as
|
|
125768
|
+
useEffect as useEffect40,
|
|
125571
125769
|
useState as useState43
|
|
125572
125770
|
} from "react";
|
|
125573
125771
|
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
@@ -125581,7 +125779,7 @@ var VimModeProvider = ({
|
|
|
125581
125779
|
const [vimMode, setVimMode] = useState43(
|
|
125582
125780
|
initialVimEnabled ? "NORMAL" : "INSERT"
|
|
125583
125781
|
);
|
|
125584
|
-
|
|
125782
|
+
useEffect40(() => {
|
|
125585
125783
|
const enabled = settings.merged.vimMode ?? false;
|
|
125586
125784
|
setVimEnabled(enabled);
|
|
125587
125785
|
if (enabled) {
|
|
@@ -125614,7 +125812,7 @@ var useVimMode = () => {
|
|
|
125614
125812
|
};
|
|
125615
125813
|
|
|
125616
125814
|
// packages/cli/src/ui/hooks/vim.ts
|
|
125617
|
-
import { useCallback as useCallback26, useReducer as useReducer4, useEffect as
|
|
125815
|
+
import { useCallback as useCallback26, useReducer as useReducer4, useEffect as useEffect41 } from "react";
|
|
125618
125816
|
var DIGIT_MULTIPLIER = 10;
|
|
125619
125817
|
var DEFAULT_COUNT = 1;
|
|
125620
125818
|
var DIGIT_1_TO_9 = /^[1-9]$/;
|
|
@@ -125678,7 +125876,7 @@ var vimReducer = (state, action) => {
|
|
|
125678
125876
|
function useVim(buffer, onSubmit) {
|
|
125679
125877
|
const { vimEnabled, vimMode, setVimMode } = useVimMode();
|
|
125680
125878
|
const [state, dispatch] = useReducer4(vimReducer, initialVimState);
|
|
125681
|
-
|
|
125879
|
+
useEffect41(() => {
|
|
125682
125880
|
dispatch({ type: "SET_MODE", mode: vimMode });
|
|
125683
125881
|
}, [vimMode]);
|
|
125684
125882
|
const updateMode = useCallback26(
|
|
@@ -126474,12 +126672,12 @@ import { Box as Box56, Newline as Newline3, Text as Text61 } from "ink";
|
|
|
126474
126672
|
|
|
126475
126673
|
// packages/cli/src/ui/hooks/usePrivacySettings.ts
|
|
126476
126674
|
init_dist2();
|
|
126477
|
-
import { useState as useState45, useEffect as
|
|
126675
|
+
import { useState as useState45, useEffect as useEffect42, useCallback as useCallback27 } from "react";
|
|
126478
126676
|
var usePrivacySettings = (config) => {
|
|
126479
126677
|
const [privacyState, setPrivacyState] = useState45({
|
|
126480
126678
|
isLoading: true
|
|
126481
126679
|
});
|
|
126482
|
-
|
|
126680
|
+
useEffect42(() => {
|
|
126483
126681
|
const fetchInitialState = async () => {
|
|
126484
126682
|
setPrivacyState({
|
|
126485
126683
|
isLoading: true
|
|
@@ -126693,7 +126891,7 @@ function useSettingsCommand() {
|
|
|
126693
126891
|
}
|
|
126694
126892
|
|
|
126695
126893
|
// packages/cli/src/ui/components/SettingsDialog.tsx
|
|
126696
|
-
import React30, { useState as useState47, useEffect as
|
|
126894
|
+
import React30, { useState as useState47, useEffect as useEffect43 } from "react";
|
|
126697
126895
|
import { Box as Box58, Text as Text62 } from "ink";
|
|
126698
126896
|
init_settings();
|
|
126699
126897
|
import chalk2 from "chalk";
|
|
@@ -126725,7 +126923,7 @@ function SettingsDialog({
|
|
|
126725
126923
|
);
|
|
126726
126924
|
const [globalPendingChanges, setGlobalPendingChanges] = useState47(/* @__PURE__ */ new Map());
|
|
126727
126925
|
const [_restartRequiredSettings, setRestartRequiredSettings] = useState47(/* @__PURE__ */ new Set());
|
|
126728
|
-
|
|
126926
|
+
useEffect43(() => {
|
|
126729
126927
|
let updated = structuredClone(settings.forScope(selectedScope).settings);
|
|
126730
126928
|
const newModified = /* @__PURE__ */ new Set();
|
|
126731
126929
|
const newRestartRequired = /* @__PURE__ */ new Set();
|
|
@@ -126835,7 +127033,7 @@ function SettingsDialog({
|
|
|
126835
127033
|
const [editBuffer, setEditBuffer] = useState47("");
|
|
126836
127034
|
const [editCursorPos, setEditCursorPos] = useState47(0);
|
|
126837
127035
|
const [cursorVisible, setCursorVisible] = useState47(true);
|
|
126838
|
-
|
|
127036
|
+
useEffect43(() => {
|
|
126839
127037
|
if (!editingKey) {
|
|
126840
127038
|
setCursorVisible(true);
|
|
126841
127039
|
return;
|
|
@@ -127539,11 +127737,11 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127539
127737
|
const { history, addItem, clearItems, loadHistory } = useHistory();
|
|
127540
127738
|
const [idePromptAnswered, setIdePromptAnswered] = useState48(false);
|
|
127541
127739
|
const currentIDE = config.getIdeClient().getCurrentIde();
|
|
127542
|
-
|
|
127740
|
+
useEffect44(() => {
|
|
127543
127741
|
registerCleanup(() => config.getIdeClient().disconnect());
|
|
127544
127742
|
}, [config]);
|
|
127545
127743
|
const shouldShowIdePrompt = currentIDE && !config.getIdeMode() && !settings.merged.hasSeenIdeIntegrationNudge && !idePromptAnswered;
|
|
127546
|
-
|
|
127744
|
+
useEffect44(() => {
|
|
127547
127745
|
const cleanup = setUpdateHandler(addItem, setUpdateInfo);
|
|
127548
127746
|
return cleanup;
|
|
127549
127747
|
}, [addItem]);
|
|
@@ -127552,7 +127750,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127552
127750
|
handleNewMessage,
|
|
127553
127751
|
clearConsoleMessages: clearConsoleMessagesState
|
|
127554
127752
|
} = useConsoleMessages();
|
|
127555
|
-
|
|
127753
|
+
useEffect44(() => {
|
|
127556
127754
|
const consolePatcher = new ConsolePatcher({
|
|
127557
127755
|
onNewMessage: handleNewMessage,
|
|
127558
127756
|
debugMode: config.getDebugMode()
|
|
@@ -127575,7 +127773,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127575
127773
|
const [isSearchDialogOpen, setIsSearchDialogOpen] = useState48(false);
|
|
127576
127774
|
const [isAddCustomEndpointDialogOpen, setIsAddCustomEndpointDialogOpen] = useState48(false);
|
|
127577
127775
|
const [footerHeight, setFooterHeight] = useState48(0);
|
|
127578
|
-
|
|
127776
|
+
useEffect44(() => {
|
|
127579
127777
|
const initializeSearchEngineConfig = async () => {
|
|
127580
127778
|
const configProvider = SearchEngineConfigProvider.getInstance();
|
|
127581
127779
|
await configProvider.loadConfiguration();
|
|
@@ -127602,12 +127800,12 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127602
127800
|
const [ideContextState, setIdeContextState] = useState48();
|
|
127603
127801
|
const [showEscapePrompt, setShowEscapePrompt] = useState48(false);
|
|
127604
127802
|
const [isProcessing, setIsProcessing] = useState48(false);
|
|
127605
|
-
|
|
127803
|
+
useEffect44(() => {
|
|
127606
127804
|
const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
|
|
127607
127805
|
setIdeContextState(ideContext.getIdeContext());
|
|
127608
127806
|
return unsubscribe;
|
|
127609
127807
|
}, []);
|
|
127610
|
-
|
|
127808
|
+
useEffect44(() => {
|
|
127611
127809
|
const openDebugConsole = () => {
|
|
127612
127810
|
setShowErrorDetails(true);
|
|
127613
127811
|
setConstrainHeight(false);
|
|
@@ -127674,7 +127872,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127674
127872
|
handleRestart: handleWelcomeBackRestart,
|
|
127675
127873
|
handleCancel: handleWelcomeBackCancel
|
|
127676
127874
|
} = useWelcomeBack(settings);
|
|
127677
|
-
|
|
127875
|
+
useEffect44(() => {
|
|
127678
127876
|
if (settings.merged.selectedAuthType && !settings.merged.useExternalAuth) {
|
|
127679
127877
|
const error = validateAuthMethod(settings.merged.selectedAuthType);
|
|
127680
127878
|
if (error) {
|
|
@@ -127688,7 +127886,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127688
127886
|
openAuthDialog,
|
|
127689
127887
|
setAuthError
|
|
127690
127888
|
]);
|
|
127691
|
-
|
|
127889
|
+
useEffect44(() => {
|
|
127692
127890
|
if (!isAuthenticating) {
|
|
127693
127891
|
setUserTier(config.getGeminiClient()?.getUserTier());
|
|
127694
127892
|
}
|
|
@@ -127752,7 +127950,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127752
127950
|
console.error("Error refreshing memory:", error);
|
|
127753
127951
|
}
|
|
127754
127952
|
}, [config, addItem, settings.merged]);
|
|
127755
|
-
|
|
127953
|
+
useEffect44(() => {
|
|
127756
127954
|
const checkModelChange = () => {
|
|
127757
127955
|
const configModel = config.getModel();
|
|
127758
127956
|
if (configModel !== currentModel) {
|
|
@@ -127763,7 +127961,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127763
127961
|
const interval = setInterval(checkModelChange, 1e3);
|
|
127764
127962
|
return () => clearInterval(interval);
|
|
127765
127963
|
}, [config, currentModel]);
|
|
127766
|
-
|
|
127964
|
+
useEffect44(() => {
|
|
127767
127965
|
const flashFallbackHandler = async (currentModel2, fallbackModel, error) => {
|
|
127768
127966
|
let message;
|
|
127769
127967
|
if (config.getContentGeneratorConfig().authType === AuthType.LOGIN_WITH_GOOGLE) {
|
|
@@ -127922,7 +128120,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
|
|
|
127922
128120
|
refreshStatic,
|
|
127923
128121
|
() => cancelHandlerRef.current()
|
|
127924
128122
|
);
|
|
127925
|
-
|
|
128123
|
+
useEffect44(() => {
|
|
127926
128124
|
if (contextToPopulate && !initialPromptSubmitted.current) {
|
|
127927
128125
|
submitQuery(contextToPopulate);
|
|
127928
128126
|
initialPromptSubmitted.current = true;
|
|
@@ -128057,13 +128255,13 @@ ${queuedText}` : queuedText;
|
|
|
128057
128255
|
useKeypress(handleGlobalKeypress, {
|
|
128058
128256
|
isActive: true
|
|
128059
128257
|
});
|
|
128060
|
-
|
|
128258
|
+
useEffect44(() => {
|
|
128061
128259
|
if (config) {
|
|
128062
128260
|
setGeminiMdFileCount(config.getGeminiMdFileCount());
|
|
128063
128261
|
}
|
|
128064
128262
|
}, [config, config.getGeminiMdFileCount]);
|
|
128065
128263
|
const logger6 = useLogger();
|
|
128066
|
-
|
|
128264
|
+
useEffect44(() => {
|
|
128067
128265
|
const fetchUserMessages = async () => {
|
|
128068
128266
|
const pastMessagesRaw = await logger6?.getPreviousUserMessages() || [];
|
|
128069
128267
|
const currentSessionUserMessages = history.filter(
|
|
@@ -128095,7 +128293,7 @@ ${queuedText}` : queuedText;
|
|
|
128095
128293
|
}, [clearItems, clearConsoleMessagesState, refreshStatic]);
|
|
128096
128294
|
const mainControlsRef = useRef12(null);
|
|
128097
128295
|
const pendingHistoryItemRef = useRef12(null);
|
|
128098
|
-
|
|
128296
|
+
useEffect44(() => {
|
|
128099
128297
|
if (mainControlsRef.current) {
|
|
128100
128298
|
const fullFooterMeasurement = measureElement(mainControlsRef.current);
|
|
128101
128299
|
setFooterHeight(fullFooterMeasurement.height);
|
|
@@ -128109,7 +128307,7 @@ ${queuedText}` : queuedText;
|
|
|
128109
128307
|
() => terminalHeight - footerHeight - staticExtraHeight,
|
|
128110
128308
|
[terminalHeight, footerHeight]
|
|
128111
128309
|
);
|
|
128112
|
-
|
|
128310
|
+
useEffect44(() => {
|
|
128113
128311
|
if (isInitialMount.current) {
|
|
128114
128312
|
isInitialMount.current = false;
|
|
128115
128313
|
return;
|
|
@@ -128122,7 +128320,7 @@ ${queuedText}` : queuedText;
|
|
|
128122
128320
|
clearTimeout(handler);
|
|
128123
128321
|
};
|
|
128124
128322
|
}, [terminalWidth, terminalHeight, refreshStatic]);
|
|
128125
|
-
|
|
128323
|
+
useEffect44(() => {
|
|
128126
128324
|
if (streamingState === "idle" /* Idle */ && staticNeedsRefresh) {
|
|
128127
128325
|
setStaticNeedsRefresh(false);
|
|
128128
128326
|
refreshStatic();
|
|
@@ -128144,7 +128342,7 @@ ${queuedText}` : queuedText;
|
|
|
128144
128342
|
}, [settings.merged.contextFileName]);
|
|
128145
128343
|
const initialPrompt = useMemo9(() => config.getQuestion(), [config]);
|
|
128146
128344
|
const geminiClient = config.getGeminiClient();
|
|
128147
|
-
|
|
128345
|
+
useEffect44(() => {
|
|
128148
128346
|
if (initialPrompt && !initialPromptSubmitted.current && !isAuthenticating && !isAuthDialogOpen && !shouldShowWelcomeBack && !isThemeDialogOpen && !isEditorDialogOpen && !isSearchDialogOpen && modelDialogState === "none" && !showPrivacyNotice && geminiClient?.isInitialized?.()) {
|
|
128149
128347
|
submitQuery(initialPrompt);
|
|
128150
128348
|
initialPromptSubmitted.current = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fss-link",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.0.0"
|
|
6
6
|
},
|
|
@@ -133,6 +133,7 @@
|
|
|
133
133
|
"ink-link": "^4.1.0",
|
|
134
134
|
"ink-select-input": "^6.2.0",
|
|
135
135
|
"ink-spinner": "^5.0.0",
|
|
136
|
+
"ink-text-input": "^6.0.0",
|
|
136
137
|
"jsdom": "^27.0.0",
|
|
137
138
|
"lowlight": "^3.3.0",
|
|
138
139
|
"mime-types": "^3.0.1",
|