vigthoria-cli 1.13.18 → 1.13.22

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 (185) hide show
  1. package/completions/_vigthoria +49 -0
  2. package/completions/vigthoria.bash +6 -0
  3. package/completions/vigthoria.fish +41 -0
  4. package/dist/commands/auth.d.ts +1 -0
  5. package/dist/commands/auth.js +84 -135
  6. package/dist/commands/background.d.ts +0 -2
  7. package/dist/commands/background.js +26 -34
  8. package/dist/commands/bridge.js +45 -41
  9. package/dist/commands/cancel.d.ts +1 -0
  10. package/dist/commands/cancel.js +22 -16
  11. package/dist/commands/chat.d.ts +5 -42
  12. package/dist/commands/chat.js +462 -1122
  13. package/dist/commands/coding-registration.d.ts +4 -0
  14. package/dist/commands/coding-registration.js +24 -0
  15. package/dist/commands/config.js +32 -42
  16. package/dist/commands/conversation-registration.d.ts +4 -0
  17. package/dist/commands/conversation-registration.js +122 -0
  18. package/dist/commands/deploy.d.ts +8 -2
  19. package/dist/commands/deploy.js +92 -90
  20. package/dist/commands/device.d.ts +1 -2
  21. package/dist/commands/device.js +37 -21
  22. package/dist/commands/doctor-registration.d.ts +4 -0
  23. package/dist/commands/doctor-registration.js +200 -0
  24. package/dist/commands/edit.js +22 -33
  25. package/dist/commands/explain.js +7 -10
  26. package/dist/commands/fork.d.ts +1 -2
  27. package/dist/commands/fork.js +72 -22
  28. package/dist/commands/game.d.ts +1 -1
  29. package/dist/commands/game.js +17 -6
  30. package/dist/commands/generate.js +7 -9
  31. package/dist/commands/history.js +11 -7
  32. package/dist/commands/hub.d.ts +2 -2
  33. package/dist/commands/hub.js +34 -35
  34. package/dist/commands/legion.d.ts +0 -1
  35. package/dist/commands/legion.js +62 -79
  36. package/dist/commands/music.d.ts +1 -2
  37. package/dist/commands/music.js +62 -27
  38. package/dist/commands/platform-registration.d.ts +4 -0
  39. package/dist/commands/platform-registration.js +45 -0
  40. package/dist/commands/preview.d.ts +0 -1
  41. package/dist/commands/preview.js +82 -35
  42. package/dist/commands/product-run-registration.d.ts +4 -0
  43. package/dist/commands/product-run-registration.js +490 -0
  44. package/dist/commands/replay.d.ts +1 -2
  45. package/dist/commands/replay.js +15 -11
  46. package/dist/commands/repo.d.ts +14 -7
  47. package/dist/commands/repo.js +245 -196
  48. package/dist/commands/review.js +9 -12
  49. package/dist/commands/security.d.ts +1 -2
  50. package/dist/commands/security.js +12 -6
  51. package/dist/commands/update-registration.d.ts +3 -0
  52. package/dist/commands/update-registration.js +338 -0
  53. package/dist/commands/v4-registration.d.ts +4 -0
  54. package/dist/commands/v4-registration.js +24 -0
  55. package/dist/commands/v4.d.ts +1 -1
  56. package/dist/commands/v4.js +46 -8
  57. package/dist/commands/wallet.d.ts +1 -3
  58. package/dist/commands/wallet.js +18 -45
  59. package/dist/commands/workflow.d.ts +2 -0
  60. package/dist/commands/workflow.js +52 -39
  61. package/dist/index.js +122 -1498
  62. package/dist/utils/agent-stream-state.d.ts +27 -0
  63. package/dist/utils/agent-stream-state.js +93 -0
  64. package/dist/utils/agentRoute.d.ts +2 -1
  65. package/dist/utils/agentRoute.js +22 -9
  66. package/dist/utils/agentRunOutcome.d.ts +16 -0
  67. package/dist/utils/agentRunOutcome.js +37 -2
  68. package/dist/utils/api-client-factory.d.ts +8 -0
  69. package/dist/utils/api-client-factory.js +8 -0
  70. package/dist/utils/api.d.ts +45 -269
  71. package/dist/utils/api.js +664 -3210
  72. package/dist/utils/auth-session.d.ts +41 -0
  73. package/dist/utils/auth-session.js +224 -0
  74. package/dist/utils/brain-hub-client.d.ts +0 -4
  75. package/dist/utils/brain-hub-client.js +6 -3
  76. package/dist/utils/bridge-client.js +2 -0
  77. package/dist/utils/capability-health-service.d.ts +48 -0
  78. package/dist/utils/capability-health-service.js +64 -0
  79. package/dist/utils/chat-prompt-policy.d.ts +18 -0
  80. package/dist/utils/chat-prompt-policy.js +61 -0
  81. package/dist/utils/chat-tool-call-parser.d.ts +11 -0
  82. package/dist/utils/chat-tool-call-parser.js +71 -0
  83. package/dist/utils/cli-state.d.ts +22 -4
  84. package/dist/utils/cli-state.js +105 -47
  85. package/dist/utils/code-operations-service.d.ts +104 -0
  86. package/dist/utils/code-operations-service.js +837 -0
  87. package/dist/utils/codebase-indexer.d.ts +1 -0
  88. package/dist/utils/codebase-indexer.js +28 -8
  89. package/dist/utils/command-contract.d.ts +61 -0
  90. package/dist/utils/command-contract.js +149 -0
  91. package/dist/utils/command-policy.d.ts +10 -0
  92. package/dist/utils/command-policy.js +54 -0
  93. package/dist/utils/config.d.ts +13 -5
  94. package/dist/utils/config.js +227 -99
  95. package/dist/utils/context-ranker.js +11 -2
  96. package/dist/utils/context-state.d.ts +39 -0
  97. package/dist/utils/context-state.js +52 -0
  98. package/dist/utils/deckEvents.d.ts +0 -5
  99. package/dist/utils/deckEvents.js +3 -2
  100. package/dist/utils/desktop-bridge-client.js +2 -0
  101. package/dist/utils/direct-output-policy.d.ts +3 -0
  102. package/dist/utils/direct-output-policy.js +76 -0
  103. package/dist/utils/durable-json.d.ts +57 -0
  104. package/dist/utils/durable-json.js +319 -0
  105. package/dist/utils/fastAgentRouter.d.ts +6 -7
  106. package/dist/utils/fastAgentRouter.js +21 -30
  107. package/dist/utils/files.js +21 -13
  108. package/dist/utils/frontend-preview-service.d.ts +76 -0
  109. package/dist/utils/frontend-preview-service.js +482 -0
  110. package/dist/utils/goaEvents.d.ts +0 -4
  111. package/dist/utils/goaEvents.js +5 -2
  112. package/dist/utils/logger.d.ts +2 -1
  113. package/dist/utils/logger.js +27 -20
  114. package/dist/utils/mcp-context-client.d.ts +24 -0
  115. package/dist/utils/mcp-context-client.js +58 -0
  116. package/dist/utils/model-governance.d.ts +18 -0
  117. package/dist/utils/model-governance.js +75 -0
  118. package/dist/utils/model-transport-service.d.ts +44 -0
  119. package/dist/utils/model-transport-service.js +111 -0
  120. package/dist/utils/mutation-journal.d.ts +42 -0
  121. package/dist/utils/mutation-journal.js +387 -0
  122. package/dist/utils/network-policy.d.ts +24 -0
  123. package/dist/utils/network-policy.js +202 -0
  124. package/dist/utils/operator-client.d.ts +45 -0
  125. package/dist/utils/operator-client.js +159 -0
  126. package/dist/utils/post-write-validator.js +7 -9
  127. package/dist/utils/preview-screenshot-adapter.d.ts +13 -0
  128. package/dist/utils/preview-screenshot-adapter.js +36 -0
  129. package/dist/utils/process-policy.d.ts +23 -0
  130. package/dist/utils/process-policy.js +284 -0
  131. package/dist/utils/project-memory.d.ts +13 -3
  132. package/dist/utils/project-memory.js +70 -17
  133. package/dist/utils/prompt-workspace-resolver.d.ts +14 -0
  134. package/dist/utils/prompt-workspace-resolver.js +64 -0
  135. package/dist/utils/release-install.d.ts +11 -0
  136. package/dist/utils/release-install.js +155 -0
  137. package/dist/utils/release-policy.d.ts +64 -0
  138. package/dist/utils/release-policy.js +293 -0
  139. package/dist/utils/requestIntent.js +22 -3
  140. package/dist/utils/runtime-capability.d.ts +8 -0
  141. package/dist/utils/runtime-capability.js +16 -0
  142. package/dist/utils/secret-policy.d.ts +20 -0
  143. package/dist/utils/secret-policy.js +160 -0
  144. package/dist/utils/session.d.ts +34 -2
  145. package/dist/utils/session.js +354 -110
  146. package/dist/utils/tool-approval-service.d.ts +17 -0
  147. package/dist/utils/tool-approval-service.js +78 -0
  148. package/dist/utils/tool-capability-providers.d.ts +57 -0
  149. package/dist/utils/tool-capability-providers.js +57 -0
  150. package/dist/utils/tools.d.ts +2 -23
  151. package/dist/utils/tools.js +216 -508
  152. package/dist/utils/update-policy.d.ts +18 -0
  153. package/dist/utils/update-policy.js +137 -0
  154. package/dist/utils/v3-agent-client.d.ts +40 -0
  155. package/dist/utils/v3-agent-client.js +165 -0
  156. package/dist/utils/v3-workspace-service.d.ts +28 -0
  157. package/dist/utils/v3-workspace-service.js +279 -0
  158. package/dist/utils/vigflow-client.d.ts +95 -0
  159. package/dist/utils/vigflow-client.js +105 -0
  160. package/dist/utils/workspace-boundary.d.ts +45 -0
  161. package/dist/utils/workspace-boundary.js +377 -0
  162. package/dist/utils/workspace-brain-service.d.ts +2 -0
  163. package/dist/utils/workspace-brain-service.js +11 -1
  164. package/dist/utils/workspace-cache.js +37 -15
  165. package/dist/utils/workspace-stream.js +35 -10
  166. package/install.ps1 +86 -143
  167. package/install.sh +76 -81
  168. package/package.json +44 -9
  169. package/release-policy.json +43 -0
  170. package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +1 -1
  171. package/scripts/release/generate-completions.mjs +24 -0
  172. package/scripts/release/install-release.mjs +10 -0
  173. package/scripts/release/publish-cli-release.mjs +116 -0
  174. package/scripts/release/publish-cli-release.sh +2 -70
  175. package/scripts/release/resolve-release-manifest.mjs +26 -0
  176. package/scripts/release/test-balanced-model-live.sh +42 -0
  177. package/scripts/release/validate-live-service-gates.sh +90 -0
  178. package/scripts/release/validate-no-go-gates.sh +135 -172
  179. package/scripts/release/verify-runtime-consistency.mjs +4 -1
  180. package/dist/commands/index.d.ts +0 -12
  181. package/dist/commands/index.js +0 -194
  182. package/dist/commands/update.d.ts +0 -9
  183. package/dist/commands/update.js +0 -301
  184. package/dist/utils/templateInstantPath.d.ts +0 -18
  185. package/dist/utils/templateInstantPath.js +0 -228
package/install.sh CHANGED
@@ -26,34 +26,59 @@ else
26
26
  fi
27
27
 
28
28
  # Configuration
29
- CLI_VERSION="1.13.18"
29
+ CLI_VERSION="1.13.20"
30
30
  INSTALL_DIR="$HOME/.vigthoria"
31
- REPO_URL="https://market.vigthoria.io/vigthoria/vigthoria-cli"
32
- GIT_PACKAGE_URL="git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
33
31
  MANIFEST_URL="${VIGTHORIA_UPDATE_MANIFEST_URL:-https://extension.vigthoria.io/downloads/manifest.json}"
34
32
  HOSTED_TARBALL_URL="https://extension.vigthoria.io/downloads/vigthoria-cli-${CLI_VERSION}.tgz"
35
33
  HOSTED_TARBALL_SHA256=""
34
+ INSTALLER_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || true)"
35
+ RELEASE_RESOLVER="$INSTALLER_ROOT/scripts/release/resolve-release-manifest.mjs"
36
+ RELEASE_INSTALLER="$INSTALLER_ROOT/scripts/release/install-release.mjs"
37
+
38
+ validate_release_url() {
39
+ python3 - "$1" <<'PY'
40
+ import sys
41
+ from urllib.parse import urlsplit
42
+ allowed = {
43
+ 'extension.vigthoria.io', 'landing.vigthoria.io', 'cli.vigthoria.io',
44
+ 'coder.vigthoria.io', 'market.vigthoria.io', 'registry.npmjs.org',
45
+ }
46
+ try:
47
+ parsed = urlsplit(sys.argv[1])
48
+ valid = parsed.scheme == 'https' and parsed.hostname in allowed and parsed.port in (None, 443) and not parsed.username and not parsed.password and '\\' not in sys.argv[1]
49
+ except Exception:
50
+ valid = False
51
+ raise SystemExit(0 if valid else 1)
52
+ PY
53
+ }
36
54
 
37
55
  resolve_release_manifest() {
38
- if ! command -v curl >/dev/null 2>&1 || ! command -v python3 >/dev/null 2>&1; then
56
+ # Direct artifacts are accepted only when the packaged shared verifier is
57
+ # present and validates the strict manifest plus detached Ed25519 signature.
58
+ # A curl-piped legacy installer therefore falls back to the exact pinned npm
59
+ # version instead of trusting an unsigned manifest.
60
+ if [[ ! -f "$RELEASE_RESOLVER" ]] || ! command -v node >/dev/null 2>&1 || ! command -v python3 >/dev/null 2>&1; then
39
61
  return 0
40
62
  fi
41
63
 
42
- local manifest_json
43
- manifest_json="$(curl -fsSL "$MANIFEST_URL" 2>/dev/null || true)"
44
- if [[ -z "$manifest_json" ]]; then
64
+ if ! validate_release_url "$MANIFEST_URL"; then
65
+ echo "Refusing untrusted release manifest URL" >&2
66
+ exit 1
67
+ fi
68
+ local resolved_json
69
+ resolved_json="$(node "$RELEASE_RESOLVER" "$MANIFEST_URL" stable 2>/dev/null || true)"
70
+ if [[ -z "$resolved_json" ]]; then
45
71
  return 0
46
72
  fi
47
73
 
48
74
  local resolved
49
- resolved="$(printf '%s' "$manifest_json" | python3 -c "
75
+ resolved="$(printf '%s' "$resolved_json" | python3 -c "
50
76
  import json, sys
51
77
  try:
52
78
  data = json.load(sys.stdin)
53
- stable = (data.get('channels') or {}).get('stable') or {}
54
- version = str(stable.get('version') or '').strip()
55
- url = str(stable.get('url') or '').strip()
56
- sha256 = str(stable.get('sha256') or '').strip().lower()
79
+ version = str(data.get('version') or '').strip()
80
+ url = str(data.get('url') or '').strip()
81
+ sha256 = str(data.get('sha256') or '').strip().lower()
57
82
  if version:
58
83
  print(version)
59
84
  if url:
@@ -74,6 +99,10 @@ except Exception:
74
99
  CLI_VERSION="$manifest_version"
75
100
  fi
76
101
  if [[ -n "$manifest_url" ]]; then
102
+ if ! validate_release_url "$manifest_url"; then
103
+ echo "Refusing untrusted release artifact URL" >&2
104
+ exit 1
105
+ fi
77
106
  HOSTED_TARBALL_URL="$manifest_url"
78
107
  elif [[ -n "$manifest_version" ]]; then
79
108
  HOSTED_TARBALL_URL="https://extension.vigthoria.io/downloads/vigthoria-cli-${CLI_VERSION}.tgz"
@@ -193,7 +222,11 @@ install_cli() {
193
222
  echo "Downloading checksum-verified hosted release package..."
194
223
  RELEASE_TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/vigthoria-cli-install.XXXXXX")"
195
224
  RELEASE_ARCHIVE="$RELEASE_TMP_DIR/vigthoria-cli-${CLI_VERSION}.tgz"
196
- if ! curl -fsSL "$HOSTED_TARBALL_URL" -o "$RELEASE_ARCHIVE"; then
225
+ if ! validate_release_url "$HOSTED_TARBALL_URL"; then
226
+ echo -e "${RED}Refusing untrusted release artifact URL${NC}"
227
+ return 1
228
+ fi
229
+ if ! curl -fsS --proto '=https' --max-redirs 0 "$HOSTED_TARBALL_URL" -o "$RELEASE_ARCHIVE"; then
197
230
  rm -rf "$RELEASE_TMP_DIR"
198
231
  echo -e "${RED}✗ Failed to download verified release package${NC}"
199
232
  exit 1
@@ -212,42 +245,23 @@ install_cli() {
212
245
  echo -e "${RED}✗ Release checksum verification failed${NC}"
213
246
  exit 1
214
247
  fi
215
- npm install -g --force "$RELEASE_ARCHIVE"
248
+ if [[ -f "$RELEASE_INSTALLER" ]]; then
249
+ node "$RELEASE_INSTALLER" "$RELEASE_ARCHIVE" "$CLI_VERSION"
250
+ else
251
+ echo -e "${RED}✗ Transactional release installer is unavailable${NC}"
252
+ exit 1
253
+ fi
216
254
  rm -rf "$RELEASE_TMP_DIR"
217
- elif npm view vigthoria-cli version &> /dev/null; then
218
- echo "Installing from npm registry..."
219
- npm install -g --force vigthoria-cli
220
- elif npm install -g --force "$GIT_PACKAGE_URL"; then
221
- echo "Installed from git package fallback."
222
- else
223
- # Option 2: Install from local or git
224
- echo "Installing from source..."
225
-
226
- # Check if we're in the CLI directory
227
- if [ -f "package.json" ] && grep -q '"name": "vigthoria-cli"' package.json; then
228
- echo "Installing from current directory..."
229
- npm install
230
- npm run build
231
- npm link
255
+ elif npm view --registry=https://registry.npmjs.org/ "vigthoria-cli@${CLI_VERSION}" version &> /dev/null; then
256
+ echo "Installing exact version ${CLI_VERSION} from npm registry..."
257
+ if [[ -f "$RELEASE_INSTALLER" ]]; then
258
+ node "$RELEASE_INSTALLER" "vigthoria-cli@${CLI_VERSION}" "$CLI_VERSION"
232
259
  else
233
- # Clone from repo
234
- echo "Cloning from repository..."
235
- git clone "$REPO_URL" "$INSTALL_DIR/cli" 2>/dev/null || {
236
- echo -e "${YELLOW}Repository not available, using local install${NC}"
237
- # Copy local files for development
238
- SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
239
- if [ -d "$SCRIPT_DIR/../src" ]; then
240
- cp -r "$SCRIPT_DIR/.." "$INSTALL_DIR/cli"
241
- fi
242
- }
243
-
244
- if [ -d "$INSTALL_DIR/cli" ]; then
245
- cd "$INSTALL_DIR/cli"
246
- npm install
247
- npm run build
248
- npm link
249
- fi
260
+ npm install -g --force --registry=https://registry.npmjs.org/ "vigthoria-cli@${CLI_VERSION}"
250
261
  fi
262
+ else
263
+ echo -e "${RED}✗ No checksum-verified artifact or exact npm release ${CLI_VERSION} is available${NC}"
264
+ return 1
251
265
  fi
252
266
 
253
267
  echo -e "${GREEN}✓ Installation complete${NC}"
@@ -280,55 +294,36 @@ create_symlinks() {
280
294
  # Setup shell completion
281
295
  setup_completion() {
282
296
  echo -e "${CYAN}Setting up shell completion...${NC}"
283
-
284
- # Detect shell
297
+ COMPLETION_ROOT="$INSTALLER_ROOT/completions"
298
+ if [[ ! -d "$COMPLETION_ROOT" ]] && [[ -d "$HOME/.vigthoria/cli/current/node_modules/vigthoria-cli/completions" ]]; then
299
+ COMPLETION_ROOT="$HOME/.vigthoria/cli/current/node_modules/vigthoria-cli/completions"
300
+ fi
301
+ if [[ ! -d "$COMPLETION_ROOT" ]]; then
302
+ echo -e "${YELLOW}⚠ Generated completions are unavailable; no stale static list was installed.${NC}"
303
+ return 0
304
+ fi
285
305
  SHELL_NAME=$(basename "$SHELL")
286
-
287
306
  case "$SHELL_NAME" in
288
307
  bash)
289
308
  COMPLETION_FILE="$HOME/.bash_completion.d/vigthoria"
290
309
  mkdir -p "$HOME/.bash_completion.d"
291
- cat > "$COMPLETION_FILE" << 'EOF'
292
- _vigthoria_completions() {
293
- local cur="${COMP_WORDS[COMP_CWORD]}"
294
- local commands="chat edit generate explain fix review login logout status config init"
295
- COMPREPLY=($(compgen -W "$commands" -- "$cur"))
296
- }
297
- complete -F _vigthoria_completions vigthoria
298
- complete -F _vigthoria_completions vig
299
- EOF
310
+ install -m 0644 "$COMPLETION_ROOT/vigthoria.bash" "$COMPLETION_FILE"
300
311
  echo -e "${GREEN}✓ Bash completion installed${NC}"
301
312
  echo " Run: source ~/.bash_completion.d/vigthoria"
302
313
  ;;
303
314
  zsh)
304
315
  COMPLETION_FILE="$HOME/.zsh/completion/_vigthoria"
305
316
  mkdir -p "$HOME/.zsh/completion"
306
- cat > "$COMPLETION_FILE" << 'EOF'
307
- #compdef vigthoria vig
308
-
309
- _vigthoria() {
310
- local -a commands
311
- commands=(
312
- 'chat:Start interactive chat with AI'
313
- 'edit:Edit a file with AI assistance'
314
- 'generate:Generate code from description'
315
- 'explain:Explain code in a file'
316
- 'fix:Fix issues in a file'
317
- 'review:Review code quality'
318
- 'login:Login to Vigthoria'
319
- 'logout:Logout from Vigthoria'
320
- 'status:Show account status'
321
- 'config:Configure settings'
322
- 'init:Initialize project'
323
- )
324
- _describe 'command' commands
325
- }
326
-
327
- _vigthoria "$@"
328
- EOF
317
+ install -m 0644 "$COMPLETION_ROOT/_vigthoria" "$COMPLETION_FILE"
329
318
  echo -e "${GREEN}✓ Zsh completion installed${NC}"
330
319
  echo " Add to ~/.zshrc: fpath=(~/.zsh/completion \$fpath)"
331
320
  ;;
321
+ fish)
322
+ COMPLETION_FILE="$HOME/.config/fish/completions/vigthoria.fish"
323
+ mkdir -p "$HOME/.config/fish/completions"
324
+ install -m 0644 "$COMPLETION_ROOT/vigthoria.fish" "$COMPLETION_FILE"
325
+ echo -e "${GREEN}✓ Fish completion installed${NC}"
326
+ ;;
332
327
  *)
333
328
  echo -e "${YELLOW}⚠ Shell completion not available for $SHELL_NAME${NC}"
334
329
  ;;
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "vigthoria-cli",
3
- "version": "1.13.18",
3
+ "version": "1.13.22",
4
4
  "description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "files": [
8
8
  "dist",
9
+ "completions",
10
+ "release-policy.json",
9
11
  "scripts/release",
10
12
  "README.md",
11
13
  "SECURITY_HARDENING.md",
@@ -16,6 +18,8 @@
16
18
  "publishConfig": {
17
19
  "files": [
18
20
  "dist/",
21
+ "completions/",
22
+ "release-policy.json",
19
23
  "scripts/release/",
20
24
  "README.md",
21
25
  "SECURITY_HARDENING.md",
@@ -32,10 +36,14 @@
32
36
  },
33
37
  "scripts": {
34
38
  "clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
35
- "build": "npm run clean && tsc && node -e \"const fs=require('fs'); try { fs.chmodSync('dist/index.js', 0o755); } catch (error) { if (!error || error.code !== 'ENOENT') throw error; }\"",
39
+ "build": "npm run clean && tsc && node scripts/release/generate-completions.mjs && node -e \"const fs=require('fs'); try { fs.chmodSync('dist/index.js', 0o755); } catch (error) { if (!error || error.code !== 'ENOENT') throw error; }\"",
36
40
  "start": "node dist/index.js",
37
41
  "dev": "ts-node src/index.ts",
38
- "test": "npm run test:cli",
42
+ "test": "npm run test:hermetic",
43
+ "test:hermetic": "npm run validate:no-go",
44
+ "test:integration:local": "npm run build && node scripts/run-test-suite.mjs local",
45
+ "test:live:all": "npm run build && node scripts/run-test-suite.mjs live",
46
+ "test:suite:policy": "node scripts/run-test-suite.mjs check",
39
47
  "test:agent:outcome": "npm run build && node scripts/test-agent-run-outcome.js",
40
48
  "test:cli": "npm run build && npm run precheck:services && node scripts/test-cli-suite.js && npm run test:agent:outcome && npm run test:v3-stream-mutation",
41
49
  "test:regression": "npm run build && node scripts/test-regression-1.6.22.js",
@@ -62,6 +70,8 @@
62
70
  "test:repo:live": "npm run build && node scripts/test-live-repo-e2e.js",
63
71
  "test:repo:auth-fallback": "node scripts/test-community-repo-auth-fallback.mjs",
64
72
  "test:repo:payload-fallback": "node scripts/test-repo-payload-fallback.mjs",
73
+ "test:repo:public-clone": "npm run build && node scripts/test-public-repo-clone.mjs",
74
+ "test:command:timeouts": "npm run build && node scripts/test-timeout-cancellation.mjs",
65
75
  "test:game:live": "npm run build && node scripts/test-live-game-push.js",
66
76
  "proof:agent": "npm run build && node scripts/proof-agent-mode.js",
67
77
  "test:fresh-install": "node scripts/test-fresh-install.js",
@@ -69,16 +79,34 @@
69
79
  "precheck:services": "node scripts/precheck-local-services.js",
70
80
  "test:model:governance": "npm run build && node scripts/test-model-governance-no-agent.js",
71
81
  "validate:no-go": "bash scripts/release/validate-no-go-gates.sh",
82
+ "test:model:balanced-live": "bash scripts/release/test-balanced-model-live.sh",
83
+ "test:release:live-services": "bash scripts/release/validate-live-service-gates.sh",
72
84
  "test:legion:billing:e2e": "npm run build && node scripts/test-legion-godmode-billing-e2e.js",
73
85
  "test:windows:v3-sync": "npm run build && node scripts/test-windows-v3-sync-recovery.js",
74
86
  "test:v3-workspace-path": "npm run build && node scripts/test-v3-workspace-path.js",
75
87
  "test:v3-server-tool-execution": "npm run build && node scripts/test-v3-server-tool-execution.js",
76
88
  "test:session:project-match": "npm run build && node scripts/test-session-project-match.mjs",
89
+ "test:external-client-resume": "npm run build && node scripts/test-external-client-resume.mjs",
77
90
  "test:v3-stream-mutation": "npm run build && node scripts/test-v3-stream-mutation.js",
78
91
  "test:context:budget": "npm run build && node scripts/test-context-budget.js",
79
92
  "test:v3-client-tool-quality": "npm run build && node scripts/test-v3-client-tool-quality.mjs",
80
93
  "test:pitfall:context": "npm run build && node scripts/test-pitfall-context-smoke.js",
81
- "test:game:command": "node scripts/test-game-command.mjs"
94
+ "test:game:command": "node scripts/test-game-command.mjs",
95
+ "test:security:dependencies": "node scripts/test-dependency-security.mjs",
96
+ "test:security:network": "npm run build && node scripts/test-network-policy.mjs && node scripts/test-installer-trust-policy.mjs",
97
+ "test:security:workspace": "npm run build && node scripts/test-workspace-archive-containment.mjs",
98
+ "test:security:process": "npm run build && node scripts/test-process-approval-safety.mjs",
99
+ "test:security:mutation-preview": "npm run build && node scripts/test-mutation-preview-transaction.mjs",
100
+ "test:security:context-secrets": "npm run build && node scripts/test-context-secret-hygiene.mjs",
101
+ "test:architecture:vigflow": "npm run build && node scripts/test-vigflow-client.mjs",
102
+ "test:state:durable": "npm run build && node scripts/test-durable-json-state.mjs",
103
+ "test:state:auth": "npm run build && node scripts/test-auth-state.mjs",
104
+ "test:state:sessions": "npm run build && node scripts/test-session-durable-lifecycle.mjs && node scripts/test-session-project-match.mjs && node scripts/test-external-client-resume.mjs",
105
+ "test:state:context": "npm run build && node scripts/test-context-state-ownership.mjs && node scripts/test-context-secret-hygiene.mjs",
106
+ "test:phase3:command-contract": "npm run build && node scripts/test-command-contract.mjs",
107
+ "test:phase3:update-policy": "npm run build && node scripts/test-update-policy.mjs",
108
+ "test:phase6:delivery": "npm run build && node scripts/test-release-delivery.mjs",
109
+ "architecture:graph": "node scripts/architecture/verify-import-graph.mjs"
82
110
  },
83
111
  "keywords": [
84
112
  "ai",
@@ -92,7 +120,6 @@
92
120
  "author": "Vigthoria Technologies",
93
121
  "license": "MIT",
94
122
  "dependencies": {
95
- "archiver": "^8.0.0",
96
123
  "axios": "^1.6.0",
97
124
  "chalk": "^5.3.0",
98
125
  "chokidar": "^5.0.0",
@@ -104,12 +131,9 @@
104
131
  "marked": "^11.0.0",
105
132
  "marked-terminal": "^6.2.0",
106
133
  "ora": "^7.0.1",
107
- "rxjs": "^7.8.2",
108
- "simple-git": "^3.21.0",
109
134
  "ws": "^8.14.2"
110
135
  },
111
136
  "devDependencies": {
112
- "@types/archiver": "^6.0.2",
113
137
  "@types/diff": "^5.0.8",
114
138
  "@types/inquirer": "^9.0.7",
115
139
  "@types/node": "^20.10.0",
@@ -118,11 +142,22 @@
118
142
  "ts-node": "^10.9.2",
119
143
  "typescript": "^5.3.2"
120
144
  },
145
+ "peerDependencies": {
146
+ "puppeteer": "^24.40.0"
147
+ },
148
+ "peerDependenciesMeta": {
149
+ "puppeteer": {
150
+ "optional": true
151
+ }
152
+ },
121
153
  "engines": {
122
154
  "node": ">=20.19.0"
123
155
  },
124
156
  "overrides": {
125
157
  "glob": "^13.0.6",
126
- "brace-expansion": "^5.0.8"
158
+ "brace-expansion": "5.0.9",
159
+ "fast-uri": "3.1.5",
160
+ "ip-address": "10.3.1",
161
+ "js-yaml": "4.3.1"
127
162
  }
128
163
  }
@@ -0,0 +1,43 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "packageName": "vigthoria-cli",
4
+ "manifest": {
5
+ "schemaVersion": 1,
6
+ "maximumBytes": 262144,
7
+ "requiredChannels": ["stable"],
8
+ "allowedChannels": ["stable", "candidate"]
9
+ },
10
+ "origins": {
11
+ "manifest": "https://extension.vigthoria.io/downloads/manifest.json",
12
+ "artifacts": "https://extension.vigthoria.io/downloads/",
13
+ "allowedHosts": [
14
+ "extension.vigthoria.io",
15
+ "cli.vigthoria.io",
16
+ "coder.vigthoria.io",
17
+ "landing.vigthoria.io",
18
+ "market.vigthoria.io"
19
+ ],
20
+ "port": 443,
21
+ "maximumRedirects": 0
22
+ },
23
+ "artifact": {
24
+ "maximumBytes": 104857600,
25
+ "filenamePattern": "^vigthoria-cli-(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-[0-9A-Za-z.-]+)?\\.tgz$"
26
+ },
27
+ "signature": {
28
+ "algorithm": "Ed25519",
29
+ "trustedKeys": {
30
+ "vigthoria-release-2026-01": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAotTXdcHwZ+D1z5lJMdgAAeMU99BRdMCaCZ465DN2aug=\n-----END PUBLIC KEY-----\n"
31
+ }
32
+ },
33
+ "channels": {
34
+ "stable": { "allowPrerelease": false, "allowDowngrade": false },
35
+ "candidate": { "allowPrerelease": true, "allowDowngrade": false }
36
+ },
37
+ "installation": {
38
+ "versionsDirectory": ".vigthoria/cli/versions",
39
+ "currentLink": ".vigthoria/cli/current",
40
+ "binDirectory": ".local/bin",
41
+ "preservePrevious": 1
42
+ }
43
+ }
@@ -85,7 +85,7 @@ Commands:
85
85
 
86
86
  ```bash
87
87
  vigthoria hyper-loop status
88
- vigthoria devtools connect
88
+ vigthoria devtools status
89
89
  vigthoria bridge status
90
90
  vigthoria operator --prompt "status check" --json
91
91
  ```
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
7
+ const manifest = JSON.parse(fs.readFileSync(path.join(root, 'contracts/phase-0/command-manifest.json'), 'utf8'));
8
+ const commands = manifest.commands
9
+ .filter((command) => !command.path.includes(' '))
10
+ .map((command) => command.path)
11
+ .sort();
12
+ const descriptions = new Map(manifest.commands.filter((command) => !command.path.includes(' ')).map((command) => [command.path, command.description || 'Vigthoria command']));
13
+ if (commands.length !== new Set(commands).size || commands.length === 0) throw new Error('Authoritative command manifest has duplicate or missing top-level commands.');
14
+
15
+ const bash = `# Generated from contracts/phase-0/command-manifest.json; do not edit.\n_vigthoria_completions() {\n local cur="\${COMP_WORDS[COMP_CWORD]}"\n COMPREPLY=( $(compgen -W '${commands.join(' ')}' -- "$cur") )\n}\ncomplete -F _vigthoria_completions vigthoria vig vigthoria-chat\n`;
16
+ const zshRows = commands.map((command) => ` '${command.replaceAll("'", "''")}:${String(descriptions.get(command)).replaceAll("'", "''")}'`).join('\n');
17
+ const zsh = `#compdef vigthoria vig vigthoria-chat\n# Generated from contracts/phase-0/command-manifest.json; do not edit.\n_vigthoria() {\n local -a commands\n commands=(\n${zshRows}\n )\n _describe 'command' commands\n}\n_vigthoria "$@"\n`;
18
+ const fish = `# Generated from contracts/phase-0/command-manifest.json; do not edit.\n${commands.map((command) => `complete -c vigthoria -c vig -c vigthoria-chat -n '__fish_use_subcommand' -a '${command}' -d '${String(descriptions.get(command)).replaceAll("'", "\\'")}'`).join('\n')}\n`;
19
+ const output = path.join(root, 'completions');
20
+ fs.mkdirSync(output, { recursive: true });
21
+ fs.writeFileSync(path.join(output, 'vigthoria.bash'), bash);
22
+ fs.writeFileSync(path.join(output, '_vigthoria'), zsh);
23
+ fs.writeFileSync(path.join(output, 'vigthoria.fish'), fish);
24
+ console.log(`Generated bash, zsh, and fish completion definitions for ${commands.length} commands.`);
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { installReleaseTransaction } from '../../dist/utils/release-install.js';
3
+
4
+ const packageSpec = String(process.argv[2] || '');
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
+ });
10
+ process.stdout.write(`${JSON.stringify(result)}\n`);
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { createHash, createPrivateKey, createPublicKey, sign } from 'node:crypto';
5
+ import { spawnSync } from 'node:child_process';
6
+ import { fileURLToPath } from 'node:url';
7
+ import {
8
+ getReleasePolicy,
9
+ parseReleaseManifest,
10
+ releaseSignaturePayload,
11
+ verifyReleaseSignature,
12
+ } from '../../dist/utils/release-policy.js';
13
+
14
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
15
+ const version = String(process.argv[2] || '').trim();
16
+ const channel = String(process.env.CHANNEL || 'stable').trim();
17
+ const downloadsDirectory = String(process.env.HOST_DOWNLOADS_DIR || '');
18
+ const manifestFile = String(process.env.HOST_MANIFEST_FILE || '');
19
+ const privateKeyFile = String(process.env.RELEASE_SIGNING_PRIVATE_KEY_FILE || '');
20
+ const keyId = String(process.env.RELEASE_SIGNING_KEY_ID || '');
21
+ const sbomFile = String(process.env.RELEASE_SBOM_FILE || '');
22
+ const provenanceFile = String(process.env.RELEASE_PROVENANCE_FILE || '');
23
+ const policy = getReleasePolicy();
24
+
25
+ function stop(message) { throw new Error(message); }
26
+ function digest(file) { return createHash('sha256').update(fs.readFileSync(file)).digest('hex'); }
27
+ function requiredFile(file, label) { if (!file || !fs.statSync(file, { throwIfNoEntry: false })?.isFile()) stop(`${label} is required: ${file || '(unset)'}`); }
28
+ function exactPackageMetadata(archive) {
29
+ const result = spawnSync('tar', ['-xOf', archive, 'package/package.json'], {
30
+ cwd: root, encoding: 'utf8', timeout: 15_000, maxBuffer: 1024 * 1024,
31
+ });
32
+ if (result.status !== 0) stop(`Unable to inspect archive metadata: ${result.stderr || result.stdout}`);
33
+ const metadata = JSON.parse(result.stdout);
34
+ return { name: String(metadata.name || ''), version: String(metadata.version || '') };
35
+ }
36
+
37
+ if (!version) stop('Usage: publish-cli-release.sh <version>');
38
+ if (!downloadsDirectory || !manifestFile) stop('HOST_DOWNLOADS_DIR and HOST_MANIFEST_FILE are required.');
39
+ requiredFile(privateKeyFile, 'RELEASE_SIGNING_PRIVATE_KEY_FILE');
40
+ requiredFile(sbomFile, 'RELEASE_SBOM_FILE');
41
+ requiredFile(provenanceFile, 'RELEASE_PROVENANCE_FILE');
42
+ if (!Object.hasOwn(policy.signature.trustedKeys, keyId)) stop(`RELEASE_SIGNING_KEY_ID is not trusted by release-policy.json: ${keyId || '(unset)'}`);
43
+
44
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
45
+ const lock = JSON.parse(fs.readFileSync(path.join(root, 'package-lock.json'), 'utf8'));
46
+ if ([pkg.version, lock.version, lock.packages?.['']?.version].some((identity) => identity !== version)) stop('Requested version conflicts with package.json or package-lock.json.');
47
+ const runtime = spawnSync(process.execPath, ['dist/index.js', '--version'], { cwd: root, encoding: 'utf8', env: { ...process.env, VIGTHORIA_OFFLINE: '1', VIGTHORIA_NO_BANNER: '1' } });
48
+ if (runtime.status !== 0 || runtime.stdout.trim() !== version) stop('Requested version conflicts with the built CLI banner.');
49
+
50
+ const archiveFilename = `${policy.packageName}-${version}.tgz`;
51
+ const archive = path.join(root, archiveFilename);
52
+ requiredFile(archive, 'Release archive');
53
+ const metadata = exactPackageMetadata(archive);
54
+ if (metadata.name !== policy.packageName || metadata.version !== version) stop('Requested version conflicts with archive metadata.');
55
+
56
+ fs.mkdirSync(downloadsDirectory, { recursive: true });
57
+ fs.mkdirSync(path.dirname(manifestFile), { recursive: true });
58
+ const lockPath = `${manifestFile}.lock`;
59
+ let lockHandle;
60
+ const published = [];
61
+ try {
62
+ lockHandle = fs.openSync(lockPath, 'wx', 0o600);
63
+ const suffix = `${process.pid}-${Date.now()}`;
64
+ const publicBase = new URL(policy.origins.artifacts);
65
+ const signatureFilename = `${archiveFilename}.sig`;
66
+ const sbomFilename = `${archiveFilename}.sbom.json`;
67
+ const provenanceFilename = `${archiveFilename}.provenance.json`;
68
+ const entry = {
69
+ version,
70
+ url: new URL(archiveFilename, publicBase).toString(),
71
+ sha256: digest(archive),
72
+ size: fs.statSync(archive).size,
73
+ archiveFilename,
74
+ packageName: policy.packageName,
75
+ packageVersion: version,
76
+ publishedAt: new Date().toISOString(),
77
+ signature: { algorithm: policy.signature.algorithm, keyId, url: new URL(signatureFilename, publicBase).toString() },
78
+ sbom: { url: new URL(sbomFilename, publicBase).toString(), sha256: digest(sbomFile) },
79
+ provenance: { url: new URL(provenanceFilename, publicBase).toString(), sha256: digest(provenanceFile) },
80
+ notes: String(process.env.RELEASE_NOTES || 'Vigthoria CLI release'),
81
+ };
82
+ const privateKey = createPrivateKey(fs.readFileSync(privateKeyFile));
83
+ const configuredPublic = createPublicKey(policy.signature.trustedKeys[keyId]).export({ type: 'spki', format: 'der' });
84
+ const signingPublic = createPublicKey(privateKey).export({ type: 'spki', format: 'der' });
85
+ if (!configuredPublic.equals(signingPublic)) stop('Signing private key does not match the configured verification key.');
86
+ const detached = sign(null, releaseSignaturePayload(channel, entry), privateKey).toString('base64');
87
+ verifyReleaseSignature(channel, entry, detached);
88
+
89
+ let manifest = { schemaVersion: policy.manifest.schemaVersion, channels: {} };
90
+ if (fs.existsSync(manifestFile)) manifest = JSON.parse(fs.readFileSync(manifestFile, 'utf8'));
91
+ manifest.channels = { ...manifest.channels, [channel]: entry };
92
+ parseReleaseManifest(manifest, channel);
93
+
94
+ const inputs = [[archive, archiveFilename], [sbomFile, sbomFilename], [provenanceFile, provenanceFilename]];
95
+ const staged = [];
96
+ for (const [source, filename] of inputs) {
97
+ const temporary = path.join(downloadsDirectory, `.${filename}.${suffix}.tmp`);
98
+ fs.copyFileSync(source, temporary, fs.constants.COPYFILE_EXCL);
99
+ staged.push([temporary, path.join(downloadsDirectory, filename)]);
100
+ }
101
+ const signatureTemporary = path.join(downloadsDirectory, `.${signatureFilename}.${suffix}.tmp`);
102
+ fs.writeFileSync(signatureTemporary, `${detached}\n`, { flag: 'wx', mode: 0o644 });
103
+ staged.push([signatureTemporary, path.join(downloadsDirectory, signatureFilename)]);
104
+ for (const [, destination] of staged) if (fs.existsSync(destination)) stop(`Refusing to overwrite published release component: ${destination}`);
105
+ for (const [temporary, destination] of staged) { fs.renameSync(temporary, destination); published.push(destination); }
106
+ const manifestTemporary = `${manifestFile}.${suffix}.tmp`;
107
+ fs.writeFileSync(manifestTemporary, `${JSON.stringify(manifest, null, 2)}\n`, { flag: 'wx', mode: 0o644 });
108
+ fs.renameSync(manifestTemporary, manifestFile);
109
+ console.log(JSON.stringify({ status: 'published', channel, version, sha256: entry.sha256, size: entry.size, manifestFile }, null, 2));
110
+ } catch (error) {
111
+ for (const file of published.reverse()) { try { fs.unlinkSync(file); } catch {} }
112
+ throw error;
113
+ } finally {
114
+ if (lockHandle !== undefined) fs.closeSync(lockHandle);
115
+ try { fs.unlinkSync(lockPath); } catch {}
116
+ }
@@ -1,73 +1,5 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
- # Publish Vigthoria CLI release artifact + manifest entry.
5
- # Usage:
6
- # HOST_DOWNLOADS_DIR=/path/to/downloads \
7
- # HOST_MANIFEST_FILE=/path/to/releases/manifest.json \
8
- # ./scripts/release/publish-cli-release.sh 1.9.0
9
-
10
- VERSION="${1:-}"
11
- if [[ -z "$VERSION" ]]; then
12
- echo "Usage: $0 <version>"
13
- exit 1
14
- fi
15
-
16
- REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
17
- PKG_FILE="$REPO_ROOT/vigthoria-cli-${VERSION}.tgz"
18
- HOST_DOWNLOADS_DIR="${HOST_DOWNLOADS_DIR:-}"
19
- HOST_MANIFEST_FILE="${HOST_MANIFEST_FILE:-}"
20
- PUBLIC_BASE_URL="${PUBLIC_BASE_URL:-https://extension.vigthoria.io/downloads}"
21
- CHANNEL="${CHANNEL:-stable}"
22
-
23
- if [[ ! -f "$PKG_FILE" ]]; then
24
- echo "Artifact not found: $PKG_FILE"
25
- echo "Run: npm pack"
26
- exit 1
27
- fi
28
-
29
- if [[ -z "$HOST_DOWNLOADS_DIR" || -z "$HOST_MANIFEST_FILE" ]]; then
30
- echo "Set HOST_DOWNLOADS_DIR and HOST_MANIFEST_FILE before running."
31
- exit 1
32
- fi
33
-
34
- SHA256="$(sha256sum "$PKG_FILE" | awk '{print $1}')"
35
- URL="$PUBLIC_BASE_URL/vigthoria-cli-${VERSION}.tgz"
36
-
37
- echo "Publishing vigthoria-cli v${VERSION}"
38
- echo "Artifact: $PKG_FILE"
39
- echo "SHA256: $SHA256"
40
- echo "URL: $URL"
41
-
42
- install -d "$HOST_DOWNLOADS_DIR"
43
- cp -f "$PKG_FILE" "$HOST_DOWNLOADS_DIR/"
44
-
45
- echo "Copied artifact to $HOST_DOWNLOADS_DIR"
46
-
47
- if [[ ! -f "$HOST_MANIFEST_FILE" ]]; then
48
- echo "Manifest does not exist at: $HOST_MANIFEST_FILE"
49
- echo "Create it first with {\"channels\":{\"stable\":{}}}"
50
- exit 1
51
- fi
52
-
53
- python3 - << PYEOF
54
- import json, pathlib
55
- manifest_path = pathlib.Path(r"$HOST_MANIFEST_FILE")
56
- data = json.loads(manifest_path.read_text())
57
- data.setdefault("channels", {})
58
- data["channels"].setdefault("$CHANNEL", {})
59
- data["channels"]["$CHANNEL"].update({
60
- "version": "$VERSION",
61
- "url": "$URL",
62
- "sha256": "$SHA256",
63
- "notes": "Automated publish via scripts/release/publish-cli-release.sh"
64
- })
65
- manifest_path.write_text(json.dumps(data, indent=2) + "\n")
66
- print("Manifest updated:", manifest_path)
67
- PYEOF
68
-
69
- echo "Publish complete."
70
- echo "Verification commands:"
71
- echo " curl -I $URL"
72
- echo " curl -fsSL https://coder.vigthoria.io/releases/manifest.json | head -40"
73
- echo " node dist/index.js update --check --manifest https://coder.vigthoria.io/releases/manifest.json --channel $CHANNEL"
4
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ exec node "$ROOT/scripts/release/publish-cli-release.mjs" "$@"