@open330/oac 2026.3.6 → 2026.4.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.
Files changed (52) hide show
  1. package/dist/budget/index.d.ts +78 -0
  2. package/dist/budget/index.js +17 -0
  3. package/dist/chunk-LQC5DLT7.js +317 -0
  4. package/dist/chunk-LQC5DLT7.js.map +1 -0
  5. package/dist/chunk-NZEI4RPP.js +1499 -0
  6. package/dist/chunk-NZEI4RPP.js.map +1 -0
  7. package/dist/{chunk-Z7KEQPGV.js → chunk-SZUDHVBF.js} +65 -89
  8. package/dist/chunk-SZUDHVBF.js.map +1 -0
  9. package/dist/chunk-TGZ2TGDA.js +348 -0
  10. package/dist/chunk-TGZ2TGDA.js.map +1 -0
  11. package/dist/chunk-UL66HWYF.js +392 -0
  12. package/dist/chunk-UL66HWYF.js.map +1 -0
  13. package/dist/chunk-VLR2VYFW.js +475 -0
  14. package/dist/chunk-VLR2VYFW.js.map +1 -0
  15. package/dist/chunk-ZPI2VQ7U.js +1732 -0
  16. package/dist/chunk-ZPI2VQ7U.js.map +1 -0
  17. package/dist/cli/cli.js +15 -0
  18. package/dist/cli/cli.js.map +1 -0
  19. package/dist/cli/index.js +18 -0
  20. package/dist/cli/index.js.map +1 -0
  21. package/dist/completion/index.d.ts +91 -0
  22. package/dist/completion/index.js +590 -0
  23. package/dist/completion/index.js.map +1 -0
  24. package/dist/core/index.d.ts +1403 -0
  25. package/dist/core/index.js +75 -0
  26. package/dist/core/index.js.map +1 -0
  27. package/dist/dashboard/index.d.ts +14 -0
  28. package/dist/dashboard/index.js +1257 -0
  29. package/dist/dashboard/index.js.map +1 -0
  30. package/dist/discovery/index.d.ts +115 -0
  31. package/dist/discovery/index.js +19 -0
  32. package/dist/discovery/index.js.map +1 -0
  33. package/dist/event-bus-CRLkpNo0.d.ts +91 -0
  34. package/dist/execution/index.d.ts +162 -0
  35. package/dist/execution/index.js +18 -0
  36. package/dist/execution/index.js.map +1 -0
  37. package/dist/repo/index.d.ts +33 -0
  38. package/dist/repo/index.js +19 -0
  39. package/dist/repo/index.js.map +1 -0
  40. package/dist/tracking/index.d.ts +357 -0
  41. package/dist/tracking/index.js +15 -0
  42. package/dist/tracking/index.js.map +1 -0
  43. package/dist/types-CYCwgojB.d.ts +34 -0
  44. package/dist/types-cJZwCZZX.d.ts +172 -0
  45. package/package.json +42 -20
  46. package/dist/chunk-Z7KEQPGV.js.map +0 -1
  47. package/dist/cli.js +0 -9
  48. package/dist/index.js +0 -12
  49. package/dist/index.js.map +0 -1
  50. /package/dist/{cli.js.map → budget/index.js.map} +0 -0
  51. /package/dist/{cli.d.ts → cli/cli.d.ts} +0 -0
  52. /package/dist/{index.d.ts → cli/index.d.ts} +0 -0
@@ -0,0 +1,78 @@
1
+ type AgentProviderId = "claude-code" | "codex" | "opencode" | string;
2
+ type TaskSource = "lint" | "todo" | "test-gap" | "dead-code" | "github-issue" | "custom";
3
+ type TaskComplexity = "trivial" | "simple" | "moderate" | "complex";
4
+ type ExecutionMode = "new-pr" | "update-pr" | "direct-commit";
5
+ interface Task {
6
+ id: string;
7
+ source: TaskSource;
8
+ title: string;
9
+ description: string;
10
+ targetFiles: string[];
11
+ priority: number;
12
+ complexity: TaskComplexity;
13
+ executionMode: ExecutionMode;
14
+ linkedIssue?: {
15
+ number: number;
16
+ url: string;
17
+ labels: string[];
18
+ };
19
+ metadata: Record<string, unknown>;
20
+ discoveredAt: string;
21
+ }
22
+ interface TokenEstimate {
23
+ taskId: string;
24
+ providerId: AgentProviderId;
25
+ contextTokens: number;
26
+ promptTokens: number;
27
+ expectedOutputTokens: number;
28
+ totalEstimatedTokens: number;
29
+ confidence: number;
30
+ feasible: boolean;
31
+ estimatedCostUsd?: number;
32
+ }
33
+ interface TokenCounter {
34
+ countTokens(text: string): number;
35
+ readonly invocationOverhead: number;
36
+ readonly maxContextTokens: number;
37
+ }
38
+ declare function estimateTokens(task: Task, provider: AgentProviderId): Promise<TokenEstimate>;
39
+
40
+ declare function estimateLocChanges(task: Task): number;
41
+ declare function analyzeTaskComplexity(task: Task): TaskComplexity;
42
+
43
+ type DeferredReason = "budget_exceeded" | "low_confidence" | "too_complex";
44
+ interface ExecutionPlan {
45
+ totalBudget: number;
46
+ selectedTasks: Array<{
47
+ task: Task;
48
+ estimate: TokenEstimate;
49
+ cumulativeBudgetUsed: number;
50
+ }>;
51
+ deferredTasks: Array<{
52
+ task: Task;
53
+ estimate: TokenEstimate;
54
+ reason: DeferredReason;
55
+ }>;
56
+ reserveTokens: number;
57
+ remainingTokens: number;
58
+ }
59
+ declare function buildExecutionPlan(tasks: Task[], estimates: Map<string, TokenEstimate>, budget: number): ExecutionPlan;
60
+
61
+ declare class ClaudeTokenCounter {
62
+ readonly invocationOverhead = 1500;
63
+ readonly maxContextTokens = 200000;
64
+ readonly encoding = "cl100k_base";
65
+ countTokens(text: string): number;
66
+ }
67
+
68
+ declare const PRIMARY_ENCODING = "o200k_base";
69
+ declare const FALLBACK_ENCODING = "cl100k_base";
70
+ type SupportedCodexEncoding = typeof PRIMARY_ENCODING | typeof FALLBACK_ENCODING;
71
+ declare class CodexTokenCounter {
72
+ readonly invocationOverhead = 1000;
73
+ readonly maxContextTokens = 200000;
74
+ get encoding(): SupportedCodexEncoding;
75
+ countTokens(text: string): number;
76
+ }
77
+
78
+ export { type AgentProviderId, ClaudeTokenCounter, CodexTokenCounter, type ExecutionMode, type ExecutionPlan, type Task, type TaskComplexity, type TaskSource, type TokenCounter, type TokenEstimate, analyzeTaskComplexity, buildExecutionPlan, estimateLocChanges, estimateTokens };
@@ -0,0 +1,17 @@
1
+ import {
2
+ ClaudeTokenCounter,
3
+ CodexTokenCounter,
4
+ analyzeTaskComplexity,
5
+ buildExecutionPlan,
6
+ estimateLocChanges,
7
+ estimateTokens
8
+ } from "../chunk-UL66HWYF.js";
9
+ export {
10
+ ClaudeTokenCounter,
11
+ CodexTokenCounter,
12
+ analyzeTaskComplexity,
13
+ buildExecutionPlan,
14
+ estimateLocChanges,
15
+ estimateTokens
16
+ };
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,317 @@
1
+ // src/tracking/log-schema.ts
2
+ import { z } from "zod";
3
+ var taskSourceValues = [
4
+ "lint",
5
+ "todo",
6
+ "test-gap",
7
+ "dead-code",
8
+ "github-issue",
9
+ "github-pr-review",
10
+ "custom"
11
+ ];
12
+ var taskComplexityValues = ["trivial", "simple", "moderate", "complex"];
13
+ var contributionTaskStatusValues = ["success", "partial", "failed"];
14
+ var githubUsernameSchema = z.string().min(1).max(39).regex(/^(?!-)[A-Za-z0-9-]+(?<!-)$/, "Invalid GitHub username.");
15
+ var contributionTaskSchema = z.object({
16
+ taskId: z.string().min(1),
17
+ title: z.string().min(1),
18
+ source: z.enum(taskSourceValues),
19
+ complexity: z.enum(taskComplexityValues),
20
+ status: z.enum(contributionTaskStatusValues),
21
+ tokensUsed: z.number().int().nonnegative(),
22
+ duration: z.number().nonnegative(),
23
+ filesChanged: z.array(z.string().min(1)),
24
+ pr: z.object({
25
+ number: z.number().int().positive(),
26
+ url: z.string().url(),
27
+ status: z.enum(["open", "merged", "closed"])
28
+ }).optional(),
29
+ linkedIssue: z.object({
30
+ number: z.number().int().positive(),
31
+ url: z.string().url()
32
+ }).optional(),
33
+ error: z.string().min(1).optional()
34
+ });
35
+ var contributionLogSchema = z.object({
36
+ version: z.literal("1.0"),
37
+ runId: z.string().min(1),
38
+ timestamp: z.string().datetime({ offset: true }),
39
+ contributor: z.object({
40
+ githubUsername: githubUsernameSchema,
41
+ email: z.string().email().optional()
42
+ }),
43
+ repo: z.object({
44
+ fullName: z.string().min(1).regex(/^[^\s/]+\/[^\s/]+$/, "Expected repository in owner/repo format."),
45
+ headSha: z.string().regex(/^[A-Fa-f0-9]{7,40}$/, "Expected git SHA (7-40 hex chars)."),
46
+ defaultBranch: z.string().min(1)
47
+ }),
48
+ budget: z.object({
49
+ provider: z.string().min(1),
50
+ totalTokensBudgeted: z.number().int().nonnegative(),
51
+ totalTokensUsed: z.number().int().nonnegative(),
52
+ estimatedCostUsd: z.number().nonnegative().optional()
53
+ }),
54
+ tasks: z.array(contributionTaskSchema),
55
+ metrics: z.object({
56
+ tasksDiscovered: z.number().int().nonnegative(),
57
+ tasksAttempted: z.number().int().nonnegative(),
58
+ tasksSucceeded: z.number().int().nonnegative(),
59
+ tasksFailed: z.number().int().nonnegative(),
60
+ totalDuration: z.number().nonnegative(),
61
+ totalFilesChanged: z.number().int().nonnegative(),
62
+ totalLinesAdded: z.number().int().nonnegative(),
63
+ totalLinesRemoved: z.number().int().nonnegative()
64
+ })
65
+ });
66
+ function parseContributionLog(input) {
67
+ return contributionLogSchema.parse(input);
68
+ }
69
+
70
+ // src/tracking/logger.ts
71
+ import { randomUUID as randomUUID2 } from "crypto";
72
+ import { mkdir as mkdir2, rename as rename2, rm as rm2, writeFile as writeFile2 } from "fs/promises";
73
+ import { join as join2, resolve as resolve2 } from "path";
74
+
75
+ // src/tracking/leaderboard.ts
76
+ import { randomUUID } from "crypto";
77
+ import { mkdir, readFile, readdir, rename, rm, writeFile } from "fs/promises";
78
+ import { join, resolve } from "path";
79
+ var OAC_DIRECTORY = ".oac";
80
+ var CONTRIBUTIONS_DIRECTORY = "contributions";
81
+ var LEADERBOARD_FILENAME = "leaderboard.json";
82
+ var EMPTY_TIMESTAMP = "";
83
+ async function buildLeaderboard(repoPath) {
84
+ const repoRoot = resolve(repoPath);
85
+ const oacPath = join(repoRoot, OAC_DIRECTORY);
86
+ const contributionsPath = join(oacPath, CONTRIBUTIONS_DIRECTORY);
87
+ const logs = await readContributionLogs(contributionsPath);
88
+ const aggregates = /* @__PURE__ */ new Map();
89
+ const repoStats = {
90
+ totalContributions: logs.length,
91
+ totalTokensUsed: 0,
92
+ totalPRsCreated: 0,
93
+ totalPRsMerged: 0,
94
+ firstContribution: EMPTY_TIMESTAMP,
95
+ lastContribution: EMPTY_TIMESTAMP
96
+ };
97
+ for (const log of logs) {
98
+ const username = log.contributor.githubUsername;
99
+ const accumulator = aggregates.get(username) ?? createAccumulator(username, log.timestamp);
100
+ accumulator.totalRuns += 1;
101
+ accumulator.totalTasksCompleted += log.tasks.filter((task) => task.status !== "failed").length;
102
+ accumulator.totalTokensDonated += log.budget.totalTokensUsed;
103
+ accumulator.totalFilesChanged += log.metrics.totalFilesChanged;
104
+ accumulator.totalLinesChanged += log.metrics.totalLinesAdded + log.metrics.totalLinesRemoved;
105
+ accumulator.firstContribution = minIsoTimestamp(accumulator.firstContribution, log.timestamp);
106
+ accumulator.lastContribution = maxIsoTimestamp(accumulator.lastContribution, log.timestamp);
107
+ for (const task of log.tasks) {
108
+ if (task.pr) {
109
+ accumulator.totalPRsCreated += 1;
110
+ if (task.pr.status === "merged") {
111
+ accumulator.totalPRsMerged += 1;
112
+ }
113
+ }
114
+ accumulator.sourceCounts.set(
115
+ task.source,
116
+ (accumulator.sourceCounts.get(task.source) ?? 0) + 1
117
+ );
118
+ }
119
+ aggregates.set(username, accumulator);
120
+ repoStats.totalTokensUsed += log.budget.totalTokensUsed;
121
+ repoStats.firstContribution = minIsoTimestamp(repoStats.firstContribution, log.timestamp);
122
+ repoStats.lastContribution = maxIsoTimestamp(repoStats.lastContribution, log.timestamp);
123
+ repoStats.totalPRsCreated += log.tasks.filter((task) => Boolean(task.pr)).length;
124
+ repoStats.totalPRsMerged += log.tasks.filter((task) => task.pr?.status === "merged").length;
125
+ }
126
+ const entries = Array.from(aggregates.values()).map((entry) => ({
127
+ githubUsername: entry.githubUsername,
128
+ totalRuns: entry.totalRuns,
129
+ totalTasksCompleted: entry.totalTasksCompleted,
130
+ totalTokensDonated: entry.totalTokensDonated,
131
+ totalFilesChanged: entry.totalFilesChanged,
132
+ totalLinesChanged: entry.totalLinesChanged,
133
+ totalPRsCreated: entry.totalPRsCreated,
134
+ totalPRsMerged: entry.totalPRsMerged,
135
+ favoriteTaskSource: getFavoriteTaskSource(entry.sourceCounts),
136
+ firstContribution: entry.firstContribution,
137
+ lastContribution: entry.lastContribution
138
+ })).sort((a, b) => {
139
+ if (b.totalTasksCompleted !== a.totalTasksCompleted) {
140
+ return b.totalTasksCompleted - a.totalTasksCompleted;
141
+ }
142
+ if (b.totalRuns !== a.totalRuns) {
143
+ return b.totalRuns - a.totalRuns;
144
+ }
145
+ if (b.totalTokensDonated !== a.totalTokensDonated) {
146
+ return b.totalTokensDonated - a.totalTokensDonated;
147
+ }
148
+ return a.githubUsername.localeCompare(b.githubUsername);
149
+ });
150
+ const leaderboard = {
151
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
152
+ entries,
153
+ repoStats
154
+ };
155
+ await mkdir(oacPath, { recursive: true });
156
+ const leaderboardPath = join(oacPath, LEADERBOARD_FILENAME);
157
+ const payload = `${JSON.stringify(leaderboard, null, 2)}
158
+ `;
159
+ await writeFileAtomically(leaderboardPath, payload);
160
+ return leaderboard;
161
+ }
162
+ function createAccumulator(githubUsername, initialTimestamp) {
163
+ return {
164
+ githubUsername,
165
+ totalRuns: 0,
166
+ totalTasksCompleted: 0,
167
+ totalTokensDonated: 0,
168
+ totalFilesChanged: 0,
169
+ totalLinesChanged: 0,
170
+ totalPRsCreated: 0,
171
+ totalPRsMerged: 0,
172
+ firstContribution: initialTimestamp,
173
+ lastContribution: initialTimestamp,
174
+ sourceCounts: /* @__PURE__ */ new Map()
175
+ };
176
+ }
177
+ async function readContributionLogs(contributionsPath) {
178
+ let fileNames;
179
+ try {
180
+ const entries = await readdir(contributionsPath, { withFileTypes: true, encoding: "utf8" });
181
+ fileNames = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
182
+ } catch (error) {
183
+ if (isFileNotFoundError(error)) {
184
+ return [];
185
+ }
186
+ throw error;
187
+ }
188
+ const logs = await Promise.all(
189
+ fileNames.map(async (fileName) => {
190
+ const filePath = join(contributionsPath, fileName);
191
+ try {
192
+ const fileContent = await readFile(filePath, "utf8");
193
+ const parsedJson = JSON.parse(fileContent);
194
+ const parsedLog = contributionLogSchema.safeParse(parsedJson);
195
+ if (!parsedLog.success) {
196
+ console.warn(
197
+ `[tracking] Skipping invalid contribution log "${fileName}": ${parsedLog.error.issues[0]?.message ?? "Schema validation failed."}`
198
+ );
199
+ return null;
200
+ }
201
+ return parsedLog.data;
202
+ } catch (error) {
203
+ const message = error instanceof Error ? error.message : "Unknown read error";
204
+ console.warn(`[tracking] Skipping unreadable contribution log "${fileName}": ${message}`);
205
+ return null;
206
+ }
207
+ })
208
+ );
209
+ return logs.filter((log) => log !== null);
210
+ }
211
+ function getFavoriteTaskSource(sourceCounts) {
212
+ if (sourceCounts.size === 0) {
213
+ return "custom";
214
+ }
215
+ let favorite = "custom";
216
+ let favoriteCount = -1;
217
+ for (const [source, count] of sourceCounts.entries()) {
218
+ if (count > favoriteCount) {
219
+ favorite = source;
220
+ favoriteCount = count;
221
+ continue;
222
+ }
223
+ if (count === favoriteCount && source.localeCompare(favorite) < 0) {
224
+ favorite = source;
225
+ }
226
+ }
227
+ return favorite;
228
+ }
229
+ function minIsoTimestamp(a, b) {
230
+ if (!a) {
231
+ return b;
232
+ }
233
+ if (!b) {
234
+ return a;
235
+ }
236
+ return Date.parse(a) <= Date.parse(b) ? a : b;
237
+ }
238
+ function maxIsoTimestamp(a, b) {
239
+ if (!a) {
240
+ return b;
241
+ }
242
+ if (!b) {
243
+ return a;
244
+ }
245
+ return Date.parse(a) >= Date.parse(b) ? a : b;
246
+ }
247
+ function isFileNotFoundError(error) {
248
+ if (typeof error !== "object" || error === null) {
249
+ return false;
250
+ }
251
+ const code = error.code;
252
+ return code === "ENOENT";
253
+ }
254
+ async function writeFileAtomically(destinationPath, content) {
255
+ const tempPath = `${destinationPath}.${process.pid}.${randomUUID()}.tmp`;
256
+ try {
257
+ await writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
258
+ await rename(tempPath, destinationPath);
259
+ } finally {
260
+ await rm(tempPath, { force: true });
261
+ }
262
+ }
263
+
264
+ // src/tracking/logger.ts
265
+ var OAC_DIRECTORY2 = ".oac";
266
+ var CONTRIBUTIONS_DIRECTORY2 = "contributions";
267
+ async function writeContributionLog(log, repoPath) {
268
+ const parsedLog = contributionLogSchema.parse(log);
269
+ const contributionsPath = resolve2(repoPath, OAC_DIRECTORY2, CONTRIBUTIONS_DIRECTORY2);
270
+ await mkdir2(contributionsPath, { recursive: true });
271
+ const timestamp = formatFileTimestamp(parsedLog.timestamp);
272
+ const username = toSafeFilenameSegment(parsedLog.contributor.githubUsername);
273
+ const filename = `${timestamp}-${username}.json`;
274
+ const filePath = join2(contributionsPath, filename);
275
+ const payload = `${JSON.stringify(parsedLog, null, 2)}
276
+ `;
277
+ await writeFileAtomically2(filePath, payload);
278
+ try {
279
+ await buildLeaderboard(repoPath);
280
+ } catch (error) {
281
+ const message = error instanceof Error ? error.message : "Unknown leaderboard error";
282
+ console.warn(`[tracking] Contribution log written, but leaderboard refresh failed: ${message}`);
283
+ }
284
+ return filePath;
285
+ }
286
+ function formatFileTimestamp(timestamp) {
287
+ const date = new Date(timestamp);
288
+ const yyyy = String(date.getUTCFullYear());
289
+ const mm = String(date.getUTCMonth() + 1).padStart(2, "0");
290
+ const dd = String(date.getUTCDate()).padStart(2, "0");
291
+ const hh = String(date.getUTCHours()).padStart(2, "0");
292
+ const min = String(date.getUTCMinutes()).padStart(2, "0");
293
+ const sec = String(date.getUTCSeconds()).padStart(2, "0");
294
+ return `${yyyy}-${mm}-${dd}-${hh}${min}${sec}`;
295
+ }
296
+ function toSafeFilenameSegment(value) {
297
+ const sanitized = value.trim().replace(/[^A-Za-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
298
+ return sanitized || "unknown";
299
+ }
300
+ async function writeFileAtomically2(destinationPath, content) {
301
+ const tempPath = `${destinationPath}.${process.pid}.${randomUUID2()}.tmp`;
302
+ try {
303
+ await writeFile2(tempPath, content, { encoding: "utf8", flag: "wx" });
304
+ await rename2(tempPath, destinationPath);
305
+ } finally {
306
+ await rm2(tempPath, { force: true });
307
+ }
308
+ }
309
+
310
+ export {
311
+ contributionTaskSchema,
312
+ contributionLogSchema,
313
+ parseContributionLog,
314
+ buildLeaderboard,
315
+ writeContributionLog
316
+ };
317
+ //# sourceMappingURL=chunk-LQC5DLT7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tracking/log-schema.ts","../src/tracking/logger.ts","../src/tracking/leaderboard.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const taskSourceValues = [\n \"lint\",\n \"todo\",\n \"test-gap\",\n \"dead-code\",\n \"github-issue\",\n \"github-pr-review\",\n \"custom\",\n] as const;\n\nexport const taskComplexityValues = [\"trivial\", \"simple\", \"moderate\", \"complex\"] as const;\n\nexport const contributionTaskStatusValues = [\"success\", \"partial\", \"failed\"] as const;\n\nexport type TaskSource = (typeof taskSourceValues)[number];\nexport type TaskComplexity = (typeof taskComplexityValues)[number];\nexport type ContributionTaskStatus = (typeof contributionTaskStatusValues)[number];\nexport type AgentProviderId = string;\n\nconst githubUsernameSchema = z\n .string()\n .min(1)\n .max(39)\n .regex(/^(?!-)[A-Za-z0-9-]+(?<!-)$/, \"Invalid GitHub username.\");\n\nexport const contributionTaskSchema = z.object({\n taskId: z.string().min(1),\n title: z.string().min(1),\n source: z.enum(taskSourceValues),\n complexity: z.enum(taskComplexityValues),\n status: z.enum(contributionTaskStatusValues),\n tokensUsed: z.number().int().nonnegative(),\n duration: z.number().nonnegative(),\n filesChanged: z.array(z.string().min(1)),\n pr: z\n .object({\n number: z.number().int().positive(),\n url: z.string().url(),\n status: z.enum([\"open\", \"merged\", \"closed\"]),\n })\n .optional(),\n linkedIssue: z\n .object({\n number: z.number().int().positive(),\n url: z.string().url(),\n })\n .optional(),\n error: z.string().min(1).optional(),\n});\n\nexport const contributionLogSchema = z.object({\n version: z.literal(\"1.0\"),\n runId: z.string().min(1),\n timestamp: z.string().datetime({ offset: true }),\n contributor: z.object({\n githubUsername: githubUsernameSchema,\n email: z.string().email().optional(),\n }),\n repo: z.object({\n fullName: z\n .string()\n .min(1)\n .regex(/^[^\\s/]+\\/[^\\s/]+$/, \"Expected repository in owner/repo format.\"),\n headSha: z.string().regex(/^[A-Fa-f0-9]{7,40}$/, \"Expected git SHA (7-40 hex chars).\"),\n defaultBranch: z.string().min(1),\n }),\n budget: z.object({\n provider: z.string().min(1),\n totalTokensBudgeted: z.number().int().nonnegative(),\n totalTokensUsed: z.number().int().nonnegative(),\n estimatedCostUsd: z.number().nonnegative().optional(),\n }),\n tasks: z.array(contributionTaskSchema),\n metrics: z.object({\n tasksDiscovered: z.number().int().nonnegative(),\n tasksAttempted: z.number().int().nonnegative(),\n tasksSucceeded: z.number().int().nonnegative(),\n tasksFailed: z.number().int().nonnegative(),\n totalDuration: z.number().nonnegative(),\n totalFilesChanged: z.number().int().nonnegative(),\n totalLinesAdded: z.number().int().nonnegative(),\n totalLinesRemoved: z.number().int().nonnegative(),\n }),\n});\n\nexport type ContributionTask = z.infer<typeof contributionTaskSchema>;\nexport type ContributionLog = z.infer<typeof contributionLogSchema>;\n\nexport function parseContributionLog(input: unknown): ContributionLog {\n return contributionLogSchema.parse(input);\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nimport { buildLeaderboard } from \"./leaderboard.js\";\nimport { type ContributionLog, contributionLogSchema } from \"./log-schema.js\";\n\nconst OAC_DIRECTORY = \".oac\";\nconst CONTRIBUTIONS_DIRECTORY = \"contributions\";\n\nexport async function writeContributionLog(\n log: ContributionLog,\n repoPath: string,\n): Promise<string> {\n const parsedLog = contributionLogSchema.parse(log);\n const contributionsPath = resolve(repoPath, OAC_DIRECTORY, CONTRIBUTIONS_DIRECTORY);\n\n await mkdir(contributionsPath, { recursive: true });\n\n const timestamp = formatFileTimestamp(parsedLog.timestamp);\n const username = toSafeFilenameSegment(parsedLog.contributor.githubUsername);\n const filename = `${timestamp}-${username}.json`;\n const filePath = join(contributionsPath, filename);\n\n const payload = `${JSON.stringify(parsedLog, null, 2)}\\n`;\n await writeFileAtomically(filePath, payload);\n try {\n await buildLeaderboard(repoPath);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown leaderboard error\";\n console.warn(`[tracking] Contribution log written, but leaderboard refresh failed: ${message}`);\n }\n\n return filePath;\n}\n\nfunction formatFileTimestamp(timestamp: string): string {\n const date = new Date(timestamp);\n const yyyy = String(date.getUTCFullYear());\n const mm = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const dd = String(date.getUTCDate()).padStart(2, \"0\");\n const hh = String(date.getUTCHours()).padStart(2, \"0\");\n const min = String(date.getUTCMinutes()).padStart(2, \"0\");\n const sec = String(date.getUTCSeconds()).padStart(2, \"0\");\n\n return `${yyyy}-${mm}-${dd}-${hh}${min}${sec}`;\n}\n\nfunction toSafeFilenameSegment(value: string): string {\n const sanitized = value\n .trim()\n .replace(/[^A-Za-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n return sanitized || \"unknown\";\n}\n\nasync function writeFileAtomically(destinationPath: string, content: string): Promise<void> {\n const tempPath = `${destinationPath}.${process.pid}.${randomUUID()}.tmp`;\n\n try {\n await writeFile(tempPath, content, { encoding: \"utf8\", flag: \"wx\" });\n await rename(tempPath, destinationPath);\n } finally {\n await rm(tempPath, { force: true });\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, readdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nimport { type ContributionLog, type TaskSource, contributionLogSchema } from \"./log-schema.js\";\n\nconst OAC_DIRECTORY = \".oac\";\nconst CONTRIBUTIONS_DIRECTORY = \"contributions\";\nconst LEADERBOARD_FILENAME = \"leaderboard.json\";\nconst EMPTY_TIMESTAMP = \"\";\n\ninterface LeaderboardAccumulator {\n githubUsername: string;\n totalRuns: number;\n totalTasksCompleted: number;\n totalTokensDonated: number;\n totalFilesChanged: number;\n totalLinesChanged: number;\n totalPRsCreated: number;\n totalPRsMerged: number;\n firstContribution: string;\n lastContribution: string;\n sourceCounts: Map<TaskSource, number>;\n}\n\nexport interface Leaderboard {\n generatedAt: string;\n entries: LeaderboardEntry[];\n repoStats: {\n totalContributions: number;\n totalTokensUsed: number;\n totalPRsCreated: number;\n totalPRsMerged: number;\n firstContribution: string;\n lastContribution: string;\n };\n}\n\nexport interface LeaderboardEntry {\n githubUsername: string;\n totalRuns: number;\n totalTasksCompleted: number;\n totalTokensDonated: number;\n totalFilesChanged: number;\n totalLinesChanged: number;\n totalPRsCreated: number;\n totalPRsMerged: number;\n favoriteTaskSource: TaskSource;\n firstContribution: string;\n lastContribution: string;\n}\n\nexport async function buildLeaderboard(repoPath: string): Promise<Leaderboard> {\n const repoRoot = resolve(repoPath);\n const oacPath = join(repoRoot, OAC_DIRECTORY);\n const contributionsPath = join(oacPath, CONTRIBUTIONS_DIRECTORY);\n const logs = await readContributionLogs(contributionsPath);\n\n const aggregates = new Map<string, LeaderboardAccumulator>();\n const repoStats = {\n totalContributions: logs.length,\n totalTokensUsed: 0,\n totalPRsCreated: 0,\n totalPRsMerged: 0,\n firstContribution: EMPTY_TIMESTAMP,\n lastContribution: EMPTY_TIMESTAMP,\n };\n\n for (const log of logs) {\n const username = log.contributor.githubUsername;\n const accumulator = aggregates.get(username) ?? createAccumulator(username, log.timestamp);\n\n accumulator.totalRuns += 1;\n accumulator.totalTasksCompleted += log.tasks.filter((task) => task.status !== \"failed\").length;\n accumulator.totalTokensDonated += log.budget.totalTokensUsed;\n accumulator.totalFilesChanged += log.metrics.totalFilesChanged;\n accumulator.totalLinesChanged += log.metrics.totalLinesAdded + log.metrics.totalLinesRemoved;\n accumulator.firstContribution = minIsoTimestamp(accumulator.firstContribution, log.timestamp);\n accumulator.lastContribution = maxIsoTimestamp(accumulator.lastContribution, log.timestamp);\n\n for (const task of log.tasks) {\n if (task.pr) {\n accumulator.totalPRsCreated += 1;\n if (task.pr.status === \"merged\") {\n accumulator.totalPRsMerged += 1;\n }\n }\n\n accumulator.sourceCounts.set(\n task.source,\n (accumulator.sourceCounts.get(task.source) ?? 0) + 1,\n );\n }\n\n aggregates.set(username, accumulator);\n\n repoStats.totalTokensUsed += log.budget.totalTokensUsed;\n repoStats.firstContribution = minIsoTimestamp(repoStats.firstContribution, log.timestamp);\n repoStats.lastContribution = maxIsoTimestamp(repoStats.lastContribution, log.timestamp);\n repoStats.totalPRsCreated += log.tasks.filter((task) => Boolean(task.pr)).length;\n repoStats.totalPRsMerged += log.tasks.filter((task) => task.pr?.status === \"merged\").length;\n }\n\n const entries: LeaderboardEntry[] = Array.from(aggregates.values())\n .map((entry) => ({\n githubUsername: entry.githubUsername,\n totalRuns: entry.totalRuns,\n totalTasksCompleted: entry.totalTasksCompleted,\n totalTokensDonated: entry.totalTokensDonated,\n totalFilesChanged: entry.totalFilesChanged,\n totalLinesChanged: entry.totalLinesChanged,\n totalPRsCreated: entry.totalPRsCreated,\n totalPRsMerged: entry.totalPRsMerged,\n favoriteTaskSource: getFavoriteTaskSource(entry.sourceCounts),\n firstContribution: entry.firstContribution,\n lastContribution: entry.lastContribution,\n }))\n .sort((a, b) => {\n if (b.totalTasksCompleted !== a.totalTasksCompleted) {\n return b.totalTasksCompleted - a.totalTasksCompleted;\n }\n if (b.totalRuns !== a.totalRuns) {\n return b.totalRuns - a.totalRuns;\n }\n if (b.totalTokensDonated !== a.totalTokensDonated) {\n return b.totalTokensDonated - a.totalTokensDonated;\n }\n return a.githubUsername.localeCompare(b.githubUsername);\n });\n\n const leaderboard: Leaderboard = {\n generatedAt: new Date().toISOString(),\n entries,\n repoStats,\n };\n\n await mkdir(oacPath, { recursive: true });\n const leaderboardPath = join(oacPath, LEADERBOARD_FILENAME);\n const payload = `${JSON.stringify(leaderboard, null, 2)}\\n`;\n await writeFileAtomically(leaderboardPath, payload);\n\n return leaderboard;\n}\n\nfunction createAccumulator(\n githubUsername: string,\n initialTimestamp: string,\n): LeaderboardAccumulator {\n return {\n githubUsername,\n totalRuns: 0,\n totalTasksCompleted: 0,\n totalTokensDonated: 0,\n totalFilesChanged: 0,\n totalLinesChanged: 0,\n totalPRsCreated: 0,\n totalPRsMerged: 0,\n firstContribution: initialTimestamp,\n lastContribution: initialTimestamp,\n sourceCounts: new Map<TaskSource, number>(),\n };\n}\n\nasync function readContributionLogs(contributionsPath: string): Promise<ContributionLog[]> {\n let fileNames: string[];\n try {\n const entries = await readdir(contributionsPath, { withFileTypes: true, encoding: \"utf8\" });\n fileNames = entries\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".json\"))\n .map((entry) => entry.name)\n .sort();\n } catch (error) {\n if (isFileNotFoundError(error)) {\n return [];\n }\n throw error;\n }\n\n const logs = await Promise.all(\n fileNames.map(async (fileName): Promise<ContributionLog | null> => {\n const filePath = join(contributionsPath, fileName);\n\n try {\n const fileContent = await readFile(filePath, \"utf8\");\n const parsedJson = JSON.parse(fileContent) as unknown;\n const parsedLog = contributionLogSchema.safeParse(parsedJson);\n\n if (!parsedLog.success) {\n console.warn(\n `[tracking] Skipping invalid contribution log \"${fileName}\": ${parsedLog.error.issues[0]?.message ?? \"Schema validation failed.\"}`,\n );\n return null;\n }\n\n return parsedLog.data;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown read error\";\n console.warn(`[tracking] Skipping unreadable contribution log \"${fileName}\": ${message}`);\n return null;\n }\n }),\n );\n\n return logs.filter((log): log is ContributionLog => log !== null);\n}\n\nfunction getFavoriteTaskSource(sourceCounts: Map<TaskSource, number>): TaskSource {\n if (sourceCounts.size === 0) {\n return \"custom\";\n }\n\n let favorite: TaskSource = \"custom\";\n let favoriteCount = -1;\n\n for (const [source, count] of sourceCounts.entries()) {\n if (count > favoriteCount) {\n favorite = source;\n favoriteCount = count;\n continue;\n }\n\n if (count === favoriteCount && source.localeCompare(favorite) < 0) {\n favorite = source;\n }\n }\n\n return favorite;\n}\n\nfunction minIsoTimestamp(a: string, b: string): string {\n if (!a) {\n return b;\n }\n if (!b) {\n return a;\n }\n return Date.parse(a) <= Date.parse(b) ? a : b;\n}\n\nfunction maxIsoTimestamp(a: string, b: string): string {\n if (!a) {\n return b;\n }\n if (!b) {\n return a;\n }\n return Date.parse(a) >= Date.parse(b) ? a : b;\n}\n\nfunction isFileNotFoundError(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n\n const code = (error as { code?: unknown }).code;\n return code === \"ENOENT\";\n}\n\nasync function writeFileAtomically(destinationPath: string, content: string): Promise<void> {\n const tempPath = `${destinationPath}.${process.pid}.${randomUUID()}.tmp`;\n\n try {\n await writeFile(tempPath, content, { encoding: \"utf8\", flag: \"wx\" });\n await rename(tempPath, destinationPath);\n } finally {\n await rm(tempPath, { force: true });\n }\n}\n"],"mappings":"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","names":["randomUUID","mkdir","rename","rm","writeFile","join","resolve","OAC_DIRECTORY","CONTRIBUTIONS_DIRECTORY","resolve","mkdir","join","writeFileAtomically","randomUUID","writeFile","rename","rm"]}