@copado/agentia-cli 0.46.0-alpha.0 → 0.51.0-alpha.0

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.
@@ -0,0 +1,10 @@
1
+ import { AgentiaCommand } from '../lib/agentia-command.js';
2
+ import { type CliUpdateResult } from '../lib/cli-update.js';
3
+ export default class Update extends AgentiaCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ check: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<CliUpdateResult>;
10
+ }
@@ -0,0 +1,39 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { AgentiaCommand } from '../lib/agentia-command.js';
3
+ import { runCliUpdate } from '../lib/cli-update.js';
4
+ export default class Update extends AgentiaCommand {
5
+ static description = 'Update the globally installed Agentia CLI to the newest alpha release';
6
+ static examples = [
7
+ '<%= config.bin %> <%= command.id %>',
8
+ '<%= config.bin %> <%= command.id %> --check',
9
+ '<%= config.bin %> <%= command.id %> --check --json',
10
+ ];
11
+ static flags = {
12
+ check: Flags.boolean({
13
+ description: 'Check for an update without installing it',
14
+ }),
15
+ };
16
+ async run() {
17
+ const { flags } = await this.parse(Update);
18
+ const result = await this.withSpinner(flags.check ? 'Checking for Agentia CLI updates' : 'Updating Agentia CLI', () => runCliUpdate({
19
+ checkOnly: flags.check,
20
+ currentVersion: this.config.version,
21
+ }));
22
+ this.display(() => {
23
+ if (result.updated) {
24
+ this.log(`Updated Agentia CLI from ${result.currentVersion} to ${result.latestVersion}. Re-run \`agentia --version\` to verify the new installation.`);
25
+ }
26
+ else if (result.updateAvailable) {
27
+ this.log(`Agentia CLI ${result.latestVersion} is available (current: ${result.currentVersion}). Run \`agentia update\` to install it.`);
28
+ }
29
+ else if (result.versionState === 'ahead') {
30
+ this.log(`Installed Agentia CLI ${result.currentVersion} is newer than the ${result.channel} channel release ${result.latestVersion}.`);
31
+ }
32
+ else {
33
+ this.log(`Agentia CLI ${result.currentVersion} is already current on the ${result.channel} channel.`);
34
+ }
35
+ });
36
+ return result;
37
+ }
38
+ }
39
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AAEjC,OAAO,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAuB,YAAY,EAAC,MAAM,sBAAsB,CAAA;AAEvE,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,cAAc;IAChD,MAAM,CAAU,WAAW,GAAG,uEAAuE,CAAA;IACrG,MAAM,CAAU,QAAQ,GAAG;QACzB,qCAAqC;QACrC,6CAA6C;QAC7C,oDAAoD;KACrD,CAAA;IACD,MAAM,CAAU,KAAK,GAAG;QACtB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,WAAW,EAAE,2CAA2C;SACzD,CAAC;KACH,CAAA;IAEM,KAAK,CAAC,GAAG;QACd,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,sBAAsB,EAAE,GAAG,EAAE,CACpH,YAAY,CAAC;YACX,SAAS,EAAE,KAAK,CAAC,KAAK;YACtB,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;SACpC,CAAC,CACH,CAAA;QAED,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE;YAChB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,IAAI,CAAC,GAAG,CACN,4BAA4B,MAAM,CAAC,cAAc,OAAO,MAAM,CAAC,aAAa,gEAAgE,CAC7I,CAAA;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;gBAClC,IAAI,CAAC,GAAG,CACN,eAAe,MAAM,CAAC,aAAa,2BAA2B,MAAM,CAAC,cAAc,0CAA0C,CAC9H,CAAA;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,YAAY,KAAK,OAAO,EAAE,CAAC;gBAC3C,IAAI,CAAC,GAAG,CACN,yBAAyB,MAAM,CAAC,cAAc,sBAAsB,MAAM,CAAC,OAAO,oBAAoB,MAAM,CAAC,aAAa,GAAG,CAC9H,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,cAAc,8BAA8B,MAAM,CAAC,OAAO,WAAW,CAAC,CAAA;YACvG,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,OAAO,MAAM,CAAA;IACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type Hook } from '@oclif/core';
2
+ declare const hook: Hook<'init'>;
3
+ export default hook;
@@ -0,0 +1,19 @@
1
+ import { checkVersionWarning } from '../../lib/version-warning.js';
2
+ const hook = async function ({ config, id }) {
3
+ try {
4
+ const result = await checkVersionWarning({
5
+ cacheDir: config.cacheDir,
6
+ commandId: id,
7
+ currentVersion: config.version,
8
+ skip: config.scopedEnvVarTrue('SKIP_NEW_VERSION_CHECK'),
9
+ });
10
+ if (result.warning !== undefined) {
11
+ this.warn(result.warning);
12
+ }
13
+ }
14
+ catch {
15
+ // A best-effort version check must never block the requested command.
16
+ }
17
+ };
18
+ export default hook;
19
+ //# sourceMappingURL=version-warning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-warning.js","sourceRoot":"","sources":["../../../src/hooks/init/version-warning.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAA;AAEhE,MAAM,IAAI,GAAiB,KAAK,WAAW,EAAC,MAAM,EAAE,EAAE,EAAC;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;YACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,EAAE;YACb,cAAc,EAAE,MAAM,CAAC,OAAO;YAC9B,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC;SACxD,CAAC,CAAA;QAEF,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;AACH,CAAC,CAAA;AAED,eAAe,IAAI,CAAA"}
@@ -0,0 +1,27 @@
1
+ export type CliUpdateResult = {
2
+ channel: string;
3
+ checkedOnly: boolean;
4
+ currentVersion: string;
5
+ latestVersion: string;
6
+ packageName: string;
7
+ updateAvailable: boolean;
8
+ updated: boolean;
9
+ versionState: 'ahead' | 'current' | 'update-available';
10
+ };
11
+ export type CliUpdateExecutor = (command: string, args: readonly string[]) => Promise<void>;
12
+ export declare class CliUpdateError extends Error {
13
+ constructor(message: string);
14
+ }
15
+ export declare function setCliUpdateExecutorForTests(nextExecutor: CliUpdateExecutor | undefined): void;
16
+ export declare function npmExecutable(platform?: NodeJS.Platform): string;
17
+ export declare function npmUpdateArguments(version: string): string[];
18
+ export declare function npmExecOptions(platform?: NodeJS.Platform): {
19
+ maxBuffer: number;
20
+ shell: boolean;
21
+ windowsHide: boolean;
22
+ };
23
+ export declare function executeNpmUpdate(command: string, args: readonly string[]): Promise<void>;
24
+ export declare function runCliUpdate(options: {
25
+ checkOnly?: boolean;
26
+ currentVersion: string;
27
+ }): Promise<CliUpdateResult>;
@@ -0,0 +1,65 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { AGENTIA_NPM_REGISTRY, AGENTIA_PACKAGE_NAME, AGENTIA_RELEASE_CHANNEL, fetchChannelVersion, isNewerVersion, } from './cli-version.js';
4
+ const execFileAsync = promisify(execFile);
5
+ let executeUpdateFn = executeNpmUpdate;
6
+ export class CliUpdateError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = 'CliUpdateError';
10
+ }
11
+ }
12
+ export function setCliUpdateExecutorForTests(nextExecutor) {
13
+ executeUpdateFn = nextExecutor ?? executeNpmUpdate;
14
+ }
15
+ export function npmExecutable(platform = process.platform) {
16
+ return platform === 'win32' ? 'npm.cmd' : 'npm';
17
+ }
18
+ export function npmUpdateArguments(version) {
19
+ return ['install', '--global', `${AGENTIA_PACKAGE_NAME}@${version}`, '--registry', AGENTIA_NPM_REGISTRY];
20
+ }
21
+ export function npmExecOptions(platform = process.platform) {
22
+ return {
23
+ maxBuffer: 10 * 1024 * 1024,
24
+ shell: platform === 'win32',
25
+ windowsHide: true,
26
+ };
27
+ }
28
+ export async function executeNpmUpdate(command, args) {
29
+ try {
30
+ await execFileAsync(command, [...args], npmExecOptions());
31
+ }
32
+ catch (error) {
33
+ const details = error instanceof Error ? error.message : '';
34
+ if (/EACCES|EPERM|permission denied/i.test(details)) {
35
+ throw new CliUpdateError('npm does not have permission to update the global Agentia CLI installation. Configure a writable npm global prefix and retry.');
36
+ }
37
+ throw new CliUpdateError(`npm could not update the Agentia CLI. Run \`${command} ${args.join(' ')}\` manually for npm diagnostics.`);
38
+ }
39
+ }
40
+ export async function runCliUpdate(options) {
41
+ const latestVersion = await fetchChannelVersion();
42
+ const updateAvailable = isNewerVersion(latestVersion, options.currentVersion);
43
+ const versionState = updateAvailable
44
+ ? 'update-available'
45
+ : isNewerVersion(options.currentVersion, latestVersion)
46
+ ? 'ahead'
47
+ : 'current';
48
+ const checkedOnly = options.checkOnly ?? false;
49
+ let updated = false;
50
+ if (updateAvailable && !checkedOnly) {
51
+ await executeUpdateFn(npmExecutable(), npmUpdateArguments(latestVersion));
52
+ updated = true;
53
+ }
54
+ return {
55
+ channel: AGENTIA_RELEASE_CHANNEL,
56
+ checkedOnly,
57
+ currentVersion: options.currentVersion,
58
+ latestVersion,
59
+ packageName: AGENTIA_PACKAGE_NAME,
60
+ updateAvailable,
61
+ updated,
62
+ versionState,
63
+ };
64
+ }
65
+ //# sourceMappingURL=cli-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-update.js","sourceRoot":"","sources":["../../src/lib/cli-update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export declare const AGENTIA_PACKAGE_NAME = "@copado/agentia-cli";
2
+ export declare const AGENTIA_RELEASE_CHANNEL = "alpha";
3
+ export declare const AGENTIA_NPM_REGISTRY = "https://registry.npmjs.org";
4
+ export declare const VERSION_CACHE_FILENAME = "version-check.json";
5
+ export declare const VERSION_CHECK_INTERVAL_MS: number;
6
+ export type VersionCache = {
7
+ channel: string;
8
+ checkedAt: string;
9
+ latestVersion?: string;
10
+ };
11
+ export type VersionRegistryResponse = {
12
+ body: unknown;
13
+ statusCode: number;
14
+ };
15
+ export type VersionRegistryClient = (url: string, timeoutMs: number) => Promise<VersionRegistryResponse>;
16
+ export declare class CliVersionError extends Error {
17
+ constructor(message: string);
18
+ }
19
+ export declare function setCliVersionRegistryClientForTests(nextClient: undefined | VersionRegistryClient): void;
20
+ export declare function versionCachePath(cacheDir: string): string;
21
+ export declare function isNewerVersion(candidate: string, current: string): boolean;
22
+ export declare function isVersionCacheStale(cache: undefined | VersionCache, now?: Date, intervalMs?: number): boolean;
23
+ export declare function readVersionCache(cachePath: string): Promise<undefined | VersionCache>;
24
+ export declare function writeVersionCache(cachePath: string, cache: VersionCache): Promise<void>;
25
+ export declare function defaultVersionRegistryClient(url: string, timeoutMs: number): Promise<VersionRegistryResponse>;
26
+ export declare function fetchChannelVersion(options?: {
27
+ client?: VersionRegistryClient;
28
+ timeoutMs?: number;
29
+ }): Promise<string>;
30
+ export declare function refreshVersionCache(cachePath: string, now?: Date): Promise<VersionCache>;
@@ -0,0 +1,142 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
+ import { get } from 'node:https';
4
+ import path from 'node:path';
5
+ import semver from 'semver';
6
+ export const AGENTIA_PACKAGE_NAME = '@copado/agentia-cli';
7
+ export const AGENTIA_RELEASE_CHANNEL = 'alpha';
8
+ export const AGENTIA_NPM_REGISTRY = 'https://registry.npmjs.org';
9
+ export const VERSION_CACHE_FILENAME = 'version-check.json';
10
+ export const VERSION_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
11
+ let registryClientFn = defaultVersionRegistryClient;
12
+ export class CliVersionError extends Error {
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = 'CliVersionError';
16
+ }
17
+ }
18
+ export function setCliVersionRegistryClientForTests(nextClient) {
19
+ registryClientFn = nextClient ?? defaultVersionRegistryClient;
20
+ }
21
+ export function versionCachePath(cacheDir) {
22
+ return path.join(cacheDir, VERSION_CACHE_FILENAME);
23
+ }
24
+ export function isNewerVersion(candidate, current) {
25
+ if (semver.valid(candidate) === null) {
26
+ throw new CliVersionError(`npm returned an invalid Agentia CLI version: ${candidate}`);
27
+ }
28
+ if (semver.valid(current) === null) {
29
+ throw new CliVersionError(`The installed Agentia CLI version is invalid: ${current}`);
30
+ }
31
+ return semver.gt(candidate, current);
32
+ }
33
+ export function isVersionCacheStale(cache, now = new Date(), intervalMs = VERSION_CHECK_INTERVAL_MS) {
34
+ if (cache === undefined || cache.channel !== AGENTIA_RELEASE_CHANNEL) {
35
+ return true;
36
+ }
37
+ const checkedAt = Date.parse(cache.checkedAt);
38
+ return Number.isNaN(checkedAt) || now.getTime() - checkedAt >= intervalMs;
39
+ }
40
+ export async function readVersionCache(cachePath) {
41
+ try {
42
+ const parsed = JSON.parse(await readFile(cachePath, 'utf8'));
43
+ if (typeof parsed.checkedAt !== 'string' || typeof parsed.channel !== 'string') {
44
+ return undefined;
45
+ }
46
+ if (parsed.latestVersion !== undefined &&
47
+ (typeof parsed.latestVersion !== 'string' || semver.valid(parsed.latestVersion) === null)) {
48
+ return undefined;
49
+ }
50
+ return {
51
+ channel: parsed.channel,
52
+ checkedAt: parsed.checkedAt,
53
+ ...(parsed.latestVersion === undefined ? {} : { latestVersion: parsed.latestVersion }),
54
+ };
55
+ }
56
+ catch {
57
+ return undefined;
58
+ }
59
+ }
60
+ export async function writeVersionCache(cachePath, cache) {
61
+ await mkdir(path.dirname(cachePath), { recursive: true });
62
+ const temporaryPath = `${cachePath}.${process.pid}.${randomUUID()}.tmp`;
63
+ try {
64
+ await writeFile(temporaryPath, `${JSON.stringify(cache)}\n`, 'utf8');
65
+ await rename(temporaryPath, cachePath);
66
+ }
67
+ catch (error) {
68
+ await rm(temporaryPath, { force: true }).catch(() => { });
69
+ throw error;
70
+ }
71
+ }
72
+ export async function defaultVersionRegistryClient(url, timeoutMs) {
73
+ return new Promise((resolve, reject) => {
74
+ const request = get(url, {
75
+ headers: { accept: 'application/json' },
76
+ timeout: timeoutMs,
77
+ }, (response) => {
78
+ let body = '';
79
+ response.setEncoding('utf8');
80
+ response.on('data', (chunk) => {
81
+ body += chunk;
82
+ });
83
+ response.once('end', () => {
84
+ try {
85
+ resolve({
86
+ body: JSON.parse(body),
87
+ statusCode: response.statusCode ?? 0,
88
+ });
89
+ }
90
+ catch (error) {
91
+ reject(error);
92
+ }
93
+ });
94
+ });
95
+ request.once('timeout', () => {
96
+ request.destroy(new Error('npm registry request timed out'));
97
+ });
98
+ request.once('error', reject);
99
+ });
100
+ }
101
+ export async function fetchChannelVersion(options = {}) {
102
+ const client = options.client ?? registryClientFn;
103
+ const timeoutMs = options.timeoutMs ?? 5000;
104
+ const packagePath = encodeURIComponent(AGENTIA_PACKAGE_NAME);
105
+ const url = `${AGENTIA_NPM_REGISTRY}/-/package/${packagePath}/dist-tags`;
106
+ let response;
107
+ try {
108
+ response = await client(url, timeoutMs);
109
+ }
110
+ catch {
111
+ throw new CliVersionError(`Unable to reach npm while checking the Agentia CLI ${AGENTIA_RELEASE_CHANNEL} channel.`);
112
+ }
113
+ if (response.statusCode < 200 || response.statusCode >= 300) {
114
+ throw new CliVersionError(`npm returned HTTP ${response.statusCode} while checking the Agentia CLI ${AGENTIA_RELEASE_CHANNEL} channel.`);
115
+ }
116
+ if (typeof response.body !== 'object' || response.body === null || Array.isArray(response.body)) {
117
+ throw new CliVersionError(`npm did not return valid dist-tags for the Agentia CLI.`);
118
+ }
119
+ const tags = response.body;
120
+ const version = tags[AGENTIA_RELEASE_CHANNEL];
121
+ if (typeof version !== 'string' || semver.valid(version) === null) {
122
+ throw new CliVersionError(`npm did not return a valid Agentia CLI ${AGENTIA_RELEASE_CHANNEL} version.`);
123
+ }
124
+ return version;
125
+ }
126
+ export async function refreshVersionCache(cachePath, now = new Date()) {
127
+ const checkedAt = now.toISOString();
128
+ const existing = await readVersionCache(cachePath);
129
+ const marker = {
130
+ channel: AGENTIA_RELEASE_CHANNEL,
131
+ checkedAt,
132
+ ...(existing?.channel === AGENTIA_RELEASE_CHANNEL && existing.latestVersion !== undefined
133
+ ? { latestVersion: existing.latestVersion }
134
+ : {}),
135
+ };
136
+ await writeVersionCache(cachePath, marker);
137
+ const latestVersion = await fetchChannelVersion();
138
+ const cache = { channel: AGENTIA_RELEASE_CHANNEL, checkedAt, latestVersion };
139
+ await writeVersionCache(cachePath, cache);
140
+ return cache;
141
+ }
142
+ //# sourceMappingURL=cli-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-version.js","sourceRoot":"","sources":["../../src/lib/cli-version.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { refreshVersionCache } from './cli-version.js';
2
+ const cachePath = process.argv[2];
3
+ if (cachePath !== undefined) {
4
+ await refreshVersionCache(cachePath).catch(() => {
5
+ // Version checks are best effort and must never affect command execution.
6
+ });
7
+ }
8
+ //# sourceMappingURL=version-refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-refresh.js","sourceRoot":"","sources":["../../src/lib/version-refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAA;AAEpD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAEjC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;IAC5B,MAAM,mBAAmB,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QAC9C,0EAA0E;IAC5E,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ export type VersionWarningOptions = {
2
+ cacheDir: string;
3
+ commandId?: string;
4
+ currentVersion: string;
5
+ now?: Date;
6
+ skip?: boolean;
7
+ };
8
+ export type VersionWarningResult = {
9
+ latestVersion?: string;
10
+ refreshStarted: boolean;
11
+ warning?: string;
12
+ };
13
+ export type VersionRefreshSpawner = (cachePath: string) => void;
14
+ export type DetachedChild = {
15
+ once(event: 'error', listener: (error: Error) => void): DetachedChild;
16
+ unref(): void;
17
+ };
18
+ export type DetachedSpawn = (command: string, args: readonly string[], options: {
19
+ detached: boolean;
20
+ stdio: 'ignore';
21
+ windowsHide: boolean;
22
+ }) => DetachedChild;
23
+ export declare function setVersionRefreshSpawnerForTests(nextSpawner: undefined | VersionRefreshSpawner): void;
24
+ export declare function setVersionWarningChildSpawnForTests(nextSpawn: DetachedSpawn | undefined): void;
25
+ export declare function formatVersionWarning(currentVersion: string, latestVersion: string): string;
26
+ export declare function spawnVersionRefresh(cachePath: string): void;
27
+ export declare function checkVersionWarning(options: VersionWarningOptions): Promise<VersionWarningResult>;
@@ -0,0 +1,51 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { AGENTIA_RELEASE_CHANNEL, isNewerVersion, isVersionCacheStale, readVersionCache, versionCachePath, } from './cli-version.js';
4
+ let spawnRefreshFn = spawnVersionRefresh;
5
+ let spawnChildFn = spawn;
6
+ export function setVersionRefreshSpawnerForTests(nextSpawner) {
7
+ spawnRefreshFn = nextSpawner ?? spawnVersionRefresh;
8
+ }
9
+ export function setVersionWarningChildSpawnForTests(nextSpawn) {
10
+ spawnChildFn = nextSpawn ?? spawn;
11
+ }
12
+ export function formatVersionWarning(currentVersion, latestVersion) {
13
+ return `Agentia CLI ${AGENTIA_RELEASE_CHANNEL} update available from ${currentVersion} to ${latestVersion}. Run \`agentia update\`.`;
14
+ }
15
+ export function spawnVersionRefresh(cachePath) {
16
+ const workerPath = fileURLToPath(new URL('version-refresh.js', import.meta.url));
17
+ const child = spawnChildFn(process.execPath, [workerPath, cachePath], {
18
+ detached: process.platform !== 'win32',
19
+ stdio: 'ignore',
20
+ windowsHide: true,
21
+ });
22
+ child.once('error', () => {
23
+ // Detached refresh failures are best effort and must not affect the active command.
24
+ });
25
+ child.unref();
26
+ }
27
+ export async function checkVersionWarning(options) {
28
+ if (options.skip || options.commandId === 'update') {
29
+ return { refreshStarted: false };
30
+ }
31
+ const cachePath = versionCachePath(options.cacheDir);
32
+ const cache = await readVersionCache(cachePath);
33
+ let latestVersion;
34
+ let warning;
35
+ if (cache?.channel === AGENTIA_RELEASE_CHANNEL &&
36
+ cache.latestVersion !== undefined &&
37
+ isNewerVersion(cache.latestVersion, options.currentVersion)) {
38
+ latestVersion = cache.latestVersion;
39
+ warning = formatVersionWarning(options.currentVersion, cache.latestVersion);
40
+ }
41
+ const refreshStarted = isVersionCacheStale(cache, options.now);
42
+ if (refreshStarted) {
43
+ spawnRefreshFn(cachePath);
44
+ }
45
+ return {
46
+ refreshStarted,
47
+ ...(latestVersion === undefined ? {} : { latestVersion }),
48
+ ...(warning === undefined ? {} : { warning }),
49
+ };
50
+ }
51
+ //# sourceMappingURL=version-warning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-warning.js","sourceRoot":"","sources":["../../src/lib/version-warning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AAEtC,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AAiCzB,IAAI,cAAc,GAA0B,mBAAmB,CAAA;AAC/D,IAAI,YAAY,GAAkB,KAAsB,CAAA;AAExD,MAAM,UAAU,gCAAgC,CAAC,WAA8C;IAC7F,cAAc,GAAG,WAAW,IAAI,mBAAmB,CAAA;AACrD,CAAC;AAED,MAAM,UAAU,mCAAmC,CAAC,SAAoC;IACtF,YAAY,GAAG,SAAS,IAAK,KAAuB,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,cAAsB,EAAE,aAAqB;IAChF,OAAO,eAAe,uBAAuB,0BAA0B,cAAc,OAAO,aAAa,2BAA2B,CAAA;AACtI,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAChF,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE;QACpE,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;QACtC,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,IAAI;KAClB,CAAC,CAAA;IACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;QACvB,oFAAoF;IACtF,CAAC,CAAC,CAAA;IACF,KAAK,CAAC,KAAK,EAAE,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAA8B;IACtE,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACnD,OAAO,EAAC,cAAc,EAAE,KAAK,EAAC,CAAA;IAChC,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACpD,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAA;IAC/C,IAAI,aAAiC,CAAA;IACrC,IAAI,OAA2B,CAAA;IAE/B,IACE,KAAK,EAAE,OAAO,KAAK,uBAAuB;QAC1C,KAAK,CAAC,aAAa,KAAK,SAAS;QACjC,cAAc,CAAC,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,EAC3D,CAAC;QACD,aAAa,GAAG,KAAK,CAAC,aAAa,CAAA;QACnC,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;IAC7E,CAAC;IAED,MAAM,cAAc,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9D,IAAI,cAAc,EAAE,CAAC;QACnB,cAAc,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC;IAED,OAAO;QACL,cAAc;QACd,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,aAAa,EAAC,CAAC;QACvD,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,OAAO,EAAC,CAAC;KAC5C,CAAA;AACH,CAAC"}