c8ctl-plugin-nano 1.21.0 → 1.22.1
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 +17 -0
- package/c8ctl-plugin.js +146 -25
- package/nanobpmn-binary.json +4 -4
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -205,8 +205,16 @@ c8ctl nano work reviewer --job-type senior:pr-review --job-type senior:triage
|
|
|
205
205
|
```bash
|
|
206
206
|
c8ctl nano work reviewer # poll for work until Ctrl-C
|
|
207
207
|
c8ctl nano work reviewer --max-parallel 2 --job-timeout 600000
|
|
208
|
+
c8ctl nano work reviewer --name reviewer-eu # name this worker (else auto ‹host›-‹profile›-‹random›)
|
|
208
209
|
```
|
|
209
210
|
|
|
211
|
+
The optional `--name` sets **this worker's name** — the `workerName` it
|
|
212
|
+
registers under at the broker (`‹name›:‹jobType›`) and how it shows up in
|
|
213
|
+
supervisor status/logs. Omit it and a distinct `‹host›-‹profile›-‹random›`
|
|
214
|
+
name is generated, so two `work reviewer` processes never collide at the
|
|
215
|
+
broker. (`--name` names the worker; the profile to run is always the
|
|
216
|
+
positional argument.)
|
|
217
|
+
|
|
210
218
|
### Live profile reload (no restart on `assign`)
|
|
211
219
|
|
|
212
220
|
A running `c8ctl nano work <name>` **watches** the profile it is servicing. When
|
|
@@ -456,12 +464,21 @@ c8ctl nano supervisor
|
|
|
456
464
|
# Manage the fleet without the console (any terminal, any time):
|
|
457
465
|
c8ctl nano supervisor status # id, state, pid, restarts, uptime
|
|
458
466
|
c8ctl nano supervisor add reviewer --max-parallel 2 # add + spawn a worker (forwards work flags)
|
|
467
|
+
c8ctl nano supervisor add reviewer --name reviewer-2 # a SECOND reviewer, named so it stays distinct
|
|
459
468
|
c8ctl nano supervisor restart reviewer # by worker id or profile name
|
|
460
469
|
c8ctl nano supervisor remove coder # stop + drop a worker (also: `all`)
|
|
461
470
|
c8ctl nano supervisor logs reviewer --follow # tail a worker's log (or the daemon's)
|
|
462
471
|
c8ctl nano supervisor stop # stop the daemon and every worker
|
|
463
472
|
```
|
|
464
473
|
|
|
474
|
+
Each worker has a **name** — its supervisor id and the broker `workerName` it
|
|
475
|
+
registers under. Pass `--name` on `supervisor add` (or `work`) to set it;
|
|
476
|
+
omit it and one is auto-generated as `‹host›-‹profile›-‹random›`, so you can
|
|
477
|
+
run **several instances of the same profile** and they stay distinct
|
|
478
|
+
end-to-end (status, logs, and at the broker). `restart`/`remove` accept either
|
|
479
|
+
a worker id **or** a profile name — targeting a profile affects *every*
|
|
480
|
+
instance of it.
|
|
481
|
+
|
|
465
482
|
Each worker takes the **same flags as `nano work`** (`--max-parallel`,
|
|
466
483
|
`--job-timeout`, `--lock-grace`, `--poll-timeout`, `--sandbox`/`--image`,
|
|
467
484
|
`--job-type`, `--env`, `--arg`, …); they are forwarded verbatim to the spawned
|
package/c8ctl-plugin.js
CHANGED
|
@@ -49,8 +49,8 @@ import {
|
|
|
49
49
|
unwatchFile,
|
|
50
50
|
} from 'node:fs';
|
|
51
51
|
import { createConnection, createServer } from 'node:net';
|
|
52
|
-
import { randomUUID, createHash } from 'node:crypto';
|
|
53
|
-
import { homedir, platform as osPlatform, devNull, tmpdir } from 'node:os';
|
|
52
|
+
import { randomUUID, createHash, randomBytes } from 'node:crypto';
|
|
53
|
+
import { homedir, platform as osPlatform, devNull, tmpdir, hostname } from 'node:os';
|
|
54
54
|
import { join, isAbsolute, resolve as resolvePath, dirname, basename, sep } from 'node:path';
|
|
55
55
|
import { createRequire } from 'node:module';
|
|
56
56
|
import { fileURLToPath } from 'node:url';
|
|
@@ -2879,7 +2879,10 @@ function buildResultEnvelope(result, { sandbox, image, git, result: agentResult
|
|
|
2879
2879
|
*/
|
|
2880
2880
|
async function workAgent(req, flags) {
|
|
2881
2881
|
const logger = getLogger();
|
|
2882
|
-
|
|
2882
|
+
// The hire to run always comes from the positional profile. `--name` no longer
|
|
2883
|
+
// selects the hire (that was a footgun: `work reviewer --name coder` silently
|
|
2884
|
+
// ran `coder`); it now names THIS worker instance (see `workerName` below).
|
|
2885
|
+
const name = req.positional[0];
|
|
2883
2886
|
|
|
2884
2887
|
if (!name) {
|
|
2885
2888
|
const hires = readHires();
|
|
@@ -2902,6 +2905,19 @@ async function workAgent(req, flags) {
|
|
|
2902
2905
|
}
|
|
2903
2906
|
const profile = normalized.profile;
|
|
2904
2907
|
|
|
2908
|
+
// This worker's identity, surfaced to the broker as the `workerName` on every
|
|
2909
|
+
// activateJobs call (`‹workerName›:‹jobType›`). An explicit `--name` wins;
|
|
2910
|
+
// otherwise auto-generate `‹host›-‹profile›-‹random›` so two workers of the
|
|
2911
|
+
// same profile (e.g. launched by the supervisor) stay distinct at the broker
|
|
2912
|
+
// and in logs. A blank/whitespace `--name` falls back to auto (mirrors the
|
|
2913
|
+
// supervisor path); a non-blank one must be a safe worker-name token.
|
|
2914
|
+
const explicitName = flags?.name ? String(flags.name).trim() : '';
|
|
2915
|
+
if (explicitName !== '' && !isValidWorkerName(explicitName)) {
|
|
2916
|
+
logger.error(`Invalid --name "${flags.name}": use only letters, digits, and . _ -`);
|
|
2917
|
+
process.exit(1);
|
|
2918
|
+
}
|
|
2919
|
+
const workerName = explicitName !== '' ? explicitName : autoWorkerName(name);
|
|
2920
|
+
|
|
2905
2921
|
if (!globalThis.c8ctl || typeof globalThis.c8ctl.createClient !== 'function') {
|
|
2906
2922
|
logger.error('work requires the c8ctl runtime (createClient). Run it via the c8ctl CLI.');
|
|
2907
2923
|
process.exit(1);
|
|
@@ -3045,6 +3061,7 @@ async function workAgent(req, flags) {
|
|
|
3045
3061
|
const camunda = globalThis.c8ctl.createClient();
|
|
3046
3062
|
|
|
3047
3063
|
logger.info(`Putting "${name}" [${profile.rank}] to work → ${buildAgentCommandLine(profile.command, effectiveArgs)}`);
|
|
3064
|
+
logger.info(` worker: ${workerName}`);
|
|
3048
3065
|
logger.info(` model: ${profile.model || '(none)'}; capabilities: ${profile.capabilities.join(', ') || '(none)'}`);
|
|
3049
3066
|
logger.info(` sandbox: ${sandbox}${isContainer ? ` (image ${image})` : ''}`);
|
|
3050
3067
|
const profileEnvKeys = Object.keys(profileEnv);
|
|
@@ -3060,7 +3077,7 @@ async function workAgent(req, flags) {
|
|
|
3060
3077
|
const makeWorker = (jobType) =>
|
|
3061
3078
|
camunda.createJobWorker({
|
|
3062
3079
|
jobType,
|
|
3063
|
-
workerName: `${
|
|
3080
|
+
workerName: `${workerName}:${jobType}`,
|
|
3064
3081
|
maxParallelJobs,
|
|
3065
3082
|
jobTimeoutMs: jobLockMs,
|
|
3066
3083
|
pollTimeoutMs,
|
|
@@ -3491,6 +3508,78 @@ function reconstructWorkArgs(flags) {
|
|
|
3491
3508
|
return out;
|
|
3492
3509
|
}
|
|
3493
3510
|
|
|
3511
|
+
/**
|
|
3512
|
+
* Sanitize one token for use inside a worker name: keep `[A-Za-z0-9._-]`,
|
|
3513
|
+
* collapse every other run to a single `-`, and trim leading/trailing
|
|
3514
|
+
* separators. Returns `fallback` when nothing survives (e.g. an all-symbol
|
|
3515
|
+
* input). Pure.
|
|
3516
|
+
*/
|
|
3517
|
+
function sanitizeNameToken(raw, fallback = 'x') {
|
|
3518
|
+
const s = String(raw ?? '')
|
|
3519
|
+
.trim()
|
|
3520
|
+
.replace(/[^A-Za-z0-9._-]+/g, '-')
|
|
3521
|
+
.replace(/^[-._]+|[-._]+$/g, '');
|
|
3522
|
+
return s || fallback;
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
/**
|
|
3526
|
+
* An explicit worker name (`--name`) is valid iff — after trimming — it is a
|
|
3527
|
+
* non-empty run of `[A-Za-z0-9._-]`. That charset is the intersection of what
|
|
3528
|
+
* is safe in a broker `workerName` (no `:` to corrupt the `‹name›:‹jobType›`
|
|
3529
|
+
* form) and what survives `supervisorWorkerLogFile`'s filename sanitization
|
|
3530
|
+
* unchanged (so distinct ids can never collapse onto the same `worker-‹id›.log`
|
|
3531
|
+
* or escape the log dir). Auto-generated names are already in this shape;
|
|
3532
|
+
* operator-supplied names are validated against it so both invariants hold.
|
|
3533
|
+
* Pure.
|
|
3534
|
+
*/
|
|
3535
|
+
function isValidWorkerName(name) {
|
|
3536
|
+
const s = typeof name === 'string' ? name.trim() : '';
|
|
3537
|
+
return s !== '' && /^[A-Za-z0-9._-]+$/.test(s);
|
|
3538
|
+
}
|
|
3539
|
+
|
|
3540
|
+
/** A short, lowercase, collision-resistant suffix for auto worker names. */
|
|
3541
|
+
function randomNameSuffix(bytes = 4) {
|
|
3542
|
+
return randomBytes(bytes).toString('hex');
|
|
3543
|
+
}
|
|
3544
|
+
|
|
3545
|
+
/**
|
|
3546
|
+
* Auto-generated worker name: `‹short-hostname›-‹profile›-‹random›`. The host
|
|
3547
|
+
* defaults to this machine's short hostname (the first dot-label, lowercased);
|
|
3548
|
+
* the random suffix keeps two same-profile workers on the same host distinct.
|
|
3549
|
+
* `host`/`rand` are injectable so tests can assert a deterministic shape. Pure
|
|
3550
|
+
* given its options.
|
|
3551
|
+
*/
|
|
3552
|
+
function autoWorkerName(profile, { host = hostname(), rand = randomNameSuffix } = {}) {
|
|
3553
|
+
const shortHost = sanitizeNameToken(String(host || '').split('.')[0].toLowerCase(), 'host');
|
|
3554
|
+
const prof = sanitizeNameToken(profile, 'worker');
|
|
3555
|
+
const suffix = sanitizeNameToken(typeof rand === 'function' ? rand() : rand, '0');
|
|
3556
|
+
return `${shortHost}-${prof}-${suffix}`;
|
|
3557
|
+
}
|
|
3558
|
+
|
|
3559
|
+
/**
|
|
3560
|
+
* Split a supervised-worker name (`--name X`, `--name=X`, `-n X`) out of a raw
|
|
3561
|
+
* token list, returning `{ name, rest }` where `rest` is the remaining work
|
|
3562
|
+
* flags. Used by the interactive console's `add`, whose tokens aren't parsed by
|
|
3563
|
+
* the CLI flag layer. Last occurrence wins; a trailing `--name` with no value
|
|
3564
|
+
* yields `name: undefined`. Pure.
|
|
3565
|
+
*/
|
|
3566
|
+
function extractNameFlag(parts) {
|
|
3567
|
+
const rest = [];
|
|
3568
|
+
let name;
|
|
3569
|
+
const list = Array.isArray(parts) ? parts : [];
|
|
3570
|
+
for (let i = 0; i < list.length; i++) {
|
|
3571
|
+
const tok = String(list[i]);
|
|
3572
|
+
const eq = /^(?:--name|-n)=(.*)$/.exec(tok);
|
|
3573
|
+
if (eq) { name = eq[1]; continue; }
|
|
3574
|
+
if (tok === '--name' || tok === '-n') {
|
|
3575
|
+
if (i + 1 < list.length) { name = String(list[i + 1]); i++; }
|
|
3576
|
+
continue;
|
|
3577
|
+
}
|
|
3578
|
+
rest.push(tok);
|
|
3579
|
+
}
|
|
3580
|
+
return { name: name != null && name.trim() !== '' ? name.trim() : undefined, rest };
|
|
3581
|
+
}
|
|
3582
|
+
|
|
3494
3583
|
/** Assign a unique, stable worker id from a profile name (pure). */
|
|
3495
3584
|
function supervisorWorkerId(profile, taken) {
|
|
3496
3585
|
const base = String(profile || '').trim() || 'worker';
|
|
@@ -3766,7 +3855,9 @@ async function runSupervisorDaemon() {
|
|
|
3766
3855
|
const startWorker = (w) => {
|
|
3767
3856
|
let fd;
|
|
3768
3857
|
try { fd = openSync(w.logFile, 'a'); } catch { fd = 'ignore'; }
|
|
3769
|
-
|
|
3858
|
+
// `--name w.id` makes the child's broker workerName match this worker's
|
|
3859
|
+
// supervisor id, so the same profile launched twice is distinct end-to-end.
|
|
3860
|
+
const child = spawn(exec, [entry, 'nano', 'work', w.profile, '--name', w.id, ...w.args], {
|
|
3770
3861
|
env: process.env,
|
|
3771
3862
|
stdio: ['ignore', fd, fd],
|
|
3772
3863
|
});
|
|
@@ -3808,8 +3899,19 @@ async function runSupervisorDaemon() {
|
|
|
3808
3899
|
persist();
|
|
3809
3900
|
};
|
|
3810
3901
|
|
|
3811
|
-
const addWorker = (profile, args) => {
|
|
3812
|
-
const
|
|
3902
|
+
const addWorker = (profile, args, name) => {
|
|
3903
|
+
const taken = new Set(workers.keys());
|
|
3904
|
+
let id;
|
|
3905
|
+
if (name != null && String(name).trim() !== '') {
|
|
3906
|
+
id = String(name).trim();
|
|
3907
|
+
if (!isValidWorkerName(id)) throw new Error(`invalid worker name "${id}": use only letters, digits, and . _ -`);
|
|
3908
|
+
if (taken.has(id)) throw new Error(`a worker named "${id}" already exists`);
|
|
3909
|
+
} else {
|
|
3910
|
+
// No explicit name → auto ‹host›-‹profile›-‹random›. The random suffix is
|
|
3911
|
+
// collision-resistant, but never hand back a duplicate id.
|
|
3912
|
+
id = autoWorkerName(profile);
|
|
3913
|
+
while (taken.has(id)) id = autoWorkerName(profile);
|
|
3914
|
+
}
|
|
3813
3915
|
const w = {
|
|
3814
3916
|
id, profile: String(profile), args: Array.isArray(args) ? args.map(String) : [],
|
|
3815
3917
|
restarts: 0, stopping: false, lastExit: null, logFile: supervisorWorkerLogFile(id),
|
|
@@ -3896,20 +3998,22 @@ async function runSupervisorDaemon() {
|
|
|
3896
3998
|
case 'add': {
|
|
3897
3999
|
if (shuttingDown) { sock.write(encodeFrame({ ok: false, error: 'supervisor is shutting down', final: true })); break; }
|
|
3898
4000
|
if (!req.profile) { sock.write(encodeFrame({ ok: false, error: 'add requires a profile', final: true })); break; }
|
|
3899
|
-
//
|
|
3900
|
-
//
|
|
3901
|
-
//
|
|
3902
|
-
//
|
|
4001
|
+
// A supervised worker's name is supplied out-of-band as `req.name`
|
|
4002
|
+
// (which the daemon forwards to the child as `nano work … --name`).
|
|
4003
|
+
// A bare `--name` inside the forwarded work args is therefore ambiguous
|
|
4004
|
+
// — it would fight the supervisor-assigned id — so reject it here and
|
|
4005
|
+
// steer the operator to the dedicated flag.
|
|
3903
4006
|
// `req.args` comes from untrusted JSON and may be non-array (e.g. a
|
|
3904
4007
|
// string or object). Coerce to an array of string tokens before
|
|
3905
4008
|
// scanning/forwarding so a malformed payload yields a clean rejection
|
|
3906
4009
|
// instead of throwing a generic request error.
|
|
3907
4010
|
const args = Array.isArray(req.args) ? req.args.filter((a) => typeof a === 'string') : [];
|
|
3908
4011
|
const badName = args.find((a) => a === '--name' || a === '-n' || /^--name=/.test(a) || /^-n=/.test(a));
|
|
3909
|
-
if (badName) { sock.write(encodeFrame({ ok: false, error:
|
|
4012
|
+
if (badName) { sock.write(encodeFrame({ ok: false, error: 'name a supervised worker with `--name` on `supervisor add`, not inside its work flags', final: true })); break; }
|
|
3910
4013
|
const stored = readHires()[String(req.profile)];
|
|
3911
4014
|
if (!stored) { sock.write(encodeFrame({ ok: false, error: `no hire named "${req.profile}"`, final: true })); break; }
|
|
3912
|
-
const
|
|
4015
|
+
const name = typeof req.name === 'string' ? req.name.trim() : '';
|
|
4016
|
+
const w = await serializeOp(() => addWorker(req.profile, args, name));
|
|
3913
4017
|
sock.write(encodeFrame({ ok: true, type: 'added', worker: workerPublic(w), final: true }));
|
|
3914
4018
|
break;
|
|
3915
4019
|
}
|
|
@@ -4147,8 +4251,17 @@ async function supervisorStartCmd(req, flags) {
|
|
|
4147
4251
|
|
|
4148
4252
|
const specs = normalizeArgList(flags?.worker);
|
|
4149
4253
|
const workArgs = reconstructWorkArgs(flags);
|
|
4150
|
-
|
|
4151
|
-
|
|
4254
|
+
// `--name` names a single launched worker. With several `--worker` specs a lone
|
|
4255
|
+
// name can't apply to all of them, so honour it only for a single spec and let
|
|
4256
|
+
// the rest auto-name; warn so the intent isn't silently dropped.
|
|
4257
|
+
const explicitName = flags?.name ? String(flags.name).trim() : undefined;
|
|
4258
|
+
if (explicitName && specs.length > 1) {
|
|
4259
|
+
logger.warn('--name is ignored when starting multiple --worker specs; each is auto-named.');
|
|
4260
|
+
}
|
|
4261
|
+
const nameFor = (i) => (explicitName && specs.length === 1 ? explicitName : undefined);
|
|
4262
|
+
for (let i = 0; i < specs.length; i++) {
|
|
4263
|
+
const profile = specs[i];
|
|
4264
|
+
const res = await supervisorRequest({ op: 'add', profile, name: nameFor(i), args: workArgs });
|
|
4152
4265
|
if (res.ok) logger.info(` + worker "${res.worker.id}" (profile ${profile})`);
|
|
4153
4266
|
else logger.error(` ! could not add "${profile}": ${res.error}`);
|
|
4154
4267
|
}
|
|
@@ -4202,13 +4315,14 @@ async function supervisorStatusCmd() {
|
|
|
4202
4315
|
|
|
4203
4316
|
async function supervisorAddCmd(req, flags) {
|
|
4204
4317
|
const logger = getLogger();
|
|
4205
|
-
//
|
|
4206
|
-
//
|
|
4207
|
-
//
|
|
4318
|
+
// The positional profile is what runs; `--name` names this worker instance
|
|
4319
|
+
// (forwarded to the child as `nano work … --name`, and used as its supervisor
|
|
4320
|
+
// id). Omit `--name` to auto-generate ‹host›-‹profile›-‹random›.
|
|
4208
4321
|
const profile = req.positional[1];
|
|
4209
|
-
if (!profile) { logger.error('Usage: c8ctl nano supervisor add <profile> [work flags]'); process.exit(1); }
|
|
4322
|
+
if (!profile) { logger.error('Usage: c8ctl nano supervisor add <profile> [--name <worker>] [work flags]'); process.exit(1); }
|
|
4323
|
+
const name = flags?.name ? String(flags.name).trim() : undefined;
|
|
4210
4324
|
await startSupervisorDaemon();
|
|
4211
|
-
const res = await supervisorRequest({ op: 'add', profile, args: reconstructWorkArgs(flags) });
|
|
4325
|
+
const res = await supervisorRequest({ op: 'add', profile, name, args: reconstructWorkArgs(flags) });
|
|
4212
4326
|
if (res.ok) logger.info(`Added worker "${res.worker.id}" (profile ${profile}); pid ${res.worker.pid ?? 'starting'}.`);
|
|
4213
4327
|
else { logger.error(`Could not add "${profile}": ${res.error}`); process.exit(1); }
|
|
4214
4328
|
}
|
|
@@ -4360,14 +4474,16 @@ async function attachSupervisorConsole(state) {
|
|
|
4360
4474
|
switch (cmd) {
|
|
4361
4475
|
case '': break;
|
|
4362
4476
|
case 'help':
|
|
4363
|
-
out('Commands: status | add <profile> [work flags] |
|
|
4364
|
-
out('
|
|
4477
|
+
out('Commands: status | add <profile> [--name <worker>] [work flags] |');
|
|
4478
|
+
out(' remove <id|profile|all> | restart <id|profile|all> |');
|
|
4479
|
+
out(' logs [id] | detach | stop | help');
|
|
4365
4480
|
break;
|
|
4366
4481
|
case 'status': sock.write(encodeFrame({ op: 'status' })); break;
|
|
4367
4482
|
case 'add': {
|
|
4368
4483
|
const profile = parts.shift();
|
|
4369
|
-
if (!profile) { out('usage: add <profile> [work flags]'); break; }
|
|
4370
|
-
|
|
4484
|
+
if (!profile) { out('usage: add <profile> [--name <worker>] [work flags]'); break; }
|
|
4485
|
+
const { name, rest } = extractNameFlag(parts);
|
|
4486
|
+
sock.write(encodeFrame({ op: 'add', profile, name, args: rest }));
|
|
4371
4487
|
break;
|
|
4372
4488
|
}
|
|
4373
4489
|
case 'remove': case 'rm': {
|
|
@@ -5824,6 +5940,11 @@ export {
|
|
|
5824
5940
|
export {
|
|
5825
5941
|
reconstructWorkArgs,
|
|
5826
5942
|
supervisorWorkerId,
|
|
5943
|
+
autoWorkerName,
|
|
5944
|
+
sanitizeNameToken,
|
|
5945
|
+
isValidWorkerName,
|
|
5946
|
+
randomNameSuffix,
|
|
5947
|
+
extractNameFlag,
|
|
5827
5948
|
redactWorkArgs,
|
|
5828
5949
|
supervisorBackoffMs,
|
|
5829
5950
|
encodeFrame,
|
|
@@ -5926,7 +6047,7 @@ export const commands = {
|
|
|
5926
6047
|
workspace: { type: 'boolean', description: 'clean: also delete the workspace (models + workers)' },
|
|
5927
6048
|
check: { type: 'boolean', description: 'update: only report whether a new release is available; do not install' },
|
|
5928
6049
|
binary: { type: 'string', description: 'Path to the nanobpmn server binary' },
|
|
5929
|
-
name: { type: 'string', description: '
|
|
6050
|
+
name: { type: 'string', description: 'work/supervisor add: worker name (auto ‹host›-‹profile›-‹random› if omitted); hire/assign: agent profile name' },
|
|
5930
6051
|
rank: { type: 'string', description: 'hire: agent rank (principal|senior|junior|decider)' },
|
|
5931
6052
|
command: { type: 'string', description: 'hire: CLI command that runs the agent harness (e.g. copilot, claude, pi)' },
|
|
5932
6053
|
arg: { type: 'string', multiple: true, description: 'hire/work: command-line switch/arg appended to the harness command (repeatable), e.g. --arg --allow-all. Persisted on hire; work appends more.' },
|
package/nanobpmn-binary.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.0.
|
|
3
|
-
"commit": "
|
|
4
|
-
"updated": "2026-
|
|
5
|
-
}
|
|
2
|
+
"version": "0.0.12",
|
|
3
|
+
"commit": "39f4a33",
|
|
4
|
+
"updated": "2026-08-07T05:19:36Z"
|
|
5
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c8ctl-plugin-nano",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.1",
|
|
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",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"semantic-release": "^25.0.3"
|
|
48
48
|
},
|
|
49
49
|
"optionalDependencies": {
|
|
50
|
-
"@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.
|
|
51
|
-
"@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.
|
|
52
|
-
"@nanobpm/c8ctl-plugin-nano-linux-x64": "1.
|
|
53
|
-
"@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.
|
|
54
|
-
"@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.
|
|
55
|
-
"@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.
|
|
56
|
-
"@nanobpm/c8ctl-plugin-nano-win32-x64": "1.
|
|
50
|
+
"@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.22.1",
|
|
51
|
+
"@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.22.1",
|
|
52
|
+
"@nanobpm/c8ctl-plugin-nano-linux-x64": "1.22.1",
|
|
53
|
+
"@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.22.1",
|
|
54
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.22.1",
|
|
55
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.22.1",
|
|
56
|
+
"@nanobpm/c8ctl-plugin-nano-win32-x64": "1.22.1"
|
|
57
57
|
}
|
|
58
58
|
}
|