notioncode 0.1.0 → 0.1.2
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 +22 -9
- package/agent-runtime-server/package-lock.json +4377 -0
- package/agent-runtime-server/package.json +36 -0
- package/agent-runtime-server/scripts/fix-node-pty.js +67 -0
- package/agent-runtime-server/server/agent-session-service.js +816 -0
- package/agent-runtime-server/server/claude-sdk.js +836 -0
- package/agent-runtime-server/server/cli.js +330 -0
- package/agent-runtime-server/server/constants/config.js +5 -0
- package/agent-runtime-server/server/cursor-cli.js +335 -0
- package/agent-runtime-server/server/database/db.js +653 -0
- package/agent-runtime-server/server/database/init.sql +99 -0
- package/agent-runtime-server/server/gemini-cli.js +460 -0
- package/agent-runtime-server/server/gemini-response-handler.js +79 -0
- package/agent-runtime-server/server/index.js +2569 -0
- package/agent-runtime-server/server/load-env.js +32 -0
- package/agent-runtime-server/server/middleware/auth.js +132 -0
- package/agent-runtime-server/server/openai-codex.js +512 -0
- package/agent-runtime-server/server/projects.js +2594 -0
- package/agent-runtime-server/server/providers/claude/adapter.js +278 -0
- package/agent-runtime-server/server/providers/codex/adapter.js +248 -0
- package/agent-runtime-server/server/providers/cursor/adapter.js +353 -0
- package/agent-runtime-server/server/providers/gemini/adapter.js +186 -0
- package/agent-runtime-server/server/providers/registry.js +44 -0
- package/agent-runtime-server/server/providers/types.js +119 -0
- package/agent-runtime-server/server/providers/utils.js +29 -0
- package/agent-runtime-server/server/routes/agent-sessions.js +238 -0
- package/agent-runtime-server/server/routes/agent.js +1244 -0
- package/agent-runtime-server/server/routes/auth.js +144 -0
- package/agent-runtime-server/server/routes/cli-auth.js +478 -0
- package/agent-runtime-server/server/routes/codex.js +329 -0
- package/agent-runtime-server/server/routes/commands.js +596 -0
- package/agent-runtime-server/server/routes/cursor.js +798 -0
- package/agent-runtime-server/server/routes/gemini.js +24 -0
- package/agent-runtime-server/server/routes/git.js +1508 -0
- package/agent-runtime-server/server/routes/mcp-utils.js +48 -0
- package/agent-runtime-server/server/routes/mcp.js +552 -0
- package/agent-runtime-server/server/routes/messages.js +61 -0
- package/agent-runtime-server/server/routes/plugins.js +307 -0
- package/agent-runtime-server/server/routes/projects.js +548 -0
- package/agent-runtime-server/server/routes/settings.js +276 -0
- package/agent-runtime-server/server/routes/taskmaster.js +1963 -0
- package/agent-runtime-server/server/routes/user.js +123 -0
- package/agent-runtime-server/server/services/notification-orchestrator.js +227 -0
- package/agent-runtime-server/server/services/vapid-keys.js +35 -0
- package/agent-runtime-server/server/sessionManager.js +226 -0
- package/agent-runtime-server/server/utils/commandParser.js +303 -0
- package/agent-runtime-server/server/utils/frontmatter.js +18 -0
- package/agent-runtime-server/server/utils/gitConfig.js +34 -0
- package/agent-runtime-server/server/utils/mcp-detector.js +198 -0
- package/agent-runtime-server/server/utils/plugin-loader.js +457 -0
- package/agent-runtime-server/server/utils/plugin-process-manager.js +184 -0
- package/agent-runtime-server/server/utils/taskmaster-websocket.js +129 -0
- package/agent-runtime-server/shared/modelConstants.js +12 -0
- package/agent-runtime-server/shared/modelConstants.test.js +34 -0
- package/agent-runtime-server/shared/networkHosts.js +22 -0
- package/agent-runtime-server/test_sdk.mjs +16 -0
- package/bin/bridges/darwin-x64/nocode-bridge +0 -0
- package/bin/{nocode-local.js → notioncode.js} +2 -8
- package/dist/assets/icon-CQtd7WEB.png +0 -0
- package/dist/assets/index-D_1ZrHDe.js +1 -0
- package/dist/assets/index-DhCWie1Z.css +1 -0
- package/dist/assets/index-DkGqIiwF.js +689 -0
- package/dist/index.html +46 -0
- package/dist/onboarding/step1_create.png +0 -0
- package/dist/onboarding/step2_capabilities.png +0 -0
- package/dist/onboarding/step2b_content_access.png +0 -0
- package/dist/onboarding/step2c_page_access.png +0 -0
- package/dist/onboarding/step3_token.png +0 -0
- package/dist/onboarding/step4_webhook.png +0 -0
- package/dist/onboarding/step6a_verify.png +0 -0
- package/dist/onboarding/step6b_copy_verify_token.png +0 -0
- package/dist/tinyfish-fish-only.png +0 -0
- package/lib/certs.js +332 -0
- package/lib/install.js +48 -4
- package/lib/start.js +346 -29
- package/package.json +10 -4
- package/src/shared/modelRegistry.d.ts +24 -0
- package/src/shared/modelRegistry.js +163 -0
package/dist/index.html
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" style="background-color: #1a1f2e;">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<link rel="icon" type="image/png" href="/icon.png" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
|
+
<title>Notion Code</title>
|
|
9
|
+
<script>
|
|
10
|
+
(function () {
|
|
11
|
+
try {
|
|
12
|
+
const savedTheme = localStorage.getItem('app-theme-preference');
|
|
13
|
+
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
14
|
+
|
|
15
|
+
// Determine if should be dark for later use, but ALWAYS start with splash color
|
|
16
|
+
const shouldBeDark = savedTheme === 'dark' || ((!savedTheme || savedTheme === 'system') && systemDark);
|
|
17
|
+
|
|
18
|
+
// Set background color IMMEDIATELY to SPLASH COLOR (seamless transition)
|
|
19
|
+
document.documentElement.style.backgroundColor = '#1a1f2e';
|
|
20
|
+
|
|
21
|
+
if (shouldBeDark) {
|
|
22
|
+
document.documentElement.classList.add('dark');
|
|
23
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
24
|
+
} else {
|
|
25
|
+
document.documentElement.classList.remove('dark');
|
|
26
|
+
document.documentElement.setAttribute('data-theme', 'light');
|
|
27
|
+
}
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.error('Failed to apply theme during boot:', e);
|
|
30
|
+
document.documentElement.style.backgroundColor = '#1a1f2e';
|
|
31
|
+
}
|
|
32
|
+
})();
|
|
33
|
+
</script>
|
|
34
|
+
<script type="module" crossorigin src="./assets/index-DkGqIiwF.js"></script>
|
|
35
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DhCWie1Z.css">
|
|
36
|
+
</head>
|
|
37
|
+
|
|
38
|
+
<body style="margin: 0; background-color: #1a1f2e;">
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
<div id="root"></div>
|
|
44
|
+
</body>
|
|
45
|
+
|
|
46
|
+
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/certs.js
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { chmodSync, createWriteStream, existsSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { execFileSync } from 'node:child_process';
|
|
5
|
+
import https from 'node:https';
|
|
6
|
+
|
|
7
|
+
import { defaultCacheDir } from './platform.js';
|
|
8
|
+
|
|
9
|
+
function appDataDir() {
|
|
10
|
+
return path.join(defaultCacheDir(), 'local-https');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function localBinDir() {
|
|
14
|
+
return path.join(appDataDir(), 'bin');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function ensureDir(dirPath) {
|
|
18
|
+
mkdirSync(dirPath, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function pathEntries() {
|
|
22
|
+
return (process.env.PATH || '').split(path.delimiter).filter(Boolean);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function resolveCommand(command) {
|
|
26
|
+
const names = process.platform === 'win32' ? [command, `${command}.exe`, `${command}.cmd`] : [command];
|
|
27
|
+
const extraDirs = process.platform === 'darwin'
|
|
28
|
+
? ['/opt/homebrew/bin', '/usr/local/bin', localBinDir()]
|
|
29
|
+
: process.platform === 'win32'
|
|
30
|
+
? [
|
|
31
|
+
'C:\\ProgramData\\chocolatey\\bin',
|
|
32
|
+
path.join(os.homedir(), 'scoop', 'shims'),
|
|
33
|
+
localBinDir(),
|
|
34
|
+
]
|
|
35
|
+
: [localBinDir()];
|
|
36
|
+
|
|
37
|
+
for (const dir of [...pathEntries(), ...extraDirs]) {
|
|
38
|
+
for (const name of names) {
|
|
39
|
+
const fullPath = path.join(dir, name);
|
|
40
|
+
if (existsSync(fullPath)) {
|
|
41
|
+
return fullPath;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function hasCommand(command) {
|
|
50
|
+
return Boolean(resolveCommand(command));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function runResolvedCommand(command, args, options = {}) {
|
|
54
|
+
const resolved = resolveCommand(command);
|
|
55
|
+
if (!resolved) {
|
|
56
|
+
throw new Error(`Command not found: ${command}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return execFileSync(resolved, args, {
|
|
60
|
+
stdio: 'inherit',
|
|
61
|
+
...options,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function certificatePaths() {
|
|
66
|
+
const dir = path.join(appDataDir(), 'certs');
|
|
67
|
+
return {
|
|
68
|
+
dir,
|
|
69
|
+
certFile: path.join(dir, 'localhost.pem'),
|
|
70
|
+
keyFile: path.join(dir, 'localhost-key.pem'),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function hasCertificateFiles(paths) {
|
|
75
|
+
return existsSync(paths.certFile) && existsSync(paths.keyFile);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function mkcertInstallInstructions() {
|
|
79
|
+
if (process.platform === 'darwin') {
|
|
80
|
+
return ['brew install mkcert', 'mkcert -install'];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (process.platform === 'win32') {
|
|
84
|
+
return ['choco install mkcert', 'mkcert -install'];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return ['install mkcert with your package manager', 'mkcert -install'];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function mkcertAssetMatcher() {
|
|
91
|
+
if (process.platform === 'darwin' && process.arch === 'arm64') {
|
|
92
|
+
return /darwin-arm64$/;
|
|
93
|
+
}
|
|
94
|
+
if (process.platform === 'darwin' && process.arch === 'x64') {
|
|
95
|
+
return /darwin-amd64$|darwin-x86_64$|darwin-x64$/;
|
|
96
|
+
}
|
|
97
|
+
if (process.platform === 'linux' && process.arch === 'x64') {
|
|
98
|
+
return /linux-amd64$|linux-x86_64$|linux-x64$/;
|
|
99
|
+
}
|
|
100
|
+
if (process.platform === 'win32' && process.arch === 'x64') {
|
|
101
|
+
return /windows-amd64\.exe$|windows-x86_64\.exe$|windows-x64\.exe$/;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
throw new Error(`Unsupported platform for automatic mkcert download: ${process.platform}/${process.arch}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function requestJson(url) {
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
https
|
|
110
|
+
.get(
|
|
111
|
+
url,
|
|
112
|
+
{
|
|
113
|
+
headers: {
|
|
114
|
+
'User-Agent': 'notioncode-local',
|
|
115
|
+
Accept: 'application/vnd.github+json',
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
(response) => {
|
|
119
|
+
if ((response.statusCode || 0) >= 300 && (response.statusCode || 0) < 400 && response.headers.location) {
|
|
120
|
+
response.resume();
|
|
121
|
+
requestJson(response.headers.location).then(resolve, reject);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if ((response.statusCode || 0) >= 400) {
|
|
126
|
+
response.resume();
|
|
127
|
+
reject(new Error(`GitHub API request failed with HTTP ${response.statusCode}`));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let body = '';
|
|
132
|
+
response.setEncoding('utf8');
|
|
133
|
+
response.on('data', (chunk) => {
|
|
134
|
+
body += chunk;
|
|
135
|
+
});
|
|
136
|
+
response.on('end', () => {
|
|
137
|
+
try {
|
|
138
|
+
resolve(JSON.parse(body));
|
|
139
|
+
} catch (error) {
|
|
140
|
+
reject(error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
.on('error', reject);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function downloadFile(url, destination) {
|
|
150
|
+
return new Promise((resolve, reject) => {
|
|
151
|
+
https
|
|
152
|
+
.get(
|
|
153
|
+
url,
|
|
154
|
+
{
|
|
155
|
+
headers: {
|
|
156
|
+
'User-Agent': 'notioncode-local',
|
|
157
|
+
Accept: 'application/octet-stream',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
(response) => {
|
|
161
|
+
if ((response.statusCode || 0) >= 300 && (response.statusCode || 0) < 400 && response.headers.location) {
|
|
162
|
+
response.resume();
|
|
163
|
+
downloadFile(response.headers.location, destination).then(resolve, reject);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if ((response.statusCode || 0) >= 400) {
|
|
168
|
+
response.resume();
|
|
169
|
+
reject(new Error(`mkcert download failed with HTTP ${response.statusCode}`));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const output = createWriteStream(destination, { mode: 0o755 });
|
|
174
|
+
response.pipe(output);
|
|
175
|
+
output.on('finish', () => {
|
|
176
|
+
output.close(() => resolve(destination));
|
|
177
|
+
});
|
|
178
|
+
output.on('error', reject);
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
.on('error', reject);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function installStandaloneMkcert() {
|
|
186
|
+
ensureDir(localBinDir());
|
|
187
|
+
|
|
188
|
+
const latestRelease = await requestJson('https://api.github.com/repos/FiloSottile/mkcert/releases/latest');
|
|
189
|
+
const matcher = mkcertAssetMatcher();
|
|
190
|
+
const asset = Array.isArray(latestRelease.assets)
|
|
191
|
+
? latestRelease.assets.find((entry) => typeof entry?.name === 'string' && matcher.test(entry.name))
|
|
192
|
+
: null;
|
|
193
|
+
|
|
194
|
+
if (!asset?.browser_download_url) {
|
|
195
|
+
throw new Error(`Could not find a mkcert download for ${process.platform}/${process.arch}.`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const targetName = process.platform === 'win32' ? 'mkcert.exe' : 'mkcert';
|
|
199
|
+
const targetPath = path.join(localBinDir(), targetName);
|
|
200
|
+
console.log(`[notioncode] Downloading mkcert to ${targetPath} ...`);
|
|
201
|
+
await downloadFile(asset.browser_download_url, targetPath);
|
|
202
|
+
if (process.platform !== 'win32') {
|
|
203
|
+
chmodSync(targetPath, 0o755);
|
|
204
|
+
}
|
|
205
|
+
return targetPath;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function installMkcertIfPossible() {
|
|
209
|
+
if (hasCommand('mkcert')) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (process.platform === 'darwin' && hasCommand('brew')) {
|
|
214
|
+
console.log('[notioncode] Installing mkcert with Homebrew...');
|
|
215
|
+
runResolvedCommand('brew', ['install', 'mkcert']);
|
|
216
|
+
if (!hasCommand('mkcert')) {
|
|
217
|
+
throw new Error('Homebrew completed, but mkcert is still not available on PATH.');
|
|
218
|
+
}
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (process.platform === 'win32' && hasCommand('choco')) {
|
|
223
|
+
console.log('[notioncode] Installing mkcert with Chocolatey...');
|
|
224
|
+
runResolvedCommand('choco', ['install', 'mkcert', '-y']);
|
|
225
|
+
if (!hasCommand('mkcert')) {
|
|
226
|
+
throw new Error('Chocolatey completed, but mkcert is still not available on PATH.');
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (process.platform === 'win32' && hasCommand('scoop')) {
|
|
232
|
+
console.log('[notioncode] Installing mkcert with Scoop...');
|
|
233
|
+
runResolvedCommand('scoop', ['install', 'mkcert']);
|
|
234
|
+
if (!hasCommand('mkcert')) {
|
|
235
|
+
throw new Error('Scoop completed, but mkcert is still not available on PATH.');
|
|
236
|
+
}
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
console.log('[notioncode] No package-manager mkcert installation path was detected. Falling back to a direct mkcert download...');
|
|
241
|
+
throw new Error('__DOWNLOAD_MKCERT__');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function ensureMkcertAvailable() {
|
|
245
|
+
try {
|
|
246
|
+
installMkcertIfPossible();
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (error instanceof Error && error.message === '__DOWNLOAD_MKCERT__') {
|
|
249
|
+
return installStandaloneMkcert();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
throw error;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function waitForMkcertOnPath() {
|
|
257
|
+
const resolved = resolveCommand('mkcert');
|
|
258
|
+
if (!resolved) {
|
|
259
|
+
throw new Error('mkcert installation completed, but the binary is still unavailable.');
|
|
260
|
+
}
|
|
261
|
+
return resolved;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async function ensureMkcertReady() {
|
|
265
|
+
await ensureMkcertAvailable();
|
|
266
|
+
return waitForMkcertOnPath();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function installMkcertAndTrust() {
|
|
270
|
+
await ensureMkcertReady();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async function installTrustedLocalCa() {
|
|
274
|
+
await installMkcertAndTrust();
|
|
275
|
+
|
|
276
|
+
console.log(
|
|
277
|
+
'[notioncode] NotionCode needs to install a local certificate authority so Safari can trust https://localhost:1420.'
|
|
278
|
+
);
|
|
279
|
+
console.log(
|
|
280
|
+
'[notioncode] Your OS may ask for approval or your system password because this updates the local trust store.'
|
|
281
|
+
);
|
|
282
|
+
runResolvedCommand('mkcert', ['-install']);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function generateTrustedLocalhostCert(paths) {
|
|
286
|
+
console.log('[notioncode] Generating trusted localhost certificate...');
|
|
287
|
+
runResolvedCommand('mkcert', [
|
|
288
|
+
'-cert-file',
|
|
289
|
+
paths.certFile,
|
|
290
|
+
'-key-file',
|
|
291
|
+
paths.keyFile,
|
|
292
|
+
'localhost',
|
|
293
|
+
'127.0.0.1',
|
|
294
|
+
'::1',
|
|
295
|
+
]);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export async function ensureTrustedLocalhostCert() {
|
|
299
|
+
const paths = certificatePaths();
|
|
300
|
+
ensureDir(paths.dir);
|
|
301
|
+
|
|
302
|
+
await installTrustedLocalCa();
|
|
303
|
+
|
|
304
|
+
if (!hasCertificateFiles(paths)) {
|
|
305
|
+
generateTrustedLocalhostCert(paths);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
certFile: paths.certFile,
|
|
310
|
+
keyFile: paths.keyFile,
|
|
311
|
+
certDir: paths.dir,
|
|
312
|
+
appDataDir: appDataDir(),
|
|
313
|
+
localBinDir: localBinDir(),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function diagnoseTrustedLocalhostCert() {
|
|
318
|
+
const paths = certificatePaths();
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
appDataDir: appDataDir(),
|
|
322
|
+
certDir: paths.dir,
|
|
323
|
+
certFile: paths.certFile,
|
|
324
|
+
keyFile: paths.keyFile,
|
|
325
|
+
mkcertInstalled: hasCommand('mkcert'),
|
|
326
|
+
mkcertPath: resolveCommand('mkcert'),
|
|
327
|
+
brewInstalled: hasCommand('brew'),
|
|
328
|
+
brewPath: resolveCommand('brew'),
|
|
329
|
+
certExists: existsSync(paths.certFile),
|
|
330
|
+
keyExists: existsSync(paths.keyFile),
|
|
331
|
+
};
|
|
332
|
+
}
|
package/lib/install.js
CHANGED
|
@@ -1,16 +1,31 @@
|
|
|
1
|
-
import { chmodSync, copyFileSync, createWriteStream, existsSync, mkdirSync } from 'node:fs';
|
|
1
|
+
import { chmodSync, copyFileSync, createWriteStream, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { pipeline } from 'node:stream/promises';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
6
7
|
import { fileURLToPath } from 'node:url';
|
|
7
8
|
|
|
8
9
|
import { commandForPlatform, defaultCacheDir, resolvePlatformTarget } from './platform.js';
|
|
9
10
|
|
|
10
|
-
const DEFAULT_VERSION = '0.1.0';
|
|
11
11
|
const DEFAULT_ASSET_BASE =
|
|
12
12
|
process.env.NOCODE_COMPANION_ASSET_BASE_URL ||
|
|
13
13
|
'https://github.com/tadkt/nocode/releases/download';
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
|
|
16
|
+
function packageVersion() {
|
|
17
|
+
try {
|
|
18
|
+
const packageJsonPath = path.join(packageRootDir(), 'package.json');
|
|
19
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
20
|
+
return typeof packageJson.version === 'string' && packageJson.version.trim()
|
|
21
|
+
? packageJson.version.trim()
|
|
22
|
+
: '0.1.0';
|
|
23
|
+
} catch {
|
|
24
|
+
return '0.1.0';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const DEFAULT_VERSION = packageVersion();
|
|
14
29
|
|
|
15
30
|
function packageRootDir() {
|
|
16
31
|
return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
@@ -27,6 +42,30 @@ function localBinaryName() {
|
|
|
27
42
|
return process.platform === 'win32' ? 'nocode-bridge.exe' : 'nocode-bridge';
|
|
28
43
|
}
|
|
29
44
|
|
|
45
|
+
export function bridgeAssetFileNameForTarget(target = resolvePlatformTarget()) {
|
|
46
|
+
return `nocode-bridge-${target}${process.platform === 'win32' ? '.exe' : ''}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function resolveBundledNpmBridgePath(target = resolvePlatformTarget()) {
|
|
50
|
+
try {
|
|
51
|
+
const packageJsonPath = require.resolve('notioncode/package.json');
|
|
52
|
+
const packageDir = path.dirname(packageJsonPath);
|
|
53
|
+
const binaryPath = path.join(packageDir, 'bin', 'bridges', target, localBinaryName());
|
|
54
|
+
|
|
55
|
+
if (!existsSync(binaryPath)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (process.platform !== 'win32') {
|
|
60
|
+
chmodSync(binaryPath, 0o755);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return binaryPath;
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
30
69
|
function canUseCargo() {
|
|
31
70
|
const result = spawnSync(commandForPlatform('cargo'), ['--version'], {
|
|
32
71
|
stdio: 'ignore',
|
|
@@ -53,6 +92,11 @@ export async function ensureBridgeBinary(version = DEFAULT_VERSION) {
|
|
|
53
92
|
return envPath;
|
|
54
93
|
}
|
|
55
94
|
|
|
95
|
+
const npmInstalled = resolveBundledNpmBridgePath();
|
|
96
|
+
if (npmInstalled) {
|
|
97
|
+
return npmInstalled;
|
|
98
|
+
}
|
|
99
|
+
|
|
56
100
|
const installed = resolveInstalledBridgePath(version);
|
|
57
101
|
if (existsSync(installed)) {
|
|
58
102
|
return installed;
|
|
@@ -75,7 +119,7 @@ export async function ensureBridgeBinary(version = DEFAULT_VERSION) {
|
|
|
75
119
|
export async function downloadBridgeBinary(version = DEFAULT_VERSION, destination = resolveInstalledBridgePath(version)) {
|
|
76
120
|
mkdirSync(path.dirname(destination), { recursive: true });
|
|
77
121
|
const target = resolvePlatformTarget();
|
|
78
|
-
const assetName =
|
|
122
|
+
const assetName = bridgeAssetFileNameForTarget(target);
|
|
79
123
|
const url = `${DEFAULT_ASSET_BASE}/notioncode-v${version}/${assetName}`;
|
|
80
124
|
|
|
81
125
|
const response = await fetch(url);
|
|
@@ -110,7 +154,7 @@ export function buildLocalBridgeAsset(version = DEFAULT_VERSION) {
|
|
|
110
154
|
const artifactsDir = path.join(repoRoot, 'artifacts', 'local-companion', version);
|
|
111
155
|
mkdirSync(artifactsDir, { recursive: true });
|
|
112
156
|
const target = resolvePlatformTarget();
|
|
113
|
-
const dest = path.join(artifactsDir,
|
|
157
|
+
const dest = path.join(artifactsDir, bridgeAssetFileNameForTarget(target));
|
|
114
158
|
copyFileSync(source, dest);
|
|
115
159
|
if (process.platform !== 'win32') {
|
|
116
160
|
chmodSync(dest, 0o755);
|