forkit-connect 0.1.23 → 0.1.24
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 +7 -3
- package/dist/cli.js +20 -115
- package/dist/v1/credential-store.js +5 -0
- package/dist/v1/service.js +8 -164
- package/package.json +1 -3
- package/assets/connect-notifier-512.png +0 -0
- package/dist/v1/startup.d.ts +0 -12
- package/dist/v1/startup.js +0 -229
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ Naming convention:
|
|
|
6
6
|
|
|
7
7
|
- Product name: Forkit Connect
|
|
8
8
|
- Command name: `forkit-connect`
|
|
9
|
-
-
|
|
9
|
+
- Published package name: `forkit-connect`
|
|
10
|
+
- Workspace dependency alias: `@forkit/connect`
|
|
10
11
|
|
|
11
12
|
## Install Surface
|
|
12
13
|
|
|
@@ -60,10 +61,13 @@ If `~/.local/bin` is already on your `PATH`, the command is immediately accessib
|
|
|
60
61
|
- `forkit-connect login` — link this device to Forkit.dev with the device flow
|
|
61
62
|
- `forkit-connect scan` — discover local runtimes and AI models
|
|
62
63
|
- `forkit-connect inbox` — review the Smart Registration Inbox
|
|
64
|
+
- `forkit-connect connect <modelNameOrDiscoveryHash>` — prepare or sync a passport draft for a detected model
|
|
63
65
|
- `forkit-connect runtime register` — register or reuse the current repo/worktree as a governed runtime
|
|
64
66
|
- `forkit-connect runtime observe --gaid <gaid>` — emit a repo-scoped runtime journal for the current runtime target
|
|
65
67
|
- `forkit-connect status` — show public Connect readiness status
|
|
66
68
|
- `forkit-connect changes` — view collected local evidence, runtime signal history, and pending sync items
|
|
69
|
+
- `forkit-connect doctor` — run local environment, secure-storage, backend-session, and account checks
|
|
70
|
+
- `forkit-connect update-check` — inspect release metadata without enabling auto-update
|
|
67
71
|
- `forkit-connect start` — start the local daemon loop
|
|
68
72
|
- `forkit-connect stop` — stop the background daemon without deleting local state
|
|
69
73
|
- `forkit-connect uninstall` — preview a cautious uninstall plan and write local backup logs
|
|
@@ -72,7 +76,7 @@ If `~/.local/bin` is already on your `PATH`, the command is immediately accessib
|
|
|
72
76
|
|
|
73
77
|
## Advanced Commands
|
|
74
78
|
|
|
75
|
-
Advanced flows remain available under the same binary, including `
|
|
79
|
+
Advanced flows remain available under the same binary, including `review`, `daemon`, `config`, `pulse`, `c2`, `train`, `agent`, notification utilities, and runtime target management.
|
|
76
80
|
|
|
77
81
|
Runtime registration notes:
|
|
78
82
|
|
|
@@ -117,7 +121,7 @@ Then install the generated tarball into a clean directory:
|
|
|
117
121
|
mkdir -p /tmp/forkit-connect-smoke
|
|
118
122
|
cd /tmp/forkit-connect-smoke
|
|
119
123
|
npm init -y
|
|
120
|
-
npm install /absolute/path/to/forkit-connect-0.1.
|
|
124
|
+
npm install /absolute/path/to/forkit-connect-0.1.24.tgz
|
|
121
125
|
npx forkit-connect --help
|
|
122
126
|
npx forkit-connect status
|
|
123
127
|
npx forkit-connect inbox
|
package/dist/cli.js
CHANGED
|
@@ -13,7 +13,6 @@ const daemon_1 = require("./v1/daemon");
|
|
|
13
13
|
const service_1 = require("./v1/service");
|
|
14
14
|
const discovery_1 = require("./v1/discovery");
|
|
15
15
|
const heartbeat_1 = require("./v1/heartbeat");
|
|
16
|
-
const startup_1 = require("./v1/startup");
|
|
17
16
|
const runtime_activity_1 = require("./v1/runtime-activity");
|
|
18
17
|
const runtime_editor_activity_1 = require("./v1/runtime-editor-activity");
|
|
19
18
|
const runtime_observation_runner_1 = require("./v1/runtime-observation-runner");
|
|
@@ -82,7 +81,6 @@ const PUBLIC_COMMANDS = [
|
|
|
82
81
|
['login', 'Link this device to your Forkit.dev account'],
|
|
83
82
|
['logout', 'Remove the stored Forkit.dev session from this device'],
|
|
84
83
|
['status', 'Show account, scope, daemon, and queue status'],
|
|
85
|
-
['startup', 'Enable, disable, or inspect CLI startup on login'],
|
|
86
84
|
['changes', 'View all collected local changes and queued sync items'],
|
|
87
85
|
['start', 'Open the interactive launcher or start foreground sync'],
|
|
88
86
|
['stop', 'Stop the local Connect daemon'],
|
|
@@ -119,28 +117,14 @@ const ADVANCED_COMMAND_GROUPS = [
|
|
|
119
117
|
['notify', 'Notification preview and delivery controls'],
|
|
120
118
|
];
|
|
121
119
|
function usage() {
|
|
122
|
-
printCliHeader('CLI', '
|
|
123
|
-
console.log(cliKeyLine('
|
|
124
|
-
console.log(cliKeyLine('
|
|
125
|
-
console.log(cliKeyLine('review', 'forkit-connect inbox'));
|
|
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>'));
|
|
126
123
|
console.log(cliKeyLine('runtime', 'forkit-connect runtime <register|review|status>'));
|
|
127
|
-
printCliSection('
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
console.log(cliKeyLine('startup', 'Keep Connect running from sign-in'));
|
|
132
|
-
printCliSection('Daily');
|
|
133
|
-
console.log(cliKeyLine('status', 'See account, queue, and daemon state'));
|
|
134
|
-
console.log(cliKeyLine('start', 'Open the interactive local console'));
|
|
135
|
-
console.log(cliKeyLine('sync', 'Flush queued local metadata'));
|
|
136
|
-
console.log(cliKeyLine('stop', 'Stop the background daemon'));
|
|
137
|
-
printCliSection('Governed');
|
|
138
|
-
console.log(cliKeyLine('workspace', 'Optional workspace and project scope'));
|
|
139
|
-
console.log(cliKeyLine('register', 'Register ready local models'));
|
|
140
|
-
console.log(cliKeyLine('runtime', 'Register or review local runtimes'));
|
|
141
|
-
printCliSection('Safety');
|
|
142
|
-
console.log(cliKeyLine('ignore', 'Deny one detected local model on this device'));
|
|
143
|
-
console.log(cliKeyLine('doctor', 'Check notifications, storage, and runtime wiring'));
|
|
124
|
+
printCliSection('Core');
|
|
125
|
+
for (const [command, description] of PUBLIC_COMMANDS) {
|
|
126
|
+
console.log(cliKeyLine(command, description));
|
|
127
|
+
}
|
|
144
128
|
printCliSection('Flags');
|
|
145
129
|
console.log(cliKeyLine('--json', 'Machine-readable output when supported'));
|
|
146
130
|
console.log(cliKeyLine('--all-ready', 'Register every ready local model in the current scope'));
|
|
@@ -269,10 +253,10 @@ function printDeviceLoginInstructions(start) {
|
|
|
269
253
|
}
|
|
270
254
|
function printSessionExportFallback(token) {
|
|
271
255
|
void token;
|
|
272
|
-
console.log('[forkit-connect] Approval succeeded, but secure credential storage is unavailable
|
|
273
|
-
console.log('[forkit-connect] Forkit Connect
|
|
274
|
-
console.log('[forkit-connect]
|
|
275
|
-
console.log('[forkit-connect] Headless automation may pass FORKIT_CONNECT_SESSION_REF explicitly
|
|
256
|
+
console.log('[forkit-connect] Approval succeeded, but secure credential storage is unavailable or timed out on this machine.');
|
|
257
|
+
console.log('[forkit-connect] Forkit Connect will not print session tokens. Persistent login requires working secure storage.');
|
|
258
|
+
console.log('[forkit-connect] macOS: unlock Keychain and run forkit-connect login again. Linux: install libsecret-tools and run inside a DBus user session.');
|
|
259
|
+
console.log('[forkit-connect] Headless automation may pass FORKIT_CONNECT_SESSION_REF explicitly from a secret manager.');
|
|
276
260
|
}
|
|
277
261
|
function hasLinuxGuiSession() {
|
|
278
262
|
if (process.platform !== 'linux') {
|
|
@@ -951,7 +935,7 @@ function formatCliScopeLabel(workspaceId, projectId) {
|
|
|
951
935
|
if (workspace) {
|
|
952
936
|
return `${shortId(workspace)} / project needed`;
|
|
953
937
|
}
|
|
954
|
-
return '
|
|
938
|
+
return 'personal device / workspace not selected';
|
|
955
939
|
}
|
|
956
940
|
function summarizeReviewQueueCounts(values) {
|
|
957
941
|
const parts = [
|
|
@@ -2146,7 +2130,6 @@ function printPublicStatusOverview(status) {
|
|
|
2146
2130
|
console.log(cliKeyLine('device', status.device_paired ? 'paired' : 'approval pending'));
|
|
2147
2131
|
console.log(cliKeyLine('scope', formatCliScopeLabel(status.workspace_id, status.project_id)));
|
|
2148
2132
|
console.log(cliKeyLine('daemon', status.daemon_status));
|
|
2149
|
-
console.log(cliKeyLine('background', status.daemon_status === 'running' ? 'always on' : 'start required'));
|
|
2150
2133
|
console.log(cliKeyLine('privacy', status.privacy_mode));
|
|
2151
2134
|
console.log(cliKeyLine('inventory', joinCliSummary([
|
|
2152
2135
|
formatCliCompactCount(status.models_discovered, 'model'),
|
|
@@ -2167,47 +2150,6 @@ function printPublicStatusOverview(status) {
|
|
|
2167
2150
|
console.log(cliKeyLine('warning', 'Local governed scope exists, but login is still required.'));
|
|
2168
2151
|
}
|
|
2169
2152
|
}
|
|
2170
|
-
function formatStartupSummary(status) {
|
|
2171
|
-
if (!status.supported)
|
|
2172
|
-
return 'not supported';
|
|
2173
|
-
if (status.enabled === true)
|
|
2174
|
-
return 'enabled';
|
|
2175
|
-
if (status.enabled === false)
|
|
2176
|
-
return 'disabled';
|
|
2177
|
-
return 'unknown';
|
|
2178
|
-
}
|
|
2179
|
-
function printStartupStatusLine(status) {
|
|
2180
|
-
console.log(cliKeyLine('startup', formatStartupSummary(status)));
|
|
2181
|
-
}
|
|
2182
|
-
function printPublicStartupStatus(status) {
|
|
2183
|
-
const enabled = status.enabled === true;
|
|
2184
|
-
const platform = status.mode === 'launch_agent'
|
|
2185
|
-
? 'macOS LaunchAgent'
|
|
2186
|
-
: status.mode === 'registry_run'
|
|
2187
|
-
? 'Windows sign-in registry'
|
|
2188
|
-
: status.mode === 'systemd_user'
|
|
2189
|
-
? 'Linux user service'
|
|
2190
|
-
: 'not available';
|
|
2191
|
-
printCliHeader('Startup', 'Keep Forkit Connect running from sign-in without a tray app.');
|
|
2192
|
-
console.log(cliKeyLine('auto start', enabled ? 'on' : status.enabled === false ? 'off' : 'unknown'));
|
|
2193
|
-
console.log(cliKeyLine('behavior', enabled
|
|
2194
|
-
? 'Forkit Connect launches its background daemon when you sign in.'
|
|
2195
|
-
: 'Forkit Connect starts only when you run it manually.'));
|
|
2196
|
-
console.log(cliKeyLine('platform', platform));
|
|
2197
|
-
console.log(cliKeyLine('next', enabled ? 'forkit-connect startup disable' : 'forkit-connect startup enable'));
|
|
2198
|
-
if (hasFlag('--advanced-help') && status.configPath) {
|
|
2199
|
-
console.log(cliKeyLine('config', status.configPath));
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
2202
|
-
function getNotificationReadiness() {
|
|
2203
|
-
if (process.platform === 'darwin') {
|
|
2204
|
-
return 'Forkit Connect click-through ready';
|
|
2205
|
-
}
|
|
2206
|
-
if (process.platform === 'win32') {
|
|
2207
|
-
return 'native Windows toasts ready';
|
|
2208
|
-
}
|
|
2209
|
-
return 'native desktop alerts when a GUI session is available';
|
|
2210
|
-
}
|
|
2211
2153
|
function getOtherReadyCount(readyToConnectCount, draftFirstCount) {
|
|
2212
2154
|
return Math.max(0, readyToConnectCount - draftFirstCount);
|
|
2213
2155
|
}
|
|
@@ -2688,7 +2630,6 @@ async function run() {
|
|
|
2688
2630
|
const runPublicConnectStatus = async () => {
|
|
2689
2631
|
const sessionState = await checkBackendSessionState(service);
|
|
2690
2632
|
const secureStorage = service.getCredentialStoreStatus();
|
|
2691
|
-
const startupStatus = (0, startup_1.getCliStartupStatus)();
|
|
2692
2633
|
if (service.readSessionRef()) {
|
|
2693
2634
|
await withTimeout(service.refreshEffectiveBinding(), STATUS_BINDING_TIMEOUT_MS, undefined);
|
|
2694
2635
|
}
|
|
@@ -2696,7 +2637,12 @@ async function run() {
|
|
|
2696
2637
|
const overview = withSmartInboxSnapshotCounts(service.getConnectStatusOverview({ includeInbox: false }));
|
|
2697
2638
|
const localScopeCached = Boolean(String(overview.workspace_id || '').trim() || String(overview.project_id || '').trim());
|
|
2698
2639
|
const displayOverview = accountTrusted
|
|
2699
|
-
?
|
|
2640
|
+
? {
|
|
2641
|
+
...overview,
|
|
2642
|
+
lifecycle_note: !localScopeCached && overview.device_paired
|
|
2643
|
+
? 'Account connected. Personal scanning works; select workspace/project later for C2.'
|
|
2644
|
+
: overview.lifecycle_note,
|
|
2645
|
+
}
|
|
2700
2646
|
: {
|
|
2701
2647
|
...overview,
|
|
2702
2648
|
workspace_id: null,
|
|
@@ -2714,10 +2660,6 @@ async function run() {
|
|
|
2714
2660
|
session_truth: accountTrusted ? 'account_verified_or_offline' : 'local_scope_cached_login_required',
|
|
2715
2661
|
local_scope_cached: !accountTrusted && localScopeCached,
|
|
2716
2662
|
binding_truth: accountTrusted ? 'account_binding_active' : 'account_login_required',
|
|
2717
|
-
startup_on_login: startupStatus,
|
|
2718
|
-
notifications: {
|
|
2719
|
-
readiness: getNotificationReadiness(),
|
|
2720
|
-
},
|
|
2721
2663
|
secure_storage: {
|
|
2722
2664
|
backend: secureStorage.backend,
|
|
2723
2665
|
available: secureStorage.available,
|
|
@@ -2733,28 +2675,8 @@ async function run() {
|
|
|
2733
2675
|
if (!secureStorage.available || secureStorage.plaintextFallbackActive) {
|
|
2734
2676
|
console.log(cliKeyLine('secure note', secureStorage.detail));
|
|
2735
2677
|
}
|
|
2736
|
-
console.log(cliKeyLine('notifications', getNotificationReadiness()));
|
|
2737
|
-
printStartupStatusLine(startupStatus);
|
|
2738
2678
|
printPublicStatusGuidance(displayOverview, sessionState);
|
|
2739
2679
|
};
|
|
2740
|
-
const runPublicStartupStatus = () => {
|
|
2741
|
-
const startupStatus = (0, startup_1.getCliStartupStatus)();
|
|
2742
|
-
if (hasFlag('--json')) {
|
|
2743
|
-
printJson(startupStatus);
|
|
2744
|
-
return;
|
|
2745
|
-
}
|
|
2746
|
-
printPublicStartupStatus(startupStatus);
|
|
2747
|
-
};
|
|
2748
|
-
const runPublicStartupEnable = () => {
|
|
2749
|
-
const startupStatus = (0, startup_1.enableCliStartup)(process.execPath, __filename);
|
|
2750
|
-
printPublicStartupStatus(startupStatus);
|
|
2751
|
-
console.log('[forkit-connect] CLI startup on login is enabled. The background daemon will come up when your session starts.');
|
|
2752
|
-
};
|
|
2753
|
-
const runPublicStartupDisable = () => {
|
|
2754
|
-
const startupStatus = (0, startup_1.disableCliStartup)();
|
|
2755
|
-
printPublicStartupStatus(startupStatus);
|
|
2756
|
-
console.log('[forkit-connect] CLI startup on login is disabled. Use forkit-connect stop if you also want to stop the daemon right now.');
|
|
2757
|
-
};
|
|
2758
2680
|
const runPublicConnectInbox = async () => {
|
|
2759
2681
|
const forceRefresh = hasFlag('--refresh');
|
|
2760
2682
|
const inbox = service.getSmartRegistrationInbox({
|
|
@@ -2850,7 +2772,8 @@ async function run() {
|
|
|
2850
2772
|
}
|
|
2851
2773
|
console.log(`[forkit-connect] Queue processed=${result.sync.processed} succeeded=${result.sync.succeeded} failed=${result.sync.failed}`);
|
|
2852
2774
|
if (!result.ok) {
|
|
2853
|
-
|
|
2775
|
+
console.log('[forkit-connect] No runtime passport was created. Start Ollama, LM Studio, an OpenAI-compatible local server, or add local model directories, then rerun scan.');
|
|
2776
|
+
process.exitCode = 0;
|
|
2854
2777
|
}
|
|
2855
2778
|
};
|
|
2856
2779
|
const runPublicUpdateCheck = async () => {
|
|
@@ -5017,24 +4940,6 @@ async function run() {
|
|
|
5017
4940
|
await runPublicConnectStatus();
|
|
5018
4941
|
return;
|
|
5019
4942
|
}
|
|
5020
|
-
if (command === 'startup') {
|
|
5021
|
-
const subcommand = args[1] || 'status';
|
|
5022
|
-
if (subcommand === 'status') {
|
|
5023
|
-
runPublicStartupStatus();
|
|
5024
|
-
return;
|
|
5025
|
-
}
|
|
5026
|
-
if (subcommand === 'enable') {
|
|
5027
|
-
runPublicStartupEnable();
|
|
5028
|
-
return;
|
|
5029
|
-
}
|
|
5030
|
-
if (subcommand === 'disable') {
|
|
5031
|
-
runPublicStartupDisable();
|
|
5032
|
-
return;
|
|
5033
|
-
}
|
|
5034
|
-
showUsage();
|
|
5035
|
-
process.exitCode = 1;
|
|
5036
|
-
return;
|
|
5037
|
-
}
|
|
5038
4943
|
if (command === 'changes') {
|
|
5039
4944
|
runPublicCollectedChanges();
|
|
5040
4945
|
return;
|
|
@@ -20,6 +20,7 @@ exports.ConnectCredentialStoreError = ConnectCredentialStoreError;
|
|
|
20
20
|
const SERVICE_BASE_NAME = 'ForkitConnect';
|
|
21
21
|
const LEGACY_SERVICE_NAME = SERVICE_BASE_NAME;
|
|
22
22
|
const LINUX_SECRET_TOOL_TIMEOUT_MS = 1200;
|
|
23
|
+
const MACOS_SECURITY_TIMEOUT_MS = Number(process.env.FORKIT_CONNECT_MACOS_SECURITY_TIMEOUT_MS || 15000);
|
|
23
24
|
function nowIso() {
|
|
24
25
|
return new Date().toISOString();
|
|
25
26
|
}
|
|
@@ -187,6 +188,7 @@ class MacOsKeychainBackend {
|
|
|
187
188
|
'-w',
|
|
188
189
|
], {
|
|
189
190
|
encoding: 'utf8',
|
|
191
|
+
timeout: MACOS_SECURITY_TIMEOUT_MS,
|
|
190
192
|
});
|
|
191
193
|
if (result.error) {
|
|
192
194
|
throw new ConnectCredentialStoreError('secure_storage_read_failed', `Forkit Connect could not read secure credentials from macOS Keychain: ${result.error.message}`);
|
|
@@ -211,6 +213,7 @@ class MacOsKeychainBackend {
|
|
|
211
213
|
value,
|
|
212
214
|
], {
|
|
213
215
|
encoding: 'utf8',
|
|
216
|
+
timeout: MACOS_SECURITY_TIMEOUT_MS,
|
|
214
217
|
});
|
|
215
218
|
if (result.error) {
|
|
216
219
|
throw new ConnectCredentialStoreError('secure_storage_write_failed', `Forkit Connect could not write secure credentials to macOS Keychain: ${result.error.message}`);
|
|
@@ -229,6 +232,7 @@ class MacOsKeychainBackend {
|
|
|
229
232
|
account,
|
|
230
233
|
], {
|
|
231
234
|
encoding: 'utf8',
|
|
235
|
+
timeout: MACOS_SECURITY_TIMEOUT_MS,
|
|
232
236
|
});
|
|
233
237
|
if (result.error) {
|
|
234
238
|
throw new ConnectCredentialStoreError('secure_storage_delete_failed', `Forkit Connect could not remove secure credentials from macOS Keychain: ${result.error.message}`);
|
|
@@ -241,6 +245,7 @@ class MacOsKeychainBackend {
|
|
|
241
245
|
getStatus() {
|
|
242
246
|
const result = (0, node_child_process_1.spawnSync)('security', ['list-keychains'], {
|
|
243
247
|
encoding: 'utf8',
|
|
248
|
+
timeout: MACOS_SECURITY_TIMEOUT_MS,
|
|
244
249
|
});
|
|
245
250
|
if (result.error) {
|
|
246
251
|
return {
|
package/dist/v1/service.js
CHANGED
|
@@ -173,33 +173,6 @@ function notificationTargetUrl(candidate) {
|
|
|
173
173
|
}
|
|
174
174
|
return `${base}/?${params.toString()}`;
|
|
175
175
|
}
|
|
176
|
-
function notificationTargetCommand(candidate) {
|
|
177
|
-
const targetArgs = (() => {
|
|
178
|
-
if (!candidate) {
|
|
179
|
-
return ['inbox'];
|
|
180
|
-
}
|
|
181
|
-
if (candidate.suggested_action === 'reconnect_account' || candidate.type === 'credential_reconnect_needed') {
|
|
182
|
-
return ['login'];
|
|
183
|
-
}
|
|
184
|
-
if (candidate.suggested_action === 'sync_c2' || candidate.type === 'c2_sync_pending') {
|
|
185
|
-
return ['sync'];
|
|
186
|
-
}
|
|
187
|
-
if (candidate.suggested_action === 'view_pulse_history') {
|
|
188
|
-
return ['changes'];
|
|
189
|
-
}
|
|
190
|
-
return ['inbox'];
|
|
191
|
-
})();
|
|
192
|
-
const currentScriptPath = process.argv[1] && node_path_1.default.isAbsolute(process.argv[1])
|
|
193
|
-
? process.argv[1]
|
|
194
|
-
: process.argv[1]
|
|
195
|
-
? node_path_1.default.resolve(process.cwd(), process.argv[1])
|
|
196
|
-
: null;
|
|
197
|
-
if (currentScriptPath && node_fs_1.default.existsSync(currentScriptPath)) {
|
|
198
|
-
const quote = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
|
|
199
|
-
return [quote(process.execPath), quote(currentScriptPath), ...targetArgs.map(quote)].join(' ');
|
|
200
|
-
}
|
|
201
|
-
return `forkit-connect ${targetArgs.join(' ')}`;
|
|
202
|
-
}
|
|
203
176
|
function hasLinuxGuiSession() {
|
|
204
177
|
return Boolean(normalizeSessionReference(process.env.DISPLAY)
|
|
205
178
|
|| normalizeSessionReference(process.env.WAYLAND_DISPLAY)
|
|
@@ -213,129 +186,6 @@ function resolveTerminalNotifierPath() {
|
|
|
213
186
|
const resolved = String(notifierPath.stdout || '').trim();
|
|
214
187
|
return resolved || null;
|
|
215
188
|
}
|
|
216
|
-
function resolveBundledTerminalNotifierBinary() {
|
|
217
|
-
try {
|
|
218
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
219
|
-
const notifierPackageJson = require.resolve('node-notifier/package.json');
|
|
220
|
-
const candidate = node_path_1.default.join(node_path_1.default.dirname(notifierPackageJson), 'vendor', 'mac.noindex', 'terminal-notifier.app', 'Contents', 'MacOS', 'terminal-notifier');
|
|
221
|
-
return node_fs_1.default.existsSync(candidate) ? candidate : null;
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
return null;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
function resolveBrandedNotifierIconSource() {
|
|
228
|
-
const candidate = node_path_1.default.resolve(__dirname, '..', '..', 'assets', 'connect-notifier-512.png');
|
|
229
|
-
return node_fs_1.default.existsSync(candidate) ? candidate : null;
|
|
230
|
-
}
|
|
231
|
-
function ensureBrandedMacNotifierIcon(helperApp) {
|
|
232
|
-
const sourcePng = resolveBrandedNotifierIconSource();
|
|
233
|
-
if (!sourcePng) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
const resourcesDir = node_path_1.default.join(helperApp, 'Contents', 'Resources');
|
|
237
|
-
const iconTarget = node_path_1.default.join(resourcesDir, 'Terminal.icns');
|
|
238
|
-
const iconMarker = node_path_1.default.join(resourcesDir, '.forkit-notifier-icon-v1');
|
|
239
|
-
if (node_fs_1.default.existsSync(iconMarker) && node_fs_1.default.existsSync(iconTarget)) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const iconsetDir = node_path_1.default.join(resourcesDir, 'ForkitConnect.iconset');
|
|
243
|
-
node_fs_1.default.rmSync(iconsetDir, { recursive: true, force: true });
|
|
244
|
-
node_fs_1.default.mkdirSync(iconsetDir, { recursive: true });
|
|
245
|
-
const variants = [
|
|
246
|
-
{ file: 'icon_16x16.png', size: 16 },
|
|
247
|
-
{ file: 'icon_16x16@2x.png', size: 32 },
|
|
248
|
-
{ file: 'icon_32x32.png', size: 32 },
|
|
249
|
-
{ file: 'icon_32x32@2x.png', size: 64 },
|
|
250
|
-
{ file: 'icon_128x128.png', size: 128 },
|
|
251
|
-
{ file: 'icon_128x128@2x.png', size: 256 },
|
|
252
|
-
{ file: 'icon_256x256.png', size: 256 },
|
|
253
|
-
{ file: 'icon_256x256@2x.png', size: 512 },
|
|
254
|
-
{ file: 'icon_512x512.png', size: 512 },
|
|
255
|
-
];
|
|
256
|
-
try {
|
|
257
|
-
for (const variant of variants) {
|
|
258
|
-
const outputPath = node_path_1.default.join(iconsetDir, variant.file);
|
|
259
|
-
const result = (0, node_child_process_1.spawnSync)('/usr/bin/sips', ['-z', String(variant.size), String(variant.size), sourcePng, '--out', outputPath], {
|
|
260
|
-
stdio: 'ignore',
|
|
261
|
-
});
|
|
262
|
-
if (result.status !== 0) {
|
|
263
|
-
throw new Error('icon_resize_failed');
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
node_fs_1.default.copyFileSync(sourcePng, node_path_1.default.join(iconsetDir, 'icon_512x512@2x.png'));
|
|
267
|
-
const buildResult = (0, node_child_process_1.spawnSync)('/usr/bin/iconutil', ['-c', 'icns', iconsetDir, '-o', iconTarget], {
|
|
268
|
-
stdio: 'ignore',
|
|
269
|
-
});
|
|
270
|
-
if (buildResult.status !== 0) {
|
|
271
|
-
throw new Error('iconutil_failed');
|
|
272
|
-
}
|
|
273
|
-
node_fs_1.default.writeFileSync(iconMarker, 'forkit-connect-notifier-icon-v1\n', 'utf8');
|
|
274
|
-
}
|
|
275
|
-
catch {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
finally {
|
|
279
|
-
node_fs_1.default.rmSync(iconsetDir, { recursive: true, force: true });
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
function notificationExecuteCommand(candidate) {
|
|
283
|
-
if (process.platform !== 'darwin') {
|
|
284
|
-
return null;
|
|
285
|
-
}
|
|
286
|
-
const targetCommand = notificationTargetCommand(candidate);
|
|
287
|
-
const escapedCommand = `${targetCommand}; exec "\${SHELL:-/bin/zsh}" -l`
|
|
288
|
-
.replace(/\\/g, '\\\\')
|
|
289
|
-
.replace(/"/g, '\\"');
|
|
290
|
-
return [
|
|
291
|
-
'/usr/bin/osascript',
|
|
292
|
-
`-e 'tell application "Terminal" to activate'`,
|
|
293
|
-
`-e 'tell application "Terminal" to do script "${escapedCommand}"'`,
|
|
294
|
-
].join(' ');
|
|
295
|
-
}
|
|
296
|
-
function resolveBrandedMacNotifierBinary() {
|
|
297
|
-
if (process.platform !== 'darwin') {
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
const bundledBinary = resolveBundledTerminalNotifierBinary();
|
|
301
|
-
if (!bundledBinary) {
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
const sourceApp = node_path_1.default.resolve(bundledBinary, '..', '..', '..');
|
|
305
|
-
const helperApp = node_path_1.default.join(node_os_1.default.homedir(), '.forkit-connect', 'vendor', 'Forkit Connect.app');
|
|
306
|
-
const helperBinary = node_path_1.default.join(helperApp, 'Contents', 'MacOS', 'terminal-notifier');
|
|
307
|
-
const helperPlist = node_path_1.default.join(helperApp, 'Contents', 'Info.plist');
|
|
308
|
-
const isAlreadyBranded = () => {
|
|
309
|
-
if (!node_fs_1.default.existsSync(helperBinary) || !node_fs_1.default.existsSync(helperPlist)) {
|
|
310
|
-
return false;
|
|
311
|
-
}
|
|
312
|
-
try {
|
|
313
|
-
const result = (0, node_child_process_1.spawnSync)('plutil', ['-extract', 'CFBundleIdentifier', 'raw', '-o', '-', helperPlist], {
|
|
314
|
-
encoding: 'utf8',
|
|
315
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
316
|
-
});
|
|
317
|
-
return result.status === 0 && String(result.stdout || '').trim() === 'dev.forkit.connect.notifications';
|
|
318
|
-
}
|
|
319
|
-
catch {
|
|
320
|
-
return false;
|
|
321
|
-
}
|
|
322
|
-
};
|
|
323
|
-
if (!isAlreadyBranded()) {
|
|
324
|
-
node_fs_1.default.mkdirSync(node_path_1.default.dirname(helperApp), { recursive: true });
|
|
325
|
-
node_fs_1.default.rmSync(helperApp, { recursive: true, force: true });
|
|
326
|
-
node_fs_1.default.cpSync(sourceApp, helperApp, { recursive: true });
|
|
327
|
-
const replacements = [
|
|
328
|
-
['CFBundleIdentifier', 'dev.forkit.connect.notifications'],
|
|
329
|
-
['CFBundleName', 'Forkit Connect'],
|
|
330
|
-
['CFBundleDisplayName', 'Forkit Connect'],
|
|
331
|
-
];
|
|
332
|
-
for (const [key, value] of replacements) {
|
|
333
|
-
(0, node_child_process_1.spawnSync)('plutil', ['-replace', key, '-string', value, helperPlist], { stdio: 'ignore' });
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
ensureBrandedMacNotifierIcon(helperApp);
|
|
337
|
-
return node_fs_1.default.existsSync(helperBinary) ? helperBinary : null;
|
|
338
|
-
}
|
|
339
189
|
function defaultNotificationSender(title, message, candidate) {
|
|
340
190
|
if (process.platform === 'linux') {
|
|
341
191
|
if (!hasLinuxGuiSession()) {
|
|
@@ -360,21 +210,15 @@ function defaultNotificationSender(title, message, candidate) {
|
|
|
360
210
|
}
|
|
361
211
|
}
|
|
362
212
|
if (process.platform === 'darwin') {
|
|
363
|
-
const
|
|
213
|
+
const targetUrl = notificationTargetUrl(candidate);
|
|
214
|
+
const resolvedNotifier = resolveTerminalNotifierPath();
|
|
364
215
|
if (resolvedNotifier) {
|
|
365
|
-
const
|
|
366
|
-
const
|
|
216
|
+
const openCommand = `/usr/bin/open '${targetUrl.replace(/'/g, "'\\''")}'`;
|
|
217
|
+
const result = (0, node_child_process_1.spawnSync)(resolvedNotifier, [
|
|
367
218
|
'-title', title,
|
|
368
|
-
'-subtitle', 'Forkit Connect',
|
|
369
219
|
'-message', message,
|
|
220
|
+
'-execute', openCommand,
|
|
370
221
|
'-group', 'forkit-connect',
|
|
371
|
-
'-sender', 'dev.forkit.connect.notifications',
|
|
372
|
-
];
|
|
373
|
-
if (executeCommand) {
|
|
374
|
-
args.push('-execute', executeCommand);
|
|
375
|
-
}
|
|
376
|
-
const result = (0, node_child_process_1.spawnSync)(resolvedNotifier, [
|
|
377
|
-
...args,
|
|
378
222
|
], { stdio: 'ignore' });
|
|
379
223
|
if (result.status === 0) {
|
|
380
224
|
return true;
|
|
@@ -9081,13 +8925,13 @@ class ConnectV1Service {
|
|
|
9081
8925
|
: `Unavailable at ${ollama.endpoint}: ${ollama.error ?? 'unknown_error'}`,
|
|
9082
8926
|
});
|
|
9083
8927
|
if (process.platform === 'darwin') {
|
|
9084
|
-
const notifierPath =
|
|
8928
|
+
const notifierPath = resolveTerminalNotifierPath();
|
|
9085
8929
|
checks.push({
|
|
9086
8930
|
name: 'desktop_notifications',
|
|
9087
8931
|
status: notifierPath ? 'PASS' : 'WARN',
|
|
9088
8932
|
details: notifierPath
|
|
9089
|
-
?
|
|
9090
|
-
: '
|
|
8933
|
+
? `terminal-notifier available at ${notifierPath}`
|
|
8934
|
+
: 'terminal-notifier is not installed. Notifications will be recorded locally but click-through will not work on macOS.',
|
|
9091
8935
|
});
|
|
9092
8936
|
}
|
|
9093
8937
|
const sessionRefSource = this.getSessionRefSource();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forkit-connect",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "Forkit Connect Local Engine - The Global AI Governance Fabric",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
|
-
"assets",
|
|
14
13
|
"README.md",
|
|
15
14
|
"QUICKSTART.md"
|
|
16
15
|
],
|
|
@@ -34,7 +33,6 @@
|
|
|
34
33
|
"better-sqlite3": "^12.10.0",
|
|
35
34
|
"cors": "^2.8.6",
|
|
36
35
|
"express": "^4.19.2",
|
|
37
|
-
"node-notifier": "^10.0.1",
|
|
38
36
|
"ps-list": "^8.1.1",
|
|
39
37
|
"uuid": "^10.0.0",
|
|
40
38
|
"ws": "^8.16.0",
|
|
Binary file
|
package/dist/v1/startup.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface CliStartupStatus {
|
|
2
|
-
supported: boolean;
|
|
3
|
-
platform: 'macos' | 'windows' | 'linux';
|
|
4
|
-
enabled: boolean | null;
|
|
5
|
-
mode: 'launch_agent' | 'registry_run' | 'systemd_user' | 'unsupported';
|
|
6
|
-
configPath: string | null;
|
|
7
|
-
note: string;
|
|
8
|
-
}
|
|
9
|
-
export declare function getCliStartupStatus(): CliStartupStatus;
|
|
10
|
-
export declare function enableCliStartup(processExecPath: string, cliPath: string): CliStartupStatus;
|
|
11
|
-
export declare function disableCliStartup(): CliStartupStatus;
|
|
12
|
-
//# sourceMappingURL=startup.d.ts.map
|
package/dist/v1/startup.js
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getCliStartupStatus = getCliStartupStatus;
|
|
7
|
-
exports.enableCliStartup = enableCliStartup;
|
|
8
|
-
exports.disableCliStartup = disableCliStartup;
|
|
9
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
-
const node_os_1 = __importDefault(require("node:os"));
|
|
11
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
-
const node_child_process_1 = require("node:child_process");
|
|
13
|
-
function normalizePlatform() {
|
|
14
|
-
if (process.platform === 'darwin')
|
|
15
|
-
return 'macos';
|
|
16
|
-
if (process.platform === 'win32')
|
|
17
|
-
return 'windows';
|
|
18
|
-
return 'linux';
|
|
19
|
-
}
|
|
20
|
-
function macLabel() {
|
|
21
|
-
return 'dev.forkit.connect.cli';
|
|
22
|
-
}
|
|
23
|
-
function macPlistPath() {
|
|
24
|
-
return node_path_1.default.join(node_os_1.default.homedir(), 'Library', 'LaunchAgents', `${macLabel()}.plist`);
|
|
25
|
-
}
|
|
26
|
-
function linuxServiceName() {
|
|
27
|
-
return 'forkit-connect.service';
|
|
28
|
-
}
|
|
29
|
-
function linuxServicePath() {
|
|
30
|
-
return node_path_1.default.join(node_os_1.default.homedir(), '.config', 'systemd', 'user', linuxServiceName());
|
|
31
|
-
}
|
|
32
|
-
function windowsRegistryKey() {
|
|
33
|
-
return 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';
|
|
34
|
-
}
|
|
35
|
-
function windowsRegistryValueName() {
|
|
36
|
-
return 'ForkitConnectCLI';
|
|
37
|
-
}
|
|
38
|
-
function launchctlGuiTarget() {
|
|
39
|
-
return `gui/${process.getuid?.() ?? 0}`;
|
|
40
|
-
}
|
|
41
|
-
function quoteWindows(value) {
|
|
42
|
-
return `"${value.replace(/"/g, '\\"')}"`;
|
|
43
|
-
}
|
|
44
|
-
function startupCommand(processExecPath, cliPath) {
|
|
45
|
-
return {
|
|
46
|
-
executable: processExecPath,
|
|
47
|
-
args: [cliPath, 'daemon', 'run-loop'],
|
|
48
|
-
display: `${quoteWindows(processExecPath)} ${quoteWindows(cliPath)} daemon run-loop`,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function writeMacPlist(processExecPath, cliPath) {
|
|
52
|
-
const command = startupCommand(processExecPath, cliPath);
|
|
53
|
-
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
54
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
55
|
-
<plist version="1.0">
|
|
56
|
-
<dict>
|
|
57
|
-
<key>Label</key>
|
|
58
|
-
<string>${macLabel()}</string>
|
|
59
|
-
<key>ProgramArguments</key>
|
|
60
|
-
<array>
|
|
61
|
-
<string>${command.executable}</string>
|
|
62
|
-
<string>${command.args[0]}</string>
|
|
63
|
-
<string>${command.args[1]}</string>
|
|
64
|
-
<string>${command.args[2]}</string>
|
|
65
|
-
</array>
|
|
66
|
-
<key>RunAtLoad</key>
|
|
67
|
-
<true/>
|
|
68
|
-
<key>KeepAlive</key>
|
|
69
|
-
<true/>
|
|
70
|
-
<key>WorkingDirectory</key>
|
|
71
|
-
<string>${process.cwd()}</string>
|
|
72
|
-
</dict>
|
|
73
|
-
</plist>
|
|
74
|
-
`;
|
|
75
|
-
const plistPath = macPlistPath();
|
|
76
|
-
node_fs_1.default.mkdirSync(node_path_1.default.dirname(plistPath), { recursive: true });
|
|
77
|
-
node_fs_1.default.writeFileSync(plistPath, plist, 'utf8');
|
|
78
|
-
return plistPath;
|
|
79
|
-
}
|
|
80
|
-
function writeLinuxService(processExecPath, cliPath) {
|
|
81
|
-
const command = startupCommand(processExecPath, cliPath);
|
|
82
|
-
const unit = `[Unit]
|
|
83
|
-
Description=Forkit Connect CLI background daemon
|
|
84
|
-
After=default.target
|
|
85
|
-
|
|
86
|
-
[Service]
|
|
87
|
-
Type=simple
|
|
88
|
-
ExecStart=${command.executable} ${command.args.join(' ')}
|
|
89
|
-
Restart=always
|
|
90
|
-
RestartSec=3
|
|
91
|
-
WorkingDirectory=${process.cwd()}
|
|
92
|
-
|
|
93
|
-
[Install]
|
|
94
|
-
WantedBy=default.target
|
|
95
|
-
`;
|
|
96
|
-
const servicePath = linuxServicePath();
|
|
97
|
-
node_fs_1.default.mkdirSync(node_path_1.default.dirname(servicePath), { recursive: true });
|
|
98
|
-
node_fs_1.default.writeFileSync(servicePath, unit, 'utf8');
|
|
99
|
-
return servicePath;
|
|
100
|
-
}
|
|
101
|
-
function getMacStatus() {
|
|
102
|
-
const plistPath = macPlistPath();
|
|
103
|
-
const exists = node_fs_1.default.existsSync(plistPath);
|
|
104
|
-
return {
|
|
105
|
-
supported: true,
|
|
106
|
-
platform: 'macos',
|
|
107
|
-
enabled: exists,
|
|
108
|
-
mode: 'launch_agent',
|
|
109
|
-
configPath: plistPath,
|
|
110
|
-
note: exists
|
|
111
|
-
? 'Forkit Connect CLI will start at sign-in through a LaunchAgent.'
|
|
112
|
-
: 'Forkit Connect CLI is not set to start at sign-in on this Mac.',
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
function getWindowsStatus() {
|
|
116
|
-
const query = (0, node_child_process_1.spawnSync)('reg', ['query', windowsRegistryKey(), '/v', windowsRegistryValueName()], {
|
|
117
|
-
encoding: 'utf8',
|
|
118
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
119
|
-
});
|
|
120
|
-
const enabled = query.status === 0;
|
|
121
|
-
return {
|
|
122
|
-
supported: true,
|
|
123
|
-
platform: 'windows',
|
|
124
|
-
enabled,
|
|
125
|
-
mode: 'registry_run',
|
|
126
|
-
configPath: windowsRegistryKey(),
|
|
127
|
-
note: enabled
|
|
128
|
-
? 'Forkit Connect CLI will start after sign-in through the Windows Run registry.'
|
|
129
|
-
: 'Forkit Connect CLI is not set to start after sign-in on Windows.',
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
function getLinuxStatus() {
|
|
133
|
-
const servicePath = linuxServicePath();
|
|
134
|
-
const exists = node_fs_1.default.existsSync(servicePath);
|
|
135
|
-
return {
|
|
136
|
-
supported: true,
|
|
137
|
-
platform: 'linux',
|
|
138
|
-
enabled: exists,
|
|
139
|
-
mode: 'systemd_user',
|
|
140
|
-
configPath: servicePath,
|
|
141
|
-
note: exists
|
|
142
|
-
? 'Forkit Connect CLI will start in the user session through systemd.'
|
|
143
|
-
: 'Forkit Connect CLI is not set to start in the user session on Linux.',
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
function getCliStartupStatus() {
|
|
147
|
-
const platform = normalizePlatform();
|
|
148
|
-
if (platform === 'macos')
|
|
149
|
-
return getMacStatus();
|
|
150
|
-
if (platform === 'windows')
|
|
151
|
-
return getWindowsStatus();
|
|
152
|
-
if (platform === 'linux')
|
|
153
|
-
return getLinuxStatus();
|
|
154
|
-
return {
|
|
155
|
-
supported: false,
|
|
156
|
-
platform,
|
|
157
|
-
enabled: null,
|
|
158
|
-
mode: 'unsupported',
|
|
159
|
-
configPath: null,
|
|
160
|
-
note: 'Startup management is not available on this platform.',
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
function enableCliStartup(processExecPath, cliPath) {
|
|
164
|
-
const platform = normalizePlatform();
|
|
165
|
-
if (platform === 'macos') {
|
|
166
|
-
const plistPath = writeMacPlist(processExecPath, cliPath);
|
|
167
|
-
(0, node_child_process_1.spawnSync)('launchctl', ['bootout', launchctlGuiTarget(), plistPath], { stdio: 'ignore' });
|
|
168
|
-
const bootstrap = (0, node_child_process_1.spawnSync)('launchctl', ['bootstrap', launchctlGuiTarget(), plistPath], { stdio: 'ignore' });
|
|
169
|
-
if (bootstrap.status !== 0) {
|
|
170
|
-
throw new Error('cli_startup_enable_failed_macos');
|
|
171
|
-
}
|
|
172
|
-
(0, node_child_process_1.spawnSync)('launchctl', ['kickstart', '-k', `${launchctlGuiTarget()}/${macLabel()}`], { stdio: 'ignore' });
|
|
173
|
-
return getMacStatus();
|
|
174
|
-
}
|
|
175
|
-
if (platform === 'windows') {
|
|
176
|
-
const command = startupCommand(processExecPath, cliPath);
|
|
177
|
-
const add = (0, node_child_process_1.spawnSync)('reg', [
|
|
178
|
-
'add',
|
|
179
|
-
windowsRegistryKey(),
|
|
180
|
-
'/v',
|
|
181
|
-
windowsRegistryValueName(),
|
|
182
|
-
'/t',
|
|
183
|
-
'REG_SZ',
|
|
184
|
-
'/d',
|
|
185
|
-
command.display,
|
|
186
|
-
'/f',
|
|
187
|
-
], { stdio: 'ignore' });
|
|
188
|
-
if (add.status !== 0) {
|
|
189
|
-
throw new Error('cli_startup_enable_failed_windows');
|
|
190
|
-
}
|
|
191
|
-
return getWindowsStatus();
|
|
192
|
-
}
|
|
193
|
-
if (platform === 'linux') {
|
|
194
|
-
const servicePath = writeLinuxService(processExecPath, cliPath);
|
|
195
|
-
const reload = (0, node_child_process_1.spawnSync)('systemctl', ['--user', 'daemon-reload'], { stdio: 'ignore' });
|
|
196
|
-
const enable = (0, node_child_process_1.spawnSync)('systemctl', ['--user', 'enable', '--now', linuxServiceName()], { stdio: 'ignore' });
|
|
197
|
-
if (reload.status !== 0 || enable.status !== 0 || !node_fs_1.default.existsSync(servicePath)) {
|
|
198
|
-
throw new Error('cli_startup_enable_failed_linux');
|
|
199
|
-
}
|
|
200
|
-
return getLinuxStatus();
|
|
201
|
-
}
|
|
202
|
-
throw new Error('cli_startup_unsupported');
|
|
203
|
-
}
|
|
204
|
-
function disableCliStartup() {
|
|
205
|
-
const platform = normalizePlatform();
|
|
206
|
-
if (platform === 'macos') {
|
|
207
|
-
const plistPath = macPlistPath();
|
|
208
|
-
(0, node_child_process_1.spawnSync)('launchctl', ['bootout', launchctlGuiTarget(), plistPath], { stdio: 'ignore' });
|
|
209
|
-
if (node_fs_1.default.existsSync(plistPath)) {
|
|
210
|
-
node_fs_1.default.rmSync(plistPath, { force: true });
|
|
211
|
-
}
|
|
212
|
-
return getMacStatus();
|
|
213
|
-
}
|
|
214
|
-
if (platform === 'windows') {
|
|
215
|
-
(0, node_child_process_1.spawnSync)('reg', ['delete', windowsRegistryKey(), '/v', windowsRegistryValueName(), '/f'], { stdio: 'ignore' });
|
|
216
|
-
return getWindowsStatus();
|
|
217
|
-
}
|
|
218
|
-
if (platform === 'linux') {
|
|
219
|
-
(0, node_child_process_1.spawnSync)('systemctl', ['--user', 'disable', '--now', linuxServiceName()], { stdio: 'ignore' });
|
|
220
|
-
(0, node_child_process_1.spawnSync)('systemctl', ['--user', 'daemon-reload'], { stdio: 'ignore' });
|
|
221
|
-
const servicePath = linuxServicePath();
|
|
222
|
-
if (node_fs_1.default.existsSync(servicePath)) {
|
|
223
|
-
node_fs_1.default.rmSync(servicePath, { force: true });
|
|
224
|
-
}
|
|
225
|
-
return getLinuxStatus();
|
|
226
|
-
}
|
|
227
|
-
throw new Error('cli_startup_unsupported');
|
|
228
|
-
}
|
|
229
|
-
//# sourceMappingURL=startup.js.map
|