@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 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
@@ -0,0 +1,4 @@
1
+ # Notices
2
+
3
+ This package is part of Nimbus. See the project notices at
4
+ https://github.com/AshishKumar4/Nimbus/blob/main/NOTICE.md.
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 wrangler r2 object put for each blob
14
- * listed in `@nimbus-sh/worker`'s bundled `scripts/bundle-runtime.mjs`.
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;;;;;;;;;;;;;;;;GAgBG;AAeH;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAsClE;AAED,uEAAuE;AACvE,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAUnE"}
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 wrangler r2 object put for each blob
14
- * listed in `@nimbus-sh/worker`'s bundled `scripts/bundle-runtime.mjs`.
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 bundle-runtime.mjs script in `@nimbus-sh/worker`. When
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 @nimbus-sh/worker/scripts/bundle-runtime.mjs\n');
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 packageJson = nodeRequire.resolve('@nimbus-sh/worker/package.json');
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
- // fallthrough
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 wsUrl = new URL('../../../worker/scripts/bundle-runtime.mjs', import.meta.url);
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,CAsF9D"}
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 run. Visit the returned
100
- URL and hit "Launch" to mint a session.
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/worker': '^0.1.1',
128
- '@nimbus-sh/sdk': '^0.1.1',
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
- export default createNimbusHandler();
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. Click "Launch" to mint a session.
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
- ## Custom auth
276
+ ## Tokens
255
277
 
256
- By default tokens are enforced (\`JWT_SECRET\` set). To mint:
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 --tenant acme --sub alice
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
- Edit \`src/index.ts\`:
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, { tn: tenant, sub });
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;
@@ -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 r = await fetch(`${endpoint.replace(/\/+$/, '')}/new`, {
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 m = loc.match(/\/s\/([^/]+)/);
21
- if (!m) {
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 sessionId = m[1];
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
@@ -3,5 +3,5 @@
3
3
  * `require('./package.json')` because that breaks under bun's
4
4
  * single-file binary mode.
5
5
  */
6
- export declare const CLI_VERSION = "0.1.4";
6
+ export declare const CLI_VERSION = "0.1.6";
7
7
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -3,4 +3,4 @@
3
3
  * `require('./package.json')` because that breaks under bun's
4
4
  * single-file binary mode.
5
5
  */
6
- export const CLI_VERSION = '0.1.4';
6
+ export const CLI_VERSION = '0.1.6';
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "@nimbus-sh/cli",
3
- "version": "0.1.4",
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": "./dist/bin.js",
16
- "nimbus": "./dist/bin.js",
17
- "create-nimbus-app": "./dist/scaffold-bin.js"
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.1",
40
- "@nimbus-sh/worker": "^0.1.1"
48
+ "@nimbus-sh/sdk": "^0.1.3",
49
+ "@nimbus-sh/worker": "^0.1.3"
41
50
  },
42
51
  "engines": {
43
52
  "node": ">=20"