vigthoria-cli 1.13.34 → 1.13.42

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 (51) hide show
  1. package/README.md +11 -56
  2. package/SECURITY_HARDENING.md +2 -4
  3. package/dist/commands/auth.js +16 -14
  4. package/dist/commands/cancel.d.ts +1 -0
  5. package/dist/commands/cancel.js +21 -4
  6. package/dist/commands/chat.d.ts +13 -0
  7. package/dist/commands/chat.js +170 -14
  8. package/dist/commands/fork.js +8 -3
  9. package/dist/commands/history.js +8 -3
  10. package/dist/commands/legion.js +1 -1
  11. package/dist/commands/replay.js +8 -3
  12. package/dist/commands/update-registration.js +63 -206
  13. package/dist/commands/v4-menu.d.ts +0 -1
  14. package/dist/commands/v4-menu.js +8 -6
  15. package/dist/commands/v4-registration.js +0 -2
  16. package/dist/commands/v4.js +9 -4
  17. package/dist/commands/wallet.d.ts +1 -1
  18. package/dist/commands/wallet.js +3 -3
  19. package/dist/index.js +2 -3
  20. package/dist/utils/agent-stream-state.d.ts +7 -0
  21. package/dist/utils/agent-stream-state.js +31 -0
  22. package/dist/utils/agentRunOutcome.js +5 -1
  23. package/dist/utils/api.d.ts +19 -4
  24. package/dist/utils/api.js +322 -550
  25. package/dist/utils/frontend-preview-service.d.ts +10 -1
  26. package/dist/utils/frontend-preview-service.js +162 -17
  27. package/dist/utils/javascript-syntax.d.ts +19 -0
  28. package/dist/utils/javascript-syntax.js +35 -0
  29. package/dist/utils/localTestMode.js +1 -1
  30. package/dist/utils/mutation-journal.d.ts +10 -0
  31. package/dist/utils/mutation-journal.js +104 -76
  32. package/dist/utils/network-policy.js +7 -10
  33. package/dist/utils/preview-screenshot-adapter.d.ts +81 -0
  34. package/dist/utils/preview-screenshot-adapter.js +615 -38
  35. package/dist/utils/release-install.d.ts +0 -1
  36. package/dist/utils/release-install.js +44 -7
  37. package/dist/utils/requestIntent.d.ts +1 -1
  38. package/dist/utils/requestIntent.js +17 -3
  39. package/dist/utils/tools.js +21 -15
  40. package/dist/utils/update-policy.d.ts +0 -4
  41. package/dist/utils/update-policy.js +5 -9
  42. package/dist/utils/v3-agent-client.js +25 -11
  43. package/install.ps1 +30 -50
  44. package/install.sh +13 -24
  45. package/package.json +4 -2
  46. package/release-policy.json +1 -5
  47. package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +6 -7
  48. package/scripts/release/install-release.mjs +5 -4
  49. package/scripts/release/publish-cli-release.mjs +21 -8
  50. package/scripts/release/test-balanced-model-live.sh +4 -1
  51. package/scripts/release/validate-live-service-gates.sh +27 -5
@@ -8,6 +8,7 @@ Use this checklist on real user machines before and after rollout. The goal is t
8
8
  - [ ] `npm` available
9
9
  - [ ] No stale shell aliases shadowing `vigthoria`
10
10
  - [ ] Network access to:
11
+ - `https://extension.vigthoria.io`
11
12
  - `https://coder.vigthoria.io`
12
13
  - `https://api.vigthoria.io`
13
14
  - [ ] If running browser runtime proofs: Microsoft Edge, Chrome, or Chromium is installed in a standard OS location
@@ -29,7 +30,7 @@ which vigthoria || where.exe vigthoria
29
30
  Commands:
30
31
 
31
32
  ```bash
32
- npm install -g vigthoria-cli@latest
33
+ curl -fsSL https://extension.vigthoria.io/downloads/install.sh | bash
33
34
  vigthoria --version
34
35
  vigthoria doctor
35
36
  ```
@@ -98,7 +99,7 @@ Expected:
98
99
  ## 6. Update Path
99
100
 
100
101
  - [ ] Update check works
101
- - [ ] Upgrade path works from npm/manifest
102
+ - [ ] Upgrade path works from the signed extension manifest
102
103
 
103
104
  Commands:
104
105
 
@@ -139,11 +140,9 @@ These are external dependencies, not CLI code regressions:
139
140
  - [ ] One-command rollback documented
140
141
  - [ ] Support note prepared for users
141
142
 
142
- Example rollback:
143
-
144
- ```bash
145
- npm install -g vigthoria-cli@<known-good-version>
146
- ```
143
+ Rollback must use an approved, previously signed archive retained on the
144
+ canonical extension origin and a separately authorized recovery procedure;
145
+ the public updater does not permit client-selected downgrades.
147
146
 
148
147
  ## 10. Signoff Template
149
148
 
@@ -3,8 +3,9 @@ import { installReleaseTransaction } from '../../dist/utils/release-install.js';
3
3
 
4
4
  const packageSpec = String(process.argv[2] || '');
5
5
  const expectedVersion = String(process.argv[3] || '');
6
- if (!packageSpec || !expectedVersion) throw new Error('Usage: install-release.mjs <package-spec> <expected-version>');
7
- const result = installReleaseTransaction(packageSpec, expectedVersion, {
8
- ...(packageSpec.startsWith('vigthoria-cli@') ? { npmRegistry: 'https://registry.npmjs.org/' } : {}),
9
- });
6
+ if (!packageSpec || !expectedVersion) throw new Error('Usage: install-release.mjs <local-package.tgz> <expected-version>');
7
+ if (!packageSpec.toLowerCase().endsWith('.tgz')) {
8
+ throw new Error('Release installer accepts only a locally verified .tgz archive');
9
+ }
10
+ const result = installReleaseTransaction(packageSpec, expectedVersion);
10
11
  process.stdout.write(`${JSON.stringify(result)}\n`);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
- import { createHash, createPrivateKey, createPublicKey, sign } from 'node:crypto';
4
+ import { createHash } from 'node:crypto';
5
5
  import { spawnSync } from 'node:child_process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import {
@@ -16,7 +16,7 @@ const version = String(process.argv[2] || '').trim();
16
16
  const channel = String(process.env.CHANNEL || 'stable').trim();
17
17
  const downloadsDirectory = String(process.env.HOST_DOWNLOADS_DIR || '');
18
18
  const manifestFile = String(process.env.HOST_MANIFEST_FILE || '');
19
- const privateKeyFile = String(process.env.RELEASE_SIGNING_PRIVATE_KEY_FILE || '');
19
+ const signerCommand = String(process.env.RELEASE_SIGNER_COMMAND || '');
20
20
  const keyId = String(process.env.RELEASE_SIGNING_KEY_ID || '');
21
21
  const sbomFile = String(process.env.RELEASE_SBOM_FILE || '');
22
22
  const provenanceFile = String(process.env.RELEASE_PROVENANCE_FILE || '');
@@ -39,7 +39,11 @@ function exactPackageMetadata(archive) {
39
39
 
40
40
  if (!version) stop('Usage: publish-cli-release.sh <version>');
41
41
  if (!downloadsDirectory || !manifestFile) stop('HOST_DOWNLOADS_DIR and HOST_MANIFEST_FILE are required.');
42
- requiredFile(privateKeyFile, 'RELEASE_SIGNING_PRIVATE_KEY_FILE');
42
+ if (!path.isAbsolute(signerCommand)) stop('RELEASE_SIGNER_COMMAND must name an absolute protected signer executable.');
43
+ const signerStat = fs.statSync(signerCommand, { throwIfNoEntry: false });
44
+ if (!signerStat?.isFile() || signerStat.uid !== 0 || (signerStat.mode & 0o022) !== 0 || (signerStat.mode & 0o111) === 0) {
45
+ stop('RELEASE_SIGNER_COMMAND must be a root-owned executable that is not group/world writable.');
46
+ }
43
47
  requiredFile(sbomFile, 'RELEASE_SBOM_FILE');
44
48
  requiredFile(provenanceFile, 'RELEASE_PROVENANCE_FILE');
45
49
  if (!Object.hasOwn(policy.signature.trustedKeys, keyId)) stop(`RELEASE_SIGNING_KEY_ID is not trusted by release-policy.json: ${keyId || '(unset)'}`);
@@ -85,11 +89,20 @@ try {
85
89
  provenance: { url: new URL(provenanceFilename, publicBase).toString(), sha256: digest(provenanceFile) },
86
90
  notes: String(process.env.RELEASE_NOTES || 'Vigthoria CLI release'),
87
91
  };
88
- const privateKey = createPrivateKey(fs.readFileSync(privateKeyFile));
89
- const configuredPublic = createPublicKey(policy.signature.trustedKeys[keyId]).export({ type: 'spki', format: 'der' });
90
- const signingPublic = createPublicKey(privateKey).export({ type: 'spki', format: 'der' });
91
- if (!configuredPublic.equals(signingPublic)) stop('Signing private key does not match the configured verification key.');
92
- const detached = sign(null, releaseSignaturePayload(channel, entry), privateKey).toString('base64');
92
+ const signingResult = spawnSync(signerCommand, ['--key-id', keyId], {
93
+ input: releaseSignaturePayload(channel, entry),
94
+ encoding: 'utf8',
95
+ timeout: 30_000,
96
+ maxBuffer: 16 * 1024,
97
+ env: {
98
+ PATH: '/usr/sbin:/usr/bin:/sbin:/bin',
99
+ LANG: 'C.UTF-8',
100
+ RELEASE_SIGNING_KEY_ID: keyId,
101
+ },
102
+ });
103
+ if (signingResult.status !== 0) stop('Protected release signer rejected the signing request.');
104
+ const detached = String(signingResult.stdout || '').trim();
105
+ if (!/^[A-Za-z0-9+/]{86}==$/.test(detached)) stop('Protected release signer returned an invalid Ed25519 signature encoding.');
93
106
  verifyReleaseSignature(channel, entry, detached);
94
107
 
95
108
  let manifest = { schemaVersion: policy.manifest.schemaVersion, channels: {} };
@@ -40,6 +40,9 @@ import fs from 'node:fs';
40
40
  const result = JSON.parse(fs.readFileSync(process.env.BALANCED_RESULT, 'utf8'));
41
41
  if (result.success !== true) throw new Error(`balanced probe failed: ${JSON.stringify(result)}`);
42
42
  const allowed = new Set(['Vigthoria-v4-Assistant-9B', 'vigthoria-balanced-4b', 'vigthoria-v3-balanced-4b']);
43
- if (!allowed.has(result.model)) throw new Error(`unexpected balanced model: ${result.model}`);
43
+ const model = result.data?.model ?? result.model;
44
+ if (!allowed.has(model)) throw new Error(`unexpected balanced model: ${model}`);
45
+ if (result.data?.requestedModel !== 'balanced-4b') throw new Error(`balanced alias was not preserved: ${JSON.stringify(result.data)}`);
46
+ if (typeof result.data?.content !== 'string' || !result.data.content.trim()) throw new Error('balanced probe returned empty content');
44
47
  console.log('[pass] credentialed balanced-4b live probe');
45
48
  EOF
@@ -24,12 +24,25 @@ export VIGTHORIA_NO_BANNER=1
24
24
  export VIGTHORIA_NO_UPDATE_CHECK=1
25
25
 
26
26
  echo "[AUTH PREFLIGHT] invalid session message"
27
- VIGTHORIA_AUTH_TOKEN=invalid-token-for-preflight node dist/index.js chat --no-agent --model balanced-4b --prompt "ok" --json >"$LIVE_TMP/auth.json" 2>/dev/null || true
27
+ # This assertion belongs to the public Coder authentication gateway. Release
28
+ # runners also configure local TestFarm transports for the service gates below;
29
+ # do not let those overrides silently turn this into a model-router probe.
30
+ env \
31
+ -u VIGTHORIA_SELF_HOSTED_MODELS_API_URL \
32
+ -u VIGTHORIA_LOCAL_TEST_MODE \
33
+ -u VIGTHORIA_LOCAL_TEST_TOKEN \
34
+ -u VIGTHORIA_ALLOW_LOCAL_SERVICES \
35
+ VIGTHORIA_AUTH_TOKEN=invalid-token-for-preflight \
36
+ node dist/index.js chat --no-agent --model balanced-4b --prompt "ok" --json >"$LIVE_TMP/auth.json" 2>/dev/null || true
28
37
  AUTH_RESULT="$LIVE_TMP/auth.json" node --input-type=module - <<'EOF'
29
38
  import fs from 'node:fs';
30
39
  const result = JSON.parse(fs.readFileSync(process.env.AUTH_RESULT, 'utf8'));
31
40
  const expected = 'Vigthoria Gate way user authentification failed. Please log out and login again.';
32
- if (result.success !== false || result.error !== expected) throw new Error(`unexpected auth preflight: ${JSON.stringify(result)}`);
41
+ const errorMessage = typeof result.error === 'string' ? result.error : result.error?.message;
42
+ const errorCode = typeof result.error === 'object' && result.error !== null ? result.error.code : undefined;
43
+ if (result.success !== false || errorMessage !== expected || (errorCode && errorCode !== 'AUTH_SESSION_INVALID')) {
44
+ throw new Error(`unexpected auth preflight: ${JSON.stringify(result)}`);
45
+ }
33
46
  console.log('[pass] live auth preflight message');
34
47
  EOF
35
48
 
@@ -65,9 +78,18 @@ console.log('[pass] live model inventory gates');
65
78
  EOF
66
79
 
67
80
  echo "[7.5 policy] secured hosted HyperLoop endpoint"
68
- if ! code="$(curl --silent --show-error --connect-timeout 5 --max-time 15 --output /dev/null --write-out '%{http_code}' https://coder.vigthoria.io/api/hyperloop/health)"; then
69
- block "hosted HyperLoop endpoint is unavailable"
70
- fi
81
+ code=""
82
+ for attempt in 1 2 3; do
83
+ if code="$(curl --silent --show-error --connect-timeout 5 --max-time 15 --output /dev/null --write-out '%{http_code}' https://coder.vigthoria.io/api/hyperloop/health)"; then
84
+ break
85
+ fi
86
+ code=""
87
+ if [[ "$attempt" != "3" ]]; then
88
+ echo "[retry] hosted HyperLoop policy probe transient failure ($attempt/3)"
89
+ sleep 2
90
+ fi
91
+ done
92
+ [[ -n "$code" ]] || block "hosted HyperLoop endpoint is unavailable after 3 bounded attempts"
71
93
  echo "unauth_hyperloop_code=$code"
72
94
  [[ "$code" == "401" || "$code" == "302" ]]
73
95