@cleocode/playbooks 2026.4.88 → 2026.4.91
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 +207 -0
- package/package.json +3 -3
- package/dist/approval.d.ts +0 -113
- package/dist/approval.js +0 -244
- package/dist/index.d.ts +0 -29
- package/dist/index.js +0 -32
- package/dist/parser.d.ts +0 -60
- package/dist/parser.js +0 -509
- package/dist/policy.d.ts +0 -55
- package/dist/policy.js +0 -85
- package/dist/schema.d.ts +0 -374
- package/dist/schema.js +0 -34
- package/dist/state.d.ts +0 -96
- package/dist/state.js +0 -322
package/dist/policy.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HITL auto-policy — evaluates whether a deterministic command requires
|
|
3
|
-
* human approval before execution. Conservative defaults per OpenProse standard.
|
|
4
|
-
*
|
|
5
|
-
* `require-human` rules are evaluated FIRST and cannot be bypassed by
|
|
6
|
-
* `auto-approve` rules even when callers append custom rules to the list.
|
|
7
|
-
* The default decision for an unmatched command is `require-human` so the
|
|
8
|
-
* runtime fails closed when confronted with unknown surface area.
|
|
9
|
-
*
|
|
10
|
-
* @task T889 / T908 / W4-9
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Conservative default policy. `require-human` rules come first for ordering
|
|
14
|
-
* clarity, but evaluation order in {@link evaluatePolicy} enforces the
|
|
15
|
-
* priority regardless of array position.
|
|
16
|
-
*/
|
|
17
|
-
export const DEFAULT_POLICY_RULES = Object.freeze([
|
|
18
|
-
{ pattern: /\bnpm\s+publish\b/, action: 'require-human', reason: 'publish' },
|
|
19
|
-
{ pattern: /\bpnpm\s+publish\b/, action: 'require-human', reason: 'publish' },
|
|
20
|
-
{ pattern: /\byarn\s+publish\b/, action: 'require-human', reason: 'publish' },
|
|
21
|
-
{ pattern: /\bgit\s+push\b/, action: 'require-human', reason: 'push' },
|
|
22
|
-
{ pattern: /\bgit\s+tag\b/, action: 'require-human', reason: 'tag' },
|
|
23
|
-
{ pattern: /\bgh\s+release\s+create\b/, action: 'require-human', reason: 'release' },
|
|
24
|
-
{ pattern: /\bgh\s+workflow\s+run\b/, action: 'require-human', reason: 'workflow-trigger' },
|
|
25
|
-
{
|
|
26
|
-
pattern: /\b(rm\s+-rf|drop\s+table|truncate|delete\s+from)\b/i,
|
|
27
|
-
action: 'require-human',
|
|
28
|
-
reason: 'destructive',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
pattern: /\b(curl|wget|fetch)\b.*\bhttps?:/i,
|
|
32
|
-
action: 'require-human',
|
|
33
|
-
reason: 'external-api',
|
|
34
|
-
},
|
|
35
|
-
{ pattern: /\b(ssh|scp|rsync)\b.+@/, action: 'require-human', reason: 'remote-access' },
|
|
36
|
-
{
|
|
37
|
-
pattern: /^pnpm\s+(test|run\s+test|biome|tsc)\b/,
|
|
38
|
-
action: 'auto-approve',
|
|
39
|
-
reason: 'safe-qa-tool',
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
pattern: /^cleo\s+(verify|check|show|find|list|status|current|next)\b/,
|
|
43
|
-
action: 'auto-approve',
|
|
44
|
-
reason: 'safe-cleo-read',
|
|
45
|
-
},
|
|
46
|
-
]);
|
|
47
|
-
/**
|
|
48
|
-
* Evaluates a command against the supplied policy rules and returns the
|
|
49
|
-
* resolved approval decision.
|
|
50
|
-
*
|
|
51
|
-
* Priority:
|
|
52
|
-
* 1. Every `require-human` rule across the list is tested first.
|
|
53
|
-
* 2. `auto-approve` rules are tested only if no block fired.
|
|
54
|
-
* 3. Fallback is `{ action: 'require-human', reason: 'default' }` so
|
|
55
|
-
* unknown commands never auto-execute.
|
|
56
|
-
*
|
|
57
|
-
* Callers MAY pass a custom rule list, but they CANNOT relax default blocks —
|
|
58
|
-
* any rule elsewhere in the list that matches with `require-human` wins over
|
|
59
|
-
* any auto-approve match, regardless of order.
|
|
60
|
-
*
|
|
61
|
-
* @param command The fully-resolved command string (executable plus arguments).
|
|
62
|
-
* @param rules The ordered rule list. Defaults to {@link DEFAULT_POLICY_RULES}.
|
|
63
|
-
* @returns The approval decision including the matched reason.
|
|
64
|
-
*/
|
|
65
|
-
export function evaluatePolicy(command, rules = DEFAULT_POLICY_RULES) {
|
|
66
|
-
for (const rule of rules) {
|
|
67
|
-
if (rule.action === 'require-human' && rule.pattern.test(command)) {
|
|
68
|
-
return {
|
|
69
|
-
action: 'require-human',
|
|
70
|
-
reason: rule.reason,
|
|
71
|
-
matchedPattern: rule.pattern.source,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
for (const rule of rules) {
|
|
76
|
-
if (rule.action === 'auto-approve' && rule.pattern.test(command)) {
|
|
77
|
-
return {
|
|
78
|
-
action: 'auto-approve',
|
|
79
|
-
reason: rule.reason,
|
|
80
|
-
matchedPattern: rule.pattern.source,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return { action: 'require-human', reason: 'default' };
|
|
85
|
-
}
|
package/dist/schema.d.ts
DELETED
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Drizzle ORM table definitions for playbook state.
|
|
3
|
-
* Both tables are added to tasks.db via migration at
|
|
4
|
-
* packages/core/migrations/drizzle-tasks/20260417220000_t889-playbook-tables/.
|
|
5
|
-
*
|
|
6
|
-
* @task T889 / T904 / W4-6
|
|
7
|
-
*/
|
|
8
|
-
export declare const playbookRuns: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
9
|
-
name: "playbook_runs";
|
|
10
|
-
schema: undefined;
|
|
11
|
-
columns: {
|
|
12
|
-
runId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
13
|
-
name: string;
|
|
14
|
-
tableName: "playbook_runs";
|
|
15
|
-
dataType: "string";
|
|
16
|
-
data: string;
|
|
17
|
-
driverParam: string;
|
|
18
|
-
notNull: true;
|
|
19
|
-
hasDefault: false;
|
|
20
|
-
isPrimaryKey: true;
|
|
21
|
-
isAutoincrement: false;
|
|
22
|
-
hasRuntimeDefault: false;
|
|
23
|
-
enumValues: [string, ...string[]];
|
|
24
|
-
baseColumn: never;
|
|
25
|
-
identity: undefined;
|
|
26
|
-
generated: undefined;
|
|
27
|
-
}, {}>;
|
|
28
|
-
playbookName: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
29
|
-
name: string;
|
|
30
|
-
tableName: "playbook_runs";
|
|
31
|
-
dataType: "string";
|
|
32
|
-
data: string;
|
|
33
|
-
driverParam: string;
|
|
34
|
-
notNull: true;
|
|
35
|
-
hasDefault: false;
|
|
36
|
-
isPrimaryKey: false;
|
|
37
|
-
isAutoincrement: false;
|
|
38
|
-
hasRuntimeDefault: false;
|
|
39
|
-
enumValues: [string, ...string[]];
|
|
40
|
-
baseColumn: never;
|
|
41
|
-
identity: undefined;
|
|
42
|
-
generated: undefined;
|
|
43
|
-
}, {}>;
|
|
44
|
-
playbookHash: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
45
|
-
name: string;
|
|
46
|
-
tableName: "playbook_runs";
|
|
47
|
-
dataType: "string";
|
|
48
|
-
data: string;
|
|
49
|
-
driverParam: string;
|
|
50
|
-
notNull: true;
|
|
51
|
-
hasDefault: false;
|
|
52
|
-
isPrimaryKey: false;
|
|
53
|
-
isAutoincrement: false;
|
|
54
|
-
hasRuntimeDefault: false;
|
|
55
|
-
enumValues: [string, ...string[]];
|
|
56
|
-
baseColumn: never;
|
|
57
|
-
identity: undefined;
|
|
58
|
-
generated: undefined;
|
|
59
|
-
}, {}>;
|
|
60
|
-
currentNode: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
61
|
-
name: string;
|
|
62
|
-
tableName: "playbook_runs";
|
|
63
|
-
dataType: "string";
|
|
64
|
-
data: string;
|
|
65
|
-
driverParam: string;
|
|
66
|
-
notNull: false;
|
|
67
|
-
hasDefault: false;
|
|
68
|
-
isPrimaryKey: false;
|
|
69
|
-
isAutoincrement: false;
|
|
70
|
-
hasRuntimeDefault: false;
|
|
71
|
-
enumValues: [string, ...string[]];
|
|
72
|
-
baseColumn: never;
|
|
73
|
-
identity: undefined;
|
|
74
|
-
generated: undefined;
|
|
75
|
-
}, {}>;
|
|
76
|
-
bindings: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
77
|
-
name: string;
|
|
78
|
-
tableName: "playbook_runs";
|
|
79
|
-
dataType: "string";
|
|
80
|
-
data: string;
|
|
81
|
-
driverParam: string;
|
|
82
|
-
notNull: true;
|
|
83
|
-
hasDefault: true;
|
|
84
|
-
isPrimaryKey: false;
|
|
85
|
-
isAutoincrement: false;
|
|
86
|
-
hasRuntimeDefault: false;
|
|
87
|
-
enumValues: [string, ...string[]];
|
|
88
|
-
baseColumn: never;
|
|
89
|
-
identity: undefined;
|
|
90
|
-
generated: undefined;
|
|
91
|
-
}, {}>;
|
|
92
|
-
errorContext: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
93
|
-
name: string;
|
|
94
|
-
tableName: "playbook_runs";
|
|
95
|
-
dataType: "string";
|
|
96
|
-
data: string;
|
|
97
|
-
driverParam: string;
|
|
98
|
-
notNull: false;
|
|
99
|
-
hasDefault: false;
|
|
100
|
-
isPrimaryKey: false;
|
|
101
|
-
isAutoincrement: false;
|
|
102
|
-
hasRuntimeDefault: false;
|
|
103
|
-
enumValues: [string, ...string[]];
|
|
104
|
-
baseColumn: never;
|
|
105
|
-
identity: undefined;
|
|
106
|
-
generated: undefined;
|
|
107
|
-
}, {}>;
|
|
108
|
-
status: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
109
|
-
name: string;
|
|
110
|
-
tableName: "playbook_runs";
|
|
111
|
-
dataType: "string";
|
|
112
|
-
data: string;
|
|
113
|
-
driverParam: string;
|
|
114
|
-
notNull: true;
|
|
115
|
-
hasDefault: true;
|
|
116
|
-
isPrimaryKey: false;
|
|
117
|
-
isAutoincrement: false;
|
|
118
|
-
hasRuntimeDefault: false;
|
|
119
|
-
enumValues: [string, ...string[]];
|
|
120
|
-
baseColumn: never;
|
|
121
|
-
identity: undefined;
|
|
122
|
-
generated: undefined;
|
|
123
|
-
}, {}>;
|
|
124
|
-
iterationCounts: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
125
|
-
name: string;
|
|
126
|
-
tableName: "playbook_runs";
|
|
127
|
-
dataType: "string";
|
|
128
|
-
data: string;
|
|
129
|
-
driverParam: string;
|
|
130
|
-
notNull: true;
|
|
131
|
-
hasDefault: true;
|
|
132
|
-
isPrimaryKey: false;
|
|
133
|
-
isAutoincrement: false;
|
|
134
|
-
hasRuntimeDefault: false;
|
|
135
|
-
enumValues: [string, ...string[]];
|
|
136
|
-
baseColumn: never;
|
|
137
|
-
identity: undefined;
|
|
138
|
-
generated: undefined;
|
|
139
|
-
}, {}>;
|
|
140
|
-
epicId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
141
|
-
name: string;
|
|
142
|
-
tableName: "playbook_runs";
|
|
143
|
-
dataType: "string";
|
|
144
|
-
data: string;
|
|
145
|
-
driverParam: string;
|
|
146
|
-
notNull: false;
|
|
147
|
-
hasDefault: false;
|
|
148
|
-
isPrimaryKey: false;
|
|
149
|
-
isAutoincrement: false;
|
|
150
|
-
hasRuntimeDefault: false;
|
|
151
|
-
enumValues: [string, ...string[]];
|
|
152
|
-
baseColumn: never;
|
|
153
|
-
identity: undefined;
|
|
154
|
-
generated: undefined;
|
|
155
|
-
}, {}>;
|
|
156
|
-
sessionId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
157
|
-
name: string;
|
|
158
|
-
tableName: "playbook_runs";
|
|
159
|
-
dataType: "string";
|
|
160
|
-
data: string;
|
|
161
|
-
driverParam: string;
|
|
162
|
-
notNull: false;
|
|
163
|
-
hasDefault: false;
|
|
164
|
-
isPrimaryKey: false;
|
|
165
|
-
isAutoincrement: false;
|
|
166
|
-
hasRuntimeDefault: false;
|
|
167
|
-
enumValues: [string, ...string[]];
|
|
168
|
-
baseColumn: never;
|
|
169
|
-
identity: undefined;
|
|
170
|
-
generated: undefined;
|
|
171
|
-
}, {}>;
|
|
172
|
-
startedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
173
|
-
name: string;
|
|
174
|
-
tableName: "playbook_runs";
|
|
175
|
-
dataType: "string";
|
|
176
|
-
data: string;
|
|
177
|
-
driverParam: string;
|
|
178
|
-
notNull: true;
|
|
179
|
-
hasDefault: true;
|
|
180
|
-
isPrimaryKey: false;
|
|
181
|
-
isAutoincrement: false;
|
|
182
|
-
hasRuntimeDefault: false;
|
|
183
|
-
enumValues: [string, ...string[]];
|
|
184
|
-
baseColumn: never;
|
|
185
|
-
identity: undefined;
|
|
186
|
-
generated: undefined;
|
|
187
|
-
}, {}>;
|
|
188
|
-
completedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
189
|
-
name: string;
|
|
190
|
-
tableName: "playbook_runs";
|
|
191
|
-
dataType: "string";
|
|
192
|
-
data: string;
|
|
193
|
-
driverParam: string;
|
|
194
|
-
notNull: false;
|
|
195
|
-
hasDefault: false;
|
|
196
|
-
isPrimaryKey: false;
|
|
197
|
-
isAutoincrement: false;
|
|
198
|
-
hasRuntimeDefault: false;
|
|
199
|
-
enumValues: [string, ...string[]];
|
|
200
|
-
baseColumn: never;
|
|
201
|
-
identity: undefined;
|
|
202
|
-
generated: undefined;
|
|
203
|
-
}, {}>;
|
|
204
|
-
};
|
|
205
|
-
dialect: "sqlite";
|
|
206
|
-
}>;
|
|
207
|
-
export declare const playbookApprovals: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
208
|
-
name: "playbook_approvals";
|
|
209
|
-
schema: undefined;
|
|
210
|
-
columns: {
|
|
211
|
-
approvalId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
212
|
-
name: string;
|
|
213
|
-
tableName: "playbook_approvals";
|
|
214
|
-
dataType: "string";
|
|
215
|
-
data: string;
|
|
216
|
-
driverParam: string;
|
|
217
|
-
notNull: true;
|
|
218
|
-
hasDefault: false;
|
|
219
|
-
isPrimaryKey: true;
|
|
220
|
-
isAutoincrement: false;
|
|
221
|
-
hasRuntimeDefault: false;
|
|
222
|
-
enumValues: [string, ...string[]];
|
|
223
|
-
baseColumn: never;
|
|
224
|
-
identity: undefined;
|
|
225
|
-
generated: undefined;
|
|
226
|
-
}, {}>;
|
|
227
|
-
runId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
228
|
-
name: string;
|
|
229
|
-
tableName: "playbook_approvals";
|
|
230
|
-
dataType: "string";
|
|
231
|
-
data: string;
|
|
232
|
-
driverParam: string;
|
|
233
|
-
notNull: true;
|
|
234
|
-
hasDefault: false;
|
|
235
|
-
isPrimaryKey: false;
|
|
236
|
-
isAutoincrement: false;
|
|
237
|
-
hasRuntimeDefault: false;
|
|
238
|
-
enumValues: [string, ...string[]];
|
|
239
|
-
baseColumn: never;
|
|
240
|
-
identity: undefined;
|
|
241
|
-
generated: undefined;
|
|
242
|
-
}, {}>;
|
|
243
|
-
nodeId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
244
|
-
name: string;
|
|
245
|
-
tableName: "playbook_approvals";
|
|
246
|
-
dataType: "string";
|
|
247
|
-
data: string;
|
|
248
|
-
driverParam: string;
|
|
249
|
-
notNull: true;
|
|
250
|
-
hasDefault: false;
|
|
251
|
-
isPrimaryKey: false;
|
|
252
|
-
isAutoincrement: false;
|
|
253
|
-
hasRuntimeDefault: false;
|
|
254
|
-
enumValues: [string, ...string[]];
|
|
255
|
-
baseColumn: never;
|
|
256
|
-
identity: undefined;
|
|
257
|
-
generated: undefined;
|
|
258
|
-
}, {}>;
|
|
259
|
-
token: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
260
|
-
name: string;
|
|
261
|
-
tableName: "playbook_approvals";
|
|
262
|
-
dataType: "string";
|
|
263
|
-
data: string;
|
|
264
|
-
driverParam: string;
|
|
265
|
-
notNull: true;
|
|
266
|
-
hasDefault: false;
|
|
267
|
-
isPrimaryKey: false;
|
|
268
|
-
isAutoincrement: false;
|
|
269
|
-
hasRuntimeDefault: false;
|
|
270
|
-
enumValues: [string, ...string[]];
|
|
271
|
-
baseColumn: never;
|
|
272
|
-
identity: undefined;
|
|
273
|
-
generated: undefined;
|
|
274
|
-
}, {}>;
|
|
275
|
-
requestedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
276
|
-
name: string;
|
|
277
|
-
tableName: "playbook_approvals";
|
|
278
|
-
dataType: "string";
|
|
279
|
-
data: string;
|
|
280
|
-
driverParam: string;
|
|
281
|
-
notNull: true;
|
|
282
|
-
hasDefault: true;
|
|
283
|
-
isPrimaryKey: false;
|
|
284
|
-
isAutoincrement: false;
|
|
285
|
-
hasRuntimeDefault: false;
|
|
286
|
-
enumValues: [string, ...string[]];
|
|
287
|
-
baseColumn: never;
|
|
288
|
-
identity: undefined;
|
|
289
|
-
generated: undefined;
|
|
290
|
-
}, {}>;
|
|
291
|
-
approvedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
292
|
-
name: string;
|
|
293
|
-
tableName: "playbook_approvals";
|
|
294
|
-
dataType: "string";
|
|
295
|
-
data: string;
|
|
296
|
-
driverParam: string;
|
|
297
|
-
notNull: false;
|
|
298
|
-
hasDefault: false;
|
|
299
|
-
isPrimaryKey: false;
|
|
300
|
-
isAutoincrement: false;
|
|
301
|
-
hasRuntimeDefault: false;
|
|
302
|
-
enumValues: [string, ...string[]];
|
|
303
|
-
baseColumn: never;
|
|
304
|
-
identity: undefined;
|
|
305
|
-
generated: undefined;
|
|
306
|
-
}, {}>;
|
|
307
|
-
approver: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
308
|
-
name: string;
|
|
309
|
-
tableName: "playbook_approvals";
|
|
310
|
-
dataType: "string";
|
|
311
|
-
data: string;
|
|
312
|
-
driverParam: string;
|
|
313
|
-
notNull: false;
|
|
314
|
-
hasDefault: false;
|
|
315
|
-
isPrimaryKey: false;
|
|
316
|
-
isAutoincrement: false;
|
|
317
|
-
hasRuntimeDefault: false;
|
|
318
|
-
enumValues: [string, ...string[]];
|
|
319
|
-
baseColumn: never;
|
|
320
|
-
identity: undefined;
|
|
321
|
-
generated: undefined;
|
|
322
|
-
}, {}>;
|
|
323
|
-
reason: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
324
|
-
name: string;
|
|
325
|
-
tableName: "playbook_approvals";
|
|
326
|
-
dataType: "string";
|
|
327
|
-
data: string;
|
|
328
|
-
driverParam: string;
|
|
329
|
-
notNull: false;
|
|
330
|
-
hasDefault: false;
|
|
331
|
-
isPrimaryKey: false;
|
|
332
|
-
isAutoincrement: false;
|
|
333
|
-
hasRuntimeDefault: false;
|
|
334
|
-
enumValues: [string, ...string[]];
|
|
335
|
-
baseColumn: never;
|
|
336
|
-
identity: undefined;
|
|
337
|
-
generated: undefined;
|
|
338
|
-
}, {}>;
|
|
339
|
-
status: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
340
|
-
name: string;
|
|
341
|
-
tableName: "playbook_approvals";
|
|
342
|
-
dataType: "string";
|
|
343
|
-
data: string;
|
|
344
|
-
driverParam: string;
|
|
345
|
-
notNull: true;
|
|
346
|
-
hasDefault: true;
|
|
347
|
-
isPrimaryKey: false;
|
|
348
|
-
isAutoincrement: false;
|
|
349
|
-
hasRuntimeDefault: false;
|
|
350
|
-
enumValues: [string, ...string[]];
|
|
351
|
-
baseColumn: never;
|
|
352
|
-
identity: undefined;
|
|
353
|
-
generated: undefined;
|
|
354
|
-
}, {}>;
|
|
355
|
-
autoPassed: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
356
|
-
name: string;
|
|
357
|
-
tableName: "playbook_approvals";
|
|
358
|
-
dataType: "number int53";
|
|
359
|
-
data: number;
|
|
360
|
-
driverParam: number;
|
|
361
|
-
notNull: true;
|
|
362
|
-
hasDefault: true;
|
|
363
|
-
isPrimaryKey: false;
|
|
364
|
-
isAutoincrement: false;
|
|
365
|
-
hasRuntimeDefault: false;
|
|
366
|
-
enumValues: undefined;
|
|
367
|
-
baseColumn: never;
|
|
368
|
-
identity: undefined;
|
|
369
|
-
generated: undefined;
|
|
370
|
-
}, {}>;
|
|
371
|
-
};
|
|
372
|
-
dialect: "sqlite";
|
|
373
|
-
}>;
|
|
374
|
-
export type { PlaybookApproval, PlaybookApprovalStatus, PlaybookRun, PlaybookRunStatus, } from '@cleocode/contracts';
|
package/dist/schema.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Drizzle ORM table definitions for playbook state.
|
|
3
|
-
* Both tables are added to tasks.db via migration at
|
|
4
|
-
* packages/core/migrations/drizzle-tasks/20260417220000_t889-playbook-tables/.
|
|
5
|
-
*
|
|
6
|
-
* @task T889 / T904 / W4-6
|
|
7
|
-
*/
|
|
8
|
-
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
9
|
-
export const playbookRuns = sqliteTable('playbook_runs', {
|
|
10
|
-
runId: text('run_id').primaryKey(),
|
|
11
|
-
playbookName: text('playbook_name').notNull(),
|
|
12
|
-
playbookHash: text('playbook_hash').notNull(),
|
|
13
|
-
currentNode: text('current_node'),
|
|
14
|
-
bindings: text('bindings').notNull().default('{}'),
|
|
15
|
-
errorContext: text('error_context'),
|
|
16
|
-
status: text('status').notNull().default('running'),
|
|
17
|
-
iterationCounts: text('iteration_counts').notNull().default('{}'),
|
|
18
|
-
epicId: text('epic_id'),
|
|
19
|
-
sessionId: text('session_id'),
|
|
20
|
-
startedAt: text('started_at').notNull().default("(datetime('now'))"),
|
|
21
|
-
completedAt: text('completed_at'),
|
|
22
|
-
});
|
|
23
|
-
export const playbookApprovals = sqliteTable('playbook_approvals', {
|
|
24
|
-
approvalId: text('approval_id').primaryKey(),
|
|
25
|
-
runId: text('run_id').notNull(),
|
|
26
|
-
nodeId: text('node_id').notNull(),
|
|
27
|
-
token: text('token').notNull().unique(),
|
|
28
|
-
requestedAt: text('requested_at').notNull().default("(datetime('now'))"),
|
|
29
|
-
approvedAt: text('approved_at'),
|
|
30
|
-
approver: text('approver'),
|
|
31
|
-
reason: text('reason'),
|
|
32
|
-
status: text('status').notNull().default('pending'),
|
|
33
|
-
autoPassed: integer('auto_passed').notNull().default(0),
|
|
34
|
-
});
|
package/dist/state.d.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* State layer for playbook runtime — CRUD against playbook_runs + playbook_approvals.
|
|
3
|
-
* Uses node:sqlite DatabaseSync for consistency with rest of CLEO.
|
|
4
|
-
*
|
|
5
|
-
* All JSON-shaped columns (`bindings`, `iteration_counts`) are serialized to
|
|
6
|
-
* text at the write boundary and strictly parsed on read. Parse failures throw
|
|
7
|
-
* rather than silently reset state, per the data-integrity contract of ADR-013.
|
|
8
|
-
*
|
|
9
|
-
* Multi-column updates and cross-table operations run inside a BEGIN/COMMIT
|
|
10
|
-
* transaction so partial failures cannot leave the run in a half-mutated state.
|
|
11
|
-
*
|
|
12
|
-
* @task T889 / T904 / W4-8
|
|
13
|
-
*/
|
|
14
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
15
|
-
import type { PlaybookApproval, PlaybookRun, PlaybookRunStatus } from '@cleocode/contracts';
|
|
16
|
-
/**
|
|
17
|
-
* Input payload for {@link createPlaybookRun}. `playbookHash` MUST be a stable
|
|
18
|
-
* digest of the `.cantbook` source so replays can prove definition parity.
|
|
19
|
-
*/
|
|
20
|
-
export interface CreatePlaybookRunInput {
|
|
21
|
-
playbookName: string;
|
|
22
|
-
playbookHash: string;
|
|
23
|
-
epicId?: string;
|
|
24
|
-
sessionId?: string;
|
|
25
|
-
initialBindings?: Record<string, unknown>;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Input payload for {@link createPlaybookApproval}. Callers MUST supply an
|
|
29
|
-
* opaque `token` — approval resume flows look up runs by this value.
|
|
30
|
-
*/
|
|
31
|
-
export interface CreatePlaybookApprovalInput {
|
|
32
|
-
runId: string;
|
|
33
|
-
nodeId: string;
|
|
34
|
-
token: string;
|
|
35
|
-
autoPassed?: boolean;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Filter options for {@link listPlaybookRuns}. All fields are optional; when
|
|
39
|
-
* omitted the call returns the most recent runs ordered by `started_at DESC`.
|
|
40
|
-
*/
|
|
41
|
-
export interface ListPlaybookRunsOptions {
|
|
42
|
-
status?: PlaybookRunStatus;
|
|
43
|
-
epicId?: string;
|
|
44
|
-
limit?: number;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Inserts a new playbook run with a freshly generated UUID, `status='running'`,
|
|
48
|
-
* and the provided initial bindings. Returns the hydrated {@link PlaybookRun}
|
|
49
|
-
* read back from the row so callers see all server-defaulted columns
|
|
50
|
-
* (`started_at`, empty `iteration_counts`, etc.).
|
|
51
|
-
*/
|
|
52
|
-
export declare function createPlaybookRun(db: DatabaseSync, input: CreatePlaybookRunInput): PlaybookRun;
|
|
53
|
-
/**
|
|
54
|
-
* Fetches a playbook run by its primary key. Returns `null` when the run
|
|
55
|
-
* does not exist. Never throws on missing rows.
|
|
56
|
-
*/
|
|
57
|
-
export declare function getPlaybookRun(db: DatabaseSync, runId: string): PlaybookRun | null;
|
|
58
|
-
/**
|
|
59
|
-
* Applies a partial patch to a playbook run inside a transaction so mixed
|
|
60
|
-
* column updates (e.g. `status` + `currentNode`) commit atomically. Returns
|
|
61
|
-
* the fully-hydrated run read back after commit.
|
|
62
|
-
*/
|
|
63
|
-
export declare function updatePlaybookRun(db: DatabaseSync, runId: string, patch: Partial<Omit<PlaybookRun, 'runId' | 'startedAt'>>): PlaybookRun;
|
|
64
|
-
/**
|
|
65
|
-
* Lists playbook runs filtered by status and/or epic. Defaults to `ORDER BY
|
|
66
|
-
* started_at DESC` so the newest runs surface first for dashboards.
|
|
67
|
-
*/
|
|
68
|
-
export declare function listPlaybookRuns(db: DatabaseSync, opts?: ListPlaybookRunsOptions): PlaybookRun[];
|
|
69
|
-
/**
|
|
70
|
-
* Deletes a playbook run by primary key. Returns `true` if a row was removed.
|
|
71
|
-
* CASCADE wipes all associated approvals via the foreign-key constraint on
|
|
72
|
-
* `playbook_approvals.run_id`.
|
|
73
|
-
*/
|
|
74
|
-
export declare function deletePlaybookRun(db: DatabaseSync, runId: string): boolean;
|
|
75
|
-
/**
|
|
76
|
-
* Inserts a new approval record with a freshly generated UUID, `status='pending'`,
|
|
77
|
-
* and the caller-supplied opaque token. Returns the hydrated
|
|
78
|
-
* {@link PlaybookApproval} so callers see the server-defaulted `requested_at`.
|
|
79
|
-
*/
|
|
80
|
-
export declare function createPlaybookApproval(db: DatabaseSync, input: CreatePlaybookApprovalInput): PlaybookApproval;
|
|
81
|
-
/**
|
|
82
|
-
* Fetches an approval by its opaque token. Returns `null` if no row matches.
|
|
83
|
-
* The token column carries a UNIQUE constraint so at most one row is returned.
|
|
84
|
-
*/
|
|
85
|
-
export declare function getPlaybookApprovalByToken(db: DatabaseSync, token: string): PlaybookApproval | null;
|
|
86
|
-
/**
|
|
87
|
-
* Applies a partial patch to an approval record inside a transaction. Used by
|
|
88
|
-
* the approval-resume flow to transactionally set both `status` and
|
|
89
|
-
* `approved_at` when a human resolves a HITL checkpoint.
|
|
90
|
-
*/
|
|
91
|
-
export declare function updatePlaybookApproval(db: DatabaseSync, approvalId: string, patch: Partial<Omit<PlaybookApproval, 'approvalId' | 'requestedAt'>>): PlaybookApproval;
|
|
92
|
-
/**
|
|
93
|
-
* Lists all approvals for a given run, ordered by `requested_at ASC` so the
|
|
94
|
-
* first HITL checkpoint surfaces first.
|
|
95
|
-
*/
|
|
96
|
-
export declare function listPlaybookApprovals(db: DatabaseSync, runId: string): PlaybookApproval[];
|