substrate-ai 0.19.28 → 0.19.30

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/dist/cli/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot } from "../health-M0iCuP26.js";
2
+ import { FileStateStore, RunManifest, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveRunManifest } from "../health-DKallkoo.js";
3
3
  import { createLogger } from "../logger-KeHncl-f.js";
4
4
  import { createEventBus } from "../helpers-CElYrONe.js";
5
5
  import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, GlobalSettingsSchema, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-R0W4ofKv.js";
6
6
  import "../adapter-registry-DXLMTmfD.js";
7
- import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-DabSV2xH.js";
7
+ import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-B0Pe5kol.js";
8
8
  import "../errors-BJRMJyGb.js";
9
9
  import "../routing-CcBOCuC9.js";
10
10
  import "../decisions-C0pz9Clx.js";
@@ -21,6 +21,7 @@ import * as path$3 from "node:path";
21
21
  import * as path$2 from "node:path";
22
22
  import * as path$1 from "node:path";
23
23
  import { join as join$1 } from "node:path";
24
+ import { randomUUID } from "node:crypto";
24
25
  import { z } from "zod";
25
26
  import * as fs from "node:fs/promises";
26
27
  import { access as access$1, readFile as readFile$1, readdir as readdir$1 } from "node:fs/promises";
@@ -29,7 +30,7 @@ import { homedir } from "os";
29
30
  import { createRequire } from "node:module";
30
31
  import { fileURLToPath as fileURLToPath$1 } from "node:url";
31
32
  import { createInterface } from "node:readline";
32
- import { randomUUID } from "crypto";
33
+ import { randomUUID as randomUUID$1 } from "crypto";
33
34
  import { createInterface as createInterface$1 } from "readline";
34
35
 
35
36
  //#region packages/core/dist/git/git-utils.js
@@ -2761,6 +2762,23 @@ async function runResumeAction(options) {
2761
2762
  if (Array.isArray(config.explicitStories) && config.explicitStories.length > 0) scopedStories = config.explicitStories;
2762
2763
  } catch {}
2763
2764
  const dbDir = dbPath.replace("/substrate.db", "");
2765
+ if (options.stories === void 0 || options.stories.length === 0) {
2766
+ const { manifest: resolvedManifest } = await resolveRunManifest(dbRoot, runId);
2767
+ if (resolvedManifest !== null) try {
2768
+ const manifestData = await resolvedManifest.read();
2769
+ const manifestStories = manifestData.cli_flags["stories"] ?? manifestData.story_scope;
2770
+ if (Array.isArray(manifestStories) && manifestStories.length > 0) {
2771
+ scopedStories = manifestStories;
2772
+ logger$13.debug({
2773
+ runId,
2774
+ stories: scopedStories
2775
+ }, "resume scope loaded from manifest");
2776
+ }
2777
+ } catch {
2778
+ logger$13.debug({ runId }, "manifest read failed in resume — using legacy config_json scope");
2779
+ }
2780
+ else logger$13.debug({ runId }, "Run manifest not found for scope preservation — using legacy config_json scope");
2781
+ }
2764
2782
  return runFullPipelineFromPhase({
2765
2783
  packName,
2766
2784
  packPath,
@@ -3134,6 +3152,55 @@ function registerResumeCommand(program, _version = "0.0.0", projectRoot = proces
3134
3152
  //#endregion
3135
3153
  //#region src/cli/commands/status.ts
3136
3154
  const logger$12 = createLogger("status-cmd");
3155
+ /**
3156
+ * Map a manifest per-story status string to the appropriate WorkGraphCounts bucket.
3157
+ * Unknown strings are treated as `inProgress` (safe default).
3158
+ */
3159
+ function manifestStatusToWorkGraphBucket(status) {
3160
+ switch (status) {
3161
+ case "complete": return "complete";
3162
+ case "escalated": return "escalated";
3163
+ case "failed":
3164
+ case "verification-failed": return "failed";
3165
+ case "dispatched":
3166
+ case "in-review":
3167
+ case "recovered": return "inProgress";
3168
+ case "gated":
3169
+ case "pending": return "ready";
3170
+ default: return "inProgress";
3171
+ }
3172
+ }
3173
+ /**
3174
+ * Build a WorkGraphSummary from manifest `per_story_state`.
3175
+ * readyStories and blockedStories are left empty — manifest does not carry
3176
+ * dependency-graph detail (only status counts).
3177
+ */
3178
+ function buildWorkGraphFromManifest(perStoryState) {
3179
+ const counts = {
3180
+ ready: 0,
3181
+ blocked: 0,
3182
+ inProgress: 0,
3183
+ complete: 0,
3184
+ escalated: 0,
3185
+ failed: 0
3186
+ };
3187
+ for (const entry of Object.values(perStoryState)) {
3188
+ const bucket = manifestStatusToWorkGraphBucket(entry.status);
3189
+ counts[bucket]++;
3190
+ }
3191
+ return {
3192
+ summary: {
3193
+ ready: counts.ready,
3194
+ blocked: counts.blocked,
3195
+ inProgress: counts.inProgress,
3196
+ complete: counts.complete,
3197
+ escalated: counts.escalated,
3198
+ failed: counts.failed
3199
+ },
3200
+ readyStories: [],
3201
+ blockedStories: []
3202
+ };
3203
+ }
3137
3204
  async function runStatusAction(options) {
3138
3205
  const { outputFormat, runId, projectRoot, stateStore, history } = options;
3139
3206
  if (history === true) {
@@ -3176,8 +3243,29 @@ async function runStatusAction(options) {
3176
3243
  });
3177
3244
  try {
3178
3245
  await initSchema(adapter);
3246
+ let run;
3247
+ if (runId !== void 0 && runId !== "") run = await getPipelineRunById(adapter, runId);
3248
+ else {
3249
+ let currentRunId;
3250
+ try {
3251
+ const currentRunIdPath = join(dbRoot, ".substrate", "current-run-id");
3252
+ const content = readFileSync$1(currentRunIdPath, "utf-8").trim();
3253
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3254
+ if (UUID_RE.test(content)) currentRunId = content;
3255
+ } catch {}
3256
+ if (currentRunId !== void 0) run = await getPipelineRunById(adapter, currentRunId);
3257
+ if (run === void 0) run = await getLatestRun(adapter);
3258
+ }
3179
3259
  let workGraph;
3180
- try {
3260
+ const { manifest: resolvedManifest } = await resolveRunManifest(dbRoot, run?.id);
3261
+ if (resolvedManifest !== null) try {
3262
+ const manifestData = await resolvedManifest.read();
3263
+ workGraph = buildWorkGraphFromManifest(manifestData.per_story_state);
3264
+ logger$12.debug({ runId: run?.id }, "status: workGraph built from manifest per_story_state");
3265
+ } catch {
3266
+ logger$12.debug({ runId: run?.id }, "status: manifest read failed — falling back to wg_stories");
3267
+ }
3268
+ if (workGraph === void 0) try {
3181
3269
  const wgRepo = new WorkGraphRepository(adapter);
3182
3270
  const allStories = await adapter.query(`SELECT story_key, title, status FROM wg_stories`);
3183
3271
  if (allStories.length > 0) {
@@ -3214,21 +3302,8 @@ async function runStatusAction(options) {
3214
3302
  } catch (err) {
3215
3303
  logger$12.debug({ err }, "Work graph query failed, continuing without work graph data");
3216
3304
  }
3217
- let run;
3218
- if (runId !== void 0 && runId !== "") run = await getPipelineRunById(adapter, runId);
3219
- else {
3220
- let currentRunId;
3221
- try {
3222
- const currentRunIdPath = join(dbRoot, ".substrate", "current-run-id");
3223
- const content = readFileSync$1(currentRunIdPath, "utf-8").trim();
3224
- const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3225
- if (UUID_RE.test(content)) currentRunId = content;
3226
- } catch {}
3227
- if (currentRunId !== void 0) run = await getPipelineRunById(adapter, currentRunId);
3228
- if (run === void 0) run = await getLatestRun(adapter);
3229
- }
3230
3305
  if (run === void 0) {
3231
- const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-CVfyC7j0.js");
3306
+ const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-Bb5KxPlE.js");
3232
3307
  const substrateDirPath = join(projectRoot, ".substrate");
3233
3308
  const processInfo = inspectProcessTree$1({
3234
3309
  projectRoot,
@@ -3822,7 +3897,7 @@ async function runAmendAction(options) {
3822
3897
  }
3823
3898
  parentRunId = latestCompleted.id;
3824
3899
  }
3825
- const amendmentRunId = randomUUID();
3900
+ const amendmentRunId = randomUUID$1();
3826
3901
  let methodology = packName;
3827
3902
  try {
3828
3903
  const packLoader$1 = createPackLoader();
@@ -4044,6 +4119,7 @@ function registerAmendCommand(program, _version = "0.0.0", projectRoot = process
4044
4119
 
4045
4120
  //#endregion
4046
4121
  //#region src/cli/commands/supervisor.ts
4122
+ const supervisorLogger = createLogger("supervisor-cmd");
4047
4123
  function defaultSupervisorDeps() {
4048
4124
  return {
4049
4125
  getHealth: getAutoHealthData,
@@ -4370,7 +4446,10 @@ async function handleStallRecovery(health, state, config, deps, io) {
4370
4446
  };
4371
4447
  }
4372
4448
  const newRestartCount = state.restartCount + 1;
4373
- if (health.run_id !== null) await incrementRestarts(health.run_id, projectRoot);
4449
+ if (health.run_id !== null) {
4450
+ await incrementRestarts(health.run_id, projectRoot);
4451
+ RunManifest.open(health.run_id, join(projectRoot, ".substrate", "runs")).update({ restart_count: newRestartCount }).catch(() => {});
4452
+ }
4374
4453
  emitEvent({
4375
4454
  type: "supervisor:restart",
4376
4455
  run_id: health.run_id,
@@ -4379,7 +4458,13 @@ async function handleStallRecovery(health, state, config, deps, io) {
4379
4458
  log(`Supervisor: Restarting pipeline (attempt ${newRestartCount}/${maxRestarts})`);
4380
4459
  try {
4381
4460
  let scopedStories;
4382
- if (deps.getRunConfig !== void 0 && health.run_id !== null) try {
4461
+ if (health.run_id !== null) try {
4462
+ const manifest = RunManifest.open(health.run_id, projectRoot);
4463
+ const data = await manifest.read();
4464
+ const manifestStories = data?.cli_flags?.stories;
4465
+ if (Array.isArray(manifestStories) && manifestStories.length > 0) scopedStories = manifestStories;
4466
+ } catch {}
4467
+ if (scopedStories === void 0 && deps.getRunConfig !== void 0 && health.run_id !== null) try {
4383
4468
  const runConfig = await deps.getRunConfig(health.run_id, projectRoot);
4384
4469
  if (runConfig?.explicitStories !== void 0 && runConfig.explicitStories.length > 0) scopedStories = runConfig.explicitStories;
4385
4470
  } catch {}
@@ -4442,7 +4527,7 @@ async function handleStallRecovery(health, state, config, deps, io) {
4442
4527
  * 2 — max restarts exceeded (safety valve triggered)
4443
4528
  */
4444
4529
  async function runSupervisorAction(options, deps = {}) {
4445
- const { pollInterval, stallThreshold, maxRestarts, outputFormat, projectRoot, runId, pack, experiment, maxExperiments } = options;
4530
+ const { pollInterval, stallThreshold, maxRestarts, outputFormat, projectRoot, runId, pack, experiment, maxExperiments, force } = options;
4446
4531
  const resolvedDeps = {
4447
4532
  ...defaultSupervisorDeps(),
4448
4533
  ...deps
@@ -4455,6 +4540,62 @@ async function runSupervisorAction(options, deps = {}) {
4455
4540
  };
4456
4541
  let maxRestartsExhausted = false;
4457
4542
  const startTime = Date.now();
4543
+ const sessionId = randomUUID();
4544
+ let supervisorLock = null;
4545
+ /** Track whether process exit handlers have been registered for this supervisor. */
4546
+ let exitHandlersRegistered = false;
4547
+ /**
4548
+ * Register process.once exit handlers to release the lock on exit.
4549
+ * Called exactly once, after the first successful lock acquisition.
4550
+ * Using process.once (not process.on) per Story 52-2 spec.
4551
+ */
4552
+ function registerExitHandlers(lock) {
4553
+ if (exitHandlersRegistered) return;
4554
+ exitHandlersRegistered = true;
4555
+ process.once("exit", () => {
4556
+ lock.release().catch((e) => {
4557
+ supervisorLogger.debug({ error: e }, "lock release on exit failed");
4558
+ });
4559
+ });
4560
+ process.once("SIGTERM", () => {
4561
+ lock.release().then(() => process.exit(0)).catch(() => process.exit(1));
4562
+ });
4563
+ process.once("SIGINT", () => {
4564
+ lock.release().then(() => process.exit(0)).catch(() => process.exit(1));
4565
+ });
4566
+ }
4567
+ /**
4568
+ * Acquire the supervisor lock for a given run ID.
4569
+ * Non-fatal: logs and continues on failure so the supervisor can still
4570
+ * function in degraded mode without blocking the pipeline.
4571
+ */
4572
+ async function acquireLockForRun(targetRunId) {
4573
+ if (supervisorLock !== null) return;
4574
+ try {
4575
+ const runsDir = join(projectRoot, ".substrate", "runs");
4576
+ const manifest = RunManifest.open(targetRunId, runsDir);
4577
+ const lock = new SupervisorLock(targetRunId, manifest, supervisorLogger);
4578
+ await lock.acquire(process.pid, sessionId, { force: force ?? false });
4579
+ supervisorLock = lock;
4580
+ supervisorLogger.debug({ runId: targetRunId }, "Supervisor lock acquired");
4581
+ registerExitHandlers(lock);
4582
+ } catch (lockErr) {
4583
+ const msg = lockErr instanceof Error ? lockErr.message : String(lockErr);
4584
+ supervisorLogger.warn({
4585
+ runId: targetRunId,
4586
+ error: msg
4587
+ }, "Supervisor lock acquisition failed");
4588
+ if (outputFormat === "json") process.stdout.write(JSON.stringify({
4589
+ type: "supervisor:lock-failed",
4590
+ run_id: targetRunId,
4591
+ reason: msg,
4592
+ ts: new Date().toISOString()
4593
+ }) + "\n");
4594
+ else process.stderr.write(`Warning: Supervisor lock acquisition failed: ${msg}\n`);
4595
+ if (msg.includes("is already supervised by PID") && !force) throw lockErr;
4596
+ }
4597
+ }
4598
+ if (runId !== void 0) await acquireLockForRun(runId);
4458
4599
  function emitEvent(event) {
4459
4600
  if (outputFormat === "json") {
4460
4601
  const stamped = {
@@ -4479,6 +4620,7 @@ async function runSupervisorAction(options, deps = {}) {
4479
4620
  runId: health.run_id
4480
4621
  };
4481
4622
  log(`Supervisor: auto-bound to active run ${health.run_id}`);
4623
+ await acquireLockForRun(health.run_id);
4482
4624
  }
4483
4625
  if (outputFormat === "json") {
4484
4626
  const tokenSnapshot = health.run_id !== null ? await getTokenSnapshot(health.run_id, projectRoot) : {
@@ -4571,7 +4713,7 @@ async function runSupervisorAction(options, deps = {}) {
4571
4713
  await initSchema(expAdapter);
4572
4714
  const { runRunAction: runPipeline } = await import(
4573
4715
  /* @vite-ignore */
4574
- "../run-CjwCYY8Q.js"
4716
+ "../run-BIVex2-V.js"
4575
4717
  );
4576
4718
  const runStoryFn = async (opts) => {
4577
4719
  const exitCode = await runPipeline({
@@ -4780,7 +4922,7 @@ async function runMultiProjectSupervisor(options, deps = {}) {
4780
4922
  }
4781
4923
  }
4782
4924
  function registerSupervisorCommand(program, _version = "0.0.0", projectRoot = process.cwd()) {
4783
- program.command("supervisor").description("Monitor a pipeline run and automatically recover from stalls").option("--poll-interval <seconds>", "Health poll interval in seconds", (v) => parseInt(v, 10), 60).option("--stall-threshold <seconds>", "Staleness in seconds before killing a stalled pipeline", (v) => parseInt(v, 10), 600).option("--max-restarts <n>", "Maximum automatic restarts before aborting", (v) => parseInt(v, 10), 3).option("--run-id <id>", "Pipeline run ID to monitor (defaults to latest)").option("--pack <name>", "Methodology pack name", "bmad").option("--project-root <path>", "Project root directory", projectRoot).option("--projects <paths>", "Comma-separated project root directories to monitor (multi-project mode)").option("--output-format <format>", "Output format: human (default) or json", "human").option("--experiment", "After post-run analysis, enter experiment mode: create branches, apply modifications, run single-story experiments, and report verdicts (Story 17-4)", false).option("--max-experiments <n>", "Maximum number of experiments to run per analysis cycle (default: 2, Story 17-4 AC6)", (v) => parseInt(v, 10), 2).action(async (opts) => {
4925
+ program.command("supervisor").description("Monitor a pipeline run and automatically recover from stalls").option("--poll-interval <seconds>", "Health poll interval in seconds", (v) => parseInt(v, 10), 60).option("--stall-threshold <seconds>", "Staleness in seconds before killing a stalled pipeline", (v) => parseInt(v, 10), 600).option("--max-restarts <n>", "Maximum automatic restarts before aborting", (v) => parseInt(v, 10), 3).option("--run-id <id>", "Pipeline run ID to monitor (defaults to latest)").option("--pack <name>", "Methodology pack name", "bmad").option("--project-root <path>", "Project root directory", projectRoot).option("--projects <paths>", "Comma-separated project root directories to monitor (multi-project mode)").option("--output-format <format>", "Output format: human (default) or json", "human").option("--experiment", "After post-run analysis, enter experiment mode: create branches, apply modifications, run single-story experiments, and report verdicts (Story 17-4)", false).option("--max-experiments <n>", "Maximum number of experiments to run per analysis cycle (default: 2, Story 17-4 AC6)", (v) => parseInt(v, 10), 2).option("--force", "Forcefully evict an existing supervisor process (SIGTERM + 500ms) before attaching (Story 52-2)", false).action(async (opts) => {
4784
4926
  const outputFormat = opts.outputFormat === "json" ? "json" : "human";
4785
4927
  if (opts.stallThreshold < 120) console.warn(`Warning: --stall-threshold ${opts.stallThreshold}s is below 120s. Agent steps typically take 45-90s. This may cause false stall detections and wasted restarts.`);
4786
4928
  if (opts.projects) {
@@ -4811,7 +4953,8 @@ function registerSupervisorCommand(program, _version = "0.0.0", projectRoot = pr
4811
4953
  outputFormat,
4812
4954
  projectRoot: opts.projectRoot,
4813
4955
  experiment: opts.experiment,
4814
- maxExperiments: opts.maxExperiments
4956
+ maxExperiments: opts.maxExperiments,
4957
+ force: opts.force
4815
4958
  });
4816
4959
  process.exitCode = exitCode;
4817
4960
  });
@@ -7504,6 +7647,7 @@ async function runCancelAction(options) {
7504
7647
  const runningRuns = await getRunningPipelineRuns(adapter);
7505
7648
  for (const run of runningRuns) {
7506
7649
  await updatePipelineRun(adapter, run.id, { status: "stopped" });
7650
+ RunManifest.open(run.id, join(dbRoot, "runs")).update({ run_status: "stopped" }).catch(() => {});
7507
7651
  if (outputFormat === "human") process.stdout.write(`Marked pipeline run ${run.id} as stopped.\n`);
7508
7652
  }
7509
7653
  } finally {
@@ -1,4 +1,4 @@
1
- import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-M0iCuP26.js";
1
+ import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-DKallkoo.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./dist-R0W4ofKv.js";
4
4
  import "./decisions-C0pz9Clx.js";