flight-rules 0.9.0 → 0.10.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.
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.js +137 -0
- package/dist/index.js +41 -0
- package/dist/utils/config.d.ts +44 -0
- package/dist/utils/config.js +89 -0
- package/dist/utils/version-check.d.ts +25 -0
- package/dist/utils/version-check.js +87 -0
- package/package.json +1 -1
- package/payload/AGENTS.md +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function update(args?: string[]): Promise<void>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import { checkForUpdate } from '../utils/version-check.js';
|
|
5
|
+
import { getChannel, setChannel } from '../utils/config.js';
|
|
6
|
+
import { isInteractive } from '../utils/interactive.js';
|
|
7
|
+
/**
|
|
8
|
+
* Parse --channel flag from args
|
|
9
|
+
*/
|
|
10
|
+
function parseChannelArg(args) {
|
|
11
|
+
const channelIndex = args.findIndex(arg => arg === '--channel');
|
|
12
|
+
if (channelIndex !== -1 && args[channelIndex + 1]) {
|
|
13
|
+
const value = args[channelIndex + 1];
|
|
14
|
+
if (value === 'dev' || value === 'latest') {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Also support --channel=dev format
|
|
19
|
+
const channelArg = args.find(arg => arg.startsWith('--channel='));
|
|
20
|
+
if (channelArg) {
|
|
21
|
+
const value = channelArg.split('=')[1];
|
|
22
|
+
if (value === 'dev' || value === 'latest') {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Run npm install to update the CLI
|
|
30
|
+
*/
|
|
31
|
+
function runNpmInstall(channel) {
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
const packageSpec = `flight-rules@${channel}`;
|
|
34
|
+
const npmProcess = spawn('npm', ['install', '-g', packageSpec], {
|
|
35
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
36
|
+
shell: true,
|
|
37
|
+
});
|
|
38
|
+
let stdout = '';
|
|
39
|
+
let stderr = '';
|
|
40
|
+
npmProcess.stdout?.on('data', (data) => {
|
|
41
|
+
stdout += data.toString();
|
|
42
|
+
});
|
|
43
|
+
npmProcess.stderr?.on('data', (data) => {
|
|
44
|
+
stderr += data.toString();
|
|
45
|
+
});
|
|
46
|
+
npmProcess.on('close', (code) => {
|
|
47
|
+
if (code === 0) {
|
|
48
|
+
resolve({ success: true });
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
resolve({
|
|
52
|
+
success: false,
|
|
53
|
+
error: stderr || stdout || `npm exited with code ${code}`
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
npmProcess.on('error', (err) => {
|
|
58
|
+
resolve({ success: false, error: err.message });
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export async function update(args = []) {
|
|
63
|
+
const interactive = isInteractive();
|
|
64
|
+
// Parse --channel flag
|
|
65
|
+
const requestedChannel = parseChannelArg(args);
|
|
66
|
+
const currentChannel = getChannel();
|
|
67
|
+
const targetChannel = requestedChannel || currentChannel;
|
|
68
|
+
// If switching channels, inform the user
|
|
69
|
+
if (requestedChannel && requestedChannel !== currentChannel) {
|
|
70
|
+
p.log.info(`Switching from ${pc.yellow(currentChannel)} to ${pc.cyan(requestedChannel)} channel.`);
|
|
71
|
+
}
|
|
72
|
+
// Check for updates (force fetch, bypass cache)
|
|
73
|
+
const spinner = p.spinner();
|
|
74
|
+
spinner.start('Checking for updates...');
|
|
75
|
+
const result = await checkForUpdate({ force: true });
|
|
76
|
+
if (!result) {
|
|
77
|
+
spinner.stop('Unable to check for updates');
|
|
78
|
+
p.log.error('Could not connect to npm registry. Check your network connection.');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
spinner.stop('Version check complete');
|
|
82
|
+
// Display version info
|
|
83
|
+
p.log.info(`Current version: ${pc.cyan(result.currentVersion)}`);
|
|
84
|
+
p.log.info(`Latest version (${targetChannel}): ${pc.cyan(result.latestVersion)}`);
|
|
85
|
+
// Check if update is needed
|
|
86
|
+
if (!result.updateAvailable && targetChannel === currentChannel) {
|
|
87
|
+
p.log.success('You are already on the latest version!');
|
|
88
|
+
p.outro(pc.green('No update needed.'));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// If only switching channels (no version change), still proceed
|
|
92
|
+
const switchingChannels = requestedChannel && requestedChannel !== currentChannel;
|
|
93
|
+
if (!result.updateAvailable && !switchingChannels) {
|
|
94
|
+
p.log.success('You are already on the latest version!');
|
|
95
|
+
p.outro(pc.green('No update needed.'));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Non-interactive mode: show info but don't update
|
|
99
|
+
if (!interactive) {
|
|
100
|
+
if (result.updateAvailable) {
|
|
101
|
+
p.log.info(`Update available: ${pc.yellow(result.currentVersion)} → ${pc.cyan(result.latestVersion)}`);
|
|
102
|
+
p.log.message('Run this command in an interactive terminal to update.');
|
|
103
|
+
}
|
|
104
|
+
if (switchingChannels) {
|
|
105
|
+
p.log.info(`Run this command in an interactive terminal to switch to the ${requestedChannel} channel.`);
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// Interactive mode: confirm and update
|
|
110
|
+
const message = result.updateAvailable
|
|
111
|
+
? `Update from ${result.currentVersion} to ${result.latestVersion}?`
|
|
112
|
+
: `Switch to ${targetChannel} channel?`;
|
|
113
|
+
const shouldUpdate = await p.confirm({
|
|
114
|
+
message,
|
|
115
|
+
initialValue: true,
|
|
116
|
+
});
|
|
117
|
+
if (p.isCancel(shouldUpdate) || !shouldUpdate) {
|
|
118
|
+
p.log.info('Update cancelled.');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// Perform update
|
|
122
|
+
spinner.start(`Installing flight-rules@${targetChannel}...`);
|
|
123
|
+
const installResult = await runNpmInstall(targetChannel);
|
|
124
|
+
if (!installResult.success) {
|
|
125
|
+
spinner.stop('Update failed');
|
|
126
|
+
p.log.error(installResult.error || 'Unknown error during npm install');
|
|
127
|
+
p.log.message(`You can try manually: ${pc.cyan(`npm install -g flight-rules@${targetChannel}`)}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
spinner.stop('Update complete!');
|
|
131
|
+
// Update channel in config if it changed
|
|
132
|
+
if (requestedChannel && requestedChannel !== currentChannel) {
|
|
133
|
+
setChannel(requestedChannel);
|
|
134
|
+
p.log.success(`Channel set to ${pc.cyan(requestedChannel)}`);
|
|
135
|
+
}
|
|
136
|
+
p.outro(pc.green(`Successfully updated to flight-rules@${targetChannel}!`));
|
|
137
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,10 @@ import pc from 'picocolors';
|
|
|
4
4
|
import { init } from './commands/init.js';
|
|
5
5
|
import { upgrade } from './commands/upgrade.js';
|
|
6
6
|
import { adapter } from './commands/adapter.js';
|
|
7
|
+
import { update } from './commands/update.js';
|
|
7
8
|
import { getCliVersion } from './utils/files.js';
|
|
9
|
+
import { checkForUpdate, shouldSkipUpdateCheck } from './utils/version-check.js';
|
|
10
|
+
import { isInteractive } from './utils/interactive.js';
|
|
8
11
|
const command = process.argv[2];
|
|
9
12
|
const args = process.argv.slice(3);
|
|
10
13
|
/**
|
|
@@ -41,6 +44,9 @@ async function main() {
|
|
|
41
44
|
case 'adapter':
|
|
42
45
|
await adapter(args);
|
|
43
46
|
break;
|
|
47
|
+
case 'update':
|
|
48
|
+
await update(args);
|
|
49
|
+
break;
|
|
44
50
|
case undefined:
|
|
45
51
|
case '--help':
|
|
46
52
|
case '-h':
|
|
@@ -51,6 +57,8 @@ async function main() {
|
|
|
51
57
|
showHelp();
|
|
52
58
|
process.exit(1);
|
|
53
59
|
}
|
|
60
|
+
// Show update notification after command completes (uses cache, non-blocking)
|
|
61
|
+
await showUpdateNotification();
|
|
54
62
|
}
|
|
55
63
|
function showHelp() {
|
|
56
64
|
console.log(`
|
|
@@ -60,11 +68,16 @@ ${pc.bold('Commands:')}
|
|
|
60
68
|
init Install Flight Rules into the current project
|
|
61
69
|
upgrade Upgrade Flight Rules (preserves your docs)
|
|
62
70
|
adapter Generate agent-specific adapter files
|
|
71
|
+
update Update the Flight Rules CLI itself
|
|
63
72
|
|
|
64
73
|
${pc.bold('Upgrade Options:')}
|
|
65
74
|
--version <version> Upgrade to a specific version (e.g., 0.1.4)
|
|
66
75
|
Defaults to latest from main branch
|
|
67
76
|
|
|
77
|
+
${pc.bold('Update Options:')}
|
|
78
|
+
--channel <channel> Switch release channel (dev or latest)
|
|
79
|
+
Defaults to current channel
|
|
80
|
+
|
|
68
81
|
${pc.bold('Adapter Options:')}
|
|
69
82
|
--cursor Generate AGENTS.md for Cursor
|
|
70
83
|
--claude Generate CLAUDE.md for Claude Code
|
|
@@ -74,9 +87,37 @@ ${pc.bold('Examples:')}
|
|
|
74
87
|
flight-rules init
|
|
75
88
|
flight-rules upgrade
|
|
76
89
|
flight-rules upgrade --version 0.1.4
|
|
90
|
+
flight-rules update
|
|
91
|
+
flight-rules update --channel=latest
|
|
77
92
|
flight-rules adapter --cursor --claude
|
|
78
93
|
`);
|
|
79
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Show update notification if a newer version is available.
|
|
97
|
+
* Uses cached check result to avoid slowing down commands.
|
|
98
|
+
* Only shows in interactive (TTY) mode.
|
|
99
|
+
*/
|
|
100
|
+
async function showUpdateNotification() {
|
|
101
|
+
// Skip in non-interactive mode or if disabled
|
|
102
|
+
if (!isInteractive() || shouldSkipUpdateCheck()) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Skip for commands that handle their own version checking
|
|
106
|
+
if (command === 'update' || command === '--version' || command === '-v') {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
const result = await checkForUpdate(); // Uses cache, won't slow down
|
|
111
|
+
if (result?.updateAvailable) {
|
|
112
|
+
console.log();
|
|
113
|
+
p.log.message(pc.yellow(`Update available: ${result.currentVersion} → ${result.latestVersion}`) +
|
|
114
|
+
pc.dim(` Run 'flight-rules update' to upgrade.`));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Silent failure - don't disrupt the user's workflow
|
|
119
|
+
}
|
|
120
|
+
}
|
|
80
121
|
main().catch((err) => {
|
|
81
122
|
p.log.error(err.message);
|
|
82
123
|
process.exit(1);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-level configuration for Flight Rules CLI
|
|
3
|
+
*/
|
|
4
|
+
export interface UserConfig {
|
|
5
|
+
channel: 'dev' | 'latest';
|
|
6
|
+
lastUpdateCheck?: {
|
|
7
|
+
timestamp: string;
|
|
8
|
+
latestVersion: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the path to the user-level Flight Rules directory
|
|
13
|
+
*/
|
|
14
|
+
export declare function getUserFlightRulesDir(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Get the path to the user-level config file
|
|
17
|
+
*/
|
|
18
|
+
export declare function getConfigPath(): string;
|
|
19
|
+
/**
|
|
20
|
+
* Read the user-level config, creating default if missing
|
|
21
|
+
*/
|
|
22
|
+
export declare function readConfig(): UserConfig;
|
|
23
|
+
/**
|
|
24
|
+
* Write the user-level config
|
|
25
|
+
*/
|
|
26
|
+
export declare function writeConfig(config: UserConfig): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get the configured release channel
|
|
29
|
+
*/
|
|
30
|
+
export declare function getChannel(): 'dev' | 'latest';
|
|
31
|
+
/**
|
|
32
|
+
* Set the release channel
|
|
33
|
+
*/
|
|
34
|
+
export declare function setChannel(channel: 'dev' | 'latest'): void;
|
|
35
|
+
/**
|
|
36
|
+
* Update the cached update check result
|
|
37
|
+
*/
|
|
38
|
+
export declare function updateLastCheck(latestVersion: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Get the cached update check result, if still valid
|
|
41
|
+
* @param maxAgeMs - Maximum age in milliseconds (default 24 hours)
|
|
42
|
+
* @returns The cached version if valid, null otherwise
|
|
43
|
+
*/
|
|
44
|
+
export declare function getCachedVersion(maxAgeMs?: number): string | null;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
const DEFAULT_CONFIG = {
|
|
5
|
+
channel: 'dev',
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Get the path to the user-level Flight Rules directory
|
|
9
|
+
*/
|
|
10
|
+
export function getUserFlightRulesDir() {
|
|
11
|
+
return join(homedir(), '.flight-rules');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get the path to the user-level config file
|
|
15
|
+
*/
|
|
16
|
+
export function getConfigPath() {
|
|
17
|
+
return join(getUserFlightRulesDir(), 'config.json');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Read the user-level config, creating default if missing
|
|
21
|
+
*/
|
|
22
|
+
export function readConfig() {
|
|
23
|
+
const configPath = getConfigPath();
|
|
24
|
+
if (!existsSync(configPath)) {
|
|
25
|
+
return { ...DEFAULT_CONFIG };
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
29
|
+
const parsed = JSON.parse(content);
|
|
30
|
+
// Merge with defaults to handle missing fields
|
|
31
|
+
return { ...DEFAULT_CONFIG, ...parsed };
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return { ...DEFAULT_CONFIG };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Write the user-level config
|
|
39
|
+
*/
|
|
40
|
+
export function writeConfig(config) {
|
|
41
|
+
const configPath = getConfigPath();
|
|
42
|
+
const configDir = dirname(configPath);
|
|
43
|
+
if (!existsSync(configDir)) {
|
|
44
|
+
mkdirSync(configDir, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the configured release channel
|
|
50
|
+
*/
|
|
51
|
+
export function getChannel() {
|
|
52
|
+
return readConfig().channel;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Set the release channel
|
|
56
|
+
*/
|
|
57
|
+
export function setChannel(channel) {
|
|
58
|
+
const config = readConfig();
|
|
59
|
+
config.channel = channel;
|
|
60
|
+
writeConfig(config);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Update the cached update check result
|
|
64
|
+
*/
|
|
65
|
+
export function updateLastCheck(latestVersion) {
|
|
66
|
+
const config = readConfig();
|
|
67
|
+
config.lastUpdateCheck = {
|
|
68
|
+
timestamp: new Date().toISOString(),
|
|
69
|
+
latestVersion,
|
|
70
|
+
};
|
|
71
|
+
writeConfig(config);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the cached update check result, if still valid
|
|
75
|
+
* @param maxAgeMs - Maximum age in milliseconds (default 24 hours)
|
|
76
|
+
* @returns The cached version if valid, null otherwise
|
|
77
|
+
*/
|
|
78
|
+
export function getCachedVersion(maxAgeMs = 24 * 60 * 60 * 1000) {
|
|
79
|
+
const config = readConfig();
|
|
80
|
+
if (!config.lastUpdateCheck) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const checkTime = new Date(config.lastUpdateCheck.timestamp).getTime();
|
|
84
|
+
const now = Date.now();
|
|
85
|
+
if (now - checkTime > maxAgeMs) {
|
|
86
|
+
return null; // Cache expired
|
|
87
|
+
}
|
|
88
|
+
return config.lastUpdateCheck.latestVersion;
|
|
89
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of a version check
|
|
3
|
+
*/
|
|
4
|
+
export interface VersionCheckResult {
|
|
5
|
+
currentVersion: string;
|
|
6
|
+
latestVersion: string;
|
|
7
|
+
updateAvailable: boolean;
|
|
8
|
+
channel: 'dev' | 'latest';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Options for version check
|
|
12
|
+
*/
|
|
13
|
+
export interface VersionCheckOptions {
|
|
14
|
+
force?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Check for available updates
|
|
18
|
+
* @param options - Options for the check
|
|
19
|
+
* @returns Version check result, or null if check failed
|
|
20
|
+
*/
|
|
21
|
+
export declare function checkForUpdate(options?: VersionCheckOptions): Promise<VersionCheckResult | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Check if update check should be skipped based on environment
|
|
24
|
+
*/
|
|
25
|
+
export declare function shouldSkipUpdateCheck(): boolean;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { getCliVersion } from './files.js';
|
|
2
|
+
import { getChannel, getCachedVersion, updateLastCheck } from './config.js';
|
|
3
|
+
const NPM_REGISTRY_URL = 'https://registry.npmjs.org/flight-rules';
|
|
4
|
+
/**
|
|
5
|
+
* Compare two semver versions
|
|
6
|
+
* @returns true if v2 is newer than v1
|
|
7
|
+
*/
|
|
8
|
+
function isNewerVersion(current, latest) {
|
|
9
|
+
const v1Parts = current.split('.').map(Number);
|
|
10
|
+
const v2Parts = latest.split('.').map(Number);
|
|
11
|
+
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
|
12
|
+
const v1 = v1Parts[i] || 0;
|
|
13
|
+
const v2 = v2Parts[i] || 0;
|
|
14
|
+
if (v2 > v1)
|
|
15
|
+
return true;
|
|
16
|
+
if (v2 < v1)
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Fetch the latest version from npm registry
|
|
23
|
+
* @returns The latest version for the given channel, or null on error
|
|
24
|
+
*/
|
|
25
|
+
async function fetchLatestVersion(channel) {
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetch(NPM_REGISTRY_URL, {
|
|
28
|
+
headers: { 'Accept': 'application/json' },
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const data = await response.json();
|
|
34
|
+
const distTags = data['dist-tags'];
|
|
35
|
+
if (!distTags) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return distTags[channel] || null;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Silent failure on network errors
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check for available updates
|
|
47
|
+
* @param options - Options for the check
|
|
48
|
+
* @returns Version check result, or null if check failed
|
|
49
|
+
*/
|
|
50
|
+
export async function checkForUpdate(options = {}) {
|
|
51
|
+
const currentVersion = getCliVersion();
|
|
52
|
+
const channel = getChannel();
|
|
53
|
+
if (currentVersion === 'unknown') {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
// Check cache first (unless forced)
|
|
57
|
+
if (!options.force) {
|
|
58
|
+
const cachedVersion = getCachedVersion();
|
|
59
|
+
if (cachedVersion) {
|
|
60
|
+
return {
|
|
61
|
+
currentVersion,
|
|
62
|
+
latestVersion: cachedVersion,
|
|
63
|
+
updateAvailable: isNewerVersion(currentVersion, cachedVersion),
|
|
64
|
+
channel,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Fetch from npm registry
|
|
69
|
+
const latestVersion = await fetchLatestVersion(channel);
|
|
70
|
+
if (!latestVersion) {
|
|
71
|
+
return null; // Network error or registry issue
|
|
72
|
+
}
|
|
73
|
+
// Update cache
|
|
74
|
+
updateLastCheck(latestVersion);
|
|
75
|
+
return {
|
|
76
|
+
currentVersion,
|
|
77
|
+
latestVersion,
|
|
78
|
+
updateAvailable: isNewerVersion(currentVersion, latestVersion),
|
|
79
|
+
channel,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if update check should be skipped based on environment
|
|
84
|
+
*/
|
|
85
|
+
export function shouldSkipUpdateCheck() {
|
|
86
|
+
return process.env.FLIGHT_RULES_NO_UPDATE_CHECK === '1';
|
|
87
|
+
}
|
package/package.json
CHANGED