vigthoria-cli 1.13.6 → 1.13.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.
package/README.md CHANGED
@@ -30,7 +30,7 @@ AI-powered terminal coding assistant for Vigthoria Coder subscribers, integrated
30
30
 
31
31
  ## Installation
32
32
 
33
- Version 1.9.3 is published as `vigthoria-cli` and installs the `vigthoria`, `vig`, and `vigthoria-chat` commands. Use the platform installer for automatic setup and updates, or install the npm package globally on any Node.js 18+ platform.
33
+ The `vigthoria-cli` package installs the `vigthoria`, `vig`, and `vigthoria-chat` commands. Use the platform installer for automatic setup and updates, or install the npm package globally on Node.js 20.19 or later.
34
34
 
35
35
  ### Quick Install (Linux/macOS)
36
36
 
@@ -99,7 +99,7 @@ If you see `ENOTFOUND registry.npmjs.org`, try these solutions:
99
99
  4. **Direct tarball download:**
100
100
  ```bash
101
101
  # Download directly
102
- npm install -g https://coder.vigthoria.io/releases/vigthoria-cli-1.9.10.tgz
102
+ npm install -g https://coder.vigthoria.io/releases/vigthoria-cli-latest.tgz
103
103
  ```
104
104
 
105
105
  5. **Use Git clone method (no npm registry needed):**
@@ -402,16 +402,6 @@ export class ChatCommand {
402
402
  routeReason: `balanced-4b-router → ${this.lastAgentRoute.taskKind}`,
403
403
  };
404
404
  }
405
- if (this.config.shouldUseCloudForHeavyTask(prompt)) {
406
- return {
407
- selectedModel: 'cloud',
408
- explicitModel: false,
409
- heavyTask: true,
410
- cloudEligible: true,
411
- cloudSelected: true,
412
- routeReason: 'heavy-enterprise-task',
413
- };
414
- }
415
405
  return {
416
406
  selectedModel: 'agent',
417
407
  explicitModel: false,
@@ -1322,7 +1312,15 @@ export class ChatCommand {
1322
1312
  const toolCalls = Number.isFinite(Number(event.tool_calls)) ? Number(event.tool_calls) : 0;
1323
1313
  const chars = Number.isFinite(Number(event.content_chars)) ? Number(event.content_chars) : 0;
1324
1314
  const finish = event.finish_reason ? `, ${this.sanitizeServerPath(String(event.finish_reason))}` : '';
1325
- process.stderr.write(chalk.cyan(' [Model] ') + `${model}: produced ${toolCalls} tool call${toolCalls === 1 ? '' : 's'}${chars ? `, ${chars} chars` : ''}${finish}\n`);
1315
+ const billing = event.billing && typeof event.billing === 'object' ? event.billing : null;
1316
+ const billingSuffix = billing
1317
+ ? billing.billingMode === 'master_admin'
1318
+ ? chalk.gray(' · Master Admin audited access')
1319
+ : billing.status === 'settlement_pending'
1320
+ ? chalk.yellow(` · ${Number(billing.reservedCredits || 0)} ⓥ reserved (settlement pending)`)
1321
+ : chalk.yellow(` · ${Number(billing.actualCredits || 0)} ⓥ charged${billing.balanceAfter != null ? ` · ${Number(billing.balanceAfter)} ⓥ remaining` : ''}`)
1322
+ : '';
1323
+ process.stderr.write(chalk.cyan(' [Model] ') + `${model}: produced ${toolCalls} tool call${toolCalls === 1 ? '' : 's'}${chars ? `, ${chars} chars` : ''}${finish}${billingSuffix}\n`);
1326
1324
  spinner.start();
1327
1325
  spinner.text = toolCalls > 0 ? 'Executing model-selected tools...' : 'Processing model response...';
1328
1326
  return;
@@ -3059,7 +3057,7 @@ export class ChatCommand {
3059
3057
  console.log(chalk.gray(`Reason: ${routingPolicy.routeReason}`));
3060
3058
  console.log(chalk.gray(`Model: ${routingPolicy.selectedModel}`));
3061
3059
  console.log(chalk.gray('Remote Engine Session: true'));
3062
- console.log(chalk.gray(`Cloud Eligible: ${routingPolicy.cloudEligible}`));
3060
+ console.log(chalk.gray(`Cloud PAYG Available: ${routingPolicy.cloudEligible}`));
3063
3061
  console.log(chalk.gray(`Cloud Selected: ${routingPolicy.cloudSelected}`));
3064
3062
  if (routingPolicy.heavyTask) {
3065
3063
  console.log(chalk.gray(`Task Complexity: HEAVY`));
@@ -19,7 +19,7 @@ import { createRequire } from 'node:module';
19
19
  import { createSpinner, CH } from '../utils/logger.js';
20
20
  const require = createRequire(import.meta.url);
21
21
  import inquirer from 'inquirer';
22
- import archiver from 'archiver';
22
+ import * as archiverModule from 'archiver';
23
23
  import { createWriteStream } from 'fs';
24
24
  const MAX_REPOSITORY_CONTENT_BYTES = 100 * 1024 * 1024;
25
25
  const MAX_REPOSITORY_REQUEST_BYTES = 120 * 1024 * 1024;
@@ -331,7 +331,9 @@ export class RepoCommand {
331
331
  }
332
332
  const archivePath = path.join(tempDir, `project-${Date.now()}.zip`);
333
333
  const output = createWriteStream(archivePath);
334
- const archive = archiver('zip', { zlib: { level: 9 } });
334
+ // Archiver 8 is ESM-only and exposes format-specific constructors
335
+ // instead of the legacy default factory.
336
+ const archive = new archiverModule.ZipArchive({ zlib: { level: 9 } });
335
337
  return new Promise((resolve, reject) => {
336
338
  output.on('close', () => resolve(archivePath));
337
339
  archive.on('error', (err) => reject(err));
@@ -159,16 +159,15 @@ export class WalletCommand {
159
159
  if (data.isMasterAdmin) {
160
160
  console.log(` Access: ${chalk.bold.green('Master Admin — unlimited cloud access')}`);
161
161
  }
162
- else if (data.hasGrant) {
163
- const models = data.grantDetails?.allowedModels === '*' ? 'All models' : data.grantDetails?.allowedModels;
164
- const exp = data.grantDetails?.expiresAt ? ` (expires ${new Date(data.grantDetails.expiresAt).toLocaleDateString()})` : '';
165
- console.log(` Access: ${chalk.green(`Granted — ${models}${exp}`)}`);
166
- }
167
162
  else if (data.cloudAccessAllowed) {
168
- console.log(` Access: ${chalk.yellow('Enabledpay per request with VigCoins')}`);
163
+ console.log(` Access: ${chalk.yellow('Pay as you go explicit selection and wallet credits required')}`);
164
+ console.log(` Balance: ${chalk.bold.yellow(Number(data.balance || 0).toLocaleString())} ⓥ`);
165
+ if (data.hasGrant) {
166
+ console.log(chalk.gray(' Model grant: active (billing still applies)'));
167
+ }
169
168
  }
170
169
  else {
171
- console.log(` Access: ${chalk.red('Not enabled contact admin to request cloud access')}`);
170
+ console.log(` Access: ${chalk.red('Unavailable for this account')}`);
172
171
  }
173
172
  console.log('');
174
173
  if (data.cloudModels) {
package/dist/utils/api.js CHANGED
@@ -10,6 +10,7 @@ import https from 'https';
10
10
  import net from 'net';
11
11
  import path from 'path';
12
12
  import WebSocket from 'ws';
13
+ import { globSync } from 'glob';
13
14
  import { buildSemanticContext } from './context-ranker.js';
14
15
  import { getChangedFiles } from './workspace-cache.js';
15
16
  import { isSubstantiveAgentAnswer, isToolEvidenceStubAnswer } from './agentRunOutcome.js';
@@ -1725,12 +1726,7 @@ export class APIClient {
1725
1726
  }
1726
1727
  compactionMeta.applied = true;
1727
1728
  phases.push('over_limit');
1728
- if (!/^(1|true|yes)$/i.test(String(process.env.VIGTHORIA_QUIET_CONTEXT_COMPACTION || ''))) {
1729
- process.stderr.write(`Workspace context is large — sending a focused summary (~${Math.round(LIMIT / 1000)}k char budget, token-aligned).\n`);
1730
- }
1731
- if (process.env.DEBUG || process.env.VIGTHORIA_DEBUG) {
1732
- process.stderr.write(`[context] Payload ${json.length} chars exceeds ${LIMIT} limit, compacting...\n`);
1733
- }
1729
+ this.logger.debug(`Workspace context ${json.length} chars exceeds ${LIMIT}; applying token-aligned compaction.`);
1734
1730
  const summary = payload.localWorkspaceSummary;
1735
1731
  const hydrationRequired = payload.workspaceHydrationRequired === true;
1736
1732
  const finish = () => {
@@ -3062,8 +3058,8 @@ menu {
3062
3058
  return { success: true, output: entries.join('\n') || '(empty)' };
3063
3059
  }
3064
3060
  if (name === 'glob' || name === 'search_files' || name === 'grep') {
3065
- const pattern = String(args.pattern || args.query || '').toLowerCase();
3066
- const files = [];
3061
+ const rawPattern = String(args.pattern || args.query || '').trim();
3062
+ const pattern = rawPattern.toLowerCase();
3067
3063
  const matches = [];
3068
3064
  const walk = (dir) => {
3069
3065
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
@@ -3075,12 +3071,7 @@ menu {
3075
3071
  continue;
3076
3072
  }
3077
3073
  const relative = path.relative(rootPath, absolute).replace(/\\/g, '/');
3078
- if (name === 'glob' && pattern) {
3079
- if (!pattern || relative.toLowerCase().includes(pattern.replace(/\*/g, ''))) {
3080
- files.push(relative);
3081
- }
3082
- }
3083
- else if (pattern) {
3074
+ if (name !== 'glob' && pattern) {
3084
3075
  try {
3085
3076
  const content = fs.readFileSync(absolute, 'utf8');
3086
3077
  if (relative.toLowerCase().includes(pattern.replace(/\*/g, '')) || content.toLowerCase().includes(pattern)) {
@@ -3094,10 +3085,19 @@ menu {
3094
3085
  }
3095
3086
  };
3096
3087
  const searchRoot = fs.statSync(target.absolutePath).isDirectory() ? target.absolutePath : rootPath;
3097
- walk(searchRoot);
3098
3088
  if (name === 'glob') {
3099
- return { success: true, output: files.slice(0, 200).join('\n') || '(no matches)' };
3089
+ const normalizedPattern = rawPattern.replace(/\\/g, '/') || '**/*';
3090
+ const globbed = globSync(normalizedPattern, {
3091
+ cwd: searchRoot,
3092
+ nodir: true,
3093
+ dot: false,
3094
+ ignore: ['**/node_modules/**', '**/.git/**'],
3095
+ })
3096
+ .map((entry) => String(entry).replace(/\\/g, '/'))
3097
+ .sort((left, right) => left.localeCompare(right));
3098
+ return { success: true, output: globbed.slice(0, 200).join('\n') || '(no matches)' };
3100
3099
  }
3100
+ walk(searchRoot);
3101
3101
  return { success: true, output: matches.slice(0, 100).join('\n') || '(no matches)' };
3102
3102
  }
3103
3103
  if (name === 'syntax_check') {
@@ -3185,27 +3185,8 @@ menu {
3185
3185
  if (!contextId || !callId)
3186
3186
  return;
3187
3187
  const backendUrl = responseUrl ? new URL(responseUrl).origin : (context.mcpContextBackendUrl || null);
3188
- const emitStream = (streamEvent) => {
3189
- if (typeof context.onStreamEvent === 'function') {
3190
- try {
3191
- context.onStreamEvent(streamEvent);
3192
- }
3193
- catch {
3194
- // UI callbacks must never break the client tool bridge.
3195
- }
3196
- }
3197
- };
3198
- emitStream({ type: 'tool_call', name: toolName, tool: toolName, arguments: event.arguments || {} });
3199
3188
  try {
3200
3189
  const result = await this.executeV3ClientToolRequest(event, context);
3201
- emitStream({
3202
- type: 'tool_result',
3203
- name: toolName,
3204
- tool: toolName,
3205
- success: result.success,
3206
- output: result.output,
3207
- error: result.error || '',
3208
- });
3209
3190
  try {
3210
3191
  await this.submitClientToolResult(contextId, callId, result, backendUrl);
3211
3192
  }
@@ -4787,6 +4768,7 @@ document.addEventListener('DOMContentLoaded', () => {
4787
4768
  model: resolvedModel,
4788
4769
  maxTokens: this.config.get('preferences').maxTokens,
4789
4770
  temperature: 0.7,
4771
+ cloudConsent: this.isCloudModelId(resolvedModel),
4790
4772
  });
4791
4773
  if (response.data.success !== false) {
4792
4774
  const content = response.data.response || response.data.message || response.data.content;
@@ -4817,6 +4799,7 @@ document.addEventListener('DOMContentLoaded', () => {
4817
4799
  model: resolvedModel,
4818
4800
  maxTokens: this.config.get('preferences').maxTokens,
4819
4801
  temperature: 0.7,
4802
+ cloudConsent: this.isCloudModelId(resolvedModel),
4820
4803
  }, {
4821
4804
  timeout: 180000,
4822
4805
  httpsAgent: this._httpsAgent ?? undefined,
@@ -147,7 +147,10 @@ export class Config {
147
147
  return Config.OPERATOR_PLANS.has(this.getNormalizedPlan());
148
148
  }
149
149
  hasCloudAccess() {
150
- return Config.CLOUD_PLANS.has(this.getNormalizedPlan());
150
+ // Cloud model visibility means the authenticated user may explicitly
151
+ // request PAYG execution. It never implies free access; the server
152
+ // atomically reserves wallet credits for every provider call.
153
+ return this.isAuthenticated();
151
154
  }
152
155
  getConfigPath() {
153
156
  return this.store.path;
package/install.ps1 CHANGED
@@ -5,7 +5,7 @@
5
5
  $ErrorActionPreference = "Stop"
6
6
 
7
7
  # Configuration
8
- $CLI_VERSION = "1.11.42"
8
+ $CLI_VERSION = "1.13.8"
9
9
  $INSTALL_DIR = "$env:USERPROFILE\.vigthoria"
10
10
  $NPM_PACKAGE = "vigthoria-cli"
11
11
  $GIT_PACKAGE_URL = "git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
@@ -74,11 +74,12 @@ function Test-Prerequisites {
74
74
  try {
75
75
  $nodeVersion = node -v 2>$null
76
76
  if ($nodeVersion) {
77
- $major = [int]($nodeVersion -replace 'v(\d+)\..*', '$1')
78
- if ($major -ge 18) {
77
+ $versionText = $nodeVersion.TrimStart('v')
78
+ $parsedVersion = [version]$versionText
79
+ if ($parsedVersion -ge [version]"20.19.0") {
79
80
  Write-Host "✓ Node.js $nodeVersion" -ForegroundColor Green
80
81
  } else {
81
- Write-Host "✗ Node.js 18+ required (found $nodeVersion)" -ForegroundColor Red
82
+ Write-Host "✗ Node.js 20.19+ required (found $nodeVersion)" -ForegroundColor Red
82
83
  Write-Host " Download from: https://nodejs.org/" -ForegroundColor Yellow
83
84
  return $false
84
85
  }
package/install.sh CHANGED
@@ -26,7 +26,7 @@ else
26
26
  fi
27
27
 
28
28
  # Configuration
29
- CLI_VERSION="1.11.42"
29
+ CLI_VERSION="1.13.8"
30
30
  INSTALL_DIR="$HOME/.vigthoria"
31
31
  REPO_URL="https://market.vigthoria.io/vigthoria/vigthoria-cli"
32
32
  GIT_PACKAGE_URL="git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
@@ -130,7 +130,7 @@ check_requirements() {
130
130
  if ! command -v node &> /dev/null; then
131
131
  echo -e "${RED}✗ Node.js is not installed${NC}"
132
132
  echo ""
133
- echo " Please install Node.js 18 or later:"
133
+ echo " Please install Node.js 20.19 or later:"
134
134
  if [ "$PLATFORM" = "macos" ]; then
135
135
  echo " brew install node"
136
136
  echo " or download from: https://nodejs.org/"
@@ -144,9 +144,11 @@ check_requirements() {
144
144
  exit 1
145
145
  fi
146
146
 
147
- NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
148
- if [ "$NODE_VERSION" -lt 18 ]; then
149
- echo -e "${RED}✗ Node.js version must be 18 or higher (found: v$NODE_VERSION)${NC}"
147
+ NODE_VERSION_FULL=$(node -v | sed 's/^v//')
148
+ NODE_VERSION_MAJOR=$(printf '%s' "$NODE_VERSION_FULL" | cut -d'.' -f1)
149
+ NODE_VERSION_MINOR=$(printf '%s' "$NODE_VERSION_FULL" | cut -d'.' -f2)
150
+ if [ "$NODE_VERSION_MAJOR" -lt 20 ] || { [ "$NODE_VERSION_MAJOR" -eq 20 ] && [ "$NODE_VERSION_MINOR" -lt 19 ]; }; then
151
+ echo -e "${RED}✗ Node.js version must be 20.19 or higher (found: v$NODE_VERSION_FULL)${NC}"
150
152
  exit 1
151
153
  fi
152
154
  echo -e "${GREEN}✓ Node.js v$(node -v | cut -d'v' -f2)${NC}"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vigthoria-cli",
3
- "version": "1.13.6",
3
+ "version": "1.13.8",
4
4
  "description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -75,6 +75,7 @@
75
75
  "test:session:project-match": "npm run build && node scripts/test-session-project-match.mjs",
76
76
  "test:v3-stream-mutation": "npm run build && node scripts/test-v3-stream-mutation.js",
77
77
  "test:context:budget": "npm run build && node scripts/test-context-budget.js",
78
+ "test:v3-client-tool-quality": "npm run build && node scripts/test-v3-client-tool-quality.mjs",
78
79
  "test:pitfall:context": "npm run build && node scripts/test-pitfall-context-smoke.js",
79
80
  "test:game:command": "node scripts/test-game-command.mjs"
80
81
  },
@@ -90,7 +91,7 @@
90
91
  "author": "Vigthoria Technologies",
91
92
  "license": "MIT",
92
93
  "dependencies": {
93
- "archiver": "^7.0.1",
94
+ "archiver": "^8.0.0",
94
95
  "axios": "^1.6.0",
95
96
  "chalk": "^5.3.0",
96
97
  "chokidar": "^5.0.0",
@@ -117,9 +118,10 @@
117
118
  "typescript": "^5.3.2"
118
119
  },
119
120
  "engines": {
120
- "node": ">=18.0.0"
121
+ "node": ">=20.19.0"
121
122
  },
122
123
  "overrides": {
123
- "glob": "^13.0.6"
124
+ "glob": "^13.0.6",
125
+ "brace-expansion": "^5.0.8"
124
126
  }
125
127
  }
@@ -4,7 +4,7 @@ Use this checklist on real user machines before and after rollout. The goal is t
4
4
 
5
5
  ## 1. Preflight
6
6
 
7
- - [ ] Node.js `>=18` available
7
+ - [ ] Node.js `>=20.19` available
8
8
  - [ ] `npm` available
9
9
  - [ ] No stale shell aliases shadowing `vigthoria`
10
10
  - [ ] Network access to:
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
- ROOT="/var/www/vigthoria-coder/VigthoriaCoderMain/vigthoria-cli"
4
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
5
  cd "$ROOT"
6
6
 
7
7
  CLI="node dist/index.js"