@open330/oac 2026.2.5

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 (56) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/LICENSE +21 -0
  3. package/README.md +597 -0
  4. package/dist/budget/index.d.ts +117 -0
  5. package/dist/budget/index.js +23 -0
  6. package/dist/budget/index.js.map +1 -0
  7. package/dist/chunk-4IUL7ECC.js +3152 -0
  8. package/dist/chunk-4IUL7ECC.js.map +1 -0
  9. package/dist/chunk-5GAUWC3L.js +469 -0
  10. package/dist/chunk-5GAUWC3L.js.map +1 -0
  11. package/dist/chunk-6A37SKAJ.js +58 -0
  12. package/dist/chunk-6A37SKAJ.js.map +1 -0
  13. package/dist/chunk-7C7SC4TZ.js +358 -0
  14. package/dist/chunk-7C7SC4TZ.js.map +1 -0
  15. package/dist/chunk-CJAJ4MBO.js +475 -0
  16. package/dist/chunk-CJAJ4MBO.js.map +1 -0
  17. package/dist/chunk-LQC5DLT7.js +317 -0
  18. package/dist/chunk-LQC5DLT7.js.map +1 -0
  19. package/dist/chunk-OTPXGXO7.js +2368 -0
  20. package/dist/chunk-OTPXGXO7.js.map +1 -0
  21. package/dist/chunk-QPVNC7S4.js +1833 -0
  22. package/dist/chunk-QPVNC7S4.js.map +1 -0
  23. package/dist/cli/cli.d.ts +13 -0
  24. package/dist/cli/cli.js +16 -0
  25. package/dist/cli/cli.js.map +1 -0
  26. package/dist/cli/index.d.ts +1 -0
  27. package/dist/cli/index.js +22 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/completion/index.d.ts +91 -0
  30. package/dist/completion/index.js +587 -0
  31. package/dist/completion/index.js.map +1 -0
  32. package/dist/config-DequKoFA.d.ts +1468 -0
  33. package/dist/core/index.d.ts +64 -0
  34. package/dist/core/index.js +87 -0
  35. package/dist/core/index.js.map +1 -0
  36. package/dist/dashboard/index.d.ts +14 -0
  37. package/dist/dashboard/index.js +1253 -0
  38. package/dist/dashboard/index.js.map +1 -0
  39. package/dist/discovery/index.d.ts +285 -0
  40. package/dist/discovery/index.js +50 -0
  41. package/dist/discovery/index.js.map +1 -0
  42. package/dist/event-bus-KiuR6e3P.d.ts +91 -0
  43. package/dist/execution/index.d.ts +215 -0
  44. package/dist/execution/index.js +27 -0
  45. package/dist/execution/index.js.map +1 -0
  46. package/dist/repo/index.d.ts +33 -0
  47. package/dist/repo/index.js +19 -0
  48. package/dist/repo/index.js.map +1 -0
  49. package/dist/tracking/index.d.ts +357 -0
  50. package/dist/tracking/index.js +15 -0
  51. package/dist/tracking/index.js.map +1 -0
  52. package/dist/types-CYCwgojB.d.ts +34 -0
  53. package/dist/types-Ck7IucqK.d.ts +195 -0
  54. package/docs/config-reference.md +271 -0
  55. package/docs/multi-agent-support-technical-spec.md +312 -0
  56. package/package.json +82 -0
@@ -0,0 +1,34 @@
1
+ interface RepoPermissions {
2
+ push: boolean;
3
+ pull: boolean;
4
+ admin: boolean;
5
+ }
6
+ interface ResolvedRepoMeta {
7
+ defaultBranch: string;
8
+ language: string | null;
9
+ languages: Record<string, number>;
10
+ size: number;
11
+ stars: number;
12
+ openIssuesCount: number;
13
+ topics: string[];
14
+ license: string | null;
15
+ isArchived: boolean;
16
+ isFork: boolean;
17
+ permissions: RepoPermissions;
18
+ }
19
+ interface ResolvedRepoGitState {
20
+ headSha: string;
21
+ remoteUrl: string;
22
+ isShallowClone: boolean;
23
+ }
24
+ interface ResolvedRepo {
25
+ fullName: string;
26
+ owner: string;
27
+ name: string;
28
+ localPath: string;
29
+ worktreePath: string;
30
+ meta: ResolvedRepoMeta;
31
+ git: ResolvedRepoGitState;
32
+ }
33
+
34
+ export type { ResolvedRepo as R, RepoPermissions as a, ResolvedRepoGitState as b, ResolvedRepoMeta as c };
@@ -0,0 +1,195 @@
1
+ type AgentProviderId = "claude-code" | "codex" | "opencode" | (string & {});
2
+ /**
3
+ * Sentinel value representing an unlimited token budget.
4
+ * Uses MAX_SAFE_INTEGER (passes Number.isFinite() checks in budget planner).
5
+ */
6
+ declare const UNLIMITED_BUDGET: number;
7
+ interface ResolvedRepo {
8
+ fullName: string;
9
+ owner: string;
10
+ name: string;
11
+ localPath: string;
12
+ worktreePath: string;
13
+ meta: {
14
+ defaultBranch: string;
15
+ language?: string;
16
+ languages: Record<string, number>;
17
+ size: number;
18
+ stars: number;
19
+ openIssuesCount: number;
20
+ topics: string[];
21
+ license?: string;
22
+ isArchived: boolean;
23
+ isFork: boolean;
24
+ permissions: {
25
+ admin: boolean;
26
+ maintain: boolean;
27
+ push: boolean;
28
+ triage: boolean;
29
+ pull: boolean;
30
+ };
31
+ };
32
+ git: {
33
+ headSha: string;
34
+ remoteUrl: string;
35
+ isShallowClone: boolean;
36
+ };
37
+ }
38
+ type TaskSource = "lint" | "todo" | "test-gap" | "dead-code" | "github-issue" | "custom";
39
+ type TaskComplexity = "trivial" | "simple" | "moderate" | "complex";
40
+ type ExecutionMode = "new-pr" | "update-pr" | "direct-commit";
41
+ interface Task {
42
+ id: string;
43
+ source: TaskSource;
44
+ title: string;
45
+ description: string;
46
+ targetFiles: string[];
47
+ priority: number;
48
+ complexity: TaskComplexity;
49
+ executionMode: ExecutionMode;
50
+ linkedIssue?: {
51
+ number: number;
52
+ url: string;
53
+ labels: string[];
54
+ };
55
+ metadata: Record<string, unknown>;
56
+ discoveredAt: string;
57
+ /** When this task belongs to an epic, the parent epic's id. */
58
+ parentEpicId?: string;
59
+ }
60
+ type EpicStatus = "pending" | "in-progress" | "completed" | "skipped";
61
+ /**
62
+ * An Epic groups related tasks that should be executed together in a single
63
+ * agent session, producing one PR with coherent multi-file changes.
64
+ */
65
+ interface Epic {
66
+ id: string;
67
+ title: string;
68
+ description: string;
69
+ /** Module scope, e.g. "budget", "discovery", or "root" */
70
+ scope: string;
71
+ subtasks: Task[];
72
+ /** Broader file set the agent should read for context */
73
+ contextFiles: string[];
74
+ status: EpicStatus;
75
+ priority: number;
76
+ estimatedTokens: number;
77
+ createdAt: string;
78
+ completedAt?: string;
79
+ metadata: Record<string, unknown>;
80
+ }
81
+ interface TokenEstimate {
82
+ taskId: string;
83
+ providerId: AgentProviderId;
84
+ contextTokens: number;
85
+ promptTokens: number;
86
+ expectedOutputTokens: number;
87
+ totalEstimatedTokens: number;
88
+ confidence: number;
89
+ feasible: boolean;
90
+ estimatedCostUsd?: number;
91
+ }
92
+ interface ExecutionPlan {
93
+ totalBudget: number;
94
+ selectedTasks: Array<{
95
+ task: Task;
96
+ estimate: TokenEstimate;
97
+ cumulativeBudgetUsed: number;
98
+ }>;
99
+ deferredTasks: Array<{
100
+ task: Task;
101
+ estimate: TokenEstimate;
102
+ reason: "budget_exceeded" | "low_confidence" | "too_complex";
103
+ }>;
104
+ reserveTokens: number;
105
+ remainingTokens: number;
106
+ }
107
+ interface ContributionTask {
108
+ taskId: string;
109
+ title: string;
110
+ source: TaskSource;
111
+ complexity: TaskComplexity;
112
+ status: "success" | "partial" | "failed";
113
+ tokensUsed: number;
114
+ duration: number;
115
+ filesChanged: string[];
116
+ pr?: {
117
+ number: number;
118
+ url: string;
119
+ status: "open" | "merged" | "closed";
120
+ };
121
+ linkedIssue?: {
122
+ number: number;
123
+ url: string;
124
+ };
125
+ error?: string;
126
+ }
127
+ interface ContributionLog {
128
+ version: "1.0";
129
+ runId: string;
130
+ timestamp: string;
131
+ contributor: {
132
+ githubUsername: string;
133
+ email?: string;
134
+ };
135
+ repo: {
136
+ fullName: string;
137
+ headSha: string;
138
+ defaultBranch: string;
139
+ };
140
+ budget: {
141
+ provider: AgentProviderId;
142
+ totalTokensBudgeted: number;
143
+ totalTokensUsed: number;
144
+ estimatedCostUsd?: number;
145
+ };
146
+ tasks: ContributionTask[];
147
+ metrics: {
148
+ tasksDiscovered: number;
149
+ tasksAttempted: number;
150
+ tasksSucceeded: number;
151
+ tasksFailed: number;
152
+ totalDuration: number;
153
+ totalFilesChanged: number;
154
+ totalLinesAdded: number;
155
+ totalLinesRemoved: number;
156
+ };
157
+ }
158
+ interface ExecutionResult {
159
+ success: boolean;
160
+ exitCode: number;
161
+ totalTokensUsed: number;
162
+ filesChanged: string[];
163
+ duration: number;
164
+ error?: string;
165
+ }
166
+ interface RunSummary {
167
+ runId: string;
168
+ repo: string;
169
+ provider: AgentProviderId;
170
+ startedAt: string;
171
+ completedAt: string;
172
+ duration: number;
173
+ budget: {
174
+ totalTokens: number;
175
+ reserveTokens: number;
176
+ usedTokens: number;
177
+ remainingTokens: number;
178
+ estimatedCostUsd?: number;
179
+ };
180
+ tasks: {
181
+ discovered: number;
182
+ selected: number;
183
+ attempted: number;
184
+ succeeded: number;
185
+ failed: number;
186
+ deferred: number;
187
+ };
188
+ pullRequests: {
189
+ created: number;
190
+ merged: number;
191
+ urls: string[];
192
+ };
193
+ }
194
+
195
+ export { type AgentProviderId as A, type ContributionLog as C, type Epic as E, type ResolvedRepo as R, type Task as T, UNLIMITED_BUDGET as U, type ContributionTask as a, type EpicStatus as b, type ExecutionMode as c, type ExecutionPlan as d, type ExecutionResult as e, type RunSummary as f, type TaskComplexity as g, type TaskSource as h, type TokenEstimate as i };
@@ -0,0 +1,271 @@
1
+ # OAC Configuration Reference
2
+
3
+ > Auto-generated from the Zod schema in `src/core/config.ts`.
4
+ > Version: **2026.2.5**
5
+
6
+ OAC is configured via an `oac.config.ts` (or `.js` / `.json`) file at the project root. Use `defineConfig()` for type-safe authoring:
7
+
8
+ ```ts
9
+ import { defineConfig } from "@open330/oac";
10
+
11
+ export default defineConfig({
12
+ repos: ["facebook/react"],
13
+ budget: { totalTokens: 50_000 },
14
+ execution: { concurrency: 3, mode: "new-pr" },
15
+ });
16
+ ```
17
+
18
+ Environment variables can be interpolated with `${VAR_NAME}` syntax anywhere a string value is accepted.
19
+
20
+ ---
21
+
22
+ ## `repos`
23
+
24
+ Target repositories to contribute to.
25
+
26
+ | Property | Type | Default | Description |
27
+ |----------|------|---------|-------------|
28
+ | `repos` | `Array<string \| { name, branch? }>` | `[]` | List of repos. Each entry is either a GitHub slug (`"owner/repo"`) or an object with `name` (required) and `branch` (optional). |
29
+
30
+ ```ts
31
+ repos: [
32
+ "facebook/react",
33
+ { name: "vercel/next.js", branch: "canary" },
34
+ ]
35
+ ```
36
+
37
+ ---
38
+
39
+ ## `provider`
40
+
41
+ AI agent provider configuration.
42
+
43
+ | Property | Type | Default | Description |
44
+ |----------|------|---------|-------------|
45
+ | `provider.id` | `string` | `"claude-code"` | Provider identifier. |
46
+ | `provider.options` | `Record<string, unknown>` | `{}` | Provider-specific options passed through to the agent. |
47
+
48
+ ---
49
+
50
+ ## `budget`
51
+
52
+ Token budget controls.
53
+
54
+ | Property | Type | Default | Description |
55
+ |----------|------|---------|-------------|
56
+ | `budget.totalTokens` | `integer` | `100000` | Maximum tokens to spend across all tasks. Must be positive. |
57
+ | `budget.reservePercent` | `number` | `0.1` | Fraction of budget to reserve for retries/overhead (0–1). |
58
+ | `budget.estimationPadding` | `number` | `1.2` | Multiplier applied to token estimates for safety margin. Must be positive. |
59
+
60
+ ---
61
+
62
+ ## `discovery`
63
+
64
+ Task discovery and scanning settings.
65
+
66
+ ### `discovery.scanners`
67
+
68
+ Toggle individual scanners on or off.
69
+
70
+ | Property | Type | Default | Description |
71
+ |----------|------|---------|-------------|
72
+ | `discovery.scanners.lint` | `boolean` | `true` | Scan for lint warnings and errors. |
73
+ | `discovery.scanners.todo` | `boolean` | `true` | Scan for TODO/FIXME/HACK comments. |
74
+ | `discovery.scanners.testGap` | `boolean` | `true` | Scan for files missing test coverage. |
75
+ | `discovery.scanners.deadCode` | `boolean` | `false` | Scan for dead/unused code. |
76
+ | `discovery.scanners.githubIssues` | `boolean` | `true` | Fetch open GitHub issues matching labels. |
77
+
78
+ ### Other discovery options
79
+
80
+ | Property | Type | Default | Description |
81
+ |----------|------|---------|-------------|
82
+ | `discovery.issueLabels` | `string[]` | `["good-first-issue", "help-wanted", "bug"]` | GitHub issue labels to match. |
83
+ | `discovery.minPriority` | `integer` | `20` | Minimum priority score (0–100) for a task to be included. |
84
+ | `discovery.maxTasks` | `integer` | `50` | Maximum number of tasks to discover. Must be positive. |
85
+ | `discovery.customScanners` | `string[]` | `[]` | Paths to custom scanner modules. |
86
+ | `discovery.exclude` | `string[]` | `["node_modules", "dist", "build", ".git", "*.min.js", "vendor/"]` | Glob patterns to exclude from scanning. |
87
+
88
+ ---
89
+
90
+ ## `execution`
91
+
92
+ Task execution settings.
93
+
94
+ | Property | Type | Default | Description |
95
+ |----------|------|---------|-------------|
96
+ | `execution.concurrency` | `integer` | `2` | Max parallel task executions. Must be positive. |
97
+ | `execution.taskTimeout` | `integer` | `300` | Timeout per task in seconds. Must be positive. |
98
+ | `execution.maxRetries` | `integer` | `2` | Max retry attempts for failed tasks (0 = no retries). |
99
+ | `execution.mode` | `"new-pr" \| "update-pr" \| "direct-commit"` | `"new-pr"` | How to submit completed work. |
100
+ | `execution.branchPattern` | `string` | `"oac/{date}/{task}"` | Branch naming pattern. `{date}` and `{task}` are interpolated. |
101
+
102
+ ### `execution.validation`
103
+
104
+ Post-execution validation checks.
105
+
106
+ | Property | Type | Default | Description |
107
+ |----------|------|---------|-------------|
108
+ | `execution.validation.lint` | `boolean` | `true` | Run linter after task completion. |
109
+ | `execution.validation.test` | `boolean` | `true` | Run tests after task completion. |
110
+ | `execution.validation.typeCheck` | `boolean` | `true` | Run type checker after task completion. |
111
+ | `execution.validation.maxDiffLines` | `integer` | `500` | Reject diffs exceeding this line count. Must be positive. |
112
+
113
+ ### `execution.pr`
114
+
115
+ Pull request settings.
116
+
117
+ | Property | Type | Default | Description |
118
+ |----------|------|---------|-------------|
119
+ | `execution.pr.draft` | `boolean` | `false` | Create PRs as drafts. |
120
+ | `execution.pr.labels` | `string[]` | `["oac-contribution"]` | Labels to apply to created PRs. |
121
+ | `execution.pr.reviewers` | `string[]` | `[]` | GitHub usernames to request as reviewers. |
122
+ | `execution.pr.assignees` | `string[]` | `[]` | GitHub usernames to assign to the PR. |
123
+
124
+ ---
125
+
126
+ ## `completion`
127
+
128
+ Post-PR completion and monitoring.
129
+
130
+ ### `completion.integrations.linear`
131
+
132
+ Linear issue tracker integration.
133
+
134
+ | Property | Type | Default | Description |
135
+ |----------|------|---------|-------------|
136
+ | `completion.integrations.linear.enabled` | `boolean` | `false` | Enable Linear integration. |
137
+ | `completion.integrations.linear.apiKey` | `string` | — | Linear API key. **Required** when `enabled: true`. Supports `${ENV_VAR}` syntax. |
138
+ | `completion.integrations.linear.teamId` | `string` | — | Linear team ID. **Required** when `enabled: true`. |
139
+
140
+ ### `completion.integrations.jira`
141
+
142
+ Jira issue tracker integration.
143
+
144
+ | Property | Type | Default | Description |
145
+ |----------|------|---------|-------------|
146
+ | `completion.integrations.jira.enabled` | `boolean` | `false` | Enable Jira integration. |
147
+ | `completion.integrations.jira.baseUrl` | `string (URL)` | — | Jira instance URL. **Required** when `enabled: true`. |
148
+ | `completion.integrations.jira.email` | `string` | — | Jira account email. **Required** when `enabled: true`. |
149
+ | `completion.integrations.jira.apiToken` | `string` | — | Jira API token. **Required** when `enabled: true`. Supports `${ENV_VAR}` syntax. |
150
+ | `completion.integrations.jira.projectKey` | `string` | — | Jira project key. **Required** when `enabled: true`. |
151
+
152
+ ### `completion.monitor`
153
+
154
+ PR monitoring settings.
155
+
156
+ | Property | Type | Default | Description |
157
+ |----------|------|---------|-------------|
158
+ | `completion.monitor.enabled` | `boolean` | `false` | Enable post-PR monitoring. |
159
+ | `completion.monitor.pollInterval` | `integer` | `300` | Seconds between status checks. Must be positive. |
160
+ | `completion.monitor.autoRespondToReviews` | `boolean` | `false` | Automatically respond to review comments. |
161
+ | `completion.monitor.autoDeleteBranch` | `boolean` | `true` | Delete branch after PR is merged. |
162
+
163
+ ---
164
+
165
+ ## `tracking`
166
+
167
+ Local state tracking.
168
+
169
+ | Property | Type | Default | Description |
170
+ |----------|------|---------|-------------|
171
+ | `tracking.directory` | `string` | `".oac"` | Directory for local OAC state files. |
172
+ | `tracking.autoCommit` | `boolean` | `false` | Auto-commit tracking changes to git. |
173
+ | `tracking.gitTracked` | `boolean` | `true` | Include tracking directory in git. |
174
+
175
+ ---
176
+
177
+ ## `dashboard`
178
+
179
+ Local dashboard server.
180
+
181
+ | Property | Type | Default | Description |
182
+ |----------|------|---------|-------------|
183
+ | `dashboard.port` | `integer` | `3141` | Port for the dashboard server (1–65535). |
184
+ | `dashboard.openBrowser` | `boolean` | `true` | Automatically open the dashboard in a browser. |
185
+
186
+ ---
187
+
188
+ ## `analyze`
189
+
190
+ Context analysis settings for `oac analyze` / auto-analysis before `oac run`.
191
+
192
+ | Property | Type | Default | Description |
193
+ |----------|------|---------|-------------|
194
+ | `analyze.autoAnalyze` | `boolean` | `true` | Auto-run analysis before `oac run` if context is stale or missing. |
195
+ | `analyze.staleAfterMs` | `integer` | `86400000` | Max age in milliseconds before context is considered stale (default: 24 hours). |
196
+ | `analyze.contextDir` | `string` | `".oac/context"` | Directory for persisted analysis context, relative to repo root. |
197
+
198
+ ---
199
+
200
+ ## Environment Variable Interpolation
201
+
202
+ Any string value in the config supports `${VAR_NAME}` interpolation:
203
+
204
+ ```ts
205
+ export default defineConfig({
206
+ completion: {
207
+ integrations: {
208
+ linear: {
209
+ enabled: true,
210
+ apiKey: "${LINEAR_API_KEY}",
211
+ teamId: "${LINEAR_TEAM_ID}",
212
+ },
213
+ },
214
+ },
215
+ });
216
+ ```
217
+
218
+ If a referenced variable is not set, OAC throws a `CONFIG_SECRET_MISSING` error with the variable name and config path.
219
+
220
+ ---
221
+
222
+ ## Minimal Example
223
+
224
+ ```ts
225
+ import { defineConfig } from "@open330/oac";
226
+
227
+ export default defineConfig({
228
+ repos: ["my-org/my-repo"],
229
+ });
230
+ ```
231
+
232
+ All other options use sensible defaults. See individual sections above for default values.
233
+
234
+ ## Full Example
235
+
236
+ ```ts
237
+ import { defineConfig } from "@open330/oac";
238
+
239
+ export default defineConfig({
240
+ repos: [
241
+ "facebook/react",
242
+ { name: "vercel/next.js", branch: "canary" },
243
+ ],
244
+ provider: { id: "claude-code" },
245
+ budget: {
246
+ totalTokens: 200_000,
247
+ reservePercent: 0.15,
248
+ estimationPadding: 1.3,
249
+ },
250
+ discovery: {
251
+ scanners: { lint: true, todo: true, testGap: true, deadCode: true, githubIssues: true },
252
+ issueLabels: ["good-first-issue", "help-wanted"],
253
+ minPriority: 30,
254
+ maxTasks: 25,
255
+ exclude: ["node_modules", "dist", "vendor/", "**/*.generated.ts"],
256
+ },
257
+ execution: {
258
+ concurrency: 4,
259
+ taskTimeout: 600,
260
+ maxRetries: 1,
261
+ mode: "new-pr",
262
+ branchPattern: "oac/{date}/{task}",
263
+ validation: { lint: true, test: true, typeCheck: true, maxDiffLines: 800 },
264
+ pr: { draft: true, labels: ["oac-contribution", "automated"], reviewers: ["maintainer"] },
265
+ },
266
+ tracking: { directory: ".oac", autoCommit: true },
267
+ dashboard: { port: 3141 },
268
+ analyze: { autoAnalyze: true, staleAfterMs: 43_200_000 },
269
+ });
270
+ ```
271
+