@hasna/workflows 0.1.4 → 0.2.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.
- package/README.md +180 -98
- package/dist/agent-tools.js +554 -1418
- package/dist/cli/index.js +4120 -2474
- package/dist/handlers.js +3339 -55
- package/dist/index.js +2372 -1253
- package/dist/mcp/index.js +1738 -1744
- package/dist/sdk.js +1620 -0
- package/dist/serve/admin.js +4291 -0
- package/dist/serve/index.js +3392 -1381
- package/dist/service.js +2134 -1165
- package/hasna.contract.json +17 -17
- package/package.json +16 -13
- package/types/agent-tools.d.ts +3 -17
- package/types/client-error.d.ts +4 -0
- package/types/client-tools.d.ts +4 -0
- package/types/client.d.ts +60 -0
- package/types/daemon.d.ts +15 -9
- package/types/db/postgres-store.d.ts +54 -0
- package/types/graph.d.ts +6 -0
- package/types/handlers.d.ts +2 -1
- package/types/identity.d.ts +7 -0
- package/types/lanes/codex.d.ts +0 -6
- package/types/lanes/types.d.ts +16 -3
- package/types/openapi.d.ts +7 -0
- package/types/paths.d.ts +10 -1
- package/types/sdk/generated-api.d.ts +161 -0
- package/types/sdk.d.ts +6 -0
- package/types/serve/admin.d.ts +2 -0
- package/types/service.d.ts +75 -4
- package/types/session.d.ts +7 -8
- package/types/setup.d.ts +71 -0
- package/types/store.d.ts +30 -0
- package/types/tool-definitions.d.ts +18 -0
- package/types/types.d.ts +8 -0
- package/types/version.d.ts +1 -0
- package/types/wal.d.ts +9 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
export interface ApiError {
|
|
2
|
+
"error": string;
|
|
3
|
+
"message"?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface HealthReport {
|
|
6
|
+
"ok": boolean;
|
|
7
|
+
"status": "ok";
|
|
8
|
+
"backend": "postgresql" | "sqlite";
|
|
9
|
+
"service": string;
|
|
10
|
+
"version": string;
|
|
11
|
+
"pid": number;
|
|
12
|
+
"uptimeMs": number;
|
|
13
|
+
}
|
|
14
|
+
export interface ReadinessReport {
|
|
15
|
+
"ok": boolean;
|
|
16
|
+
"service": string;
|
|
17
|
+
"version": string;
|
|
18
|
+
"checks": Record<string, string>;
|
|
19
|
+
}
|
|
20
|
+
export interface GraphValidation {
|
|
21
|
+
"ok": boolean;
|
|
22
|
+
"issues": Array<{
|
|
23
|
+
"path": string;
|
|
24
|
+
"message": string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
export interface StartNode {
|
|
28
|
+
"id": string;
|
|
29
|
+
"type": "start";
|
|
30
|
+
"next"?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface StepNode {
|
|
33
|
+
"id": string;
|
|
34
|
+
"type": "step";
|
|
35
|
+
"next"?: string;
|
|
36
|
+
"lane"?: "claude" | "codex" | "cursor" | "grok";
|
|
37
|
+
"prompt"?: string;
|
|
38
|
+
"command"?: string;
|
|
39
|
+
"cwd"?: string;
|
|
40
|
+
"codexMode"?: "repository" | "read-only";
|
|
41
|
+
"maxRetries"?: number;
|
|
42
|
+
"memo"?: boolean;
|
|
43
|
+
"timeoutMs"?: number;
|
|
44
|
+
}
|
|
45
|
+
export interface DecisionNode {
|
|
46
|
+
"id": string;
|
|
47
|
+
"type": "decision";
|
|
48
|
+
"condition": string;
|
|
49
|
+
"then"?: string;
|
|
50
|
+
"else"?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface WhileNode {
|
|
53
|
+
"id": string;
|
|
54
|
+
"type": "while";
|
|
55
|
+
"condition": string;
|
|
56
|
+
"body": Array<string>;
|
|
57
|
+
"maxIterations": number;
|
|
58
|
+
"next"?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface EndNode {
|
|
61
|
+
"id": string;
|
|
62
|
+
"type": "end";
|
|
63
|
+
}
|
|
64
|
+
export type GraphNode = StartNode | StepNode | DecisionNode | WhileNode | EndNode;
|
|
65
|
+
export interface WorkflowGraph {
|
|
66
|
+
"name": string;
|
|
67
|
+
"version": string;
|
|
68
|
+
"nodes": Array<GraphNode>;
|
|
69
|
+
"memoWatch"?: Array<string>;
|
|
70
|
+
}
|
|
71
|
+
export interface RunSummary {
|
|
72
|
+
"runId": string;
|
|
73
|
+
"status": "pending" | "running" | "completed" | "failed" | "interrupted" | "cancelled";
|
|
74
|
+
"error": string | null;
|
|
75
|
+
"result": unknown;
|
|
76
|
+
"reused": boolean;
|
|
77
|
+
}
|
|
78
|
+
export interface RunRow {
|
|
79
|
+
"id": string;
|
|
80
|
+
"graphName": string;
|
|
81
|
+
"graphVersion": string;
|
|
82
|
+
"status": "pending" | "running" | "completed" | "failed" | "interrupted" | "cancelled";
|
|
83
|
+
"attempts": number;
|
|
84
|
+
"contextJson": string;
|
|
85
|
+
"resultJson": string | null;
|
|
86
|
+
"error": string | null;
|
|
87
|
+
"startedAt": string | null;
|
|
88
|
+
"finishedAt": string | null;
|
|
89
|
+
"createdAt": string;
|
|
90
|
+
"updatedAt": string;
|
|
91
|
+
}
|
|
92
|
+
export interface RunNodeRow {
|
|
93
|
+
"id": string;
|
|
94
|
+
"runId": string;
|
|
95
|
+
"nodeId": string;
|
|
96
|
+
"status": "pending" | "running" | "completed" | "failed" | "skipped";
|
|
97
|
+
"attempts": number;
|
|
98
|
+
"lane": string | null;
|
|
99
|
+
"exitCode": number | null;
|
|
100
|
+
"outputJson": string | null;
|
|
101
|
+
"error": string | null;
|
|
102
|
+
"startedAt": string | null;
|
|
103
|
+
"finishedAt": string | null;
|
|
104
|
+
}
|
|
105
|
+
export declare abstract class WorkflowsApi {
|
|
106
|
+
protected abstract apiRequest<T>(method: string, path: string, opts: {
|
|
107
|
+
body?: unknown;
|
|
108
|
+
query?: Record<string, unknown>;
|
|
109
|
+
}): Promise<T>;
|
|
110
|
+
/** Bounded-trigger executor status */
|
|
111
|
+
inspectDaemon(): Promise<Record<string, unknown>>;
|
|
112
|
+
/** Service health */
|
|
113
|
+
getHealth(): Promise<HealthReport>;
|
|
114
|
+
/** Inspect lane substrates; this does not prove sign-in or model capacity */
|
|
115
|
+
listLanes(): Promise<Array<Record<string, unknown>>>;
|
|
116
|
+
/** Inspect one lane substrate */
|
|
117
|
+
probeLane(lane: "claude" | "codex" | "cursor" | "grok"): Promise<Record<string, unknown>>;
|
|
118
|
+
/** This executor, not a fleet census */
|
|
119
|
+
listServerMachines(): Promise<Array<Record<string, unknown>>>;
|
|
120
|
+
/** This executor's health and claims */
|
|
121
|
+
inspectServerMachine(): Promise<Record<string, unknown>>;
|
|
122
|
+
/** Recent memo results */
|
|
123
|
+
listMemoRecords(): Promise<Array<Record<string, unknown>>>;
|
|
124
|
+
/** Authentication and actual schema readiness */
|
|
125
|
+
getReadiness(): Promise<ReadinessReport>;
|
|
126
|
+
/** List recent runs */
|
|
127
|
+
listRunRecords(query?: {
|
|
128
|
+
"status"?: "pending" | "running" | "completed" | "failed" | "interrupted" | "cancelled";
|
|
129
|
+
"limit"?: number;
|
|
130
|
+
}): Promise<Array<RunRow>>;
|
|
131
|
+
/** Read a durable run */
|
|
132
|
+
getRunRecord(id: string): Promise<RunRow>;
|
|
133
|
+
/** Cancel a pending, running or interrupted run and fence late results */
|
|
134
|
+
cancelWorkflow(id: string): Promise<RunRow>;
|
|
135
|
+
/** Preserved execution journal events */
|
|
136
|
+
getRunEvents(id: string): Promise<Array<Record<string, unknown>>>;
|
|
137
|
+
/** Ordered node execution history */
|
|
138
|
+
getRunNodes(id: string): Promise<Array<RunNodeRow>>;
|
|
139
|
+
/** Continue a failed, cancelled or interrupted run using its pinned graph; active or unconfirmed execution refuses resume */
|
|
140
|
+
resumeWorkflow(id: string): Promise<RunSummary>;
|
|
141
|
+
/** Recent journal event metadata */
|
|
142
|
+
listSessionEvents(): Promise<Array<Record<string, unknown>>>;
|
|
143
|
+
/** Read journal and claim state without repair */
|
|
144
|
+
inspectSession(): Promise<Record<string, unknown>>;
|
|
145
|
+
/** Execute a bounded workflow; identical keyed retries reuse the original run */
|
|
146
|
+
triggerWorkflow(body: {
|
|
147
|
+
"graph": WorkflowGraph;
|
|
148
|
+
"context"?: Record<string, unknown>;
|
|
149
|
+
"idempotencyKey"?: string;
|
|
150
|
+
"maxCycles"?: number;
|
|
151
|
+
}): Promise<RunSummary>;
|
|
152
|
+
/** Validate a workflow graph */
|
|
153
|
+
validateWorkflow(body: {
|
|
154
|
+
"graph": WorkflowGraph;
|
|
155
|
+
}): Promise<GraphValidation>;
|
|
156
|
+
/** Package version */
|
|
157
|
+
getVersion(): Promise<{
|
|
158
|
+
"service": string;
|
|
159
|
+
"version": string;
|
|
160
|
+
}>;
|
|
161
|
+
}
|
package/types/sdk.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** The SDK is a hosted HTTP client; server implementation is exported at the package root. */
|
|
2
|
+
export { WorkflowsClient, createWorkflowsClient } from "./client.js";
|
|
3
|
+
export type { WorkflowsClientOptions, RunSummary } from "./client.js";
|
|
4
|
+
export type { WorkflowGraph, GraphNode, GraphValidation } from "./graph.js";
|
|
5
|
+
export type { RunRow, RunNodeRow, RunStatus } from "./store.js";
|
|
6
|
+
export type { HealthReport, ReadinessReport } from "./types.js";
|
package/types/service.d.ts
CHANGED
|
@@ -1,16 +1,82 @@
|
|
|
1
|
+
import { type RunToCompletionOptions } from "./daemon.js";
|
|
2
|
+
import { openStore } from "./store.js";
|
|
1
3
|
import type { WorkflowGraph } from "./graph.js";
|
|
2
4
|
import type { HealthReport, ReadinessReport, WorkflowsConfig } from "./types.js";
|
|
3
|
-
export
|
|
5
|
+
export { packageVersion } from "./version.js";
|
|
4
6
|
/** Resolve the service configuration from env + explicit overrides. */
|
|
5
7
|
export declare function resolveWorkflowsConfig(overrides?: Partial<WorkflowsConfig>): WorkflowsConfig;
|
|
6
8
|
export declare class WorkflowsService {
|
|
9
|
+
private readonly execution;
|
|
7
10
|
readonly name = "workflows";
|
|
8
11
|
readonly version: string;
|
|
9
12
|
readonly config: WorkflowsConfig;
|
|
10
13
|
private readonly startedAt;
|
|
11
|
-
|
|
14
|
+
private readonly databaseEnv;
|
|
15
|
+
constructor(config?: Partial<WorkflowsConfig>, execution?: RunToCompletionOptions);
|
|
12
16
|
health(): HealthReport;
|
|
13
|
-
ready(): ReadinessReport
|
|
17
|
+
ready(): Promise<ReadinessReport>;
|
|
18
|
+
private openEngineStore;
|
|
19
|
+
private withStore;
|
|
20
|
+
/** Explicit operator bootstrap; ordinary reads and server startup never create tables. */
|
|
21
|
+
initializeStorage(): Promise<void>;
|
|
22
|
+
listRuns(options?: Parameters<ReturnType<typeof openStore>["listRuns"]>[0]): Promise<import("./store.js").RunRow[]>;
|
|
23
|
+
getRun(id: string): Promise<import("./store.js").RunRow | undefined>;
|
|
24
|
+
listNodes(id: string): Promise<import("./store.js").RunNodeRow[]>;
|
|
25
|
+
events(id: string): import("./wal.js").WalEntry[];
|
|
26
|
+
cancelRun(id: string): Promise<import("./store.js").RunRow | undefined>;
|
|
27
|
+
resumeRun(id: string): Promise<{
|
|
28
|
+
runId: string;
|
|
29
|
+
status: "cancelled" | "pending" | "running" | "completed" | "failed" | "interrupted";
|
|
30
|
+
error: string | null;
|
|
31
|
+
result: any;
|
|
32
|
+
reused: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
sessions(action: "list" | "pull"): {
|
|
35
|
+
seq: number;
|
|
36
|
+
at: string;
|
|
37
|
+
operation: "claim_acquired" | "claim_released" | "graph_registered" | "run_started" | "run_finished" | "node_started" | "node_finished" | "memo_set";
|
|
38
|
+
}[] | {
|
|
39
|
+
entries: number;
|
|
40
|
+
torn: boolean;
|
|
41
|
+
repaired: boolean;
|
|
42
|
+
liveClaims: {
|
|
43
|
+
runId: string;
|
|
44
|
+
worker: string;
|
|
45
|
+
fencing: number;
|
|
46
|
+
expiresAt: string;
|
|
47
|
+
}[];
|
|
48
|
+
};
|
|
49
|
+
machines(action: "list" | "status"): {
|
|
50
|
+
name: string;
|
|
51
|
+
role: string;
|
|
52
|
+
version: string;
|
|
53
|
+
}[] | {
|
|
54
|
+
health: HealthReport;
|
|
55
|
+
sessions: {
|
|
56
|
+
seq: number;
|
|
57
|
+
at: string;
|
|
58
|
+
operation: "claim_acquired" | "claim_released" | "graph_registered" | "run_started" | "run_finished" | "node_started" | "node_finished" | "memo_set";
|
|
59
|
+
}[] | {
|
|
60
|
+
entries: number;
|
|
61
|
+
torn: boolean;
|
|
62
|
+
repaired: boolean;
|
|
63
|
+
liveClaims: {
|
|
64
|
+
runId: string;
|
|
65
|
+
worker: string;
|
|
66
|
+
fencing: number;
|
|
67
|
+
expiresAt: string;
|
|
68
|
+
}[];
|
|
69
|
+
};
|
|
70
|
+
name: string;
|
|
71
|
+
role: string;
|
|
72
|
+
version: string;
|
|
73
|
+
};
|
|
74
|
+
daemonStatus(): {
|
|
75
|
+
activeClaims: number;
|
|
76
|
+
mode: string;
|
|
77
|
+
continuousDaemon: boolean;
|
|
78
|
+
};
|
|
79
|
+
listMemos(): Promise<import("./store.js").MemoRow[]>;
|
|
14
80
|
/**
|
|
15
81
|
* The authenticated trigger: run a graph to a terminal state (bounded
|
|
16
82
|
* cycles) and return its summary. The HTTP layer authenticates; this
|
|
@@ -29,4 +95,9 @@ export declare class WorkflowsService {
|
|
|
29
95
|
reused: boolean;
|
|
30
96
|
}>;
|
|
31
97
|
}
|
|
32
|
-
export declare function createWorkflowsService(config?: Partial<WorkflowsConfig
|
|
98
|
+
export declare function createWorkflowsService(config?: Partial<WorkflowsConfig>, execution?: RunToCompletionOptions): WorkflowsService;
|
|
99
|
+
export declare class WorkflowRequestError extends Error {
|
|
100
|
+
readonly code: string;
|
|
101
|
+
readonly status: number;
|
|
102
|
+
constructor(code: string, message: string, status?: number);
|
|
103
|
+
}
|
package/types/session.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SessionWAL } from "./wal.js";
|
|
2
|
-
import type { RunRow, WorkflowsStore } from "./store.js";
|
|
2
|
+
import type { RunRow, WorkflowsStore, EngineStore } from "./store.js";
|
|
3
3
|
import type { WorkflowGraph } from "./graph.js";
|
|
4
4
|
export interface RepairResult {
|
|
5
5
|
/** runs found running with no live claim */
|
|
@@ -10,18 +10,18 @@ export interface RepairResult {
|
|
|
10
10
|
failed: number;
|
|
11
11
|
}
|
|
12
12
|
export declare const DEFAULT_MAX_ATTEMPTS = 3;
|
|
13
|
-
export declare function repairTornRuns(store:
|
|
13
|
+
export declare function repairTornRuns<S extends EngineStore>(store: S, wal: SessionWAL, opts?: {
|
|
14
14
|
maxAttempts?: number;
|
|
15
15
|
now?: number;
|
|
16
|
-
}): RepairResult
|
|
16
|
+
}): S extends WorkflowsStore ? RepairResult : Promise<RepairResult>;
|
|
17
17
|
/** Stable hash of a JSON-serializable payload. */
|
|
18
18
|
export declare function inputHash(payload: unknown): string;
|
|
19
19
|
/** Memo key: graphName:nodeId:<inputHash>. */
|
|
20
20
|
export declare function memoKey(graphName: string, nodeId: string, input: unknown): string;
|
|
21
21
|
/** Look up a memo by input; a hit increments hitCount and returns the row. */
|
|
22
|
-
export declare function tryMemoHit(store:
|
|
22
|
+
export declare function tryMemoHit<S extends EngineStore>(store: S, graphName: string, nodeId: string, input: unknown): ReturnType<S["memoGet"]>;
|
|
23
23
|
/** Persist a node output for future runs with the same input. */
|
|
24
|
-
export declare function recordMemo(store:
|
|
24
|
+
export declare function recordMemo<S extends EngineStore>(store: S, graphName: string, nodeId: string, input: unknown, output: unknown): ReturnType<S["memoPut"]>;
|
|
25
25
|
/** One watched file's fingerprint entry (mtime + sha256). */
|
|
26
26
|
export interface MemoWatchEntry {
|
|
27
27
|
/** The pattern as declared on the graph. */
|
|
@@ -69,7 +69,6 @@ export declare function restoreInterruptedRun(store: WorkflowsStore, runId: stri
|
|
|
69
69
|
/**
|
|
70
70
|
* Idempotent run lookup: the run whose context carries the given idempotency
|
|
71
71
|
* key, if any. The three-table law forbids an extra column, so the key lives
|
|
72
|
-
* in the reserved __wf namespace of context_json;
|
|
73
|
-
* store's own listRuns cap (1000 rows).
|
|
72
|
+
* in the reserved __wf namespace of context_json; a database lookup covers the entire run history.
|
|
74
73
|
*/
|
|
75
|
-
export declare function findRunByIdempotencyKey(store:
|
|
74
|
+
export declare function findRunByIdempotencyKey<S extends EngineStore>(store: S, key: string): ReturnType<S["getRunByIdempotencyKey"]>;
|
package/types/setup.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type IdentityEnvironment } from "./identity.js";
|
|
2
|
+
type SetupOptions = {
|
|
3
|
+
apiUrl?: string;
|
|
4
|
+
replace?: boolean;
|
|
5
|
+
agent?: string;
|
|
6
|
+
env?: IdentityEnvironment;
|
|
7
|
+
fetchImpl?: typeof fetch;
|
|
8
|
+
};
|
|
9
|
+
export declare function setupWorkflows(options?: SetupOptions): Promise<{
|
|
10
|
+
app: string;
|
|
11
|
+
action: string;
|
|
12
|
+
credentials_path: string;
|
|
13
|
+
mode: string;
|
|
14
|
+
authority: string;
|
|
15
|
+
verified_before_write: boolean;
|
|
16
|
+
verified_after_write: boolean;
|
|
17
|
+
effective_tier: "disk";
|
|
18
|
+
effective_source: string;
|
|
19
|
+
preservation: string | undefined;
|
|
20
|
+
warning: null;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function loginWorkflows(options?: SetupOptions, suppliedKey?: string): Promise<{
|
|
23
|
+
app: string;
|
|
24
|
+
action: string;
|
|
25
|
+
credentials_path: string;
|
|
26
|
+
mode: string;
|
|
27
|
+
authority: string;
|
|
28
|
+
verified_before_write: boolean;
|
|
29
|
+
verified_after_write: boolean;
|
|
30
|
+
effective_tier: "disk";
|
|
31
|
+
effective_source: string;
|
|
32
|
+
preservation: string | undefined;
|
|
33
|
+
warning: null;
|
|
34
|
+
}>;
|
|
35
|
+
/** Sign out only a key written by login; environment and setup credentials stay owned by their source. */
|
|
36
|
+
export declare function logoutWorkflows(options?: {
|
|
37
|
+
revoke?: boolean;
|
|
38
|
+
env?: IdentityEnvironment;
|
|
39
|
+
}): {
|
|
40
|
+
app: string;
|
|
41
|
+
action: string;
|
|
42
|
+
exit_code: number;
|
|
43
|
+
message: string;
|
|
44
|
+
} | {
|
|
45
|
+
app: string;
|
|
46
|
+
action: string;
|
|
47
|
+
credentials_path: string;
|
|
48
|
+
preservation: string;
|
|
49
|
+
exit_code: number;
|
|
50
|
+
message: string;
|
|
51
|
+
};
|
|
52
|
+
export declare function workflowsWhoami(options?: {
|
|
53
|
+
apiUrl?: string;
|
|
54
|
+
agent?: string;
|
|
55
|
+
env?: IdentityEnvironment;
|
|
56
|
+
}): {
|
|
57
|
+
app: string;
|
|
58
|
+
agent: string;
|
|
59
|
+
agent_source: string;
|
|
60
|
+
authority: string;
|
|
61
|
+
credential_tier: import("@hasna/contracts").CredentialTier;
|
|
62
|
+
credential_source: string | null;
|
|
63
|
+
} | {
|
|
64
|
+
app: string;
|
|
65
|
+
agent: string;
|
|
66
|
+
agent_source: string;
|
|
67
|
+
authority: string;
|
|
68
|
+
credential_tier: string;
|
|
69
|
+
credential_source: null;
|
|
70
|
+
};
|
|
71
|
+
export {};
|
package/types/store.d.ts
CHANGED
|
@@ -48,6 +48,27 @@ export interface CreateRunNodeInput {
|
|
|
48
48
|
nodeId: string;
|
|
49
49
|
lane?: string;
|
|
50
50
|
}
|
|
51
|
+
export interface StepCommit {
|
|
52
|
+
runId: string;
|
|
53
|
+
nodeRowId: string;
|
|
54
|
+
status: NodeStatus;
|
|
55
|
+
patch?: Parameters<WorkflowsStore["setRunNodeStatus"]>[2];
|
|
56
|
+
incrementAttempts?: boolean;
|
|
57
|
+
context?: unknown;
|
|
58
|
+
memo?: {
|
|
59
|
+
key: string;
|
|
60
|
+
graphName: string;
|
|
61
|
+
nodeId: string;
|
|
62
|
+
inputHash: string;
|
|
63
|
+
outputJson: string;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export type DispatchResult<T> = {
|
|
67
|
+
started: false;
|
|
68
|
+
} | {
|
|
69
|
+
started: true;
|
|
70
|
+
result: T;
|
|
71
|
+
};
|
|
51
72
|
export interface WorkflowsStore {
|
|
52
73
|
/** The data dir this store was opened on (resolves relative memoWatch paths). */
|
|
53
74
|
readonly dataDir: string;
|
|
@@ -55,6 +76,7 @@ export interface WorkflowsStore {
|
|
|
55
76
|
listTables(): string[];
|
|
56
77
|
createRun(input: CreateRunInput): RunRow;
|
|
57
78
|
getRun(id: string): RunRow | undefined;
|
|
79
|
+
getRunByIdempotencyKey(key: string): RunRow | undefined;
|
|
58
80
|
listRuns(opts?: {
|
|
59
81
|
status?: RunStatus;
|
|
60
82
|
limit?: number;
|
|
@@ -65,8 +87,14 @@ export interface WorkflowsStore {
|
|
|
65
87
|
startedAt?: string;
|
|
66
88
|
finishedAt?: string;
|
|
67
89
|
}): void;
|
|
90
|
+
compareRunStatus(id: string, expected: RunStatus[], status: RunStatus, patch?: Parameters<WorkflowsStore["setRunStatus"]>[2]): boolean;
|
|
68
91
|
/** Persist the run's durable execution state (the engine's cursor + steps). */
|
|
69
92
|
setRunContext(id: string, context: unknown): void;
|
|
93
|
+
setRunningContext(id: string, context: unknown): boolean;
|
|
94
|
+
blockRunResume(id: string): void;
|
|
95
|
+
finishDispatch(id: string, unconfirmed: boolean): void;
|
|
96
|
+
dispatchIfRunning<T>(id: string, action: () => T): DispatchResult<T>;
|
|
97
|
+
commitStep(input: StepCommit): boolean;
|
|
70
98
|
bumpAttempts(id: string): void;
|
|
71
99
|
createRunNode(input: CreateRunNodeInput): RunNodeRow;
|
|
72
100
|
getRunNode(id: string): RunNodeRow | undefined;
|
|
@@ -89,3 +117,5 @@ export interface WorkflowsStore {
|
|
|
89
117
|
memoClear(): void;
|
|
90
118
|
}
|
|
91
119
|
export declare function openStore(dataDir: string): WorkflowsStore;
|
|
120
|
+
/** One execution engine accepts the synchronous embedded and asynchronous hosted stores. */
|
|
121
|
+
export type EngineStore = WorkflowsStore | import("./db/postgres-store.js").AsyncWorkflowsStore;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface McpTool {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object";
|
|
6
|
+
properties: Record<string, unknown>;
|
|
7
|
+
required?: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface ToolCallResult {
|
|
11
|
+
content: {
|
|
12
|
+
type: "text";
|
|
13
|
+
text: string;
|
|
14
|
+
}[];
|
|
15
|
+
isError: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function textResult(payload: unknown): ToolCallResult;
|
|
18
|
+
export declare function workflowsTools(_service?: unknown): McpTool[];
|
package/types/types.d.ts
CHANGED
|
@@ -20,9 +20,17 @@ export interface WorkflowsConfig {
|
|
|
20
20
|
apiUrl?: string;
|
|
21
21
|
/** Optional client API key (WORKFLOWS_API_KEY) — resolved, never printed. */
|
|
22
22
|
apiKey?: string;
|
|
23
|
+
/** Gateway origin identity. When configured, every /v1 route requires it. */
|
|
24
|
+
originAuth?: string;
|
|
25
|
+
/** Hosted server authority. SQLite requires an explicit embedded selection. */
|
|
26
|
+
storageBackend: "postgresql" | "sqlite";
|
|
27
|
+
databaseUrl?: string;
|
|
28
|
+
databaseSchema?: string;
|
|
23
29
|
}
|
|
24
30
|
export interface HealthReport {
|
|
25
31
|
ok: boolean;
|
|
32
|
+
status: "ok";
|
|
33
|
+
backend: "postgresql" | "sqlite";
|
|
26
34
|
service: string;
|
|
27
35
|
version: string;
|
|
28
36
|
pid: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function packageVersion(): string;
|
package/types/wal.d.ts
CHANGED
|
@@ -71,14 +71,22 @@ export declare const WAL_FILE_NAME = "session.wal";
|
|
|
71
71
|
export declare const SESSIONS_DIR_NAME = "sessions";
|
|
72
72
|
export declare class SessionWAL {
|
|
73
73
|
readonly filePath: string;
|
|
74
|
+
private journalLocked;
|
|
74
75
|
private constructor();
|
|
75
76
|
static open(dataDir: string): SessionWAL;
|
|
76
77
|
static openAt(filePath: string): SessionWAL;
|
|
77
78
|
/** Append one op and return the persisted entry (seq is 1-based). */
|
|
78
79
|
append(op: WalOp): WalEntry;
|
|
80
|
+
private withJournalLock;
|
|
81
|
+
/** Atomic journal claim/release decisions use the same cross-process mutex. */
|
|
82
|
+
exclusive<T>(operation: () => T): T;
|
|
83
|
+
private appendLocked;
|
|
79
84
|
private nextSeq;
|
|
80
85
|
/** Read and verify the whole WAL; truncate the first torn tail. */
|
|
81
|
-
replay(
|
|
86
|
+
replay(options?: {
|
|
87
|
+
repair?: boolean;
|
|
88
|
+
}): WalReplay;
|
|
89
|
+
private replayLocked;
|
|
82
90
|
close(): void;
|
|
83
91
|
}
|
|
84
92
|
/** Write a fresh (empty) WAL — used by tests and by init. */
|