c8ctl-plugin-nano 1.25.1 → 1.26.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 +15 -5
- package/c8ctl-plugin.js +184 -11
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -106,6 +106,10 @@ c8ctl nano clean
|
|
|
106
106
|
c8ctl nano set bin ~/workspace/nanobpmn/server/target/release/nanobpm-gateway-rest-server
|
|
107
107
|
c8ctl nano set model-dir ~/bpmn-workspace
|
|
108
108
|
|
|
109
|
+
# Clear a custom setting (back to the managed/release binary, or default workspace)
|
|
110
|
+
c8ctl nano unset bin
|
|
111
|
+
c8ctl nano unset model-dir
|
|
112
|
+
|
|
109
113
|
# Show current configuration and on-disk locations
|
|
110
114
|
c8ctl nano config
|
|
111
115
|
```
|
|
@@ -575,17 +579,23 @@ c8ctl nano start --console off # headless: no console router at all
|
|
|
575
579
|
env var is honored when the flag is not passed. The plugin passes the choice
|
|
576
580
|
through as `NANOBPMN_CONSOLE` on every node.
|
|
577
581
|
|
|
578
|
-
## Configuration (`set` / `config`)
|
|
582
|
+
## Configuration (`set` / `unset` / `config`)
|
|
579
583
|
|
|
580
584
|
Persistent settings are stored in `<state home>/config.json`:
|
|
581
585
|
|
|
582
|
-
| Setting | Env mapping | Set with |
|
|
583
|
-
|
|
584
|
-
| Binary path | (used to launch nodes) | `c8ctl nano set bin <path>` |
|
|
585
|
-
| Workspace directory | `NANOBPMN_WORKSPACE_DIR` | `c8ctl nano set model-dir <path>` |
|
|
586
|
+
| Setting | Env mapping | Set with | Clear with |
|
|
587
|
+
|---------------------|--------------------------|-----------------------------------|-------------------------------|
|
|
588
|
+
| Binary path | (used to launch nodes) | `c8ctl nano set bin <path>` | `c8ctl nano unset bin` |
|
|
589
|
+
| Workspace directory | `NANOBPMN_WORKSPACE_DIR` | `c8ctl nano set model-dir <path>` | `c8ctl nano unset model-dir` |
|
|
586
590
|
|
|
587
591
|
Show the effective configuration and all on-disk locations with `c8ctl nano config`.
|
|
588
592
|
|
|
593
|
+
`unset bin` clears a custom binary path so node launches fall back to the
|
|
594
|
+
managed platform binary — i.e. back on the release train that `c8ctl nano
|
|
595
|
+
update` tracks. (Note: a `NANOBPMN_BINARY` environment variable still overrides
|
|
596
|
+
even after `unset`.) `unset model-dir` returns the workspace to its default
|
|
597
|
+
(`<state home>/workspace`).
|
|
598
|
+
|
|
589
599
|
## Updating to a new release (`update`)
|
|
590
600
|
|
|
591
601
|
The plugin and the bundled server binary (delivered via the matching platform
|
package/c8ctl-plugin.js
CHANGED
|
@@ -450,7 +450,7 @@ function launcherEnvMarkers(resolved) {
|
|
|
450
450
|
// Argument parsing
|
|
451
451
|
// ---------------------------------------------------------------------------
|
|
452
452
|
|
|
453
|
-
const VALID_SUBCOMMANDS = ['start', 'stop', 'status', 'logs', 'log', 'restart', 'pause', 'resume', 'clean', 'set', 'config', 'update', 'hire', 'assign', 'work', 'supervisor'];
|
|
453
|
+
const VALID_SUBCOMMANDS = ['start', 'stop', 'status', 'logs', 'log', 'restart', 'pause', 'resume', 'clean', 'set', 'unset', 'config', 'update', 'hire', 'assign', 'work', 'supervisor'];
|
|
454
454
|
|
|
455
455
|
/**
|
|
456
456
|
* Parse positional args + flags into a normalized request.
|
|
@@ -1387,7 +1387,7 @@ function setConfig(req) {
|
|
|
1387
1387
|
const key = req.positional[0];
|
|
1388
1388
|
const value = req.positional[1];
|
|
1389
1389
|
|
|
1390
|
-
if (!key || !(key
|
|
1390
|
+
if (!key || !Object.hasOwn(SETTING_ALIASES, key)) {
|
|
1391
1391
|
logger.error('Usage: c8ctl nano set <bin|model-dir> <path>');
|
|
1392
1392
|
logger.info('Settings:');
|
|
1393
1393
|
logger.info(' bin <path> Path to the nanobpmn server binary');
|
|
@@ -1423,12 +1423,69 @@ function setConfig(req) {
|
|
|
1423
1423
|
}
|
|
1424
1424
|
}
|
|
1425
1425
|
|
|
1426
|
+
/**
|
|
1427
|
+
* Clear a configured setting so resolution falls back to the default. The
|
|
1428
|
+
* headline use is `unset bin`: after `set bin <path>` pins a self-managed
|
|
1429
|
+
* binary (source 'configured', which disables self-update), clearing it lets
|
|
1430
|
+
* the plugin fall back to the managed npm platform package — i.e. back on the
|
|
1431
|
+
* release train. `unset model-dir` returns the workspace to its default.
|
|
1432
|
+
*/
|
|
1433
|
+
function unsetConfig(req) {
|
|
1434
|
+
const logger = getLogger();
|
|
1435
|
+
const key = req.positional[0];
|
|
1436
|
+
|
|
1437
|
+
if (!key || !Object.hasOwn(SETTING_ALIASES, key)) {
|
|
1438
|
+
logger.error('Usage: c8ctl nano unset <bin|model-dir>');
|
|
1439
|
+
logger.info('Settings:');
|
|
1440
|
+
logger.info(' bin Clear the custom server binary (back to the managed/release binary)');
|
|
1441
|
+
logger.info(' model-dir Clear the custom workspace dir (back to the default)');
|
|
1442
|
+
process.exit(1);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
const field = SETTING_ALIASES[key];
|
|
1446
|
+
const cfg = readConfig();
|
|
1447
|
+
const prev = cfg[field];
|
|
1448
|
+
const wasSet = prev !== undefined && prev !== null && prev !== '';
|
|
1449
|
+
const label = field === 'binary' ? 'custom binary override' : 'custom workspace override';
|
|
1450
|
+
|
|
1451
|
+
if (!wasSet) {
|
|
1452
|
+
logger.info(`No ${label} is configured — nothing to clear.`);
|
|
1453
|
+
} else {
|
|
1454
|
+
delete cfg[field];
|
|
1455
|
+
writeConfig(cfg);
|
|
1456
|
+
logger.info(`Cleared ${label} (was ${prev}).`);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
if (field === 'binary') {
|
|
1460
|
+
// Report what resolves now, so the operator can see they are back on the
|
|
1461
|
+
// managed release train (or what still overrides it).
|
|
1462
|
+
try {
|
|
1463
|
+
const r = resolveBinary({});
|
|
1464
|
+
logger.info(`Now using: ${r.path} (${r.from}).`);
|
|
1465
|
+
if (r.source === 'managed-npm') {
|
|
1466
|
+
logger.info('Back on the managed release train — "c8ctl nano update" now tracks the published release.');
|
|
1467
|
+
} else if (r.source === 'configured') {
|
|
1468
|
+
logger.warn('Still pinned by NANOBPMN_BINARY in your environment; unset that to use the managed binary.');
|
|
1469
|
+
}
|
|
1470
|
+
} catch (err) {
|
|
1471
|
+
logger.warn(`No binary resolves now: ${err instanceof Error ? err.message : err}`);
|
|
1472
|
+
logger.info('Reinstall the plugin to fetch the managed platform binary, or set one again with "c8ctl nano set bin <path>".');
|
|
1473
|
+
}
|
|
1474
|
+
} else if (field === 'workspaceDir') {
|
|
1475
|
+
logger.info(`Workspace is now the default: ${getWorkspaceDir()}.`);
|
|
1476
|
+
const running = readState();
|
|
1477
|
+
if (running && liveNodeCount(running) > 0) {
|
|
1478
|
+
logger.warn('A cluster is running — restart it for the new workspace to take effect.');
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1426
1483
|
function showConfig() {
|
|
1427
1484
|
const cfg = readConfig();
|
|
1428
1485
|
console.log('Nano plugin configuration:');
|
|
1429
1486
|
console.log('');
|
|
1430
1487
|
console.log(` state home ${getStateHome()}`);
|
|
1431
|
-
console.log(` binary ${cfg.binary || '(auto-detect: $NANOBPMN_BINARY or repo build)'}`);
|
|
1488
|
+
console.log(` binary ${cfg.binary || '(auto-detect: $NANOBPMN_BINARY, managed platform package, or repo build)'}`);
|
|
1432
1489
|
const bundled = readBundledBinaryInfo();
|
|
1433
1490
|
if (bundled) {
|
|
1434
1491
|
const at = bundled.commit && bundled.commit !== 'unknown' ? ` (${bundled.commit})` : '';
|
|
@@ -1441,6 +1498,7 @@ function showConfig() {
|
|
|
1441
1498
|
console.log(` config file ${getConfigFile()}`);
|
|
1442
1499
|
console.log('');
|
|
1443
1500
|
console.log(' Change with: c8ctl nano set bin <path> | c8ctl nano set model-dir <path>');
|
|
1501
|
+
console.log(' Clear with: c8ctl nano unset bin | c8ctl nano unset model-dir');
|
|
1444
1502
|
}
|
|
1445
1503
|
|
|
1446
1504
|
// ---------------------------------------------------------------------------
|
|
@@ -2237,14 +2295,9 @@ function makeSecretResolver(kind) {
|
|
|
2237
2295
|
// Resolve the names a job needs (setup.secretRefs, plus the repo/PR credential
|
|
2238
2296
|
// when allowPr). Returns resolved values + a list of names that were missing so
|
|
2239
2297
|
// the caller can fail the job with a clear provisioning error.
|
|
2240
|
-
function resolveJobSecrets(resolver, envelope) {
|
|
2298
|
+
function resolveJobSecrets(resolver, envelope, { ghAuthToken = ghAuthTokenFromCli } = {}) {
|
|
2241
2299
|
const names = new Set();
|
|
2242
2300
|
for (const n of envelope.setup?.secretRefs || []) if (n) names.add(n);
|
|
2243
|
-
if (envelope.task?.allowPr) {
|
|
2244
|
-
const provider = envelope.repository?.provider || 'github';
|
|
2245
|
-
const authRef = envelope.repository?.authRef || (provider === 'github' ? 'GITHUB_TOKEN' : undefined);
|
|
2246
|
-
if (authRef) names.add(authRef);
|
|
2247
|
-
}
|
|
2248
2301
|
const resolved = {};
|
|
2249
2302
|
const missing = [];
|
|
2250
2303
|
for (const name of names) {
|
|
@@ -2252,6 +2305,34 @@ function resolveJobSecrets(resolver, envelope) {
|
|
|
2252
2305
|
if (v === undefined) missing.push(name);
|
|
2253
2306
|
else resolved[name] = v;
|
|
2254
2307
|
}
|
|
2308
|
+
// The github clone/push credential is resolved with a gh-CLI fallback so a
|
|
2309
|
+
// default GITHUB_TOKEN isn't reported "missing" merely because it isn't in the
|
|
2310
|
+
// env when `gh auth login` provides it. A custom authRef stays strict.
|
|
2311
|
+
if (envelope.task?.allowPr) {
|
|
2312
|
+
const provider = envelope.repository?.provider || 'github';
|
|
2313
|
+
const authRef = envelope.repository?.authRef;
|
|
2314
|
+
const ref = normalizeAuthRef(authRef);
|
|
2315
|
+
if (ref.kind === 'invalid') {
|
|
2316
|
+
// A present-but-blank authRef is a misconfiguration: surface it as missing
|
|
2317
|
+
// so provisioning sheds rather than silently borrowing the default/gh token.
|
|
2318
|
+
if (!missing.includes('repository.authRef')) missing.push('repository.authRef');
|
|
2319
|
+
} else {
|
|
2320
|
+
const ghAuthRef = ref.kind === 'custom'
|
|
2321
|
+
? ref.name
|
|
2322
|
+
: (provider === 'github' ? 'GITHUB_TOKEN' : undefined);
|
|
2323
|
+
if (ghAuthRef) {
|
|
2324
|
+
names.add(ghAuthRef);
|
|
2325
|
+
const token = githubCloneToken({ provider, authRef, secretResolver: resolver, ghAuthToken });
|
|
2326
|
+
const missingIdx = missing.indexOf(ghAuthRef);
|
|
2327
|
+
if (token) {
|
|
2328
|
+
resolved[ghAuthRef] = token;
|
|
2329
|
+
if (missingIdx !== -1) missing.splice(missingIdx, 1);
|
|
2330
|
+
} else if (missingIdx === -1) {
|
|
2331
|
+
missing.push(ghAuthRef);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2255
2336
|
return { resolved, missing, names: [...names] };
|
|
2256
2337
|
}
|
|
2257
2338
|
|
|
@@ -2402,6 +2483,82 @@ function credArgs() {
|
|
|
2402
2483
|
return ['-c', 'credential.helper='];
|
|
2403
2484
|
}
|
|
2404
2485
|
|
|
2486
|
+
// Fall back to the `gh` CLI's stored credential when GITHUB_TOKEN is not exported
|
|
2487
|
+
// to the env. Most interactive setups authenticate with `gh auth login` (keychain)
|
|
2488
|
+
// rather than an env var, so an env-only secret resolver yields no token and a
|
|
2489
|
+
// private/internal clone fails with "could not read Username". Best effort: returns
|
|
2490
|
+
// a trimmed token, or null when gh is missing / not logged in. The token is fed to
|
|
2491
|
+
// git via GIT_ASKPASS only (never argv/URL/helper), preserving the ephemeral-token
|
|
2492
|
+
// guarantee.
|
|
2493
|
+
// Memoized for the process lifetime: this is a synchronous spawnSync (up to a
|
|
2494
|
+
// 10s timeout) that can be reached per job, and jobs may run concurrently
|
|
2495
|
+
// (maxParallelJobs > 1), so consult the CLI at most once per worker run rather
|
|
2496
|
+
// than blocking every handler. A sentinel distinguishes "not yet computed" from
|
|
2497
|
+
// a cached null (gh missing / not logged in).
|
|
2498
|
+
//
|
|
2499
|
+
// Memoization alone still lets the *first* job pay the synchronous spawn on the
|
|
2500
|
+
// event loop, stalling any sibling handlers (and lock-extension heartbeats) for
|
|
2501
|
+
// up to the timeout. So `nano work` primes this cache once at startup via
|
|
2502
|
+
// `primeGhAuthToken()` — before the poll loop — moving the one unavoidable
|
|
2503
|
+
// blocking spawn off the job-handling path entirely. Any later call is a warm
|
|
2504
|
+
// cache hit; the memoization here is the safety net for paths that never primed.
|
|
2505
|
+
const GH_AUTH_TOKEN_UNSET = Symbol('gh-auth-token-unset');
|
|
2506
|
+
let ghAuthTokenCache = GH_AUTH_TOKEN_UNSET;
|
|
2507
|
+
function ghAuthTokenFromCli() {
|
|
2508
|
+
if (ghAuthTokenCache !== GH_AUTH_TOKEN_UNSET) return ghAuthTokenCache;
|
|
2509
|
+
let token = null;
|
|
2510
|
+
try {
|
|
2511
|
+
const r = spawnSync('gh', ['auth', 'token'], { encoding: 'utf8', timeout: 10_000 });
|
|
2512
|
+
const tok = r.status === 0 ? (r.stdout || '').trim() : '';
|
|
2513
|
+
token = tok || null;
|
|
2514
|
+
} catch {
|
|
2515
|
+
token = null;
|
|
2516
|
+
}
|
|
2517
|
+
ghAuthTokenCache = token;
|
|
2518
|
+
return token;
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
// Warm the gh-token cache once, off the job-handling path. Safe to call any
|
|
2522
|
+
// number of times: the first call performs the (possibly blocking) lookup, the
|
|
2523
|
+
// rest are cache hits. Returns true once the cache is populated.
|
|
2524
|
+
function primeGhAuthToken() {
|
|
2525
|
+
ghAuthTokenFromCli();
|
|
2526
|
+
return ghAuthTokenCache !== GH_AUTH_TOKEN_UNSET;
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
// Normalize a repository authRef into one of three intents. Trimming matters so
|
|
2530
|
+
// a present-but-blank authRef ('' or whitespace) is treated as a misconfiguration
|
|
2531
|
+
// rather than "absent": absence enables the default/gh fallback, but a blank
|
|
2532
|
+
// custom ref must NOT silently borrow the operator's gh login.
|
|
2533
|
+
// { kind: 'default' } no custom authRef configured (undefined/null)
|
|
2534
|
+
// { kind: 'custom', name } a non-empty custom authRef (strict)
|
|
2535
|
+
// { kind: 'invalid' } authRef present but blank (config error)
|
|
2536
|
+
function normalizeAuthRef(authRef) {
|
|
2537
|
+
if (authRef === undefined || authRef === null) return { kind: 'default' };
|
|
2538
|
+
const trimmed = String(authRef).trim();
|
|
2539
|
+
if (trimmed === '') return { kind: 'invalid' };
|
|
2540
|
+
return { kind: 'custom', name: trimmed };
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
// Resolve the github clone/push credential. The default credential (env
|
|
2544
|
+
// GITHUB_TOKEN) falls back to the gh CLI's stored token so `gh auth login`
|
|
2545
|
+
// setups work without exporting GITHUB_TOKEN. A custom `authRef` is honored
|
|
2546
|
+
// strictly (env/secret resolver only, no gh fallback) so a misconfigured named
|
|
2547
|
+
// secret surfaces as missing rather than silently borrowing the operator's gh
|
|
2548
|
+
// login. An authRef that is present but blank is a misconfiguration and yields no
|
|
2549
|
+
// token (never the gh fallback). `ghAuthToken` is injectable for testing.
|
|
2550
|
+
// Returns a token or null.
|
|
2551
|
+
function githubCloneToken({ provider, authRef, secretResolver, ghAuthToken = ghAuthTokenFromCli }) {
|
|
2552
|
+
const prov = provider || 'github';
|
|
2553
|
+
const ref = normalizeAuthRef(authRef);
|
|
2554
|
+
if (ref.kind === 'invalid') return null;
|
|
2555
|
+
const usesDefault = prov === 'github' && ref.kind === 'default';
|
|
2556
|
+
const name = ref.kind === 'custom' ? ref.name : (prov === 'github' ? 'GITHUB_TOKEN' : null);
|
|
2557
|
+
let token = name ? (secretResolver.resolve(name) || null) : null;
|
|
2558
|
+
if (!token && usesDefault) token = ghAuthToken() || null;
|
|
2559
|
+
return token;
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2405
2562
|
// Clone repo into <runDir>/workspace and check out / create the working branch.
|
|
2406
2563
|
// Returns { workspaceDir, gitEnv, startSha, workingBranch, remote }. Throws a
|
|
2407
2564
|
// ProvisionError (token-redacted) on any git failure so the caller can shed.
|
|
@@ -3136,6 +3293,12 @@ async function workAgent(req, flags) {
|
|
|
3136
3293
|
const extraNote = extraJobTypes.length > 0 ? ` (${extraJobTypes.length} via --job-type)` : '';
|
|
3137
3294
|
logger.info(` listening on ${jobTypes.length} job type(s)${extraNote}: ${jobTypes.join(' ')}`);
|
|
3138
3295
|
logger.info(` max parallel: ${maxParallelJobs}; recovery window: ${recoveryWindowMs}ms; idle timeout: ${idleTimeoutMs}ms; hard cap: ${hardCapMs > 0 ? `${hardCapMs}ms` : 'off'}; poll timeout: ${pollTimeoutMs}ms`);
|
|
3296
|
+
// Warm the gh-token cache now, off the job-handling path: githubCloneToken()
|
|
3297
|
+
// may consult `gh auth token` (a synchronous spawn, up to 10s) as its default
|
|
3298
|
+
// credential fallback, and doing that inside a job handler would stall sibling
|
|
3299
|
+
// handlers + lock heartbeats when maxParallelJobs > 1. Priming here pays that
|
|
3300
|
+
// cost once at startup so every later lookup is a warm cache hit.
|
|
3301
|
+
primeGhAuthToken();
|
|
3139
3302
|
logger.info('Polling for work — press Ctrl-C to stop.');
|
|
3140
3303
|
|
|
3141
3304
|
// When launched under the supervisor, report per-job activity — which job(s)
|
|
@@ -3237,8 +3400,8 @@ async function workAgent(req, flags) {
|
|
|
3237
3400
|
let repoToken = null;
|
|
3238
3401
|
if (hasRepo) {
|
|
3239
3402
|
const provider = envelope.repository.provider || 'github';
|
|
3240
|
-
const authRef = envelope.repository.authRef
|
|
3241
|
-
|
|
3403
|
+
const authRef = envelope.repository.authRef;
|
|
3404
|
+
repoToken = githubCloneToken({ provider, authRef, secretResolver }); // absent → anonymous clone
|
|
3242
3405
|
try {
|
|
3243
3406
|
mkdirSync(agentRunsRoot(), { recursive: true });
|
|
3244
3407
|
runDir = mkdtempSync(join(agentRunsRoot(), 'run-'));
|
|
@@ -6121,6 +6284,7 @@ function parseProcessosRequest(args, flags) {
|
|
|
6121
6284
|
// Internal helpers exported for tests/tooling only. c8ctl consumes just
|
|
6122
6285
|
// `metadata` and `commands`; these named exports are inert to it.
|
|
6123
6286
|
export { resolveBinary, findBinary, launcherEnvMarkers };
|
|
6287
|
+
export { setConfig, unsetConfig, readConfig, writeConfig, getConfigFile, SETTING_ALIASES };
|
|
6124
6288
|
export { buildNpmInvocation };
|
|
6125
6289
|
export {
|
|
6126
6290
|
webConsoleUrl,
|
|
@@ -6158,6 +6322,9 @@ export {
|
|
|
6158
6322
|
reconcileAgentPr,
|
|
6159
6323
|
reapAgentRunDirs,
|
|
6160
6324
|
authUrl,
|
|
6325
|
+
githubCloneToken,
|
|
6326
|
+
ghAuthTokenFromCli,
|
|
6327
|
+
primeGhAuthToken,
|
|
6161
6328
|
redactToken,
|
|
6162
6329
|
agentRunsRoot,
|
|
6163
6330
|
ProvisionError,
|
|
@@ -6231,6 +6398,7 @@ export const metadata = {
|
|
|
6231
6398
|
{ command: 'c8ctl nano restart --purge', description: 'Restart the cluster from a clean slate (delete engine data)' },
|
|
6232
6399
|
{ command: 'c8ctl nano clean', description: 'Wipe journal/data + logs on disk (keeps models/workers)' },
|
|
6233
6400
|
{ command: 'c8ctl nano set bin <path>', description: 'Set the nanobpmn server binary path' },
|
|
6401
|
+
{ command: 'c8ctl nano unset bin', description: 'Clear a custom binary path and return to the managed/release binary' },
|
|
6234
6402
|
{ command: 'c8ctl nano set model-dir <path>', description: 'Set the workspace dir (models + workers)' },
|
|
6235
6403
|
{ command: 'c8ctl nano config', description: 'Show current plugin configuration and paths' },
|
|
6236
6404
|
{ command: 'c8ctl nano update', description: 'Pull the latest published nano release (re-installs via npm)' },
|
|
@@ -6360,6 +6528,9 @@ export const commands = {
|
|
|
6360
6528
|
case 'set':
|
|
6361
6529
|
setConfig(req);
|
|
6362
6530
|
break;
|
|
6531
|
+
case 'unset':
|
|
6532
|
+
unsetConfig(req);
|
|
6533
|
+
break;
|
|
6363
6534
|
case 'config':
|
|
6364
6535
|
showConfig();
|
|
6365
6536
|
break;
|
|
@@ -6464,6 +6635,7 @@ function printUsage() {
|
|
|
6464
6635
|
console.log(' c8ctl nano restart [<nodes>] [--purge] ...');
|
|
6465
6636
|
console.log(' c8ctl nano clean [--workspace]');
|
|
6466
6637
|
console.log(' c8ctl nano set <bin|model-dir> <path>');
|
|
6638
|
+
console.log(' c8ctl nano unset <bin|model-dir>');
|
|
6467
6639
|
console.log(' c8ctl nano config');
|
|
6468
6640
|
console.log(' c8ctl nano update [--check]');
|
|
6469
6641
|
console.log(' c8ctl nano hire [--name <n>] [--rank <r>] [--command <c>] [--arg <switch> ...] [--model <m>] [--capabilities <a,b>] [--sandbox none|docker|podman] [--image <ref>] [--env NAME=VALUE ...] [--list]');
|
|
@@ -6481,6 +6653,7 @@ function printUsage() {
|
|
|
6481
6653
|
console.log(' restart Stop then start');
|
|
6482
6654
|
console.log(' clean Wipe journal/data + logs on disk (keeps models/workers)');
|
|
6483
6655
|
console.log(' set Persist a setting: "bin <path>" or "model-dir <path>"');
|
|
6656
|
+
console.log(' unset Clear a setting ("bin" or "model-dir") back to its default');
|
|
6484
6657
|
console.log(' config Show current configuration and on-disk locations');
|
|
6485
6658
|
console.log(' update Pull the latest published nano release (--check to only report)');
|
|
6486
6659
|
console.log(' hire Create a CLI agent worker profile (rank + capabilities → job-type matrix)');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c8ctl-plugin-nano",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.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.26.1",
|
|
51
|
+
"@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.26.1",
|
|
52
|
+
"@nanobpm/c8ctl-plugin-nano-linux-x64": "1.26.1",
|
|
53
|
+
"@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.26.1",
|
|
54
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.26.1",
|
|
55
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.26.1",
|
|
56
|
+
"@nanobpm/c8ctl-plugin-nano-win32-x64": "1.26.1"
|
|
57
57
|
}
|
|
58
58
|
}
|