@mingchuno/agent-workflows 0.1.0

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.
Files changed (62) hide show
  1. package/LICENCE +21 -0
  2. package/README.md +74 -0
  3. package/dist/drizzle/0000_initial.sql +45 -0
  4. package/dist/drizzle/meta/0000_snapshot.json +264 -0
  5. package/dist/drizzle/meta/_journal.json +13 -0
  6. package/dist/src/adapters/agent-worker.d.ts +1 -0
  7. package/dist/src/adapters/agent-worker.js +16 -0
  8. package/dist/src/adapters/agents.d.ts +24 -0
  9. package/dist/src/adapters/agents.js +142 -0
  10. package/dist/src/adapters/hosting.d.ts +33 -0
  11. package/dist/src/adapters/hosting.js +275 -0
  12. package/dist/src/adapters/sdk-protocol.d.ts +43 -0
  13. package/dist/src/adapters/sdk-protocol.js +64 -0
  14. package/dist/src/cli.d.ts +2 -0
  15. package/dist/src/cli.js +175 -0
  16. package/dist/src/config.d.ts +224 -0
  17. package/dist/src/config.js +82 -0
  18. package/dist/src/db/locks.d.ts +4 -0
  19. package/dist/src/db/locks.js +14 -0
  20. package/dist/src/db/migrate.d.ts +1 -0
  21. package/dist/src/db/migrate.js +12 -0
  22. package/dist/src/db/migrations.d.ts +2 -0
  23. package/dist/src/db/migrations.js +22 -0
  24. package/dist/src/db/schema.d.ts +486 -0
  25. package/dist/src/db/schema.js +46 -0
  26. package/dist/src/domain.d.ts +133 -0
  27. package/dist/src/domain.js +24 -0
  28. package/dist/src/index.d.ts +8 -0
  29. package/dist/src/index.js +8 -0
  30. package/dist/src/operations.d.ts +35 -0
  31. package/dist/src/operations.js +378 -0
  32. package/dist/src/run-record.d.ts +7 -0
  33. package/dist/src/run-record.js +19 -0
  34. package/dist/src/runner.d.ts +47 -0
  35. package/dist/src/runner.js +370 -0
  36. package/dist/src/runtime/ownership.d.ts +8 -0
  37. package/dist/src/runtime/ownership.js +84 -0
  38. package/dist/src/runtime/process.d.ts +18 -0
  39. package/dist/src/runtime/process.js +98 -0
  40. package/dist/src/runtime/redaction.d.ts +8 -0
  41. package/dist/src/runtime/redaction.js +33 -0
  42. package/dist/src/store.d.ts +87 -0
  43. package/dist/src/store.js +355 -0
  44. package/dist/src/tui-data.d.ts +25 -0
  45. package/dist/src/tui-data.js +89 -0
  46. package/dist/src/tui.d.ts +5 -0
  47. package/dist/src/tui.js +69 -0
  48. package/dist/src/workspace.d.ts +16 -0
  49. package/dist/src/workspace.js +186 -0
  50. package/docs/acceptance.md +35 -0
  51. package/docs/api.md +64 -0
  52. package/docs/architecture.md +24 -0
  53. package/docs/configuration.md +41 -0
  54. package/docs/database.md +28 -0
  55. package/docs/operations.md +46 -0
  56. package/docs/providers.md +49 -0
  57. package/docs/releases.md +89 -0
  58. package/examples/config.ts +57 -0
  59. package/examples/custom-workflow.ts +32 -0
  60. package/examples/observe.ts +18 -0
  61. package/examples/run.ts +31 -0
  62. package/package.json +78 -0
@@ -0,0 +1,224 @@
1
+ import { z } from "zod";
2
+ export declare const profileSchema: z.ZodObject<{
3
+ provider: z.ZodEnum<{
4
+ codex: "codex";
5
+ copilot: "copilot";
6
+ }>;
7
+ model: z.ZodOptional<z.ZodString>;
8
+ reasoningEffort: z.ZodOptional<z.ZodString>;
9
+ context: z.ZodOptional<z.ZodObject<{
10
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
11
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
12
+ }, z.core.$strict>>;
13
+ }, z.core.$strict>;
14
+ export type AgentProfile = z.infer<typeof profileSchema>;
15
+ export declare const stageSchema: z.ZodObject<{
16
+ profile: z.ZodOptional<z.ZodObject<{
17
+ provider: z.ZodOptional<z.ZodEnum<{
18
+ codex: "codex";
19
+ copilot: "copilot";
20
+ }>>;
21
+ model: z.ZodOptional<z.ZodOptional<z.ZodString>>;
22
+ reasoningEffort: z.ZodOptional<z.ZodOptional<z.ZodString>>;
23
+ context: z.ZodOptional<z.ZodOptional<z.ZodObject<{
24
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
25
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
26
+ }, z.core.$strict>>>;
27
+ }, z.core.$strict>>;
28
+ prompt: z.ZodDefault<z.ZodString>;
29
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
30
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
31
+ }, z.core.$strict>;
32
+ export declare const projectSchema: z.ZodObject<{
33
+ id: z.ZodString;
34
+ checkout: z.ZodString;
35
+ hosting: z.ZodObject<{
36
+ provider: z.ZodEnum<{
37
+ github: "github";
38
+ gitlab: "gitlab";
39
+ }>;
40
+ origin: z.ZodURL;
41
+ repository: z.ZodString;
42
+ tokenEnv: z.ZodString;
43
+ }, z.core.$strict>;
44
+ labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
45
+ baseBranch: z.ZodDefault<z.ZodString>;
46
+ remote: z.ZodDefault<z.ZodString>;
47
+ branchTemplate: z.ZodDefault<z.ZodString>;
48
+ pollIntervalMs: z.ZodDefault<z.ZodNumber>;
49
+ validation: z.ZodDefault<z.ZodArray<z.ZodObject<{
50
+ command: z.ZodString;
51
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
52
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
53
+ }, z.core.$strict>>>;
54
+ gitIdentity: z.ZodObject<{
55
+ name: z.ZodString;
56
+ email: z.ZodEmail;
57
+ }, z.core.$strict>;
58
+ agent: z.ZodObject<{
59
+ provider: z.ZodEnum<{
60
+ codex: "codex";
61
+ copilot: "copilot";
62
+ }>;
63
+ model: z.ZodOptional<z.ZodString>;
64
+ reasoningEffort: z.ZodOptional<z.ZodString>;
65
+ context: z.ZodOptional<z.ZodObject<{
66
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
67
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
68
+ }, z.core.$strict>>;
69
+ }, z.core.$strict>;
70
+ stages: z.ZodDefault<z.ZodObject<{
71
+ implementation: z.ZodDefault<z.ZodObject<{
72
+ profile: z.ZodOptional<z.ZodObject<{
73
+ provider: z.ZodOptional<z.ZodEnum<{
74
+ codex: "codex";
75
+ copilot: "copilot";
76
+ }>>;
77
+ model: z.ZodOptional<z.ZodOptional<z.ZodString>>;
78
+ reasoningEffort: z.ZodOptional<z.ZodOptional<z.ZodString>>;
79
+ context: z.ZodOptional<z.ZodOptional<z.ZodObject<{
80
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
81
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
82
+ }, z.core.$strict>>>;
83
+ }, z.core.$strict>>;
84
+ prompt: z.ZodDefault<z.ZodString>;
85
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
86
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
87
+ }, z.core.$strict>>;
88
+ writing: z.ZodDefault<z.ZodObject<{
89
+ profile: z.ZodOptional<z.ZodObject<{
90
+ provider: z.ZodOptional<z.ZodEnum<{
91
+ codex: "codex";
92
+ copilot: "copilot";
93
+ }>>;
94
+ model: z.ZodOptional<z.ZodOptional<z.ZodString>>;
95
+ reasoningEffort: z.ZodOptional<z.ZodOptional<z.ZodString>>;
96
+ context: z.ZodOptional<z.ZodOptional<z.ZodObject<{
97
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
98
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
99
+ }, z.core.$strict>>>;
100
+ }, z.core.$strict>>;
101
+ prompt: z.ZodDefault<z.ZodString>;
102
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
103
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
104
+ }, z.core.$strict>>;
105
+ review: z.ZodDefault<z.ZodObject<{
106
+ profile: z.ZodOptional<z.ZodObject<{
107
+ provider: z.ZodOptional<z.ZodEnum<{
108
+ codex: "codex";
109
+ copilot: "copilot";
110
+ }>>;
111
+ model: z.ZodOptional<z.ZodOptional<z.ZodString>>;
112
+ reasoningEffort: z.ZodOptional<z.ZodOptional<z.ZodString>>;
113
+ context: z.ZodOptional<z.ZodOptional<z.ZodObject<{
114
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
115
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
116
+ }, z.core.$strict>>>;
117
+ }, z.core.$strict>>;
118
+ prompt: z.ZodDefault<z.ZodString>;
119
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
120
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
121
+ }, z.core.$strict>>;
122
+ }, z.core.$strict>>;
123
+ }, z.core.$strict>;
124
+ export declare const configSchema: z.ZodObject<{
125
+ id: z.ZodString;
126
+ databaseUrlEnv: z.ZodDefault<z.ZodString>;
127
+ stateDirectory: z.ZodDefault<z.ZodString>;
128
+ projects: z.ZodArray<z.ZodObject<{
129
+ id: z.ZodString;
130
+ checkout: z.ZodString;
131
+ hosting: z.ZodObject<{
132
+ provider: z.ZodEnum<{
133
+ github: "github";
134
+ gitlab: "gitlab";
135
+ }>;
136
+ origin: z.ZodURL;
137
+ repository: z.ZodString;
138
+ tokenEnv: z.ZodString;
139
+ }, z.core.$strict>;
140
+ labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
141
+ baseBranch: z.ZodDefault<z.ZodString>;
142
+ remote: z.ZodDefault<z.ZodString>;
143
+ branchTemplate: z.ZodDefault<z.ZodString>;
144
+ pollIntervalMs: z.ZodDefault<z.ZodNumber>;
145
+ validation: z.ZodDefault<z.ZodArray<z.ZodObject<{
146
+ command: z.ZodString;
147
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
148
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
149
+ }, z.core.$strict>>>;
150
+ gitIdentity: z.ZodObject<{
151
+ name: z.ZodString;
152
+ email: z.ZodEmail;
153
+ }, z.core.$strict>;
154
+ agent: z.ZodObject<{
155
+ provider: z.ZodEnum<{
156
+ codex: "codex";
157
+ copilot: "copilot";
158
+ }>;
159
+ model: z.ZodOptional<z.ZodString>;
160
+ reasoningEffort: z.ZodOptional<z.ZodString>;
161
+ context: z.ZodOptional<z.ZodObject<{
162
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
163
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
164
+ }, z.core.$strict>>;
165
+ }, z.core.$strict>;
166
+ stages: z.ZodDefault<z.ZodObject<{
167
+ implementation: z.ZodDefault<z.ZodObject<{
168
+ profile: z.ZodOptional<z.ZodObject<{
169
+ provider: z.ZodOptional<z.ZodEnum<{
170
+ codex: "codex";
171
+ copilot: "copilot";
172
+ }>>;
173
+ model: z.ZodOptional<z.ZodOptional<z.ZodString>>;
174
+ reasoningEffort: z.ZodOptional<z.ZodOptional<z.ZodString>>;
175
+ context: z.ZodOptional<z.ZodOptional<z.ZodObject<{
176
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
177
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
178
+ }, z.core.$strict>>>;
179
+ }, z.core.$strict>>;
180
+ prompt: z.ZodDefault<z.ZodString>;
181
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
182
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
183
+ }, z.core.$strict>>;
184
+ writing: z.ZodDefault<z.ZodObject<{
185
+ profile: z.ZodOptional<z.ZodObject<{
186
+ provider: z.ZodOptional<z.ZodEnum<{
187
+ codex: "codex";
188
+ copilot: "copilot";
189
+ }>>;
190
+ model: z.ZodOptional<z.ZodOptional<z.ZodString>>;
191
+ reasoningEffort: z.ZodOptional<z.ZodOptional<z.ZodString>>;
192
+ context: z.ZodOptional<z.ZodOptional<z.ZodObject<{
193
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
194
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
195
+ }, z.core.$strict>>>;
196
+ }, z.core.$strict>>;
197
+ prompt: z.ZodDefault<z.ZodString>;
198
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
199
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
200
+ }, z.core.$strict>>;
201
+ review: z.ZodDefault<z.ZodObject<{
202
+ profile: z.ZodOptional<z.ZodObject<{
203
+ provider: z.ZodOptional<z.ZodEnum<{
204
+ codex: "codex";
205
+ copilot: "copilot";
206
+ }>>;
207
+ model: z.ZodOptional<z.ZodOptional<z.ZodString>>;
208
+ reasoningEffort: z.ZodOptional<z.ZodOptional<z.ZodString>>;
209
+ context: z.ZodOptional<z.ZodOptional<z.ZodObject<{
210
+ backgroundCompactionThreshold: z.ZodOptional<z.ZodNumber>;
211
+ bufferExhaustionThreshold: z.ZodOptional<z.ZodNumber>;
212
+ }, z.core.$strict>>>;
213
+ }, z.core.$strict>>;
214
+ prompt: z.ZodDefault<z.ZodString>;
215
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
216
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
217
+ }, z.core.$strict>>;
218
+ }, z.core.$strict>>;
219
+ }, z.core.$strict>>;
220
+ }, z.core.$strict>;
221
+ export type Project = z.infer<typeof projectSchema>;
222
+ export type Configuration = z.infer<typeof configSchema>;
223
+ export type Stage = z.infer<typeof stageSchema>;
224
+ export declare function resolveProfile(defaults: AgentProfile, override?: Partial<AgentProfile>): AgentProfile;
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+ export const profileSchema = z.strictObject({
3
+ provider: z.enum(["codex", "copilot"]),
4
+ model: z.string().min(1).optional(),
5
+ reasoningEffort: z.string().min(1).optional(),
6
+ context: z
7
+ .strictObject({
8
+ backgroundCompactionThreshold: z.number().positive().lt(1).optional(),
9
+ bufferExhaustionThreshold: z.number().positive().lte(1).optional(),
10
+ })
11
+ .optional(),
12
+ });
13
+ export const stageSchema = z.strictObject({
14
+ profile: profileSchema.partial().optional(),
15
+ prompt: z.string().default(""),
16
+ skills: z.array(z.string()).default([]),
17
+ timeoutMs: z.number().int().positive().default(1_800_000),
18
+ });
19
+ export const projectSchema = z.strictObject({
20
+ id: z.string().regex(/^[a-zA-Z0-9_-]+$/),
21
+ checkout: z.string().min(1),
22
+ hosting: z.strictObject({
23
+ provider: z.enum(["github", "gitlab"]),
24
+ origin: z.url(),
25
+ repository: z.string().min(1),
26
+ tokenEnv: z.string().regex(/^[A-Z_][A-Z0-9_]*$/),
27
+ }),
28
+ labels: z.array(z.string().min(1)).min(1).default(["ready-for-agent"]),
29
+ baseBranch: z.string().min(1).default("main"),
30
+ remote: z
31
+ .string()
32
+ .regex(/^[a-zA-Z0-9_-]+$/)
33
+ .default("origin"),
34
+ branchTemplate: z
35
+ .string()
36
+ .includes("{issue}")
37
+ .default("agent/{issue}-{attempt}"),
38
+ pollIntervalMs: z.number().int().min(100).default(30_000),
39
+ validation: z
40
+ .array(z.strictObject({
41
+ command: z.string().min(1),
42
+ args: z.array(z.string()).default([]),
43
+ timeoutMs: z.number().int().positive().default(300_000),
44
+ }))
45
+ .default([]),
46
+ gitIdentity: z.strictObject({ name: z.string().min(1), email: z.email() }),
47
+ agent: profileSchema,
48
+ stages: z
49
+ .strictObject({
50
+ implementation: stageSchema.default(() => ({
51
+ prompt: "",
52
+ skills: [],
53
+ timeoutMs: 1_800_000,
54
+ })),
55
+ writing: stageSchema.default(() => ({
56
+ prompt: "",
57
+ skills: [],
58
+ timeoutMs: 1_800_000,
59
+ })),
60
+ review: stageSchema.default(() => ({
61
+ prompt: "",
62
+ skills: [],
63
+ timeoutMs: 1_800_000,
64
+ })),
65
+ })
66
+ .default(() => ({
67
+ implementation: { prompt: "", skills: [], timeoutMs: 1_800_000 },
68
+ writing: { prompt: "", skills: [], timeoutMs: 1_800_000 },
69
+ review: { prompt: "", skills: [], timeoutMs: 1_800_000 },
70
+ })),
71
+ });
72
+ export const configSchema = z.strictObject({
73
+ id: z.string().regex(/^[a-zA-Z0-9_-]+$/),
74
+ databaseUrlEnv: z.string().default("AGENT_WORKFLOWS_DATABASE_URL"),
75
+ stateDirectory: z.string().default(".agent-workflows"),
76
+ projects: z.array(projectSchema).min(1),
77
+ });
78
+ export function resolveProfile(defaults, override = {}) {
79
+ if (override.provider && override.provider !== defaults.provider)
80
+ return profileSchema.parse(override);
81
+ return profileSchema.parse({ ...defaults, ...override });
82
+ }
@@ -0,0 +1,4 @@
1
+ import type { PoolClient } from "pg";
2
+ export declare function tryLock(client: PoolClient, key: string): Promise<boolean>;
3
+ export declare function lockMigrations(client: PoolClient): Promise<void>;
4
+ export declare function unlockAll(client: PoolClient): Promise<void>;
@@ -0,0 +1,14 @@
1
+ // PostgreSQL session locks have no Drizzle query-builder equivalent.
2
+ // Keep these fixed, parameterized driver calls on the owning connection.
3
+ export async function tryLock(client, key) {
4
+ const result = await client.query("SELECT pg_try_advisory_lock(hashtextextended($1,0)) AS locked", [key]);
5
+ return result.rows[0]?.locked === true;
6
+ }
7
+ export async function lockMigrations(client) {
8
+ await client.query("SELECT pg_advisory_lock(hashtextextended($1,0))", [
9
+ "agent_workflows:migrations",
10
+ ]);
11
+ }
12
+ export async function unlockAll(client) {
13
+ await client.query("SELECT pg_advisory_unlock_all()");
14
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Pool } from "pg";
2
+ import { migrateDatabase } from "./migrations.js";
3
+ const databaseUrl = process.env.AGENT_WORKFLOWS_DATABASE_URL;
4
+ if (!databaseUrl)
5
+ throw new Error("Set AGENT_WORKFLOWS_DATABASE_URL to a PostgreSQL URL");
6
+ const pool = new Pool({ connectionString: databaseUrl });
7
+ try {
8
+ await migrateDatabase(pool);
9
+ }
10
+ finally {
11
+ await pool.end();
12
+ }
@@ -0,0 +1,2 @@
1
+ import type { Pool } from "pg";
2
+ export declare function migrateDatabase(pool: Pool): Promise<void>;
@@ -0,0 +1,22 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { drizzle } from "drizzle-orm/node-postgres";
3
+ import { migrate } from "drizzle-orm/node-postgres/migrator";
4
+ import { lockMigrations, unlockAll } from "./locks.js";
5
+ export async function migrateDatabase(pool) {
6
+ const client = await pool.connect();
7
+ try {
8
+ await lockMigrations(client);
9
+ await migrate(drizzle(client), {
10
+ migrationsFolder: fileURLToPath(new URL("../../drizzle", import.meta.url)),
11
+ migrationsSchema: "agent_workflows_migrations",
12
+ });
13
+ }
14
+ finally {
15
+ try {
16
+ await unlockAll(client);
17
+ }
18
+ finally {
19
+ client.release(true);
20
+ }
21
+ }
22
+ }