c8ctl-plugin-nano 1.36.0 → 1.36.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.
Files changed (2) hide show
  1. package/c8ctl-plugin.js +53 -6
  2. package/package.json +8 -8
package/c8ctl-plugin.js CHANGED
@@ -2408,11 +2408,16 @@ function sameOrigin(a, b) {
2408
2408
  }
2409
2409
  }
2410
2410
 
2411
- function resolveBrokerRestConfig(env = process.env) {
2411
+ function resolveBrokerRestConfig(env = process.env, opts = {}) {
2412
2412
  // readConfig() swallows parse/IO errors and never throws (returns {}), so no
2413
2413
  // local try/catch is needed here.
2414
2414
  const cfg = readConfig() || {};
2415
+ // `opts.baseUrl` lets a caller pin the effective base (e.g. the active c8ctl
2416
+ // profile's REST address — see resolveAutoRestConfig) while still running it
2417
+ // through the SAME token same-origin gate below, so the token logic stays
2418
+ // single-sourced (never duplicated per call site).
2415
2419
  const baseUrl =
2420
+ opts.baseUrl ||
2416
2421
  env.NANO_REST_URL ||
2417
2422
  env.NANO_BASE_URL ||
2418
2423
  cfg.nanoUrl ||
@@ -2440,6 +2445,33 @@ function resolveBrokerRestConfig(env = process.env) {
2440
2445
  return { baseUrl, token };
2441
2446
  }
2442
2447
 
2448
+ // Resolve the C8 REST config the `--auto` engine-read reader is built from.
2449
+ // This is the job-type-read analogue of resolveLinkedPromptSource: an explicit
2450
+ // NANO_REST_URL / NANO_BASE_URL / cfg.nanoUrl override still wins (operator
2451
+ // escape hatch), but with NONE of those set the base is derived from the SAME
2452
+ // c8ctl client that activates jobs (its getConfig().restAddress) rather than the
2453
+ // localhost default — so a worker that can activate jobs against a profile
2454
+ // engine can also read the deployed job types from it. Without this, an `--auto`
2455
+ // worker on an active remote profile reads from http://localhost:8080, finds no
2456
+ // engine, discovers 0 job types, and crash-loops (jwulf/c8ctl-plugin-nano#93).
2457
+ // Falls back to resolveBrokerRestConfig's localhost default only when the client
2458
+ // exposes no usable restAddress. The token same-origin gate lives in
2459
+ // resolveBrokerRestConfig (re-run against the profile base), never duplicated.
2460
+ function resolveAutoRestConfig(camunda, env = process.env) {
2461
+ const cfg = readConfig() || {};
2462
+ const hasExplicitBase = Boolean(env.NANO_REST_URL || env.NANO_BASE_URL || cfg.nanoUrl);
2463
+ if (!hasExplicitBase && camunda && typeof camunda.getConfig === 'function') {
2464
+ let profileBase = '';
2465
+ try {
2466
+ profileBase = normalizeRestBase(camunda.getConfig()?.restAddress);
2467
+ } catch {
2468
+ // ignore — degrade to the resolveBrokerRestConfig (localhost) default below
2469
+ }
2470
+ if (profileBase) return resolveBrokerRestConfig(env, { baseUrl: profileBase });
2471
+ }
2472
+ return resolveBrokerRestConfig(env);
2473
+ }
2474
+
2443
2475
  // ---------------------------------------------------------------------------
2444
2476
  // `nano work --auto`: zero-config engine-read enrolment (issue #66).
2445
2477
  //
@@ -4558,10 +4590,14 @@ async function workAgent(req, flags) {
4558
4590
  }
4559
4591
  const camunda = globalThis.c8ctl.createClient();
4560
4592
 
4561
- // Broker REST endpoint for live linked-resource prompts (issue #63) the same
4562
- // nano endpoint this worker already talks to. Resolved once at startup, and
4563
- // reused as the C8 REST source for `--auto`'s engine-read enrolment.
4564
- const restConfig = resolveBrokerRestConfig();
4593
+ // Broker REST endpoint for live linked-resource prompts (issue #63) and the
4594
+ // C8 REST source for `--auto`'s engine-read enrolment. Derived from the SAME
4595
+ // client that activates jobs (its profile REST address) when no explicit
4596
+ // NANO_REST_URL/NANO_BASE_URL/cfg.nanoUrl override is set — so a worker that
4597
+ // can activate jobs against the active profile engine also reads job types
4598
+ // from it, instead of a localhost default that crash-loops when nothing is
4599
+ // listening on :8080 (jwulf/c8ctl-plugin-nano#93). Resolved once at startup.
4600
+ const restConfig = resolveAutoRestConfig(camunda);
4565
4601
 
4566
4602
  // The desired job-type set. In `--auto` it is engine-read (∪ any --job-type
4567
4603
  // extras); otherwise it is the rank×capability matrix (∪ extras). The initial
@@ -5183,7 +5219,16 @@ async function workAgent(req, flags) {
5183
5219
  if (inFlightReconcile) return;
5184
5220
  reconcile().catch((err) => logger.warn(`--auto reconcile failed: ${err?.message || err}`));
5185
5221
  }, AUTO_POLL_INTERVAL_MS);
5186
- if (typeof autoPollTimer.unref === 'function') autoPollTimer.unref();
5222
+ // Deliberately REF'd (unlike the reaper/run-dir hygiene timers, which are
5223
+ // unref'd): in `--auto` this poll IS the retry loop, and it must keep the
5224
+ // process alive even with zero pollers. When the INITIAL engine read fails
5225
+ // (transient miss, or the engine isn't up yet) the worker registers 0
5226
+ // pollers; nothing else holds the event loop open (the SDK client with no
5227
+ // job workers doesn't, and the hygiene timers are unref'd), so an unref'd
5228
+ // poll timer would let the process exit 0 — the observed crash-loop under a
5229
+ // supervisor (jwulf/c8ctl-plugin-nano#93). Keeping it ref'd makes the worker
5230
+ // stay up and re-read on the next poll, exactly as the initial-read warning
5231
+ // promises. Shutdown clears it (clearInterval), so Ctrl-C/SIGTERM still exit.
5187
5232
  } else {
5188
5233
  // `watchFile` (polling stat) is deliberate over `fs.watch`: it survives the
5189
5234
  // atomic temp+rename that `writeConfig` does (fs.watch would rebind to the old
@@ -8547,6 +8592,7 @@ export {
8547
8592
  parseLinkedResources,
8548
8593
  pickLinkedResource,
8549
8594
  resolveBrokerRestConfig,
8595
+ resolveAutoRestConfig,
8550
8596
  resourceContentUrl,
8551
8597
  fetchLinkedResourceContent,
8552
8598
  resolveLinkedPrompt,
@@ -8602,6 +8648,7 @@ export {
8602
8648
  scanAgentTaskLeaves,
8603
8649
  readDeployedAgentJobTypes,
8604
8650
  resolveAutoJobTypes,
8651
+ workAgent,
8605
8652
  derivePollTimeoutMs,
8606
8653
  AGENT_TASK_NS,
8607
8654
  AGENT_RESULT_KEY,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c8ctl-plugin-nano",
3
- "version": "1.36.0",
3
+ "version": "1.36.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",
@@ -57,12 +57,12 @@
57
57
  },
58
58
  "optionalDependencies": {
59
59
  "node-pty": "^1.0.0",
60
- "@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.36.0",
61
- "@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.36.0",
62
- "@nanobpm/c8ctl-plugin-nano-linux-x64": "1.36.0",
63
- "@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.36.0",
64
- "@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.36.0",
65
- "@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.36.0",
66
- "@nanobpm/c8ctl-plugin-nano-win32-x64": "1.36.0"
60
+ "@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.36.1",
61
+ "@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.36.1",
62
+ "@nanobpm/c8ctl-plugin-nano-linux-x64": "1.36.1",
63
+ "@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.36.1",
64
+ "@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.36.1",
65
+ "@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.36.1",
66
+ "@nanobpm/c8ctl-plugin-nano-win32-x64": "1.36.1"
67
67
  }
68
68
  }