@hasna/loops 0.4.13 → 0.4.22
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/CHANGELOG.md +99 -3
- package/README.md +171 -39
- package/dist/api/index.d.ts +36 -0
- package/dist/api/index.js +1518 -15
- package/dist/cli/index.js +7280 -3213
- package/dist/cli/ui.d.ts +44 -0
- package/dist/daemon/index.js +1433 -303
- package/dist/generated/storage-kit/health.d.ts +19 -0
- package/dist/generated/storage-kit/index.d.ts +7 -0
- package/dist/generated/storage-kit/migrations.d.ts +47 -0
- package/dist/generated/storage-kit/mode.d.ts +47 -0
- package/dist/generated/storage-kit/pool.d.ts +33 -0
- package/dist/generated/storage-kit/query.d.ts +35 -0
- package/dist/generated/storage-kit/tls.d.ts +25 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8689 -4837
- package/dist/lib/cloud/mode.d.ts +17 -0
- package/dist/lib/cloud/resolve.d.ts +16 -0
- package/dist/lib/cloud/storage.d.ts +82 -0
- package/dist/lib/cloud/transport.d.ts +148 -0
- package/dist/lib/format.d.ts +2 -1
- package/dist/lib/health.d.ts +83 -3
- package/dist/lib/migration.d.ts +40 -0
- package/dist/lib/mode.js +15 -3
- package/dist/lib/route/index.d.ts +2 -0
- package/dist/lib/route/policies.d.ts +51 -0
- package/dist/lib/route/provider-admission.d.ts +37 -0
- package/dist/lib/route/throttle.d.ts +4 -0
- package/dist/lib/route/types.d.ts +8 -0
- package/dist/lib/run-receipts.d.ts +14 -0
- package/dist/lib/scheduler.d.ts +5 -2
- package/dist/lib/storage/contract.d.ts +7 -1
- package/dist/lib/storage/index.d.ts +1 -0
- package/dist/lib/storage/index.js +2028 -231
- package/dist/lib/storage/pg-executor.d.ts +27 -0
- package/dist/lib/storage/pg-runner-claim.d.ts +40 -0
- package/dist/lib/storage/postgres-loop-storage.d.ts +120 -0
- package/dist/lib/storage/postgres-schema.js +29 -0
- package/dist/lib/storage/postgres.js +29 -0
- package/dist/lib/storage/sqlite.d.ts +6 -0
- package/dist/lib/storage/sqlite.js +748 -26
- package/dist/lib/store/index.d.ts +268 -0
- package/dist/lib/store.d.ts +282 -1
- package/dist/lib/store.js +746 -26
- package/dist/lib/template-kit.d.ts +25 -0
- package/dist/lib/templates.d.ts +16 -1
- package/dist/mcp/http.d.ts +16 -0
- package/dist/mcp/index.js +2885 -634
- package/dist/runner/index.js +198 -32
- package/dist/sdk/http.d.ts +182 -0
- package/dist/sdk/http.js +166 -0
- package/dist/sdk/index.d.ts +55 -18
- package/dist/sdk/index.js +2734 -617
- package/dist/serve/index.d.ts +4 -0
- package/dist/serve/index.js +9095 -0
- package/dist/types.d.ts +52 -0
- package/docs/AUTOMATION_RUNTIME_DESIGN.md +442 -1
- package/docs/CUTOVER-RUNBOOK.md +78 -0
- package/docs/DEPLOYMENT_MODES.md +35 -18
- package/docs/RUNTIME_BOUNDARY.md +203 -0
- package/docs/USAGE.md +195 -38
- package/package.json +15 -3
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PoolQueryClient } from "../../generated/storage-kit/query.js";
|
|
2
|
+
import type { PostgresQueryExecutor } from "./postgres.js";
|
|
3
|
+
export interface PgExecutorOptions {
|
|
4
|
+
connectionString: string;
|
|
5
|
+
max?: number;
|
|
6
|
+
applicationName?: string;
|
|
7
|
+
connectionTimeoutMillis?: number;
|
|
8
|
+
idleTimeoutMillis?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* `PostgresQueryExecutor` backed by a live `pg.Pool` via the vendored kit.
|
|
12
|
+
*
|
|
13
|
+
* Transaction support is intentionally omitted: `PostgresStorage.migrate`
|
|
14
|
+
* treats DDL as idempotent (`CREATE ... IF NOT EXISTS` + a checksum ledger), so
|
|
15
|
+
* a pooled sequential apply is correct and avoids binding every inner
|
|
16
|
+
* `execute` to a single dedicated client.
|
|
17
|
+
*/
|
|
18
|
+
export declare class PgPoolExecutor implements PostgresQueryExecutor {
|
|
19
|
+
private readonly client;
|
|
20
|
+
constructor(client: PoolQueryClient);
|
|
21
|
+
static fromConnectionString(options: PgExecutorOptions): PgPoolExecutor;
|
|
22
|
+
/** The underlying typed query client, for callers that need `get`/`one`/`transaction`. */
|
|
23
|
+
get queryClient(): PoolQueryClient;
|
|
24
|
+
query<T extends Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<T[]>;
|
|
25
|
+
execute(sql: string, params?: readonly unknown[]): Promise<void>;
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { PoolQueryClient } from "../../generated/storage-kit/query.js";
|
|
2
|
+
export interface ClaimedRunRow extends Record<string, unknown> {
|
|
3
|
+
id: string;
|
|
4
|
+
loop_id: string;
|
|
5
|
+
loop_name: string;
|
|
6
|
+
scheduled_for: string | Date;
|
|
7
|
+
attempt: number;
|
|
8
|
+
status: string;
|
|
9
|
+
claimed_by: string | null;
|
|
10
|
+
claim_token: string | null;
|
|
11
|
+
lease_expires_at: string | Date | null;
|
|
12
|
+
}
|
|
13
|
+
export interface ClaimNextRunOptions {
|
|
14
|
+
runnerId: string;
|
|
15
|
+
leaseMs: number;
|
|
16
|
+
claimToken: string;
|
|
17
|
+
/** Statuses a run may be in to be claimable. Defaults to queued + lease-expired running. */
|
|
18
|
+
now?: Date;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Atomically claim the next claimable run for `runnerId`.
|
|
22
|
+
*
|
|
23
|
+
* A run is claimable when it is `queued`, or `running` with an expired lease
|
|
24
|
+
* (crash recovery). Returns the claimed row, or `null` when nothing was
|
|
25
|
+
* available. Two concurrent callers are guaranteed to receive distinct rows
|
|
26
|
+
* (or one receives `null`) thanks to `FOR UPDATE SKIP LOCKED`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function claimNextRun(client: PoolQueryClient, options: ClaimNextRunOptions): Promise<ClaimedRunRow | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Heartbeat a claimed run's lease. Returns true when the lease was extended
|
|
31
|
+
* (the caller still owns the run), false when ownership was lost (claim token
|
|
32
|
+
* mismatch, run finalized, or lease already stolen).
|
|
33
|
+
*/
|
|
34
|
+
export declare function heartbeatRunLease(client: PoolQueryClient, input: {
|
|
35
|
+
runId: string;
|
|
36
|
+
runnerId: string;
|
|
37
|
+
claimToken: string;
|
|
38
|
+
leaseMs: number;
|
|
39
|
+
now?: Date;
|
|
40
|
+
}): Promise<boolean>;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { RecoverExpiredRunLeasesResult } from "../store.js";
|
|
2
|
+
import { Store } from "../store.js";
|
|
3
|
+
import type { PoolQueryClient } from "../../generated/storage-kit/query.js";
|
|
4
|
+
import type { LoopStorageContract, LoopStorageMethodName } from "./contract.js";
|
|
5
|
+
/** Thrown by store methods that are not yet ported to the Postgres backend. */
|
|
6
|
+
export declare class NotImplementedError extends Error {
|
|
7
|
+
readonly code = "not_implemented";
|
|
8
|
+
constructor(method: string);
|
|
9
|
+
}
|
|
10
|
+
type M<K extends LoopStorageMethodName> = Store[K] extends (...a: infer A) => infer R ? {
|
|
11
|
+
args: A;
|
|
12
|
+
result: R;
|
|
13
|
+
} : never;
|
|
14
|
+
export declare class PostgresLoopStorage implements LoopStorageContract {
|
|
15
|
+
private readonly client;
|
|
16
|
+
readonly backend = "postgres";
|
|
17
|
+
readonly supportsRemoteRunners = true;
|
|
18
|
+
constructor(client: PoolQueryClient);
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
private assertDaemonLeaseFence;
|
|
21
|
+
private loadLoop;
|
|
22
|
+
private loadRun;
|
|
23
|
+
private loadRunBySlot;
|
|
24
|
+
private loadDaemonLease;
|
|
25
|
+
private setWorkItemsForLoop;
|
|
26
|
+
private setWorkItemsForWorkflowRun;
|
|
27
|
+
private cascadeWorkItemsForLoopRun;
|
|
28
|
+
createLoop(...args: M<"createLoop">["args"]): Promise<M<"createLoop">["result"]>;
|
|
29
|
+
getLoop(...args: M<"getLoop">["args"]): Promise<M<"getLoop">["result"]>;
|
|
30
|
+
findLoopByName(...args: M<"findLoopByName">["args"]): Promise<M<"findLoopByName">["result"]>;
|
|
31
|
+
requireLoop(...args: M<"requireLoop">["args"]): Promise<M<"requireLoop">["result"]>;
|
|
32
|
+
listLoops(...args: M<"listLoops">["args"]): Promise<M<"listLoops">["result"]>;
|
|
33
|
+
dueLoops(...args: M<"dueLoops">["args"]): Promise<M<"dueLoops">["result"]>;
|
|
34
|
+
updateLoop(...args: M<"updateLoop">["args"]): Promise<M<"updateLoop">["result"]>;
|
|
35
|
+
renameLoop(...args: M<"renameLoop">["args"]): Promise<M<"renameLoop">["result"]>;
|
|
36
|
+
archiveLoop(...args: M<"archiveLoop">["args"]): Promise<M<"archiveLoop">["result"]>;
|
|
37
|
+
unarchiveLoop(...args: M<"unarchiveLoop">["args"]): Promise<M<"unarchiveLoop">["result"]>;
|
|
38
|
+
deleteLoop(...args: M<"deleteLoop">["args"]): Promise<M<"deleteLoop">["result"]>;
|
|
39
|
+
private requireLoopIn;
|
|
40
|
+
countLoops(...args: M<"countLoops">["args"]): Promise<M<"countLoops">["result"]>;
|
|
41
|
+
upsertMigrationWorkflow(...args: M<"upsertMigrationWorkflow">["args"]): Promise<M<"upsertMigrationWorkflow">["result"]>;
|
|
42
|
+
upsertMigrationLoop(...args: M<"upsertMigrationLoop">["args"]): Promise<M<"upsertMigrationLoop">["result"]>;
|
|
43
|
+
upsertMigrationRun(...args: M<"upsertMigrationRun">["args"]): Promise<M<"upsertMigrationRun">["result"]>;
|
|
44
|
+
createSkippedRun(...args: M<"createSkippedRun">["args"]): Promise<M<"createSkippedRun">["result"]>;
|
|
45
|
+
getRun(...args: M<"getRun">["args"]): Promise<M<"getRun">["result"]>;
|
|
46
|
+
getRunBySlot(...args: M<"getRunBySlot">["args"]): Promise<M<"getRunBySlot">["result"]>;
|
|
47
|
+
/**
|
|
48
|
+
* Claim a specific loop slot for a runner.
|
|
49
|
+
*
|
|
50
|
+
* Divergence from the sqlite Store (documented, not accidental): the sqlite
|
|
51
|
+
* path also consults LOCAL process liveness (`isRecordedProcessAlive`,
|
|
52
|
+
* `hasLiveWorkflowStepProcesses`) before stealing an expired-lease run,
|
|
53
|
+
* because the daemon and the run's child process share a host. On the
|
|
54
|
+
* Postgres/remote backend the claiming runner may be a different machine than
|
|
55
|
+
* the one that holds the (possibly still-live) process, so local pid checks
|
|
56
|
+
* are meaningless. Ownership here is governed purely by lease expiry: an
|
|
57
|
+
* expired lease is reclaimable, a live lease is not. The lease/heartbeat
|
|
58
|
+
* contract (plus `FOR UPDATE` row locks) is the remote correctness boundary.
|
|
59
|
+
*/
|
|
60
|
+
claimRun(...args: M<"claimRun">["args"]): Promise<M<"claimRun">["result"]>;
|
|
61
|
+
finalizeRun(...args: M<"finalizeRun">["args"]): Promise<M<"finalizeRun">["result"]>;
|
|
62
|
+
heartbeatRunLease(...args: M<"heartbeatRunLease">["args"]): Promise<M<"heartbeatRunLease">["result"]>;
|
|
63
|
+
recordRunProcess(...args: M<"recordRunProcess">["args"]): Promise<M<"recordRunProcess">["result"]>;
|
|
64
|
+
listRuns(...args: M<"listRuns">["args"]): Promise<M<"listRuns">["result"]>;
|
|
65
|
+
writeRunReceipt(...args: M<"writeRunReceipt">["args"]): Promise<M<"writeRunReceipt">["result"]>;
|
|
66
|
+
getRunReceipt(...args: M<"getRunReceipt">["args"]): Promise<M<"getRunReceipt">["result"]>;
|
|
67
|
+
listRunReceipts(...args: M<"listRunReceipts">["args"]): Promise<M<"listRunReceipts">["result"]>;
|
|
68
|
+
countRuns(...args: M<"countRuns">["args"]): Promise<M<"countRuns">["result"]>;
|
|
69
|
+
recoverExpiredRunLeases(...args: M<"recoverExpiredRunLeases">["args"]): Promise<M<"recoverExpiredRunLeases">["result"]>;
|
|
70
|
+
/**
|
|
71
|
+
* Recover expired run leases. Divergence from sqlite (documented): the remote
|
|
72
|
+
* backend cannot inspect local process liveness, so an expired lease is always
|
|
73
|
+
* abandoned (never "deferred because the local process is still alive"). The
|
|
74
|
+
* `deferred` array is therefore always empty here. The generated-route
|
|
75
|
+
* workflow archival side effect is not ported (route automation is a TIER 2
|
|
76
|
+
* path); the core guarantee — no run stays `running` past its lease — holds.
|
|
77
|
+
*/
|
|
78
|
+
recoverExpiredRunLeasesDetailed(...args: M<"recoverExpiredRunLeasesDetailed">["args"]): Promise<RecoverExpiredRunLeasesResult>;
|
|
79
|
+
pruneHistory(...args: M<"pruneHistory">["args"]): Promise<M<"pruneHistory">["result"]>;
|
|
80
|
+
acquireDaemonLease(...args: M<"acquireDaemonLease">["args"]): Promise<M<"acquireDaemonLease">["result"]>;
|
|
81
|
+
heartbeatDaemonLease(...args: M<"heartbeatDaemonLease">["args"]): Promise<M<"heartbeatDaemonLease">["result"]>;
|
|
82
|
+
releaseDaemonLease(...args: M<"releaseDaemonLease">["args"]): Promise<M<"releaseDaemonLease">["result"]>;
|
|
83
|
+
getDaemonLease(...args: M<"getDaemonLease">["args"]): Promise<M<"getDaemonLease">["result"]>;
|
|
84
|
+
private loadWorkflow;
|
|
85
|
+
getWorkflow(...args: M<"getWorkflow">["args"]): Promise<M<"getWorkflow">["result"]>;
|
|
86
|
+
listWorkflows(...args: M<"listWorkflows">["args"]): Promise<M<"listWorkflows">["result"]>;
|
|
87
|
+
countWorkflows(...args: M<"countWorkflows">["args"]): Promise<M<"countWorkflows">["result"]>;
|
|
88
|
+
getWorkflowInvocation(...args: M<"getWorkflowInvocation">["args"]): Promise<M<"getWorkflowInvocation">["result"]>;
|
|
89
|
+
listWorkflowInvocations(...args: M<"listWorkflowInvocations">["args"]): Promise<M<"listWorkflowInvocations">["result"]>;
|
|
90
|
+
getWorkflowWorkItem(...args: M<"getWorkflowWorkItem">["args"]): Promise<M<"getWorkflowWorkItem">["result"]>;
|
|
91
|
+
listWorkflowWorkItems(...args: M<"listWorkflowWorkItems">["args"]): Promise<M<"listWorkflowWorkItems">["result"]>;
|
|
92
|
+
countActiveWorkflowWorkItems(...args: M<"countActiveWorkflowWorkItems">["args"]): Promise<M<"countActiveWorkflowWorkItems">["result"]>;
|
|
93
|
+
getWorkflowRun(...args: M<"getWorkflowRun">["args"]): Promise<M<"getWorkflowRun">["result"]>;
|
|
94
|
+
listWorkflowRuns(...args: M<"listWorkflowRuns">["args"]): Promise<M<"listWorkflowRuns">["result"]>;
|
|
95
|
+
listWorkflowStepRuns(...args: M<"listWorkflowStepRuns">["args"]): Promise<M<"listWorkflowStepRuns">["result"]>;
|
|
96
|
+
getWorkflowStepRun(...args: M<"getWorkflowStepRun">["args"]): Promise<M<"getWorkflowStepRun">["result"]>;
|
|
97
|
+
listWorkflowEvents(...args: M<"listWorkflowEvents">["args"]): Promise<M<"listWorkflowEvents">["result"]>;
|
|
98
|
+
getGoal(...args: M<"getGoal">["args"]): Promise<M<"getGoal">["result"]>;
|
|
99
|
+
listGoals(...args: M<"listGoals">["args"]): Promise<M<"listGoals">["result"]>;
|
|
100
|
+
listGoalPlanNodes(...args: M<"listGoalPlanNodes">["args"]): Promise<M<"listGoalPlanNodes">["result"]>;
|
|
101
|
+
listGoalRuns(...args: M<"listGoalRuns">["args"]): Promise<M<"listGoalRuns">["result"]>;
|
|
102
|
+
createWorkflow(): never;
|
|
103
|
+
archiveWorkflow(): never;
|
|
104
|
+
createWorkflowInvocation(): never;
|
|
105
|
+
upsertWorkflowWorkItem(): never;
|
|
106
|
+
admitWorkflowWorkItem(): never;
|
|
107
|
+
createGoal(): never;
|
|
108
|
+
createGoalPlanNodes(): never;
|
|
109
|
+
updateGoalStatus(): never;
|
|
110
|
+
updateGoalPlanNode(): never;
|
|
111
|
+
recordGoalEvent(): never;
|
|
112
|
+
createWorkflowRun(): never;
|
|
113
|
+
startWorkflowStepRun(): never;
|
|
114
|
+
recoverWorkflowRun(): never;
|
|
115
|
+
finalizeWorkflowStepRun(): never;
|
|
116
|
+
finalizeWorkflowRun(): never;
|
|
117
|
+
appendWorkflowEvent(): never;
|
|
118
|
+
}
|
|
119
|
+
export declare function createPostgresLoopStorage(client: PoolQueryClient): PostgresLoopStorage;
|
|
120
|
+
export {};
|
|
@@ -323,6 +323,35 @@ CREATE INDEX IF NOT EXISTS idx_audit_events_action ON audit_events(action, creat
|
|
|
323
323
|
migration("0004_work_item_route_scope", `
|
|
324
324
|
ALTER TABLE workflow_work_items ADD COLUMN IF NOT EXISTS route_scope TEXT;
|
|
325
325
|
CREATE INDEX IF NOT EXISTS idx_workflow_work_items_scope ON workflow_work_items(route_scope, status);
|
|
326
|
+
`),
|
|
327
|
+
migration("0005_run_receipts", `
|
|
328
|
+
CREATE TABLE IF NOT EXISTS run_receipts (
|
|
329
|
+
run_id TEXT PRIMARY KEY,
|
|
330
|
+
loop_id TEXT NOT NULL,
|
|
331
|
+
machine_json JSONB NOT NULL,
|
|
332
|
+
repo TEXT NOT NULL,
|
|
333
|
+
task_ids_json JSONB NOT NULL,
|
|
334
|
+
knowledge_ids_json JSONB NOT NULL,
|
|
335
|
+
digest_id TEXT NOT NULL,
|
|
336
|
+
started_at TIMESTAMPTZ,
|
|
337
|
+
finished_at TIMESTAMPTZ,
|
|
338
|
+
status TEXT NOT NULL,
|
|
339
|
+
exit_code INTEGER,
|
|
340
|
+
summary_json JSONB NOT NULL,
|
|
341
|
+
evidence_paths_json JSONB NOT NULL,
|
|
342
|
+
created_at TIMESTAMPTZ NOT NULL,
|
|
343
|
+
updated_at TIMESTAMPTZ NOT NULL
|
|
344
|
+
);
|
|
345
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_loop ON run_receipts(loop_id, created_at DESC);
|
|
346
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_repo ON run_receipts(repo, created_at DESC);
|
|
347
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_digest ON run_receipts(digest_id);
|
|
348
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_status ON run_receipts(status, created_at DESC);
|
|
349
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_task_ids ON run_receipts USING GIN (task_ids_json);
|
|
350
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_knowledge_ids ON run_receipts USING GIN (knowledge_ids_json);
|
|
351
|
+
`),
|
|
352
|
+
migration("0006_work_item_machine_id", `
|
|
353
|
+
ALTER TABLE workflow_work_items ADD COLUMN IF NOT EXISTS machine_id TEXT;
|
|
354
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_work_items_machine ON workflow_work_items(machine_id, status);
|
|
326
355
|
`)
|
|
327
356
|
]);
|
|
328
357
|
export {
|
|
@@ -323,6 +323,35 @@ CREATE INDEX IF NOT EXISTS idx_audit_events_action ON audit_events(action, creat
|
|
|
323
323
|
migration("0004_work_item_route_scope", `
|
|
324
324
|
ALTER TABLE workflow_work_items ADD COLUMN IF NOT EXISTS route_scope TEXT;
|
|
325
325
|
CREATE INDEX IF NOT EXISTS idx_workflow_work_items_scope ON workflow_work_items(route_scope, status);
|
|
326
|
+
`),
|
|
327
|
+
migration("0005_run_receipts", `
|
|
328
|
+
CREATE TABLE IF NOT EXISTS run_receipts (
|
|
329
|
+
run_id TEXT PRIMARY KEY,
|
|
330
|
+
loop_id TEXT NOT NULL,
|
|
331
|
+
machine_json JSONB NOT NULL,
|
|
332
|
+
repo TEXT NOT NULL,
|
|
333
|
+
task_ids_json JSONB NOT NULL,
|
|
334
|
+
knowledge_ids_json JSONB NOT NULL,
|
|
335
|
+
digest_id TEXT NOT NULL,
|
|
336
|
+
started_at TIMESTAMPTZ,
|
|
337
|
+
finished_at TIMESTAMPTZ,
|
|
338
|
+
status TEXT NOT NULL,
|
|
339
|
+
exit_code INTEGER,
|
|
340
|
+
summary_json JSONB NOT NULL,
|
|
341
|
+
evidence_paths_json JSONB NOT NULL,
|
|
342
|
+
created_at TIMESTAMPTZ NOT NULL,
|
|
343
|
+
updated_at TIMESTAMPTZ NOT NULL
|
|
344
|
+
);
|
|
345
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_loop ON run_receipts(loop_id, created_at DESC);
|
|
346
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_repo ON run_receipts(repo, created_at DESC);
|
|
347
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_digest ON run_receipts(digest_id);
|
|
348
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_status ON run_receipts(status, created_at DESC);
|
|
349
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_task_ids ON run_receipts USING GIN (task_ids_json);
|
|
350
|
+
CREATE INDEX IF NOT EXISTS idx_run_receipts_knowledge_ids ON run_receipts USING GIN (knowledge_ids_json);
|
|
351
|
+
`),
|
|
352
|
+
migration("0006_work_item_machine_id", `
|
|
353
|
+
ALTER TABLE workflow_work_items ADD COLUMN IF NOT EXISTS machine_id TEXT;
|
|
354
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_work_items_machine ON workflow_work_items(machine_id, status);
|
|
326
355
|
`)
|
|
327
356
|
]);
|
|
328
357
|
|
|
@@ -22,6 +22,9 @@ export declare class SqliteLoopStorage implements LoopStorageContract {
|
|
|
22
22
|
archiveLoop(...args: StoreMethod<"archiveLoop">["args"]): Promise<import("../../types.js").Loop>;
|
|
23
23
|
unarchiveLoop(...args: StoreMethod<"unarchiveLoop">["args"]): Promise<import("../../types.js").Loop>;
|
|
24
24
|
deleteLoop(...args: StoreMethod<"deleteLoop">["args"]): Promise<boolean>;
|
|
25
|
+
upsertMigrationLoop(...args: StoreMethod<"upsertMigrationLoop">["args"]): Promise<import("../../types.js").Loop>;
|
|
26
|
+
upsertMigrationRun(...args: StoreMethod<"upsertMigrationRun">["args"]): Promise<import("../../types.js").LoopRun>;
|
|
27
|
+
upsertMigrationWorkflow(...args: StoreMethod<"upsertMigrationWorkflow">["args"]): Promise<import("../../types.js").WorkflowSpec>;
|
|
25
28
|
createWorkflow(...args: StoreMethod<"createWorkflow">["args"]): Promise<import("../../types.js").WorkflowSpec>;
|
|
26
29
|
getWorkflow(...args: StoreMethod<"getWorkflow">["args"]): Promise<import("../../types.js").WorkflowSpec | undefined>;
|
|
27
30
|
listWorkflows(...args: StoreMethod<"listWorkflows">["args"]): Promise<import("../../types.js").WorkflowSpec[]>;
|
|
@@ -70,6 +73,9 @@ export declare class SqliteLoopStorage implements LoopStorageContract {
|
|
|
70
73
|
finalizeRun(...args: StoreMethod<"finalizeRun">["args"]): Promise<import("../../types.js").LoopRun>;
|
|
71
74
|
heartbeatRunLease(...args: StoreMethod<"heartbeatRunLease">["args"]): Promise<import("../../types.js").LoopRun | undefined>;
|
|
72
75
|
listRuns(...args: StoreMethod<"listRuns">["args"]): Promise<import("../../types.js").LoopRun[]>;
|
|
76
|
+
writeRunReceipt(...args: StoreMethod<"writeRunReceipt">["args"]): Promise<import("../../types.js").RunReceipt>;
|
|
77
|
+
getRunReceipt(...args: StoreMethod<"getRunReceipt">["args"]): Promise<import("../../types.js").RunReceipt | undefined>;
|
|
78
|
+
listRunReceipts(...args: StoreMethod<"listRunReceipts">["args"]): Promise<import("../../types.js").RunReceipt[]>;
|
|
73
79
|
recoverExpiredRunLeases(...args: StoreMethod<"recoverExpiredRunLeases">["args"]): Promise<import("../../types.js").LoopRun[]>;
|
|
74
80
|
recoverExpiredRunLeasesDetailed(...args: StoreMethod<"recoverExpiredRunLeasesDetailed">["args"]): Promise<import("../store.js").RecoverExpiredRunLeasesResult>;
|
|
75
81
|
countLoops(...args: StoreMethod<"countLoops">["args"]): Promise<number>;
|