@hachej/boring-automation 0.1.71 → 0.1.79

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.
@@ -1,7 +1,10 @@
1
+ import { WorkspaceAgentDispatcherResolver } from '@hachej/boring-agent/server';
2
+ import { FastifyRequest, FastifyInstance } from 'fastify';
3
+ import { WorkspaceAgentServerPluginContext } from '@hachej/boring-workspace/app/server';
1
4
  import { WorkspaceServerPlugin } from '@hachej/boring-workspace/server';
2
- import { Automation, AutomationCreate, AutomationPatch, AutomationRunCreate, AutomationRun, AutomationRunPatch, BoringAutomationErrorCode } from '../shared/index.js';
3
- export { AutomationCreateInput, AutomationCreateSchema, AutomationPatchInput, AutomationPatchSchema, AutomationRunCreateInput, AutomationRunCreateSchema, AutomationRunPatchInput, AutomationRunPatchSchema, AutomationRunStatus, AutomationRunStatusSchema, AutomationRunTrigger, AutomationRunTriggerSchema, BORING_AUTOMATION_ERROR_CODES, BORING_AUTOMATION_PLUGIN_ID, BORING_AUTOMATION_PLUGIN_LABEL, BORING_AUTOMATION_ROUTE_PREFIX, IdParamsSchema, PromptUpdateSchema } from '../shared/index.js';
4
- import { FastifyInstance } from 'fastify';
5
+ import { Automation, AutomationCreate, AutomationPatch, AutomationRunBegin, AutomationRun, AutomationRunLifecyclePatch, BoringAutomationErrorCode, AutomationScheduleDecision } from '../shared/index.js';
6
+ export { AUTOMATION_SCHEDULE_ERRORS, AutomationCreateInput, AutomationCreateSchema, AutomationPatchInput, AutomationPatchSchema, AutomationRunBeginInput, AutomationRunBeginSchema, AutomationRunLifecyclePatchInput, AutomationRunLifecyclePatchSchema, AutomationRunStatus, AutomationRunStatusSchema, AutomationRunTrigger, AutomationRunTriggerSchema, AutomationScheduleDueDecision, AutomationScheduleDueReason, AutomationScheduleSkipDecision, AutomationScheduleSkipReason, AutomationScheduleValidationResult, BORING_AUTOMATION_ERROR_CODES, BORING_AUTOMATION_PLUGIN_ID, BORING_AUTOMATION_PLUGIN_LABEL, BORING_AUTOMATION_ROUTE_PREFIX, EvaluateAutomationScheduleInput, EvaluateAutomationScheduleResult, IdParamsSchema, PromptUpdateSchema, evaluateAutomationSchedule, isValidFiveFieldCron, isValidIanaTimeZone, validateAutomationSchedule } from '../shared/index.js';
7
+ import postgres from 'postgres';
5
8
  import 'zod';
6
9
 
7
10
  /** Plugin-local dependency injection seam for the single-workspace automation store. */
@@ -13,10 +16,10 @@ interface AutomationStore {
13
16
  deleteAutomation(id: string): Promise<void>;
14
17
  getPrompt(automationId: string): Promise<string>;
15
18
  updatePrompt(automationId: string, body: string): Promise<void>;
16
- createRun(input: AutomationRunCreate): Promise<AutomationRun>;
17
- updateRun(runId: string, patch: AutomationRunPatch): Promise<AutomationRun>;
19
+ reconcileOrphanedRuns(automationId: string): Promise<void>;
20
+ beginRun(input: AutomationRunBegin): Promise<AutomationRun>;
21
+ updateRunLifecycle(runId: string, patch: AutomationRunLifecyclePatch): Promise<AutomationRun>;
18
22
  listRuns(automationId: string): Promise<AutomationRun[]>;
19
- findRunningRun(automationId: string): Promise<AutomationRun | null>;
20
23
  }
21
24
  declare class AutomationStoreError extends Error {
22
25
  readonly code: BoringAutomationErrorCode;
@@ -24,17 +27,90 @@ declare class AutomationStoreError extends Error {
24
27
  }
25
28
  declare function automationNotFound(id: string): AutomationStoreError;
26
29
  declare function runNotFound(id: string): AutomationStoreError;
30
+ declare function runAlreadyActive(automationId: string): AutomationStoreError;
31
+ declare function runAlreadyRecorded(automationId: string, scheduledFor: string): AutomationStoreError;
32
+
33
+ interface VerifiedAutomationActor {
34
+ workspaceId: string;
35
+ userId: string;
36
+ }
37
+ interface ManualRunExecutorOptions {
38
+ store: AutomationStore;
39
+ storeForRequest?: (request: FastifyRequest, actor: VerifiedAutomationActor) => Promise<AutomationStore> | AutomationStore;
40
+ dispatcherResolver: WorkspaceAgentDispatcherResolver;
41
+ actorResolver: (request: FastifyRequest) => Promise<VerifiedAutomationActor> | VerifiedAutomationActor;
42
+ clock?: () => Date;
43
+ }
44
+ interface ManualRunInput {
45
+ automationId: string;
46
+ request: FastifyRequest;
47
+ trigger?: "manual" | "scheduled";
48
+ scheduledFor?: string | null;
49
+ }
50
+ declare class ManualRunExecutor {
51
+ private readonly options;
52
+ private readonly clock;
53
+ constructor(options: ManualRunExecutorOptions);
54
+ run(input: ManualRunInput): Promise<AutomationRun>;
55
+ private finalizeRun;
56
+ private nowIso;
57
+ }
58
+ declare function parseAutomationModel(value: string): {
59
+ provider: string;
60
+ id: string;
61
+ };
62
+
63
+ type DueRunSummary = Pick<AutomationRun, "id" | "automationId" | "sessionId" | "status" | "trigger" | "scheduledFor" | "startedAt" | "completedAt" | "durationMs" | "inputTokens" | "outputTokens" | "totalTokens">;
64
+ type DueRunOutcome = {
65
+ kind: "started";
66
+ automationId: string;
67
+ scheduledFor: string;
68
+ run: DueRunSummary;
69
+ } | {
70
+ kind: "skipped";
71
+ automationId: string;
72
+ scheduledFor: string | null;
73
+ reason: string;
74
+ message: string;
75
+ } | {
76
+ kind: "failed";
77
+ automationId: string;
78
+ scheduledFor: string;
79
+ code: string;
80
+ message: string;
81
+ };
82
+ interface DueRunResult {
83
+ now: string;
84
+ decisions: AutomationScheduleDecision[];
85
+ outcomes: DueRunOutcome[];
86
+ }
87
+ interface DueRunServiceOptions {
88
+ store: AutomationStore;
89
+ executor: Pick<ManualRunExecutor, "run">;
90
+ clock?: () => Date;
91
+ }
92
+ /** Deterministic, externally invoked due-run orchestration. It owns no timer. */
93
+ declare class DueRunService {
94
+ private readonly options;
95
+ private readonly clock;
96
+ constructor(options: DueRunServiceOptions);
97
+ runDue(request: FastifyRequest): Promise<DueRunResult>;
98
+ }
27
99
 
28
100
  type AtomicWriter = (path: string, content: string) => Promise<void>;
29
101
  interface FileAutomationStoreOptions {
30
102
  writer?: AtomicWriter;
103
+ clock?: () => Date;
31
104
  }
32
105
  declare class FileAutomationStore implements AutomationStore {
33
106
  private readonly rootDir;
34
107
  private state;
35
108
  private loadInFlight;
36
109
  private writeChain;
110
+ /** Active runs owned by this store process; persisted active runs are orphaned after restart. */
111
+ private readonly activeRunIds;
37
112
  private readonly writer;
113
+ private readonly clock;
38
114
  constructor(rootDir: string, options?: FileAutomationStoreOptions);
39
115
  listAutomations(): Promise<Automation[]>;
40
116
  getAutomation(id: string): Promise<Automation | null>;
@@ -43,29 +119,61 @@ declare class FileAutomationStore implements AutomationStore {
43
119
  deleteAutomation(id: string): Promise<void>;
44
120
  getPrompt(automationId: string): Promise<string>;
45
121
  updatePrompt(automationId: string, body: string): Promise<void>;
46
- createRun(input: AutomationRunCreate): Promise<AutomationRun>;
47
- updateRun(runId: string, patch: AutomationRunPatch): Promise<AutomationRun>;
122
+ reconcileOrphanedRuns(automationId: string): Promise<void>;
123
+ beginRun(input: AutomationRunBegin): Promise<AutomationRun>;
124
+ updateRunLifecycle(runId: string, patch: AutomationRunLifecyclePatch): Promise<AutomationRun>;
48
125
  listRuns(automationId: string): Promise<AutomationRun[]>;
49
- findRunningRun(automationId: string): Promise<AutomationRun | null>;
50
126
  private statePath;
51
127
  private promptPath;
52
128
  private writePromptFile;
53
129
  private mutate;
130
+ private nowIso;
54
131
  private load;
55
132
  }
56
133
 
134
+ /** Deployment-owned hosted schema registration for the automation plugin. */
135
+ declare function runBoringAutomationMigrations(sql: postgres.Sql): Promise<void>;
136
+
137
+ interface HostedAutomationActor {
138
+ workspaceId: string;
139
+ userId: string;
140
+ }
141
+ type Sql = postgres.Sql;
142
+ /** Hosted store bound to a verified workspace/user pair; every query is scoped by both. */
143
+ declare class PostgresAutomationStore implements AutomationStore {
144
+ private readonly sql;
145
+ private readonly actor;
146
+ private readonly clock;
147
+ constructor(sql: Sql, actor: HostedAutomationActor, clock?: () => Date);
148
+ listAutomations(): Promise<Automation[]>;
149
+ getAutomation(id: string): Promise<Automation | null>;
150
+ createAutomation(input: AutomationCreate): Promise<Automation>;
151
+ updateAutomation(id: string, patch: AutomationPatch): Promise<Automation>;
152
+ deleteAutomation(id: string): Promise<void>;
153
+ getPrompt(automationId: string): Promise<string>;
154
+ updatePrompt(automationId: string, body: string): Promise<void>;
155
+ reconcileOrphanedRuns(automationId: string): Promise<void>;
156
+ beginRun(input: AutomationRunBegin): Promise<AutomationRun>;
157
+ updateRunLifecycle(runId: string, patch: AutomationRunLifecyclePatch): Promise<AutomationRun>;
158
+ listRuns(automationId: string): Promise<AutomationRun[]>;
159
+ private findRun;
160
+ }
161
+
57
162
  interface AutomationRoutesOptions {
58
163
  store: AutomationStore;
164
+ storeForRequest?: (request: FastifyRequest) => Promise<AutomationStore> | AutomationStore;
165
+ manualRunExecutor?: Pick<ManualRunExecutor, "run">;
166
+ dueRunService?: Pick<DueRunService, "runDue">;
59
167
  }
60
168
  declare function automationRoutes(app: FastifyInstance, opts: AutomationRoutesOptions): Promise<void>;
61
169
 
62
170
  interface BoringAutomationServerPluginOptions {
63
171
  workspaceRoot?: string;
64
172
  store?: AutomationStore;
173
+ dispatcherResolver?: WorkspaceAgentDispatcherResolver;
174
+ actorResolver?: (request: FastifyRequest) => Promise<VerifiedAutomationActor> | VerifiedAutomationActor;
65
175
  }
66
176
  declare function createBoringAutomationServerPlugin(options?: BoringAutomationServerPluginOptions): WorkspaceServerPlugin;
67
- declare function defaultBoringAutomationServerPlugin(options?: BoringAutomationServerPluginOptions, ctx?: {
68
- workspaceRoot?: string;
69
- }): WorkspaceServerPlugin;
177
+ declare function defaultBoringAutomationServerPlugin(options?: BoringAutomationServerPluginOptions, ctx?: Pick<WorkspaceAgentServerPluginContext, "workspaceRoot"> & Partial<Pick<WorkspaceAgentServerPluginContext, "trusted">>): WorkspaceServerPlugin;
70
178
 
71
- export { Automation, AutomationCreate, AutomationPatch, type AutomationRoutesOptions, AutomationRun, AutomationRunCreate, AutomationRunPatch, type AutomationStore, AutomationStoreError, BoringAutomationErrorCode, type BoringAutomationServerPluginOptions, FileAutomationStore, type FileAutomationStoreOptions, automationNotFound, automationRoutes, createBoringAutomationServerPlugin, defaultBoringAutomationServerPlugin as default, runNotFound };
179
+ export { Automation, AutomationCreate, AutomationPatch, type AutomationRoutesOptions, AutomationRun, AutomationRunBegin, AutomationRunLifecyclePatch, AutomationScheduleDecision, type AutomationStore, AutomationStoreError, BoringAutomationErrorCode, type BoringAutomationServerPluginOptions, type DueRunOutcome, type DueRunResult, DueRunService, type DueRunServiceOptions, type DueRunSummary, FileAutomationStore, type FileAutomationStoreOptions, type HostedAutomationActor, ManualRunExecutor, type ManualRunExecutorOptions, type ManualRunInput, PostgresAutomationStore, type VerifiedAutomationActor, automationNotFound, automationRoutes, createBoringAutomationServerPlugin, defaultBoringAutomationServerPlugin as default, parseAutomationModel, runAlreadyActive, runAlreadyRecorded, runBoringAutomationMigrations, runNotFound };