forkit-connect 0.1.28 → 0.1.30

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 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'],
@@ -93,6 +94,19 @@ const PUBLIC_COMMANDS = [
93
94
  ['ignore', 'Deny one detected local model on this device'],
94
95
  ['doctor', 'Run local environment diagnostics'],
95
96
  ];
97
+ const START_HERE_COMMANDS = [
98
+ ['forkit-connect login', 'Pair this machine with your Forkit.dev account'],
99
+ ['forkit-connect workspace status', 'Confirm the active workspace and project scope'],
100
+ ['forkit-connect scan', 'Find local models, agents, and runtimes'],
101
+ ['forkit-connect inbox', 'Review what should become a Passport'],
102
+ ['forkit-connect runtime status', 'Check runtime connection and signal posture'],
103
+ ];
104
+ const EVERYDAY_COMMANDS = [
105
+ ['forkit-connect status', 'One-line account, device, queue, and scope health'],
106
+ ['forkit-connect start', 'Open the guided local launcher'],
107
+ ['forkit-connect sync', 'Flush queued metadata and lifecycle evidence'],
108
+ ['forkit-connect doctor', 'Diagnose local setup issues'],
109
+ ];
96
110
  const ADVANCED_COMMAND_GROUPS = [
97
111
  ['connect', 'Model connection, runtime review, and handoff utilities'],
98
112
  ['runtime', 'Repo-scoped runtime observation and journaling utilities'],
@@ -117,27 +131,32 @@ const ADVANCED_COMMAND_GROUPS = [
117
131
  ['notify', 'Notification preview and delivery controls'],
118
132
  ];
119
133
  function usage() {
120
- printCliHeader('CLI', 'Precise local review, runtime detection, and registration handoff.');
121
- console.log(cliKeyLine('usage', 'forkit-connect <command> [options]'));
122
- console.log(cliKeyLine('scope', 'forkit-connect workspace <list|select|create|status>'));
123
- console.log(cliKeyLine('runtime', 'forkit-connect runtime <register|review|status>'));
124
- printCliSection('Core');
125
- for (const [command, description] of PUBLIC_COMMANDS) {
126
- console.log(cliKeyLine(command, description));
134
+ printCliHeader('CLI', 'Local AI runtime passporting without copying model data.');
135
+ console.log(cliKeyLine('best first run', 'forkit-connect login'));
136
+ console.log(cliKeyLine('privacy model', 'metadata only; secrets stay local'));
137
+ console.log(cliKeyLine('advanced map', 'forkit-connect --advanced-help'));
138
+ printCliSection('Start Here');
139
+ for (const [command, description] of START_HERE_COMMANDS) {
140
+ console.log(cliCommandLine(command, description));
141
+ }
142
+ printCliSection('Daily Ops');
143
+ for (const [command, description] of EVERYDAY_COMMANDS) {
144
+ console.log(cliCommandLine(command, description));
127
145
  }
128
146
  printCliSection('Flags');
129
147
  console.log(cliKeyLine('--json', 'Machine-readable output when supported'));
130
- console.log(cliKeyLine('--all-ready', 'Register every ready local model in the current scope'));
131
- console.log(cliKeyLine('--model', 'Model name used by register'));
132
- console.log(cliKeyLine('--entrypoint', 'Relative project path used by runtime register'));
148
+ console.log(cliKeyLine('--version', 'Print the Forkit Connect CLI version'));
133
149
  console.log(cliKeyLine('--dry-run', 'Show inferred runtime payload without creating it'));
134
- console.log(cliKeyLine('--no-browser', 'Do not auto-open browser verification during login'));
135
150
  console.log(cliKeyLine('--plain', 'Disable the interactive terminal table surface'));
136
- console.log(cliKeyLine('--advanced-help', 'Show internal and engineering commands'));
151
+ console.log(cliKeyLine('--advanced-help', 'Show the full engineering command map'));
137
152
  }
138
153
  function advancedUsage() {
139
- usage();
140
- printCliSection('Advanced');
154
+ printCliHeader('Advanced CLI', 'Full engineering map for automation, C2, and release operations.');
155
+ printCliSection('Public Commands');
156
+ for (const [command, description] of PUBLIC_COMMANDS) {
157
+ console.log(cliKeyLine(command, description));
158
+ }
159
+ printCliSection('Advanced Routes');
141
160
  console.log(cliKeyLine('connect', 'forkit-connect connect <modelNameOrDiscoveryHash>'));
142
161
  console.log(cliKeyLine('connect', 'forkit-connect connect <start|init|status|inbox|services|permissions|handoff|evolution review|runtime review|runtime status>'));
143
162
  console.log(cliKeyLine('targets', 'forkit-connect runtime target <add|list|remove|status>'));
@@ -877,6 +896,9 @@ function cliTag(label, tone = 'muted') {
877
896
  function cliKeyLine(label, value) {
878
897
  return ` ${cliDim(`${label}`.padEnd(CLI_LABEL_WIDTH, ' '))} ${value}`;
879
898
  }
899
+ function cliCommandLine(command, value) {
900
+ return ` ${cliDim(command.padEnd(34, ' '))} ${value}`;
901
+ }
880
902
  function printCliHeader(title, subtitle) {
881
903
  console.log(`[forkit-connect] ${cliBold(title)}`);
882
904
  if (subtitle) {
@@ -2609,6 +2631,10 @@ async function run() {
2609
2631
  showUsage();
2610
2632
  return;
2611
2633
  }
2634
+ if (command === 'version' || command === '--version' || command === '-v') {
2635
+ console.log((0, update_1.getCurrentConnectVersion)());
2636
+ return;
2637
+ }
2612
2638
  if (isHelpCommand(command)) {
2613
2639
  showUsage();
2614
2640
  return;
@@ -2754,6 +2780,37 @@ async function run() {
2754
2780
  return;
2755
2781
  }
2756
2782
  const result = await service.runDiscoveryCycle();
2783
+ const heartbeatGaid = getArg('--heartbeat-gaid');
2784
+ const heartbeatKey = getArg('--heartbeat-key');
2785
+ let heartbeatQueueId = null;
2786
+ if (heartbeatGaid && heartbeatKey) {
2787
+ heartbeatQueueId = service.queueHeartbeatRuntimeSignal(heartbeatGaid, heartbeatKey);
2788
+ }
2789
+ if (hasFlag('--json')) {
2790
+ printJson({
2791
+ ok: result.ok,
2792
+ message: result.message,
2793
+ discovery_mode: result.discoveryMode,
2794
+ runtimes: result.runtimes,
2795
+ models: result.models,
2796
+ counts: {
2797
+ new_models: result.newModels,
2798
+ already_known_models: result.alreadyKnownModels,
2799
+ duplicate_discoveries_skipped: result.duplicateDiscoveriesSkipped,
2800
+ },
2801
+ summary: result.summary,
2802
+ queue: result.queue,
2803
+ sync: result.sync,
2804
+ heartbeat_queue_id: heartbeatQueueId,
2805
+ next_action: result.ok
2806
+ ? null
2807
+ : 'Start Ollama, LM Studio, an OpenAI-compatible local server, or add local model directories, then rerun scan.',
2808
+ });
2809
+ if (!result.ok) {
2810
+ process.exitCode = 0;
2811
+ }
2812
+ return;
2813
+ }
2757
2814
  console.log(result.message);
2758
2815
  for (const runtime of result.runtimes) {
2759
2816
  const runtimeStatus = runtime.ok ? 'detected' : 'unavailable';
@@ -2767,13 +2824,8 @@ async function run() {
2767
2824
  console.log(`[forkit-connect] Detected new=${result.newModels} already_known=${result.alreadyKnownModels} duplicates_skipped=${result.duplicateDiscoveriesSkipped}`);
2768
2825
  printDiscoverySummary(result.summary);
2769
2826
  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
- const heartbeatGaid = getArg('--heartbeat-gaid');
2771
- const heartbeatKey = getArg('--heartbeat-key');
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
- }
2827
+ if (heartbeatQueueId) {
2828
+ console.log(`[forkit-connect] Queued heartbeat runtime signal: ${heartbeatQueueId}`);
2777
2829
  }
2778
2830
  console.log(`[forkit-connect] Queue processed=${result.sync.processed} succeeded=${result.sync.succeeded} failed=${result.sync.failed}`);
2779
2831
  if (!result.ok) {
@@ -2879,11 +2931,12 @@ async function run() {
2879
2931
  await withTimeout(service.prewarmSmartRegistrationInbox(), 1800, undefined);
2880
2932
  printSessionExportFallback(polled.body.connect_access_token);
2881
2933
  const displayName = getSessionDisplayName(polled.body.connect_access_token);
2882
- console.log(displayName
2883
- ? `[forkit-connect] Welcome, ${displayName}. Continuing with an environment-backed session for this run.`
2884
- : '[forkit-connect] Continuing with an environment-backed session for this run.');
2885
- process.exitCode = 0;
2886
- return true;
2934
+ console.error(displayName
2935
+ ? `[forkit-connect] Approval reached Forkit.dev for ${displayName}, but this CLI process could not persist the session.`
2936
+ : '[forkit-connect] Approval reached Forkit.dev, but this CLI process could not persist the session.');
2937
+ console.error('[forkit-connect] Login is not complete. Rerun `forkit-connect login` from a desktop/keychain session or fix secure storage first.');
2938
+ process.exitCode = 2;
2939
+ return false;
2887
2940
  }
2888
2941
  throw error;
2889
2942
  }
@@ -6648,6 +6701,17 @@ async function run() {
6648
6701
  }
6649
6702
  if (command === 'doctor') {
6650
6703
  const checks = await service.runDoctorChecks();
6704
+ if (hasFlag('--json')) {
6705
+ printJson({
6706
+ ok: !checks.some((check) => check.status === 'FAIL'),
6707
+ generated_at: new Date().toISOString(),
6708
+ checks,
6709
+ });
6710
+ if (checks.some((check) => check.status === 'FAIL')) {
6711
+ process.exitCode = 2;
6712
+ }
6713
+ return;
6714
+ }
6651
6715
  for (const check of checks) {
6652
6716
  console.log(`[${check.status}] ${check.name}: ${check.details}`);
6653
6717
  }
@@ -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 checkForUpdates(manifestUrl?: string): Promise<ReleaseCheckResult>;
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
- async function checkForUpdates(manifestUrl = getReleaseManifestUrl()) {
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 = compareVersions(currentVersion, body.latestVersion);
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 = compareVersions(currentVersion, body.latestVersion);
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('Update available.');
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.manifest.latestVersion}`);
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.downloadUrl) {
175
- lines.push(`Download: ${result.downloadUrl}`);
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forkit-connect",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "Forkit Connect Local Engine - The Global AI Governance Fabric",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",