@atolljs/cli 0.0.0-stage → 0.1.5

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/package.json CHANGED
@@ -1,6 +1,36 @@
1
1
  {
2
2
  "name": "@atolljs/cli",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.5",
4
+ "description": "atoll — scaffold worker pools, shared-memory contracts, and framework islands (experimental)",
5
+ "homepage": "https://jwhenry3.github.io/atolljs/consumer/quickstart/",
6
+ "type": "module",
7
+ "bin": {
8
+ "atoll": "./dist/cli.js"
9
+ },
10
+ "exports": {
11
+ "./package.json": "./package.json"
12
+ },
13
+ "files": [
14
+ "src",
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "esbuild src/cli.ts --bundle --format=esm --platform=node --target=node20.12 --outfile=dist/cli.js"
19
+ },
20
+ "engines": {
21
+ "node": ">=20.12"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "registry": "https://registry.npmjs.org"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/jwhenry3/atolljs",
30
+ "directory": "packages/cli"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/jwhenry3/atolljs/issues"
34
+ },
35
+ "license": "MIT"
36
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `atoll` — bootstrap multithreading in an app: worker pools, shared-memory
4
+ * contracts, framework islands, and a doctor that checks the setup.
5
+ *
6
+ * Sources stay TypeScript — dev runs this entry via Node's type stripping
7
+ * (`npm run atoll`, vitest, CI smoke). The *published* bin is a bundled
8
+ * dist/cli.js: Node refuses type stripping inside node_modules, which is
9
+ * where npx installs packages. Keep relative imports' `.ts` extensions
10
+ * explicit and stay inside erasable syntax so both paths keep working;
11
+ * `npm run build` (esbuild) regenerates the bundle.
12
+ */
13
+ import { consoleIo, type Fmt, type Io } from './io.ts';
14
+ import { hasFlag, parseArgs } from './parse.ts';
15
+ import { runAdd, runCreate, runDoctor, runInit, type Ctx } from './commands.ts';
16
+
17
+ const HELP = (fmt: Fmt) => `${fmt.strong('atoll')} — bootstrap multithreading ${fmt.dim('(experimental)')}
18
+
19
+ ${fmt.accent('atoll new <dir>')} [--framework react|vue|solid|svelte|node] [--pm npm]
20
+ Scaffold a fresh app — vite shell + a worker-rendered island,
21
+ or a tsx Node service with a pooled worker.
22
+
23
+ ${fmt.accent('atoll init')} [--name app] [--force]
24
+ Wire Atoll into the current project: hardened .npmrc, package
25
+ install, and a contract + worker + client spine under src/atoll/.
26
+
27
+ ${fmt.accent('atoll add [framework] <kind> [variant] [name]')}
28
+ worker pool + typed client (+ framework bindings on UI projects)
29
+ memory shared-memory contract
30
+ island worker-rendered UI — facade (contract + lazy import) | mono
31
+ service nestjs: @AtollService class facade + pool module + worker
32
+ method nestjs: @AtollTask method-level offload
33
+ module nestjs: registerPool boundary module + worker entry
34
+ housed nestjs: route subtree served entirely inside workers
35
+ route nextjs: api route pool — task | client variants
36
+ component nextjs: 'use client' hooks component over a pool
37
+ instrumentation nextjs: server bootstrap that warms route pools
38
+
39
+ Frameworks: react vue solid svelte angular nestjs nextjs node
40
+ [--dir <path>] [--memory <name>|--no-memory] [--variant <v>] [--force]
41
+
42
+ ${fmt.accent('atoll doctor')} [--fix]
43
+ Check the setup — deps, lockfile, .npmrc policy, bundler-detectable
44
+ worker entries, COOP/COEP headers. --fix writes a hardened .npmrc.
45
+
46
+ ${fmt.dim(`flags: --yes/-y accepts defaults, --force overwrites existing files,
47
+ --no-install skips dependency installation`)}
48
+ `;
49
+
50
+ const DISCLAIMER =
51
+ 'atoll is experimental — report bugs or feedback: ' +
52
+ 'https://github.com/jwhenry3/atolljs/issues';
53
+
54
+ export async function runCli(argv: readonly string[], io: Io, cwd: string): Promise<number> {
55
+ const args = parseArgs(argv);
56
+ const ctx: Ctx = { io, cwd, args };
57
+ const [cmd] = args._;
58
+
59
+ io.warn(io.fmt.dim(DISCLAIMER));
60
+
61
+ try {
62
+ switch (cmd) {
63
+ case 'new':
64
+ case 'create':
65
+ return await runCreate(ctx);
66
+ case 'init':
67
+ return await runInit(ctx);
68
+ case 'add':
69
+ return await runAdd(ctx);
70
+ case 'doctor':
71
+ return runDoctor(ctx);
72
+ case 'help':
73
+ case undefined:
74
+ io.print(HELP(io.fmt));
75
+ return cmd === undefined ? 0 : 0;
76
+ default:
77
+ io.error(`unknown command ${io.fmt.accent(cmd)}`);
78
+ io.print(HELP(io.fmt));
79
+ return 1;
80
+ }
81
+ } catch (e) {
82
+ io.error(e instanceof Error ? e.message : String(e));
83
+ return 1;
84
+ } finally {
85
+ io.close();
86
+ }
87
+ }
88
+
89
+ // Entry guard — the file is also imported by tests, which pass their own io.
90
+ const invokedAs =
91
+ process.argv[1] && import.meta.url.endsWith(process.argv[1].replaceAll('\\', '/'));
92
+ if (invokedAs) {
93
+ const args = parseArgs(process.argv.slice(2));
94
+ const interactive = process.stdin.isTTY === true && !hasFlag(args, 'yes', 'y');
95
+ const code = await runCli(process.argv.slice(2), consoleIo(interactive), process.cwd());
96
+ process.exit(code);
97
+ }