agent-merge-broker 0.3.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 (75) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +352 -0
  3. package/dist/broker.d.ts +110 -0
  4. package/dist/broker.d.ts.map +1 -0
  5. package/dist/broker.js +1023 -0
  6. package/dist/broker.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +558 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.d.ts +19 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +312 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/errors.d.ts +16 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +36 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/git.d.ts +46 -0
  20. package/dist/git.d.ts.map +1 -0
  21. package/dist/git.js +195 -0
  22. package/dist/git.js.map +1 -0
  23. package/dist/hooks.d.ts +22 -0
  24. package/dist/hooks.d.ts.map +1 -0
  25. package/dist/hooks.js +110 -0
  26. package/dist/hooks.js.map +1 -0
  27. package/dist/index.d.ts +11 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +10 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/patterns.d.ts +9 -0
  32. package/dist/patterns.d.ts.map +1 -0
  33. package/dist/patterns.js +66 -0
  34. package/dist/patterns.js.map +1 -0
  35. package/dist/process.d.ts +30 -0
  36. package/dist/process.d.ts.map +1 -0
  37. package/dist/process.js +91 -0
  38. package/dist/process.js.map +1 -0
  39. package/dist/provenance.d.ts +10 -0
  40. package/dist/provenance.d.ts.map +1 -0
  41. package/dist/provenance.js +36 -0
  42. package/dist/provenance.js.map +1 -0
  43. package/dist/publisher.d.ts +37 -0
  44. package/dist/publisher.d.ts.map +1 -0
  45. package/dist/publisher.js +144 -0
  46. package/dist/publisher.js.map +1 -0
  47. package/dist/scheduler.d.ts +6 -0
  48. package/dist/scheduler.d.ts.map +1 -0
  49. package/dist/scheduler.js +96 -0
  50. package/dist/scheduler.js.map +1 -0
  51. package/dist/store.d.ts +73 -0
  52. package/dist/store.d.ts.map +1 -0
  53. package/dist/store.js +323 -0
  54. package/dist/store.js.map +1 -0
  55. package/dist/types.d.ts +219 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +3 -0
  58. package/dist/types.js.map +1 -0
  59. package/dist/validation.d.ts +13 -0
  60. package/dist/validation.d.ts.map +1 -0
  61. package/dist/validation.js +75 -0
  62. package/dist/validation.js.map +1 -0
  63. package/dist/verify.d.ts +40 -0
  64. package/dist/verify.d.ts.map +1 -0
  65. package/dist/verify.js +177 -0
  66. package/dist/verify.js.map +1 -0
  67. package/docs/ARCHITECTURE.md +144 -0
  68. package/docs/PROTOCOL.md +127 -0
  69. package/docs/RELEASING.md +23 -0
  70. package/docs/SECURITY.md +57 -0
  71. package/package.json +68 -0
  72. package/schemas/config.schema.json +149 -0
  73. package/schemas/provenance.schema.json +56 -0
  74. package/schemas/receipt.schema.json +39 -0
  75. package/templates/AGENTS.snippet.md +5 -0
package/dist/store.js ADDED
@@ -0,0 +1,323 @@
1
+ import path from "node:path";
2
+ import { hostname } from "node:os";
3
+ import { createHash, randomUUID } from "node:crypto";
4
+ import { constants } from "node:fs";
5
+ import { access, appendFile, chmod, mkdir, open, readFile, rename, rm, stat, writeFile, } from "node:fs/promises";
6
+ import { BrokerError } from "./errors.js";
7
+ import { STATE_VERSION } from "./types.js";
8
+ /** Most recent audit bytes scanned by a read. Older events remain in the rotated segments. */
9
+ const AUDIT_TAIL_BYTES = 1_024 * 1_024;
10
+ /** Size at which the active audit file is rotated into an archive segment. */
11
+ const AUDIT_ROTATE_BYTES = 16 * 1_024 * 1_024;
12
+ const delay = async (milliseconds) => {
13
+ await new Promise((resolve) => setTimeout(resolve, milliseconds));
14
+ };
15
+ async function exists(target) {
16
+ try {
17
+ await access(target, constants.F_OK);
18
+ return true;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ export class StateStore {
25
+ directory;
26
+ worktreesDirectory;
27
+ archiveDirectory;
28
+ tokensDirectory;
29
+ stateFile;
30
+ auditFile;
31
+ receiptsDirectory;
32
+ batchesDirectory;
33
+ lockTimeoutMs;
34
+ constructor(commonGitDir, stateDirectory, lockTimeoutSeconds) {
35
+ this.directory = path.resolve(commonGitDir, stateDirectory);
36
+ this.worktreesDirectory = path.join(this.directory, "worktrees");
37
+ this.archiveDirectory = path.join(this.directory, "archive");
38
+ this.tokensDirectory = path.join(this.directory, "tokens");
39
+ this.stateFile = path.join(this.directory, "state.json");
40
+ this.auditFile = path.join(this.directory, "audit.jsonl");
41
+ this.receiptsDirectory = path.join(this.directory, "receipts");
42
+ this.batchesDirectory = path.join(this.directory, "batches");
43
+ this.lockTimeoutMs = lockTimeoutSeconds * 1_000;
44
+ }
45
+ async initialize() {
46
+ await Promise.all([
47
+ mkdir(this.directory, { recursive: true }),
48
+ mkdir(this.worktreesDirectory, { recursive: true }),
49
+ mkdir(this.receiptsDirectory, { recursive: true }),
50
+ mkdir(this.batchesDirectory, { recursive: true }),
51
+ mkdir(this.archiveDirectory, { recursive: true }),
52
+ mkdir(this.tokensDirectory, { recursive: true, mode: 0o700 }),
53
+ ]);
54
+ if (!(await exists(this.stateFile))) {
55
+ try {
56
+ await writeFile(this.stateFile, `${JSON.stringify({
57
+ version: STATE_VERSION,
58
+ sequence: 0,
59
+ tasks: {},
60
+ batches: {},
61
+ }, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
62
+ }
63
+ catch (error) {
64
+ if (error.code !== "EEXIST")
65
+ throw error;
66
+ }
67
+ }
68
+ }
69
+ async read() {
70
+ await this.initialize();
71
+ const source = await readFile(this.stateFile, "utf8");
72
+ let state;
73
+ try {
74
+ state = JSON.parse(source);
75
+ }
76
+ catch (error) {
77
+ throw new BrokerError("STATE_CORRUPT", `Broker state is not valid JSON: ${this.stateFile}`, {
78
+ cause: error instanceof Error ? error.message : String(error),
79
+ });
80
+ }
81
+ if (state.version !== STATE_VERSION) {
82
+ throw new BrokerError("STATE_VERSION", `Unsupported broker state version: ${String(state.version)}`);
83
+ }
84
+ return state;
85
+ }
86
+ async transaction(mutator) {
87
+ return await this.withLock("state", async () => {
88
+ const state = await this.read();
89
+ const events = [];
90
+ const record = (event, fields = {}) => {
91
+ state.sequence += 1;
92
+ events.push({ sequence: state.sequence, at: new Date().toISOString(), event, ...fields });
93
+ };
94
+ const result = await mutator(state, record);
95
+ await this.atomicWrite(this.stateFile, state);
96
+ if (events.length > 0) {
97
+ await this.rotateAuditIfLarge();
98
+ await appendFile(this.auditFile, `${events.map((event) => JSON.stringify(event)).join("\n")}\n`, "utf8");
99
+ }
100
+ return result;
101
+ });
102
+ }
103
+ async withIntegrationLock(operation) {
104
+ return await this.withLock("integration", operation, 24 * 60 * 60 * 1_000);
105
+ }
106
+ async writeReceipt(receipt) {
107
+ await this.initialize();
108
+ const target = path.join(this.receiptsDirectory, `${safeName(receipt.taskId)}.json`);
109
+ await this.atomicWrite(target, receipt);
110
+ return target;
111
+ }
112
+ tokenPath(taskId) {
113
+ return path.join(this.tokensDirectory, `${safeName(taskId)}.token`);
114
+ }
115
+ /**
116
+ * Holds a worker's lease token for it. A token shown once and never stored forces every adopter to
117
+ * build a token store, and the obvious implementation puts a live credential in the working tree
118
+ * where `git add` and validator commands can reach it. Here it stays owner-readable, beside the
119
+ * state it authorizes, under a directory whose contents are already trusted.
120
+ */
121
+ async writeToken(taskId, token, target = this.tokenPath(taskId)) {
122
+ await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
123
+ await chmod(path.dirname(target), 0o700).catch(() => undefined);
124
+ const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`;
125
+ await writeFile(temporary, `${token}\n`, { encoding: "utf8", mode: 0o600 });
126
+ await chmod(temporary, 0o600).catch(() => undefined);
127
+ await rename(temporary, target);
128
+ return target;
129
+ }
130
+ async readToken(taskId) {
131
+ try {
132
+ return (await readFile(this.tokenPath(taskId), "utf8")).trim() || undefined;
133
+ }
134
+ catch {
135
+ return undefined;
136
+ }
137
+ }
138
+ async deleteToken(taskId) {
139
+ await rm(this.tokenPath(taskId), { force: true });
140
+ }
141
+ async writeBatchManifest(batchId, manifest) {
142
+ await this.initialize();
143
+ const target = path.join(this.batchesDirectory, `${safeName(batchId)}.json`);
144
+ await this.atomicWrite(target, manifest);
145
+ return target;
146
+ }
147
+ /**
148
+ * Reads the tail of the active audit stream. Deliberately tolerant: a tail read can begin
149
+ * mid-line, and a crash between writing and flushing can leave a truncated final line. Neither is
150
+ * a reason to make the whole audit trail unreadable, which is exactly when it is needed most.
151
+ */
152
+ async readAudit(limit = 100) {
153
+ if (!(await exists(this.auditFile)))
154
+ return [];
155
+ const handle = await open(this.auditFile, "r");
156
+ let text;
157
+ let partialStart;
158
+ try {
159
+ const { size } = await handle.stat();
160
+ const start = Math.max(0, size - AUDIT_TAIL_BYTES);
161
+ partialStart = start > 0;
162
+ const length = size - start;
163
+ if (length === 0)
164
+ return [];
165
+ const buffer = Buffer.alloc(length);
166
+ await handle.read(buffer, 0, length, start);
167
+ text = buffer.toString("utf8");
168
+ }
169
+ finally {
170
+ await handle.close();
171
+ }
172
+ const lines = text.split("\n").filter((line) => line.trim() !== "");
173
+ if (partialStart)
174
+ lines.shift();
175
+ const events = [];
176
+ for (const line of lines) {
177
+ try {
178
+ events.push(JSON.parse(line));
179
+ }
180
+ catch {
181
+ continue;
182
+ }
183
+ }
184
+ return events.slice(-limit);
185
+ }
186
+ /**
187
+ * Moves the active audit file aside once it grows large enough to make reads expensive. Segments
188
+ * are never deleted: an audit stream that silently forgets is worse than a large one.
189
+ */
190
+ async rotateAuditIfLarge() {
191
+ const current = await stat(this.auditFile).catch(() => undefined);
192
+ if (!current || current.size < AUDIT_ROTATE_BYTES)
193
+ return;
194
+ const stamp = new Date().toISOString().replace(/[:.]/gu, "-");
195
+ await mkdir(this.archiveDirectory, { recursive: true });
196
+ await rename(this.auditFile, path.join(this.archiveDirectory, `audit-${stamp}.jsonl`));
197
+ }
198
+ /** Writes a retired slice of state to the archive directory and returns its path. */
199
+ async archive(name, value) {
200
+ await mkdir(this.archiveDirectory, { recursive: true });
201
+ const stamp = new Date().toISOString().replace(/[:.]/gu, "-");
202
+ const label = name.replace(/[^a-zA-Z0-9._-]/gu, "-").slice(0, 32) || "archive";
203
+ const target = path.join(this.archiveDirectory, `${label}-${stamp}.json`);
204
+ await this.atomicWrite(target, value);
205
+ return target;
206
+ }
207
+ async inspectLock(name) {
208
+ const lockDirectory = path.join(this.directory, `${name}.lock`);
209
+ const lockStat = await stat(lockDirectory).catch(() => undefined);
210
+ if (!lockStat)
211
+ return { name, held: false, path: lockDirectory };
212
+ let owner;
213
+ try {
214
+ const parsed = JSON.parse(await readFile(path.join(lockDirectory, "owner.json"), "utf8"));
215
+ owner = {
216
+ ...(Number.isInteger(parsed.pid) ? { pid: parsed.pid } : {}),
217
+ ...(typeof parsed.host === "string" ? { host: parsed.host } : {}),
218
+ ...(typeof parsed.createdAt === "string" ? { createdAt: parsed.createdAt } : {}),
219
+ };
220
+ }
221
+ catch {
222
+ owner = undefined;
223
+ }
224
+ return {
225
+ name,
226
+ held: true,
227
+ path: lockDirectory,
228
+ ...(owner ? { owner } : {}),
229
+ ageMs: Date.now() - lockStat.mtimeMs,
230
+ abandoned: await this.lockOwnerCrashed(lockDirectory),
231
+ };
232
+ }
233
+ /**
234
+ * Releases a held lock. Without `force` this refuses unless the holder is provably gone, because
235
+ * removing a live lock allows two integrations to run against the same repository at once.
236
+ */
237
+ async releaseLock(name, options = {}) {
238
+ const status = await this.inspectLock(name);
239
+ if (!status.held)
240
+ return status;
241
+ if (!options.force && !status.abandoned) {
242
+ throw new BrokerError("LOCK_HELD", `The ${name} lock is held by ${status.owner?.host ?? "an unknown host"} (pid ${status.owner?.pid ?? "unknown"}) and is not provably abandoned. Re-run with --force only after confirming no integration is running.`, { lock: status });
243
+ }
244
+ await rm(status.path, { recursive: true, force: true });
245
+ return { ...status, held: false };
246
+ }
247
+ async withLock(name, operation, staleMs = 60_000) {
248
+ await this.initialize();
249
+ const lockDirectory = path.join(this.directory, `${name}.lock`);
250
+ const startedAt = Date.now();
251
+ while (true) {
252
+ try {
253
+ await mkdir(lockDirectory);
254
+ await writeFile(path.join(lockDirectory, "owner.json"), `${JSON.stringify({ pid: process.pid, host: hostname(), createdAt: new Date().toISOString() })}\n`, "utf8");
255
+ break;
256
+ }
257
+ catch (error) {
258
+ const code = error.code;
259
+ if (code !== "EEXIST")
260
+ throw error;
261
+ const lockStat = await stat(lockDirectory).catch(() => undefined);
262
+ // A crashed holder on this machine can be detected directly, so its lock is reclaimed after a
263
+ // short grace period. A holder on another machine cannot be probed at all -- the state
264
+ // directory is shared, but process IDs are not -- so those wait out the full stale timeout
265
+ // rather than risk two integrations running at once.
266
+ const age = lockStat ? Date.now() - lockStat.mtimeMs : 0;
267
+ if (lockStat && (age > staleMs || (age > 2_000 && (await this.lockOwnerCrashed(lockDirectory))))) {
268
+ await rm(lockDirectory, { recursive: true, force: true });
269
+ continue;
270
+ }
271
+ if (Date.now() - startedAt > this.lockTimeoutMs) {
272
+ throw new BrokerError("LOCK_TIMEOUT", `Timed out waiting for the ${name} lock.`, { lockDirectory });
273
+ }
274
+ await delay(50 + Math.floor(Math.random() * 100));
275
+ }
276
+ }
277
+ try {
278
+ return await operation();
279
+ }
280
+ finally {
281
+ await rm(lockDirectory, { recursive: true, force: true });
282
+ }
283
+ }
284
+ /**
285
+ * True only when the lock is provably abandoned: written by this machine, by a process that is
286
+ * gone. An unreadable owner file is not proof -- it is also what a lock looks like in the instant
287
+ * between creating the directory and recording its owner.
288
+ */
289
+ async lockOwnerCrashed(lockDirectory) {
290
+ let owner;
291
+ try {
292
+ owner = JSON.parse(await readFile(path.join(lockDirectory, "owner.json"), "utf8"));
293
+ }
294
+ catch {
295
+ return false;
296
+ }
297
+ // Records written before owners carried a hostname fall back to the process check. Treating them
298
+ // as foreign instead would strand a crashed holder's lock for the full stale timeout.
299
+ if (owner.host !== undefined && owner.host !== hostname())
300
+ return false;
301
+ if (!Number.isInteger(owner.pid) || owner.pid <= 0)
302
+ return false;
303
+ try {
304
+ process.kill(owner.pid, 0);
305
+ return false;
306
+ }
307
+ catch (error) {
308
+ return error.code !== "EPERM";
309
+ }
310
+ }
311
+ async atomicWrite(target, value) {
312
+ await mkdir(path.dirname(target), { recursive: true });
313
+ const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`;
314
+ await writeFile(temporary, `${JSON.stringify(value, null, 2)}\n`, "utf8");
315
+ await rename(temporary, target);
316
+ }
317
+ }
318
+ function safeName(value) {
319
+ const readable = value.replace(/[^a-zA-Z0-9._-]/gu, "-").slice(0, 96);
320
+ const digest = createHash("sha256").update(value).digest("hex").slice(0, 12);
321
+ return `${readable || "record"}-${digest}`;
322
+ }
323
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ export declare const STATE_VERSION: 1;
2
+ export declare const CONFIG_VERSION: 1;
3
+ export type UnexpectedPathPolicy = "error" | "warn" | "allow";
4
+ export type PublishMode = "none" | "branch" | "pull-request";
5
+ export type HistoryMode = "preserve" | "squash";
6
+ export type MergeMethod = "squash" | "merge" | "rebase";
7
+ export type TaskStatus = "registered" | "claimed" | "submitted" | "integrating" | "batched" | "published" | "merged" | "failed" | "cancelled";
8
+ export type BatchStatus = "running" | "verified" | "prepared" | "published" | "merged" | "closed" | "failed";
9
+ export interface ValidatorConfig {
10
+ name: string;
11
+ command: string;
12
+ paths?: string[];
13
+ timeoutSeconds?: number;
14
+ env?: Record<string, string>;
15
+ }
16
+ export interface BrokerConfig {
17
+ version: typeof CONFIG_VERSION;
18
+ baseBranch: string;
19
+ baseRef: string;
20
+ remote: string;
21
+ stateDirectory: string;
22
+ leases: {
23
+ ttlSeconds: number;
24
+ lockTimeoutSeconds: number;
25
+ serializedPatterns: string[];
26
+ };
27
+ policies: {
28
+ unexpectedPaths: UnexpectedPathPolicy;
29
+ requireCleanWorktree: boolean;
30
+ requireDependencies: boolean;
31
+ };
32
+ scheduling: {
33
+ maxTasks: number;
34
+ maxCommits: number;
35
+ maxWaitSeconds: number;
36
+ allowPathOverlap: boolean;
37
+ };
38
+ integration: {
39
+ branchPrefix: string;
40
+ history: HistoryMode;
41
+ keepFailedWorktrees: boolean;
42
+ refreshBase: boolean;
43
+ maxAttempts: number;
44
+ provenance?: {
45
+ enabled: boolean;
46
+ directory: string;
47
+ };
48
+ };
49
+ validation: {
50
+ shell?: string;
51
+ focused: ValidatorConfig[];
52
+ authoritative: ValidatorConfig[];
53
+ };
54
+ publish: {
55
+ mode: PublishMode;
56
+ draft: boolean;
57
+ autoMerge: boolean;
58
+ mergeMethod: MergeMethod;
59
+ labels: string[];
60
+ titleTemplate: string;
61
+ };
62
+ }
63
+ export interface LeaseRecord {
64
+ tokenHash: string;
65
+ holder: string;
66
+ acquiredAt: string;
67
+ heartbeatAt: string;
68
+ expiresAt: string;
69
+ }
70
+ export interface ValidationResult {
71
+ name: string;
72
+ command: string;
73
+ scope: "focused" | "authoritative";
74
+ taskId?: string;
75
+ startedAt: string;
76
+ finishedAt: string;
77
+ durationMs: number;
78
+ exitCode: number;
79
+ stdout: string;
80
+ stderr: string;
81
+ }
82
+ export interface TaskRecord {
83
+ id: string;
84
+ title?: string;
85
+ agent?: string;
86
+ status: TaskStatus;
87
+ priority: number;
88
+ baseSha: string;
89
+ expectedPaths: string[];
90
+ actualPaths: string[];
91
+ dependsOn: string[];
92
+ commits: string[];
93
+ worktree?: string;
94
+ lease?: LeaseRecord;
95
+ warnings: string[];
96
+ validations: ValidationResult[];
97
+ createdAt: string;
98
+ updatedAt: string;
99
+ submittedAt?: string;
100
+ batchedAt?: string;
101
+ publishedAt?: string;
102
+ mergedAt?: string;
103
+ batchId?: string;
104
+ lastError?: string;
105
+ attempts?: number;
106
+ }
107
+ export interface BatchRecord {
108
+ id: string;
109
+ status: BatchStatus;
110
+ taskIds: string[];
111
+ baseBranch: string;
112
+ baseSha: string;
113
+ branchName?: string;
114
+ headSha?: string;
115
+ integratedHeadSha?: string;
116
+ provenancePath?: string;
117
+ worktree?: string;
118
+ validations: ValidationResult[];
119
+ createdAt: string;
120
+ finishedAt?: string;
121
+ publishedAt?: string;
122
+ pullRequestUrl?: string;
123
+ autoMergeEnabled?: boolean;
124
+ closedAt?: string;
125
+ error?: string;
126
+ }
127
+ export interface BatchProvenance {
128
+ version: 1;
129
+ generator: "agent-merge-broker";
130
+ batchId: string;
131
+ baseBranch: string;
132
+ /**
133
+ * How the batch was assembled. Squashing replaces the cherry-pick trail, so a verifier cannot
134
+ * look for submitted commits in the integrated history. Absent on manifests written before this
135
+ * field existed, which were always assembled with preserved history.
136
+ */
137
+ history?: HistoryMode;
138
+ baseSha: string;
139
+ integratedHeadSha: string;
140
+ taskIds: string[];
141
+ tasks: Array<{
142
+ id: string;
143
+ commits: string[];
144
+ actualPaths: string[];
145
+ dependsOn: string[];
146
+ }>;
147
+ validations: Array<{
148
+ name: string;
149
+ scope: "focused" | "authoritative";
150
+ taskId?: string;
151
+ exitCode: number;
152
+ durationMs: number;
153
+ }>;
154
+ createdAt: string;
155
+ }
156
+ export interface AuditEvent {
157
+ sequence: number;
158
+ at: string;
159
+ event: string;
160
+ actor?: string;
161
+ taskId?: string;
162
+ batchId?: string;
163
+ details?: Record<string, unknown>;
164
+ }
165
+ export interface BrokerState {
166
+ version: typeof STATE_VERSION;
167
+ sequence: number;
168
+ tasks: Record<string, TaskRecord>;
169
+ batches: Record<string, BatchRecord>;
170
+ }
171
+ export interface CommitReceipt {
172
+ version: 1;
173
+ taskId: string;
174
+ agent?: string;
175
+ baseSha: string;
176
+ commits: string[];
177
+ expectedPaths: string[];
178
+ actualPaths: string[];
179
+ dependsOn: string[];
180
+ worktree?: string;
181
+ submittedAt: string;
182
+ warnings: string[];
183
+ }
184
+ export interface ScheduleRejection {
185
+ taskId: string;
186
+ reason: string;
187
+ conflictsWith?: string;
188
+ }
189
+ export interface SchedulePlan {
190
+ selected: TaskRecord[];
191
+ rejected: ScheduleRejection[];
192
+ totalCommits: number;
193
+ }
194
+ export interface IntegrationOptions {
195
+ dryRun?: boolean;
196
+ publish?: boolean;
197
+ taskIds?: string[];
198
+ maxTasks?: number;
199
+ }
200
+ export interface IntegrationResult {
201
+ batch: BatchRecord;
202
+ selected: string[];
203
+ rejected: ScheduleRejection[];
204
+ dryRun: boolean;
205
+ }
206
+ export interface PruneOptions {
207
+ olderThanDays?: number;
208
+ dryRun?: boolean;
209
+ }
210
+ export interface PruneResult {
211
+ tasks: string[];
212
+ batches: string[];
213
+ /** Completed tasks kept because a retained task still declares them as a dependency. */
214
+ retainedForDependencies: string[];
215
+ cutoff: string;
216
+ archivePath?: string;
217
+ dryRun: boolean;
218
+ }
219
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ export const STATE_VERSION = 1;
2
+ export const CONFIG_VERSION = 1;
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAU,CAAC;AACxC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAU,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ValidationResult, ValidatorConfig } from "./types.js";
2
+ export declare function runValidators(options: {
3
+ validators: ValidatorConfig[];
4
+ scope: "focused" | "authoritative";
5
+ cwd: string;
6
+ taskId?: string;
7
+ files: string[];
8
+ baseSha: string;
9
+ headSha: string;
10
+ batchId: string;
11
+ shell?: string;
12
+ }): Promise<ValidationResult[]>;
13
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgCpE,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,KAAK,EAAE,SAAS,GAAG,eAAe,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkD9B"}