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 +2 -2
- package/dist/commands/chat.js +10 -12
- package/dist/commands/repo.js +4 -2
- package/dist/commands/wallet.js +6 -7
- package/dist/utils/api.js +18 -35
- package/dist/utils/config.js +4 -1
- package/install.ps1 +5 -4
- package/install.sh +7 -5
- package/package.json +6 -4
- package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +1 -1
- package/scripts/release/validate-no-go-gates.sh +1 -1
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
|
-
|
|
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-
|
|
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):**
|
package/dist/commands/chat.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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`));
|
package/dist/commands/repo.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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));
|
package/dist/commands/wallet.js
CHANGED
|
@@ -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('
|
|
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('
|
|
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
|
-
|
|
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
|
|
3066
|
-
const
|
|
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
|
|
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
|
-
|
|
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,
|
package/dist/utils/config.js
CHANGED
|
@@ -147,7 +147,10 @@ export class Config {
|
|
|
147
147
|
return Config.OPERATOR_PLANS.has(this.getNormalizedPlan());
|
|
148
148
|
}
|
|
149
149
|
hasCloudAccess() {
|
|
150
|
-
|
|
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.
|
|
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
|
-
$
|
|
78
|
-
|
|
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
|
|
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.
|
|
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
|
|
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
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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.
|
|
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": "^
|
|
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": ">=
|
|
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 `>=
|
|
7
|
+
- [ ] Node.js `>=20.19` available
|
|
8
8
|
- [ ] `npm` available
|
|
9
9
|
- [ ] No stale shell aliases shadowing `vigthoria`
|
|
10
10
|
- [ ] Network access to:
|