forkit-connect 0.1.28 → 0.1.29
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/cli.js +56 -12
- package/dist/v1/update.d.ts +5 -1
- package/dist/v1/update.js +53 -9
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -78,6 +78,7 @@ const CLI_FALLBACK_PLAN_LIMITS = {
|
|
|
78
78
|
};
|
|
79
79
|
const PUBLIC_COMMANDS = [
|
|
80
80
|
['init', 'Initialize local Connect identity and privacy posture'],
|
|
81
|
+
['version', 'Print the Forkit Connect CLI version'],
|
|
81
82
|
['login', 'Link this device to your Forkit.dev account'],
|
|
82
83
|
['logout', 'Remove the stored Forkit.dev session from this device'],
|
|
83
84
|
['status', 'Show account, scope, daemon, and queue status'],
|
|
@@ -127,6 +128,7 @@ function usage() {
|
|
|
127
128
|
}
|
|
128
129
|
printCliSection('Flags');
|
|
129
130
|
console.log(cliKeyLine('--json', 'Machine-readable output when supported'));
|
|
131
|
+
console.log(cliKeyLine('--version', 'Print the Forkit Connect CLI version'));
|
|
130
132
|
console.log(cliKeyLine('--all-ready', 'Register every ready local model in the current scope'));
|
|
131
133
|
console.log(cliKeyLine('--model', 'Model name used by register'));
|
|
132
134
|
console.log(cliKeyLine('--entrypoint', 'Relative project path used by runtime register'));
|
|
@@ -2609,6 +2611,10 @@ async function run() {
|
|
|
2609
2611
|
showUsage();
|
|
2610
2612
|
return;
|
|
2611
2613
|
}
|
|
2614
|
+
if (command === 'version' || command === '--version' || command === '-v') {
|
|
2615
|
+
console.log((0, update_1.getCurrentConnectVersion)());
|
|
2616
|
+
return;
|
|
2617
|
+
}
|
|
2612
2618
|
if (isHelpCommand(command)) {
|
|
2613
2619
|
showUsage();
|
|
2614
2620
|
return;
|
|
@@ -2754,6 +2760,37 @@ async function run() {
|
|
|
2754
2760
|
return;
|
|
2755
2761
|
}
|
|
2756
2762
|
const result = await service.runDiscoveryCycle();
|
|
2763
|
+
const heartbeatGaid = getArg('--heartbeat-gaid');
|
|
2764
|
+
const heartbeatKey = getArg('--heartbeat-key');
|
|
2765
|
+
let heartbeatQueueId = null;
|
|
2766
|
+
if (heartbeatGaid && heartbeatKey) {
|
|
2767
|
+
heartbeatQueueId = service.queueHeartbeatRuntimeSignal(heartbeatGaid, heartbeatKey);
|
|
2768
|
+
}
|
|
2769
|
+
if (hasFlag('--json')) {
|
|
2770
|
+
printJson({
|
|
2771
|
+
ok: result.ok,
|
|
2772
|
+
message: result.message,
|
|
2773
|
+
discovery_mode: result.discoveryMode,
|
|
2774
|
+
runtimes: result.runtimes,
|
|
2775
|
+
models: result.models,
|
|
2776
|
+
counts: {
|
|
2777
|
+
new_models: result.newModels,
|
|
2778
|
+
already_known_models: result.alreadyKnownModels,
|
|
2779
|
+
duplicate_discoveries_skipped: result.duplicateDiscoveriesSkipped,
|
|
2780
|
+
},
|
|
2781
|
+
summary: result.summary,
|
|
2782
|
+
queue: result.queue,
|
|
2783
|
+
sync: result.sync,
|
|
2784
|
+
heartbeat_queue_id: heartbeatQueueId,
|
|
2785
|
+
next_action: result.ok
|
|
2786
|
+
? null
|
|
2787
|
+
: 'Start Ollama, LM Studio, an OpenAI-compatible local server, or add local model directories, then rerun scan.',
|
|
2788
|
+
});
|
|
2789
|
+
if (!result.ok) {
|
|
2790
|
+
process.exitCode = 0;
|
|
2791
|
+
}
|
|
2792
|
+
return;
|
|
2793
|
+
}
|
|
2757
2794
|
console.log(result.message);
|
|
2758
2795
|
for (const runtime of result.runtimes) {
|
|
2759
2796
|
const runtimeStatus = runtime.ok ? 'detected' : 'unavailable';
|
|
@@ -2767,13 +2804,8 @@ async function run() {
|
|
|
2767
2804
|
console.log(`[forkit-connect] Detected new=${result.newModels} already_known=${result.alreadyKnownModels} duplicates_skipped=${result.duplicateDiscoveriesSkipped}`);
|
|
2768
2805
|
printDiscoverySummary(result.summary);
|
|
2769
2806
|
console.log(`[forkit-connect] Queue queued=${result.queue.queued} skipped_pending=${result.queue.skippedPending} skipped_bound=${result.queue.skippedBound} skipped_duplicates=${result.queue.skippedDuplicate}`);
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
if (heartbeatGaid && heartbeatKey) {
|
|
2773
|
-
const queueId = service.queueHeartbeatRuntimeSignal(heartbeatGaid, heartbeatKey);
|
|
2774
|
-
if (queueId) {
|
|
2775
|
-
console.log(`[forkit-connect] Queued heartbeat runtime signal: ${queueId}`);
|
|
2776
|
-
}
|
|
2807
|
+
if (heartbeatQueueId) {
|
|
2808
|
+
console.log(`[forkit-connect] Queued heartbeat runtime signal: ${heartbeatQueueId}`);
|
|
2777
2809
|
}
|
|
2778
2810
|
console.log(`[forkit-connect] Queue processed=${result.sync.processed} succeeded=${result.sync.succeeded} failed=${result.sync.failed}`);
|
|
2779
2811
|
if (!result.ok) {
|
|
@@ -2879,11 +2911,12 @@ async function run() {
|
|
|
2879
2911
|
await withTimeout(service.prewarmSmartRegistrationInbox(), 1800, undefined);
|
|
2880
2912
|
printSessionExportFallback(polled.body.connect_access_token);
|
|
2881
2913
|
const displayName = getSessionDisplayName(polled.body.connect_access_token);
|
|
2882
|
-
console.
|
|
2883
|
-
? `[forkit-connect]
|
|
2884
|
-
: '[forkit-connect]
|
|
2885
|
-
|
|
2886
|
-
|
|
2914
|
+
console.error(displayName
|
|
2915
|
+
? `[forkit-connect] Approval reached Forkit.dev for ${displayName}, but this CLI process could not persist the session.`
|
|
2916
|
+
: '[forkit-connect] Approval reached Forkit.dev, but this CLI process could not persist the session.');
|
|
2917
|
+
console.error('[forkit-connect] Login is not complete. Rerun `forkit-connect login` from a desktop/keychain session or fix secure storage first.');
|
|
2918
|
+
process.exitCode = 2;
|
|
2919
|
+
return false;
|
|
2887
2920
|
}
|
|
2888
2921
|
throw error;
|
|
2889
2922
|
}
|
|
@@ -6648,6 +6681,17 @@ async function run() {
|
|
|
6648
6681
|
}
|
|
6649
6682
|
if (command === 'doctor') {
|
|
6650
6683
|
const checks = await service.runDoctorChecks();
|
|
6684
|
+
if (hasFlag('--json')) {
|
|
6685
|
+
printJson({
|
|
6686
|
+
ok: !checks.some((check) => check.status === 'FAIL'),
|
|
6687
|
+
generated_at: new Date().toISOString(),
|
|
6688
|
+
checks,
|
|
6689
|
+
});
|
|
6690
|
+
if (checks.some((check) => check.status === 'FAIL')) {
|
|
6691
|
+
process.exitCode = 2;
|
|
6692
|
+
}
|
|
6693
|
+
return;
|
|
6694
|
+
}
|
|
6651
6695
|
for (const check of checks) {
|
|
6652
6696
|
console.log(`[${check.status}] ${check.name}: ${check.details}`);
|
|
6653
6697
|
}
|
package/dist/v1/update.d.ts
CHANGED
|
@@ -19,7 +19,9 @@ export interface ReleaseManifest {
|
|
|
19
19
|
export interface ReleaseCheckSuccess {
|
|
20
20
|
ok: true;
|
|
21
21
|
manifestUrl: string;
|
|
22
|
+
npmLatestUrl: string;
|
|
22
23
|
currentVersion: string;
|
|
24
|
+
cliLatestVersion: string | null;
|
|
23
25
|
manifest: ReleaseManifest;
|
|
24
26
|
availability: 'up-to-date' | 'update-available' | 'required-update';
|
|
25
27
|
downloadUrl: string | null;
|
|
@@ -27,12 +29,14 @@ export interface ReleaseCheckSuccess {
|
|
|
27
29
|
export interface ReleaseCheckFailure {
|
|
28
30
|
ok: false;
|
|
29
31
|
manifestUrl: string;
|
|
32
|
+
npmLatestUrl: string;
|
|
30
33
|
currentVersion: string;
|
|
31
34
|
error: string;
|
|
32
35
|
}
|
|
33
36
|
export type ReleaseCheckResult = ReleaseCheckSuccess | ReleaseCheckFailure;
|
|
34
37
|
export declare function getCurrentConnectVersion(): string;
|
|
35
38
|
export declare function getReleaseManifestUrl(): string;
|
|
36
|
-
export declare function
|
|
39
|
+
export declare function getNpmLatestUrl(): string;
|
|
40
|
+
export declare function checkForUpdates(manifestUrl?: string, npmLatestUrl?: string): Promise<ReleaseCheckResult>;
|
|
37
41
|
export declare function formatUpdateCheckLines(result: ReleaseCheckResult): string[];
|
|
38
42
|
//# sourceMappingURL=update.d.ts.map
|
package/dist/v1/update.js
CHANGED
|
@@ -5,12 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getCurrentConnectVersion = getCurrentConnectVersion;
|
|
7
7
|
exports.getReleaseManifestUrl = getReleaseManifestUrl;
|
|
8
|
+
exports.getNpmLatestUrl = getNpmLatestUrl;
|
|
8
9
|
exports.checkForUpdates = checkForUpdates;
|
|
9
10
|
exports.formatUpdateCheckLines = formatUpdateCheckLines;
|
|
10
11
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
12
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
13
|
const node_url_1 = require("node:url");
|
|
13
14
|
const DEFAULT_RELEASE_MANIFEST_URL = process.env.FORKIT_CONNECT_RELEASE_MANIFEST_URL ?? 'https://forkit.dev/connect/releases/latest.json';
|
|
15
|
+
const DEFAULT_NPM_LATEST_URL = process.env.FORKIT_CONNECT_NPM_LATEST_URL ?? 'https://registry.npmjs.org/forkit-connect/latest';
|
|
14
16
|
function readPackageJsonVersion() {
|
|
15
17
|
try {
|
|
16
18
|
const packageJsonPath = node_path_1.default.resolve(__dirname, '..', '..', 'package.json');
|
|
@@ -64,15 +66,41 @@ function pickDownloadUrl(downloads) {
|
|
|
64
66
|
}
|
|
65
67
|
return downloads.linuxAppImage?.url || downloads.linuxDeb?.url || null;
|
|
66
68
|
}
|
|
69
|
+
function isNpmLatestResponse(value) {
|
|
70
|
+
return !!value
|
|
71
|
+
&& typeof value === 'object'
|
|
72
|
+
&& typeof value.version === 'string'
|
|
73
|
+
&& Boolean(String(value.version).trim());
|
|
74
|
+
}
|
|
75
|
+
async function fetchNpmLatestVersion(npmLatestUrl = DEFAULT_NPM_LATEST_URL) {
|
|
76
|
+
if (process.env.FORKIT_CONNECT_SKIP_NPM_UPDATE_CHECK === '1') {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const response = await fetch(npmLatestUrl, {
|
|
80
|
+
method: 'GET',
|
|
81
|
+
headers: {
|
|
82
|
+
Accept: 'application/json',
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const body = await response.json();
|
|
89
|
+
return isNpmLatestResponse(body) ? body.version.trim() : null;
|
|
90
|
+
}
|
|
67
91
|
function getCurrentConnectVersion() {
|
|
68
92
|
return readPackageJsonVersion();
|
|
69
93
|
}
|
|
70
94
|
function getReleaseManifestUrl() {
|
|
71
95
|
return DEFAULT_RELEASE_MANIFEST_URL;
|
|
72
96
|
}
|
|
73
|
-
|
|
97
|
+
function getNpmLatestUrl() {
|
|
98
|
+
return DEFAULT_NPM_LATEST_URL;
|
|
99
|
+
}
|
|
100
|
+
async function checkForUpdates(manifestUrl = getReleaseManifestUrl(), npmLatestUrl = getNpmLatestUrl()) {
|
|
74
101
|
const currentVersion = getCurrentConnectVersion();
|
|
75
102
|
try {
|
|
103
|
+
const cliLatestVersion = await fetchNpmLatestVersion(npmLatestUrl).catch(() => null);
|
|
76
104
|
if (manifestUrl.startsWith('file://')) {
|
|
77
105
|
const manifestPath = (0, node_url_1.fileURLToPath)(manifestUrl);
|
|
78
106
|
const raw = await node_fs_1.default.promises.readFile(manifestPath, 'utf8');
|
|
@@ -81,12 +109,15 @@ async function checkForUpdates(manifestUrl = getReleaseManifestUrl()) {
|
|
|
81
109
|
return {
|
|
82
110
|
ok: false,
|
|
83
111
|
manifestUrl,
|
|
112
|
+
npmLatestUrl,
|
|
84
113
|
currentVersion,
|
|
85
114
|
error: 'invalid_manifest',
|
|
86
115
|
};
|
|
87
116
|
}
|
|
88
117
|
const minimumSupportedComparison = compareVersions(currentVersion, body.minimumSupportedVersion);
|
|
89
|
-
const latestComparison =
|
|
118
|
+
const latestComparison = cliLatestVersion
|
|
119
|
+
? compareVersions(currentVersion, cliLatestVersion)
|
|
120
|
+
: compareVersions(currentVersion, body.latestVersion);
|
|
90
121
|
const availability = minimumSupportedComparison < 0
|
|
91
122
|
? 'required-update'
|
|
92
123
|
: latestComparison < 0
|
|
@@ -95,7 +126,9 @@ async function checkForUpdates(manifestUrl = getReleaseManifestUrl()) {
|
|
|
95
126
|
return {
|
|
96
127
|
ok: true,
|
|
97
128
|
manifestUrl,
|
|
129
|
+
npmLatestUrl,
|
|
98
130
|
currentVersion,
|
|
131
|
+
cliLatestVersion,
|
|
99
132
|
manifest: body,
|
|
100
133
|
availability,
|
|
101
134
|
downloadUrl: pickDownloadUrl(body.downloads),
|
|
@@ -111,6 +144,7 @@ async function checkForUpdates(manifestUrl = getReleaseManifestUrl()) {
|
|
|
111
144
|
return {
|
|
112
145
|
ok: false,
|
|
113
146
|
manifestUrl,
|
|
147
|
+
npmLatestUrl,
|
|
114
148
|
currentVersion,
|
|
115
149
|
error: `manifest_http_${response.status}`,
|
|
116
150
|
};
|
|
@@ -120,12 +154,15 @@ async function checkForUpdates(manifestUrl = getReleaseManifestUrl()) {
|
|
|
120
154
|
return {
|
|
121
155
|
ok: false,
|
|
122
156
|
manifestUrl,
|
|
157
|
+
npmLatestUrl,
|
|
123
158
|
currentVersion,
|
|
124
159
|
error: 'invalid_manifest',
|
|
125
160
|
};
|
|
126
161
|
}
|
|
127
162
|
const minimumSupportedComparison = compareVersions(currentVersion, body.minimumSupportedVersion);
|
|
128
|
-
const latestComparison =
|
|
163
|
+
const latestComparison = cliLatestVersion
|
|
164
|
+
? compareVersions(currentVersion, cliLatestVersion)
|
|
165
|
+
: compareVersions(currentVersion, body.latestVersion);
|
|
129
166
|
const availability = minimumSupportedComparison < 0
|
|
130
167
|
? 'required-update'
|
|
131
168
|
: latestComparison < 0
|
|
@@ -134,7 +171,9 @@ async function checkForUpdates(manifestUrl = getReleaseManifestUrl()) {
|
|
|
134
171
|
return {
|
|
135
172
|
ok: true,
|
|
136
173
|
manifestUrl,
|
|
174
|
+
npmLatestUrl,
|
|
137
175
|
currentVersion,
|
|
176
|
+
cliLatestVersion,
|
|
138
177
|
manifest: body,
|
|
139
178
|
availability,
|
|
140
179
|
downloadUrl: pickDownloadUrl(body.downloads),
|
|
@@ -144,6 +183,7 @@ async function checkForUpdates(manifestUrl = getReleaseManifestUrl()) {
|
|
|
144
183
|
return {
|
|
145
184
|
ok: false,
|
|
146
185
|
manifestUrl,
|
|
186
|
+
npmLatestUrl,
|
|
147
187
|
currentVersion,
|
|
148
188
|
error: error instanceof Error ? error.message : 'manifest_fetch_failed',
|
|
149
189
|
};
|
|
@@ -163,16 +203,20 @@ function formatUpdateCheckLines(result) {
|
|
|
163
203
|
lines.push('This version is no longer supported.');
|
|
164
204
|
}
|
|
165
205
|
else if (result.availability === 'update-available') {
|
|
166
|
-
lines.push('
|
|
206
|
+
lines.push('CLI update available.');
|
|
167
207
|
}
|
|
168
208
|
else {
|
|
169
|
-
lines.push('Forkit Connect is up to date.');
|
|
209
|
+
lines.push('Forkit Connect CLI is up to date.');
|
|
170
210
|
}
|
|
171
|
-
lines.push(`Current version: ${result.currentVersion}`);
|
|
172
|
-
lines.push(`Latest version: ${result.
|
|
211
|
+
lines.push(`Current CLI version: ${result.currentVersion}`);
|
|
212
|
+
lines.push(`Latest CLI version: ${result.cliLatestVersion || 'unavailable'}`);
|
|
213
|
+
lines.push(`Desktop installer latest: ${result.manifest.latestVersion}`);
|
|
173
214
|
if (result.availability !== 'up-to-date') {
|
|
174
|
-
if (result.
|
|
175
|
-
lines.push(
|
|
215
|
+
if (result.cliLatestVersion && compareVersions(result.currentVersion, result.cliLatestVersion) < 0) {
|
|
216
|
+
lines.push('Update command: npm install -g forkit-connect@latest');
|
|
217
|
+
}
|
|
218
|
+
else if (result.downloadUrl) {
|
|
219
|
+
lines.push(`Desktop download: ${result.downloadUrl}`);
|
|
176
220
|
}
|
|
177
221
|
lines.push(`Release notes: ${result.manifest.releaseNotesUrl}`);
|
|
178
222
|
if (result.manifest.updateMessage) {
|