pplx-zero 1.1.6 → 1.1.8

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 (3) hide show
  1. package/README.md +401 -259
  2. package/dist/index.js +283 -175
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1883,7 +1883,7 @@ __export(exports_version, {
1883
1883
  getDescription: () => getDescription,
1884
1884
  getAuthor: () => getAuthor,
1885
1885
  formatVersionInfo: () => formatVersionInfo,
1886
- compareVersions: () => compareVersions
1886
+ compareVersions: () => compareVersions2
1887
1887
  });
1888
1888
  import { readFile as readFile2 } from "node:fs/promises";
1889
1889
  import { join as join6, dirname as dirname3 } from "node:path";
@@ -1972,7 +1972,7 @@ async function formatVersionInfo(verbose = false) {
1972
1972
  }
1973
1973
  return `${versionInfo.name} v${versionInfo.version}`;
1974
1974
  }
1975
- function compareVersions(version1, version2) {
1975
+ function compareVersions2(version1, version2) {
1976
1976
  const v1Parts = version1.split(".").map(Number);
1977
1977
  const v2Parts = version2.split(".").map(Number);
1978
1978
  const maxLength = Math.max(v1Parts.length, v2Parts.length);
@@ -1987,7 +1987,7 @@ function compareVersions(version1, version2) {
1987
1987
  return 0;
1988
1988
  }
1989
1989
  function isNewerVersion(current, latest) {
1990
- return compareVersions(latest, current) > 0;
1990
+ return compareVersions2(latest, current) > 0;
1991
1991
  }
1992
1992
  function parseVersion(version) {
1993
1993
  const mainVersion = version.split("-")[0];
@@ -2008,7 +2008,7 @@ function isValidVersion(version) {
2008
2008
  const semverRegex = /^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.-]+))?(?:\+([a-zA-Z0-9.-]+))?$/;
2009
2009
  return semverRegex.test(version);
2010
2010
  }
2011
- var __filename2, __dirname2, FALLBACK_VERSION = "1.1.4", FALLBACK_PACKAGE_INFO, packageJsonCache = null;
2011
+ var __filename2, __dirname2, FALLBACK_VERSION = "1.1.8", FALLBACK_PACKAGE_INFO, packageJsonCache = null;
2012
2012
  var init_version = __esm(() => {
2013
2013
  __filename2 = fileURLToPath(import.meta.url);
2014
2014
  __dirname2 = dirname3(__filename2);
@@ -7857,7 +7857,7 @@ ${textContent}`
7857
7857
  async executeAdvancedModel(query, options = {}) {
7858
7858
  const startTime = performance.now();
7859
7859
  try {
7860
- const { model, attachments, webhook } = options;
7860
+ const { model, attachments, webhook, timeout } = options;
7861
7861
  if (model === "sonar-pro" || model === "sonar-deep-research" || model === "sonar-reasoning") {
7862
7862
  let messages = [];
7863
7863
  if (attachments && attachments.length > 0) {
@@ -7902,12 +7902,13 @@ ${textContent}`
7902
7902
  { role: "user", content: query }
7903
7903
  ];
7904
7904
  }
7905
+ const effectiveTimeout = model === "sonar-deep-research" ? Math.max(timeout || 300000, 300000) : timeout || this.config.timeout;
7905
7906
  const response = await this.executeWithTimeout(this.client.chat.completions.create({
7906
7907
  model,
7907
7908
  messages,
7908
7909
  max_tokens: options.maxTokens || 4000,
7909
7910
  temperature: options.temperature || 0.1
7910
- }), this.config.timeout);
7911
+ }), effectiveTimeout);
7911
7912
  let content = "";
7912
7913
  if (response && response.choices && response.choices.length > 0) {
7913
7914
  const choice = response.choices[0];
@@ -9118,149 +9119,156 @@ class CliFormatter {
9118
9119
  import { promises as fs3 } from "node:fs";
9119
9120
  import { join as join3 } from "node:path";
9120
9121
  import { homedir as homedir3 } from "node:os";
9121
-
9122
- class AutoUpdateService {
9123
- static UPDATE_CACHE_FILE = join3(homedir3(), ".pplx-zero", "update-cache.json");
9124
- static DEFAULT_CONFIG = {
9125
- enabled: true,
9126
- checkInterval: 1440,
9127
- autoInstall: false,
9128
- quietMode: true
9129
- };
9130
- config;
9131
- updateCache = null;
9132
- constructor(config = {}) {
9133
- this.config = { ...AutoUpdateService.DEFAULT_CONFIG, ...config };
9134
- }
9135
- async checkForUpdates() {
9136
- if (!this.config.enabled) {
9137
- return null;
9138
- }
9139
- try {
9140
- await this.loadUpdateCache();
9141
- const now = new Date;
9142
- const timeSinceLastCheck = this.updateCache?.lastChecked ? now.getTime() - this.updateCache.lastChecked.getTime() : Infinity;
9143
- const checkIntervalMs = this.config.checkInterval * 60 * 1000;
9144
- if (this.updateCache && timeSinceLastCheck < checkIntervalMs) {
9145
- return this.updateCache;
9146
- }
9147
- const updateInfo = await this.fetchUpdateInfo();
9148
- await this.saveUpdateCache(updateInfo);
9149
- if (this.config.autoInstall && updateInfo.updateAvailable) {
9150
- this.performAutoUpdate(updateInfo).catch((error) => {
9151
- if (!this.config.quietMode) {
9152
- console.error("Auto-update failed:", error);
9153
- }
9154
- });
9155
- }
9156
- return updateInfo;
9157
- } catch (error) {
9158
- if (!this.config.quietMode) {
9159
- console.error("Update check failed:", error);
9160
- }
9161
- return null;
9162
- }
9163
- }
9164
- async fetchUpdateInfo() {
9165
- const currentVersion = await this.getCurrentVersion();
9166
- try {
9167
- const npmResponse = await fetch("https://registry.npmjs.org/pplx-zero");
9168
- const npmData = await npmResponse.json();
9169
- const latestVersion = npmData["dist-tags"]?.latest || currentVersion;
9170
- const updateAvailable = this.compareVersions(latestVersion, currentVersion) > 0;
9171
- return {
9172
- currentVersion,
9173
- latestVersion,
9174
- updateAvailable,
9175
- lastChecked: new Date,
9176
- updateUrl: npmData.versions?.[latestVersion]?.dist?.tarball,
9177
- releaseNotes: npmData.versions?.[latestVersion]?.description
9178
- };
9179
- } catch (error) {
9180
- return {
9181
- currentVersion,
9182
- latestVersion: currentVersion,
9183
- updateAvailable: false,
9184
- lastChecked: new Date
9185
- };
9186
- }
9122
+ var UPDATE_CACHE_FILE = join3(homedir3(), ".pplx-zero", "update-cache.json");
9123
+ var CONFIG_FILE = join3(homedir3(), ".pplx-zero", "config.json");
9124
+ var DEFAULT_CONFIG = {
9125
+ enabled: true,
9126
+ checkInterval: 1440,
9127
+ autoInstall: false,
9128
+ quietMode: true
9129
+ };
9130
+ async function loadAutoUpdateConfig() {
9131
+ try {
9132
+ const configContent = await fs3.readFile(CONFIG_FILE, "utf-8");
9133
+ const config = JSON.parse(configContent);
9134
+ return { ...DEFAULT_CONFIG, ...config.autoUpdate };
9135
+ } catch {
9136
+ return DEFAULT_CONFIG;
9187
9137
  }
9188
- async getCurrentVersion() {
9189
- try {
9190
- const packageJsonPath = join3(process.cwd(), "package.json");
9191
- const packageJson = JSON.parse(await fs3.readFile(packageJsonPath, "utf-8"));
9192
- return packageJson.version || "1.1.4";
9193
- } catch {
9194
- return "1.1.4";
9138
+ }
9139
+ async function saveAutoUpdateConfig(config) {
9140
+ try {
9141
+ const configDir = join3(homedir3(), ".pplx-zero");
9142
+ await fs3.mkdir(configDir, { recursive: true });
9143
+ const existingConfig = await loadAutoUpdateConfig();
9144
+ const updatedConfig = { ...existingConfig, ...config };
9145
+ await fs3.writeFile(CONFIG_FILE, JSON.stringify({ autoUpdate: updatedConfig }, null, 2), "utf-8");
9146
+ } catch (error) {
9147
+ if (process.env.PPLX_DEBUG) {
9148
+ console.error("Failed to save auto-update config:", error);
9195
9149
  }
9196
9150
  }
9197
- compareVersions(version1, version2) {
9198
- const v1Parts = version1.split(".").map(Number);
9199
- const v2Parts = version2.split(".").map(Number);
9200
- const maxLength = Math.max(v1Parts.length, v2Parts.length);
9201
- for (let i = 0;i < maxLength; i++) {
9202
- const v1Part = v1Parts[i] || 0;
9203
- const v2Part = v2Parts[i] || 0;
9204
- if (v1Part > v2Part)
9205
- return 1;
9206
- if (v1Part < v2Part)
9207
- return -1;
9151
+ }
9152
+ async function checkForUpdatesCached() {
9153
+ try {
9154
+ const config = await loadAutoUpdateConfig();
9155
+ if (!config.enabled) {
9156
+ return null;
9208
9157
  }
9209
- return 0;
9210
- }
9211
- async loadUpdateCache() {
9158
+ let updateCache = null;
9212
9159
  try {
9213
- const cacheData = await fs3.readFile(AutoUpdateService.UPDATE_CACHE_FILE, "utf-8");
9214
- this.updateCache = JSON.parse(cacheData);
9160
+ const cacheData = await fs3.readFile(UPDATE_CACHE_FILE, "utf-8");
9161
+ updateCache = JSON.parse(cacheData);
9215
9162
  } catch {
9216
- this.updateCache = null;
9163
+ updateCache = null;
9217
9164
  }
9218
- }
9219
- async saveUpdateCache(updateInfo) {
9220
- try {
9221
- await fs3.mkdir(join3(homedir3(), ".pplx-zero"), { recursive: true });
9222
- await fs3.writeFile(AutoUpdateService.UPDATE_CACHE_FILE, JSON.stringify(updateInfo, null, 2), "utf-8");
9223
- this.updateCache = updateInfo;
9224
- } catch (error) {
9225
- if (!this.config.quietMode) {
9226
- console.error("Failed to save update cache:", error);
9227
- }
9165
+ const now = new Date;
9166
+ const timeSinceLastCheck = updateCache?.lastChecked ? now.getTime() - new Date(updateCache.lastChecked).getTime() : Infinity;
9167
+ const checkIntervalMs = config.checkInterval * 60 * 1000;
9168
+ if (updateCache && timeSinceLastCheck < checkIntervalMs) {
9169
+ return updateCache;
9170
+ }
9171
+ const updateInfo = await fetchUpdateInfo();
9172
+ await saveUpdateCache(updateInfo);
9173
+ return updateInfo;
9174
+ } catch (error) {
9175
+ if (process.env.PPLX_DEBUG) {
9176
+ console.error("Update check failed:", error);
9228
9177
  }
9178
+ return null;
9229
9179
  }
9230
- async performAutoUpdate(updateInfo) {
9231
- if (!updateInfo.updateAvailable || !updateInfo.updateUrl) {
9232
- return;
9233
- }
9234
- try {
9235
- if (!this.config.quietMode) {
9236
- console.log(`\uD83D\uDD04 Update available: ${updateInfo.currentVersion} → ${updateInfo.latestVersion}`);
9237
- console.log(`\uD83D\uDCA1 Run 'pplx update --auto' to install`);
9238
- }
9239
- } catch (error) {
9240
- if (!this.config.quietMode) {
9241
- console.error("Auto-update failed:", error);
9242
- }
9243
- }
9180
+ }
9181
+ async function forceUpdateCheck() {
9182
+ try {
9183
+ await fs3.unlink(UPDATE_CACHE_FILE);
9184
+ } catch {}
9185
+ return fetchUpdateInfo();
9186
+ }
9187
+ async function toggleAutoUpdate(enabled, autoInstall = false) {
9188
+ const config = await loadAutoUpdateConfig();
9189
+ const updatedConfig = {
9190
+ ...config,
9191
+ enabled,
9192
+ autoInstall
9193
+ };
9194
+ await saveAutoUpdateConfig(updatedConfig);
9195
+ }
9196
+ async function getAutoUpdateStatus() {
9197
+ const config = await loadAutoUpdateConfig();
9198
+ let updateCache = null;
9199
+ try {
9200
+ const cacheData = await fs3.readFile(UPDATE_CACHE_FILE, "utf-8");
9201
+ updateCache = JSON.parse(cacheData);
9202
+ } catch {
9203
+ updateCache = null;
9244
9204
  }
9245
- async getUpdateStatus() {
9246
- await this.loadUpdateCache();
9205
+ return {
9206
+ enabled: config.enabled,
9207
+ autoInstall: config.autoInstall,
9208
+ lastChecked: updateCache?.lastChecked ? new Date(updateCache.lastChecked) : undefined,
9209
+ updateAvailable: updateCache?.updateAvailable,
9210
+ currentVersion: updateCache?.currentVersion,
9211
+ latestVersion: updateCache?.latestVersion
9212
+ };
9213
+ }
9214
+ async function fetchUpdateInfo() {
9215
+ const currentVersion = await getCurrentVersion();
9216
+ try {
9217
+ const npmResponse = await fetch("https://registry.npmjs.org/pplx-zero");
9218
+ const npmData = await npmResponse.json();
9219
+ const latestVersion = npmData["dist-tags"]?.latest || currentVersion;
9220
+ const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;
9247
9221
  return {
9248
- enabled: this.config.enabled,
9249
- lastChecked: this.updateCache?.lastChecked,
9250
- updateAvailable: this.updateCache?.updateAvailable,
9251
- currentVersion: this.updateCache?.currentVersion,
9252
- latestVersion: this.updateCache?.latestVersion
9222
+ currentVersion,
9223
+ latestVersion,
9224
+ updateAvailable,
9225
+ lastChecked: new Date,
9226
+ updateUrl: npmData.versions?.[latestVersion]?.dist?.tarball,
9227
+ releaseNotes: npmData.versions?.[latestVersion]?.description
9228
+ };
9229
+ } catch (error) {
9230
+ return {
9231
+ currentVersion,
9232
+ latestVersion: currentVersion,
9233
+ updateAvailable: false,
9234
+ lastChecked: new Date
9253
9235
  };
9254
9236
  }
9255
- async forceUpdateCheck() {
9256
- this.updateCache = null;
9257
- try {
9258
- await fs3.unlink(AutoUpdateService.UPDATE_CACHE_FILE);
9259
- } catch {}
9260
- return this.checkForUpdates();
9237
+ }
9238
+ async function getCurrentVersion() {
9239
+ try {
9240
+ const packageJsonPath = join3(process.cwd(), "package.json");
9241
+ const packageJson = JSON.parse(await fs3.readFile(packageJsonPath, "utf-8"));
9242
+ return packageJson.version || "1.1.8";
9243
+ } catch {
9244
+ return "1.1.8";
9245
+ }
9246
+ }
9247
+ function compareVersions(version1, version2) {
9248
+ const v1Parts = version1.split(".").map(Number);
9249
+ const v2Parts = version2.split(".").map(Number);
9250
+ const maxLength = Math.max(v1Parts.length, v2Parts.length);
9251
+ for (let i = 0;i < maxLength; i++) {
9252
+ const v1Part = v1Parts[i] || 0;
9253
+ const v2Part = v2Parts[i] || 0;
9254
+ if (v1Part > v2Part)
9255
+ return 1;
9256
+ if (v1Part < v2Part)
9257
+ return -1;
9258
+ }
9259
+ return 0;
9260
+ }
9261
+ async function saveUpdateCache(updateInfo) {
9262
+ try {
9263
+ const configDir = join3(homedir3(), ".pplx-zero");
9264
+ await fs3.mkdir(configDir, { recursive: true });
9265
+ await fs3.writeFile(UPDATE_CACHE_FILE, JSON.stringify(updateInfo, null, 2), "utf-8");
9266
+ } catch (error) {
9267
+ if (process.env.PPLX_DEBUG) {
9268
+ console.error("Failed to save update cache:", error);
9269
+ }
9261
9270
  }
9262
9271
  }
9263
- var service_default = AutoUpdateService;
9264
9272
 
9265
9273
  // src/cli/commands/search.ts
9266
9274
  function parseNumber(value, defaultValue, min, max, name) {
@@ -9318,7 +9326,13 @@ async function parseQueries(options) {
9318
9326
  metadata = { lineCount };
9319
9327
  } else if (options.input) {
9320
9328
  source = "file";
9321
- const fileContent = await Bun.file(options.input).text();
9329
+ let fileContent;
9330
+ if (typeof Bun !== "undefined") {
9331
+ fileContent = await Bun.file(options.input).text();
9332
+ } else {
9333
+ const fs4 = await import("node:fs");
9334
+ fileContent = await fs4.promises.readFile(options.input, "utf-8");
9335
+ }
9322
9336
  const parsed = JSON.parse(fileContent);
9323
9337
  if (parsed.queries && Array.isArray(parsed.queries)) {
9324
9338
  queries.push(...parsed.queries);
@@ -9351,7 +9365,8 @@ async function executeSearch(query, options, filePaths = []) {
9351
9365
  response = await engine.executeAdvancedModel(query, {
9352
9366
  model: options.model,
9353
9367
  attachments,
9354
- webhook: options.webhook
9368
+ webhook: options.webhook,
9369
+ timeout: options.timeout
9355
9370
  });
9356
9371
  result = {
9357
9372
  success: true,
@@ -9563,13 +9578,7 @@ async function logToHistory(queries, results, metadata, exportPath) {
9563
9578
  async function handleSearchCommand(options) {
9564
9579
  const startTime = Date.now();
9565
9580
  const sessionId = randomUUID3();
9566
- const autoUpdateService = new service_default({
9567
- enabled: true,
9568
- checkInterval: 1440,
9569
- autoInstall: false,
9570
- quietMode: true
9571
- });
9572
- autoUpdateService.checkForUpdates().catch((error) => {
9581
+ checkForUpdatesCached().catch((error) => {
9573
9582
  if (process.env.PPLX_DEBUG) {
9574
9583
  console.error("Background update check failed:", error);
9575
9584
  }
@@ -9598,14 +9607,58 @@ async function handleSearchCommand(options) {
9598
9607
  positionals: options.positionals
9599
9608
  });
9600
9609
  const filePaths = [];
9601
- if (options.file)
9610
+ const filesToValidate = [];
9611
+ if (options.file) {
9602
9612
  filePaths.push(options.file);
9603
- if (options.image)
9613
+ filesToValidate.push(options.file);
9614
+ }
9615
+ if (options.image) {
9604
9616
  filePaths.push(options.image);
9605
- if (options.attach)
9617
+ filesToValidate.push(options.image);
9618
+ }
9619
+ if (options.attach) {
9606
9620
  filePaths.push(...options.attach);
9607
- if (options.attachImage)
9621
+ filesToValidate.push(...options.attach);
9622
+ }
9623
+ if (options.attachImage) {
9608
9624
  filePaths.push(...options.attachImage);
9625
+ filesToValidate.push(...options.attachImage);
9626
+ }
9627
+ if (filesToValidate.length > 0) {
9628
+ const missingFiles = [];
9629
+ for (const filePath of filesToValidate) {
9630
+ try {
9631
+ if (typeof Bun !== "undefined") {
9632
+ const file = Bun.file(filePath);
9633
+ if (!await file.exists()) {
9634
+ missingFiles.push(filePath);
9635
+ } else if (file.size === 0) {
9636
+ throw new Error(`File is empty: ${filePath}`);
9637
+ }
9638
+ } else {
9639
+ const fs4 = await import("node:fs");
9640
+ const stats = await fs4.promises.stat(filePath);
9641
+ if (!stats.isFile()) {
9642
+ missingFiles.push(filePath);
9643
+ } else if (stats.size === 0) {
9644
+ throw new Error(`File is empty: ${filePath}`);
9645
+ }
9646
+ }
9647
+ } catch (error) {
9648
+ if (error instanceof Error && error.message.includes("File is empty")) {
9649
+ throw error;
9650
+ }
9651
+ missingFiles.push(filePath);
9652
+ }
9653
+ }
9654
+ if (missingFiles.length > 0) {
9655
+ const fileList = missingFiles.length === 1 ? `File "${missingFiles[0]}" does not exist or is not readable` : `Files do not exist or are not readable:
9656
+ ${missingFiles.map((f) => ` - ${f}`).join(`
9657
+ `)}`;
9658
+ throw new Error(`${fileList}
9659
+ Please check the file paths and try again.`);
9660
+ }
9661
+ }
9609
9662
  const searchOptions = {
9610
9663
  maxResults,
9611
9664
  concurrency,
@@ -9877,7 +9930,9 @@ import { join as join5 } from "node:path";
9877
9930
  import { homedir as homedir4 } from "node:os";
9878
9931
  async function handleUpdateCommand(options) {
9879
9932
  try {
9880
- if (options.check) {
9933
+ if (options.check && options.auto) {
9934
+ return await handleToggleAutoUpdate();
9935
+ } else if (options.check) {
9881
9936
  return await handleUpdateCheck(options.silent);
9882
9937
  } else if (options.auto) {
9883
9938
  return await handleAutoUpdate();
@@ -9895,14 +9950,8 @@ async function handleUpdateCommand(options) {
9895
9950
  }
9896
9951
  }
9897
9952
  async function handleUpdateCheck(silent = false) {
9898
- const autoUpdateService = new service_default({
9899
- enabled: true,
9900
- checkInterval: 0,
9901
- autoInstall: false,
9902
- quietMode: silent
9903
- });
9904
9953
  try {
9905
- const updateInfo = await autoUpdateService.forceUpdateCheck();
9954
+ const updateInfo = await forceUpdateCheck();
9906
9955
  if (!updateInfo) {
9907
9956
  const errorMessage = "Update check failed";
9908
9957
  if (!silent) {
@@ -9921,7 +9970,16 @@ async function handleUpdateCheck(silent = false) {
9921
9970
  if (updateInfo.updateAvailable && !silent) {
9922
9971
  const updateMessage = CliFormatter.formatUpdateNotification(updateInfo.currentVersion, updateInfo.latestVersion);
9923
9972
  console.log(CliFormatter.supportsColors() ? updateMessage : CliFormatter.formatPlainText(updateMessage));
9924
- console.log('\uD83D\uDCA1 Run "pplx update --auto" to install automatically');
9973
+ const status = await getAutoUpdateStatus();
9974
+ if (status.enabled) {
9975
+ console.log("\uD83D\uDCA1 Auto-updates are enabled");
9976
+ if (status.autoInstall) {
9977
+ console.log("\uD83D\uDD04 Auto-install is enabled - updates will install automatically");
9978
+ }
9979
+ } else {
9980
+ console.log('\uD83D\uDCA1 Run "pplx update --auto --check" to enable auto-updates');
9981
+ console.log(' or run "pplx update --auto" to install manually');
9982
+ }
9925
9983
  }
9926
9984
  return {
9927
9985
  exitCode: 0,
@@ -9958,13 +10016,7 @@ async function handleAutoUpdate() {
9958
10016
  } catch {}
9959
10017
  await writeFile(updateLockFile, currentPid.toString());
9960
10018
  try {
9961
- const autoUpdateService = new service_default({
9962
- enabled: true,
9963
- checkInterval: 0,
9964
- autoInstall: false,
9965
- quietMode: false
9966
- });
9967
- const updateInfo = await autoUpdateService.forceUpdateCheck();
10019
+ const updateInfo = await forceUpdateCheck();
9968
10020
  if (!updateInfo || !updateInfo.updateAvailable) {
9969
10021
  console.log("ℹ️ No updates available. You are running the latest version.");
9970
10022
  return {
@@ -10051,17 +10103,36 @@ async function executeCommand(command, args) {
10051
10103
  });
10052
10104
  });
10053
10105
  }
10054
- function validateUpdateOptions(options) {
10055
- if (!options.check && !options.auto) {
10106
+ async function handleToggleAutoUpdate() {
10107
+ try {
10108
+ const status = await getAutoUpdateStatus();
10109
+ if (status.enabled) {
10110
+ await toggleAutoUpdate(false);
10111
+ return {
10112
+ exitCode: 0,
10113
+ output: "Auto-updates disabled"
10114
+ };
10115
+ } else {
10116
+ await toggleAutoUpdate(true, false);
10117
+ return {
10118
+ exitCode: 0,
10119
+ output: "Auto-updates enabled"
10120
+ };
10121
+ }
10122
+ } catch (error) {
10123
+ const errorMessage = error instanceof Error ? error.message : String(error);
10124
+ console.error(`❌ Failed to toggle auto-update: ${errorMessage}`);
10056
10125
  return {
10057
- valid: false,
10058
- error: "Either --check or --auto must be specified for update command"
10126
+ exitCode: 1,
10127
+ error: errorMessage
10059
10128
  };
10060
10129
  }
10061
- if (options.check && options.auto) {
10130
+ }
10131
+ function validateUpdateOptions(options) {
10132
+ if (!options.check && !options.auto) {
10062
10133
  return {
10063
10134
  valid: false,
10064
- error: "Cannot specify both --check and --auto options"
10135
+ error: "Either --check or --auto must be specified for update command"
10065
10136
  };
10066
10137
  }
10067
10138
  return { valid: true };
@@ -10085,7 +10156,7 @@ class UpdateChecker {
10085
10156
  return await getVersion2();
10086
10157
  } catch (error) {
10087
10158
  console.error("Failed to read current version:", error);
10088
- return "1.1.4";
10159
+ return "1.1.8";
10089
10160
  }
10090
10161
  }
10091
10162
  async getLatestVersion() {
@@ -10217,7 +10288,7 @@ async function handleVersionCommand(options) {
10217
10288
  }
10218
10289
  } catch (error) {
10219
10290
  const errorMessage = error instanceof Error ? error.message : String(error);
10220
- const fallbackVersion = "pplx-zero v1.1.4";
10291
+ const fallbackVersion = "pplx-zero v1.1.8";
10221
10292
  console.log(fallbackVersion);
10222
10293
  if (!errorMessage.includes("ENOENT") && !errorMessage.includes("package.json")) {
10223
10294
  const formattedError = CliFormatter.formatError(`Warning: ${errorMessage}`);
@@ -10280,8 +10351,8 @@ function validateVersionOptions(options) {
10280
10351
 
10281
10352
  // src/cli/index.ts
10282
10353
  var program2 = new Command;
10283
- program2.name("pplx").description("Fast Perplexity AI search CLI with multi-search, history, and export").version("1.1.4", "-v, --version", "Show version information").helpOption("-h, --help", "Show this help message");
10284
- program2.option("-m, --model <model>", "AI model: sonar, sonar-pro, sonar-reasoning, sonar-deep-research").option("-n, --max-results <n>", "Maximum results per query (default: 5, range: 1-20)", "5").option("-c, --concurrency <n>", "Concurrency for batch searches (default: 5, range: 1-20)", "5").option("-t, --timeout <ms>", "Request timeout in milliseconds (default: 30000, range: 1000-300000)", "30000").option("-f, --file <file>", "Attach document for analysis").option("-i, --image <file>", "Attach image for analysis").option("-o, --format <format>", "Output format: json|jsonl (default: json)", "json").option("-q, --query <query>", "Search query (alternative to positional queries)").option("--export <filename>", "Export results to file").option("-I, --input <file>", "Read queries from JSON file").option("-s, --stdin", "Read queries from stdin (JSON format)").option("--attach <files...>", "Additional file attachments (multiple allowed)").option("--attach-image <files...>", "Additional image attachments (multiple allowed)").option("--async", "Enable async mode for advanced models").option("--webhook <url>", "Webhook URL for async results").option("--workspace <path>", "Workspace directory for file operations").option("--use-search-api", "Use search API (default: true)", true).option("--batch-size <n>", "Batch size for processing (default: 20, range: 1-100)", "20").allowExcessArguments(true).argument("[queries...]", "Search queries (multiple queries enable multi-search)");
10354
+ program2.name("pplx").description("Fast Perplexity AI search CLI with multi-search, history, and export").version("1.1.8", "-v, --version", "Show version information").helpOption("-h, --help", "Show this help message");
10355
+ program2.option("-m, --model <model>", "AI model: sonar, sonar-pro, sonar-reasoning, sonar-deep-research").option("-n, --max-results <n>", "Maximum results per query (default: 5, range: 1-20)", "5").option("-c, --concurrency <n>", "Concurrency for batch searches (default: 5, range: 1-20)", "5").option("-t, --timeout <ms>", "Request timeout in milliseconds (default: 30000, range: 1000-300000)", "30000").option("-f, --file <file>", "Attach document for analysis").option("-i, --image <file>", "Attach image for analysis").option("-o, --format <format>", "Output format: json|jsonl (default: json)", "json").option("-q, --query <query>", "Search query (alternative to positional queries)").option("--export <filename>", "Export results to file").option("-I, --input <file>", "Read queries from JSON file").option("-s, --stdin", "Read queries from stdin (JSON format)").option("--attach <file>", "Additional file attachment (can be used multiple times)").option("--attach-image <file>", "Additional image attachment (can be used multiple times)").option("--async", "Enable async mode for advanced models").option("--webhook <url>", "Webhook URL for async results").option("--workspace <path>", "Workspace directory for file operations").option("--use-search-api", "Use search API (default: true)", true).option("--batch-size <n>", "Batch size for processing (default: 20, range: 1-100)", "20").allowExcessArguments(true).argument("[queries...]", "Search queries (multiple queries enable multi-search)");
10285
10356
  program2.command("history").description("Show search history").argument("[limit]", "Number of recent searches to show (max 50)").option("-f, --files", "Show individual search files with query+date naming").option("--query-pattern <pattern>", "Filter search files by query pattern").action(async (limit, options, command) => {
10286
10357
  const args = command.parent?.args.slice(command.parent.args.indexOf(command.name()) + 1) || [];
10287
10358
  const historyOptions = parseHistoryArgs(args);
@@ -10369,7 +10440,44 @@ program2.hook("preSubcommand", async (thisCommand) => {
10369
10440
  process.exit(result.exitCode);
10370
10441
  }
10371
10442
  });
10443
+ function parseAttachOptions(rawArgs) {
10444
+ const attach = [];
10445
+ const attachImage = [];
10446
+ const remainingArgs = [];
10447
+ let i = 0;
10448
+ while (i < rawArgs.length) {
10449
+ const arg = rawArgs[i];
10450
+ if (arg === "--attach") {
10451
+ if (i + 1 < rawArgs.length && !rawArgs[i + 1].startsWith("-")) {
10452
+ attach.push(rawArgs[i + 1]);
10453
+ i += 2;
10454
+ } else {
10455
+ console.error("Error: --attach requires a file path");
10456
+ process.exit(1);
10457
+ }
10458
+ } else if (arg === "--attach-image") {
10459
+ if (i + 1 < rawArgs.length && !rawArgs[i + 1].startsWith("-")) {
10460
+ attachImage.push(rawArgs[i + 1]);
10461
+ i += 2;
10462
+ } else {
10463
+ console.error("Error: --attach-image requires a file path");
10464
+ process.exit(1);
10465
+ }
10466
+ } else {
10467
+ remainingArgs.push(arg);
10468
+ i += 1;
10469
+ }
10470
+ }
10471
+ return { attach, attachImage, remainingArgs };
10472
+ }
10473
+ var rawArgs = process.argv.slice(2);
10474
+ var { attach: attachFiles, attachImage: attachImages, remainingArgs } = parseAttachOptions(rawArgs);
10475
+ var collectedAttach = attachFiles;
10476
+ var collectedAttachImages = attachImages;
10477
+ var originalArgv = process.argv;
10478
+ process.argv = ["node", originalArgv[1], ...remainingArgs];
10372
10479
  program2.action(async (queries, options) => {
10480
+ process.argv = originalArgv;
10373
10481
  const result = await handleSearchCommand({
10374
10482
  query: options.query,
10375
10483
  file: options.file,
@@ -10383,8 +10491,8 @@ program2.action(async (queries, options) => {
10383
10491
  useSearchAPI: options.useSearchApi,
10384
10492
  stdin: options.stdin,
10385
10493
  input: options.input,
10386
- attach: options.attach || [],
10387
- attachImage: options.attachImage || [],
10494
+ attach: collectedAttach,
10495
+ attachImage: collectedAttachImages,
10388
10496
  export: options.export,
10389
10497
  async: options.async,
10390
10498
  webhook: options.webhook,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pplx-zero",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "Fast Perplexity AI search CLI with multimodal support - minimal setup, maximal results",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",