@oisincoveney/pipeline 2.11.1 → 2.11.2

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.
@@ -0,0 +1,41 @@
1
+ //#region src/run-control/run-state-lock.ts
2
+ /**
3
+ * Process-wide serialization for critical sections that read, write, or
4
+ * temporarily relocate the `.pipeline/runs` run-state directory.
5
+ *
6
+ * The mechanical-check builtins (`lint`, `fallow`) hide `.pipeline/runs` for the
7
+ * duration of their command so those tools do not scan supervisor run-state
8
+ * (see builtins.ts `hidePipelineRunsDirectory`). Under the parallel
9
+ * mechanical-checks fan-out that hide window overlapped the run-control
10
+ * reporter's persistence of sibling node-status events, which then observed a
11
+ * momentarily-missing run directory and failed the whole run with
12
+ * "Run <id> does not exist". This lock makes the hide window and run-state
13
+ * persistence mutually exclusive without serializing any unrelated parallel
14
+ * work: only the run-state critical sections contend for it.
15
+ */
16
+ let chain = Promise.resolve();
17
+ /**
18
+ * Acquire the lock, resolving with a release function once every previously
19
+ * queued holder has released. Callers MUST invoke the returned release exactly
20
+ * once (use `withRunStateLock` unless you must span non-promise boundaries, as
21
+ * the builtin hide/restore does).
22
+ */
23
+ function acquireRunStateLock() {
24
+ const previous = chain;
25
+ let release = () => {};
26
+ chain = new Promise((resolve) => {
27
+ release = resolve;
28
+ });
29
+ return previous.then(() => release);
30
+ }
31
+ /** Run `fn` while holding the run-state lock, releasing on success or failure. */
32
+ async function withRunStateLock(fn) {
33
+ const release = await acquireRunStateLock();
34
+ try {
35
+ return await fn();
36
+ } finally {
37
+ release();
38
+ }
39
+ }
40
+ //#endregion
41
+ export { acquireRunStateLock, withRunStateLock };
@@ -1,3 +1,4 @@
1
+ import { withRunStateLock } from "./run-state-lock.js";
1
2
  import { updateNodeSessionEffect, updateNodeStatusEffect, updateRunStatusEffect } from "./store.js";
2
3
  import { Effect } from "effect";
3
4
  import { isAbsolute, join } from "node:path";
@@ -23,7 +24,7 @@ function createRunStoreRuntimeReporterRuntime(input) {
23
24
  activeHookPreviousStatuses,
24
25
  observedNodeStatuses
25
26
  });
26
- writeChain = writeChain.then(() => Effect.runPromise(persistRuntimeEventEffect(input, event, projection, now)));
27
+ writeChain = writeChain.then(() => withRunStateLock(() => Effect.runPromise(persistRuntimeEventEffect(input, event, projection, now))));
27
28
  };
28
29
  const flushEffect = () => Effect.tryPromise({
29
30
  catch: (error) => error,
@@ -1,4 +1,5 @@
1
1
  import { parseJson } from "../../safe-json.js";
2
+ import { acquireRunStateLock } from "../../run-control/run-state-lock.js";
2
3
  import { executeDrainMergeBuiltin } from "../drain-merge/drain-merge.js";
3
4
  import "../drain-merge/index.js";
4
5
  import { CommandExecutor, CommandExecutorLive } from "../services/command-executor-service.js";
@@ -95,7 +96,7 @@ function executeVisibleProjectCommand(command, context) {
95
96
  });
96
97
  }
97
98
  function withHiddenPipelineRuns(worktreePath, effect) {
98
- return Effect.acquireUseRelease(Effect.sync(() => hidePipelineRunsDirectory(worktreePath)), () => effect, (hiddenRuns) => Effect.sync(() => hiddenRuns?.restore()));
99
+ return Effect.acquireUseRelease(Effect.promise(() => acquireRunStateLock()), () => Effect.acquireUseRelease(Effect.sync(() => hidePipelineRunsDirectory(worktreePath)), () => effect, (hiddenRuns) => Effect.sync(() => hiddenRuns?.restore())), (release) => Effect.sync(() => release()));
99
100
  }
100
101
  function resolveRequiredScriptCommand(worktreePath, envName, scriptName) {
101
102
  return Effect.gen(function* () {
package/package.json CHANGED
@@ -127,7 +127,7 @@
127
127
  "prepack": "bun run build:cli"
128
128
  },
129
129
  "type": "module",
130
- "version": "2.11.1",
130
+ "version": "2.11.2",
131
131
  "description": "Config-driven multi-agent pipeline runner for repository work",
132
132
  "main": "./dist/index.js",
133
133
  "types": "./dist/index.d.ts",