c8ctl-plugin-nano 1.7.2 → 1.8.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 +15 -0
- package/c8ctl-plugin.js +47 -3
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -169,6 +169,21 @@ and the history cap.
|
|
|
169
169
|
> ⚠️ With `--in-memory`, restart recovers nothing, and Raft/replicated logs are
|
|
170
170
|
> not persisted. Use it for stress/throughput testing, not durability testing.
|
|
171
171
|
|
|
172
|
+
## Console profile (`--console` / `--profile`)
|
|
173
|
+
|
|
174
|
+
The server ships a browser console. Pick how much of it is exposed at runtime:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
c8ctl nano start # studio (default): full IDE + authoring API
|
|
178
|
+
c8ctl nano start --console observe # observability views only; authoring refused (403)
|
|
179
|
+
c8ctl nano start --console off # headless: no console router at all
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- Values: `studio` (default), `observe`, `off`. `--profile` is an alias for
|
|
183
|
+
`--console`, and an inherited `NANOBPMN_CONSOLE` env var is honored when neither
|
|
184
|
+
flag is passed. The plugin passes the choice through as `NANOBPMN_CONSOLE` on
|
|
185
|
+
every node.
|
|
186
|
+
|
|
172
187
|
## Configuration (`set` / `config`)
|
|
173
188
|
|
|
174
189
|
Persistent settings are stored in `<state home>/config.json`:
|
package/c8ctl-plugin.js
CHANGED
|
@@ -13,13 +13,15 @@
|
|
|
13
13
|
* NANOBPMN_RF replication factor (1 = single-homed, no Raft)
|
|
14
14
|
* NANOBPMN_RAFT set when RF > 1 to enable per-partition Raft
|
|
15
15
|
* NANOBPMN_DATA_DIR this node's engine data directory
|
|
16
|
+
* NANOBPMN_CONSOLE runtime console profile (off | observe | studio)
|
|
17
|
+
* NANOBPMN_NODE_BIN Node path for the server's worker fallback runtime
|
|
16
18
|
*
|
|
17
19
|
* This plugin spawns N detached node processes wired to talk to each other on
|
|
18
20
|
* localhost, tracks them in a state file, and stops them on request.
|
|
19
21
|
*
|
|
20
22
|
* Usage:
|
|
21
23
|
* c8ctl nano start [<nodes>] [--port <basePort>] [--partitions <n>] [--rf <n>]
|
|
22
|
-
* [--in-memory] [--history-max <n>]
|
|
24
|
+
* [--in-memory] [--history-max <n>] [--console <profile>]
|
|
23
25
|
* c8ctl nano status
|
|
24
26
|
* c8ctl nano stop [--purge]
|
|
25
27
|
* c8ctl nano logs [<nodeId>] [--follow]
|
|
@@ -334,6 +336,18 @@ function findBinary(flags) {
|
|
|
334
336
|
*/
|
|
335
337
|
function launcherEnvMarkers(resolved) {
|
|
336
338
|
const markers = { NANOBPMN_LAUNCHER: 'c8ctl-plugin-nano' };
|
|
339
|
+
|
|
340
|
+
// This launcher IS a Node runtime, so hand the server a known-good Node path
|
|
341
|
+
// for its worker fallback (Deno-preferred, Node >= 22.6). Avoid pinning an
|
|
342
|
+
// older Node runtime (the plugin supports Node >=18) so the server can still
|
|
343
|
+
// fall back to a newer Node on PATH when available.
|
|
344
|
+
const [nodeMajor, nodeMinor, nodePatch] = process.versions.node
|
|
345
|
+
.split('.')
|
|
346
|
+
.map((n) => Number.parseInt(n, 10));
|
|
347
|
+
const nodeOk =
|
|
348
|
+
nodeMajor > 22 ||
|
|
349
|
+
(nodeMajor === 22 && (nodeMinor > 6 || (nodeMinor === 6 && nodePatch >= 0)));
|
|
350
|
+
if (nodeOk) markers.NANOBPMN_NODE_BIN = process.execPath;
|
|
337
351
|
const { version } = pluginPackage();
|
|
338
352
|
// The plugin version is the update unit's "current" in the npm channel's
|
|
339
353
|
// version space (same space as `npm view <plugin> version` -> latest), so the
|
|
@@ -381,6 +395,7 @@ function parseRequest(args, flags) {
|
|
|
381
395
|
capture: Boolean(flags?.capture),
|
|
382
396
|
inMemory: Boolean(flags?.['in-memory'] || flags?.['no-journal']),
|
|
383
397
|
historyMax: intFlag('history-max'),
|
|
398
|
+
console: flags?.console ?? flags?.profile,
|
|
384
399
|
workspace: Boolean(flags?.workspace),
|
|
385
400
|
check: Boolean(flags?.check),
|
|
386
401
|
binary: flags?.binary,
|
|
@@ -529,6 +544,26 @@ async function waitForHealthy(url, timeoutMs = READINESS_TIMEOUT_MS) { const st
|
|
|
529
544
|
// start
|
|
530
545
|
// ---------------------------------------------------------------------------
|
|
531
546
|
|
|
547
|
+
/** Runtime console profiles the server understands (nano-bpm ADR 0035 §C). */
|
|
548
|
+
const CONSOLE_PROFILES = ['off', 'observe', 'studio'];
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Resolves the runtime console profile to pass through as NANOBPMN_CONSOLE.
|
|
552
|
+
* Precedence: --console/--profile flag > inherited NANOBPMN_CONSOLE env >
|
|
553
|
+
* 'studio' (the full IDE, our default). Unknown values are rejected so a typo
|
|
554
|
+
* fails fast here rather than silently degrading the console in the server.
|
|
555
|
+
*/
|
|
556
|
+
function resolveConsoleProfile(reqConsole) {
|
|
557
|
+
const raw = reqConsole ?? process.env.NANOBPMN_CONSOLE ?? 'studio';
|
|
558
|
+
const profile = String(raw).trim().toLowerCase();
|
|
559
|
+
if (!CONSOLE_PROFILES.includes(profile)) {
|
|
560
|
+
throw new Error(
|
|
561
|
+
`invalid console profile "${raw}" (use one of: ${CONSOLE_PROFILES.join(', ')})`,
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
return profile;
|
|
565
|
+
}
|
|
566
|
+
|
|
532
567
|
async function startCluster(req) {
|
|
533
568
|
const logger = getLogger();
|
|
534
569
|
|
|
@@ -557,6 +592,7 @@ async function startCluster(req) {
|
|
|
557
592
|
const capture = Boolean(req.capture);
|
|
558
593
|
const inMemory = Boolean(req.inMemory);
|
|
559
594
|
const historyMax = req.historyMax;
|
|
595
|
+
const consoleProfile = resolveConsoleProfile(req.console);
|
|
560
596
|
|
|
561
597
|
if (partitions < nodeCount) {
|
|
562
598
|
logger.warn(
|
|
@@ -630,7 +666,8 @@ async function startCluster(req) {
|
|
|
630
666
|
`Starting Nano BPM cluster: ${nodeCount} node(s), ${partitions} partition(s), ` +
|
|
631
667
|
`RF=${rf}${raft ? ', Raft on' : ''}${capture ? ', trace capture on' : ''}` +
|
|
632
668
|
`${inMemory ? ', in-memory (no disk)' : ''}` +
|
|
633
|
-
`${historyMax !== undefined ? `, history-max=${historyMax}` : ''}
|
|
669
|
+
`${historyMax !== undefined ? `, history-max=${historyMax}` : ''}` +
|
|
670
|
+
`${consoleProfile !== 'studio' ? `, console=${consoleProfile}` : ''}`,
|
|
634
671
|
);
|
|
635
672
|
logger.info(`Binary: ${binary}`);
|
|
636
673
|
logger.info(`Workspace: ${workspaceDir} (models/, workers/)`);
|
|
@@ -667,6 +704,10 @@ async function startCluster(req) {
|
|
|
667
704
|
// Shared, persistent authoring workspace (models + workers). Lives
|
|
668
705
|
// outside the per-node data dir so "nano clean" never wipes it.
|
|
669
706
|
NANOBPMN_WORKSPACE_DIR: workspaceDir,
|
|
707
|
+
// Runtime console profile (off | observe | studio). Default studio (full
|
|
708
|
+
// IDE); pass-through so --console/--profile or an inherited NANOBPMN_CONSOLE
|
|
709
|
+
// picks the observability-only or headless surface. See nano-bpm ADR 0035 §C.
|
|
710
|
+
NANOBPMN_CONSOLE: consoleProfile,
|
|
670
711
|
};
|
|
671
712
|
// Storage axis: an on-disk journal + read-model under the per-node data dir
|
|
672
713
|
// (default), or a fully in-memory engine (in-memory journal + :memory: read
|
|
@@ -2540,6 +2581,8 @@ export const commands = {
|
|
|
2540
2581
|
'in-memory': { type: 'boolean', description: 'start: run with NO on-disk journal/read-model (in-memory engine; state lost on restart). Alias: --no-journal' },
|
|
2541
2582
|
'no-journal': { type: 'boolean', description: 'start: alias for --in-memory' },
|
|
2542
2583
|
'history-max': { type: 'string', description: 'start: cap retained terminal instances in the read model (NANOBPMN_HISTORY_MAX_INSTANCES; 0/unset = unbounded)' },
|
|
2584
|
+
console: { type: 'string', description: 'start: runtime console profile off|observe|studio (NANOBPMN_CONSOLE; default studio). Alias: --profile' },
|
|
2585
|
+
profile: { type: 'string', description: 'start: alias for --console (off|observe|studio; default studio)' },
|
|
2543
2586
|
follow: { type: 'boolean', description: 'logs: stream output (tail -F)', short: 'f' },
|
|
2544
2587
|
purge: { type: 'boolean', description: 'stop/restart: also delete per-node engine data' },
|
|
2545
2588
|
force: { type: 'boolean', description: 'start: stop any existing cluster first' },
|
|
@@ -2671,7 +2714,7 @@ export const commands = {
|
|
|
2671
2714
|
|
|
2672
2715
|
function printUsage() {
|
|
2673
2716
|
console.log('Usage:');
|
|
2674
|
-
console.log(' c8ctl nano start [<nodes>] [--port <basePort>] [--partitions <n>] [--rf <n>] [--raft] [--capture] [--in-memory] [--history-max <n>] [--binary <path>]');
|
|
2717
|
+
console.log(' c8ctl nano start [<nodes>] [--port <basePort>] [--partitions <n>] [--rf <n>] [--raft] [--capture] [--in-memory] [--history-max <n>] [--console <profile>] [--binary <path>]');
|
|
2675
2718
|
console.log(' c8ctl nano status [--port <port>]');
|
|
2676
2719
|
console.log(' c8ctl nano stop [--purge]');
|
|
2677
2720
|
console.log(' c8ctl nano logs [<nodeId>] [--follow]');
|
|
@@ -2705,6 +2748,7 @@ function printUsage() {
|
|
|
2705
2748
|
console.log(' --capture start: enable trace capture (recorded-input replay) on every node');
|
|
2706
2749
|
console.log(' --in-memory start: run with NO on-disk journal/read-model (alias --no-journal; state lost on restart)');
|
|
2707
2750
|
console.log(' --history-max <n> start: cap retained terminal instances in the read model (0/unset = unbounded)');
|
|
2751
|
+
console.log(' --console <profile> start: runtime console profile off|observe|studio (alias --profile; default studio)');
|
|
2708
2752
|
console.log(' --binary <path> Path to the nanobpmn server binary (overrides "set bin")');
|
|
2709
2753
|
console.log(' --purge stop: also delete per-node engine data');
|
|
2710
2754
|
console.log(' --force start: stop any existing cluster first');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c8ctl-plugin-nano",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "c8ctl plugin to start, inspect, and stop a local Nano BPM (nanobpmn) cluster",
|
|
6
6
|
"main": "c8ctl-plugin.js",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"semantic-release": "^25.0.3"
|
|
50
50
|
},
|
|
51
51
|
"optionalDependencies": {
|
|
52
|
-
"@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.
|
|
53
|
-
"@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.
|
|
54
|
-
"@nanobpm/c8ctl-plugin-nano-linux-x64": "1.
|
|
55
|
-
"@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.
|
|
56
|
-
"@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.
|
|
57
|
-
"@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.
|
|
58
|
-
"@nanobpm/c8ctl-plugin-nano-win32-x64": "1.
|
|
52
|
+
"@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.8.0",
|
|
53
|
+
"@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.8.0",
|
|
54
|
+
"@nanobpm/c8ctl-plugin-nano-linux-x64": "1.8.0",
|
|
55
|
+
"@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.8.0",
|
|
56
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.8.0",
|
|
57
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.8.0",
|
|
58
|
+
"@nanobpm/c8ctl-plugin-nano-win32-x64": "1.8.0"
|
|
59
59
|
}
|
|
60
60
|
}
|