notioncode 0.1.0
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 +38 -0
- package/bin/nocode-local.js +51 -0
- package/lib/install.js +119 -0
- package/lib/platform.js +26 -0
- package/lib/start.js +194 -0
- package/package.json +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# @nocodenotioncode
|
|
2
|
+
|
|
3
|
+
Run the Notion Code local companion without opening the Tauri desktop shell.
|
|
4
|
+
|
|
5
|
+
## Intended usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @nocodenotioncode start
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @nocodenotioncode install
|
|
15
|
+
npx @nocodenotioncode doctor
|
|
16
|
+
npx @nocodenotioncode start --with-local-ui
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## What it starts
|
|
20
|
+
|
|
21
|
+
- localhost bridge on `127.0.0.1:3456`
|
|
22
|
+
- optional local UI on `127.0.0.1:1420`
|
|
23
|
+
- browser handoff to `https://www.notioncode.live`
|
|
24
|
+
|
|
25
|
+
## Bridge binaries
|
|
26
|
+
|
|
27
|
+
The package prefers a prebuilt bridge binary and falls back to a locally built binary when running from source.
|
|
28
|
+
|
|
29
|
+
Environment variables:
|
|
30
|
+
|
|
31
|
+
- `NOCODE_BRIDGE_BIN`
|
|
32
|
+
- `NOCODE_COMPANION_ASSET_BASE_URL`
|
|
33
|
+
- `NOCODE_CLOUD_URL`
|
|
34
|
+
- `NOCODE_NO_OPEN=1`
|
|
35
|
+
|
|
36
|
+
## Current limitation
|
|
37
|
+
|
|
38
|
+
This package is implemented inside the source tree and still expects local runtime assets from this repository. It is publication-ready in interface and metadata, but the final standalone distribution still needs packaged runtime assets for the agent sidecar.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
|
|
5
|
+
import { ensureBridgeBinary, buildLocalBridgeAsset } from '../lib/install.js';
|
|
6
|
+
import { startLocalCompanion } from '../lib/start.js';
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
const command = args.find((arg) => !arg.startsWith('-')) || 'start';
|
|
11
|
+
const withLocalUi = args.includes('--no-local-ui') ? false : true;
|
|
12
|
+
if (args.includes('--no-open')) {
|
|
13
|
+
process.env.NOCODE_NO_OPEN = '1';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (command === 'doctor') {
|
|
17
|
+
const checks = [
|
|
18
|
+
['node', process.version],
|
|
19
|
+
['platform', `${process.platform}/${process.arch}`],
|
|
20
|
+
];
|
|
21
|
+
for (const [label, detail] of checks) {
|
|
22
|
+
console.log(`[OK] ${label}: ${detail}`);
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (command === 'install') {
|
|
28
|
+
const bridgePath = await ensureBridgeBinary();
|
|
29
|
+
console.log(`[notioncode] Bridge ready at ${bridgePath}`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (command === 'package-bridge') {
|
|
34
|
+
const asset = buildLocalBridgeAsset();
|
|
35
|
+
console.log(`[notioncode] Packaged bridge asset at ${asset}`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (command === 'start') {
|
|
40
|
+
await startLocalCompanion({ withLocalUi });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.error(`Unknown command: ${command}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
main().catch((error) => {
|
|
49
|
+
console.error('[notioncode] Fatal error:', error);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
});
|
package/lib/install.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { chmodSync, copyFileSync, createWriteStream, existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { pipeline } from 'node:stream/promises';
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
import { commandForPlatform, defaultCacheDir, resolvePlatformTarget } from './platform.js';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_VERSION = '0.1.0';
|
|
11
|
+
const DEFAULT_ASSET_BASE =
|
|
12
|
+
process.env.NOCODE_COMPANION_ASSET_BASE_URL ||
|
|
13
|
+
'https://github.com/tadkt/nocode/releases/download';
|
|
14
|
+
|
|
15
|
+
function packageRootDir() {
|
|
16
|
+
return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function repoRootDir() {
|
|
20
|
+
if (process.env.NOCODE_RUNTIME_ROOT) {
|
|
21
|
+
return process.env.NOCODE_RUNTIME_ROOT;
|
|
22
|
+
}
|
|
23
|
+
return path.resolve(packageRootDir(), '..', '..');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function localBinaryName() {
|
|
27
|
+
return process.platform === 'win32' ? 'nocode-bridge.exe' : 'nocode-bridge';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function canUseCargo() {
|
|
31
|
+
const result = spawnSync(commandForPlatform('cargo'), ['--version'], {
|
|
32
|
+
stdio: 'ignore',
|
|
33
|
+
});
|
|
34
|
+
return result.status === 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function resolveInstallRoot() {
|
|
38
|
+
return process.env.NOCODE_COMPANION_HOME || defaultCacheDir();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function resolveInstalledBridgePath(version = DEFAULT_VERSION) {
|
|
42
|
+
return path.join(resolveInstallRoot(), 'bridge', version, localBinaryName());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function resolveLocalSourceBridgePath() {
|
|
46
|
+
const repoRoot = repoRootDir();
|
|
47
|
+
return path.join(repoRoot, 'src-tauri', 'target', 'release', process.platform === 'win32' ? 'bridge_dev.exe' : 'bridge_dev');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function ensureBridgeBinary(version = DEFAULT_VERSION) {
|
|
51
|
+
const envPath = process.env.NOCODE_BRIDGE_BIN;
|
|
52
|
+
if (envPath && existsSync(envPath)) {
|
|
53
|
+
return envPath;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const installed = resolveInstalledBridgePath(version);
|
|
57
|
+
if (existsSync(installed)) {
|
|
58
|
+
return installed;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const localBuilt = resolveLocalSourceBridgePath();
|
|
62
|
+
if (existsSync(localBuilt)) {
|
|
63
|
+
return localBuilt;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const repoRoot = repoRootDir();
|
|
67
|
+
if (existsSync(path.join(repoRoot, 'src-tauri', 'Cargo.toml')) && canUseCargo()) {
|
|
68
|
+
return buildLocalBridgeAsset(version);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await downloadBridgeBinary(version, installed);
|
|
72
|
+
return installed;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function downloadBridgeBinary(version = DEFAULT_VERSION, destination = resolveInstalledBridgePath(version)) {
|
|
76
|
+
mkdirSync(path.dirname(destination), { recursive: true });
|
|
77
|
+
const target = resolvePlatformTarget();
|
|
78
|
+
const assetName = `nocode-bridge-${target}${process.platform === 'win32' ? '.exe' : ''}`;
|
|
79
|
+
const url = `${DEFAULT_ASSET_BASE}/notioncode-v${version}/${assetName}`;
|
|
80
|
+
|
|
81
|
+
const response = await fetch(url);
|
|
82
|
+
if (!response.ok || !response.body) {
|
|
83
|
+
throw new Error(`Failed to download bridge binary from ${url} (${response.status})`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
await pipeline(response.body, createWriteStream(destination));
|
|
87
|
+
if (process.platform !== 'win32') {
|
|
88
|
+
chmodSync(destination, 0o755);
|
|
89
|
+
}
|
|
90
|
+
return destination;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function buildLocalBridgeAsset(version = DEFAULT_VERSION) {
|
|
94
|
+
const repoRoot = repoRootDir();
|
|
95
|
+
const cargo = commandForPlatform('cargo');
|
|
96
|
+
const build = spawnSync(
|
|
97
|
+
cargo,
|
|
98
|
+
['build', '--manifest-path', 'src-tauri/Cargo.toml', '--bin', 'bridge_dev', '--release'],
|
|
99
|
+
{ cwd: repoRoot, stdio: 'inherit' }
|
|
100
|
+
);
|
|
101
|
+
if (build.status !== 0) {
|
|
102
|
+
throw new Error(`cargo build failed with code ${build.status ?? 1}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const source = resolveLocalSourceBridgePath();
|
|
106
|
+
if (!existsSync(source)) {
|
|
107
|
+
throw new Error(`Expected built bridge binary at ${source}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const artifactsDir = path.join(repoRoot, 'artifacts', 'local-companion', version);
|
|
111
|
+
mkdirSync(artifactsDir, { recursive: true });
|
|
112
|
+
const target = resolvePlatformTarget();
|
|
113
|
+
const dest = path.join(artifactsDir, `nocode-bridge-${target}${process.platform === 'win32' ? '.exe' : ''}`);
|
|
114
|
+
copyFileSync(source, dest);
|
|
115
|
+
if (process.platform !== 'win32') {
|
|
116
|
+
chmodSync(dest, 0o755);
|
|
117
|
+
}
|
|
118
|
+
return dest;
|
|
119
|
+
}
|
package/lib/platform.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
|
|
3
|
+
export function resolvePlatformTarget() {
|
|
4
|
+
const platform = process.platform;
|
|
5
|
+
const arch = process.arch;
|
|
6
|
+
|
|
7
|
+
if (platform === 'darwin' && arch === 'arm64') return 'darwin-arm64';
|
|
8
|
+
if (platform === 'darwin' && arch === 'x64') return 'darwin-x64';
|
|
9
|
+
if (platform === 'linux' && arch === 'x64') return 'linux-x64';
|
|
10
|
+
if (platform === 'win32' && arch === 'x64') return 'windows-x64';
|
|
11
|
+
|
|
12
|
+
throw new Error(`Unsupported platform for Notion Code local companion: ${platform}/${arch}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function commandForPlatform(base) {
|
|
16
|
+
return process.platform === 'win32' ? `${base}.cmd` : base;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function defaultCacheDir() {
|
|
20
|
+
const home = os.homedir();
|
|
21
|
+
if (process.platform === 'darwin') return `${home}/Library/Application Support/notioncode`;
|
|
22
|
+
if (process.platform === 'win32') {
|
|
23
|
+
return `${process.env.APPDATA || `${home}\\AppData\\Roaming`}\\notioncode`;
|
|
24
|
+
}
|
|
25
|
+
return `${process.env.XDG_CONFIG_HOME || `${home}/.config`}/notioncode`;
|
|
26
|
+
}
|
package/lib/start.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
6
|
+
|
|
7
|
+
import { commandForPlatform } from './platform.js';
|
|
8
|
+
import { ensureBridgeBinary } from './install.js';
|
|
9
|
+
|
|
10
|
+
const BRIDGE_HEALTH_URL = 'http://127.0.0.1:3456/healthz';
|
|
11
|
+
const LOCAL_UI_URL = 'http://127.0.0.1:1420/';
|
|
12
|
+
const CLOUD_URL = process.env.NOCODE_CLOUD_URL || 'https://www.notioncode.live';
|
|
13
|
+
|
|
14
|
+
function packageRootDir() {
|
|
15
|
+
return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function detectRuntimeRoot() {
|
|
19
|
+
if (process.env.NOCODE_RUNTIME_ROOT) {
|
|
20
|
+
return process.env.NOCODE_RUNTIME_ROOT;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const candidates = [
|
|
24
|
+
path.resolve(packageRootDir(), '..', '..'),
|
|
25
|
+
process.cwd(),
|
|
26
|
+
path.resolve(packageRootDir(), '..'),
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
for (const candidate of candidates) {
|
|
30
|
+
if (existsSync(path.join(candidate, 'agent-runtime-server', 'package.json'))) {
|
|
31
|
+
return candidate;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return path.resolve(packageRootDir(), '..', '..');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function spawnLogged(cmd, args, options = {}) {
|
|
39
|
+
return spawn(cmd, args, {
|
|
40
|
+
cwd: options.cwd,
|
|
41
|
+
env: { ...process.env, ...(options.env || {}) },
|
|
42
|
+
stdio: 'inherit',
|
|
43
|
+
shell: false,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function isReady(url) {
|
|
48
|
+
try {
|
|
49
|
+
const response = await fetch(url, { method: 'GET' });
|
|
50
|
+
return response.ok;
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function waitFor(url, timeoutMs, label) {
|
|
57
|
+
const deadline = Date.now() + timeoutMs;
|
|
58
|
+
let lastError = null;
|
|
59
|
+
while (Date.now() < deadline) {
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(url, { method: 'GET' });
|
|
62
|
+
if (response.ok) return;
|
|
63
|
+
lastError = new Error(`${label} returned ${response.status}`);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
lastError = error;
|
|
66
|
+
}
|
|
67
|
+
await sleep(300);
|
|
68
|
+
}
|
|
69
|
+
throw lastError || new Error(`${label} did not become ready.`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function openBrowser(url) {
|
|
73
|
+
if (process.env.NOCODE_NO_OPEN === '1') return;
|
|
74
|
+
if (process.platform === 'darwin') {
|
|
75
|
+
spawn(commandForPlatform('open'), [url], { stdio: 'ignore', detached: true }).unref();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (process.platform === 'win32') {
|
|
79
|
+
spawn('cmd', ['/c', 'start', '', url], { stdio: 'ignore', detached: true }).unref();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
spawn(commandForPlatform('xdg-open'), [url], { stdio: 'ignore', detached: true }).unref();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function hasLocalUiRepo() {
|
|
86
|
+
const runtimeRoot = detectRuntimeRoot();
|
|
87
|
+
return existsSync(path.join(runtimeRoot, 'package.json')) && existsSync(path.join(runtimeRoot, 'node_modules', 'vite', 'bin', 'vite.js'));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function hasCargoBridgeSource(runtimeRoot) {
|
|
91
|
+
return existsSync(path.join(runtimeRoot, 'src-tauri', 'Cargo.toml'));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function canUseCargo() {
|
|
95
|
+
const result = spawnSync(commandForPlatform('cargo'), ['--version'], {
|
|
96
|
+
stdio: 'ignore',
|
|
97
|
+
});
|
|
98
|
+
return result.status === 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function ensureSidecarInstallIfRepoPresent() {
|
|
102
|
+
const runtimeRoot = detectRuntimeRoot();
|
|
103
|
+
if (!existsSync(path.join(runtimeRoot, 'agent-runtime-server', 'package.json'))) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const npmCmd = commandForPlatform('npm');
|
|
108
|
+
const result = spawnSync(npmCmd, ['--prefix', 'agent-runtime-server', 'install'], {
|
|
109
|
+
cwd: runtimeRoot,
|
|
110
|
+
stdio: 'inherit',
|
|
111
|
+
});
|
|
112
|
+
if (result.status !== 0) {
|
|
113
|
+
throw new Error(`Failed to install agent-runtime-server dependencies (${result.status ?? 1})`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function startLocalCompanion(options = {}) {
|
|
118
|
+
const runtimeRoot = detectRuntimeRoot();
|
|
119
|
+
const requestedLocalUi = options.withLocalUi !== false;
|
|
120
|
+
const shouldStartLocalUi = requestedLocalUi && hasLocalUiRepo();
|
|
121
|
+
const useCargoBridge = hasCargoBridgeSource(runtimeRoot) && canUseCargo();
|
|
122
|
+
const bridgeExecutable = useCargoBridge ? null : await ensureBridgeBinary(options.version);
|
|
123
|
+
|
|
124
|
+
ensureSidecarInstallIfRepoPresent();
|
|
125
|
+
|
|
126
|
+
let vite = null;
|
|
127
|
+
if (shouldStartLocalUi) {
|
|
128
|
+
if (await isReady(LOCAL_UI_URL)) {
|
|
129
|
+
console.log('[notioncode] Reusing existing local UI on http://127.0.0.1:1420 .');
|
|
130
|
+
} else {
|
|
131
|
+
console.log('[notioncode] Starting local UI on http://127.0.0.1:1420 ...');
|
|
132
|
+
vite = spawnLogged(commandForPlatform('node'), ['node_modules/vite/bin/vite.js', '--host', '127.0.0.1'], {
|
|
133
|
+
cwd: runtimeRoot,
|
|
134
|
+
env: {
|
|
135
|
+
VITE_SINGLE_USER_MODE: 'true',
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let bridge = null;
|
|
142
|
+
if (await isReady(BRIDGE_HEALTH_URL)) {
|
|
143
|
+
console.log('[notioncode] Reusing existing bridge on http://127.0.0.1:3456 .');
|
|
144
|
+
} else {
|
|
145
|
+
console.log('[notioncode] Starting local bridge on http://127.0.0.1:3456 ...');
|
|
146
|
+
if (useCargoBridge) {
|
|
147
|
+
bridge = spawnLogged(
|
|
148
|
+
commandForPlatform('cargo'),
|
|
149
|
+
['run', '--manifest-path', 'src-tauri/Cargo.toml', '--bin', 'bridge_dev'],
|
|
150
|
+
{ cwd: runtimeRoot }
|
|
151
|
+
);
|
|
152
|
+
} else {
|
|
153
|
+
bridge = spawnLogged(bridgeExecutable, [], {
|
|
154
|
+
cwd: runtimeRoot,
|
|
155
|
+
env: {
|
|
156
|
+
NOTION_BRIDGE_URL: 'http://127.0.0.1:3456',
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const shutdown = (code = 0) => {
|
|
163
|
+
vite?.kill('SIGTERM');
|
|
164
|
+
bridge?.kill('SIGTERM');
|
|
165
|
+
setTimeout(() => process.exit(code), 250);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
process.on('SIGINT', () => shutdown(0));
|
|
169
|
+
process.on('SIGTERM', () => shutdown(0));
|
|
170
|
+
|
|
171
|
+
vite?.on('exit', (code) => {
|
|
172
|
+
console.error(`[notioncode] Local UI exited with code ${code ?? 1}.`);
|
|
173
|
+
shutdown(code ?? 1);
|
|
174
|
+
});
|
|
175
|
+
bridge?.on('exit', (code) => {
|
|
176
|
+
console.error(`[notioncode] Bridge exited with code ${code ?? 1}.`);
|
|
177
|
+
shutdown(code ?? 1);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const bridgeTimeoutMs = useCargoBridge ? 180_000 : 15_000;
|
|
181
|
+
await waitFor(BRIDGE_HEALTH_URL, bridgeTimeoutMs, 'Bridge');
|
|
182
|
+
if (shouldStartLocalUi) {
|
|
183
|
+
await waitFor(LOCAL_UI_URL, 15_000, 'Local UI');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
console.log('[notioncode] Ready.');
|
|
187
|
+
console.log(`[notioncode] Cloud UI: ${CLOUD_URL}`);
|
|
188
|
+
if (shouldStartLocalUi) {
|
|
189
|
+
console.log(`[notioncode] Local UI: ${LOCAL_UI_URL}`);
|
|
190
|
+
}
|
|
191
|
+
const entryUrl = shouldStartLocalUi ? LOCAL_UI_URL : CLOUD_URL;
|
|
192
|
+
console.log(`[notioncode] Opening: ${entryUrl}`);
|
|
193
|
+
openBrowser(entryUrl);
|
|
194
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "notioncode",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Run the Notion Code local companion bridge and open the cloud UI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"bin": {
|
|
8
|
+
"notioncode": "bin/nocode-local.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"lib",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20.19.0"
|
|
20
|
+
}
|
|
21
|
+
}
|