notioncode 0.1.1 → 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 +10 -4
- 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} +0 -0
- 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/install.js +33 -2
- package/lib/start.js +157 -25
- package/package.json +7 -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/install.js
CHANGED
|
@@ -3,6 +3,7 @@ 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';
|
|
@@ -10,6 +11,7 @@ import { commandForPlatform, defaultCacheDir, resolvePlatformTarget } from './pl
|
|
|
10
11
|
const DEFAULT_ASSET_BASE =
|
|
11
12
|
process.env.NOCODE_COMPANION_ASSET_BASE_URL ||
|
|
12
13
|
'https://github.com/tadkt/nocode/releases/download';
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
13
15
|
|
|
14
16
|
function packageVersion() {
|
|
15
17
|
try {
|
|
@@ -40,6 +42,30 @@ function localBinaryName() {
|
|
|
40
42
|
return process.platform === 'win32' ? 'nocode-bridge.exe' : 'nocode-bridge';
|
|
41
43
|
}
|
|
42
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
|
+
|
|
43
69
|
function canUseCargo() {
|
|
44
70
|
const result = spawnSync(commandForPlatform('cargo'), ['--version'], {
|
|
45
71
|
stdio: 'ignore',
|
|
@@ -66,6 +92,11 @@ export async function ensureBridgeBinary(version = DEFAULT_VERSION) {
|
|
|
66
92
|
return envPath;
|
|
67
93
|
}
|
|
68
94
|
|
|
95
|
+
const npmInstalled = resolveBundledNpmBridgePath();
|
|
96
|
+
if (npmInstalled) {
|
|
97
|
+
return npmInstalled;
|
|
98
|
+
}
|
|
99
|
+
|
|
69
100
|
const installed = resolveInstalledBridgePath(version);
|
|
70
101
|
if (existsSync(installed)) {
|
|
71
102
|
return installed;
|
|
@@ -88,7 +119,7 @@ export async function ensureBridgeBinary(version = DEFAULT_VERSION) {
|
|
|
88
119
|
export async function downloadBridgeBinary(version = DEFAULT_VERSION, destination = resolveInstalledBridgePath(version)) {
|
|
89
120
|
mkdirSync(path.dirname(destination), { recursive: true });
|
|
90
121
|
const target = resolvePlatformTarget();
|
|
91
|
-
const assetName =
|
|
122
|
+
const assetName = bridgeAssetFileNameForTarget(target);
|
|
92
123
|
const url = `${DEFAULT_ASSET_BASE}/notioncode-v${version}/${assetName}`;
|
|
93
124
|
|
|
94
125
|
const response = await fetch(url);
|
|
@@ -123,7 +154,7 @@ export function buildLocalBridgeAsset(version = DEFAULT_VERSION) {
|
|
|
123
154
|
const artifactsDir = path.join(repoRoot, 'artifacts', 'local-companion', version);
|
|
124
155
|
mkdirSync(artifactsDir, { recursive: true });
|
|
125
156
|
const target = resolvePlatformTarget();
|
|
126
|
-
const dest = path.join(artifactsDir,
|
|
157
|
+
const dest = path.join(artifactsDir, bridgeAssetFileNameForTarget(target));
|
|
127
158
|
copyFileSync(source, dest);
|
|
128
159
|
if (process.platform !== 'win32') {
|
|
129
160
|
chmodSync(dest, 0o755);
|
package/lib/start.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { createReadStream, existsSync, readFileSync, statSync } from 'node:fs';
|
|
1
2
|
import http from 'node:http';
|
|
2
3
|
import https from 'node:https';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { spawn, spawnSync } from 'node:child_process';
|
|
5
|
-
import { existsSync } from 'node:fs';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { setTimeout as sleep } from 'node:timers/promises';
|
|
8
8
|
|
|
@@ -26,10 +26,18 @@ function detectRuntimeRoot() {
|
|
|
26
26
|
return process.env.NOCODE_RUNTIME_ROOT;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
const packageRoot = packageRootDir();
|
|
30
|
+
if (
|
|
31
|
+
existsSync(path.join(packageRoot, 'agent-runtime-server', 'package.json')) ||
|
|
32
|
+
existsSync(path.join(packageRoot, 'dist', 'index.html'))
|
|
33
|
+
) {
|
|
34
|
+
return packageRoot;
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
const candidates = [
|
|
30
|
-
path.resolve(
|
|
38
|
+
path.resolve(packageRoot, '..', '..'),
|
|
31
39
|
process.cwd(),
|
|
32
|
-
path.resolve(
|
|
40
|
+
path.resolve(packageRoot, '..'),
|
|
33
41
|
];
|
|
34
42
|
|
|
35
43
|
for (const candidate of candidates) {
|
|
@@ -204,6 +212,97 @@ function hasLocalUiRepo() {
|
|
|
204
212
|
return existsSync(path.join(runtimeRoot, 'package.json')) && existsSync(path.join(runtimeRoot, 'node_modules', 'vite', 'bin', 'vite.js'));
|
|
205
213
|
}
|
|
206
214
|
|
|
215
|
+
function hasBundledLocalUi(runtimeRoot) {
|
|
216
|
+
return existsSync(path.join(runtimeRoot, 'dist', 'index.html'));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function mimeTypeForPath(filePath) {
|
|
220
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
221
|
+
switch (ext) {
|
|
222
|
+
case '.html':
|
|
223
|
+
return 'text/html; charset=utf-8';
|
|
224
|
+
case '.js':
|
|
225
|
+
return 'text/javascript; charset=utf-8';
|
|
226
|
+
case '.css':
|
|
227
|
+
return 'text/css; charset=utf-8';
|
|
228
|
+
case '.json':
|
|
229
|
+
return 'application/json; charset=utf-8';
|
|
230
|
+
case '.svg':
|
|
231
|
+
return 'image/svg+xml';
|
|
232
|
+
case '.png':
|
|
233
|
+
return 'image/png';
|
|
234
|
+
case '.jpg':
|
|
235
|
+
case '.jpeg':
|
|
236
|
+
return 'image/jpeg';
|
|
237
|
+
case '.webp':
|
|
238
|
+
return 'image/webp';
|
|
239
|
+
case '.woff2':
|
|
240
|
+
return 'font/woff2';
|
|
241
|
+
case '.txt':
|
|
242
|
+
return 'text/plain; charset=utf-8';
|
|
243
|
+
default:
|
|
244
|
+
return 'application/octet-stream';
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function resolveStaticAssetPath(rootDir, requestUrl) {
|
|
249
|
+
const url = new URL(requestUrl, 'http://localhost');
|
|
250
|
+
const normalizedPath = decodeURIComponent(url.pathname);
|
|
251
|
+
const candidate = normalizedPath === '/'
|
|
252
|
+
? path.join(rootDir, 'index.html')
|
|
253
|
+
: path.join(rootDir, normalizedPath.replace(/^\/+/, ''));
|
|
254
|
+
|
|
255
|
+
const normalizedRoot = `${path.resolve(rootDir)}${path.sep}`;
|
|
256
|
+
const resolvedCandidate = path.resolve(candidate);
|
|
257
|
+
if (resolvedCandidate !== path.resolve(rootDir, 'index.html') && !resolvedCandidate.startsWith(normalizedRoot)) {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (existsSync(resolvedCandidate)) {
|
|
262
|
+
const stats = statSync(resolvedCandidate);
|
|
263
|
+
if (stats.isFile()) {
|
|
264
|
+
return resolvedCandidate;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (!path.extname(normalizedPath)) {
|
|
269
|
+
return path.join(rootDir, 'index.html');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function startBundledLocalUiServer({ runtimeRoot, useHttpsLocalUi, localHttps, localUiHost }) {
|
|
276
|
+
const distRoot = path.join(runtimeRoot, 'dist');
|
|
277
|
+
const listener = (req, res) => {
|
|
278
|
+
const targetFile = resolveStaticAssetPath(distRoot, req.url || '/');
|
|
279
|
+
if (!targetFile || !existsSync(targetFile)) {
|
|
280
|
+
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
281
|
+
res.end('Not found');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
res.writeHead(200, {
|
|
286
|
+
'Content-Type': mimeTypeForPath(targetFile),
|
|
287
|
+
'Cache-Control': targetFile.endsWith('index.html') ? 'no-cache' : 'public, max-age=31536000, immutable',
|
|
288
|
+
});
|
|
289
|
+
createReadStream(targetFile).pipe(res);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const server = useHttpsLocalUi
|
|
293
|
+
? https.createServer(
|
|
294
|
+
{
|
|
295
|
+
cert: readFileSync(localHttps.certFile),
|
|
296
|
+
key: readFileSync(localHttps.keyFile),
|
|
297
|
+
},
|
|
298
|
+
listener
|
|
299
|
+
)
|
|
300
|
+
: http.createServer(listener);
|
|
301
|
+
|
|
302
|
+
server.listen(1420, localUiHost);
|
|
303
|
+
return server;
|
|
304
|
+
}
|
|
305
|
+
|
|
207
306
|
function hasCargoBridgeSource(runtimeRoot) {
|
|
208
307
|
return existsSync(path.join(runtimeRoot, 'src-tauri', 'Cargo.toml'));
|
|
209
308
|
}
|
|
@@ -215,15 +314,19 @@ function canUseCargo() {
|
|
|
215
314
|
return result.status === 0;
|
|
216
315
|
}
|
|
217
316
|
|
|
218
|
-
function
|
|
219
|
-
const
|
|
220
|
-
if (!existsSync(path.join(
|
|
317
|
+
function ensureSidecarInstallIfPresent(runtimeRoot) {
|
|
318
|
+
const sidecarRoot = path.join(runtimeRoot, 'agent-runtime-server');
|
|
319
|
+
if (!existsSync(path.join(sidecarRoot, 'package.json'))) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (existsSync(path.join(sidecarRoot, 'node_modules', '.package-lock.json'))) {
|
|
221
324
|
return;
|
|
222
325
|
}
|
|
223
326
|
|
|
224
327
|
const npmCmd = commandForPlatform('npm');
|
|
225
|
-
const result = spawnSync(npmCmd, ['
|
|
226
|
-
cwd:
|
|
328
|
+
const result = spawnSync(npmCmd, ['install'], {
|
|
329
|
+
cwd: sidecarRoot,
|
|
227
330
|
stdio: 'inherit',
|
|
228
331
|
});
|
|
229
332
|
if (result.status !== 0) {
|
|
@@ -231,22 +334,41 @@ function ensureSidecarInstallIfRepoPresent() {
|
|
|
231
334
|
}
|
|
232
335
|
}
|
|
233
336
|
|
|
337
|
+
function hasBundledSidecar(runtimeRoot) {
|
|
338
|
+
return existsSync(path.join(runtimeRoot, 'agent-runtime-server', 'server', 'index.js'));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function ensureSidecarInstallIfRepoPresent() {
|
|
342
|
+
const runtimeRoot = detectRuntimeRoot();
|
|
343
|
+
if (!existsSync(path.join(runtimeRoot, 'agent-runtime-server', 'package.json'))) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
ensureSidecarInstallIfPresent(runtimeRoot);
|
|
347
|
+
}
|
|
348
|
+
|
|
234
349
|
export async function startLocalCompanion(options = {}) {
|
|
235
350
|
const runtimeRoot = detectRuntimeRoot();
|
|
236
351
|
const requestedLocalUi = options.withLocalUi !== false;
|
|
237
|
-
const
|
|
352
|
+
const shouldStartRepoLocalUi = requestedLocalUi && hasLocalUiRepo();
|
|
353
|
+
const shouldStartBundledLocalUi = requestedLocalUi && !shouldStartRepoLocalUi && hasBundledLocalUi(runtimeRoot);
|
|
354
|
+
const shouldStartLocalUi = shouldStartRepoLocalUi || shouldStartBundledLocalUi;
|
|
238
355
|
const useCargoBridge = hasCargoBridgeSource(runtimeRoot) && canUseCargo();
|
|
239
356
|
const useHttpsLocalUi =
|
|
240
357
|
typeof options.localUiHttps === 'boolean' ? options.localUiHttps : shouldUseHttpsLocalUi();
|
|
241
358
|
const localUiUrl = useHttpsLocalUi ? LOCAL_UI_HTTPS_URL : LOCAL_UI_URL;
|
|
242
359
|
const localUiHost = useHttpsLocalUi ? 'localhost' : '127.0.0.1';
|
|
243
360
|
let localHttps = null;
|
|
361
|
+
let bundledLocalUiServer = null;
|
|
244
362
|
|
|
245
363
|
if (shouldStartLocalUi && useHttpsLocalUi) {
|
|
246
364
|
localHttps = await ensureTrustedLocalhostCert();
|
|
247
365
|
}
|
|
248
366
|
|
|
249
|
-
|
|
367
|
+
if (hasBundledSidecar(runtimeRoot)) {
|
|
368
|
+
ensureSidecarInstallIfPresent(runtimeRoot);
|
|
369
|
+
} else {
|
|
370
|
+
ensureSidecarInstallIfRepoPresent();
|
|
371
|
+
}
|
|
250
372
|
|
|
251
373
|
let vite = null;
|
|
252
374
|
if (shouldStartLocalUi) {
|
|
@@ -254,20 +376,29 @@ export async function startLocalCompanion(options = {}) {
|
|
|
254
376
|
console.log(`[notioncode] Reusing existing local UI on ${localUiUrl} .`);
|
|
255
377
|
} else {
|
|
256
378
|
console.log(`[notioncode] Starting local UI on ${localUiUrl} ...`);
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
379
|
+
if (shouldStartRepoLocalUi) {
|
|
380
|
+
vite = spawnLogged(commandForPlatform('node'), ['node_modules/vite/bin/vite.js', '--host', localUiHost], {
|
|
381
|
+
cwd: runtimeRoot,
|
|
382
|
+
env: {
|
|
383
|
+
VITE_SINGLE_USER_MODE: 'true',
|
|
384
|
+
NOCODE_LOCAL_UI_USE_HTTPS: useHttpsLocalUi ? '1' : '0',
|
|
385
|
+
NOCODE_LOCAL_UI_HOST: localUiHost,
|
|
386
|
+
...(localHttps
|
|
387
|
+
? {
|
|
388
|
+
NOCODE_LOCAL_UI_CERT_FILE: localHttps.certFile,
|
|
389
|
+
NOCODE_LOCAL_UI_KEY_FILE: localHttps.keyFile,
|
|
390
|
+
}
|
|
391
|
+
: {}),
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
} else if (shouldStartBundledLocalUi) {
|
|
395
|
+
bundledLocalUiServer = startBundledLocalUiServer({
|
|
396
|
+
runtimeRoot,
|
|
397
|
+
useHttpsLocalUi,
|
|
398
|
+
localHttps,
|
|
399
|
+
localUiHost,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
271
402
|
}
|
|
272
403
|
}
|
|
273
404
|
|
|
@@ -297,6 +428,7 @@ export async function startLocalCompanion(options = {}) {
|
|
|
297
428
|
const shutdown = (code = 0) => {
|
|
298
429
|
vite?.kill('SIGTERM');
|
|
299
430
|
bridge?.kill('SIGTERM');
|
|
431
|
+
bundledLocalUiServer?.close();
|
|
300
432
|
setTimeout(() => process.exit(code), 250);
|
|
301
433
|
};
|
|
302
434
|
|
|
@@ -321,7 +453,7 @@ export async function startLocalCompanion(options = {}) {
|
|
|
321
453
|
await verifyTrustedBridge(localUiUrl);
|
|
322
454
|
} catch (error) {
|
|
323
455
|
throw new Error(
|
|
324
|
-
`Safari-compatible local bridge could not be initialized.\n\nReason:\n ${error instanceof Error ? error.message : String(error)}\n\nFix:\n Install mkcert and trust the local certificate authority, then rerun:\n mkcert -install\n npx
|
|
456
|
+
`Safari-compatible local bridge could not be initialized.\n\nReason:\n ${error instanceof Error ? error.message : String(error)}\n\nFix:\n Install mkcert and trust the local certificate authority, then rerun:\n mkcert -install\n npx notioncode start`
|
|
325
457
|
);
|
|
326
458
|
}
|
|
327
459
|
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "notioncode",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Local companion runtime used by the `npx
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Local companion runtime used by the `npx notioncode start` setup flow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"default-browser-id": "^5.0.1"
|
|
9
9
|
},
|
|
10
10
|
"bin": {
|
|
11
|
-
"notioncode": "bin/
|
|
11
|
+
"notioncode": "bin/notioncode.js"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
|
+
"agent-runtime-server",
|
|
14
15
|
"bin",
|
|
16
|
+
"dist",
|
|
15
17
|
"lib",
|
|
16
|
-
"README.md"
|
|
18
|
+
"README.md",
|
|
19
|
+
"src"
|
|
17
20
|
],
|
|
18
21
|
"publishConfig": {
|
|
19
22
|
"access": "public"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type AgentProvider = 'claude' | 'cursor' | 'codex' | 'gemini';
|
|
2
|
+
|
|
3
|
+
export interface ModelOption {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ModelConfig {
|
|
9
|
+
OPTIONS: ModelOption[];
|
|
10
|
+
DEFAULT: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const CLAUDE_MODELS: ModelConfig;
|
|
14
|
+
export const CURSOR_MODELS: ModelConfig;
|
|
15
|
+
export const CODEX_MODELS: ModelConfig;
|
|
16
|
+
export const GEMINI_MODELS: ModelConfig;
|
|
17
|
+
|
|
18
|
+
export const MODEL_CONFIGS: Record<AgentProvider, ModelConfig>;
|
|
19
|
+
|
|
20
|
+
export function getModelOptions(provider: AgentProvider): ModelOption[];
|
|
21
|
+
export function getDefaultModel(provider: AgentProvider): string;
|
|
22
|
+
export function isSupportedModel(provider: AgentProvider, value: string | null | undefined): boolean;
|
|
23
|
+
export function migrateLegacyModel(provider: AgentProvider, value: string | null | undefined): string | null;
|
|
24
|
+
export function normalizeModel(provider: AgentProvider, value: string | null | undefined): string;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared model registry used by both the frontend workspace UI and the
|
|
3
|
+
* agent-runtime sidecar.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** @typedef {'claude' | 'cursor' | 'codex' | 'gemini'} AgentProvider */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {{ value: string, label: string }} ModelOption
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const CLAUDE_MODELS = {
|
|
13
|
+
OPTIONS: [
|
|
14
|
+
{ value: 'sonnet', label: 'Sonnet' },
|
|
15
|
+
{ value: 'opus', label: 'Opus' },
|
|
16
|
+
{ value: 'haiku', label: 'Haiku' },
|
|
17
|
+
{ value: 'opusplan', label: 'Opus Plan' },
|
|
18
|
+
{ value: 'sonnet[1m]', label: 'Sonnet [1M]' },
|
|
19
|
+
],
|
|
20
|
+
DEFAULT: 'sonnet',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const CURSOR_MODELS = {
|
|
24
|
+
OPTIONS: [
|
|
25
|
+
{ value: 'opus-4.6-thinking', label: 'Claude 4.6 Opus (Thinking)' },
|
|
26
|
+
{ value: 'gpt-5.3-codex', label: 'GPT-5.3' },
|
|
27
|
+
{ value: 'gpt-5.2-high', label: 'GPT-5.2 High' },
|
|
28
|
+
{ value: 'gemini-3-pro', label: 'Gemini 3 Pro' },
|
|
29
|
+
{ value: 'opus-4.5-thinking', label: 'Claude 4.5 Opus (Thinking)' },
|
|
30
|
+
{ value: 'gpt-5.2', label: 'GPT-5.2' },
|
|
31
|
+
{ value: 'gpt-5.1', label: 'GPT-5.1' },
|
|
32
|
+
{ value: 'gpt-5.1-high', label: 'GPT-5.1 High' },
|
|
33
|
+
{ value: 'composer-1', label: 'Composer 1' },
|
|
34
|
+
{ value: 'auto', label: 'Auto' },
|
|
35
|
+
{ value: 'sonnet-4.5', label: 'Claude 4.5 Sonnet' },
|
|
36
|
+
{ value: 'sonnet-4.5-thinking', label: 'Claude 4.5 Sonnet (Thinking)' },
|
|
37
|
+
{ value: 'opus-4.5', label: 'Claude 4.5 Opus' },
|
|
38
|
+
{ value: 'gpt-5.1-codex', label: 'GPT-5.1 Codex' },
|
|
39
|
+
{ value: 'gpt-5.1-codex-high', label: 'GPT-5.1 Codex High' },
|
|
40
|
+
{ value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max' },
|
|
41
|
+
{ value: 'gpt-5.1-codex-max-high', label: 'GPT-5.1 Codex Max High' },
|
|
42
|
+
{ value: 'opus-4.1', label: 'Claude 4.1 Opus' },
|
|
43
|
+
{ value: 'grok', label: 'Grok' },
|
|
44
|
+
],
|
|
45
|
+
DEFAULT: 'gpt-5-3-codex',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const CODEX_MODELS = {
|
|
49
|
+
OPTIONS: [
|
|
50
|
+
{ value: 'gpt-5.4', label: 'GPT-5.4' },
|
|
51
|
+
{ value: 'gpt-5.3-codex', label: 'GPT-5.3 Codex' },
|
|
52
|
+
{ value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex' },
|
|
53
|
+
{ value: 'gpt-5.2', label: 'GPT-5.2' },
|
|
54
|
+
{ value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max' },
|
|
55
|
+
{ value: 'o3', label: 'O3' },
|
|
56
|
+
{ value: 'o4-mini', label: 'O4-mini' },
|
|
57
|
+
],
|
|
58
|
+
DEFAULT: 'gpt-5.4',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const GEMINI_MODELS = {
|
|
62
|
+
OPTIONS: [
|
|
63
|
+
{ value: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro Preview' },
|
|
64
|
+
{ value: 'gemini-3-pro-preview', label: 'Gemini 3 Pro Preview' },
|
|
65
|
+
{ value: 'gemini-3-flash-preview', label: 'Gemini 3 Flash Preview' },
|
|
66
|
+
{ value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' },
|
|
67
|
+
{ value: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro' },
|
|
68
|
+
{ value: 'gemini-2.0-flash-lite', label: 'Gemini 2.0 Flash Lite' },
|
|
69
|
+
{ value: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash' },
|
|
70
|
+
{ value: 'gemini-2.0-pro-exp', label: 'Gemini 2.0 Pro Experimental' },
|
|
71
|
+
{ value: 'gemini-2.0-flash-thinking-exp', label: 'Gemini 2.0 Flash Thinking' },
|
|
72
|
+
],
|
|
73
|
+
DEFAULT: 'gemini-2.5-flash',
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const MODEL_CONFIGS = {
|
|
77
|
+
claude: CLAUDE_MODELS,
|
|
78
|
+
cursor: CURSOR_MODELS,
|
|
79
|
+
codex: CODEX_MODELS,
|
|
80
|
+
gemini: GEMINI_MODELS,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const LEGACY_MODEL_MIGRATIONS = {
|
|
84
|
+
claude: {
|
|
85
|
+
sonnet: 'sonnet',
|
|
86
|
+
opus: 'opus',
|
|
87
|
+
haiku: 'haiku',
|
|
88
|
+
'claude-3-5-sonnet-20241022': 'sonnet',
|
|
89
|
+
'claude-3-7-sonnet-20250219': 'sonnet',
|
|
90
|
+
'claude-3-opus-20240229': 'opus',
|
|
91
|
+
'claude-3-5-haiku-20241022': 'haiku',
|
|
92
|
+
},
|
|
93
|
+
cursor: {},
|
|
94
|
+
codex: {},
|
|
95
|
+
gemini: {},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {AgentProvider} provider
|
|
100
|
+
* @returns {ModelOption[]}
|
|
101
|
+
*/
|
|
102
|
+
export function getModelOptions(provider) {
|
|
103
|
+
return MODEL_CONFIGS[provider]?.OPTIONS ?? [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {AgentProvider} provider
|
|
108
|
+
* @returns {string}
|
|
109
|
+
*/
|
|
110
|
+
export function getDefaultModel(provider) {
|
|
111
|
+
return MODEL_CONFIGS[provider]?.DEFAULT ?? CODEX_MODELS.DEFAULT;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {AgentProvider} provider
|
|
116
|
+
* @param {string | null | undefined} value
|
|
117
|
+
* @returns {boolean}
|
|
118
|
+
*/
|
|
119
|
+
export function isSupportedModel(provider, value) {
|
|
120
|
+
if (!value) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return getModelOptions(provider).some((option) => option.value === value);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @param {AgentProvider} provider
|
|
129
|
+
* @param {string | null | undefined} value
|
|
130
|
+
* @returns {string | null}
|
|
131
|
+
*/
|
|
132
|
+
export function migrateLegacyModel(provider, value) {
|
|
133
|
+
if (!value) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const directMigration = LEGACY_MODEL_MIGRATIONS[provider]?.[value];
|
|
138
|
+
if (directMigration) {
|
|
139
|
+
return directMigration;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (provider === 'claude' && value.startsWith('claude-')) {
|
|
143
|
+
return getDefaultModel('claude');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return value;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Normalize a model selection to a canonical supported value for a provider.
|
|
151
|
+
*
|
|
152
|
+
* @param {AgentProvider} provider
|
|
153
|
+
* @param {string | null | undefined} value
|
|
154
|
+
* @returns {string}
|
|
155
|
+
*/
|
|
156
|
+
export function normalizeModel(provider, value) {
|
|
157
|
+
const migrated = migrateLegacyModel(provider, value);
|
|
158
|
+
if (migrated && isSupportedModel(provider, migrated)) {
|
|
159
|
+
return migrated;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return getDefaultModel(provider);
|
|
163
|
+
}
|