main.mjs
131 lines 3.9 KB
Raw
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700 feat(companion): add production macOS distribution path Human minor ⚠ breaking 24 days ago
1 #!/usr/bin/env node
2 import { createCustodyKeychainAdapter } from './custody-client.mjs';
3 import { fileURLToPath } from 'node:url';
4 import {
5 COMPANION_HUB_ORIGIN,
6 ensureHostedSession,
7 inspectCompanionSession,
8 signInCompanion,
9 signOutCompanion,
10 verifyHostedSession,
11 } from './oauth-session.mjs';
12
13 function parseInvocation(argv) {
14 const modeIndex = argv.indexOf('--mode');
15 if (modeIndex < 0 || !['app', 'cli', 'mcp'].includes(argv[modeIndex + 1])) {
16 throw new Error('invalid_runtime_mode');
17 }
18 const separator = argv.indexOf('--', modeIndex + 2);
19 return {
20 mode: argv[modeIndex + 1],
21 args: separator < 0 ? [] : argv.slice(separator + 1),
22 };
23 }
24
25 async function runCompanionCommand(custody, args) {
26 const action = args[1] ?? 'status';
27 if (action === 'status') {
28 await custody.status();
29 const status = await inspectCompanionSession({ keychain: custody });
30 console.log(JSON.stringify({ custody: 'available', ...status }));
31 return;
32 }
33 if (action === 'sign-in') {
34 await signInCompanion({ keychain: custody });
35 console.log(JSON.stringify({ signedIn: true }));
36 return;
37 }
38 if (action === 'verify-session') {
39 const result = await verifyHostedSession({ keychain: custody });
40 console.log(JSON.stringify(result));
41 return;
42 }
43 if (action === 'sign-out') {
44 console.log(JSON.stringify(await signOutCompanion({ keychain: custody })));
45 return;
46 }
47 throw new Error('unknown_companion_command');
48 }
49
50 async function applyHostedSession(custody) {
51 try {
52 const session = await ensureHostedSession({ keychain: custody });
53 process.env.KNOWTATION_HUB_URL = COMPANION_HUB_ORIGIN;
54 process.env.KNOWTATION_HUB_TOKEN = session.accessToken;
55 return true;
56 } catch {
57 delete process.env.KNOWTATION_HUB_URL;
58 delete process.env.KNOWTATION_HUB_TOKEN;
59 return false;
60 }
61 }
62
63 async function main() {
64 const invocation = parseInvocation(process.argv.slice(2));
65 const custody = createCustodyKeychainAdapter();
66 globalThis.__knowtationCustody = custody;
67 process.once('exit', () => custody.close());
68
69 if (invocation.mode === 'app') {
70 if (invocation.args[0] === 'companion') {
71 try {
72 await runCompanionCommand(custody, invocation.args);
73 } finally {
74 custody.close();
75 }
76 return;
77 }
78 const launcherPID = process.ppid;
79 await custody.status();
80 const { startAppRuntime } = await import('./app-runtime.mjs');
81 const runtimeRoot = fileURLToPath(new URL('../../', import.meta.url));
82 const runtime = await startAppRuntime({ custody, runtimeRoot });
83 const stop = async () => {
84 await runtime.close().catch(() => {});
85 custody.close();
86 process.exit(0);
87 };
88 process.once('SIGINT', () => void stop());
89 process.once('SIGTERM', () => void stop());
90 const parentWatch = setInterval(() => {
91 if (process.ppid !== launcherPID) void stop();
92 }, 1_000);
93 parentWatch.unref();
94 await new Promise(() => {});
95 return;
96 }
97
98 if (invocation.mode === 'cli') {
99 if (invocation.args[0] === 'companion') {
100 try {
101 await runCompanionCommand(custody, invocation.args);
102 } finally {
103 custody.close();
104 }
105 return;
106 }
107 await applyHostedSession(custody);
108 process.argv = [process.execPath, fileURLToPath(new URL('../../cli/index.mjs', import.meta.url)), ...invocation.args];
109 await import('../../cli/index.mjs');
110 return;
111 }
112
113 if (invocation.args[0] === 'companion') {
114 try {
115 await runCompanionCommand(custody, invocation.args);
116 } finally {
117 custody.close();
118 }
119 return;
120 }
121 process.env.MCP_TRANSPORT = 'stdio';
122 process.env.KNOWTATION_MCP_TRANSPORT = 'stdio';
123 await applyHostedSession(custody);
124 process.argv = [process.execPath, fileURLToPath(new URL('../../mcp/server.mjs', import.meta.url)), ...invocation.args];
125 await import('../../mcp/server.mjs');
126 }
127
128 main().catch((error) => {
129 console.error(error?.code || error?.message || 'companion_runtime_failed');
130 process.exit(1);
131 });
File History 1 commit
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700 feat(companion): add production macOS distribution path Human minor ⚠ 24 days ago