c8ctl-plugin-nano 1.13.1 → 1.14.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/c8ctl-plugin.js +57 -1
- package/package.json +8 -8
package/c8ctl-plugin.js
CHANGED
|
@@ -120,6 +120,15 @@ const PROCESSOS_STATE_FILE = 'processos.json';
|
|
|
120
120
|
const PROCESSOS_DEFAULT_PORT = 8090;
|
|
121
121
|
const DEFAULT_NANO_URL = 'http://localhost:8080';
|
|
122
122
|
|
|
123
|
+
// Guided-journey deep links (ADR 0049 §2). The console renders a first-run tour
|
|
124
|
+
// chosen by `…/console?tour=<journeyId>`, and the *command the user ran* already
|
|
125
|
+
// encodes the persona — so the CLI bakes the journey into the console URL it
|
|
126
|
+
// prints rather than making the console guess. These ids are a contract with the
|
|
127
|
+
// console (`console/src/lib/tour`): an unknown id is silently ignored, so they
|
|
128
|
+
// are asserted verbatim in the tests.
|
|
129
|
+
const JOURNEY_LOCALDEV = 'localdev';
|
|
130
|
+
const JOURNEY_AGENTIC_AUTHOR = 'agentic-author';
|
|
131
|
+
|
|
123
132
|
// Passive update notifier (npm-style): refresh the latest published version
|
|
124
133
|
// from the registry in a detached background process at most once per day, and
|
|
125
134
|
// surface a one-line "update available" notice at most once per day. Never
|
|
@@ -449,6 +458,30 @@ function liveNodeCount(state) {
|
|
|
449
458
|
return state.nodes.filter((n) => isPidAlive(n.pid)).length;
|
|
450
459
|
}
|
|
451
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Compose a web-console URL for a node's base URL, optionally carrying a guided
|
|
463
|
+
* journey (`?tour=<id>`, ADR 0049 §2). Never hardcodes a port: `baseUrl` is the
|
|
464
|
+
* real address the node came up on.
|
|
465
|
+
*/
|
|
466
|
+
function webConsoleUrl(baseUrl, journey) {
|
|
467
|
+
const base = `${baseUrl}/console`;
|
|
468
|
+
return journey ? `${base}?tour=${encodeURIComponent(journey)}` : base;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Base URL of the running cluster the user would actually open: the first
|
|
473
|
+
* still-alive node, falling back to the first recorded node, then to the default
|
|
474
|
+
* gateway URL when no cluster has been started. Used by hire/work, which surface
|
|
475
|
+
* a console link for the agentic-SDLC journey.
|
|
476
|
+
*/
|
|
477
|
+
function runningConsoleBaseUrl(state = readState()) {
|
|
478
|
+
if (state && Array.isArray(state.nodes) && state.nodes.length > 0) {
|
|
479
|
+
const alive = state.nodes.find((n) => isPidAlive(n.pid));
|
|
480
|
+
return (alive || state.nodes[0]).url;
|
|
481
|
+
}
|
|
482
|
+
return DEFAULT_NANO_URL;
|
|
483
|
+
}
|
|
484
|
+
|
|
452
485
|
/** Probe a node's always-on GET /v2/topology endpoint for reachability. */
|
|
453
486
|
async function probeHealthy(url) {
|
|
454
487
|
const controller = new AbortController();
|
|
@@ -828,7 +861,7 @@ async function printSummary(state) {
|
|
|
828
861
|
console.log(` REST API ${entry.url}/v2`);
|
|
829
862
|
console.log(` Topology ${entry.url}/v2/topology`);
|
|
830
863
|
if (hasConsole) {
|
|
831
|
-
console.log(` Web console ${entry.url}
|
|
864
|
+
console.log(` Web console ${webConsoleUrl(entry.url, JOURNEY_LOCALDEV)}`);
|
|
832
865
|
console.log(` User guide ${entry.url}/docs`);
|
|
833
866
|
}
|
|
834
867
|
if (state.workspaceDir) {
|
|
@@ -1119,6 +1152,20 @@ function logsCluster(req) {
|
|
|
1119
1152
|
|
|
1120
1153
|
function controlNode(req, { signal, verb, paused }) {
|
|
1121
1154
|
const logger = getLogger();
|
|
1155
|
+
|
|
1156
|
+
// pause/resume rely on SIGSTOP/SIGCONT, which are POSIX-only. On Windows
|
|
1157
|
+
// Node throws "Unknown signal: SIGSTOP" from process.kill, so fail fast with
|
|
1158
|
+
// a clear message instead of a raw crash (see nano-bpm#390).
|
|
1159
|
+
if (process.platform === 'win32') {
|
|
1160
|
+
logger.error(
|
|
1161
|
+
`"c8ctl nano ${verb}" isn't supported on Windows yet — it relies on ` +
|
|
1162
|
+
`SIGSTOP/SIGCONT, which Windows doesn't have. To simulate a node ` +
|
|
1163
|
+
`failing and recovering, use "c8ctl nano stop <id>" then ` +
|
|
1164
|
+
`"c8ctl nano start" instead.`,
|
|
1165
|
+
);
|
|
1166
|
+
process.exit(1);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1122
1169
|
const state = readState();
|
|
1123
1170
|
|
|
1124
1171
|
if (!state || !Array.isArray(state.nodes) || state.nodes.length === 0) {
|
|
@@ -1586,6 +1633,7 @@ async function hireWorker(req, flags) {
|
|
|
1586
1633
|
if (envKeys.length > 0) logger.info(` env: ${envKeys.join(', ')}`);
|
|
1587
1634
|
logger.info(` job types (${matrix.length}): ${matrix.join(' ')}`);
|
|
1588
1635
|
logger.info(`Put it to work with: c8ctl nano work ${name}`);
|
|
1636
|
+
logger.info(`Open the console: ${webConsoleUrl(runningConsoleBaseUrl(), JOURNEY_AGENTIC_AUTHOR)}`);
|
|
1589
1637
|
}
|
|
1590
1638
|
|
|
1591
1639
|
/**
|
|
@@ -2619,6 +2667,7 @@ async function workAgent(req, flags) {
|
|
|
2619
2667
|
if (profileEnvKeys.length > 0) logger.info(` harness env: ${profileEnvKeys.join(', ')}`);
|
|
2620
2668
|
logger.info(` listening on ${matrix.length} job type(s): ${matrix.join(' ')}`);
|
|
2621
2669
|
logger.info(` max parallel: ${maxParallelJobs}; job timeout: ${jobTimeoutMs}ms`);
|
|
2670
|
+
logger.info(` console: ${webConsoleUrl(runningConsoleBaseUrl(), JOURNEY_AGENTIC_AUTHOR)}`);
|
|
2622
2671
|
logger.info('Polling for work — press Ctrl-C to stop.');
|
|
2623
2672
|
|
|
2624
2673
|
const workers = matrix.map((jobType) =>
|
|
@@ -4149,6 +4198,13 @@ function parseProcessosRequest(args, flags) {
|
|
|
4149
4198
|
// `metadata` and `commands`; these named exports are inert to it.
|
|
4150
4199
|
export { resolveBinary, findBinary, launcherEnvMarkers };
|
|
4151
4200
|
export { buildNpmInvocation };
|
|
4201
|
+
export {
|
|
4202
|
+
webConsoleUrl,
|
|
4203
|
+
runningConsoleBaseUrl,
|
|
4204
|
+
hireWorker,
|
|
4205
|
+
JOURNEY_LOCALDEV,
|
|
4206
|
+
JOURNEY_AGENTIC_AUTHOR,
|
|
4207
|
+
};
|
|
4152
4208
|
export {
|
|
4153
4209
|
normalizeTaskEnvelope,
|
|
4154
4210
|
collectEnvelopeFrom,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c8ctl-plugin-nano",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.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.14.0",
|
|
53
|
+
"@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.14.0",
|
|
54
|
+
"@nanobpm/c8ctl-plugin-nano-linux-x64": "1.14.0",
|
|
55
|
+
"@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.14.0",
|
|
56
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.14.0",
|
|
57
|
+
"@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.14.0",
|
|
58
|
+
"@nanobpm/c8ctl-plugin-nano-win32-x64": "1.14.0"
|
|
59
59
|
}
|
|
60
60
|
}
|