@osolmaz/pi-workflows 0.12.1 → 0.13.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 (233) hide show
  1. package/README.md +59 -33
  2. package/dist/builtins/autodoc.workflow.d.ts +194 -7
  3. package/dist/builtins/autodoc.workflow.js +156 -30
  4. package/dist/builtins/autodoc.workflow.js.map +1 -1
  5. package/dist/builtins/autoimplement-command-batches.d.ts +1 -0
  6. package/dist/builtins/autoimplement-command-batches.js +29 -31
  7. package/dist/builtins/autoimplement-command-batches.js.map +1 -1
  8. package/dist/builtins/autoimplement.workflow.d.ts +1619 -97
  9. package/dist/builtins/autoimplement.workflow.js +416 -153
  10. package/dist/builtins/autoimplement.workflow.js.map +1 -1
  11. package/dist/builtins/autoplan.workflow.d.ts +126 -13
  12. package/dist/builtins/autoplan.workflow.js +200 -29
  13. package/dist/builtins/autoplan.workflow.js.map +1 -1
  14. package/dist/builtins/catalog.js +7 -5
  15. package/dist/builtins/catalog.js.map +1 -1
  16. package/dist/builtins/change-verification.workflow.d.ts +110 -0
  17. package/dist/builtins/change-verification.workflow.js +860 -0
  18. package/dist/builtins/change-verification.workflow.js.map +1 -0
  19. package/dist/builtins/index.d.ts +2 -1
  20. package/dist/builtins/index.js +1 -0
  21. package/dist/builtins/index.js.map +1 -1
  22. package/dist/builtins/monitor.workflow.d.ts +56 -21
  23. package/dist/builtins/monitor.workflow.js +499 -217
  24. package/dist/builtins/monitor.workflow.js.map +1 -1
  25. package/dist/builtins/plain-summary.workflow.d.ts +32 -0
  26. package/dist/builtins/plain-summary.workflow.js +134 -0
  27. package/dist/builtins/plain-summary.workflow.js.map +1 -0
  28. package/dist/builtins/plan-change.workflow.d.ts +527 -26
  29. package/dist/builtins/plan-change.workflow.js +26 -0
  30. package/dist/builtins/plan-change.workflow.js.map +1 -1
  31. package/dist/builtins/sanity-check.workflow.d.ts +45 -3
  32. package/dist/builtins/sanity-check.workflow.js +45 -7
  33. package/dist/builtins/sanity-check.workflow.js.map +1 -1
  34. package/dist/builtins/workspace-preparation.workflow.d.ts +75 -0
  35. package/dist/builtins/workspace-preparation.workflow.js +498 -0
  36. package/dist/builtins/workspace-preparation.workflow.js.map +1 -0
  37. package/dist/controllers/effects.d.ts +3 -2
  38. package/dist/controllers/effects.js +8 -1
  39. package/dist/controllers/effects.js.map +1 -1
  40. package/dist/controllers/index.d.ts +1 -1
  41. package/dist/controllers/index.js +1 -1
  42. package/dist/controllers/index.js.map +1 -1
  43. package/dist/controllers/manager.d.ts +1 -0
  44. package/dist/controllers/manager.js +41 -17
  45. package/dist/controllers/manager.js.map +1 -1
  46. package/dist/controllers/sqlite.d.ts +107 -85
  47. package/dist/controllers/sqlite.js +1611 -1486
  48. package/dist/controllers/sqlite.js.map +1 -1
  49. package/dist/controllers/store.d.ts +9 -8
  50. package/dist/controllers/store.js +1 -31
  51. package/dist/controllers/store.js.map +1 -1
  52. package/dist/controllers/types.d.ts +3 -0
  53. package/dist/controllers/workflow-engine-scheduler.d.ts +1 -1
  54. package/dist/controllers/workflow-engine-scheduler.js +3 -5
  55. package/dist/controllers/workflow-engine-scheduler.js.map +1 -1
  56. package/dist/controllers/workflows.d.ts +2 -2
  57. package/dist/controllers/workflows.js +11 -10
  58. package/dist/controllers/workflows.js.map +1 -1
  59. package/dist/extension/controller-host.js +2 -2
  60. package/dist/extension/controller-host.js.map +1 -1
  61. package/dist/extension/decision-channels.d.ts +2 -0
  62. package/dist/extension/decision-channels.js +311 -118
  63. package/dist/extension/decision-channels.js.map +1 -1
  64. package/dist/extension/executor.d.ts +9 -2
  65. package/dist/extension/executor.js +90 -6
  66. package/dist/extension/executor.js.map +1 -1
  67. package/dist/extension/herdr-viewer.d.ts +0 -1
  68. package/dist/extension/herdr-viewer.js +0 -4
  69. package/dist/extension/herdr-viewer.js.map +1 -1
  70. package/dist/extension/index.js +156 -117
  71. package/dist/extension/index.js.map +1 -1
  72. package/dist/extension/recorder.d.ts +3 -10
  73. package/dist/extension/recorder.js +13 -22
  74. package/dist/extension/recorder.js.map +1 -1
  75. package/dist/extension/step-message.d.ts +7 -2
  76. package/dist/extension/step-message.js +94 -2
  77. package/dist/extension/step-message.js.map +1 -1
  78. package/dist/extension/widget.js +6 -0
  79. package/dist/extension/widget.js.map +1 -1
  80. package/dist/host/rpc-executor.d.ts +3 -0
  81. package/dist/host/rpc-executor.js +2 -0
  82. package/dist/host/rpc-executor.js.map +1 -1
  83. package/dist/host/runner.d.ts +3 -6
  84. package/dist/host/runner.js +83 -32
  85. package/dist/host/runner.js.map +1 -1
  86. package/dist/render/graph-render.js +14 -8
  87. package/dist/render/graph-render.js.map +1 -1
  88. package/dist/state/database.d.ts +35 -0
  89. package/dist/state/database.js +287 -0
  90. package/dist/state/database.js.map +1 -0
  91. package/dist/state/index.d.ts +4 -0
  92. package/dist/state/index.js +5 -0
  93. package/dist/state/index.js.map +1 -0
  94. package/dist/state/json.d.ts +6 -0
  95. package/dist/state/json.js +38 -0
  96. package/dist/state/json.js.map +1 -0
  97. package/dist/state/mutation.d.ts +57 -0
  98. package/dist/state/mutation.js +255 -0
  99. package/dist/state/mutation.js.map +1 -0
  100. package/dist/state/schema.d.ts +6 -0
  101. package/dist/state/schema.js +473 -0
  102. package/dist/state/schema.js.map +1 -0
  103. package/dist/viewer/cli.d.ts +2 -2
  104. package/dist/viewer/cli.js +142 -122
  105. package/dist/viewer/cli.js.map +1 -1
  106. package/dist/viewer/render.d.ts +4 -4
  107. package/dist/viewer/render.js +2 -17
  108. package/dist/viewer/render.js.map +1 -1
  109. package/dist/viewer/session-reducer.d.ts +1 -1
  110. package/dist/viewer/session-reducer.js +1 -1
  111. package/dist/viewer/tui.d.ts +3 -3
  112. package/dist/viewer/tui.js +15 -13
  113. package/dist/viewer/tui.js.map +1 -1
  114. package/dist/viewer/watch.d.ts +2 -5
  115. package/dist/viewer/watch.js +13 -13
  116. package/dist/viewer/watch.js.map +1 -1
  117. package/dist/workflows/composition.js +12 -2
  118. package/dist/workflows/composition.js.map +1 -1
  119. package/dist/workflows/definition.d.ts +6 -2
  120. package/dist/workflows/definition.js +17 -0
  121. package/dist/workflows/definition.js.map +1 -1
  122. package/dist/workflows/engine.d.ts +6 -6
  123. package/dist/workflows/engine.js +183 -103
  124. package/dist/workflows/engine.js.map +1 -1
  125. package/dist/workflows/errors.d.ts +3 -3
  126. package/dist/workflows/errors.js +3 -3
  127. package/dist/workflows/human-decision.d.ts +29 -4
  128. package/dist/workflows/human-decision.js +547 -283
  129. package/dist/workflows/human-decision.js.map +1 -1
  130. package/dist/workflows/index.d.ts +4 -5
  131. package/dist/workflows/index.js +3 -4
  132. package/dist/workflows/index.js.map +1 -1
  133. package/dist/workflows/schema.js +17 -1
  134. package/dist/workflows/schema.js.map +1 -1
  135. package/dist/workflows/store.d.ts +83 -103
  136. package/dist/workflows/store.js +902 -951
  137. package/dist/workflows/store.js.map +1 -1
  138. package/dist/workflows/types.d.ts +55 -81
  139. package/docs/CONTROLLERS.md +10 -8
  140. package/docs/DEFERRED_TURNS.md +2 -2
  141. package/docs/DESIGN_PHILOSOPHY.md +4 -2
  142. package/docs/HUMAN_DECISIONS.md +13 -14
  143. package/docs/MONITOR.md +179 -231
  144. package/docs/SQLITE_STATE.md +219 -0
  145. package/docs/WORKFLOW_COMPOSITION.md +27 -19
  146. package/docs/WORKFLOW_STEP_MESSAGES.md +20 -18
  147. package/docs/WORKFLOW_UPDATES.md +10 -9
  148. package/docs/development.md +9 -9
  149. package/docs/live-replay-protocol.md +28 -37
  150. package/docs/plans/2026-08-16-workflow-updates-plan.md +1 -1
  151. package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
  152. package/docs/plans/2026-08-21-autoimplement-timeout-fallback-plan.md +1 -1
  153. package/docs/plans/2026-08-21-plan-change-approval-policy-plan.md +1 -1
  154. package/docs/plans/2026-08-21-sanity-check-plan.md +30 -16
  155. package/docs/plans/2026-08-22-goal-finishing-monitor-plan.md +200 -0
  156. package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +701 -0
  157. package/docs/plans/2026-08-23-sqlite-state-plan.md +970 -0
  158. package/docs/plans/2026-08-24-change-scoped-verification-plan.md +419 -0
  159. package/docs/plans/replayable-run-bundles-implementation-plan.md +2 -2
  160. package/docs/plans/session-event-replay-implementation-plan.md +1 -1
  161. package/docs/plans/tui-viewer-implementation-plan.md +1 -1
  162. package/docs/session-event-journal.md +63 -434
  163. package/docs/tui-viewer.md +13 -15
  164. package/docs/workflows.md +111 -62
  165. package/examples/workflows/plain-summary.workflow.ts +1 -0
  166. package/herdr-plugin.toml +1 -1
  167. package/package.json +1 -1
  168. package/plugins/herdr/viewer.mjs +1 -11
  169. package/skills/autodoc/SKILL.md +7 -0
  170. package/skills/autoimplement/SKILL.md +4 -0
  171. package/skills/autoplan/SKILL.md +5 -4
  172. package/skills/monitor/SKILL.md +91 -163
  173. package/skills/pi-workflows/SKILL.md +7 -7
  174. package/skills/sanity-check/SKILL.md +1 -1
  175. package/src/builtins/autodoc.workflow.ts +184 -33
  176. package/src/builtins/autoimplement-command-batches.ts +39 -33
  177. package/src/builtins/autoimplement.workflow.ts +483 -175
  178. package/src/builtins/autoplan.workflow.ts +290 -40
  179. package/src/builtins/catalog.ts +7 -5
  180. package/src/builtins/change-verification.workflow.ts +1143 -0
  181. package/src/builtins/index.ts +7 -1
  182. package/src/builtins/monitor.workflow.ts +667 -250
  183. package/src/builtins/plain-summary.workflow.ts +185 -0
  184. package/src/builtins/plan-change.workflow.ts +35 -0
  185. package/src/builtins/sanity-check.workflow.ts +62 -7
  186. package/src/builtins/workspace-preparation.workflow.ts +668 -0
  187. package/src/controllers/effects.ts +7 -0
  188. package/src/controllers/index.ts +0 -6
  189. package/src/controllers/manager.ts +72 -32
  190. package/src/controllers/sqlite.ts +2420 -1948
  191. package/src/controllers/store.ts +17 -38
  192. package/src/controllers/types.ts +3 -0
  193. package/src/controllers/workflow-engine-scheduler.ts +4 -8
  194. package/src/controllers/workflows.ts +45 -21
  195. package/src/extension/controller-host.ts +1 -2
  196. package/src/extension/decision-channels.ts +427 -144
  197. package/src/extension/executor.ts +106 -6
  198. package/src/extension/herdr-viewer.ts +0 -5
  199. package/src/extension/index.ts +180 -132
  200. package/src/extension/recorder.ts +13 -22
  201. package/src/extension/step-message.ts +106 -4
  202. package/src/extension/widget.ts +8 -0
  203. package/src/host/rpc-executor.ts +4 -0
  204. package/src/host/runner.ts +93 -41
  205. package/src/render/graph-render.ts +11 -4
  206. package/src/state/database.ts +375 -0
  207. package/src/state/index.ts +29 -0
  208. package/src/state/json.ts +42 -0
  209. package/src/state/mutation.ts +435 -0
  210. package/src/state/schema.ts +475 -0
  211. package/src/viewer/cli.ts +151 -144
  212. package/src/viewer/render.ts +12 -24
  213. package/src/viewer/session-reducer.ts +1 -1
  214. package/src/viewer/tui.ts +18 -17
  215. package/src/viewer/watch.ts +13 -17
  216. package/src/workflows/composition.ts +12 -3
  217. package/src/workflows/definition.ts +36 -3
  218. package/src/workflows/engine.ts +212 -116
  219. package/src/workflows/errors.ts +3 -3
  220. package/src/workflows/human-decision.ts +795 -340
  221. package/src/workflows/index.ts +15 -19
  222. package/src/workflows/schema.ts +19 -1
  223. package/src/workflows/store.ts +1295 -1163
  224. package/src/workflows/types.ts +61 -81
  225. package/dist/workflows/artifacts.d.ts +0 -40
  226. package/dist/workflows/artifacts.js +0 -155
  227. package/dist/workflows/artifacts.js.map +0 -1
  228. package/dist/workflows/migrate-sources.d.ts +0 -42
  229. package/dist/workflows/migrate-sources.js +0 -133
  230. package/dist/workflows/migrate-sources.js.map +0 -1
  231. package/docs/run-bundles.md +0 -481
  232. package/src/workflows/artifacts.ts +0 -188
  233. package/src/workflows/migrate-sources.ts +0 -178
@@ -1,7 +1,3 @@
1
- import { createHash } from "node:crypto";
2
- import fs from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
5
1
  import type {
6
2
  ChildWorkflowRecord,
7
3
  ControllerEvent,
@@ -13,8 +9,6 @@ import type {
13
9
  JsonObject,
14
10
  } from "./types.js";
15
11
 
16
- export const CONTROLLER_STORE_SCHEMA = "pi-workflows.controller-store.v1" as const;
17
-
18
12
  export type QueueRequeueOptions = {
19
13
  availableAt: string;
20
14
  error?: string;
@@ -65,6 +59,7 @@ export interface ControllerStore {
65
59
  updateStatus<TStatus>(options: {
66
60
  ref: ControllerResourceRef;
67
61
  expectedResourceVersion: number;
62
+ claim: ControllerQueueClaim;
68
63
  status: ControllerResourceStatus<TStatus>;
69
64
  finalizers?: string[];
70
65
  now?: string;
@@ -76,11 +71,16 @@ export interface ControllerStore {
76
71
  finalizers: string[];
77
72
  now?: string;
78
73
  }): ControllerResource;
79
- deleteResource(ref: ControllerResourceRef, expectedResourceVersion: number): boolean;
74
+ deleteResource(
75
+ ref: ControllerResourceRef,
76
+ expectedResourceVersion: number,
77
+ claim: ControllerQueueClaim,
78
+ ): boolean;
80
79
 
81
80
  enqueue(ref: ControllerResourceRef, availableAt?: string): void;
82
81
  claimNext(options: {
83
82
  controllers: string[];
83
+ ownerId: string;
84
84
  leaseMs: number;
85
85
  now?: string;
86
86
  }): ControllerQueueClaim | undefined;
@@ -92,6 +92,7 @@ export interface ControllerStore {
92
92
  reserveEffect(options: {
93
93
  key: string;
94
94
  resourceUid: string;
95
+ claim: ControllerQueueClaim;
95
96
  generation: number;
96
97
  kind: string;
97
98
  requestFingerprint: string;
@@ -101,6 +102,7 @@ export interface ControllerStore {
101
102
  updateEffect(options: {
102
103
  resourceUid: string;
103
104
  key: string;
105
+ claim: ControllerQueueClaim;
104
106
  state: EffectRecord["state"];
105
107
  externalRef?: string;
106
108
  error?: string;
@@ -110,51 +112,28 @@ export interface ControllerStore {
110
112
 
111
113
  reserveWorkflow(options: {
112
114
  resourceUid: string;
115
+ claim: ControllerQueueClaim;
113
116
  requestKey: string;
114
117
  workflow: string;
115
118
  inputFingerprint: string;
116
119
  }): WorkflowReservation;
117
120
  getWorkflow(resourceUid: string, requestKey: string): ChildWorkflowRecord | undefined;
118
121
  getWorkflowByRequestId(requestId: string): ChildWorkflowRecord | undefined;
119
- updateWorkflow(requestId: string, update: WorkflowRecordUpdate): ChildWorkflowRecord;
122
+ updateWorkflow(
123
+ requestId: string,
124
+ update: WorkflowRecordUpdate,
125
+ claim: ControllerQueueClaim,
126
+ ): ChildWorkflowRecord;
127
+ completeWorkflow(requestId: string, update: WorkflowRecordUpdate): ChildWorkflowRecord;
120
128
  listWorkflows(resourceUid: string): ChildWorkflowRecord[];
121
129
 
122
130
  recordEvent(options: {
123
131
  controller: string;
124
132
  key: string;
133
+ claim?: ControllerQueueClaim;
125
134
  type: string;
126
135
  payload?: JsonObject;
127
136
  now?: string;
128
137
  }): ControllerEvent;
129
138
  listEvents(options?: { controller?: string; key?: string; limit?: number }): ControllerEvent[];
130
139
  }
131
-
132
- export function controllerStoreBaseDir(homeDir: string = os.homedir()): string {
133
- const override = process.env.PI_WORKFLOWS_CONTROLLER_DIR;
134
- if (override !== undefined && override.length > 0) {
135
- return override;
136
- }
137
- return path.join(homeDir, ".pi", "agent", "workflows", "controllers");
138
- }
139
-
140
- export function controllerStorePath(homeDir: string = os.homedir()): string {
141
- return path.join(controllerStoreBaseDir(homeDir), "controller.sqlite");
142
- }
143
-
144
- export function controllerProjectScope(cwd: string): string {
145
- let canonicalCwd: string;
146
- try {
147
- canonicalCwd = fs.realpathSync.native(cwd);
148
- } catch {
149
- canonicalCwd = path.resolve(cwd);
150
- }
151
- return createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 24);
152
- }
153
-
154
- export function projectControllerStoreBaseDir(cwd: string, homeDir: string = os.homedir()): string {
155
- return path.join(controllerStoreBaseDir(homeDir), "projects", controllerProjectScope(cwd));
156
- }
157
-
158
- export function projectControllerStorePath(cwd: string, homeDir: string = os.homedir()): string {
159
- return path.join(projectControllerStoreBaseDir(cwd, homeDir), "controller.sqlite");
160
- }
@@ -167,8 +167,11 @@ export type AnyControllerDefinition = {
167
167
  export type ControllerQueueClaim = {
168
168
  controller: string;
169
169
  key: string;
170
+ ownerId: string;
170
171
  token: string;
172
+ generation: number;
171
173
  queueVersion: number;
174
+ resourceVersion: number;
172
175
  consecutiveErrors: number;
173
176
  expiresAt: string;
174
177
  };
@@ -1,5 +1,5 @@
1
1
  import { WorkflowEngine } from "../workflows/engine.js";
2
- import { readLastTraceEvent, readRunBundle, type WorkflowRunStore } from "../workflows/store.js";
2
+ import type { WorkflowRunStore } from "../workflows/store.js";
3
3
  import type {
4
4
  WorkflowDefinition,
5
5
  WorkflowRunResult,
@@ -47,17 +47,14 @@ export class WorkflowEngineScheduler implements ControllerWorkflowScheduler {
47
47
  return { state: "running", runId: active.runId };
48
48
  }
49
49
 
50
- const bundle = await readRunBundle(this.options.store.runDirFor(request.runId));
50
+ const bundle = this.options.store.readRun(request.runId, { includeTrace: true });
51
51
  if (bundle !== null) {
52
52
  const recovered =
53
53
  bundle.state.status === "running"
54
54
  ? await this.options.store.markRunInterrupted(request.runId)
55
55
  : bundle;
56
56
  if (recovered !== null) {
57
- const lastTraceEvent = await readLastTraceEvent(
58
- recovered.runDir,
59
- recovered.manifest.paths.trace,
60
- );
57
+ const lastTraceEvent = recovered.traceEvents?.at(-1) ?? null;
61
58
  return resultFromStatus(
62
59
  recovered.state.status,
63
60
  request.runId,
@@ -68,7 +65,6 @@ export class WorkflowEngineScheduler implements ControllerWorkflowScheduler {
68
65
  return { state: "pending" };
69
66
  }
70
67
 
71
- await this.options.store.quarantineIncompleteRun(request.runId);
72
68
  const resolved = await this.options.resolveWorkflow(request.workflow);
73
69
  if (signal.aborted) {
74
70
  throw signal.reason ?? new Error("Workflow scheduling aborted");
@@ -112,7 +108,7 @@ function callCompletion(
112
108
  try {
113
109
  callback(result);
114
110
  } catch {
115
- // A later reconciliation recovers completion from the immutable run bundle.
111
+ // A later reconciliation recovers completion from the immutable run event.
116
112
  }
117
113
  }
118
114
 
@@ -5,6 +5,7 @@ import type {
5
5
  ChildWorkflowRecord,
6
6
  ChildWorkflowRequest,
7
7
  ChildWorkflowState,
8
+ ControllerQueueClaim,
8
9
  ControllerResource,
9
10
  ControllerWorkflows,
10
11
  } from "./types.js";
@@ -37,9 +38,13 @@ export class ControllerWorkflowCoordinator {
37
38
  private readonly scheduler?: ControllerWorkflowScheduler,
38
39
  ) {}
39
40
 
40
- forResource(resource: ControllerResource, signal: AbortSignal): ControllerWorkflows {
41
+ forResource(
42
+ resource: ControllerResource,
43
+ claim: ControllerQueueClaim,
44
+ signal: AbortSignal,
45
+ ): ControllerWorkflows {
41
46
  return {
42
- ensure: async (request) => await this.ensure(resource, request, signal),
47
+ ensure: async (request) => await this.ensure(resource, claim, request, signal),
43
48
  };
44
49
  }
45
50
 
@@ -48,24 +53,25 @@ export class ControllerWorkflowCoordinator {
48
53
  if (previous === undefined) {
49
54
  throw new Error(`Workflow request not found: ${requestId}`);
50
55
  }
51
- const record = this.store.updateWorkflow(requestId, {
56
+ const record = this.store.completeWorkflow(requestId, {
52
57
  state: result.state,
53
58
  ...(result.runId !== undefined ? { runId: result.runId } : {}),
54
59
  ...(result.error !== undefined ? { error: result.error } : { error: null }),
55
60
  });
56
61
  this.enqueueParent(record.resourceUid);
57
- this.recordEvent(record, "workflow_state_changed");
58
62
  return record;
59
63
  }
60
64
 
61
65
  private async ensure(
62
66
  resource: ControllerResource,
67
+ claim: ControllerQueueClaim,
63
68
  request: ChildWorkflowRequest,
64
69
  signal: AbortSignal,
65
70
  ): Promise<ChildWorkflowRecord> {
66
71
  const inputFingerprint = jsonFingerprint(request.input);
67
72
  const reservation = this.store.reserveWorkflow({
68
73
  resourceUid: resource.metadata.uid,
74
+ claim,
69
75
  requestKey: request.requestKey,
70
76
  workflow: request.workflow,
71
77
  inputFingerprint,
@@ -78,18 +84,26 @@ export class ControllerWorkflowCoordinator {
78
84
  return record;
79
85
  }
80
86
  if (record.state === "interrupted" || record.attempt === 0) {
81
- record = this.store.updateWorkflow(record.requestId, {
82
- state: "pending",
83
- attempt: record.attempt + 1,
84
- runId: createRunId(record.workflow),
85
- error: null,
86
- });
87
+ record = this.store.updateWorkflow(
88
+ record.requestId,
89
+ {
90
+ state: "pending",
91
+ attempt: record.attempt + 1,
92
+ runId: createRunId(record.workflow),
93
+ error: null,
94
+ },
95
+ claim,
96
+ );
87
97
  } else if (record.runId === undefined) {
88
- record = this.store.updateWorkflow(record.requestId, {
89
- state: "pending",
90
- runId: createRunId(record.workflow),
91
- error: null,
92
- });
98
+ record = this.store.updateWorkflow(
99
+ record.requestId,
100
+ {
101
+ state: "pending",
102
+ runId: createRunId(record.workflow),
103
+ error: null,
104
+ },
105
+ claim,
106
+ );
93
107
  }
94
108
  if (record.runId === undefined) {
95
109
  throw new Error(`Workflow request has no reserved run ID: ${record.requestId}`);
@@ -107,15 +121,20 @@ export class ControllerWorkflowCoordinator {
107
121
  this.complete(record.requestId, completed);
108
122
  },
109
123
  );
110
- record = this.store.updateWorkflow(record.requestId, {
111
- state: result.state,
112
- ...(result.runId !== undefined ? { runId: result.runId } : {}),
113
- ...(result.error !== undefined ? { error: result.error } : { error: null }),
114
- });
124
+ record = this.store.updateWorkflow(
125
+ record.requestId,
126
+ {
127
+ state: result.state,
128
+ ...(result.runId !== undefined ? { runId: result.runId } : {}),
129
+ ...(result.error !== undefined ? { error: result.error } : { error: null }),
130
+ },
131
+ claim,
132
+ );
115
133
  if (reservation.created || result.state !== "running") {
116
134
  this.recordEvent(
117
135
  record,
118
136
  reservation.created ? "workflow_requested" : "workflow_state_changed",
137
+ claim,
119
138
  );
120
139
  }
121
140
  return record;
@@ -131,7 +150,11 @@ export class ControllerWorkflowCoordinator {
131
150
  }
132
151
  }
133
152
 
134
- private recordEvent(record: ChildWorkflowRecord, type: string): void {
153
+ private recordEvent(
154
+ record: ChildWorkflowRecord,
155
+ type: string,
156
+ claim: ControllerQueueClaim,
157
+ ): void {
135
158
  const resource = this.store.getResourceByUid(record.resourceUid);
136
159
  if (resource === undefined) {
137
160
  return;
@@ -139,6 +162,7 @@ export class ControllerWorkflowCoordinator {
139
162
  this.store.recordEvent({
140
163
  controller: resource.metadata.controller,
141
164
  key: resource.metadata.key,
165
+ claim,
142
166
  type,
143
167
  payload: {
144
168
  requestId: record.requestId,
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  ControllerManager,
3
3
  SqliteControllerStore,
4
- projectControllerStorePath,
5
4
  loadDiscoveredControllers,
6
5
  type AnyControllerDefinition,
7
6
  type ControllerResource,
@@ -86,7 +85,7 @@ export class PiControllerHost {
86
85
  if (definitions.length === 0) {
87
86
  return undefined;
88
87
  }
89
- const store = new SqliteControllerStore(projectControllerStorePath(options.cwd));
88
+ const store = new SqliteControllerStore(undefined, { projectPath: options.cwd });
90
89
  const manager = new ControllerManager({
91
90
  store,
92
91
  controllers: definitions,