fss-link 1.5.0 → 1.5.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/bundle/fss-link.js +177 -92
- package/package.json +1 -1
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.5.
|
|
22382
|
+
const version = "1.5.1";
|
|
22383
22383
|
const userAgent = `FSS-Link/${version} (${process.platform}; ${process.arch})`;
|
|
22384
22384
|
const baseHeaders = {
|
|
22385
22385
|
"User-Agent": userAgent
|
|
@@ -96359,7 +96359,7 @@ async function getPackageJson() {
|
|
|
96359
96359
|
// packages/cli/src/utils/version.ts
|
|
96360
96360
|
async function getCliVersion() {
|
|
96361
96361
|
const pkgJson = await getPackageJson();
|
|
96362
|
-
return "1.5.
|
|
96362
|
+
return "1.5.1";
|
|
96363
96363
|
}
|
|
96364
96364
|
|
|
96365
96365
|
// packages/cli/src/ui/commands/aboutCommand.ts
|
|
@@ -96411,7 +96411,7 @@ import open4 from "open";
|
|
|
96411
96411
|
import process11 from "node:process";
|
|
96412
96412
|
|
|
96413
96413
|
// packages/cli/src/generated/git-commit.ts
|
|
96414
|
-
var GIT_COMMIT_INFO = "
|
|
96414
|
+
var GIT_COMMIT_INFO = "7684208c";
|
|
96415
96415
|
|
|
96416
96416
|
// packages/cli/src/ui/commands/bugCommand.ts
|
|
96417
96417
|
init_dist2();
|
|
@@ -120708,6 +120708,9 @@ import { useState as useState33, useEffect as useEffect32 } from "react";
|
|
|
120708
120708
|
import { Box as Box19, Text as Text26, useInput as useInput4 } from "ink";
|
|
120709
120709
|
|
|
120710
120710
|
// packages/cli/src/utils/modelFetcher.ts
|
|
120711
|
+
init_dist2();
|
|
120712
|
+
var modelCache = /* @__PURE__ */ new Map();
|
|
120713
|
+
var MODEL_CACHE_TTL = 5 * 60 * 1e3;
|
|
120711
120714
|
async function fetchModelsFromCustomEndpoint(baseUrl, providerType, apiKey) {
|
|
120712
120715
|
const normalizedBase = baseUrl.replace(/\/+$/, "");
|
|
120713
120716
|
const url2 = `${normalizedBase}/models`;
|
|
@@ -120779,6 +120782,39 @@ async function fetchModelsFromCustomEndpoint(baseUrl, providerType, apiKey) {
|
|
|
120779
120782
|
throw new Error(`Connection failed: ${String(error)}`);
|
|
120780
120783
|
}
|
|
120781
120784
|
}
|
|
120785
|
+
async function fetchModelsFromProvider(provider, endpoint, apiKey, forceRefresh = false) {
|
|
120786
|
+
const cacheKey = `${provider}:${endpoint || "default"}`;
|
|
120787
|
+
if (!forceRefresh) {
|
|
120788
|
+
const cached = modelCache.get(cacheKey);
|
|
120789
|
+
if (cached && Date.now() - cached.timestamp < MODEL_CACHE_TTL) {
|
|
120790
|
+
console.error(`[DEBUG] Using cached models for ${cacheKey}`);
|
|
120791
|
+
return cached.models;
|
|
120792
|
+
}
|
|
120793
|
+
}
|
|
120794
|
+
let fetchUrl;
|
|
120795
|
+
if (endpoint) {
|
|
120796
|
+
fetchUrl = endpoint;
|
|
120797
|
+
} else {
|
|
120798
|
+
switch (provider) {
|
|
120799
|
+
case AuthType.OLLAMA:
|
|
120800
|
+
fetchUrl = "http://localhost:11434";
|
|
120801
|
+
break;
|
|
120802
|
+
case AuthType.LM_STUDIO:
|
|
120803
|
+
fetchUrl = "http://localhost:1234/v1";
|
|
120804
|
+
break;
|
|
120805
|
+
default:
|
|
120806
|
+
throw new Error(`No default endpoint for provider: ${provider}`);
|
|
120807
|
+
}
|
|
120808
|
+
}
|
|
120809
|
+
console.error(`[DEBUG] Fetching models from ${provider} at ${fetchUrl}`);
|
|
120810
|
+
const models = await fetchModelsFromCustomEndpoint(fetchUrl, provider, apiKey);
|
|
120811
|
+
modelCache.set(cacheKey, {
|
|
120812
|
+
models,
|
|
120813
|
+
timestamp: Date.now()
|
|
120814
|
+
});
|
|
120815
|
+
console.error(`[DEBUG] Cached ${models.length} models for ${cacheKey}`);
|
|
120816
|
+
return models;
|
|
120817
|
+
}
|
|
120782
120818
|
|
|
120783
120819
|
// packages/cli/src/ui/components/shared/PasteAwareTextInput.tsx
|
|
120784
120820
|
import TextInput from "ink-text-input";
|
|
@@ -121791,85 +121827,104 @@ function EnhancedModelSelectionDialog({
|
|
|
121791
121827
|
onBack,
|
|
121792
121828
|
onCancel
|
|
121793
121829
|
}) {
|
|
121794
|
-
const [
|
|
121830
|
+
const [allModels, setAllModels] = useState37([]);
|
|
121795
121831
|
const [selectedIndex, setSelectedIndex] = useState37(0);
|
|
121832
|
+
const [scrollOffset, setScrollOffset] = useState37(0);
|
|
121796
121833
|
const [loading, setLoading] = useState37(true);
|
|
121797
121834
|
const [error, setError] = useState37(null);
|
|
121798
121835
|
const [switching, setSwitching] = useState37(false);
|
|
121799
|
-
const
|
|
121800
|
-
|
|
121801
|
-
|
|
121802
|
-
|
|
121803
|
-
|
|
121804
|
-
|
|
121805
|
-
const
|
|
121806
|
-
|
|
121807
|
-
|
|
121808
|
-
|
|
121809
|
-
|
|
121810
|
-
|
|
121811
|
-
|
|
121836
|
+
const VISIBLE_MODELS = 15;
|
|
121837
|
+
useEffect35(() => {
|
|
121838
|
+
const loadAndFetchModels = async () => {
|
|
121839
|
+
setLoading(true);
|
|
121840
|
+
setError(null);
|
|
121841
|
+
try {
|
|
121842
|
+
const modelManager = getModelManager();
|
|
121843
|
+
const allDbModels = await modelManager.getAllModels();
|
|
121844
|
+
const existing = allDbModels.filter(
|
|
121845
|
+
(m) => m.authType === providerType && (!endpointUrl || m.endpointUrl === endpointUrl)
|
|
121846
|
+
);
|
|
121847
|
+
const activeModel = allDbModels.find((m) => m.isActive);
|
|
121848
|
+
const activeModelId = activeModel?.modelName;
|
|
121849
|
+
console.error(`[DEBUG] Fetching models for ${providerType} from ${endpointUrl || "default"}`);
|
|
121850
|
+
const fetched = await fetchModelsFromProvider(providerType, endpointUrl);
|
|
121851
|
+
const existingModelNames = new Set(existing.map((m) => m.modelName));
|
|
121852
|
+
const merged = fetched.map((fm) => ({
|
|
121853
|
+
...fm,
|
|
121854
|
+
isNew: !existingModelNames.has(fm.id),
|
|
121855
|
+
isExisting: existingModelNames.has(fm.id),
|
|
121856
|
+
isActive: fm.id === activeModelId
|
|
121857
|
+
}));
|
|
121858
|
+
merged.sort((a, b) => {
|
|
121859
|
+
if (a.isActive && !b.isActive) return -1;
|
|
121860
|
+
if (!a.isActive && b.isActive) return 1;
|
|
121861
|
+
if (a.isExisting && !b.isExisting) return -1;
|
|
121862
|
+
if (!a.isExisting && b.isExisting) return 1;
|
|
121863
|
+
return 0;
|
|
121864
|
+
});
|
|
121865
|
+
setAllModels(merged);
|
|
121866
|
+
setLoading(false);
|
|
121867
|
+
} catch (err) {
|
|
121868
|
+
setError(err instanceof Error ? err.message : "Failed to fetch models");
|
|
121812
121869
|
setLoading(false);
|
|
121813
|
-
return;
|
|
121814
|
-
}
|
|
121815
|
-
filtered.sort((a, b) => {
|
|
121816
|
-
if (a.isFavorite && !b.isFavorite) return -1;
|
|
121817
|
-
if (!a.isFavorite && b.isFavorite) return 1;
|
|
121818
|
-
if (a.isActive && !b.isActive) return -1;
|
|
121819
|
-
if (!a.isActive && b.isActive) return 1;
|
|
121820
|
-
return a.modelName.localeCompare(b.modelName);
|
|
121821
|
-
});
|
|
121822
|
-
const activeIndex = filtered.findIndex((m) => m.isActive);
|
|
121823
|
-
if (activeIndex !== -1) {
|
|
121824
|
-
setSelectedIndex(activeIndex);
|
|
121825
121870
|
}
|
|
121826
|
-
|
|
121827
|
-
|
|
121828
|
-
} catch (err) {
|
|
121829
|
-
setError(err instanceof Error ? err.message : "Failed to load models");
|
|
121830
|
-
setLoading(false);
|
|
121831
|
-
}
|
|
121832
|
-
};
|
|
121833
|
-
useEffect35(() => {
|
|
121834
|
-
loadModels();
|
|
121871
|
+
};
|
|
121872
|
+
loadAndFetchModels();
|
|
121835
121873
|
}, [providerType, endpointUrl]);
|
|
121836
121874
|
useInput6((input, key) => {
|
|
121837
121875
|
if (loading || switching) return;
|
|
121838
|
-
if (key.escape) {
|
|
121876
|
+
if (key.escape || input === "b" || input === "B") {
|
|
121839
121877
|
onBack();
|
|
121840
121878
|
return;
|
|
121841
121879
|
}
|
|
121842
|
-
if (
|
|
121843
|
-
const
|
|
121844
|
-
|
|
121845
|
-
|
|
121846
|
-
|
|
121847
|
-
loadModels();
|
|
121848
|
-
}).catch((err) => {
|
|
121849
|
-
console.error("Failed to toggle favorite:", err);
|
|
121850
|
-
});
|
|
121880
|
+
if (key.upArrow && selectedIndex > 0) {
|
|
121881
|
+
const newIndex = selectedIndex - 1;
|
|
121882
|
+
setSelectedIndex(newIndex);
|
|
121883
|
+
if (newIndex < scrollOffset) {
|
|
121884
|
+
setScrollOffset(newIndex);
|
|
121851
121885
|
}
|
|
121852
121886
|
return;
|
|
121853
121887
|
}
|
|
121854
|
-
if (
|
|
121855
|
-
|
|
121856
|
-
|
|
121857
|
-
|
|
121858
|
-
|
|
121859
|
-
modelManager.switchToModel(selectedModel.id).then(() => {
|
|
121860
|
-
onComplete();
|
|
121861
|
-
}).catch((err) => {
|
|
121862
|
-
setError(err instanceof Error ? err.message : "Failed to switch model");
|
|
121863
|
-
setSwitching(false);
|
|
121864
|
-
});
|
|
121888
|
+
if (key.downArrow && selectedIndex < allModels.length - 1) {
|
|
121889
|
+
const newIndex = selectedIndex + 1;
|
|
121890
|
+
setSelectedIndex(newIndex);
|
|
121891
|
+
if (newIndex >= scrollOffset + VISIBLE_MODELS) {
|
|
121892
|
+
setScrollOffset(newIndex - VISIBLE_MODELS + 1);
|
|
121865
121893
|
}
|
|
121866
121894
|
return;
|
|
121867
121895
|
}
|
|
121868
|
-
if (key.
|
|
121869
|
-
|
|
121870
|
-
|
|
121871
|
-
|
|
121872
|
-
|
|
121896
|
+
if (key.return && allModels.length > 0) {
|
|
121897
|
+
const selectedModel = allModels[selectedIndex];
|
|
121898
|
+
setSwitching(true);
|
|
121899
|
+
const modelManager = getModelManager();
|
|
121900
|
+
(async () => {
|
|
121901
|
+
try {
|
|
121902
|
+
if (selectedModel.isNew) {
|
|
121903
|
+
console.error(`[DEBUG] Auto-adding new model: ${selectedModel.id}`);
|
|
121904
|
+
await modelManager.configureModel(
|
|
121905
|
+
providerType,
|
|
121906
|
+
selectedModel.id,
|
|
121907
|
+
endpointUrl,
|
|
121908
|
+
void 0,
|
|
121909
|
+
// No API key needed for already configured endpoints
|
|
121910
|
+
selectedModel.id
|
|
121911
|
+
// Use model ID as display name
|
|
121912
|
+
);
|
|
121913
|
+
}
|
|
121914
|
+
const allDbModels = await modelManager.getAllModels();
|
|
121915
|
+
const dbModel = allDbModels.find((m) => m.modelName === selectedModel.id);
|
|
121916
|
+
if (dbModel?.id) {
|
|
121917
|
+
await modelManager.switchToModel(dbModel.id);
|
|
121918
|
+
onComplete();
|
|
121919
|
+
} else {
|
|
121920
|
+
throw new Error("Failed to find model after adding");
|
|
121921
|
+
}
|
|
121922
|
+
} catch (err) {
|
|
121923
|
+
setError(err instanceof Error ? err.message : "Failed to switch model");
|
|
121924
|
+
setSwitching(false);
|
|
121925
|
+
}
|
|
121926
|
+
})();
|
|
121927
|
+
return;
|
|
121873
121928
|
}
|
|
121874
121929
|
});
|
|
121875
121930
|
if (loading) {
|
|
@@ -121882,11 +121937,8 @@ function EnhancedModelSelectionDialog({
|
|
|
121882
121937
|
padding: 1,
|
|
121883
121938
|
width: "100%",
|
|
121884
121939
|
children: [
|
|
121885
|
-
/* @__PURE__ */
|
|
121886
|
-
|
|
121887
|
-
endpointLabel
|
|
121888
|
-
] }),
|
|
121889
|
-
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text30, { children: "Loading models..." }) })
|
|
121940
|
+
/* @__PURE__ */ jsx29(Text30, { bold: true, color: Colors.AccentBlue, children: "Model Selection" }),
|
|
121941
|
+
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text30, { children: "Loading configured models..." }) })
|
|
121890
121942
|
]
|
|
121891
121943
|
}
|
|
121892
121944
|
);
|
|
@@ -121904,7 +121956,7 @@ function EnhancedModelSelectionDialog({
|
|
|
121904
121956
|
/* @__PURE__ */ jsx29(Text30, { bold: true, color: Colors.AccentBlue, children: "Switching Model" }),
|
|
121905
121957
|
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsxs26(Text30, { children: [
|
|
121906
121958
|
"Activating ",
|
|
121907
|
-
|
|
121959
|
+
allModels[selectedIndex]?.id,
|
|
121908
121960
|
"..."
|
|
121909
121961
|
] }) })
|
|
121910
121962
|
]
|
|
@@ -121923,11 +121975,14 @@ function EnhancedModelSelectionDialog({
|
|
|
121923
121975
|
children: [
|
|
121924
121976
|
/* @__PURE__ */ jsx29(Text30, { bold: true, color: Colors.AccentRed, children: "Model Selection Error" }),
|
|
121925
121977
|
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text30, { children: error }) }),
|
|
121926
|
-
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text30, { color: Colors.Gray, children: "Press Esc to
|
|
121978
|
+
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text30, { color: Colors.Gray, children: "Press Esc to cancel" }) })
|
|
121927
121979
|
]
|
|
121928
121980
|
}
|
|
121929
121981
|
);
|
|
121930
121982
|
}
|
|
121983
|
+
const visibleModels = allModels.slice(scrollOffset, scrollOffset + VISIBLE_MODELS);
|
|
121984
|
+
const modelsAbove = scrollOffset;
|
|
121985
|
+
const modelsBelow = Math.max(0, allModels.length - (scrollOffset + VISIBLE_MODELS));
|
|
121931
121986
|
return /* @__PURE__ */ jsxs26(
|
|
121932
121987
|
Box23,
|
|
121933
121988
|
{
|
|
@@ -121939,15 +121994,35 @@ function EnhancedModelSelectionDialog({
|
|
|
121939
121994
|
children: [
|
|
121940
121995
|
/* @__PURE__ */ jsxs26(Text30, { bold: true, color: Colors.AccentBlue, children: [
|
|
121941
121996
|
"Model Selection - ",
|
|
121942
|
-
|
|
121997
|
+
providerType
|
|
121943
121998
|
] }),
|
|
121944
|
-
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */
|
|
121945
|
-
|
|
121946
|
-
|
|
121999
|
+
endpointLabel && /* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsxs26(Text30, { color: Colors.Gray, children: [
|
|
122000
|
+
"Endpoint: ",
|
|
122001
|
+
endpointLabel
|
|
122002
|
+
] }) }),
|
|
122003
|
+
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsxs26(Text30, { children: [
|
|
122004
|
+
"Select a model (",
|
|
122005
|
+
allModels.length,
|
|
122006
|
+
" available):"
|
|
122007
|
+
] }) }),
|
|
122008
|
+
modelsAbove > 0 && /* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsxs26(Text30, { color: Colors.Gray, children: [
|
|
122009
|
+
"\u2191 ",
|
|
122010
|
+
modelsAbove,
|
|
122011
|
+
" more above"
|
|
122012
|
+
] }) }),
|
|
122013
|
+
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, flexDirection: "column", children: visibleModels.map((model, visibleIndex) => {
|
|
122014
|
+
const actualIndex = scrollOffset + visibleIndex;
|
|
122015
|
+
const isSelected = actualIndex === selectedIndex;
|
|
121947
122016
|
const prefix = isSelected ? ">" : " ";
|
|
121948
|
-
|
|
121949
|
-
|
|
121950
|
-
|
|
122017
|
+
let statusIcon = "";
|
|
122018
|
+
if (model.isActive) {
|
|
122019
|
+
statusIcon = "\u25CF ";
|
|
122020
|
+
} else if (model.isNew) {
|
|
122021
|
+
statusIcon = "\u{1F195} ";
|
|
122022
|
+
} else if (model.isExisting) {
|
|
122023
|
+
statusIcon = "\u2713 ";
|
|
122024
|
+
}
|
|
122025
|
+
const label = `${prefix} ${statusIcon}${model.id}`;
|
|
121951
122026
|
return /* @__PURE__ */ jsx29(
|
|
121952
122027
|
Text30,
|
|
121953
122028
|
{
|
|
@@ -121955,15 +122030,16 @@ function EnhancedModelSelectionDialog({
|
|
|
121955
122030
|
bold: isSelected,
|
|
121956
122031
|
children: label
|
|
121957
122032
|
},
|
|
121958
|
-
model.id
|
|
122033
|
+
model.id
|
|
121959
122034
|
);
|
|
121960
122035
|
}) }),
|
|
121961
|
-
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */
|
|
121962
|
-
|
|
121963
|
-
|
|
121964
|
-
"
|
|
121965
|
-
|
|
121966
|
-
|
|
122036
|
+
modelsBelow > 0 && /* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsxs26(Text30, { color: Colors.Gray, children: [
|
|
122037
|
+
"\u2193 ",
|
|
122038
|
+
modelsBelow,
|
|
122039
|
+
" more below"
|
|
122040
|
+
] }) }),
|
|
122041
|
+
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text30, { color: Colors.Gray, children: "\u2191/\u2193 to navigate, Enter to select, Esc/b to go back" }) }),
|
|
122042
|
+
/* @__PURE__ */ jsx29(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text30, { color: Colors.Gray, children: "\u{1F195} = new model, \u2713 = existing, \u25CF = currently active" }) })
|
|
121967
122043
|
]
|
|
121968
122044
|
}
|
|
121969
122045
|
);
|
|
@@ -123668,14 +123744,18 @@ async function loadCliConfig(settings, extensions, sessionId2, argv, cwd3 = proc
|
|
|
123668
123744
|
const { SearchEngineConfigProvider: SearchEngineConfigProvider2 } = await Promise.resolve().then(() => (init_SearchEngineConfigProvider(), SearchEngineConfigProvider_exports));
|
|
123669
123745
|
const configProvider = SearchEngineConfigProvider2.getInstance();
|
|
123670
123746
|
const config2 = await configProvider.loadConfiguration();
|
|
123671
|
-
|
|
123672
|
-
|
|
123673
|
-
|
|
123674
|
-
|
|
123675
|
-
|
|
123676
|
-
|
|
123747
|
+
if (debugMode) {
|
|
123748
|
+
console.log("[API KEY DEBUG] Search engine config loaded at startup:", {
|
|
123749
|
+
hasBrave: !!config2.braveApiKey,
|
|
123750
|
+
hasTavily: !!config2.tavilyApiKey,
|
|
123751
|
+
braveEnvSet: !!process16.env["BRAVE_SEARCH_API_KEY"],
|
|
123752
|
+
tavilyEnvSet: !!process16.env["TAVILY_API_KEY"]
|
|
123753
|
+
});
|
|
123754
|
+
}
|
|
123677
123755
|
} catch (error) {
|
|
123678
|
-
|
|
123756
|
+
if (debugMode) {
|
|
123757
|
+
console.error("[API KEY DEBUG] Failed to load search engine config at startup:", error);
|
|
123758
|
+
}
|
|
123679
123759
|
}
|
|
123680
123760
|
const webScraperConfigLoader = () => {
|
|
123681
123761
|
try {
|
|
@@ -131762,6 +131842,11 @@ main().catch((error) => {
|
|
|
131762
131842
|
* Copyright 2025 FSS Coding
|
|
131763
131843
|
* SPDX-License-Identifier: Apache-2.0
|
|
131764
131844
|
*/
|
|
131845
|
+
/**
|
|
131846
|
+
* @license
|
|
131847
|
+
* Copyright 2025 Google LLC
|
|
131848
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
131849
|
+
*/
|
|
131765
131850
|
/*! Bundled license information:
|
|
131766
131851
|
|
|
131767
131852
|
js-yaml/dist/js-yaml.mjs:
|