vigthoria-cli 1.8.8 → 1.8.9

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.
@@ -1773,13 +1773,16 @@ class ChatCommand {
1773
1773
  spinner.stop();
1774
1774
  }
1775
1775
  this.logger.warn('Falling back to legacy CLI agent loop');
1776
- this.logger.debug(`V3 agent workflow unavailable: ${error.message}`);
1776
+ this.logger.debug(`V3 agent workflow unavailable: ${(0, api_js_1.sanitizeUserFacingErrorText)(error.message || '')}`);
1777
1777
  return false;
1778
1778
  }
1779
1779
  if (spinner) {
1780
1780
  spinner.stop();
1781
1781
  }
1782
- const errorMessage = `Agent mode requires the V3 workflow and will not fall back to the legacy CLI loop. ${error.message}`;
1782
+ const safeDetail = (0, api_js_1.sanitizeUserFacingErrorText)(error.message || '');
1783
+ const errorMessage = safeDetail
1784
+ ? `Agent mode is unavailable right now. ${safeDetail}`
1785
+ : 'Agent mode is unavailable right now. Please retry shortly or run vigthoria login if the issue persists.';
1783
1786
  this.logger.error(errorMessage);
1784
1787
  this.messages.push({ role: 'assistant', content: errorMessage });
1785
1788
  if (this.jsonOutput) {
@@ -186,6 +186,8 @@ export interface VigthoriUser {
186
186
  adminAccess: boolean;
187
187
  };
188
188
  }
189
+ export declare function sanitizeUserFacingErrorText(input: string): string;
190
+ export declare function describeUpstreamStatus(status: number): string;
189
191
  export declare class APIClient {
190
192
  private client;
191
193
  private modelRouterClient;
package/dist/utils/api.js CHANGED
@@ -10,6 +10,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.APIClient = exports.CLIError = void 0;
11
11
  exports.classifyError = classifyError;
12
12
  exports.formatCLIError = formatCLIError;
13
+ exports.sanitizeUserFacingErrorText = sanitizeUserFacingErrorText;
14
+ exports.describeUpstreamStatus = describeUpstreamStatus;
13
15
  const axios_1 = __importDefault(require("axios"));
14
16
  const crypto_1 = require("crypto");
15
17
  const fs_1 = __importDefault(require("fs"));
@@ -116,6 +118,39 @@ const DEFAULT_OPERATOR_TIMEOUT_MS = (() => {
116
118
  const parsed = Number.parseInt(rawValue, 10);
117
119
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
118
120
  })();
121
+ // Sanitize an upstream error string before exposing it to the end user.
122
+ // Strips URLs, IPs:ports, absolute server paths, and bare hostnames so the
123
+ // CLI never reveals internal infrastructure to remote users.
124
+ function sanitizeUserFacingErrorText(input) {
125
+ if (!input)
126
+ return '';
127
+ let out = String(input);
128
+ out = out.replace(/https?:\/\/[^\s'"<>)]+/gi, '[redacted-url]');
129
+ out = out.replace(/\b\d{1,3}(?:\.\d{1,3}){3}(?::\d+)?\b/g, '[redacted-host]');
130
+ out = out.replace(/\b(?:localhost|127\.0\.0\.1)(?::\d+)?\b/gi, '[redacted-host]');
131
+ out = out.replace(/\b[a-z0-9.-]+\.vigthoria\.io\b/gi, '[redacted-host]');
132
+ out = out.replace(/(?:[A-Za-z]:)?[\\/](?:var|opt|tmp|home|root|etc|usr)[\\/][^\s'"<>)]*/gi, '[redacted-path]');
133
+ out = out.replace(/\{\s*"detail"\s*:\s*"[^"]*"\s*\}/g, '');
134
+ out = out.replace(/\s+/g, ' ').trim();
135
+ if (out.length > 160)
136
+ out = out.slice(0, 160) + '...';
137
+ return out;
138
+ }
139
+ function describeUpstreamStatus(status) {
140
+ if (status === 401 || status === 403)
141
+ return 'Authentication failed. Please run vigthoria login.';
142
+ if (status === 404)
143
+ return 'Requested service endpoint was not found.';
144
+ if (status === 408 || status === 504)
145
+ return 'Upstream service timed out.';
146
+ if (status === 429)
147
+ return 'Rate limit reached. Please retry shortly.';
148
+ if (status >= 500)
149
+ return 'Upstream service is temporarily unavailable.';
150
+ if (status >= 400)
151
+ return 'Request was rejected by the service.';
152
+ return 'Unexpected response from service.';
153
+ }
119
154
  class APIClient {
120
155
  client;
121
156
  modelRouterClient;
@@ -805,7 +840,7 @@ class APIClient {
805
840
  });
806
841
  if (!response.ok) {
807
842
  const errorText = await response.text().catch(() => '');
808
- throw new Error(`Template preview proof ${response.status}: ${errorText.slice(0, 200)}`);
843
+ throw new Error(`Template preview proof ${response.status}: ${describeUpstreamStatus(response.status)}`);
809
844
  }
810
845
  const payload = await response.json();
811
846
  const modes = payload?.modes || {};
@@ -1746,7 +1781,7 @@ menu {
1746
1781
  });
1747
1782
  if (!response.ok) {
1748
1783
  const errorText = await response.text().catch(() => '');
1749
- throw new Error(`MCP context update ${response.status}: ${errorText.slice(0, 200)}`);
1784
+ throw new Error(`MCP context update ${response.status}: ${describeUpstreamStatus(response.status)}`);
1750
1785
  }
1751
1786
  return {
1752
1787
  ...executionContext,
@@ -1777,7 +1812,7 @@ menu {
1777
1812
  });
1778
1813
  if (!createResponse.ok) {
1779
1814
  const errorText = await createResponse.text().catch(() => '');
1780
- throw new Error(`MCP context create ${createResponse.status}: ${errorText.slice(0, 200)}`);
1815
+ throw new Error(`MCP context create ${createResponse.status}: ${describeUpstreamStatus(createResponse.status)}`);
1781
1816
  }
1782
1817
  const payload = await createResponse.json();
1783
1818
  const mcpContextId = String(payload.contextId || '').trim();
@@ -2723,7 +2758,7 @@ document.addEventListener('DOMContentLoaded', () => {
2723
2758
  partial: true,
2724
2759
  };
2725
2760
  }
2726
- throw new Error(event.message || 'V3 agent returned an error');
2761
+ throw new Error(`V3 agent: ${sanitizeUserFacingErrorText(event.message || '') || 'returned an error'}`);
2727
2762
  }
2728
2763
  if (event.type === 'complete' || event.type === 'message') {
2729
2764
  final = event;
@@ -2786,7 +2821,7 @@ document.addEventListener('DOMContentLoaded', () => {
2786
2821
  const response = await this.executeV3AgentRunRequest(baseUrl, requestBody, requestExecutionContext, controller.signal);
2787
2822
  if (!response.ok) {
2788
2823
  const errorText = await response.text().catch(() => '');
2789
- throw new Error(`V3 agent ${response.status}: ${errorText.slice(0, 200)}`);
2824
+ throw new Error(`V3 agent ${response.status}: ${describeUpstreamStatus(response.status)}`);
2790
2825
  }
2791
2826
  const data = await this.collectV3AgentStream(response, requestExecutionContext);
2792
2827
  // Auto-continuation: if the agent checkpointed (budget exceeded), continue automatically
@@ -3013,7 +3048,7 @@ document.addEventListener('DOMContentLoaded', () => {
3013
3048
  });
3014
3049
  if (!response.ok) {
3015
3050
  const errorText = await response.text().catch(() => '');
3016
- throw new Error(`Operator stream ${response.status}: ${errorText.slice(0, 200)}`);
3051
+ throw new Error(`Operator stream ${response.status}: ${describeUpstreamStatus(response.status)}`);
3017
3052
  }
3018
3053
  if (!response.body || typeof response.body.getReader !== 'function') {
3019
3054
  const fallbackData = await response.json();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vigthoria-cli",
3
- "version": "1.8.8",
3
+ "version": "1.8.9",
4
4
  "description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
5
5
  "main": "dist/index.js",
6
6
  "files": [