fss-link 1.0.7 → 1.0.10

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.
Files changed (2) hide show
  1. package/bundle/fss-link.js +221 -109
  2. package/package.json +41 -5
@@ -6098,7 +6098,7 @@ async function cleanupCheckpoints() {
6098
6098
  import { AuthType } from "@fsscoding/fss-link-core";
6099
6099
 
6100
6100
  // packages/cli/src/config/database.ts
6101
- import Database from "better-sqlite3";
6101
+ import initSqlJs from "sql.js";
6102
6102
  import * as path5 from "path";
6103
6103
  import * as fs6 from "fs";
6104
6104
 
@@ -6467,21 +6467,52 @@ function saveSettings(settingsFile) {
6467
6467
 
6468
6468
  // packages/cli/src/config/database.ts
6469
6469
  var FSSLinkDatabase = class {
6470
- db;
6470
+ db = null;
6471
6471
  dbPath;
6472
+ SQL;
6473
+ initialized = false;
6472
6474
  constructor() {
6473
6475
  if (!fs6.existsSync(USER_SETTINGS_DIR)) {
6474
6476
  fs6.mkdirSync(USER_SETTINGS_DIR, { recursive: true });
6475
6477
  }
6476
6478
  this.dbPath = path5.join(USER_SETTINGS_DIR, "fss-link.db");
6477
- this.db = new Database(this.dbPath);
6478
- this.db.pragma("journal_mode = WAL");
6479
+ }
6480
+ /**
6481
+ * Initialize the database - must be called before any operations
6482
+ */
6483
+ async initialize() {
6484
+ if (this.initialized) return;
6485
+ this.SQL = await initSqlJs();
6486
+ if (fs6.existsSync(this.dbPath)) {
6487
+ const data = fs6.readFileSync(this.dbPath);
6488
+ this.db = new this.SQL.Database(data);
6489
+ } else {
6490
+ this.db = new this.SQL.Database();
6491
+ }
6479
6492
  this.initializeSchema();
6493
+ this.initialized = true;
6494
+ }
6495
+ /**
6496
+ * Ensure database is initialized
6497
+ */
6498
+ async ensureInitialized() {
6499
+ if (!this.initialized) {
6500
+ await this.initialize();
6501
+ }
6502
+ }
6503
+ /**
6504
+ * Save database to disk
6505
+ */
6506
+ save() {
6507
+ if (!this.db) return;
6508
+ const data = this.db.export();
6509
+ fs6.writeFileSync(this.dbPath, Buffer.from(data));
6480
6510
  }
6481
6511
  /**
6482
6512
  * Initialize database schema
6483
6513
  */
6484
6514
  initializeSchema() {
6515
+ if (!this.db) return;
6485
6516
  this.db.exec(`
6486
6517
  CREATE TABLE IF NOT EXISTS model_configs (
6487
6518
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -6510,11 +6541,14 @@ var FSSLinkDatabase = class {
6510
6541
  CREATE INDEX IF NOT EXISTS idx_model_configs_last_used ON model_configs(last_used DESC);
6511
6542
  CREATE INDEX IF NOT EXISTS idx_model_configs_auth_type ON model_configs(auth_type);
6512
6543
  `);
6544
+ this.save();
6513
6545
  }
6514
6546
  /**
6515
6547
  * Get the currently active model configuration
6516
6548
  */
6517
- getActiveModel() {
6549
+ async getActiveModel() {
6550
+ await this.ensureInitialized();
6551
+ if (!this.db) return null;
6518
6552
  const stmt = this.db.prepare(`
6519
6553
  SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
6520
6554
  is_favorite, is_active, last_used, created_at
@@ -6522,32 +6556,35 @@ var FSSLinkDatabase = class {
6522
6556
  WHERE is_active = 1
6523
6557
  LIMIT 1
6524
6558
  `);
6525
- const result = stmt.get();
6526
- return result ? this.mapRowToModelConfig(result) : null;
6559
+ const result = stmt.getAsObject({});
6560
+ return result && Object.keys(result).length > 0 ? this.mapRowToModelConfig(result) : null;
6527
6561
  }
6528
6562
  /**
6529
6563
  * Set a model as active (and deactivate all others)
6530
6564
  */
6531
- setActiveModel(id) {
6532
- this.db.transaction(() => {
6533
- this.db.prepare("UPDATE model_configs SET is_active = 0").run();
6534
- this.db.prepare(`
6535
- UPDATE model_configs
6536
- SET is_active = 1, last_used = CURRENT_TIMESTAMP
6537
- WHERE id = ?
6538
- `).run(id);
6539
- })();
6565
+ async setActiveModel(id) {
6566
+ await this.ensureInitialized();
6567
+ if (!this.db) return;
6568
+ this.db.run("UPDATE model_configs SET is_active = 0");
6569
+ this.db.run(`
6570
+ UPDATE model_configs
6571
+ SET is_active = 1, last_used = CURRENT_TIMESTAMP
6572
+ WHERE id = ?
6573
+ `, [id]);
6574
+ this.save();
6540
6575
  }
6541
6576
  /**
6542
6577
  * Add or update a model configuration
6543
6578
  */
6544
- upsertModelConfig(config) {
6579
+ async upsertModelConfig(config) {
6580
+ await this.ensureInitialized();
6581
+ if (!this.db) return -1;
6545
6582
  const stmt = this.db.prepare(`
6546
6583
  INSERT OR REPLACE INTO model_configs
6547
6584
  (auth_type, model_name, endpoint_url, api_key, display_name, is_favorite, is_active, last_used)
6548
6585
  VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
6549
6586
  `);
6550
- const result = stmt.run(
6587
+ stmt.run([
6551
6588
  config.authType,
6552
6589
  config.modelName,
6553
6590
  config.endpointUrl || null,
@@ -6555,25 +6592,35 @@ var FSSLinkDatabase = class {
6555
6592
  config.displayName || null,
6556
6593
  config.isFavorite ? 1 : 0,
6557
6594
  config.isActive ? 1 : 0
6558
- );
6559
- return result.lastInsertRowid;
6595
+ ]);
6596
+ this.save();
6597
+ const result = this.db.exec("SELECT last_insert_rowid() as id");
6598
+ return result[0]?.values[0]?.[0] || -1;
6560
6599
  }
6561
6600
  /**
6562
6601
  * Get all model configurations
6563
6602
  */
6564
- getAllModels() {
6603
+ async getAllModels() {
6604
+ await this.ensureInitialized();
6605
+ if (!this.db) return [];
6565
6606
  const stmt = this.db.prepare(`
6566
6607
  SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
6567
6608
  is_favorite, is_active, last_used, created_at
6568
6609
  FROM model_configs
6569
6610
  ORDER BY is_favorite DESC, last_used DESC, created_at DESC
6570
6611
  `);
6571
- return stmt.all().map((row) => this.mapRowToModelConfig(row));
6612
+ const results = [];
6613
+ while (stmt.step()) {
6614
+ results.push(this.mapRowToModelConfig(stmt.getAsObject()));
6615
+ }
6616
+ return results;
6572
6617
  }
6573
6618
  /**
6574
6619
  * Get favorite models
6575
6620
  */
6576
- getFavoriteModels() {
6621
+ async getFavoriteModels() {
6622
+ await this.ensureInitialized();
6623
+ if (!this.db) return [];
6577
6624
  const stmt = this.db.prepare(`
6578
6625
  SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
6579
6626
  is_favorite, is_active, last_used, created_at
@@ -6581,12 +6628,18 @@ var FSSLinkDatabase = class {
6581
6628
  WHERE is_favorite = 1
6582
6629
  ORDER BY last_used DESC, created_at DESC
6583
6630
  `);
6584
- return stmt.all().map((row) => this.mapRowToModelConfig(row));
6631
+ const results = [];
6632
+ while (stmt.step()) {
6633
+ results.push(this.mapRowToModelConfig(stmt.getAsObject()));
6634
+ }
6635
+ return results;
6585
6636
  }
6586
6637
  /**
6587
6638
  * Get recently used models
6588
6639
  */
6589
- getRecentModels(limit = 10) {
6640
+ async getRecentModels(limit = 10) {
6641
+ await this.ensureInitialized();
6642
+ if (!this.db) return [];
6590
6643
  const stmt = this.db.prepare(`
6591
6644
  SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
6592
6645
  is_favorite, is_active, last_used, created_at
@@ -6594,48 +6647,70 @@ var FSSLinkDatabase = class {
6594
6647
  WHERE last_used IS NOT NULL
6595
6648
  ORDER BY last_used DESC
6596
6649
  LIMIT ?
6597
- `);
6598
- return stmt.all(limit).map((row) => this.mapRowToModelConfig(row));
6650
+ `, [limit]);
6651
+ const results = [];
6652
+ while (stmt.step()) {
6653
+ results.push(this.mapRowToModelConfig(stmt.getAsObject()));
6654
+ }
6655
+ return results;
6599
6656
  }
6600
6657
  /**
6601
6658
  * Toggle favorite status for a model
6602
6659
  */
6603
- toggleModelFavorite(id) {
6604
- this.db.prepare(`
6660
+ async toggleModelFavorite(id) {
6661
+ await this.ensureInitialized();
6662
+ if (!this.db) return;
6663
+ this.db.run(`
6605
6664
  UPDATE model_configs
6606
6665
  SET is_favorite = CASE WHEN is_favorite = 1 THEN 0 ELSE 1 END
6607
6666
  WHERE id = ?
6608
- `).run(id);
6667
+ `, [id]);
6668
+ this.save();
6609
6669
  }
6610
6670
  /**
6611
6671
  * Delete a model configuration
6612
6672
  */
6613
- deleteModel(id) {
6614
- this.db.prepare("DELETE FROM model_configs WHERE id = ?").run(id);
6673
+ async deleteModel(id) {
6674
+ await this.ensureInitialized();
6675
+ if (!this.db) return;
6676
+ this.db.run("DELETE FROM model_configs WHERE id = ?", [id]);
6677
+ this.save();
6615
6678
  }
6616
6679
  /**
6617
6680
  * Set user preference
6618
6681
  */
6619
- setUserPreference(key, value) {
6620
- this.db.prepare(`
6682
+ async setUserPreference(key, value) {
6683
+ await this.ensureInitialized();
6684
+ if (!this.db) return;
6685
+ this.db.run(`
6621
6686
  INSERT OR REPLACE INTO user_preferences (key, value, updated_at)
6622
6687
  VALUES (?, ?, CURRENT_TIMESTAMP)
6623
- `).run(key, value);
6688
+ `, [key, value]);
6689
+ this.save();
6624
6690
  }
6625
6691
  /**
6626
6692
  * Get user preference
6627
6693
  */
6628
- getUserPreference(key) {
6629
- const result = this.db.prepare("SELECT value FROM user_preferences WHERE key = ?").get(key);
6630
- return result ? result.value : null;
6694
+ async getUserPreference(key) {
6695
+ await this.ensureInitialized();
6696
+ if (!this.db) return null;
6697
+ const stmt = this.db.prepare("SELECT value FROM user_preferences WHERE key = ?", [key]);
6698
+ if (stmt.step()) {
6699
+ const result = stmt.getAsObject();
6700
+ return result.value || null;
6701
+ }
6702
+ return null;
6631
6703
  }
6632
6704
  /**
6633
6705
  * Get all user preferences
6634
6706
  */
6635
- getAllUserPreferences() {
6636
- const rows = this.db.prepare("SELECT key, value FROM user_preferences").all();
6707
+ async getAllUserPreferences() {
6708
+ await this.ensureInitialized();
6709
+ if (!this.db) return {};
6710
+ const stmt = this.db.prepare("SELECT key, value FROM user_preferences");
6637
6711
  const prefs = {};
6638
- for (const row of rows) {
6712
+ while (stmt.step()) {
6713
+ const row = stmt.getAsObject();
6639
6714
  prefs[row.key] = row.value;
6640
6715
  }
6641
6716
  return prefs;
@@ -6644,7 +6719,12 @@ var FSSLinkDatabase = class {
6644
6719
  * Close database connection
6645
6720
  */
6646
6721
  close() {
6647
- this.db.close();
6722
+ if (this.db) {
6723
+ this.save();
6724
+ this.db.close();
6725
+ this.db = null;
6726
+ this.initialized = false;
6727
+ }
6648
6728
  }
6649
6729
  /**
6650
6730
  * Get database file path (for debugging)
@@ -6671,23 +6751,27 @@ var FSSLinkDatabase = class {
6671
6751
  }
6672
6752
  };
6673
6753
  var databaseInstance = null;
6674
- function getFSSLinkDatabase() {
6754
+ async function getFSSLinkDatabase() {
6675
6755
  if (!databaseInstance) {
6676
6756
  databaseInstance = new FSSLinkDatabase();
6757
+ await databaseInstance.initialize();
6677
6758
  }
6678
6759
  return databaseInstance;
6679
6760
  }
6680
6761
 
6681
6762
  // packages/cli/src/config/modelManager.ts
6682
6763
  var ModelManager = class {
6683
- db = getFSSLinkDatabase();
6764
+ async getDb() {
6765
+ return await getFSSLinkDatabase();
6766
+ }
6684
6767
  /**
6685
6768
  * Set up a new model configuration and make it active
6686
6769
  * Implements ModelStateProvider.setActiveModel
6687
6770
  */
6688
6771
  async setActiveModel(config) {
6689
- const modelId = this.db.upsertModelConfig(config);
6690
- this.db.setActiveModel(modelId);
6772
+ const db = await this.getDb();
6773
+ const modelId = await db.upsertModelConfig(config);
6774
+ await db.setActiveModel(modelId);
6691
6775
  this.updateEnvironmentFromModel(config);
6692
6776
  return modelId;
6693
6777
  }
@@ -6695,6 +6779,7 @@ var ModelManager = class {
6695
6779
  * Set up a new model configuration and make it active (legacy method)
6696
6780
  */
6697
6781
  async configureModel(authType, modelName, endpointUrl, apiKey, displayName) {
6782
+ const db = await this.getDb();
6698
6783
  const config = {
6699
6784
  authType: this.mapAuthType(authType),
6700
6785
  modelName,
@@ -6705,8 +6790,8 @@ var ModelManager = class {
6705
6790
  isActive: true
6706
6791
  // Make this the active model
6707
6792
  };
6708
- const modelId = this.db.upsertModelConfig(config);
6709
- this.db.setActiveModel(modelId);
6793
+ const modelId = await db.upsertModelConfig(config);
6794
+ await db.setActiveModel(modelId);
6710
6795
  this.updateEnvironmentFromModel(config);
6711
6796
  return modelId;
6712
6797
  }
@@ -6715,8 +6800,9 @@ var ModelManager = class {
6715
6800
  */
6716
6801
  async switchToModel(modelId) {
6717
6802
  try {
6718
- this.db.setActiveModel(modelId);
6719
- const activeModel = this.db.getActiveModel();
6803
+ const db = await this.getDb();
6804
+ await db.setActiveModel(modelId);
6805
+ const activeModel = await db.getActiveModel();
6720
6806
  if (activeModel) {
6721
6807
  this.updateEnvironmentFromModel(activeModel);
6722
6808
  return true;
@@ -6730,45 +6816,52 @@ var ModelManager = class {
6730
6816
  /**
6731
6817
  * Get the currently active model
6732
6818
  */
6733
- getActiveModel() {
6734
- return this.db.getActiveModel();
6819
+ async getActiveModel() {
6820
+ const db = await this.getDb();
6821
+ return await db.getActiveModel();
6735
6822
  }
6736
6823
  /**
6737
6824
  * Get all configured models
6738
6825
  */
6739
- getAllModels() {
6740
- return this.db.getAllModels();
6826
+ async getAllModels() {
6827
+ const db = await this.getDb();
6828
+ return await db.getAllModels();
6741
6829
  }
6742
6830
  /**
6743
6831
  * Get favorite models
6744
6832
  */
6745
- getFavoriteModels() {
6746
- return this.db.getFavoriteModels();
6833
+ async getFavoriteModels() {
6834
+ const db = await this.getDb();
6835
+ return await db.getFavoriteModels();
6747
6836
  }
6748
6837
  /**
6749
6838
  * Get recently used models
6750
6839
  */
6751
- getRecentModels(limit = 5) {
6752
- return this.db.getRecentModels(limit);
6840
+ async getRecentModels(limit = 5) {
6841
+ const db = await this.getDb();
6842
+ return await db.getRecentModels(limit);
6753
6843
  }
6754
6844
  /**
6755
6845
  * Toggle favorite status for a model
6756
6846
  */
6757
- toggleFavorite(modelId) {
6758
- this.db.toggleModelFavorite(modelId);
6847
+ async toggleFavorite(modelId) {
6848
+ const db = await this.getDb();
6849
+ await db.toggleModelFavorite(modelId);
6759
6850
  }
6760
6851
  /**
6761
6852
  * Delete a model configuration
6762
6853
  */
6763
- deleteModel(modelId) {
6764
- this.db.deleteModel(modelId);
6854
+ async deleteModel(modelId) {
6855
+ const db = await this.getDb();
6856
+ await db.deleteModel(modelId);
6765
6857
  }
6766
6858
  /**
6767
6859
  * Initialize environment variables from active model on startup
6768
6860
  * Implements ModelStateProvider.initializeFromStore
6769
6861
  */
6770
- initializeFromStore() {
6771
- const activeModel = this.db.getActiveModel();
6862
+ async initializeFromStore() {
6863
+ const db = await this.getDb();
6864
+ const activeModel = await db.getActiveModel();
6772
6865
  if (activeModel) {
6773
6866
  this.updateEnvironmentFromModel(activeModel);
6774
6867
  return true;
@@ -6778,26 +6871,29 @@ var ModelManager = class {
6778
6871
  /**
6779
6872
  * Check if we have a valid active model configuration
6780
6873
  */
6781
- hasValidConfiguration() {
6782
- const activeModel = this.db.getActiveModel();
6874
+ async hasValidConfiguration() {
6875
+ const db = await this.getDb();
6876
+ const activeModel = await db.getActiveModel();
6783
6877
  return activeModel !== null;
6784
6878
  }
6785
6879
  /**
6786
6880
  * Get current auth type from active model
6787
6881
  * Implements ModelStateProvider.getCurrentAuthType
6788
6882
  */
6789
- getCurrentAuthType() {
6790
- const activeModel = this.db.getActiveModel();
6791
- if (!activeModel) return void 0;
6883
+ async getCurrentAuthType() {
6884
+ const db = await this.getDb();
6885
+ const activeModel = await db.getActiveModel();
6886
+ if (!activeModel || !activeModel.authType) return void 0;
6792
6887
  const authType = this.mapToFSSLinkAuthType(activeModel.authType);
6793
6888
  return authType;
6794
6889
  }
6795
6890
  /**
6796
6891
  * Get current auth type as FSS Link AuthType enum (legacy method)
6797
6892
  */
6798
- getCurrentFSSAuthType() {
6799
- const activeModel = this.db.getActiveModel();
6800
- if (!activeModel) return void 0;
6893
+ async getCurrentFSSAuthType() {
6894
+ const db = await this.getDb();
6895
+ const activeModel = await db.getActiveModel();
6896
+ if (!activeModel || !activeModel.authType) return void 0;
6801
6897
  return this.mapToFSSLinkAuthType(activeModel.authType);
6802
6898
  }
6803
6899
  /**
@@ -6845,6 +6941,9 @@ var ModelManager = class {
6845
6941
  * Map database auth type to FSS Link AuthType
6846
6942
  */
6847
6943
  mapToFSSLinkAuthType(authType) {
6944
+ if (!authType) {
6945
+ throw new Error(`Auth type is null or undefined`);
6946
+ }
6848
6947
  switch (authType) {
6849
6948
  case "openai":
6850
6949
  return AuthType.USE_OPENAI;
@@ -6870,7 +6969,14 @@ function getModelManager() {
6870
6969
  // packages/cli/src/ui/hooks/useAuthCommand.ts
6871
6970
  var useAuthCommand = (settings, setAuthError, config) => {
6872
6971
  const modelManager = getModelManager();
6873
- const hasActiveModel = modelManager.hasValidConfiguration();
6972
+ const [hasActiveModel, setHasActiveModel] = useState11(false);
6973
+ useEffect12(() => {
6974
+ const checkActiveModel = async () => {
6975
+ const result = await modelManager.hasValidConfiguration();
6976
+ setHasActiveModel(result);
6977
+ };
6978
+ void checkActiveModel();
6979
+ }, [modelManager]);
6874
6980
  const [isAuthDialogOpen, setIsAuthDialogOpen] = useState11(
6875
6981
  !hasActiveModel && settings.merged.selectedAuthType === void 0
6876
6982
  );
@@ -6884,7 +6990,7 @@ var useAuthCommand = (settings, setAuthError, config) => {
6884
6990
  return;
6885
6991
  }
6886
6992
  if (hasActiveModel) {
6887
- const currentAuthType = modelManager.getCurrentAuthType();
6993
+ const currentAuthType = await modelManager.getCurrentAuthType();
6888
6994
  if (currentAuthType) {
6889
6995
  try {
6890
6996
  setIsAuthenticating(true);
@@ -7583,7 +7689,7 @@ async function getPackageJson() {
7583
7689
  // packages/cli/src/utils/version.ts
7584
7690
  async function getCliVersion() {
7585
7691
  const pkgJson = await getPackageJson();
7586
- return "1.0.7";
7692
+ return "1.0.10";
7587
7693
  }
7588
7694
 
7589
7695
  // packages/cli/src/ui/commands/aboutCommand.ts
@@ -7635,7 +7741,7 @@ import open from "open";
7635
7741
  import process6 from "node:process";
7636
7742
 
7637
7743
  // packages/cli/src/generated/git-commit.ts
7638
- var GIT_COMMIT_INFO = "a6af513";
7744
+ var GIT_COMMIT_INFO = "3a11de7";
7639
7745
 
7640
7746
  // packages/cli/src/ui/commands/bugCommand.ts
7641
7747
  import { sessionId as sessionId3 } from "@fsscoding/fss-link-core";
@@ -18354,16 +18460,19 @@ function SearchEngineConfigDialog({
18354
18460
  const [currentField, setCurrentField] = useState33("braveApiKey");
18355
18461
  const [isLoading, setIsLoading] = useState33(true);
18356
18462
  useEffect32(() => {
18357
- const db = getFSSLinkDatabase();
18358
- const existingBrave = db.getUserPreference("webscraper.brave_api_key");
18359
- const existingTavily = db.getUserPreference("webscraper.tavily_api_key");
18360
- if (existingBrave) {
18361
- setBraveApiKey(existingBrave);
18362
- }
18363
- if (existingTavily) {
18364
- setTavilyApiKey(existingTavily);
18365
- }
18366
- setIsLoading(false);
18463
+ const loadConfig = async () => {
18464
+ const db = await getFSSLinkDatabase();
18465
+ const existingBrave = await db.getUserPreference("webscraper.brave_api_key");
18466
+ const existingTavily = await db.getUserPreference("webscraper.tavily_api_key");
18467
+ if (existingBrave) {
18468
+ setBraveApiKey(existingBrave);
18469
+ }
18470
+ if (existingTavily) {
18471
+ setTavilyApiKey(existingTavily);
18472
+ }
18473
+ setIsLoading(false);
18474
+ };
18475
+ loadConfig().catch(console.error);
18367
18476
  }, []);
18368
18477
  useInput4((input, key) => {
18369
18478
  if (isLoading) return;
@@ -18390,15 +18499,18 @@ function SearchEngineConfigDialog({
18390
18499
  setCurrentField("braveApiKey");
18391
18500
  return;
18392
18501
  }
18393
- const db = getFSSLinkDatabase();
18394
- if (braveApiKey.trim()) {
18395
- db.setUserPreference("webscraper.brave_api_key", braveApiKey.trim());
18396
- process.env["BRAVE_SEARCH_API_KEY"] = braveApiKey.trim();
18397
- }
18398
- if (tavilyApiKey.trim()) {
18399
- db.setUserPreference("webscraper.tavily_api_key", tavilyApiKey.trim());
18400
- process.env["TAVILY_API_KEY"] = tavilyApiKey.trim();
18401
- }
18502
+ const saveConfig = async () => {
18503
+ const db = await getFSSLinkDatabase();
18504
+ if (braveApiKey.trim()) {
18505
+ await db.setUserPreference("webscraper.brave_api_key", braveApiKey.trim());
18506
+ process.env["BRAVE_SEARCH_API_KEY"] = braveApiKey.trim();
18507
+ }
18508
+ if (tavilyApiKey.trim()) {
18509
+ await db.setUserPreference("webscraper.tavily_api_key", tavilyApiKey.trim());
18510
+ process.env["TAVILY_API_KEY"] = tavilyApiKey.trim();
18511
+ }
18512
+ };
18513
+ saveConfig().catch(console.error);
18402
18514
  onSubmit({
18403
18515
  braveApiKey: braveApiKey.trim() || void 0,
18404
18516
  braveEnabled: !!braveApiKey.trim(),
@@ -23024,10 +23136,10 @@ var SearchEngineConfigProvider = class _SearchEngineConfigProvider {
23024
23136
  /**
23025
23137
  * Load search engine configuration from database and set environment variables
23026
23138
  */
23027
- loadConfiguration() {
23028
- const db = getFSSLinkDatabase();
23029
- const braveApiKey = db.getUserPreference("webscraper.brave_api_key");
23030
- const tavilyApiKey = db.getUserPreference("webscraper.tavily_api_key");
23139
+ async loadConfiguration() {
23140
+ const db = await getFSSLinkDatabase();
23141
+ const braveApiKey = await db.getUserPreference("webscraper.brave_api_key");
23142
+ const tavilyApiKey = await db.getUserPreference("webscraper.tavily_api_key");
23031
23143
  if (braveApiKey) {
23032
23144
  process.env["BRAVE_SEARCH_API_KEY"] = braveApiKey;
23033
23145
  }
@@ -23042,31 +23154,31 @@ var SearchEngineConfigProvider = class _SearchEngineConfigProvider {
23042
23154
  /**
23043
23155
  * Save search engine configuration to database
23044
23156
  */
23045
- saveConfiguration(config) {
23046
- const db = getFSSLinkDatabase();
23157
+ async saveConfiguration(config) {
23158
+ const db = await getFSSLinkDatabase();
23047
23159
  if (config.braveApiKey) {
23048
- db.setUserPreference("webscraper.brave_api_key", config.braveApiKey);
23049
- db.setUserPreference("webscraper.brave_enabled", "true");
23160
+ await db.setUserPreference("webscraper.brave_api_key", config.braveApiKey);
23161
+ await db.setUserPreference("webscraper.brave_enabled", "true");
23050
23162
  process.env["BRAVE_SEARCH_API_KEY"] = config.braveApiKey;
23051
23163
  }
23052
23164
  if (config.tavilyApiKey) {
23053
- db.setUserPreference("webscraper.tavily_api_key", config.tavilyApiKey);
23054
- db.setUserPreference("webscraper.tavily_enabled", "true");
23165
+ await db.setUserPreference("webscraper.tavily_api_key", config.tavilyApiKey);
23166
+ await db.setUserPreference("webscraper.tavily_enabled", "true");
23055
23167
  process.env["TAVILY_API_KEY"] = config.tavilyApiKey;
23056
23168
  }
23057
23169
  }
23058
23170
  /**
23059
23171
  * Check if search engines are configured
23060
23172
  */
23061
- hasConfiguration() {
23062
- const config = this.loadConfiguration();
23173
+ async hasConfiguration() {
23174
+ const config = await this.loadConfiguration();
23063
23175
  return !!(config.braveApiKey || config.tavilyApiKey);
23064
23176
  }
23065
23177
  /**
23066
23178
  * Get configuration status for display
23067
23179
  */
23068
- getConfigurationStatus() {
23069
- const config = this.loadConfiguration();
23180
+ async getConfigurationStatus() {
23181
+ const config = await this.loadConfiguration();
23070
23182
  let status = "\u{1F50D} Search Engine Configuration:\n";
23071
23183
  if (config.braveApiKey) {
23072
23184
  status += `\u2705 Brave Search: Configured
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fss-link",
3
- "version": "1.0.7",
3
+ "version": "1.0.10",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },
@@ -89,18 +89,53 @@
89
89
  "tsx": "^4.20.3",
90
90
  "typescript-eslint": "^8.30.1",
91
91
  "vitest": "^3.2.4",
92
- "yargs": "^17.7.2"
92
+ "yargs": "^17.7.2",
93
+ "@fsscoding/fss-link-core": "1.0.1",
94
+ "@google/genai": "1.9.0",
95
+ "@iarna/toml": "^2.2.5",
96
+ "@modelcontextprotocol/sdk": "^1.15.1",
97
+ "@types/sql.js": "^1.4.9",
98
+ "@types/fs-extra": "^11.0.4",
99
+ "@types/update-notifier": "^6.0.8",
100
+ "axios": "^1.11.0",
101
+ "cheerio": "^1.1.2",
102
+ "command-exists": "^1.2.9",
103
+ "diff": "^7.0.0",
104
+ "dotenv": "^17.1.0",
105
+ "fs-extra": "^11.3.1",
106
+ "highlight.js": "^11.11.1",
107
+ "ink": "^6.1.1",
108
+ "ink-big-text": "^2.0.0",
109
+ "ink-gradient": "^3.0.0",
110
+ "ink-link": "^4.1.0",
111
+ "ink-select-input": "^6.2.0",
112
+ "ink-spinner": "^5.0.0",
113
+ "lowlight": "^3.3.0",
114
+ "mime-types": "^3.0.1",
115
+ "node-fetch": "^3.3.2",
116
+ "open": "^10.1.2",
117
+ "p-limit": "^7.1.1",
118
+ "qrcode-terminal": "^0.12.0",
119
+ "react": "^19.1.0",
120
+ "read-package-up": "^11.0.0",
121
+ "shell-quote": "^1.8.3",
122
+ "string-width": "^7.1.0",
123
+ "strip-ansi": "^7.1.0",
124
+ "strip-json-comments": "^3.1.1",
125
+ "undici": "^7.10.0",
126
+ "update-notifier": "^7.3.1",
127
+ "zod": "^3.23.8"
93
128
  },
94
129
  "dependencies": {
95
130
  "@fsscoding/fss-link-core": "1.0.1",
96
131
  "@google/genai": "1.9.0",
97
132
  "@iarna/toml": "^2.2.5",
98
133
  "@modelcontextprotocol/sdk": "^1.15.1",
99
- "@types/better-sqlite3": "^7.6.13",
134
+ "@types/sql.js": "^1.4.9",
100
135
  "@types/fs-extra": "^11.0.4",
101
136
  "@types/update-notifier": "^6.0.8",
102
137
  "axios": "^1.11.0",
103
- "better-sqlite3": "^12.2.0",
138
+ "sql.js": "^1.11.0",
104
139
  "cheerio": "^1.1.2",
105
140
  "command-exists": "^1.2.9",
106
141
  "diff": "^7.0.0",
@@ -129,7 +164,8 @@
129
164
  "undici": "^7.10.0",
130
165
  "update-notifier": "^7.3.1",
131
166
  "yargs": "^17.7.2",
132
- "zod": "^3.23.8"
167
+ "zod": "^3.23.8",
168
+ "better-sqlite3": "^12.2.0"
133
169
  },
134
170
  "optionalDependencies": {
135
171
  "@lydell/node-pty": "1.1.0",