vigthoria-cli 1.13.20 → 1.13.23
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/completions/_vigthoria +49 -0
- package/completions/vigthoria.bash +6 -0
- package/completions/vigthoria.fish +41 -0
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/auth.js +63 -128
- package/dist/commands/background.d.ts +0 -2
- package/dist/commands/background.js +26 -34
- package/dist/commands/bridge.js +45 -41
- package/dist/commands/cancel.d.ts +1 -0
- package/dist/commands/cancel.js +22 -16
- package/dist/commands/chat.d.ts +3 -42
- package/dist/commands/chat.js +378 -1123
- package/dist/commands/coding-registration.d.ts +4 -0
- package/dist/commands/coding-registration.js +24 -0
- package/dist/commands/config.js +23 -29
- package/dist/commands/conversation-registration.d.ts +4 -0
- package/dist/commands/conversation-registration.js +122 -0
- package/dist/commands/deploy.d.ts +8 -2
- package/dist/commands/deploy.js +92 -90
- package/dist/commands/device.d.ts +1 -2
- package/dist/commands/device.js +37 -21
- package/dist/commands/doctor-registration.d.ts +4 -0
- package/dist/commands/doctor-registration.js +207 -0
- package/dist/commands/edit.js +22 -33
- package/dist/commands/explain.js +7 -10
- package/dist/commands/fork.d.ts +1 -2
- package/dist/commands/fork.js +72 -22
- package/dist/commands/game.d.ts +1 -1
- package/dist/commands/game.js +17 -6
- package/dist/commands/generate.js +7 -9
- package/dist/commands/history.js +11 -7
- package/dist/commands/hub.d.ts +2 -2
- package/dist/commands/hub.js +34 -35
- package/dist/commands/legion.d.ts +0 -1
- package/dist/commands/legion.js +62 -79
- package/dist/commands/music.d.ts +1 -2
- package/dist/commands/music.js +62 -27
- package/dist/commands/platform-registration.d.ts +4 -0
- package/dist/commands/platform-registration.js +45 -0
- package/dist/commands/preview.d.ts +0 -1
- package/dist/commands/preview.js +82 -35
- package/dist/commands/product-run-registration.d.ts +4 -0
- package/dist/commands/product-run-registration.js +490 -0
- package/dist/commands/replay.d.ts +1 -2
- package/dist/commands/replay.js +15 -11
- package/dist/commands/repo.d.ts +14 -7
- package/dist/commands/repo.js +244 -198
- package/dist/commands/review.js +9 -12
- package/dist/commands/security.d.ts +1 -2
- package/dist/commands/security.js +12 -6
- package/dist/commands/update-registration.d.ts +3 -0
- package/dist/commands/update-registration.js +368 -0
- package/dist/commands/v4-registration.d.ts +4 -0
- package/dist/commands/v4-registration.js +24 -0
- package/dist/commands/v4.d.ts +1 -1
- package/dist/commands/v4.js +46 -8
- package/dist/commands/wallet.d.ts +1 -3
- package/dist/commands/wallet.js +18 -45
- package/dist/commands/workflow.d.ts +2 -0
- package/dist/commands/workflow.js +52 -39
- package/dist/index.js +124 -1589
- package/dist/utils/agent-stream-state.d.ts +27 -0
- package/dist/utils/agent-stream-state.js +93 -0
- package/dist/utils/agentRoute.d.ts +2 -1
- package/dist/utils/agentRoute.js +22 -9
- package/dist/utils/agentRunOutcome.d.ts +16 -0
- package/dist/utils/agentRunOutcome.js +37 -2
- package/dist/utils/api-client-factory.d.ts +8 -0
- package/dist/utils/api-client-factory.js +8 -0
- package/dist/utils/api.d.ts +44 -266
- package/dist/utils/api.js +647 -3180
- package/dist/utils/auth-session.d.ts +41 -0
- package/dist/utils/auth-session.js +224 -0
- package/dist/utils/brain-hub-client.d.ts +0 -4
- package/dist/utils/brain-hub-client.js +6 -3
- package/dist/utils/bridge-client.js +2 -0
- package/dist/utils/capability-health-service.d.ts +48 -0
- package/dist/utils/capability-health-service.js +64 -0
- package/dist/utils/chat-prompt-policy.d.ts +18 -0
- package/dist/utils/chat-prompt-policy.js +61 -0
- package/dist/utils/chat-tool-call-parser.d.ts +11 -0
- package/dist/utils/chat-tool-call-parser.js +71 -0
- package/dist/utils/cli-state.d.ts +22 -4
- package/dist/utils/cli-state.js +105 -47
- package/dist/utils/code-operations-service.d.ts +104 -0
- package/dist/utils/code-operations-service.js +837 -0
- package/dist/utils/codebase-indexer.d.ts +1 -0
- package/dist/utils/codebase-indexer.js +28 -8
- package/dist/utils/command-contract.d.ts +61 -0
- package/dist/utils/command-contract.js +149 -0
- package/dist/utils/command-policy.d.ts +10 -0
- package/dist/utils/command-policy.js +54 -0
- package/dist/utils/config.d.ts +13 -5
- package/dist/utils/config.js +220 -94
- package/dist/utils/context-ranker.js +11 -2
- package/dist/utils/context-state.d.ts +39 -0
- package/dist/utils/context-state.js +52 -0
- package/dist/utils/deckEvents.d.ts +0 -5
- package/dist/utils/deckEvents.js +3 -2
- package/dist/utils/desktop-bridge-client.js +2 -0
- package/dist/utils/direct-output-policy.d.ts +3 -0
- package/dist/utils/direct-output-policy.js +76 -0
- package/dist/utils/durable-json.d.ts +57 -0
- package/dist/utils/durable-json.js +319 -0
- package/dist/utils/fastAgentRouter.d.ts +5 -6
- package/dist/utils/fastAgentRouter.js +17 -25
- package/dist/utils/files.js +21 -13
- package/dist/utils/frontend-preview-service.d.ts +76 -0
- package/dist/utils/frontend-preview-service.js +482 -0
- package/dist/utils/goaEvents.d.ts +0 -4
- package/dist/utils/goaEvents.js +5 -2
- package/dist/utils/logger.d.ts +2 -1
- package/dist/utils/logger.js +27 -20
- package/dist/utils/mcp-context-client.d.ts +24 -0
- package/dist/utils/mcp-context-client.js +58 -0
- package/dist/utils/model-governance.d.ts +18 -0
- package/dist/utils/model-governance.js +75 -0
- package/dist/utils/model-transport-service.d.ts +44 -0
- package/dist/utils/model-transport-service.js +111 -0
- package/dist/utils/mutation-journal.d.ts +42 -0
- package/dist/utils/mutation-journal.js +387 -0
- package/dist/utils/network-policy.d.ts +24 -0
- package/dist/utils/network-policy.js +202 -0
- package/dist/utils/operator-client.d.ts +45 -0
- package/dist/utils/operator-client.js +159 -0
- package/dist/utils/post-write-validator.js +7 -9
- package/dist/utils/preview-screenshot-adapter.d.ts +15 -0
- package/dist/utils/preview-screenshot-adapter.js +51 -0
- package/dist/utils/process-policy.d.ts +23 -0
- package/dist/utils/process-policy.js +284 -0
- package/dist/utils/project-memory.d.ts +13 -3
- package/dist/utils/project-memory.js +70 -17
- package/dist/utils/prompt-workspace-resolver.d.ts +14 -0
- package/dist/utils/prompt-workspace-resolver.js +64 -0
- package/dist/utils/release-install.d.ts +11 -0
- package/dist/utils/release-install.js +155 -0
- package/dist/utils/release-policy.d.ts +64 -0
- package/dist/utils/release-policy.js +293 -0
- package/dist/utils/requestIntent.js +22 -3
- package/dist/utils/runtime-capability.d.ts +8 -0
- package/dist/utils/runtime-capability.js +16 -0
- package/dist/utils/runtime-temp.d.ts +76 -0
- package/dist/utils/runtime-temp.js +492 -0
- package/dist/utils/secret-policy.d.ts +20 -0
- package/dist/utils/secret-policy.js +160 -0
- package/dist/utils/session.d.ts +17 -3
- package/dist/utils/session.js +354 -110
- package/dist/utils/tool-approval-service.d.ts +17 -0
- package/dist/utils/tool-approval-service.js +78 -0
- package/dist/utils/tool-capability-providers.d.ts +57 -0
- package/dist/utils/tool-capability-providers.js +57 -0
- package/dist/utils/tools.d.ts +2 -23
- package/dist/utils/tools.js +226 -512
- package/dist/utils/update-policy.d.ts +18 -0
- package/dist/utils/update-policy.js +137 -0
- package/dist/utils/v3-agent-client.d.ts +40 -0
- package/dist/utils/v3-agent-client.js +165 -0
- package/dist/utils/v3-workspace-service.d.ts +28 -0
- package/dist/utils/v3-workspace-service.js +279 -0
- package/dist/utils/vigflow-client.d.ts +95 -0
- package/dist/utils/vigflow-client.js +105 -0
- package/dist/utils/workspace-boundary.d.ts +45 -0
- package/dist/utils/workspace-boundary.js +377 -0
- package/dist/utils/workspace-brain-service.d.ts +2 -0
- package/dist/utils/workspace-brain-service.js +11 -1
- package/dist/utils/workspace-cache.js +37 -15
- package/dist/utils/workspace-stream.js +35 -10
- package/install.ps1 +115 -142
- package/install.sh +112 -81
- package/package.json +43 -9
- package/release-policy.json +43 -0
- package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +1 -1
- package/scripts/release/generate-completions.mjs +24 -0
- package/scripts/release/install-release.mjs +10 -0
- package/scripts/release/publish-cli-release.mjs +116 -0
- package/scripts/release/publish-cli-release.sh +2 -70
- package/scripts/release/resolve-release-manifest.mjs +26 -0
- package/scripts/release/test-balanced-model-live.sh +45 -0
- package/scripts/release/validate-live-service-gates.sh +93 -0
- package/scripts/release/validate-no-go-gates.sh +145 -174
- package/scripts/release/verify-runtime-consistency.mjs +4 -1
- package/dist/commands/index.d.ts +0 -12
- package/dist/commands/index.js +0 -194
- package/dist/commands/update.d.ts +0 -9
- package/dist/commands/update.js +0 -301
- package/dist/utils/templateInstantPath.d.ts +0 -18
- package/dist/utils/templateInstantPath.js +0 -228
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
import { createHash } from 'node:crypto';
|
|
10
10
|
import fs from 'node:fs';
|
|
11
11
|
import path from 'node:path';
|
|
12
|
+
import { isSensitivePath } from './secret-policy.js';
|
|
13
|
+
import { DurableJsonStore } from './durable-json.js';
|
|
14
|
+
import { resolveWorkspacePath } from './workspace-boundary.js';
|
|
12
15
|
const CACHE_SUBDIR = '.vigthoria';
|
|
13
16
|
const CACHE_FILENAME = 'file-hashes.json';
|
|
14
17
|
function getCachePath(workspacePath) {
|
|
@@ -24,20 +27,37 @@ function hashFile(absPath) {
|
|
|
24
27
|
}
|
|
25
28
|
function loadCache(workspacePath) {
|
|
26
29
|
try {
|
|
27
|
-
return
|
|
30
|
+
return cacheStore(workspacePath).read();
|
|
28
31
|
}
|
|
29
32
|
catch {
|
|
30
33
|
return {};
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
function persistCache(workspacePath, hashes) {
|
|
37
|
+
cacheStore(workspacePath).update((current) => ({ ...current, ...hashes }));
|
|
38
|
+
}
|
|
39
|
+
function cacheStore(workspacePath) {
|
|
40
|
+
const isHashMap = (value) => Boolean(value && typeof value === 'object' && !Array.isArray(value)
|
|
41
|
+
&& Object.entries(value).every(([key, hash]) => (Boolean(key) && typeof hash === 'string' && /^[a-f0-9]{64}$/i.test(hash))));
|
|
42
|
+
return new DurableJsonStore({
|
|
43
|
+
filePath: getCachePath(workspacePath),
|
|
44
|
+
schemaVersion: 1,
|
|
45
|
+
defaultValue: () => ({}),
|
|
46
|
+
validate: isHashMap,
|
|
47
|
+
migrate: (value) => isHashMap(value) ? value : {},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function resolveTrackedFile(workspacePath, candidate) {
|
|
34
51
|
try {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
52
|
+
const absolutePath = resolveWorkspacePath(workspacePath, candidate, { allowAbsoluteInsideRoot: true });
|
|
53
|
+
const key = path.relative(fs.realpathSync(workspacePath), absolutePath).replace(/\\/g, '/');
|
|
54
|
+
if (!key || key.startsWith('../') || isSensitivePath(key))
|
|
55
|
+
return null;
|
|
56
|
+
return { absolutePath, key };
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
39
60
|
}
|
|
40
|
-
catch { /* non-fatal */ }
|
|
41
61
|
}
|
|
42
62
|
/**
|
|
43
63
|
* Partition file paths into changed and unchanged sets.
|
|
@@ -50,17 +70,18 @@ export function getChangedFiles(workspacePath, relativePaths) {
|
|
|
50
70
|
const changed = [];
|
|
51
71
|
const unchanged = [];
|
|
52
72
|
for (const rel of relativePaths) {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
73
|
+
const tracked = resolveTrackedFile(workspacePath, rel);
|
|
74
|
+
if (!tracked)
|
|
75
|
+
continue;
|
|
76
|
+
const currentHash = hashFile(tracked.absolutePath);
|
|
77
|
+
if (!currentHash || cache[tracked.key] !== currentHash) {
|
|
57
78
|
changed.push(rel);
|
|
58
79
|
}
|
|
59
80
|
else {
|
|
60
81
|
unchanged.push(rel);
|
|
61
82
|
}
|
|
62
83
|
}
|
|
63
|
-
return { changed, unchanged, total:
|
|
84
|
+
return { changed, unchanged, total: changed.length + unchanged.length };
|
|
64
85
|
}
|
|
65
86
|
/**
|
|
66
87
|
* Write current hashes for the given files into the persistent cache.
|
|
@@ -71,11 +92,12 @@ export function updateWorkspaceCache(workspacePath, relativePaths) {
|
|
|
71
92
|
return;
|
|
72
93
|
const cache = loadCache(workspacePath);
|
|
73
94
|
for (const rel of relativePaths) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
95
|
+
const tracked = resolveTrackedFile(workspacePath, rel);
|
|
96
|
+
if (!tracked)
|
|
97
|
+
continue;
|
|
98
|
+
const hash = hashFile(tracked.absolutePath);
|
|
77
99
|
if (hash)
|
|
78
|
-
cache[key] = hash;
|
|
100
|
+
cache[tracked.key] = hash;
|
|
79
101
|
}
|
|
80
102
|
persistCache(workspacePath, cache);
|
|
81
103
|
}
|
|
@@ -22,7 +22,10 @@ import fs from 'fs';
|
|
|
22
22
|
import path from 'path';
|
|
23
23
|
import WebSocket from 'ws';
|
|
24
24
|
import { Logger } from './logger.js';
|
|
25
|
-
import {
|
|
25
|
+
import { normalizeV3WorkspaceRelativePath } from './v3-workspace-path.js';
|
|
26
|
+
import { assertTrustedWebSocketEndpoint } from './network-policy.js';
|
|
27
|
+
import { resolveWorkspacePath } from './workspace-boundary.js';
|
|
28
|
+
import { containsHighConfidenceSecret, isSensitivePath } from './secret-policy.js';
|
|
26
29
|
const logger = new Logger();
|
|
27
30
|
logger.setVerbose(!!process.env.VIGTHORIA_DEBUG);
|
|
28
31
|
// Files/dirs to ignore in the watcher
|
|
@@ -36,6 +39,12 @@ const IGNORE_PATTERNS = [
|
|
|
36
39
|
'**/.next/**',
|
|
37
40
|
'**/.cache/**',
|
|
38
41
|
'**/.vigthoria/**',
|
|
42
|
+
'**/.env',
|
|
43
|
+
'**/.env.*',
|
|
44
|
+
'**/credentials*',
|
|
45
|
+
'**/secrets*',
|
|
46
|
+
'**/*.pem',
|
|
47
|
+
'**/*.key',
|
|
39
48
|
'**/coverage/**',
|
|
40
49
|
'**/*.pyc',
|
|
41
50
|
// CRITICAL: Windows AppData & system directories (prevents EPERM errors)
|
|
@@ -80,10 +89,15 @@ export function applyFileMutation(event, workspaceRoot) {
|
|
|
80
89
|
logger.warn(`Refusing to apply mutation with invalid path: ${event.path}`);
|
|
81
90
|
return false;
|
|
82
91
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
if (isSensitivePath(relativePath)) {
|
|
93
|
+
logger.warn(`Refusing to apply mutation to sensitive path: ${path.basename(relativePath)}`);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
let absPath;
|
|
97
|
+
try {
|
|
98
|
+
absPath = resolveWorkspacePath(workspaceRoot, relativePath, { allowMissing: event.action !== 'delete' });
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
87
101
|
logger.warn(`Refusing to apply mutation outside workspace: ${event.path}`);
|
|
88
102
|
return false;
|
|
89
103
|
}
|
|
@@ -115,7 +129,7 @@ export class WorkspaceWatcher {
|
|
|
115
129
|
onFileChange;
|
|
116
130
|
_ready = false;
|
|
117
131
|
constructor(options) {
|
|
118
|
-
this.workspaceRoot = path.resolve(options.workspaceRoot);
|
|
132
|
+
this.workspaceRoot = fs.realpathSync(path.resolve(options.workspaceRoot));
|
|
119
133
|
this.onFileChange = options.onFileChange;
|
|
120
134
|
}
|
|
121
135
|
start() {
|
|
@@ -132,6 +146,7 @@ export class WorkspaceWatcher {
|
|
|
132
146
|
interval: 100,
|
|
133
147
|
binaryInterval: 300,
|
|
134
148
|
depth: 50, // Limit traversal depth
|
|
149
|
+
followSymlinks: false,
|
|
135
150
|
});
|
|
136
151
|
this.watcher
|
|
137
152
|
.on('ready', () => {
|
|
@@ -183,9 +198,16 @@ export class WorkspaceWatcher {
|
|
|
183
198
|
const ext = path.extname(filePath).toLowerCase();
|
|
184
199
|
if (BINARY_EXTENSIONS.has(ext))
|
|
185
200
|
return;
|
|
186
|
-
const relativePath = path.relative(this.workspaceRoot, filePath);
|
|
187
|
-
if (relativePath
|
|
188
|
-
return;
|
|
201
|
+
const relativePath = path.relative(this.workspaceRoot, filePath).replace(/\\/g, '/');
|
|
202
|
+
if (isSensitivePath(relativePath))
|
|
203
|
+
return;
|
|
204
|
+
try {
|
|
205
|
+
resolveWorkspacePath(this.workspaceRoot, relativePath, { allowMissing: action === 'delete' });
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
logger.warn(`Refusing to synchronize path outside workspace: ${relativePath}`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
189
211
|
if (action === 'delete') {
|
|
190
212
|
this.onFileChange?.(relativePath, null, 'delete');
|
|
191
213
|
return;
|
|
@@ -195,6 +217,8 @@ export class WorkspaceWatcher {
|
|
|
195
217
|
if (stat.size > MAX_SYNC_FILE_BYTES)
|
|
196
218
|
return;
|
|
197
219
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
220
|
+
if (containsHighConfidenceSecret(content))
|
|
221
|
+
return;
|
|
198
222
|
this.onFileChange?.(relativePath, content, 'write');
|
|
199
223
|
}
|
|
200
224
|
catch {
|
|
@@ -216,7 +240,8 @@ export class WorkspaceWSClient {
|
|
|
216
240
|
if (this.ws)
|
|
217
241
|
return;
|
|
218
242
|
const url = `${this.opts.serverUrl}/ws/workspace`;
|
|
219
|
-
|
|
243
|
+
assertTrustedWebSocketEndpoint(url, 'v3', Boolean(this.opts.token));
|
|
244
|
+
this.ws = new WebSocket(url, { handshakeTimeout: 10_000 });
|
|
220
245
|
this.ws.on('open', () => {
|
|
221
246
|
this._connected = true;
|
|
222
247
|
this._send({
|
package/install.ps1
CHANGED
|
@@ -8,26 +8,44 @@ $ErrorActionPreference = "Stop"
|
|
|
8
8
|
$CLI_VERSION = "1.13.20"
|
|
9
9
|
$INSTALL_DIR = "$env:USERPROFILE\.vigthoria"
|
|
10
10
|
$NPM_PACKAGE = "vigthoria-cli"
|
|
11
|
-
$GIT_PACKAGE_URL = "git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
|
|
12
11
|
$MANIFEST_URL = "https://extension.vigthoria.io/downloads/manifest.json"
|
|
13
12
|
$HOSTED_TARBALL_URL = "https://extension.vigthoria.io/downloads/vigthoria-cli-$CLI_VERSION.tgz"
|
|
13
|
+
$HOSTED_TARBALL_SHA256 = ""
|
|
14
|
+
$RELEASE_RESOLVER = Join-Path $PSScriptRoot "scripts\release\resolve-release-manifest.mjs"
|
|
15
|
+
$RELEASE_INSTALLER = Join-Path $PSScriptRoot "scripts\release\install-release.mjs"
|
|
16
|
+
|
|
17
|
+
function Assert-TrustedReleaseUrl([string]$Value) {
|
|
18
|
+
$allowed = @(
|
|
19
|
+
"extension.vigthoria.io", "landing.vigthoria.io", "cli.vigthoria.io",
|
|
20
|
+
"coder.vigthoria.io", "market.vigthoria.io", "registry.npmjs.org"
|
|
21
|
+
)
|
|
22
|
+
try { $uri = [Uri]$Value } catch { throw "Invalid release URL" }
|
|
23
|
+
if ($uri.Scheme -ne "https" -or -not $uri.IsDefaultPort -or $uri.UserInfo -or $allowed -notcontains $uri.DnsSafeHost.ToLowerInvariant() -or $Value.Contains("\")) {
|
|
24
|
+
throw "Release URL must use HTTPS on an exact approved host and port"
|
|
25
|
+
}
|
|
26
|
+
return $uri.AbsoluteUri
|
|
27
|
+
}
|
|
14
28
|
|
|
15
29
|
function Resolve-ReleaseManifest {
|
|
30
|
+
# The hosted path is enabled only when the packaged shared policy verifier
|
|
31
|
+
# can validate strict metadata and the detached Ed25519 signature.
|
|
32
|
+
if (-not (Test-Path $RELEASE_RESOLVER)) { return }
|
|
16
33
|
try {
|
|
17
|
-
$
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
$
|
|
21
|
-
if ($
|
|
22
|
-
$script:CLI_VERSION = [string]$
|
|
34
|
+
$trustedManifest = Assert-TrustedReleaseUrl $MANIFEST_URL
|
|
35
|
+
$resolvedJson = & node $RELEASE_RESOLVER $trustedManifest stable
|
|
36
|
+
if ($LASTEXITCODE -ne 0) { throw "release resolver exited with status $LASTEXITCODE" }
|
|
37
|
+
$resolved = $resolvedJson | ConvertFrom-Json
|
|
38
|
+
if ($resolved.version) {
|
|
39
|
+
$script:CLI_VERSION = [string]$resolved.version
|
|
40
|
+
}
|
|
41
|
+
if ($resolved.url) {
|
|
42
|
+
$script:HOSTED_TARBALL_URL = Assert-TrustedReleaseUrl ([string]$resolved.url)
|
|
23
43
|
}
|
|
24
|
-
if ($
|
|
25
|
-
$script:
|
|
26
|
-
} elseif ($stable.version) {
|
|
27
|
-
$script:HOSTED_TARBALL_URL = "https://extension.vigthoria.io/downloads/vigthoria-cli-$($stable.version).tgz"
|
|
44
|
+
if ($resolved.sha256 -and ([string]$resolved.sha256) -match '^[a-fA-F0-9]{64}$') {
|
|
45
|
+
$script:HOSTED_TARBALL_SHA256 = ([string]$resolved.sha256).ToLowerInvariant()
|
|
28
46
|
}
|
|
29
47
|
} catch {
|
|
30
|
-
Write-Host "
|
|
48
|
+
Write-Host "Signed release manifest unavailable, using exact pinned fallback $CLI_VERSION" -ForegroundColor Yellow
|
|
31
49
|
}
|
|
32
50
|
}
|
|
33
51
|
|
|
@@ -48,7 +66,8 @@ function Test-NetworkConnectivity {
|
|
|
48
66
|
Write-Host "[CHECK] Checking network connectivity..." -ForegroundColor Yellow
|
|
49
67
|
|
|
50
68
|
try {
|
|
51
|
-
$
|
|
69
|
+
$trustedTarball = Assert-TrustedReleaseUrl $HOSTED_TARBALL_URL
|
|
70
|
+
$response = Invoke-WebRequest -Uri $trustedTarball -Method Head -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 10 -ErrorAction Stop
|
|
52
71
|
Write-Host "[OK] Hosted CLI package is reachable" -ForegroundColor Green
|
|
53
72
|
return $true
|
|
54
73
|
}
|
|
@@ -57,7 +76,7 @@ function Test-NetworkConnectivity {
|
|
|
57
76
|
}
|
|
58
77
|
|
|
59
78
|
try {
|
|
60
|
-
$response = Invoke-WebRequest -Uri "https://registry.npmjs.org/vigthoria-cli" -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
|
|
79
|
+
$response = Invoke-WebRequest -Uri "https://registry.npmjs.org/vigthoria-cli" -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 10 -ErrorAction Stop
|
|
61
80
|
Write-Host "[OK] npm registry is reachable" -ForegroundColor Green
|
|
62
81
|
return $true
|
|
63
82
|
}
|
|
@@ -110,35 +129,78 @@ function Test-Prerequisites {
|
|
|
110
129
|
return $true
|
|
111
130
|
}
|
|
112
131
|
|
|
132
|
+
function Get-VigthoriaTempRoot {
|
|
133
|
+
$explicitRoot = $env:VIGTHORIA_TEMP_DIR
|
|
134
|
+
$candidate = if ($explicitRoot) { $explicitRoot } else { Join-Path $env:USERPROFILE ".vigthoria\tmp" }
|
|
135
|
+
if (-not [IO.Path]::IsPathRooted($candidate)) { throw "VIGTHORIA_TEMP_DIR must be an absolute local path" }
|
|
136
|
+
if ($candidate.StartsWith("\\") -or $candidate.StartsWith("\\?\") -or $candidate.StartsWith("\\.\")) {
|
|
137
|
+
throw "VIGTHORIA_TEMP_DIR cannot use a UNC or Windows device path"
|
|
138
|
+
}
|
|
139
|
+
$fullRoot = [IO.Path]::GetFullPath($candidate).TrimEnd([IO.Path]::DirectorySeparatorChar)
|
|
140
|
+
$volumeRoot = [IO.Path]::GetPathRoot($fullRoot).TrimEnd([IO.Path]::DirectorySeparatorChar)
|
|
141
|
+
if ($fullRoot -eq $volumeRoot -or $fullRoot -eq [IO.Path]::GetTempPath().TrimEnd([IO.Path]::DirectorySeparatorChar)) {
|
|
142
|
+
throw "Refusing shared or filesystem-root temporary storage"
|
|
143
|
+
}
|
|
144
|
+
New-Item -ItemType Directory -Path $fullRoot -Force -ErrorAction Stop | Out-Null
|
|
145
|
+
$cursor = Get-Item -LiteralPath $fullRoot -Force -ErrorAction Stop
|
|
146
|
+
while ($cursor) {
|
|
147
|
+
if (($cursor.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) {
|
|
148
|
+
throw "Refusing a reparse-point temporary storage path"
|
|
149
|
+
}
|
|
150
|
+
if ($cursor.FullName -eq [IO.Path]::GetPathRoot($cursor.FullName)) { break }
|
|
151
|
+
$cursor = $cursor.Parent
|
|
152
|
+
}
|
|
153
|
+
if (-not $explicitRoot) {
|
|
154
|
+
$homeRoot = [IO.Path]::GetFullPath($env:USERPROFILE).TrimEnd([IO.Path]::DirectorySeparatorChar)
|
|
155
|
+
if (-not ($fullRoot.Equals($homeRoot, [StringComparison]::OrdinalIgnoreCase) -or $fullRoot.StartsWith($homeRoot + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase))) {
|
|
156
|
+
throw "Default temporary storage escaped the user profile"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return $fullRoot
|
|
160
|
+
}
|
|
161
|
+
|
|
113
162
|
function Install-VigthoriaCLI-NPM {
|
|
114
163
|
Write-Host ""
|
|
115
164
|
Write-Host "[INSTALL] Installing Vigthoria CLI..." -ForegroundColor Cyan
|
|
116
165
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
166
|
+
if ($HOSTED_TARBALL_SHA256) {
|
|
167
|
+
$releaseTemp = Join-Path (Get-VigthoriaTempRoot) ("install-" + [Guid]::NewGuid().ToString("N"))
|
|
168
|
+
$releaseArchive = Join-Path $releaseTemp "candidate.tgz"
|
|
169
|
+
try {
|
|
170
|
+
New-Item -ItemType Directory -Path $releaseTemp -Force | Out-Null
|
|
171
|
+
$trustedTarball = Assert-TrustedReleaseUrl $HOSTED_TARBALL_URL
|
|
172
|
+
Invoke-WebRequest -Uri $trustedTarball -OutFile $releaseArchive -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 60 -ErrorAction Stop
|
|
173
|
+
$actualSha256 = (Get-FileHash -Path $releaseArchive -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
174
|
+
if ($actualSha256 -ne $HOSTED_TARBALL_SHA256) { throw "Release checksum mismatch" }
|
|
175
|
+
if (-not (Test-Path $RELEASE_INSTALLER)) { throw "Transactional release installer is unavailable" }
|
|
176
|
+
& node $RELEASE_INSTALLER $releaseArchive $CLI_VERSION
|
|
177
|
+
if ($LASTEXITCODE -ne 0) { throw "transactional installer exited with status $LASTEXITCODE" }
|
|
178
|
+
Write-Host "[OK] Vigthoria CLI installed from the checksum-verified release!" -ForegroundColor Green
|
|
179
|
+
return $true
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
Write-Host "[WARN] Verified hosted package install failed, trying npm registry: $_" -ForegroundColor Yellow
|
|
183
|
+
}
|
|
184
|
+
finally {
|
|
185
|
+
if (Test-Path $releaseTemp) { Remove-Item -Recurse -Force $releaseTemp }
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
Write-Host "[WARN] Hosted package has no trusted manifest SHA-256; skipping direct URL installation." -ForegroundColor Yellow
|
|
124
189
|
}
|
|
125
190
|
|
|
126
191
|
try {
|
|
127
|
-
|
|
192
|
+
if (Test-Path $RELEASE_INSTALLER) {
|
|
193
|
+
& node $RELEASE_INSTALLER "$NPM_PACKAGE@$CLI_VERSION" $CLI_VERSION
|
|
194
|
+
if ($LASTEXITCODE -ne 0) { throw "transactional installer exited with status $LASTEXITCODE" }
|
|
195
|
+
} else {
|
|
196
|
+
npm install -g --registry=https://registry.npmjs.org/ "$NPM_PACKAGE@$CLI_VERSION"
|
|
197
|
+
if ($LASTEXITCODE -ne 0) { throw "npm exited with status $LASTEXITCODE" }
|
|
198
|
+
}
|
|
128
199
|
Write-Host "[OK] Vigthoria CLI installed successfully!" -ForegroundColor Green
|
|
129
200
|
return $true
|
|
130
201
|
}
|
|
131
202
|
catch {
|
|
132
|
-
Write-Host "[
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
npm install -g $GIT_PACKAGE_URL
|
|
137
|
-
Write-Host "[OK] Vigthoria CLI installed successfully from git package!" -ForegroundColor Green
|
|
138
|
-
return $true
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
Write-Host "[ERROR] Install failed (hosted package + npm registry + git package): $_" -ForegroundColor Red
|
|
203
|
+
Write-Host "[ERROR] Install failed: no checksum-verified artifact or exact npm release $CLI_VERSION is available: $_" -ForegroundColor Red
|
|
142
204
|
return $false
|
|
143
205
|
}
|
|
144
206
|
}
|
|
@@ -146,58 +208,18 @@ function Install-VigthoriaCLI-NPM {
|
|
|
146
208
|
function Install-VigthoriaCLI-Direct {
|
|
147
209
|
Write-Host ""
|
|
148
210
|
Write-Host "[INSTALL] Installing Vigthoria CLI (Direct Download)..." -ForegroundColor Cyan
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (-not (Test-Path $INSTALL_DIR)) {
|
|
152
|
-
New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
$tarballUrl = $HOSTED_TARBALL_URL
|
|
156
|
-
$tarballPath = "$INSTALL_DIR\vigthoria-cli.tgz"
|
|
157
|
-
$extractPath = "$INSTALL_DIR\cli"
|
|
158
|
-
|
|
211
|
+
$releaseTemp = Join-Path (Get-VigthoriaTempRoot) ("direct-" + [Guid]::NewGuid().ToString("N"))
|
|
212
|
+
$tarballPath = Join-Path $releaseTemp "candidate.tgz"
|
|
159
213
|
try {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
New-Item -ItemType Directory -Path $extractPath -Force | Out-Null
|
|
170
|
-
|
|
171
|
-
# Use tar to extract (available in Windows 10+)
|
|
172
|
-
tar -xzf $tarballPath -C $extractPath
|
|
173
|
-
|
|
174
|
-
# The tarball extracts to a 'package' folder
|
|
175
|
-
$packagePath = "$extractPath\package"
|
|
176
|
-
|
|
177
|
-
# Install dependencies
|
|
178
|
-
Write-Host " Installing dependencies..." -ForegroundColor Gray
|
|
179
|
-
Push-Location $packagePath
|
|
180
|
-
npm install --production
|
|
181
|
-
Pop-Location
|
|
182
|
-
|
|
183
|
-
# Create batch file wrapper
|
|
184
|
-
$batContent = @"
|
|
185
|
-
@echo off
|
|
186
|
-
node "$packagePath\dist\index.js" %*
|
|
187
|
-
"@
|
|
188
|
-
Set-Content -Path "$INSTALL_DIR\vigthoria.bat" -Value $batContent
|
|
189
|
-
Set-Content -Path "$INSTALL_DIR\vig.bat" -Value $batContent
|
|
190
|
-
|
|
191
|
-
# Add to PATH if not already there
|
|
192
|
-
$userPath = [Environment]::GetEnvironmentVariable("PATH", "User")
|
|
193
|
-
if ($userPath -notlike "*$INSTALL_DIR*") {
|
|
194
|
-
[Environment]::SetEnvironmentVariable("PATH", "$userPath;$INSTALL_DIR", "User")
|
|
195
|
-
Write-Host " Added $INSTALL_DIR to PATH" -ForegroundColor Gray
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
# Cleanup
|
|
199
|
-
Remove-Item $tarballPath -Force
|
|
200
|
-
|
|
214
|
+
if (-not $HOSTED_TARBALL_SHA256) { throw "Direct installation requires a signed manifest SHA-256" }
|
|
215
|
+
if (-not (Test-Path $RELEASE_INSTALLER)) { throw "Transactional release installer is unavailable" }
|
|
216
|
+
New-Item -ItemType Directory -Path $releaseTemp -ErrorAction Stop | Out-Null
|
|
217
|
+
$tarballUrl = Assert-TrustedReleaseUrl $HOSTED_TARBALL_URL
|
|
218
|
+
Invoke-WebRequest -Uri $tarballUrl -OutFile $tarballPath -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 60 -ErrorAction Stop
|
|
219
|
+
$actualSha256 = (Get-FileHash -Path $tarballPath -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
220
|
+
if ($actualSha256 -ne $HOSTED_TARBALL_SHA256) { throw "Release checksum mismatch" }
|
|
221
|
+
& node $RELEASE_INSTALLER $tarballPath $CLI_VERSION
|
|
222
|
+
if ($LASTEXITCODE -ne 0) { throw "transactional installer exited with status $LASTEXITCODE" }
|
|
201
223
|
Write-Host "[OK] Vigthoria CLI installed successfully!" -ForegroundColor Green
|
|
202
224
|
return $true
|
|
203
225
|
}
|
|
@@ -205,51 +227,8 @@ node "$packagePath\dist\index.js" %*
|
|
|
205
227
|
Write-Host "[ERROR] Direct install failed: $_" -ForegroundColor Red
|
|
206
228
|
return $false
|
|
207
229
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
function Install-VigthoriaCLI-GitHub {
|
|
211
|
-
Write-Host ""
|
|
212
|
-
Write-Host "[INSTALL] Installing Vigthoria CLI (from Vigthoria Market)..." -ForegroundColor Cyan
|
|
213
|
-
|
|
214
|
-
# Create install directory
|
|
215
|
-
if (-not (Test-Path $INSTALL_DIR)) {
|
|
216
|
-
New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
$clonePath = "$INSTALL_DIR\cli"
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
# Check if git is available
|
|
223
|
-
$gitVersion = git --version 2>$null
|
|
224
|
-
if (-not $gitVersion) {
|
|
225
|
-
Write-Host "[ERROR] Git is not installed" -ForegroundColor Red
|
|
226
|
-
return $false
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
# Clone repository
|
|
230
|
-
if (Test-Path $clonePath) {
|
|
231
|
-
Remove-Item -Recurse -Force $clonePath
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
Write-Host " Cloning from Vigthoria Market..." -ForegroundColor Gray
|
|
235
|
-
git clone --depth 1 https://market.vigthoria.io/vigthoria/vigthoria-cli.git $clonePath
|
|
236
|
-
|
|
237
|
-
# Install and build
|
|
238
|
-
Push-Location $clonePath
|
|
239
|
-
Write-Host " Installing dependencies..." -ForegroundColor Gray
|
|
240
|
-
npm install
|
|
241
|
-
Write-Host " Building..." -ForegroundColor Gray
|
|
242
|
-
npm run build
|
|
243
|
-
Write-Host " Linking globally..." -ForegroundColor Gray
|
|
244
|
-
npm link
|
|
245
|
-
Pop-Location
|
|
246
|
-
|
|
247
|
-
Write-Host "[OK] Vigthoria CLI installed successfully!" -ForegroundColor Green
|
|
248
|
-
return $true
|
|
249
|
-
}
|
|
250
|
-
catch {
|
|
251
|
-
Write-Host "[ERROR] Git install failed: $_" -ForegroundColor Red
|
|
252
|
-
return $false
|
|
230
|
+
finally {
|
|
231
|
+
if (Test-Path $releaseTemp) { Remove-Item -Recurse -Force $releaseTemp }
|
|
253
232
|
}
|
|
254
233
|
}
|
|
255
234
|
|
|
@@ -268,17 +247,13 @@ function Show-NetworkTroubleshooting {
|
|
|
268
247
|
Write-Host " npm config set proxy http://proxy.company.com:8080" -ForegroundColor Gray
|
|
269
248
|
Write-Host " npm config set https-proxy http://proxy.company.com:8080" -ForegroundColor Gray
|
|
270
249
|
Write-Host ""
|
|
271
|
-
Write-Host "3.
|
|
272
|
-
Write-Host " npm config set registry https://registry.npmmirror.com" -ForegroundColor Gray
|
|
273
|
-
Write-Host ""
|
|
274
|
-
Write-Host "4. Check Windows Firewall/Antivirus settings" -ForegroundColor Cyan
|
|
250
|
+
Write-Host "3. Check Windows Firewall/Antivirus settings" -ForegroundColor Cyan
|
|
275
251
|
Write-Host ""
|
|
276
|
-
Write-Host "
|
|
252
|
+
Write-Host "4. Try using a VPN" -ForegroundColor Cyan
|
|
277
253
|
Write-Host ""
|
|
278
|
-
Write-Host "
|
|
254
|
+
Write-Host "5. Manual download alternative:" -ForegroundColor Cyan
|
|
279
255
|
Write-Host " Hosted package: $HOSTED_TARBALL_URL" -ForegroundColor Gray
|
|
280
256
|
Write-Host " npm package: https://www.npmjs.com/package/vigthoria-cli" -ForegroundColor Gray
|
|
281
|
-
Write-Host " git package: $GIT_PACKAGE_URL" -ForegroundColor Gray
|
|
282
257
|
Write-Host ""
|
|
283
258
|
}
|
|
284
259
|
|
|
@@ -325,21 +300,19 @@ if ($networkOk) {
|
|
|
325
300
|
# Network failed or npm install failed
|
|
326
301
|
Show-NetworkTroubleshooting
|
|
327
302
|
|
|
328
|
-
Write-Host "Would you like to try
|
|
329
|
-
$choice = Read-Host "Enter 'y' to try direct download
|
|
303
|
+
Write-Host "Would you like to try the checksum-verified direct download?" -ForegroundColor Yellow
|
|
304
|
+
$choice = Read-Host "Enter 'y' to try direct download or 'n' to exit"
|
|
330
305
|
|
|
331
306
|
switch ($choice.ToLower()) {
|
|
332
307
|
'y' {
|
|
333
308
|
if (Install-VigthoriaCLI-Direct) {
|
|
334
309
|
Show-Success
|
|
310
|
+
exit 0
|
|
335
311
|
}
|
|
336
|
-
|
|
337
|
-
'g' {
|
|
338
|
-
if (Install-VigthoriaCLI-GitHub) {
|
|
339
|
-
Show-Success
|
|
340
|
-
}
|
|
312
|
+
exit 1
|
|
341
313
|
}
|
|
342
314
|
default {
|
|
343
315
|
Write-Host "Installation cancelled." -ForegroundColor Gray
|
|
316
|
+
exit 1
|
|
344
317
|
}
|
|
345
318
|
}
|