@nimbus-sh/cli 0.1.4 → 0.1.6
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/LICENSE +21 -0
- package/NOTICE.md +4 -0
- package/README.md +8 -1
- package/dist/commands/runtime-sync.d.ts +3 -6
- package/dist/commands/runtime-sync.d.ts.map +1 -1
- package/dist/commands/runtime-sync.js +8 -18
- package/dist/commands/scaffold.d.ts.map +1 -1
- package/dist/commands/scaffold.js +52 -15
- package/dist/commands/session.js +23 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +16 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ashish Kumar Singh and Nimbus contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/NOTICE.md
ADDED
package/README.md
CHANGED
|
@@ -24,6 +24,9 @@ bun packages/cli/src/scaffold-bin.ts my-app
|
|
|
24
24
|
### `nimbus init [directory]`
|
|
25
25
|
|
|
26
26
|
Scaffolds a Nimbus-powered Workers project. `.` uses the current directory.
|
|
27
|
+
The generated app embeds the interactive Nimbus UI and enables the
|
|
28
|
+
authenticated remote sandbox API. Add application-specific auth routes in
|
|
29
|
+
`src/index.ts` when you are ready to mint user tokens from your backend.
|
|
27
30
|
|
|
28
31
|
```bash
|
|
29
32
|
nimbus init my-nimbus
|
|
@@ -36,7 +39,8 @@ npx wrangler deploy
|
|
|
36
39
|
|
|
37
40
|
### `create-nimbus-app <name>`
|
|
38
41
|
|
|
39
|
-
Scaffolds a new Nimbus-powered Workers project
|
|
42
|
+
Scaffolds a new Nimbus-powered Workers project with the same template as
|
|
43
|
+
`nimbus init`.
|
|
40
44
|
|
|
41
45
|
```bash
|
|
42
46
|
create-nimbus-app my-nimbus
|
|
@@ -93,6 +97,9 @@ Flags:
|
|
|
93
97
|
| `--scopes <a,b>` | Comma-separated capability scopes. |
|
|
94
98
|
| `--sid <id>` | Pin token to a specific session ID. |
|
|
95
99
|
|
|
100
|
+
Use `--scopes sandbox:use --sid <sandbox-id>` for remote SDK calls through
|
|
101
|
+
`Nimbus.connect(...)`.
|
|
102
|
+
|
|
96
103
|
### `nimbus token verify <token>`
|
|
97
104
|
|
|
98
105
|
```bash
|
|
@@ -10,14 +10,11 @@
|
|
|
10
10
|
* (`nimbus runtime sync python clang`) or comma-separated via
|
|
11
11
|
* `--runtimes python,clang`.
|
|
12
12
|
*
|
|
13
|
-
* Implementation: shells out to
|
|
14
|
-
*
|
|
15
|
-
* The actual fetch+verify+upload work lives in that script; this CLI
|
|
16
|
-
* is a thin proxy.
|
|
13
|
+
* Implementation: shells out to the runtime bundling helper shipped in
|
|
14
|
+
* `@nimbus-sh/worker`. The CLI is the supported operator entrypoint.
|
|
17
15
|
*/
|
|
18
16
|
/**
|
|
19
|
-
* Sync runtime blobs to an R2 bucket via the bundled
|
|
20
|
-
* `bundle-runtime.mjs` script.
|
|
17
|
+
* Sync runtime blobs to an R2 bucket via the bundled worker helper.
|
|
21
18
|
*
|
|
22
19
|
* @example
|
|
23
20
|
* ```bash
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-sync.d.ts","sourceRoot":"","sources":["../../src/commands/runtime-sync.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"runtime-sync.d.ts","sourceRoot":"","sources":["../../src/commands/runtime-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoClE;AAED,uEAAuE;AACvE,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAUnE"}
|
|
@@ -10,15 +10,12 @@
|
|
|
10
10
|
* (`nimbus runtime sync python clang`) or comma-separated via
|
|
11
11
|
* `--runtimes python,clang`.
|
|
12
12
|
*
|
|
13
|
-
* Implementation: shells out to
|
|
14
|
-
*
|
|
15
|
-
* The actual fetch+verify+upload work lives in that script; this CLI
|
|
16
|
-
* is a thin proxy.
|
|
13
|
+
* Implementation: shells out to the runtime bundling helper shipped in
|
|
14
|
+
* `@nimbus-sh/worker`. The CLI is the supported operator entrypoint.
|
|
17
15
|
*/
|
|
18
16
|
import { spawn } from 'node:child_process';
|
|
19
17
|
import { existsSync } from 'node:fs';
|
|
20
18
|
import { createRequire } from 'node:module';
|
|
21
|
-
import { dirname, join } from 'node:path';
|
|
22
19
|
import { fileURLToPath } from 'node:url';
|
|
23
20
|
const nodeRequire = createRequire(import.meta.url);
|
|
24
21
|
const DEFAULT_RUNTIME_VERSIONS = {
|
|
@@ -27,8 +24,7 @@ const DEFAULT_RUNTIME_VERSIONS = {
|
|
|
27
24
|
ruby: '3.3.4',
|
|
28
25
|
};
|
|
29
26
|
/**
|
|
30
|
-
* Sync runtime blobs to an R2 bucket via the bundled
|
|
31
|
-
* `bundle-runtime.mjs` script.
|
|
27
|
+
* Sync runtime blobs to an R2 bucket via the bundled worker helper.
|
|
32
28
|
*
|
|
33
29
|
* @example
|
|
34
30
|
* ```bash
|
|
@@ -46,12 +42,10 @@ export async function syncRuntimes(args) {
|
|
|
46
42
|
process.stderr.write('nimbus runtime sync: CLOUDFLARE_ACCOUNT_ID env var required\n');
|
|
47
43
|
return 78;
|
|
48
44
|
}
|
|
49
|
-
// Locate the
|
|
50
|
-
// installed via npm, resolve via require; in workspace dogfood, use
|
|
51
|
-
// a relative path.
|
|
45
|
+
// Locate the runtime sync helper in `@nimbus-sh/worker`.
|
|
52
46
|
const scriptPath = resolveBundleRuntimeScript();
|
|
53
47
|
if (!scriptPath) {
|
|
54
|
-
process.stderr.write('nimbus runtime sync: cannot locate
|
|
48
|
+
process.stderr.write('nimbus runtime sync: cannot locate Nimbus runtime sync helper\n');
|
|
55
49
|
return 70;
|
|
56
50
|
}
|
|
57
51
|
process.stderr.write(`nimbus: syncing runtimes [${runtimes.join(', ')}] → r2://${bucket}\n`);
|
|
@@ -85,20 +79,16 @@ export async function listRuntimes(_args) {
|
|
|
85
79
|
}
|
|
86
80
|
// ── helpers ──────────────────────────────────────────────────────────
|
|
87
81
|
function resolveBundleRuntimeScript() {
|
|
88
|
-
// 1. Try resolving via the @nimbus-sh/worker package (npm-installed).
|
|
89
82
|
try {
|
|
90
|
-
const
|
|
91
|
-
const script = join(dirname(packageJson), 'scripts', 'bundle-runtime.mjs');
|
|
83
|
+
const script = nodeRequire.resolve('@nimbus-sh/worker/runtime-sync-helper');
|
|
92
84
|
if (existsSync(script))
|
|
93
85
|
return script;
|
|
94
86
|
}
|
|
95
87
|
catch {
|
|
96
|
-
//
|
|
88
|
+
// Source-workspace mode can run before workspace packages are linked.
|
|
97
89
|
}
|
|
98
|
-
// 2. Workspace dogfood — relative path inside the monorepo.
|
|
99
90
|
try {
|
|
100
|
-
const
|
|
101
|
-
const script = fileURLToPath(wsUrl);
|
|
91
|
+
const script = fileURLToPath(new URL('../../../worker/scripts/bundle-runtime.mjs', import.meta.url));
|
|
102
92
|
return existsSync(script) ? script : null;
|
|
103
93
|
}
|
|
104
94
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/commands/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/commands/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAuF9D"}
|
|
@@ -96,8 +96,9 @@ Next steps:
|
|
|
96
96
|
If setup reports Cloudflare R2 error 10042, enable R2 in the Cloudflare
|
|
97
97
|
Dashboard once for this account, then rerun the setup command.
|
|
98
98
|
|
|
99
|
-
Deploy will provision the Durable Object on first
|
|
100
|
-
|
|
99
|
+
Deploy will provision the Durable Object on first use. Mint a token with
|
|
100
|
+
\`nimbus token mint\` before attaching an interactive session or remote SDK
|
|
101
|
+
sandbox.
|
|
101
102
|
|
|
102
103
|
Docs: https://github.com/AshishKumar4/Nimbus#readme
|
|
103
104
|
`);
|
|
@@ -124,8 +125,9 @@ function renderPackageJson(name) {
|
|
|
124
125
|
typecheck: 'tsc --noEmit',
|
|
125
126
|
},
|
|
126
127
|
dependencies: {
|
|
127
|
-
'@nimbus-sh/
|
|
128
|
-
'@nimbus-sh/
|
|
128
|
+
'@nimbus-sh/config': '^0.1.2',
|
|
129
|
+
'@nimbus-sh/worker': '^0.1.3',
|
|
130
|
+
'@nimbus-sh/sdk': '^0.1.3',
|
|
129
131
|
},
|
|
130
132
|
devDependencies: {
|
|
131
133
|
'@cloudflare/workers-types': '^4.20250327.0',
|
|
@@ -146,7 +148,7 @@ function renderWranglerJsonc(name) {
|
|
|
146
148
|
"assets": {
|
|
147
149
|
"directory": "node_modules/@nimbus-sh/worker/public",
|
|
148
150
|
"binding": "ASSETS",
|
|
149
|
-
"run_worker_first": ["/s/*", "/new"]
|
|
151
|
+
"run_worker_first": ["/api/*", "/s/*", "/new"]
|
|
150
152
|
},
|
|
151
153
|
|
|
152
154
|
// The Node-compat shims isomorphic-git + the npm installer need. Do
|
|
@@ -198,6 +200,7 @@ function renderIndexTs() {
|
|
|
198
200
|
CirrusHmrRPC,
|
|
199
201
|
createNimbusHandler,
|
|
200
202
|
} from '@nimbus-sh/sdk/worker';
|
|
203
|
+
import { defineNimbusConfig } from '@nimbus-sh/config';
|
|
201
204
|
|
|
202
205
|
// Re-export the DO class + every RPC class so wrangler's
|
|
203
206
|
// \`durable_objects.bindings[].class_name\` lookup + \`enable_ctx_exports\`
|
|
@@ -214,7 +217,26 @@ export {
|
|
|
214
217
|
CirrusHmrRPC,
|
|
215
218
|
};
|
|
216
219
|
|
|
217
|
-
|
|
220
|
+
const nimbusConfig = defineNimbusConfig({
|
|
221
|
+
sandboxes: {
|
|
222
|
+
default: {
|
|
223
|
+
root: '/home/user',
|
|
224
|
+
runtimes: {
|
|
225
|
+
preinstall: ['python'],
|
|
226
|
+
onDemand: true,
|
|
227
|
+
allow: ['node', 'bun', 'npm', 'git', 'python', 'ruby', 'clang', 'shell'],
|
|
228
|
+
},
|
|
229
|
+
tools: { namespace: 'sandbox', kind: 'sandbox' },
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
export default createNimbusHandler({
|
|
235
|
+
sdk: {
|
|
236
|
+
remote: true,
|
|
237
|
+
config: nimbusConfig,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
218
240
|
`;
|
|
219
241
|
}
|
|
220
242
|
function renderTsconfig() {
|
|
@@ -246,19 +268,27 @@ npx wrangler secret put JWT_SECRET # paste a 32+ char hex secret
|
|
|
246
268
|
npx wrangler deploy
|
|
247
269
|
\`\`\`
|
|
248
270
|
|
|
249
|
-
Then visit the URL wrangler prints.
|
|
271
|
+
Then visit the URL wrangler prints.
|
|
250
272
|
|
|
251
273
|
If setup reports Cloudflare R2 error 10042, enable R2 in the Cloudflare
|
|
252
274
|
Dashboard once for this account, then rerun the setup command.
|
|
253
275
|
|
|
254
|
-
##
|
|
276
|
+
## Tokens
|
|
255
277
|
|
|
256
|
-
By default tokens are enforced
|
|
278
|
+
By default tokens are enforced because \`JWT_SECRET\` is set. Mint a token for
|
|
279
|
+
an interactive session or remote SDK sandbox:
|
|
257
280
|
|
|
258
281
|
\`\`\`bash
|
|
259
|
-
JWT_SECRET=<your-secret> npx @nimbus-sh/cli token mint
|
|
282
|
+
JWT_SECRET=<your-secret> npx @nimbus-sh/cli token mint \\
|
|
283
|
+
--tenant acme \\
|
|
284
|
+
--sub alice \\
|
|
285
|
+
--scopes sandbox:use \\
|
|
286
|
+
--sid job-123
|
|
260
287
|
\`\`\`
|
|
261
288
|
|
|
289
|
+
Use the token with \`@nimbus-sh/react\`, \`sessionAttachUrl(...)\`, or
|
|
290
|
+
\`Nimbus.connect({ endpoint, token })\`.
|
|
291
|
+
|
|
262
292
|
Embed in a React app:
|
|
263
293
|
|
|
264
294
|
\`\`\`tsx
|
|
@@ -274,15 +304,17 @@ import { NimbusTerminal } from '@nimbus-sh/react';
|
|
|
274
304
|
|
|
275
305
|
## Customize
|
|
276
306
|
|
|
277
|
-
|
|
307
|
+
In \`src/index.ts\`, keep the generated exports and \`nimbusConfig\`, then
|
|
308
|
+
replace the \`export default\` block:
|
|
278
309
|
|
|
279
310
|
\`\`\`ts
|
|
280
|
-
import { NimbusSession, createNimbusHandler } from '@nimbus-sh/sdk/worker';
|
|
281
311
|
import { issueNimbusToken } from '@nimbus-sh/sdk/token';
|
|
282
312
|
|
|
283
|
-
export { NimbusSession };
|
|
284
|
-
|
|
285
313
|
export default createNimbusHandler({
|
|
314
|
+
sdk: {
|
|
315
|
+
remote: true,
|
|
316
|
+
config: nimbusConfig,
|
|
317
|
+
},
|
|
286
318
|
hooks: {
|
|
287
319
|
onSessionStart: ({ sessionId, tenantSegment }) => {
|
|
288
320
|
console.log(\`session \${sessionId} for \${tenantSegment}\`);
|
|
@@ -290,8 +322,13 @@ export default createNimbusHandler({
|
|
|
290
322
|
},
|
|
291
323
|
routes: async (req, env) => {
|
|
292
324
|
if (new URL(req.url).pathname === '/api/auth/mint') {
|
|
325
|
+
// Authenticate your application user before minting.
|
|
293
326
|
const { tenant, sub } = await req.json();
|
|
294
|
-
const token = await issueNimbusToken(env, {
|
|
327
|
+
const token = await issueNimbusToken(env, {
|
|
328
|
+
tn: tenant,
|
|
329
|
+
sub,
|
|
330
|
+
scopes: ['sandbox:use'],
|
|
331
|
+
});
|
|
295
332
|
return Response.json({ token });
|
|
296
333
|
}
|
|
297
334
|
return null;
|
package/dist/commands/session.js
CHANGED
|
@@ -8,7 +8,8 @@ export async function newSession(args) {
|
|
|
8
8
|
?? process.env.NIMBUS_ENDPOINT
|
|
9
9
|
?? 'http://127.0.0.1:8787';
|
|
10
10
|
try {
|
|
11
|
-
const
|
|
11
|
+
const baseUrl = new URL(endpoint);
|
|
12
|
+
const r = await fetch(new URL('/new', baseUrl), {
|
|
12
13
|
method: 'POST',
|
|
13
14
|
redirect: 'manual',
|
|
14
15
|
});
|
|
@@ -17,13 +18,12 @@ export async function newSession(args) {
|
|
|
17
18
|
process.stderr.write(`nimbus session new: POST /new returned no Location (status ${r.status})\n`);
|
|
18
19
|
return 70;
|
|
19
20
|
}
|
|
20
|
-
const
|
|
21
|
-
if (!
|
|
21
|
+
const sessionId = sessionIdFromLocation(loc, baseUrl);
|
|
22
|
+
if (!sessionId) {
|
|
22
23
|
process.stderr.write(`nimbus session new: unexpected Location: ${loc}\n`);
|
|
23
24
|
return 70;
|
|
24
25
|
}
|
|
25
|
-
const
|
|
26
|
-
const url = `${endpoint.replace(/\/+$/, '')}/s/${sessionId}/`;
|
|
26
|
+
const url = new URL(`/s/${encodeURIComponent(sessionId)}/`, baseUrl).toString();
|
|
27
27
|
process.stdout.write(JSON.stringify({ sessionId, url }) + '\n');
|
|
28
28
|
return 0;
|
|
29
29
|
}
|
|
@@ -43,3 +43,21 @@ function parseFlags(args) {
|
|
|
43
43
|
}
|
|
44
44
|
return out;
|
|
45
45
|
}
|
|
46
|
+
function sessionIdFromLocation(location, baseUrl) {
|
|
47
|
+
let url;
|
|
48
|
+
try {
|
|
49
|
+
url = new URL(location, baseUrl);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const segments = url.pathname.split('/').filter(Boolean);
|
|
55
|
+
if (segments.length < 2 || segments[0] !== 's')
|
|
56
|
+
return null;
|
|
57
|
+
try {
|
|
58
|
+
return decodeURIComponent(segments[1]);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nimbus-sh/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Nimbus CLI — `create-nimbus-app` scaffolder + `token mint` + `runtime sync`.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cloudflare",
|
|
7
|
+
"workers",
|
|
8
|
+
"sandbox",
|
|
9
|
+
"cli",
|
|
10
|
+
"developer-environment"
|
|
11
|
+
],
|
|
5
12
|
"homepage": "https://github.com/AshishKumar4/Nimbus",
|
|
6
13
|
"repository": {
|
|
7
14
|
"type": "git",
|
|
@@ -12,9 +19,9 @@
|
|
|
12
19
|
"license": "MIT",
|
|
13
20
|
"type": "module",
|
|
14
21
|
"bin": {
|
|
15
|
-
"cli": "
|
|
16
|
-
"nimbus": "
|
|
17
|
-
"create-nimbus-app": "
|
|
22
|
+
"cli": "dist/bin.js",
|
|
23
|
+
"nimbus": "dist/bin.js",
|
|
24
|
+
"create-nimbus-app": "dist/scaffold-bin.js"
|
|
18
25
|
},
|
|
19
26
|
"main": "./dist/index.js",
|
|
20
27
|
"types": "./dist/index.d.ts",
|
|
@@ -28,7 +35,9 @@
|
|
|
28
35
|
},
|
|
29
36
|
"files": [
|
|
30
37
|
"dist",
|
|
31
|
-
"README.md"
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE",
|
|
40
|
+
"NOTICE.md"
|
|
32
41
|
],
|
|
33
42
|
"scripts": {
|
|
34
43
|
"build": "tsc -p tsconfig.json --noCheck --noEmit false --declaration true --declarationMap true --outDir dist --rootDir src && chmod +x dist/bin.js dist/scaffold-bin.js",
|
|
@@ -36,8 +45,8 @@
|
|
|
36
45
|
"typecheck": "tsc --noEmit"
|
|
37
46
|
},
|
|
38
47
|
"dependencies": {
|
|
39
|
-
"@nimbus-sh/sdk": "^0.1.
|
|
40
|
-
"@nimbus-sh/worker": "^0.1.
|
|
48
|
+
"@nimbus-sh/sdk": "^0.1.3",
|
|
49
|
+
"@nimbus-sh/worker": "^0.1.3"
|
|
41
50
|
},
|
|
42
51
|
"engines": {
|
|
43
52
|
"node": ">=20"
|