@workplane/workplans 0.4.0 → 0.4.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.
package/dist/index.d.ts CHANGED
@@ -80,6 +80,74 @@ declare class ScheduleBuilder {
80
80
  static withNextRunAt(schedule: WorkplanSchedule): WorkplanSchedule;
81
81
  }
82
82
 
83
+ type WorkplanRunStatus = "running" | "step_failed" | "completed" | "failed" | "cancelled";
84
+ interface WorkplanScheduleRecord {
85
+ id: string;
86
+ planId: string;
87
+ name: string;
88
+ cronExpression: string;
89
+ timezone: string;
90
+ inputs: Record<string, unknown>;
91
+ enabled: boolean;
92
+ lastRunAt: string | null;
93
+ nextRunAt: string | null;
94
+ createdBy: string | null;
95
+ createdAt: string;
96
+ updatedAt: string;
97
+ }
98
+ interface WorkplanRunRecord {
99
+ id: string;
100
+ scheduleId: string | null;
101
+ planId: string;
102
+ planName: string;
103
+ status: WorkplanRunStatus;
104
+ idempotencyKey: string | null;
105
+ createdAt: string;
106
+ endedAt: string | null;
107
+ error: string | null;
108
+ }
109
+ interface WorkplanStepResultInput {
110
+ stepId: string;
111
+ stepName: string;
112
+ output?: string;
113
+ exitCode?: number;
114
+ durationMs?: number;
115
+ metadata?: Record<string, unknown>;
116
+ }
117
+
118
+ interface ScheduleStore {
119
+ listDueWorkplanSchedules(asOf: string): Promise<WorkplanScheduleRecord[]>;
120
+ getWorkplanSchedule(scheduleId: string): Promise<WorkplanScheduleRecord | null>;
121
+ markWorkplanScheduleRan(scheduleId: string, lastRunAt: string, nextRunAt: string): Promise<void>;
122
+ tryCreateWorkplanRun(input: {
123
+ scheduleId?: string;
124
+ planId: string;
125
+ planName: string;
126
+ idempotencyKey?: string;
127
+ }): Promise<WorkplanRunRecord | null>;
128
+ updateWorkplanRun(runId: string, status: WorkplanRunRecord["status"], error?: string, endedAt?: string): Promise<WorkplanRunRecord | null>;
129
+ appendWorkplanStepResults(runId: string, steps: WorkplanStepResultInput[]): Promise<unknown>;
130
+ }
131
+ interface PlanResolver {
132
+ resolve(planId: string, inputs: Record<string, unknown>): Workplan;
133
+ }
134
+ interface ExecuteScheduleOptions {
135
+ advanceSchedule?: boolean;
136
+ idempotencyKey?: string;
137
+ }
138
+ declare class WorkplanScheduler {
139
+ private readonly store;
140
+ private readonly resolver;
141
+ private readonly contextFactory;
142
+ private readonly runner;
143
+ constructor(store: ScheduleStore, resolver: PlanResolver, contextFactory: () => WorkplanRunContext, runner?: WorkplanRunner);
144
+ tick(now?: Date): Promise<WorkplanRunRecord[]>;
145
+ runNow(scheduleId: string): Promise<WorkplanRunRecord | null>;
146
+ executeSchedule(schedule: WorkplanScheduleRecord, options: ExecuteScheduleOptions & {
147
+ scheduledTime: string;
148
+ }): Promise<WorkplanRunRecord | null>;
149
+ }
150
+
83
151
  declare function applyTemplate(payload: Record<string, unknown>, prevOutput: string): Record<string, unknown>;
84
152
 
85
153
  declare function printStepResult(stepName: string, output: string): void;
@@ -96,4 +164,4 @@ interface FileStepOptions {
96
164
  }
97
165
  declare function runFileStep(opts: FileStepOptions): Promise<string>;
98
166
 
99
- export { LocalWorkplanContext, type NodeHandle, ScheduleBuilder, SequentialWorkplanRunner, type StepOutput, type StepOutputDest, type StepResult, type Workplan, type WorkplanResult, type WorkplanRunContext, type WorkplanRunner, type WorkplanSchedule, type WorkplanStatus, type WorkplanStep, applyTemplate, printStepResult, runFileStep, runShellStep };
167
+ export { type ExecuteScheduleOptions, LocalWorkplanContext, type NodeHandle, type PlanResolver, ScheduleBuilder, type ScheduleStore, SequentialWorkplanRunner, type StepOutput, type StepOutputDest, type StepResult, type Workplan, type WorkplanResult, type WorkplanRunContext, type WorkplanRunner, type WorkplanSchedule, WorkplanScheduler, type WorkplanStatus, type WorkplanStep, applyTemplate, printStepResult, runFileStep, runShellStep };
package/dist/index.js CHANGED
@@ -195,10 +195,87 @@ var ScheduleBuilder = class _ScheduleBuilder {
195
195
  };
196
196
  }
197
197
  };
198
+
199
+ // src/scheduler.ts
200
+ var WorkplanScheduler = class {
201
+ constructor(store, resolver, contextFactory, runner = new SequentialWorkplanRunner()) {
202
+ this.store = store;
203
+ this.resolver = resolver;
204
+ this.contextFactory = contextFactory;
205
+ this.runner = runner;
206
+ }
207
+ store;
208
+ resolver;
209
+ contextFactory;
210
+ runner;
211
+ async tick(now = /* @__PURE__ */ new Date()) {
212
+ const due = await this.store.listDueWorkplanSchedules(now.toISOString());
213
+ const launched = [];
214
+ for (const schedule of due) {
215
+ if (!schedule.nextRunAt) {
216
+ continue;
217
+ }
218
+ const run = await this.executeSchedule(schedule, {
219
+ scheduledTime: schedule.nextRunAt,
220
+ advanceSchedule: true
221
+ });
222
+ if (run) {
223
+ launched.push(run);
224
+ }
225
+ }
226
+ return launched;
227
+ }
228
+ async runNow(scheduleId) {
229
+ const schedule = await this.store.getWorkplanSchedule(scheduleId);
230
+ if (!schedule) {
231
+ return null;
232
+ }
233
+ return this.executeSchedule(schedule, {
234
+ scheduledTime: (/* @__PURE__ */ new Date()).toISOString(),
235
+ advanceSchedule: false
236
+ });
237
+ }
238
+ async executeSchedule(schedule, options) {
239
+ const idempotencyKey = options.idempotencyKey ?? (options.advanceSchedule ? `${schedule.id}:${options.scheduledTime}` : void 0);
240
+ const run = await this.store.tryCreateWorkplanRun({
241
+ scheduleId: schedule.id,
242
+ planId: schedule.planId,
243
+ planName: schedule.name,
244
+ idempotencyKey
245
+ });
246
+ if (!run) {
247
+ return null;
248
+ }
249
+ if (options.advanceSchedule) {
250
+ const nextRunAt = ScheduleBuilder.nextRunAt(schedule.cronExpression, schedule.timezone);
251
+ await this.store.markWorkplanScheduleRan(schedule.id, options.scheduledTime, nextRunAt);
252
+ }
253
+ try {
254
+ const plan = this.resolver.resolve(schedule.planId, schedule.inputs);
255
+ const result = await this.runner.run(plan, this.contextFactory());
256
+ const stepNames = new Map(plan.steps.map((step) => [step.id, step.name]));
257
+ const stepInputs = result.steps.map((step) => ({
258
+ stepId: step.stepId,
259
+ stepName: stepNames.get(step.stepId) ?? step.stepId,
260
+ output: step.output,
261
+ exitCode: step.exitCode,
262
+ durationMs: step.durationMs,
263
+ metadata: step.metadata
264
+ }));
265
+ await this.store.appendWorkplanStepResults(run.id, stepInputs);
266
+ const error = result.succeeded ? void 0 : result.steps.at(-1)?.output;
267
+ return await this.store.updateWorkplanRun(run.id, result.status, error);
268
+ } catch (err) {
269
+ const message = err instanceof Error ? err.message : String(err);
270
+ return await this.store.updateWorkplanRun(run.id, "failed", message);
271
+ }
272
+ }
273
+ };
198
274
  export {
199
275
  LocalWorkplanContext,
200
276
  ScheduleBuilder,
201
277
  SequentialWorkplanRunner,
278
+ WorkplanScheduler,
202
279
  applyTemplate,
203
280
  printStepResult,
204
281
  runFileStep,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/template.ts","../src/runner.ts","../src/sinks/stdout.ts","../src/context.ts","../src/schedule-builder.ts"],"sourcesContent":["export function applyTemplate(payload: Record<string, unknown>, prevOutput: string): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(payload).map(([k, v]) => [\n k,\n typeof v === \"string\" ? v.replaceAll(\"{{prevOutput}}\", prevOutput) : v,\n ]),\n );\n}\n","import type { Workplan, WorkplanResult, WorkplanRunner, WorkplanRunContext, StepResult, WorkplanStep } from \"./types.js\";\nimport { applyTemplate } from \"./template.js\";\n\nconst INLINE_PROVIDERS = new Set([\"anthropic\", \"openai\", \"ollama\", \"shell\", \"file\"]);\n\nasync function runInlineStep(step: WorkplanStep, prompt: string): Promise<string> {\n const provider = step.provider!;\n if (provider === \"anthropic\") {\n const { runAnthropicStep } = await import(\"./providers/anthropic.js\");\n return runAnthropicStep({ model: step.model ?? \"claude-haiku-4-5-20251001\", prompt });\n }\n if (provider === \"openai\") {\n const { runOpenAIStep } = await import(\"./providers/openai.js\");\n return runOpenAIStep({ model: step.model ?? \"gpt-4o-mini\", prompt });\n }\n if (provider === \"ollama\") {\n const { runOllamaStep } = await import(\"./providers/ollama.js\");\n return runOllamaStep({ model: step.model ?? \"llama3\", prompt });\n }\n if (provider === \"shell\") {\n const { runShellStep } = await import(\"./providers/shell.js\");\n return runShellStep({\n command: String(step.payload.command ?? \"\"),\n cwd: typeof step.payload.cwd === \"string\" ? step.payload.cwd : undefined,\n });\n }\n if (provider === \"file\") {\n const { runFileStep } = await import(\"./providers/file.js\");\n return runFileStep({ path: String(step.payload.path ?? \"\") });\n }\n throw new Error(`unknown inline provider: ${provider}`);\n}\n\nexport class SequentialWorkplanRunner implements WorkplanRunner {\n async run(plan: Workplan, ctx: WorkplanRunContext): Promise<WorkplanResult> {\n const results: StepResult[] = [];\n let prevOutput = \"\";\n let planSucceeded = true;\n\n for (const step of plan.steps) {\n const payload = prevOutput ? applyTemplate(step.payload, prevOutput) : step.payload;\n const prompt = typeof payload.prompt === \"string\" ? payload.prompt : \"\";\n const start = Date.now();\n let output = \"\";\n let exitCode = 0;\n\n try {\n if (step.provider && INLINE_PROVIDERS.has(step.provider)) {\n output = await runInlineStep({ ...step, payload }, prompt);\n } else {\n const node = await ctx.resolveNode(step.requires ?? [], step.provider);\n const result = await node.execute({ ...step, payload });\n output = result.output;\n exitCode = result.exitCode;\n }\n } catch (err) {\n exitCode = 1;\n output = err instanceof Error ? err.message : String(err);\n planSucceeded = false;\n\n const stepResult: StepResult = {\n stepId: step.id,\n output,\n exitCode,\n durationMs: Date.now() - start,\n };\n results.push(stepResult);\n ctx.emitResult(step.id, step.name, output);\n\n if (!step.continueOnError) {\n return {\n planId: plan.id,\n status: \"step_failed\",\n steps: results,\n succeeded: false,\n };\n }\n prevOutput = \"\";\n continue;\n }\n\n const dest = step.output?.dest ?? \"stdout\";\n const stepResult: StepResult = {\n stepId: step.id,\n output,\n exitCode,\n durationMs: Date.now() - start,\n };\n results.push(stepResult);\n\n if (dest === \"stdout\" || dest === \"artifact\") {\n ctx.emitResult(step.id, step.name, output);\n prevOutput = \"\";\n } else if (dest === \"next\") {\n prevOutput = output;\n }\n }\n\n return {\n planId: plan.id,\n status: planSucceeded ? \"completed\" : \"failed\",\n steps: results,\n succeeded: planSucceeded,\n };\n }\n}\n","export function printStepResult(stepName: string, output: string): void {\n process.stdout.write(`=== step: ${stepName} ===\\n${output}\\n\\n`);\n}\n","import type { NodeHandle, WorkplanRunContext, WorkplanStep, StepResult } from \"./types.js\";\nimport { printStepResult } from \"./sinks/stdout.js\";\n\nexport interface LocalWorkplanContextOptions {\n serverUrl?: string;\n nodeToken?: string;\n}\n\nclass WorkplaneNodeHandle implements NodeHandle {\n constructor(\n private readonly serverUrl: string,\n private readonly nodeToken: string,\n ) {}\n\n async execute(step: WorkplanStep): Promise<StepResult> {\n const start = Date.now();\n const taskRes = await fetch(`${this.serverUrl}/tasks`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${this.nodeToken}`,\n },\n body: JSON.stringify({\n kind: \"workplan.step\",\n adapter: step.adapter,\n payload: step.payload,\n requires: step.requires ?? [],\n }),\n });\n\n if (!taskRes.ok) {\n throw new Error(`failed to submit step ${step.id}: ${taskRes.status}`);\n }\n\n const task = (await taskRes.json()) as { id: string };\n const output = await this.pollUntilDone(task.id);\n return { stepId: step.id, output, exitCode: 0, durationMs: Date.now() - start };\n }\n\n private async pollUntilDone(taskId: string): Promise<string> {\n const terminalStatuses = new Set([\"succeeded\", \"failed\", \"cancelled\"]);\n for (;;) {\n await new Promise((r) => setTimeout(r, 1000));\n const res = await fetch(`${this.serverUrl}/tasks/${taskId}`, {\n headers: { authorization: `Bearer ${this.nodeToken}` },\n });\n const task = (await res.json()) as { status: string; payload?: Record<string, unknown> };\n if (terminalStatuses.has(task.status)) {\n if (task.status !== \"succeeded\") {\n throw new Error(`step task ${taskId} ended with status: ${task.status}`);\n }\n return typeof task.payload?.output === \"string\" ? task.payload.output : \"\";\n }\n }\n }\n}\n\nexport class LocalWorkplanContext implements WorkplanRunContext {\n private readonly serverUrl: string;\n private readonly nodeToken: string;\n\n constructor(opts: LocalWorkplanContextOptions = {}) {\n this.serverUrl = opts.serverUrl ?? process.env.WORKPLANE_SERVER_URL ?? \"http://localhost:8787\";\n this.nodeToken = opts.nodeToken ?? process.env.WORKPLANE_NODE_TOKEN ?? \"\";\n }\n\n async resolveNode(_requires: string[], _provider?: string): Promise<NodeHandle> {\n return new WorkplaneNodeHandle(this.serverUrl, this.nodeToken);\n }\n\n emitResult(_stepId: string, stepName: string, output: string): void {\n printStepResult(stepName, output);\n }\n}\n","import { CronExpressionParser } from \"cron-parser\";\nimport type { WorkplanSchedule } from \"./types.js\";\n\nexport class ScheduleBuilder {\n static nextRunAt(cronExpression: string, timezone: string): string {\n const expr = CronExpressionParser.parse(cronExpression, { tz: timezone });\n return expr.next().toISOString() ?? new Date().toISOString();\n }\n\n static withNextRunAt(schedule: WorkplanSchedule): WorkplanSchedule {\n return {\n ...schedule,\n nextRunAt: ScheduleBuilder.nextRunAt(schedule.cronExpression, schedule.timezone),\n };\n }\n}\n"],"mappings":"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","names":["runShellStep","runFileStep","stepResult"]}
1
+ {"version":3,"sources":["../src/template.ts","../src/runner.ts","../src/sinks/stdout.ts","../src/context.ts","../src/schedule-builder.ts","../src/scheduler.ts"],"sourcesContent":["export function applyTemplate(payload: Record<string, unknown>, prevOutput: string): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(payload).map(([k, v]) => [\n k,\n typeof v === \"string\" ? v.replaceAll(\"{{prevOutput}}\", prevOutput) : v,\n ]),\n );\n}\n","import type { Workplan, WorkplanResult, WorkplanRunner, WorkplanRunContext, StepResult, WorkplanStep } from \"./types.js\";\nimport { applyTemplate } from \"./template.js\";\n\nconst INLINE_PROVIDERS = new Set([\"anthropic\", \"openai\", \"ollama\", \"shell\", \"file\"]);\n\nasync function runInlineStep(step: WorkplanStep, prompt: string): Promise<string> {\n const provider = step.provider!;\n if (provider === \"anthropic\") {\n const { runAnthropicStep } = await import(\"./providers/anthropic.js\");\n return runAnthropicStep({ model: step.model ?? \"claude-haiku-4-5-20251001\", prompt });\n }\n if (provider === \"openai\") {\n const { runOpenAIStep } = await import(\"./providers/openai.js\");\n return runOpenAIStep({ model: step.model ?? \"gpt-4o-mini\", prompt });\n }\n if (provider === \"ollama\") {\n const { runOllamaStep } = await import(\"./providers/ollama.js\");\n return runOllamaStep({ model: step.model ?? \"llama3\", prompt });\n }\n if (provider === \"shell\") {\n const { runShellStep } = await import(\"./providers/shell.js\");\n return runShellStep({\n command: String(step.payload.command ?? \"\"),\n cwd: typeof step.payload.cwd === \"string\" ? step.payload.cwd : undefined,\n });\n }\n if (provider === \"file\") {\n const { runFileStep } = await import(\"./providers/file.js\");\n return runFileStep({ path: String(step.payload.path ?? \"\") });\n }\n throw new Error(`unknown inline provider: ${provider}`);\n}\n\nexport class SequentialWorkplanRunner implements WorkplanRunner {\n async run(plan: Workplan, ctx: WorkplanRunContext): Promise<WorkplanResult> {\n const results: StepResult[] = [];\n let prevOutput = \"\";\n let planSucceeded = true;\n\n for (const step of plan.steps) {\n const payload = prevOutput ? applyTemplate(step.payload, prevOutput) : step.payload;\n const prompt = typeof payload.prompt === \"string\" ? payload.prompt : \"\";\n const start = Date.now();\n let output = \"\";\n let exitCode = 0;\n\n try {\n if (step.provider && INLINE_PROVIDERS.has(step.provider)) {\n output = await runInlineStep({ ...step, payload }, prompt);\n } else {\n const node = await ctx.resolveNode(step.requires ?? [], step.provider);\n const result = await node.execute({ ...step, payload });\n output = result.output;\n exitCode = result.exitCode;\n }\n } catch (err) {\n exitCode = 1;\n output = err instanceof Error ? err.message : String(err);\n planSucceeded = false;\n\n const stepResult: StepResult = {\n stepId: step.id,\n output,\n exitCode,\n durationMs: Date.now() - start,\n };\n results.push(stepResult);\n ctx.emitResult(step.id, step.name, output);\n\n if (!step.continueOnError) {\n return {\n planId: plan.id,\n status: \"step_failed\",\n steps: results,\n succeeded: false,\n };\n }\n prevOutput = \"\";\n continue;\n }\n\n const dest = step.output?.dest ?? \"stdout\";\n const stepResult: StepResult = {\n stepId: step.id,\n output,\n exitCode,\n durationMs: Date.now() - start,\n };\n results.push(stepResult);\n\n if (dest === \"stdout\" || dest === \"artifact\") {\n ctx.emitResult(step.id, step.name, output);\n prevOutput = \"\";\n } else if (dest === \"next\") {\n prevOutput = output;\n }\n }\n\n return {\n planId: plan.id,\n status: planSucceeded ? \"completed\" : \"failed\",\n steps: results,\n succeeded: planSucceeded,\n };\n }\n}\n","export function printStepResult(stepName: string, output: string): void {\n process.stdout.write(`=== step: ${stepName} ===\\n${output}\\n\\n`);\n}\n","import type { NodeHandle, WorkplanRunContext, WorkplanStep, StepResult } from \"./types.js\";\nimport { printStepResult } from \"./sinks/stdout.js\";\n\nexport interface LocalWorkplanContextOptions {\n serverUrl?: string;\n nodeToken?: string;\n}\n\nclass WorkplaneNodeHandle implements NodeHandle {\n constructor(\n private readonly serverUrl: string,\n private readonly nodeToken: string,\n ) {}\n\n async execute(step: WorkplanStep): Promise<StepResult> {\n const start = Date.now();\n const taskRes = await fetch(`${this.serverUrl}/tasks`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${this.nodeToken}`,\n },\n body: JSON.stringify({\n kind: \"workplan.step\",\n adapter: step.adapter,\n payload: step.payload,\n requires: step.requires ?? [],\n }),\n });\n\n if (!taskRes.ok) {\n throw new Error(`failed to submit step ${step.id}: ${taskRes.status}`);\n }\n\n const task = (await taskRes.json()) as { id: string };\n const output = await this.pollUntilDone(task.id);\n return { stepId: step.id, output, exitCode: 0, durationMs: Date.now() - start };\n }\n\n private async pollUntilDone(taskId: string): Promise<string> {\n const terminalStatuses = new Set([\"succeeded\", \"failed\", \"cancelled\"]);\n for (;;) {\n await new Promise((r) => setTimeout(r, 1000));\n const res = await fetch(`${this.serverUrl}/tasks/${taskId}`, {\n headers: { authorization: `Bearer ${this.nodeToken}` },\n });\n const task = (await res.json()) as { status: string; payload?: Record<string, unknown> };\n if (terminalStatuses.has(task.status)) {\n if (task.status !== \"succeeded\") {\n throw new Error(`step task ${taskId} ended with status: ${task.status}`);\n }\n return typeof task.payload?.output === \"string\" ? task.payload.output : \"\";\n }\n }\n }\n}\n\nexport class LocalWorkplanContext implements WorkplanRunContext {\n private readonly serverUrl: string;\n private readonly nodeToken: string;\n\n constructor(opts: LocalWorkplanContextOptions = {}) {\n this.serverUrl = opts.serverUrl ?? process.env.WORKPLANE_SERVER_URL ?? \"http://localhost:8787\";\n this.nodeToken = opts.nodeToken ?? process.env.WORKPLANE_NODE_TOKEN ?? \"\";\n }\n\n async resolveNode(_requires: string[], _provider?: string): Promise<NodeHandle> {\n return new WorkplaneNodeHandle(this.serverUrl, this.nodeToken);\n }\n\n emitResult(_stepId: string, stepName: string, output: string): void {\n printStepResult(stepName, output);\n }\n}\n","import { CronExpressionParser } from \"cron-parser\";\nimport type { WorkplanSchedule } from \"./types.js\";\n\nexport class ScheduleBuilder {\n static nextRunAt(cronExpression: string, timezone: string): string {\n const expr = CronExpressionParser.parse(cronExpression, { tz: timezone });\n return expr.next().toISOString() ?? new Date().toISOString();\n }\n\n static withNextRunAt(schedule: WorkplanSchedule): WorkplanSchedule {\n return {\n ...schedule,\n nextRunAt: ScheduleBuilder.nextRunAt(schedule.cronExpression, schedule.timezone),\n };\n }\n}\n","import type {\n WorkplanRunRecord,\n WorkplanScheduleRecord,\n WorkplanStepResultInput,\n} from \"../../types/src/index.js\";\nimport { ScheduleBuilder } from \"./schedule-builder.js\";\nimport { SequentialWorkplanRunner } from \"./runner.js\";\nimport type { Workplan, WorkplanRunContext, WorkplanRunner } from \"./types.js\";\n\nexport interface ScheduleStore {\n listDueWorkplanSchedules(asOf: string): Promise<WorkplanScheduleRecord[]>;\n getWorkplanSchedule(scheduleId: string): Promise<WorkplanScheduleRecord | null>;\n markWorkplanScheduleRan(scheduleId: string, lastRunAt: string, nextRunAt: string): Promise<void>;\n tryCreateWorkplanRun(input: {\n scheduleId?: string;\n planId: string;\n planName: string;\n idempotencyKey?: string;\n }): Promise<WorkplanRunRecord | null>;\n updateWorkplanRun(\n runId: string,\n status: WorkplanRunRecord[\"status\"],\n error?: string,\n endedAt?: string,\n ): Promise<WorkplanRunRecord | null>;\n appendWorkplanStepResults(runId: string, steps: WorkplanStepResultInput[]): Promise<unknown>;\n}\n\nexport interface PlanResolver {\n resolve(planId: string, inputs: Record<string, unknown>): Workplan;\n}\n\nexport interface ExecuteScheduleOptions {\n advanceSchedule?: boolean;\n idempotencyKey?: string;\n}\n\nexport class WorkplanScheduler {\n constructor(\n private readonly store: ScheduleStore,\n private readonly resolver: PlanResolver,\n private readonly contextFactory: () => WorkplanRunContext,\n private readonly runner: WorkplanRunner = new SequentialWorkplanRunner(),\n ) {}\n\n async tick(now = new Date()): Promise<WorkplanRunRecord[]> {\n const due = await this.store.listDueWorkplanSchedules(now.toISOString());\n const launched: WorkplanRunRecord[] = [];\n\n for (const schedule of due) {\n if (!schedule.nextRunAt) {\n continue;\n }\n const run = await this.executeSchedule(schedule, {\n scheduledTime: schedule.nextRunAt,\n advanceSchedule: true,\n });\n if (run) {\n launched.push(run);\n }\n }\n\n return launched;\n }\n\n async runNow(scheduleId: string): Promise<WorkplanRunRecord | null> {\n const schedule = await this.store.getWorkplanSchedule(scheduleId);\n if (!schedule) {\n return null;\n }\n\n return this.executeSchedule(schedule, {\n scheduledTime: new Date().toISOString(),\n advanceSchedule: false,\n });\n }\n\n async executeSchedule(\n schedule: WorkplanScheduleRecord,\n options: ExecuteScheduleOptions & { scheduledTime: string },\n ): Promise<WorkplanRunRecord | null> {\n const idempotencyKey = options.idempotencyKey\n ?? (options.advanceSchedule ? `${schedule.id}:${options.scheduledTime}` : undefined);\n\n const run = await this.store.tryCreateWorkplanRun({\n scheduleId: schedule.id,\n planId: schedule.planId,\n planName: schedule.name,\n idempotencyKey,\n });\n if (!run) {\n return null;\n }\n\n if (options.advanceSchedule) {\n const nextRunAt = ScheduleBuilder.nextRunAt(schedule.cronExpression, schedule.timezone);\n await this.store.markWorkplanScheduleRan(schedule.id, options.scheduledTime, nextRunAt);\n }\n\n try {\n const plan = this.resolver.resolve(schedule.planId, schedule.inputs);\n const result = await this.runner.run(plan, this.contextFactory());\n const stepNames = new Map(plan.steps.map((step) => [step.id, step.name]));\n const stepInputs: WorkplanStepResultInput[] = result.steps.map((step) => ({\n stepId: step.stepId,\n stepName: stepNames.get(step.stepId) ?? step.stepId,\n output: step.output,\n exitCode: step.exitCode,\n durationMs: step.durationMs,\n metadata: step.metadata,\n }));\n await this.store.appendWorkplanStepResults(run.id, stepInputs);\n\n const error = result.succeeded ? undefined : result.steps.at(-1)?.output;\n return await this.store.updateWorkplanRun(run.id, result.status, error);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return await this.store.updateWorkplanRun(run.id, \"failed\", message);\n }\n }\n}\n"],"mappings":"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","names":["runShellStep","runFileStep","stepResult"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workplane/workplans",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",