@solarains/va-cli 0.1.4 → 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.
@@ -9,11 +9,20 @@ const HELP_COPY = {
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
  },
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
+ },
17
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]',
@@ -50,11 +59,20 @@ const HELP_COPY = {
50
59
  globalFlagsHeading: '全局参数:',
51
60
  helpFlag: '显示帮助',
52
61
  debugFlag: '启用调试日志',
62
+ versionFlag: '显示 CLI 版本',
53
63
  commandHelp: {
54
64
  '': {
55
- summary: 'VAOne CLI,提供引导式 init、认证、资产、usage、日报、intelligence 查询与诊断能力。',
65
+ summary: 'VAOne CLI,提供版本查看、自更新、引导式 init、认证、资产、usage、日报、intelligence 查询与诊断能力。',
56
66
  usage: 'vaone <命令> [子命令] [参数]',
57
67
  },
68
+ 'version': {
69
+ summary: '显示当前 VAOne CLI 版本。',
70
+ usage: 'vaone version',
71
+ },
72
+ 'update': {
73
+ summary: '检查新版 CLI,并同步所有 VA 受管 skill pack。',
74
+ usage: 'vaone update',
75
+ },
58
76
  'init': {
59
77
  summary: '通过带品牌感的引导流程安装 VisionAlpha operator skills,并可选串联浏览器登录。',
60
78
  usage: 'vaone init [.] [--agents codex,claude,openclaw] [--scope project|user] [--lang en|zh-CN] [--skip-login] [--force] [--yes]',
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,17 @@ 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");
10
11
  const uninstall_command_1 = require("../commands/uninstall/uninstall-command");
11
12
  const usage_command_1 = require("../commands/usage/usage-command");
13
+ const version_command_1 = require("../commands/version/version-command");
12
14
  exports.rootCommand = {
13
15
  name: 'vaone',
14
- 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.',
15
17
  usage: 'vaone <command> [subcommand] [options]',
16
18
  children: [
19
+ version_command_1.versionCommand,
20
+ update_command_1.updateCommand,
17
21
  init_command_1.initCommand,
18
22
  uninstall_command_1.uninstallCommand,
19
23
  auth_command_1.authCommand,
@@ -11,10 +11,12 @@ const logger_1 = require("../shared/logger");
11
11
  const help_1 = require("./help");
12
12
  const help_copy_1 = require("./help-copy");
13
13
  const root_command_1 = require("./root-command");
14
+ const version_command_1 = require("../commands/version/version-command");
14
15
  function parseArgv(argv) {
15
16
  const tokens = [];
16
17
  let debug = false;
17
18
  let help = false;
19
+ let version = false;
18
20
  for (const token of argv) {
19
21
  if (token === '--') {
20
22
  continue;
@@ -27,6 +29,10 @@ function parseArgv(argv) {
27
29
  help = true;
28
30
  continue;
29
31
  }
32
+ if (token === '--version' || token === '-V' || token === '-v') {
33
+ version = true;
34
+ continue;
35
+ }
30
36
  tokens.push(token);
31
37
  }
32
38
  if (tokens[0] === 'help') {
@@ -36,6 +42,7 @@ function parseArgv(argv) {
36
42
  return {
37
43
  debug,
38
44
  help,
45
+ version,
39
46
  tokens,
40
47
  };
41
48
  }
@@ -67,12 +74,24 @@ function printUnknownCommand(logger, command, path, token, locale) {
67
74
  async function runCli(argv, env, deps = {}) {
68
75
  const parsedArgv = parseArgv(argv);
69
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
+ }
70
90
  const paths = (0, paths_1.createCliPaths)(env);
71
91
  const runtimeConfig = await (0, runtime_config_1.loadRuntimeConfig)(env, paths);
72
92
  logger.setDebugMode(parsedArgv.debug || runtimeConfig.debug);
73
93
  const tokenStore = new token_store_1.TokenStore(paths.authStateFile);
74
94
  const installationStore = new installation_store_1.InstallationStore(paths.installationStateFile);
75
- const resolvedCommand = resolveCommand(parsedArgv.tokens);
76
95
  const unknownToken = resolvedCommand.remainingArgs[0];
77
96
  const canTraverseFurther = Boolean(resolvedCommand.command.children?.length && unknownToken);
78
97
  const locale = runtimeConfig.locale;
@@ -96,19 +115,22 @@ async function runCli(argv, env, deps = {}) {
96
115
  logger.plain((0, help_1.renderHelp)(resolvedCommand.command, resolvedCommand.path, locale));
97
116
  return 0;
98
117
  }
99
- await (0, paths_1.ensureCliDirectories)(paths);
100
- const preflightExitCode = await (deps.runStartupPreflight ?? preflight_1.runStartupPreflight)({
101
- argv,
102
- env,
103
- logger,
104
- paths,
105
- runtimeConfig,
106
- commandPath: resolvedCommand.path,
107
- cwd: process.cwd(),
108
- homeDir: (0, node_os_1.homedir)(),
109
- });
110
- if (typeof preflightExitCode === 'number') {
111
- return preflightExitCode;
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
+ }
112
134
  }
113
135
  try {
114
136
  return await resolvedCommand.command.run(context, resolvedCommand.remainingArgs);
@@ -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
+ };
@@ -1,6 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXPLICIT_UPDATE_TARGET_VERSION_ENV = exports.EXPLICIT_UPDATE_REEXEC_ENV = exports.PREFLIGHT_GUARD_ENV = void 0;
4
+ exports.shouldSkipManagedSync = shouldSkipManagedSync;
5
+ exports.shouldSkipCliUpdate = shouldSkipCliUpdate;
6
+ exports.canPromptForUpdate = canPromptForUpdate;
7
+ exports.fetchLatestPublishedVersion = fetchLatestPublishedVersion;
8
+ exports.performSelfUpdate = performSelfUpdate;
9
+ exports.reexecCommand = reexecCommand;
3
10
  exports.resolveUpdateAction = resolveUpdateAction;
11
+ exports.runExplicitUpdate = runExplicitUpdate;
4
12
  exports.runStartupPreflight = runStartupPreflight;
5
13
  const node_child_process_1 = require("node:child_process");
6
14
  const paths_1 = require("../../state/paths");
@@ -11,7 +19,9 @@ const managed_pack_1 = require("../init/managed-pack");
11
19
  const package_metadata_1 = require("../runtime/package-metadata");
12
20
  const version_1 = require("./version");
13
21
  const UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
14
- const PREFLIGHT_GUARD_ENV = 'VAONE_SKIP_PREFLIGHT';
22
+ exports.PREFLIGHT_GUARD_ENV = 'VAONE_SKIP_PREFLIGHT';
23
+ exports.EXPLICIT_UPDATE_REEXEC_ENV = 'VAONE_EXPLICIT_UPDATE_REEXEC';
24
+ exports.EXPLICIT_UPDATE_TARGET_VERSION_ENV = 'VAONE_EXPLICIT_UPDATE_TARGET_VERSION';
15
25
  const UPDATE_COPY = {
16
26
  en: {
17
27
  promptTitle(currentVersion, latestVersion) {
@@ -57,10 +67,14 @@ function shouldSkipManagedSync(commandPath) {
57
67
  return (commandPath.length === 0 ||
58
68
  commandPath[0] === 'init' ||
59
69
  commandPath[0] === 'doctor' ||
60
- commandPath[0] === 'uninstall');
70
+ commandPath[0] === 'uninstall' ||
71
+ commandPath[0] === 'update' ||
72
+ commandPath[0] === 'version');
61
73
  }
62
74
  function shouldSkipCliUpdate(commandPath) {
63
- return commandPath[0] === 'doctor';
75
+ return (commandPath[0] === 'doctor' ||
76
+ commandPath[0] === 'update' ||
77
+ commandPath[0] === 'version');
64
78
  }
65
79
  function canPromptForUpdate(env) {
66
80
  return (process.stdin.isTTY === true &&
@@ -101,7 +115,7 @@ async function performSelfUpdate(packageName, version) {
101
115
  failureMessage: result.stderr?.trim() || result.stdout?.trim() || 'npm update failed.',
102
116
  };
103
117
  }
104
- async function reexecCommand(argv) {
118
+ async function reexecCommand(argv, extraEnv) {
105
119
  if (!process.argv[1]) {
106
120
  return null;
107
121
  }
@@ -109,7 +123,8 @@ async function reexecCommand(argv) {
109
123
  stdio: 'inherit',
110
124
  env: {
111
125
  ...process.env,
112
- [PREFLIGHT_GUARD_ENV]: '1',
126
+ [exports.PREFLIGHT_GUARD_ENV]: '1',
127
+ ...extraEnv,
113
128
  },
114
129
  });
115
130
  if (typeof result.status === 'number') {
@@ -144,14 +159,17 @@ async function resolveUpdateAction(input) {
144
159
  ],
145
160
  })
146
161
  .then((choice) => ({ kind: 'choice', choice }), (error) => ({ kind: 'error', error }));
147
- const timeoutMs = input.timeoutMs ?? 5_000;
148
- const timeoutPromise = new Promise((resolve) => {
149
- setTimeout(() => {
150
- void prompt.close().catch(() => undefined);
151
- resolve({ kind: 'timeout' });
152
- }, timeoutMs);
153
- });
154
- const result = await Promise.race([selectionPromise, timeoutPromise]);
162
+ const result = input.timeoutMs === null
163
+ ? await selectionPromise
164
+ : await Promise.race([
165
+ selectionPromise,
166
+ new Promise((resolve) => {
167
+ setTimeout(() => {
168
+ void prompt.close().catch(() => undefined);
169
+ resolve({ kind: 'timeout' });
170
+ }, input.timeoutMs ?? 5_000);
171
+ }),
172
+ ]);
155
173
  if (result.kind === 'timeout') {
156
174
  input.logger.info(copy.timeoutNotice(input.latestVersion));
157
175
  return 'update';
@@ -161,25 +179,211 @@ async function resolveUpdateAction(input) {
161
179
  }
162
180
  return result.choice;
163
181
  }
182
+ function createUpdateStateStore(paths) {
183
+ return new update_state_store_1.UpdateStateStore((0, paths_1.resolveUpdateStateFile)(paths));
184
+ }
185
+ function formatManagedPackRefreshSummary(refreshed) {
186
+ return refreshed
187
+ .map((entry) => `${entry.target.displayName} (${entry.scope})`)
188
+ .join(', ');
189
+ }
190
+ async function syncManagedPacksForVersion(input) {
191
+ const refreshed = await (input.syncManagedPacksImpl ?? managed_pack_1.syncManagedPacks)({
192
+ cwd: input.cwd,
193
+ homeDir: input.homeDir,
194
+ currentVersion: input.currentVersion,
195
+ });
196
+ if (refreshed.length > 0) {
197
+ input.logger.info(`Refreshed stale managed skill packs: ${formatManagedPackRefreshSummary(refreshed)}.`);
198
+ }
199
+ return refreshed;
200
+ }
201
+ async function resolvePublishedUpdate(input) {
202
+ const updateStateStore = createUpdateStateStore(input.paths);
203
+ const updateState = (await updateStateStore.read()) ?? {};
204
+ try {
205
+ const latestVersion = await (input.fetchLatestVersionImpl ?? fetchLatestPublishedVersion)(input.packageName);
206
+ return {
207
+ latestVersion,
208
+ updateStateStore,
209
+ updateState,
210
+ nextState: {
211
+ ...updateState,
212
+ lastCheckedAt: new Date(input.now()).toISOString(),
213
+ lastKnownLatestVersion: latestVersion,
214
+ },
215
+ };
216
+ }
217
+ catch (error) {
218
+ await updateStateStore.save({
219
+ ...updateState,
220
+ lastCheckedAt: new Date(input.now()).toISOString(),
221
+ lastFailureCode: 'version_check_failed',
222
+ lastFailureMessage: error instanceof Error ? error.message : 'Version check failed.',
223
+ });
224
+ throw error;
225
+ }
226
+ }
227
+ function createExplicitRestartEnv(latestVersion) {
228
+ return {
229
+ [exports.EXPLICIT_UPDATE_REEXEC_ENV]: '1',
230
+ [exports.EXPLICIT_UPDATE_TARGET_VERSION_ENV]: latestVersion,
231
+ };
232
+ }
233
+ async function runExplicitUpdate(input, deps = {}) {
234
+ const runtimePackage = (await deps.resolvePackageInfo?.()) ?? (await (0, package_metadata_1.resolveRuntimePackageInfo)());
235
+ if (input.env[exports.EXPLICIT_UPDATE_REEXEC_ENV] === '1') {
236
+ const updatedVersion = input.env[exports.EXPLICIT_UPDATE_TARGET_VERSION_ENV] ?? runtimePackage.version;
237
+ input.logger.info(`VAOne CLI updated to ${updatedVersion}.`);
238
+ try {
239
+ const refreshed = await syncManagedPacksForVersion({
240
+ logger: input.logger,
241
+ cwd: input.cwd,
242
+ homeDir: input.homeDir,
243
+ currentVersion: runtimePackage.version,
244
+ syncManagedPacksImpl: deps.syncManagedPacks,
245
+ });
246
+ if (refreshed.length === 0) {
247
+ input.logger.info('No stale VA-managed skill packs were found.');
248
+ }
249
+ return 0;
250
+ }
251
+ catch (error) {
252
+ input.logger.error(`Managed skill-pack sync failed after CLI update: ${error instanceof Error ? error.message : 'unknown error'}`);
253
+ return 1;
254
+ }
255
+ }
256
+ if (!runtimePackage.isPackagedInstall) {
257
+ input.logger.error('`vaone update` only works from the packaged npm install. Local repository runs must update dependencies manually.');
258
+ return 1;
259
+ }
260
+ const now = deps.now ?? Date.now;
261
+ let publishedUpdate;
262
+ try {
263
+ publishedUpdate = await resolvePublishedUpdate({
264
+ now,
265
+ logger: input.logger,
266
+ paths: input.paths,
267
+ packageName: runtimePackage.name,
268
+ fetchLatestVersionImpl: deps.fetchLatestVersion,
269
+ });
270
+ }
271
+ catch (error) {
272
+ input.logger.error(`CLI update check failed: ${error instanceof Error ? error.message : 'unknown error'}`);
273
+ return 1;
274
+ }
275
+ const { latestVersion, nextState, updateStateStore } = publishedUpdate;
276
+ if ((0, version_1.isVersionNewer)(latestVersion, runtimePackage.version)) {
277
+ const interactive = canPromptForUpdate(input.env);
278
+ const action = interactive
279
+ ? await resolveUpdateAction({
280
+ currentVersion: runtimePackage.version,
281
+ latestVersion,
282
+ locale: input.runtimeConfig.locale,
283
+ logger: input.logger,
284
+ promptFactory: deps.promptFactory,
285
+ timeoutMs: null,
286
+ })
287
+ : 'update';
288
+ if (!interactive) {
289
+ input.logger.info(`No interactive terminal detected. Updating VAOne CLI to ${latestVersion}.`);
290
+ }
291
+ if (action === 'defer') {
292
+ await (0, runtime_config_1.saveRuntimeConfig)(input.paths, {
293
+ updateDeferredUntilVersion: latestVersion,
294
+ });
295
+ input.runtimeConfig.updateDeferredUntilVersion = latestVersion;
296
+ await updateStateStore.save({
297
+ ...nextState,
298
+ lastFailureCode: undefined,
299
+ lastFailureMessage: undefined,
300
+ });
301
+ input.logger.info(`Deferred CLI self-update until a version newer than ${latestVersion} is published.`);
302
+ }
303
+ else if (action === 'skip') {
304
+ await updateStateStore.save({
305
+ ...nextState,
306
+ lastFailureCode: undefined,
307
+ lastFailureMessage: undefined,
308
+ });
309
+ input.logger.info('Skipped CLI self-update for this run.');
310
+ }
311
+ else {
312
+ const copy = UPDATE_COPY[input.runtimeConfig.locale];
313
+ input.logger.info(copy.updatingNotice(latestVersion));
314
+ const result = await (deps.performSelfUpdate ?? performSelfUpdate)(runtimePackage.name, latestVersion);
315
+ if (!result.success) {
316
+ await updateStateStore.save({
317
+ ...nextState,
318
+ lastAttemptedUpdateAt: new Date(now()).toISOString(),
319
+ lastAttemptedTargetVersion: latestVersion,
320
+ lastFailureCode: result.failureCode,
321
+ lastFailureMessage: result.failureMessage,
322
+ });
323
+ input.logger.error(result.failureMessage ?? 'CLI update failed.');
324
+ return 1;
325
+ }
326
+ await (0, runtime_config_1.saveRuntimeConfig)(input.paths, {
327
+ updateDeferredUntilVersion: undefined,
328
+ });
329
+ input.runtimeConfig.updateDeferredUntilVersion = undefined;
330
+ await updateStateStore.save({
331
+ ...nextState,
332
+ lastAttemptedUpdateAt: new Date(now()).toISOString(),
333
+ lastAttemptedTargetVersion: latestVersion,
334
+ lastFailureCode: undefined,
335
+ lastFailureMessage: undefined,
336
+ });
337
+ input.logger.info(copy.restartingNotice);
338
+ const exitCode = await (deps.reexecCommand ?? reexecCommand)(input.argv, createExplicitRestartEnv(latestVersion));
339
+ if (typeof exitCode === 'number') {
340
+ return exitCode;
341
+ }
342
+ input.logger.error('CLI update completed, but restarting `vaone update` did not return an exit code.');
343
+ return 1;
344
+ }
345
+ }
346
+ else {
347
+ await updateStateStore.save({
348
+ ...nextState,
349
+ lastFailureCode: undefined,
350
+ lastFailureMessage: undefined,
351
+ });
352
+ input.logger.info(`VAOne CLI is already up to date (${runtimePackage.version}).`);
353
+ }
354
+ try {
355
+ const refreshed = await syncManagedPacksForVersion({
356
+ logger: input.logger,
357
+ cwd: input.cwd,
358
+ homeDir: input.homeDir,
359
+ currentVersion: runtimePackage.version,
360
+ syncManagedPacksImpl: deps.syncManagedPacks,
361
+ });
362
+ if (refreshed.length === 0) {
363
+ input.logger.info('No stale VA-managed skill packs were found.');
364
+ }
365
+ return 0;
366
+ }
367
+ catch (error) {
368
+ input.logger.error(`Managed skill-pack sync failed: ${error instanceof Error ? error.message : 'unknown error'}`);
369
+ return 1;
370
+ }
371
+ }
164
372
  async function runStartupPreflight(input, deps = {}) {
165
- if (input.env[PREFLIGHT_GUARD_ENV] === '1') {
373
+ if (input.env[exports.PREFLIGHT_GUARD_ENV] === '1') {
166
374
  return null;
167
375
  }
168
376
  const now = deps.now ?? Date.now;
169
377
  const runtimePackage = (await deps.resolvePackageInfo?.()) ?? (await (0, package_metadata_1.resolveRuntimePackageInfo)());
170
378
  if (!shouldSkipManagedSync(input.commandPath)) {
171
379
  try {
172
- const refreshed = await (deps.syncManagedPacks ?? managed_pack_1.syncManagedPacks)({
380
+ await syncManagedPacksForVersion({
381
+ logger: input.logger,
173
382
  cwd: input.cwd,
174
383
  homeDir: input.homeDir,
175
384
  currentVersion: runtimePackage.version,
385
+ syncManagedPacksImpl: deps.syncManagedPacks,
176
386
  });
177
- if (refreshed.length > 0) {
178
- const summary = refreshed
179
- .map((entry) => `${entry.target.displayName} (${entry.scope})`)
180
- .join(', ');
181
- input.logger.info(`Refreshed stale managed skill packs: ${summary}.`);
182
- }
183
387
  }
184
388
  catch (error) {
185
389
  input.logger.warn(`Managed skill-pack sync failed: ${error instanceof Error ? error.message : 'unknown error'}`);
@@ -191,7 +395,7 @@ async function runStartupPreflight(input, deps = {}) {
191
395
  if (!runtimePackage.isPackagedInstall || !canPromptForUpdate(input.env)) {
192
396
  return null;
193
397
  }
194
- const updateStateStore = new update_state_store_1.UpdateStateStore((0, paths_1.resolveUpdateStateFile)(input.paths));
398
+ const updateStateStore = createUpdateStateStore(input.paths);
195
399
  const updateState = (await updateStateStore.read()) ?? {};
196
400
  const lastCheckedAt = updateState.lastCheckedAt
197
401
  ? Date.parse(updateState.lastCheckedAt)
@@ -202,15 +406,15 @@ async function runStartupPreflight(input, deps = {}) {
202
406
  }
203
407
  let latestVersion;
204
408
  try {
205
- latestVersion = await (deps.fetchLatestVersion ?? fetchLatestPublishedVersion)(runtimePackage.name);
409
+ latestVersion = (await resolvePublishedUpdate({
410
+ now,
411
+ logger: input.logger,
412
+ paths: input.paths,
413
+ packageName: runtimePackage.name,
414
+ fetchLatestVersionImpl: deps.fetchLatestVersion,
415
+ })).latestVersion;
206
416
  }
207
417
  catch (error) {
208
- await updateStateStore.save({
209
- ...updateState,
210
- lastCheckedAt: new Date(now()).toISOString(),
211
- lastFailureCode: 'version_check_failed',
212
- lastFailureMessage: error instanceof Error ? error.message : 'Version check failed.',
213
- });
214
418
  input.logger.warn(`CLI update check failed: ${error instanceof Error ? error.message : 'unknown error'}`);
215
419
  return null;
216
420
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solarains/va-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Bootstrap CLI for the VAOne product.",
5
5
  "bin": {
6
6
  "vaone": "dist/main.js"