@solarains/va-cli 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,9 @@ npm install -g @solarains/va-cli
12
12
 
13
13
  ```bash
14
14
  vaone --help
15
+ vaone --version
15
16
  vaone init
17
+ vaone update
16
18
  ```
17
19
 
18
20
  Use `vaone ...` to access the CLI command surface.
@@ -4,36 +4,49 @@ exports.getHelpCopy = getHelpCopy;
4
4
  exports.getLocalizedCommandHelp = getLocalizedCommandHelp;
5
5
  exports.getLocalizedChildSummary = getLocalizedChildSummary;
6
6
  const HELP_COPY = {
7
- en: {
7
+ 'en': {
8
8
  commandsHeading: 'Commands:',
9
9
  globalFlagsHeading: 'Global flags:',
10
10
  helpFlag: 'Show help',
11
11
  debugFlag: 'Enable debug logging',
12
+ versionFlag: 'Show CLI version',
12
13
  commandHelp: {
13
14
  '': {
14
- summary: 'VAOne CLI with guided init, auth, assets, usage, daily reports, intelligence queries, and diagnostics.',
15
+ summary: 'VAOne CLI with versioning, self-update, guided init, auth, assets, usage, daily reports, intelligence queries, and diagnostics.',
15
16
  usage: 'vaone <command> [subcommand] [options]',
16
17
  },
17
- init: {
18
+ 'version': {
19
+ summary: 'Show the current VAOne CLI version.',
20
+ usage: 'vaone version',
21
+ },
22
+ 'update': {
23
+ summary: 'Check for a newer packaged CLI release and sync VA-managed skill packs.',
24
+ usage: 'vaone update',
25
+ },
26
+ 'init': {
18
27
  summary: 'Install VisionAlpha operator skills with branded onboarding and optional browser login.',
19
28
  usage: 'vaone init [.] [--agents codex,claude,openclaw] [--scope project|user] [--lang en|zh-CN] [--skip-login] [--force] [--yes]',
20
29
  },
21
- auth: {
30
+ 'uninstall': {
31
+ summary: 'Remove VA-managed skill packs from project or global agent roots.',
32
+ usage: 'vaone uninstall [--scope project|user|all] [--agents codex,claude,openclaw]',
33
+ },
34
+ 'auth': {
22
35
  summary: 'Authentication placeholder commands for future browser login.',
23
36
  },
24
- assets: {
37
+ 'assets': {
25
38
  summary: 'Browse asset catalog commands.',
26
39
  },
27
- usage: {
40
+ 'usage': {
28
41
  summary: 'Show current account usage summary.',
29
42
  },
30
- reports: {
43
+ 'reports': {
31
44
  summary: 'List or read normalized daily reports.',
32
45
  },
33
- intelligence: {
46
+ 'intelligence': {
34
47
  summary: 'Query paid asset intelligence data.',
35
48
  },
36
- doctor: {
49
+ 'doctor': {
37
50
  summary: 'Run local diagnostics for auth, install, and configuration state.',
38
51
  },
39
52
  },
@@ -46,31 +59,44 @@ const HELP_COPY = {
46
59
  globalFlagsHeading: '全局参数:',
47
60
  helpFlag: '显示帮助',
48
61
  debugFlag: '启用调试日志',
62
+ versionFlag: '显示 CLI 版本',
49
63
  commandHelp: {
50
64
  '': {
51
- summary: 'VAOne CLI,提供引导式 init、认证、资产、usage、日报、intelligence 查询与诊断能力。',
65
+ summary: 'VAOne CLI,提供版本查看、自更新、引导式 init、认证、资产、usage、日报、intelligence 查询与诊断能力。',
52
66
  usage: 'vaone <命令> [子命令] [参数]',
53
67
  },
54
- init: {
68
+ 'version': {
69
+ summary: '显示当前 VAOne CLI 版本。',
70
+ usage: 'vaone version',
71
+ },
72
+ 'update': {
73
+ summary: '检查新版 CLI,并同步所有 VA 受管 skill pack。',
74
+ usage: 'vaone update',
75
+ },
76
+ 'init': {
55
77
  summary: '通过带品牌感的引导流程安装 VisionAlpha operator skills,并可选串联浏览器登录。',
56
78
  usage: 'vaone init [.] [--agents codex,claude,openclaw] [--scope project|user] [--lang en|zh-CN] [--skip-login] [--force] [--yes]',
57
79
  },
58
- auth: {
80
+ 'uninstall': {
81
+ summary: '从当前项目或全局 agent 根目录移除 VA 受管 skill pack。',
82
+ usage: 'vaone uninstall [--scope project|user|all] [--agents codex,claude,openclaw]',
83
+ },
84
+ 'auth': {
59
85
  summary: '认证相关命令,包括浏览器登录与退出登录。',
60
86
  },
61
- assets: {
87
+ 'assets': {
62
88
  summary: '浏览资产目录相关命令。',
63
89
  },
64
- usage: {
90
+ 'usage': {
65
91
  summary: '显示当前账户 usage 摘要。',
66
92
  },
67
- reports: {
93
+ 'reports': {
68
94
  summary: '列出或读取标准化日报。',
69
95
  },
70
- intelligence: {
96
+ 'intelligence': {
71
97
  summary: '查询付费资产 intelligence 数据。',
72
98
  },
73
- doctor: {
99
+ 'doctor': {
74
100
  summary: '运行本地认证、安装和配置状态诊断。',
75
101
  },
76
102
  },
package/dist/cli/help.js CHANGED
@@ -25,5 +25,7 @@ function renderHelp(command, pathSegments = [], locale = 'en') {
25
25
  lines.push(copy.globalFlagsHeading);
26
26
  lines.push(` --help, -h ${copy.helpFlag}`);
27
27
  lines.push(` --debug ${copy.debugFlag}`);
28
+ lines.push(` --version ${copy.versionFlag}`);
29
+ lines.push(` -V, -v ${copy.versionFlag}`);
28
30
  return lines.join('\n');
29
31
  }
@@ -7,13 +7,19 @@ const doctor_command_1 = require("../commands/doctor/doctor-command");
7
7
  const init_command_1 = require("../commands/init/init-command");
8
8
  const intelligence_command_1 = require("../commands/intelligence/intelligence-command");
9
9
  const reports_command_1 = require("../commands/reports/reports-command");
10
+ const update_command_1 = require("../commands/update/update-command");
11
+ const uninstall_command_1 = require("../commands/uninstall/uninstall-command");
10
12
  const usage_command_1 = require("../commands/usage/usage-command");
13
+ const version_command_1 = require("../commands/version/version-command");
11
14
  exports.rootCommand = {
12
15
  name: 'vaone',
13
- summary: 'VAOne CLI with guided init, auth, assets, usage, daily reports, intelligence queries, and diagnostics.',
16
+ summary: 'VAOne CLI with versioning, self-update, guided init, auth, assets, usage, daily reports, intelligence queries, and diagnostics.',
14
17
  usage: 'vaone <command> [subcommand] [options]',
15
18
  children: [
19
+ version_command_1.versionCommand,
20
+ update_command_1.updateCommand,
16
21
  init_command_1.initCommand,
22
+ uninstall_command_1.uninstallCommand,
17
23
  auth_command_1.authCommand,
18
24
  assets_command_1.assetsCommand,
19
25
  usage_command_1.usageCommand,
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runCli = runCli;
4
+ const node_os_1 = require("node:os");
4
5
  const runtime_config_1 = require("../config/runtime-config");
6
+ const preflight_1 = require("../features/update/preflight");
5
7
  const paths_1 = require("../state/paths");
6
8
  const installation_store_1 = require("../state/stores/installation-store");
7
9
  const token_store_1 = require("../state/stores/token-store");
@@ -9,10 +11,12 @@ const logger_1 = require("../shared/logger");
9
11
  const help_1 = require("./help");
10
12
  const help_copy_1 = require("./help-copy");
11
13
  const root_command_1 = require("./root-command");
14
+ const version_command_1 = require("../commands/version/version-command");
12
15
  function parseArgv(argv) {
13
16
  const tokens = [];
14
17
  let debug = false;
15
18
  let help = false;
19
+ let version = false;
16
20
  for (const token of argv) {
17
21
  if (token === '--') {
18
22
  continue;
@@ -25,6 +29,10 @@ function parseArgv(argv) {
25
29
  help = true;
26
30
  continue;
27
31
  }
32
+ if (token === '--version' || token === '-V' || token === '-v') {
33
+ version = true;
34
+ continue;
35
+ }
28
36
  tokens.push(token);
29
37
  }
30
38
  if (tokens[0] === 'help') {
@@ -34,6 +42,7 @@ function parseArgv(argv) {
34
42
  return {
35
43
  debug,
36
44
  help,
45
+ version,
37
46
  tokens,
38
47
  };
39
48
  }
@@ -62,15 +71,27 @@ function printUnknownCommand(logger, command, path, token, locale) {
62
71
  logger.plain('');
63
72
  logger.plain((0, help_1.renderHelp)(command, path, locale));
64
73
  }
65
- async function runCli(argv, env) {
74
+ async function runCli(argv, env, deps = {}) {
66
75
  const parsedArgv = parseArgv(argv);
67
76
  const logger = new logger_1.Logger(parsedArgv.debug || env.VAONE_DEBUG === 'true');
77
+ if (parsedArgv.version) {
78
+ return (0, version_command_1.printCliVersion)(logger);
79
+ }
80
+ const resolvedCommand = resolveCommand(parsedArgv.tokens);
81
+ if (!parsedArgv.help && resolvedCommand.path[0] === 'version') {
82
+ try {
83
+ return await (0, version_command_1.printCliVersion)(logger, resolvedCommand.remainingArgs);
84
+ }
85
+ catch (error) {
86
+ logger.error(error instanceof Error ? error.message : 'Unknown CLI failure.');
87
+ return 1;
88
+ }
89
+ }
68
90
  const paths = (0, paths_1.createCliPaths)(env);
69
91
  const runtimeConfig = await (0, runtime_config_1.loadRuntimeConfig)(env, paths);
70
92
  logger.setDebugMode(parsedArgv.debug || runtimeConfig.debug);
71
93
  const tokenStore = new token_store_1.TokenStore(paths.authStateFile);
72
94
  const installationStore = new installation_store_1.InstallationStore(paths.installationStateFile);
73
- const resolvedCommand = resolveCommand(parsedArgv.tokens);
74
95
  const unknownToken = resolvedCommand.remainingArgs[0];
75
96
  const canTraverseFurther = Boolean(resolvedCommand.command.children?.length && unknownToken);
76
97
  const locale = runtimeConfig.locale;
@@ -86,7 +107,6 @@ async function runCli(argv, env) {
86
107
  logger.plain((0, help_1.renderHelp)(resolvedCommand.command, resolvedCommand.path, locale));
87
108
  return 0;
88
109
  }
89
- await (0, paths_1.ensureCliDirectories)(paths);
90
110
  if (canTraverseFurther && !resolvedCommand.command.run) {
91
111
  printUnknownCommand(logger, resolvedCommand.command, resolvedCommand.path, unknownToken, locale);
92
112
  return 1;
@@ -95,6 +115,23 @@ async function runCli(argv, env) {
95
115
  logger.plain((0, help_1.renderHelp)(resolvedCommand.command, resolvedCommand.path, locale));
96
116
  return 0;
97
117
  }
118
+ if (!((0, preflight_1.shouldSkipManagedSync)(resolvedCommand.path) &&
119
+ (0, preflight_1.shouldSkipCliUpdate)(resolvedCommand.path))) {
120
+ await (0, paths_1.ensureCliDirectories)(paths);
121
+ const preflightExitCode = await (deps.runStartupPreflight ?? preflight_1.runStartupPreflight)({
122
+ argv,
123
+ env,
124
+ logger,
125
+ paths,
126
+ runtimeConfig,
127
+ commandPath: resolvedCommand.path,
128
+ cwd: process.cwd(),
129
+ homeDir: (0, node_os_1.homedir)(),
130
+ });
131
+ if (typeof preflightExitCode === 'number') {
132
+ return preflightExitCode;
133
+ }
134
+ }
98
135
  try {
99
136
  return await resolvedCommand.command.run(context, resolvedCommand.remainingArgs);
100
137
  }
@@ -22,7 +22,9 @@ exports.logoutCommand = {
22
22
  }
23
23
  catch (error) {
24
24
  remoteLogoutFailure =
25
- error instanceof Error ? error.message : 'Unknown remote logout failure.';
25
+ error instanceof Error
26
+ ? error.message
27
+ : 'Unknown remote logout failure.';
26
28
  context.logger.debug('Remote logout request failed.', error);
27
29
  }
28
30
  }
@@ -1,7 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.doctorCommand = void 0;
4
+ const node_os_1 = require("node:os");
4
5
  const output_1 = require("../../shared/output");
6
+ const package_metadata_1 = require("../../features/runtime/package-metadata");
7
+ const managed_pack_1 = require("../../features/init/managed-pack");
8
+ const paths_1 = require("../../state/paths");
9
+ const update_state_store_1 = require("../../state/stores/update-state-store");
10
+ function formatManagedStatus(input) {
11
+ if (input.kind === 'current') {
12
+ return `current (${input.installedVersion})`;
13
+ }
14
+ if (input.kind === 'stale') {
15
+ return `stale (${input.installedVersion} -> ${input.currentVersion})`;
16
+ }
17
+ if (input.kind === 'legacy') {
18
+ return `legacy (missing pack version; current ${input.currentVersion})`;
19
+ }
20
+ if (input.kind === 'ahead') {
21
+ return `ahead (${input.installedVersion})`;
22
+ }
23
+ if (input.kind === 'untracked') {
24
+ return 'managed files detected without a valid manifest';
25
+ }
26
+ return 'not installed';
27
+ }
5
28
  exports.doctorCommand = {
6
29
  name: 'doctor',
7
30
  summary: 'Inspect config, paths, and local bootstrap state.',
@@ -9,6 +32,14 @@ exports.doctorCommand = {
9
32
  async run(context) {
10
33
  const tokens = await context.tokenStore.read();
11
34
  const installation = await context.installationStore.read();
35
+ const runtimePackage = await (0, package_metadata_1.resolveRuntimePackageInfo)();
36
+ const updateStateStore = new update_state_store_1.UpdateStateStore((0, paths_1.resolveUpdateStateFile)(context.paths));
37
+ const updateState = await updateStateStore.read();
38
+ const managedStatuses = await (0, managed_pack_1.collectManagedPackStatuses)({
39
+ cwd: process.cwd(),
40
+ homeDir: (0, node_os_1.homedir)(),
41
+ currentVersion: runtimePackage.version,
42
+ });
12
43
  (0, output_1.printSection)(context.logger, 'Runtime configuration');
13
44
  (0, output_1.printKeyValue)(context.logger, 'Environment', context.runtimeConfig.appEnv);
14
45
  (0, output_1.printKeyValue)(context.logger, 'API base URL', context.runtimeConfig.apiBaseUrl);
@@ -19,6 +50,13 @@ exports.doctorCommand = {
19
50
  (0, output_1.printKeyValue)(context.logger, 'State directory', context.paths.stateDir);
20
51
  (0, output_1.printKeyValue)(context.logger, 'Auth state', context.paths.authStateFile);
21
52
  (0, output_1.printKeyValue)(context.logger, 'Installation state', context.paths.installationStateFile);
53
+ (0, output_1.printKeyValue)(context.logger, 'Update state', (0, paths_1.resolveUpdateStateFile)(context.paths));
54
+ (0, output_1.printSection)(context.logger, 'Runtime version state');
55
+ (0, output_1.printKeyValue)(context.logger, 'CLI version', runtimePackage.version);
56
+ (0, output_1.printKeyValue)(context.logger, 'Packaged install', String(runtimePackage.isPackagedInstall));
57
+ (0, output_1.printKeyValue)(context.logger, 'Deferred update boundary', context.runtimeConfig.updateDeferredUntilVersion ?? 'none');
58
+ (0, output_1.printKeyValue)(context.logger, 'Last checked', updateState?.lastCheckedAt ?? 'never');
59
+ (0, output_1.printKeyValue)(context.logger, 'Last known latest version', updateState?.lastKnownLatestVersion ?? 'unknown');
22
60
  (0, output_1.printSection)(context.logger, 'Stored bootstrap state');
23
61
  (0, output_1.printList)(context.logger, [
24
62
  tokens
@@ -28,6 +66,12 @@ exports.doctorCommand = {
28
66
  ? 'Installation state file exists.'
29
67
  : 'Installation state file is empty.',
30
68
  ]);
69
+ (0, output_1.printSection)(context.logger, 'Managed skill packs');
70
+ (0, output_1.printList)(context.logger, managedStatuses.map((status) => `${status.target.displayName} (${status.scope}): ${formatManagedStatus({
71
+ kind: status.kind,
72
+ installedVersion: status.installedVersion,
73
+ currentVersion: status.currentVersion,
74
+ })} at ${status.rootDir}`));
31
75
  return 0;
32
76
  },
33
77
  };
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uninstallCommand = void 0;
4
+ const node_os_1 = require("node:os");
5
+ const argv_1 = require("../../shared/argv");
6
+ const target_registry_1 = require("../../features/init/target-registry");
7
+ const managed_pack_1 = require("../../features/init/managed-pack");
8
+ function parseScope(value) {
9
+ if (!value) {
10
+ return 'project';
11
+ }
12
+ if (value === 'project' || value === 'user' || value === 'all') {
13
+ return value;
14
+ }
15
+ throw new Error('Option "--scope" must be project, user, or all.');
16
+ }
17
+ function parseAgentIds(value) {
18
+ if (!value) {
19
+ return (0, target_registry_1.getAgentTargetRegistry)().map((target) => target.id);
20
+ }
21
+ const supported = new Set((0, target_registry_1.getAgentTargetRegistry)().map((target) => target.id));
22
+ return value
23
+ .split(',')
24
+ .map((entry) => entry.trim().toLowerCase())
25
+ .filter(Boolean)
26
+ .map((entry) => {
27
+ if (!supported.has(entry)) {
28
+ throw new Error(`Unsupported agent "${entry}". Use one or more of: ${Array.from(supported).join(', ')}.`);
29
+ }
30
+ return entry;
31
+ })
32
+ .filter((entry, index, items) => items.indexOf(entry) === index);
33
+ }
34
+ exports.uninstallCommand = {
35
+ name: 'uninstall',
36
+ summary: 'Remove VA-managed skill packs from project or global agent roots.',
37
+ usage: 'vaone uninstall [--scope project|user|all] [--agents codex,claude,openclaw]',
38
+ async run(context, args) {
39
+ const parsed = (0, argv_1.parseCommandArgs)(args);
40
+ if (parsed.positionals.length) {
41
+ throw new Error('`vaone uninstall` does not accept positional arguments.');
42
+ }
43
+ const scope = parseScope((0, argv_1.getStringOption)(parsed, 'scope'));
44
+ const scopes = scope === 'all' ? ['project', 'user'] : [scope];
45
+ const agentIds = parseAgentIds((0, argv_1.getStringOption)(parsed, 'agents'));
46
+ const removed = await (0, managed_pack_1.removeManagedPacks)({
47
+ cwd: process.cwd(),
48
+ homeDir: (0, node_os_1.homedir)(),
49
+ agentIds,
50
+ scopes,
51
+ });
52
+ if (removed.length === 0) {
53
+ context.logger.info('No VA-managed skill packs were found for removal.');
54
+ return 0;
55
+ }
56
+ context.logger.plain('Managed skill packs removed:');
57
+ for (const entry of removed) {
58
+ context.logger.plain(`- ${entry.target.displayName} (${entry.scope}): ${entry.rootDir}`);
59
+ }
60
+ return 0;
61
+ },
62
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateCommand = void 0;
4
+ const node_os_1 = require("node:os");
5
+ const preflight_1 = require("../../features/update/preflight");
6
+ const argv_1 = require("../../shared/argv");
7
+ exports.updateCommand = {
8
+ name: 'update',
9
+ summary: 'Check for a newer packaged CLI release and sync VA-managed skill packs.',
10
+ usage: 'vaone update',
11
+ async run(context, args) {
12
+ const parsed = (0, argv_1.parseCommandArgs)(args);
13
+ if (parsed.positionals.length > 0) {
14
+ throw new Error('`vaone update` does not accept positional arguments.');
15
+ }
16
+ return (0, preflight_1.runExplicitUpdate)({
17
+ argv: context.argv,
18
+ env: process.env,
19
+ logger: context.logger,
20
+ paths: context.paths,
21
+ runtimeConfig: context.runtimeConfig,
22
+ cwd: process.cwd(),
23
+ homeDir: (0, node_os_1.homedir)(),
24
+ });
25
+ },
26
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.versionCommand = void 0;
4
+ exports.printCliVersion = printCliVersion;
5
+ const package_metadata_1 = require("../../features/runtime/package-metadata");
6
+ async function printCliVersion(logger, args = []) {
7
+ if (args.length > 0) {
8
+ throw new Error('`vaone version` does not accept positional arguments.');
9
+ }
10
+ const runtimePackage = await (0, package_metadata_1.resolveRuntimePackageInfo)();
11
+ logger.plain(runtimePackage.version);
12
+ return 0;
13
+ }
14
+ exports.versionCommand = {
15
+ name: 'version',
16
+ summary: 'Show the current VAOne CLI version.',
17
+ usage: 'vaone version',
18
+ async run(context, args) {
19
+ return printCliVersion(context.logger, args);
20
+ },
21
+ };
@@ -46,13 +46,12 @@ async function loadRuntimeConfig(env, paths) {
46
46
  const locale = envLocale ?? fileLocale ?? locale_1.DEFAULT_LOCALE;
47
47
  return {
48
48
  appEnv: env.VAONE_ENV ?? fileConfig.appEnv ?? 'local',
49
- apiBaseUrl: normalizeHomePath(env.VAONE_API_BASE_URL ??
50
- fileConfig.apiBaseUrl ??
51
- exports.DEFAULT_API_BASE_URL).replace(/\/$/, ''),
49
+ apiBaseUrl: normalizeHomePath(env.VAONE_API_BASE_URL ?? fileConfig.apiBaseUrl ?? exports.DEFAULT_API_BASE_URL).replace(/\/$/, ''),
52
50
  debug: parseBoolean(env.VAONE_DEBUG) ?? fileConfig.debug ?? false,
53
51
  authCallbackMode,
54
52
  locale,
55
53
  localeConfigured: envLocale !== undefined || fileLocale !== undefined,
54
+ updateDeferredUntilVersion: fileConfig.updateDeferredUntilVersion?.trim() || undefined,
56
55
  };
57
56
  }
58
57
  async function saveRuntimeConfig(paths, patch) {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ensureInstallationState = ensureInstallationState;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const node_os_1 = require("node:os");
6
- const CLI_VERSION = '0.1.0';
6
+ const package_metadata_1 = require("../runtime/package-metadata");
7
7
  function exportPublicKeyPem(publicKey) {
8
8
  return publicKey.export({
9
9
  type: 'spki',
@@ -28,6 +28,7 @@ function hasUsableKeys(installation) {
28
28
  installation.updatedAt);
29
29
  }
30
30
  async function ensureInstallationState(installationStore) {
31
+ const runtimePackage = await (0, package_metadata_1.resolveRuntimePackageInfo)();
31
32
  const existing = await installationStore.read();
32
33
  const now = new Date().toISOString();
33
34
  if (hasUsableKeys(existing)) {
@@ -35,7 +36,7 @@ async function ensureInstallationState(installationStore) {
35
36
  ...existing,
36
37
  clientPlatform: (0, node_os_1.platform)(),
37
38
  clientArch: (0, node_os_1.arch)(),
38
- cliVersion: existing.cliVersion ?? CLI_VERSION,
39
+ cliVersion: runtimePackage.version,
39
40
  deviceName: existing.deviceName ?? (0, node_os_1.hostname)(),
40
41
  updatedAt: now,
41
42
  };
@@ -55,7 +56,7 @@ async function ensureInstallationState(installationStore) {
55
56
  keyFingerprint,
56
57
  clientPlatform: (0, node_os_1.platform)(),
57
58
  clientArch: (0, node_os_1.arch)(),
58
- cliVersion: CLI_VERSION,
59
+ cliVersion: runtimePackage.version,
59
60
  deviceName: (0, node_os_1.hostname)(),
60
61
  createdAt: now,
61
62
  updatedAt: now,
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.renderLoopbackCallbackPage = renderLoopbackCallbackPage;
4
4
  const CALLBACK_PAGE_COPY = {
5
- en: {
5
+ 'en': {
6
6
  brand: 'VAOne',
7
7
  closeAction: 'Close page',
8
8
  success: {
@@ -108,7 +108,8 @@ function extractLoginSummary(lines, copy) {
108
108
  /^-+$/.test(line.trim())) {
109
109
  continue;
110
110
  }
111
- if (line.includes('Automatic browser launch failed') || line.startsWith('URL:')) {
111
+ if (line.includes('Automatic browser launch failed') ||
112
+ line.startsWith('URL:')) {
112
113
  details.push(line);
113
114
  continue;
114
115
  }
@@ -405,14 +406,14 @@ function resolveInitOptions(input) {
405
406
  return resolve();
406
407
  }
407
408
  function positionalscopeAndScopeConflict(positionalScope, parsedScope) {
408
- return Boolean(positionalScope &&
409
- parsedScope &&
410
- positionalScope !== parsedScope);
409
+ return Boolean(positionalScope && parsedScope && positionalScope !== parsedScope);
411
410
  }
412
411
  function describeDetection(presenter, copy, detectedTargets) {
413
412
  presenter.section(copy.sections.detection);
414
413
  for (const target of detectedTargets) {
415
- const summary = target.detected ? copy.labels.detected : copy.labels.notDetected;
414
+ const summary = target.detected
415
+ ? copy.labels.detected
416
+ : copy.labels.notDetected;
416
417
  presenter.list([
417
418
  `${target.displayName}: ${summary}`,
418
419
  ...(target.detectedIn.length > 0
@@ -477,9 +478,7 @@ async function runVerification(context, presenter, copy, options, dependencies)
477
478
  });
478
479
  if (options.skipLogin) {
479
480
  presenter.step('skipped', copy.statuses.skipped, copy.steps.usageSkipped);
480
- presenter.list([
481
- copy.messages.usageVerificationSkippedDeferred,
482
- ]);
481
+ presenter.list([copy.messages.usageVerificationSkippedDeferred]);
483
482
  return;
484
483
  }
485
484
  await runCommandInBox({
@@ -570,7 +569,9 @@ async function runInitFlow(context, args, partialDependencies = {}) {
570
569
  cwd: dependencies.cwd,
571
570
  homeDir: dependencies.homeDir,
572
571
  });
573
- const prompt = dependencies.isInteractive ? dependencies.promptFactory() : null;
572
+ const prompt = dependencies.isInteractive
573
+ ? dependencies.promptFactory()
574
+ : null;
574
575
  let shouldForceExit = false;
575
576
  let exitCode = 1;
576
577
  try {
@@ -4,6 +4,7 @@ exports.prepareInstallations = prepareInstallations;
4
4
  exports.applyInstallations = applyInstallations;
5
5
  const promises_1 = require("node:fs/promises");
6
6
  const node_path_1 = require("node:path");
7
+ const package_metadata_1 = require("../runtime/package-metadata");
7
8
  const manifest_1 = require("./manifest");
8
9
  const target_registry_1 = require("./target-registry");
9
10
  const templates_1 = require("./templates");
@@ -85,8 +86,10 @@ async function prepareInstallations(input) {
85
86
  async function applyInstallations(prepared, options) {
86
87
  const applied = [];
87
88
  const timestamp = options.now ?? (() => new Date().toISOString());
89
+ const runtimePackage = await (0, package_metadata_1.resolveRuntimePackageInfo)();
88
90
  for (const entry of prepared) {
89
- if (entry.analysis.conflicts.length > 0 && !options.allowUnmanagedOverwrite) {
91
+ if (entry.analysis.conflicts.length > 0 &&
92
+ !options.allowUnmanagedOverwrite) {
90
93
  throw new Error(`Unmanaged files block ${entry.target.displayName} installation: ${entry.analysis.conflicts.join(', ')}. Re-run with --force or confirm overwrite interactively.`);
91
94
  }
92
95
  const overwritten = [...entry.analysis.conflicts];
@@ -106,6 +109,7 @@ async function applyInstallations(prepared, options) {
106
109
  packId: 'vaone-agent-pack',
107
110
  targetId: entry.target.id,
108
111
  scope: entry.scope,
112
+ packVersion: runtimePackage.version,
109
113
  updatedAt: timestamp(),
110
114
  files: entry.files.map((file) => file.relativePath),
111
115
  });