@open330/oac 2026.221.2 → 2026.222.2

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 (38) hide show
  1. package/README.md +170 -1
  2. package/dist/budget/index.js +1 -1
  3. package/dist/{chunk-EYUQMPVO.js → chunk-27FEE5KS.js} +86 -34
  4. package/dist/chunk-27FEE5KS.js.map +1 -0
  5. package/dist/{chunk-5GAUWC3L.js → chunk-ALBVUNUY.js} +1 -1
  6. package/dist/chunk-ALBVUNUY.js.map +1 -0
  7. package/dist/{chunk-VK33A5L4.js → chunk-ATVWSG75.js} +480 -232
  8. package/dist/chunk-ATVWSG75.js.map +1 -0
  9. package/dist/{chunk-7C7SC4TZ.js → chunk-I3TKNT4M.js} +9 -2
  10. package/dist/chunk-I3TKNT4M.js.map +1 -0
  11. package/dist/{chunk-6A37SKAJ.js → chunk-JDFAJP45.js} +1 -1
  12. package/dist/{chunk-6A37SKAJ.js.map → chunk-JDFAJP45.js.map} +1 -1
  13. package/dist/{chunk-OS3XDHOJ.js → chunk-UCYK4Z6O.js} +1 -1
  14. package/dist/chunk-UCYK4Z6O.js.map +1 -0
  15. package/dist/{chunk-OCCMKAJI.js → chunk-ZJBLRKCV.js} +3 -3
  16. package/dist/chunk-ZJBLRKCV.js.map +1 -0
  17. package/dist/cli/cli.js +7 -7
  18. package/dist/cli/index.js +7 -7
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/completion/index.d.ts +1 -1
  21. package/dist/completion/index.js +2 -2
  22. package/dist/completion/index.js.map +1 -1
  23. package/dist/{config-DequKoFA.d.ts → config-DnzZ7w92.d.ts} +60 -1
  24. package/dist/core/index.d.ts +1 -1
  25. package/dist/core/index.js +4 -2
  26. package/dist/dashboard/index.js +72 -23
  27. package/dist/dashboard/index.js.map +1 -1
  28. package/dist/discovery/index.d.ts +1 -1
  29. package/dist/discovery/index.js +2 -2
  30. package/dist/execution/index.js +3 -3
  31. package/dist/repo/index.js +1 -1
  32. package/package.json +13 -15
  33. package/dist/chunk-5GAUWC3L.js.map +0 -1
  34. package/dist/chunk-7C7SC4TZ.js.map +0 -1
  35. package/dist/chunk-EYUQMPVO.js.map +0 -1
  36. package/dist/chunk-OCCMKAJI.js.map +0 -1
  37. package/dist/chunk-OS3XDHOJ.js.map +0 -1
  38. package/dist/chunk-VK33A5L4.js.map +0 -1
@@ -234,6 +234,11 @@ var AnalyzeSchema = z.object({
234
234
  /** Directory for persisted context, relative to repo root. */
235
235
  contextDir: z.string().min(1).default(".oac/context")
236
236
  }).strict().default({});
237
+ var ContextPolicySchema = z.object({
238
+ mode: z.enum(["off", "warn", "enforce"]).default("off"),
239
+ requiredGlobs: z.array(z.string().min(1)).default([".context/plans/**/*.md"]),
240
+ maxAckItems: z.number().int().positive().default(3)
241
+ }).strict().default({});
237
242
  var OacConfigSchema = z.object({
238
243
  repos: z.array(RepoTargetSchema).default([]),
239
244
  provider: ProviderSchema,
@@ -243,7 +248,8 @@ var OacConfigSchema = z.object({
243
248
  completion: CompletionSchema,
244
249
  tracking: TrackingSchema,
245
250
  dashboard: DashboardSchema,
246
- analyze: AnalyzeSchema
251
+ analyze: AnalyzeSchema,
252
+ context: ContextPolicySchema
247
253
  }).strict();
248
254
  var OacConfig = OacConfigSchema;
249
255
  function defineConfig(config) {
@@ -347,6 +353,7 @@ export {
347
353
  TrackingSchema,
348
354
  DashboardSchema,
349
355
  AnalyzeSchema,
356
+ ContextPolicySchema,
350
357
  OacConfigSchema,
351
358
  OacConfig,
352
359
  defineConfig,
@@ -355,4 +362,4 @@ export {
355
362
  createEventBus,
356
363
  UNLIMITED_BUDGET
357
364
  };
358
- //# sourceMappingURL=chunk-7C7SC4TZ.js.map
365
+ //# sourceMappingURL=chunk-I3TKNT4M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/config.ts","../src/core/errors.ts","../src/core/event-bus.ts","../src/core/types.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { configError } from \"./errors.js\";\n\nconst ENV_VAR_PATTERN = /\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g;\n\nconst DEFAULT_DISCOVERY_EXCLUDE = [\n \"node_modules\",\n \"dist\",\n \"build\",\n \".git\",\n \"*.min.js\",\n \"vendor/\",\n] as const;\n\nexport const RepoTargetSchema = z.union([\n z.string().min(1),\n z\n .object({\n name: z.string().min(1),\n branch: z.string().min(1).optional(),\n })\n .strict(),\n]);\n\nexport const ProviderSchema = z\n .object({\n id: z.string().min(1).default(\"claude-code\"),\n options: z.record(z.string(), z.unknown()).default({}),\n })\n .strict()\n .default({});\n\nexport const BudgetSchema = z\n .object({\n totalTokens: z.number().int().positive().default(100_000),\n reservePercent: z.number().min(0).max(1).default(0.1),\n estimationPadding: z.number().positive().default(1.2),\n })\n .strict()\n .default({});\n\nexport const DiscoveryScannersSchema = z\n .object({\n lint: z.boolean().default(true),\n todo: z.boolean().default(true),\n testGap: z.boolean().default(true),\n deadCode: z.boolean().default(false),\n githubIssues: z.boolean().default(true),\n })\n .strict()\n .default({});\n\nexport const DiscoverySchema = z\n .object({\n scanners: DiscoveryScannersSchema,\n issueLabels: z.array(z.string().min(1)).default([\"good-first-issue\", \"help-wanted\", \"bug\"]),\n minPriority: z.number().int().min(0).max(100).default(20),\n maxTasks: z.number().int().positive().default(50),\n customScanners: z.array(z.string().min(1)).default([]),\n exclude: z.array(z.string().min(1)).default([...DEFAULT_DISCOVERY_EXCLUDE]),\n })\n .strict()\n .default({});\n\nexport const ValidationSchema = z\n .object({\n lint: z.boolean().default(true),\n test: z.boolean().default(true),\n typeCheck: z.boolean().default(true),\n maxDiffLines: z.number().int().positive().default(500),\n })\n .strict()\n .default({});\n\nexport const PrSchema = z\n .object({\n draft: z.boolean().default(false),\n labels: z.array(z.string().min(1)).default([\"oac-contribution\"]),\n reviewers: z.array(z.string().min(1)).default([]),\n assignees: z.array(z.string().min(1)).default([]),\n })\n .strict()\n .default({});\n\nexport const ExecutionSchema = z\n .object({\n concurrency: z.number().int().positive().default(2),\n taskTimeout: z.number().int().positive().default(300),\n maxRetries: z.number().int().min(0).default(2),\n mode: z.enum([\"new-pr\", \"update-pr\", \"direct-commit\"]).default(\"new-pr\"),\n branchPattern: z.string().min(1).default(\"oac/{date}/{task}\"),\n validation: ValidationSchema,\n pr: PrSchema,\n })\n .strict()\n .default({});\n\nexport const LinearIntegrationSchema = z\n .object({\n enabled: z.boolean().default(false),\n apiKey: z.string().min(1).optional(),\n teamId: z.string().min(1).optional(),\n })\n .strict()\n .default({})\n .superRefine((value, ctx) => {\n if (value.enabled && !value.apiKey) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"apiKey\"],\n message: \"Linear integration is enabled but apiKey is missing\",\n });\n }\n if (value.enabled && !value.teamId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"teamId\"],\n message: \"Linear integration is enabled but teamId is missing\",\n });\n }\n });\n\nexport const JiraIntegrationSchema = z\n .object({\n enabled: z.boolean().default(false),\n baseUrl: z.string().url().optional(),\n email: z.string().min(1).optional(),\n apiToken: z.string().min(1).optional(),\n projectKey: z.string().min(1).optional(),\n })\n .strict()\n .default({})\n .superRefine((value, ctx) => {\n if (!value.enabled) {\n return;\n }\n\n if (!value.baseUrl) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"baseUrl\"],\n message: \"Jira integration is enabled but baseUrl is missing\",\n });\n }\n if (!value.email) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"email\"],\n message: \"Jira integration is enabled but email is missing\",\n });\n }\n if (!value.apiToken) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"apiToken\"],\n message: \"Jira integration is enabled but apiToken is missing\",\n });\n }\n if (!value.projectKey) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"projectKey\"],\n message: \"Jira integration is enabled but projectKey is missing\",\n });\n }\n });\n\nexport const CompletionSchema = z\n .object({\n integrations: z\n .object({\n linear: LinearIntegrationSchema,\n jira: JiraIntegrationSchema,\n })\n .strict()\n .default({}),\n monitor: z\n .object({\n enabled: z.boolean().default(false),\n pollInterval: z.number().int().positive().default(300),\n autoRespondToReviews: z.boolean().default(false),\n autoDeleteBranch: z.boolean().default(true),\n })\n .strict()\n .default({}),\n })\n .strict()\n .default({});\n\nexport const TrackingSchema = z\n .object({\n directory: z.string().min(1).default(\".oac\"),\n autoCommit: z.boolean().default(false),\n gitTracked: z.boolean().default(true),\n })\n .strict()\n .default({});\n\nexport const DashboardSchema = z\n .object({\n port: z.number().int().min(1).max(65535).default(3141),\n openBrowser: z.boolean().default(true),\n })\n .strict()\n .default({});\n\nexport const AnalyzeSchema = z\n .object({\n /** Auto-run analysis before `oac run` if context is stale or missing. */\n autoAnalyze: z.boolean().default(true),\n /** Max age in ms before context is considered stale (default: 24h). */\n staleAfterMs: z.number().int().positive().default(86_400_000),\n /** Directory for persisted context, relative to repo root. */\n contextDir: z.string().min(1).default(\".oac/context\"),\n })\n .strict()\n .default({});\n\nexport const ContextPolicySchema = z\n .object({\n mode: z.enum([\"off\", \"warn\", \"enforce\"]).default(\"off\"),\n requiredGlobs: z.array(z.string().min(1)).default([\".context/plans/**/*.md\"]),\n maxAckItems: z.number().int().positive().default(3),\n })\n .strict()\n .default({});\n\nexport const OacConfigSchema = z\n .object({\n repos: z.array(RepoTargetSchema).default([]),\n provider: ProviderSchema,\n budget: BudgetSchema,\n discovery: DiscoverySchema,\n execution: ExecutionSchema,\n completion: CompletionSchema,\n tracking: TrackingSchema,\n dashboard: DashboardSchema,\n analyze: AnalyzeSchema,\n context: ContextPolicySchema,\n })\n .strict();\n\nexport const OacConfig = OacConfigSchema;\nexport type OacConfig = z.output<typeof OacConfigSchema>;\nexport type OacConfigInput = z.input<typeof OacConfigSchema>;\n\nexport interface LoadConfigOptions {\n env?: Record<string, string | undefined>;\n}\n\nexport function defineConfig(config: OacConfigInput): OacConfigInput {\n return config;\n}\n\nexport function interpolateEnvVars(\n value: string,\n env: Record<string, string | undefined> = getProcessEnv(),\n path: string[] = [],\n): string {\n return value.replaceAll(ENV_VAR_PATTERN, (_, variableName: string) => {\n const interpolated = env[variableName];\n if (interpolated !== undefined) {\n return interpolated;\n }\n\n throw configError(\n \"CONFIG_SECRET_MISSING\",\n `Environment variable ${variableName} is referenced in config but not set`,\n {\n context: {\n variableName,\n path: path.length > 0 ? path.join(\".\") : \"<root>\",\n },\n },\n );\n });\n}\n\nexport function loadConfig(config: unknown = {}, options: LoadConfigOptions = {}): OacConfig {\n const env = options.env ?? getProcessEnv();\n const interpolatedConfig = interpolateConfigEnvVars(config, env);\n const parsed = OacConfigSchema.safeParse(interpolatedConfig);\n\n if (parsed.success) {\n return parsed.data;\n }\n\n throw configError(\"CONFIG_INVALID\", \"Invalid OAC configuration\", {\n context: {\n issues: parsed.error.issues.map((issue) => ({\n code: issue.code,\n message: issue.message,\n path: issue.path.join(\".\"),\n })),\n },\n });\n}\n\nfunction interpolateConfigEnvVars(\n value: unknown,\n env: Record<string, string | undefined>,\n path: string[] = [],\n): unknown {\n if (typeof value === \"string\") {\n return interpolateEnvVars(value, env, path);\n }\n\n if (Array.isArray(value)) {\n return value.map((item, index) => interpolateConfigEnvVars(item, env, [...path, `${index}`]));\n }\n\n if (!isPlainObject(value)) {\n return value;\n }\n\n const interpolatedObject: Record<string, unknown> = {};\n\n for (const [key, nestedValue] of Object.entries(value)) {\n interpolatedObject[key] = interpolateConfigEnvVars(nestedValue, env, [...path, key]);\n }\n\n return interpolatedObject;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction getProcessEnv(): Record<string, string | undefined> {\n const globalProcess = globalThis as {\n process?: { env?: Record<string, string | undefined> };\n };\n return globalProcess.process?.env ?? {};\n}\n","export type OacErrorSeverity = \"fatal\" | \"recoverable\" | \"warning\";\n\nexport const REPO_ERROR_CODES = [\n \"REPO_NOT_FOUND\",\n \"REPO_ARCHIVED\",\n \"REPO_NO_PERMISSION\",\n \"REPO_CLONE_FAILED\",\n] as const;\n\nexport const DISCOVERY_ERROR_CODES = [\n \"SCANNER_FAILED\",\n \"SCANNER_TIMEOUT\",\n \"NO_TASKS_FOUND\",\n] as const;\n\nexport const BUDGET_ERROR_CODES = [\"BUDGET_INSUFFICIENT\", \"TOKENIZER_UNAVAILABLE\"] as const;\n\nexport const EXECUTION_ERROR_CODES = [\n \"AGENT_NOT_AVAILABLE\",\n \"AGENT_EXECUTION_FAILED\",\n \"AGENT_TIMEOUT\",\n \"AGENT_OOM\",\n \"AGENT_TOKEN_LIMIT\",\n \"AGENT_RATE_LIMITED\",\n \"VALIDATION_LINT_FAILED\",\n \"VALIDATION_TEST_FAILED\",\n \"VALIDATION_DIFF_TOO_LARGE\",\n \"VALIDATION_FORBIDDEN_PATTERN\",\n] as const;\n\nexport const COMPLETION_ERROR_CODES = [\n \"PR_CREATION_FAILED\",\n \"PR_PUSH_REJECTED\",\n \"WEBHOOK_DELIVERY_FAILED\",\n] as const;\n\nexport const CONFIG_ERROR_CODES = [\"CONFIG_INVALID\", \"CONFIG_SECRET_MISSING\"] as const;\n\nexport const SYSTEM_ERROR_CODES = [\"NETWORK_ERROR\", \"DISK_SPACE_LOW\", \"GIT_LOCK_FAILED\"] as const;\n\nexport const OAC_ERROR_CODES = [\n ...REPO_ERROR_CODES,\n ...DISCOVERY_ERROR_CODES,\n ...BUDGET_ERROR_CODES,\n ...EXECUTION_ERROR_CODES,\n ...COMPLETION_ERROR_CODES,\n ...CONFIG_ERROR_CODES,\n ...SYSTEM_ERROR_CODES,\n] as const;\n\nexport type RepoErrorCode = (typeof REPO_ERROR_CODES)[number];\nexport type DiscoveryErrorCode = (typeof DISCOVERY_ERROR_CODES)[number];\nexport type BudgetErrorCode = (typeof BUDGET_ERROR_CODES)[number];\nexport type ExecutionErrorCode = (typeof EXECUTION_ERROR_CODES)[number];\nexport type CompletionErrorCode = (typeof COMPLETION_ERROR_CODES)[number];\nexport type ConfigErrorCode = (typeof CONFIG_ERROR_CODES)[number];\nexport type SystemErrorCode = (typeof SYSTEM_ERROR_CODES)[number];\nexport type OacErrorCode = (typeof OAC_ERROR_CODES)[number];\n\nexport interface OacErrorOptions {\n severity?: OacErrorSeverity;\n context?: Record<string, unknown>;\n cause?: unknown;\n}\n\nexport class OacError extends Error {\n public readonly code: OacErrorCode;\n public readonly severity: OacErrorSeverity;\n public readonly context?: Record<string, unknown>;\n public override readonly cause?: unknown;\n\n public constructor(\n message: string,\n code: OacErrorCode,\n severity: OacErrorSeverity,\n context?: Record<string, unknown>,\n cause?: unknown,\n ) {\n super(message);\n this.name = \"OacError\";\n this.code = code;\n this.severity = severity;\n this.context = context;\n this.cause = cause;\n }\n}\n\nfunction createError(\n code: OacErrorCode,\n message: string,\n defaultSeverity: OacErrorSeverity,\n options: OacErrorOptions = {},\n): OacError {\n return new OacError(\n message,\n code,\n options.severity ?? defaultSeverity,\n options.context,\n options.cause,\n );\n}\n\nexport function repoError(\n code: RepoErrorCode,\n message: string,\n options: OacErrorOptions = {},\n): OacError {\n return createError(code, message, \"fatal\", options);\n}\n\nexport function discoveryError(\n code: DiscoveryErrorCode,\n message: string,\n options: OacErrorOptions = {},\n): OacError {\n return createError(code, message, \"recoverable\", options);\n}\n\nexport function budgetError(\n code: BudgetErrorCode,\n message: string,\n options: OacErrorOptions = {},\n): OacError {\n return createError(code, message, \"recoverable\", options);\n}\n\nexport function executionError(\n code: ExecutionErrorCode,\n message: string,\n options: OacErrorOptions = {},\n): OacError {\n return createError(code, message, \"recoverable\", options);\n}\n\nexport function completionError(\n code: CompletionErrorCode,\n message: string,\n options: OacErrorOptions = {},\n): OacError {\n return createError(code, message, \"recoverable\", options);\n}\n\nexport function configError(\n code: ConfigErrorCode,\n message: string,\n options: OacErrorOptions = {},\n): OacError {\n return createError(code, message, \"fatal\", options);\n}\n","import { EventEmitter } from \"eventemitter3\";\n\nimport type { OacError } from \"./errors.js\";\nimport type { ExecutionResult, ResolvedRepo, RunSummary, Task, TokenEstimate } from \"./types.js\";\n\nexport interface OacEvents {\n \"repo:resolved\": { repo: ResolvedRepo };\n \"task:discovered\": { tasks: Task[] };\n \"task:selected\": { task: Task; reason: string };\n \"budget:estimated\": { task: Task; estimate: TokenEstimate };\n \"execution:started\": { jobId: string; task: Task; agent: string };\n \"execution:progress\": { jobId: string; tokensUsed: number; stage: string };\n \"execution:completed\": { jobId: string; result: ExecutionResult };\n \"execution:failed\": { jobId: string; error: OacError };\n \"pr:created\": { jobId: string; prUrl: string };\n \"pr:merged\": { jobId: string; prUrl: string };\n \"run:completed\": { summary: RunSummary };\n}\n\ntype OacEventArgs = {\n [K in keyof OacEvents]: [payload: OacEvents[K]];\n};\n\nexport type OacEventBus = EventEmitter<OacEventArgs>;\n\nexport function createEventBus(): OacEventBus {\n return new EventEmitter<OacEventArgs>();\n}\n","export type AgentProviderId = \"claude-code\" | \"codex\" | \"opencode\" | (string & {});\n\n/**\n * Sentinel value representing an unlimited token budget.\n * Uses MAX_SAFE_INTEGER (passes Number.isFinite() checks in budget planner).\n */\nexport const UNLIMITED_BUDGET = Number.MAX_SAFE_INTEGER;\n\nexport interface ResolvedRepo {\n fullName: string;\n owner: string;\n name: string;\n localPath: string;\n worktreePath: string;\n meta: {\n defaultBranch: string;\n language?: string;\n languages: Record<string, number>;\n size: number;\n stars: number;\n openIssuesCount: number;\n topics: string[];\n license?: string;\n isArchived: boolean;\n isFork: boolean;\n permissions: {\n admin: boolean;\n maintain: boolean;\n push: boolean;\n triage: boolean;\n pull: boolean;\n };\n };\n git: {\n headSha: string;\n remoteUrl: string;\n isShallowClone: boolean;\n };\n}\n\nexport type TaskSource = \"lint\" | \"todo\" | \"test-gap\" | \"dead-code\" | \"github-issue\" | \"custom\";\n\nexport type TaskComplexity = \"trivial\" | \"simple\" | \"moderate\" | \"complex\";\n\nexport type ExecutionMode = \"new-pr\" | \"update-pr\" | \"direct-commit\";\n\nexport interface Task {\n id: string;\n source: TaskSource;\n title: string;\n description: string;\n targetFiles: string[];\n priority: number;\n complexity: TaskComplexity;\n executionMode: ExecutionMode;\n linkedIssue?: {\n number: number;\n url: string;\n labels: string[];\n };\n metadata: Record<string, unknown>;\n discoveredAt: string;\n /** When this task belongs to an epic, the parent epic's id. */\n parentEpicId?: string;\n}\n\n// ── Epics ─────────────────────────────────────────────────────\n\nexport type EpicStatus = \"pending\" | \"in-progress\" | \"completed\" | \"skipped\";\n\n/**\n * An Epic groups related tasks that should be executed together in a single\n * agent session, producing one PR with coherent multi-file changes.\n */\nexport interface Epic {\n id: string;\n title: string;\n description: string;\n /** Module scope, e.g. \"budget\", \"discovery\", or \"root\" */\n scope: string;\n subtasks: Task[];\n /** Broader file set the agent should read for context */\n contextFiles: string[];\n status: EpicStatus;\n priority: number;\n estimatedTokens: number;\n createdAt: string;\n completedAt?: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface TokenEstimate {\n taskId: string;\n providerId: AgentProviderId;\n contextTokens: number;\n promptTokens: number;\n expectedOutputTokens: number;\n totalEstimatedTokens: number;\n confidence: number;\n feasible: boolean;\n estimatedCostUsd?: number;\n}\n\nexport interface ExecutionPlan {\n totalBudget: number;\n selectedTasks: Array<{\n task: Task;\n estimate: TokenEstimate;\n cumulativeBudgetUsed: number;\n }>;\n deferredTasks: Array<{\n task: Task;\n estimate: TokenEstimate;\n reason: \"budget_exceeded\" | \"low_confidence\" | \"too_complex\";\n }>;\n reserveTokens: number;\n remainingTokens: number;\n}\n\nexport interface ContributionTask {\n taskId: string;\n title: string;\n source: TaskSource;\n complexity: TaskComplexity;\n status: \"success\" | \"partial\" | \"failed\";\n tokensUsed: number;\n duration: number;\n filesChanged: string[];\n pr?: {\n number: number;\n url: string;\n status: \"open\" | \"merged\" | \"closed\";\n };\n linkedIssue?: {\n number: number;\n url: string;\n };\n error?: string;\n}\n\nexport interface ContributionLog {\n version: \"1.0\";\n runId: string;\n timestamp: string;\n contributor: {\n githubUsername: string;\n email?: string;\n };\n repo: {\n fullName: string;\n headSha: string;\n defaultBranch: string;\n };\n budget: {\n provider: AgentProviderId;\n totalTokensBudgeted: number;\n totalTokensUsed: number;\n estimatedCostUsd?: number;\n };\n tasks: ContributionTask[];\n metrics: {\n tasksDiscovered: number;\n tasksAttempted: number;\n tasksSucceeded: number;\n tasksFailed: number;\n totalDuration: number;\n totalFilesChanged: number;\n totalLinesAdded: number;\n totalLinesRemoved: number;\n };\n}\n\nexport interface ExecutionResult {\n success: boolean;\n exitCode: number;\n totalTokensUsed: number;\n filesChanged: string[];\n duration: number;\n error?: string;\n}\n\nexport interface RunSummary {\n runId: string;\n repo: string;\n provider: AgentProviderId;\n startedAt: string;\n completedAt: string;\n duration: number;\n budget: {\n totalTokens: number;\n reserveTokens: number;\n usedTokens: number;\n remainingTokens: number;\n estimatedCostUsd?: number;\n };\n tasks: {\n discovered: number;\n selected: number;\n attempted: number;\n succeeded: number;\n failed: number;\n deferred: number;\n };\n pullRequests: {\n created: number;\n merged: number;\n urls: string[];\n };\n}\n"],"mappings":"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","names":[]}
@@ -55,4 +55,4 @@ export {
55
55
  truncate,
56
56
  isRecord
57
57
  };
58
- //# sourceMappingURL=chunk-6A37SKAJ.js.map
58
+ //# sourceMappingURL=chunk-JDFAJP45.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/memory.ts","../src/core/utils.ts"],"sourcesContent":["/**\n * Memory pressure monitoring utilities.\n *\n * Provides lightweight heap-usage checks that callers can use to\n * throttle work when the process is approaching memory limits.\n */\n\n/** Default threshold: pause work when heap usage exceeds 85% of the limit. */\nconst DEFAULT_PRESSURE_RATIO = 0.85;\n\nexport interface MemorySnapshot {\n heapUsedMB: number;\n heapTotalMB: number;\n rssUsedMB: number;\n /** Ratio of heapUsed / heapTotal (0–1). */\n heapPressure: number;\n /** True when heapPressure exceeds the configured threshold. */\n isUnderPressure: boolean;\n}\n\n/**\n * Take a snapshot of current memory usage.\n *\n * @param pressureRatio - Threshold ratio (0–1) above which `isUnderPressure`\n * is set to `true`. Defaults to 0.85.\n */\nexport function getMemorySnapshot(pressureRatio = DEFAULT_PRESSURE_RATIO): MemorySnapshot {\n const mem = process.memoryUsage();\n const heapUsedMB = mem.heapUsed / 1_048_576;\n const heapTotalMB = mem.heapTotal / 1_048_576;\n const rssUsedMB = mem.rss / 1_048_576;\n const heapPressure = mem.heapTotal > 0 ? mem.heapUsed / mem.heapTotal : 0;\n\n return {\n heapUsedMB: Math.round(heapUsedMB * 10) / 10,\n heapTotalMB: Math.round(heapTotalMB * 10) / 10,\n rssUsedMB: Math.round(rssUsedMB * 10) / 10,\n heapPressure: Math.round(heapPressure * 1000) / 1000,\n isUnderPressure: heapPressure >= pressureRatio,\n };\n}\n\n/**\n * Creates a monitor that periodically checks memory pressure and calls\n * `onPressure` when the threshold is exceeded. The monitor can be used\n * to pause a PQueue or reduce concurrency under load.\n *\n * Returns a `stop` function to clear the interval.\n */\nexport function createMemoryMonitor(options: {\n /** Polling interval in milliseconds (default: 5 000). */\n intervalMs?: number;\n /** Heap pressure ratio threshold (default: 0.85). */\n pressureRatio?: number;\n /** Called when heap pressure exceeds the threshold. */\n onPressure: (snapshot: MemorySnapshot) => void;\n /** Called when heap pressure drops back below the threshold. */\n onRelief?: (snapshot: MemorySnapshot) => void;\n}): { stop: () => void } {\n const intervalMs = options.intervalMs ?? 5_000;\n const pressureRatio = options.pressureRatio ?? DEFAULT_PRESSURE_RATIO;\n let wasPressured = false;\n\n const timer = setInterval(() => {\n const snapshot = getMemorySnapshot(pressureRatio);\n\n if (snapshot.isUnderPressure && !wasPressured) {\n wasPressured = true;\n options.onPressure(snapshot);\n } else if (!snapshot.isUnderPressure && wasPressured) {\n wasPressured = false;\n options.onRelief?.(snapshot);\n }\n }, intervalMs);\n\n // Unref so this doesn't keep the process alive\n if (typeof timer === \"object\" && \"unref\" in timer) {\n timer.unref();\n }\n\n return {\n stop() {\n clearInterval(timer);\n },\n };\n}\n\n","/**\n * Shared utility functions used across the codebase.\n */\n\n/**\n * Truncate a string to `maxLength`, appending an ellipsis when trimmed.\n * Defaults to the unicode ellipsis `\"…\"` (1 char). Pass `\"...\"` for the\n * three-dot ASCII variant.\n */\nexport function truncate(\n value: string,\n maxLength: number,\n ellipsis = \"…\",\n): string {\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, Math.max(0, maxLength - ellipsis.length))}${ellipsis}`;\n}\n\n/**\n * Type guard: returns `true` when `value` is a non-null object\n * (i.e.\\ a `Record<string, unknown>`).\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n"],"mappings":";AAQA,IAAM,yBAAyB;AAkBxB,SAAS,kBAAkB,gBAAgB,wBAAwC;AACxF,QAAM,MAAM,QAAQ,YAAY;AAChC,QAAM,aAAa,IAAI,WAAW;AAClC,QAAM,cAAc,IAAI,YAAY;AACpC,QAAM,YAAY,IAAI,MAAM;AAC5B,QAAM,eAAe,IAAI,YAAY,IAAI,IAAI,WAAW,IAAI,YAAY;AAExE,SAAO;AAAA,IACL,YAAY,KAAK,MAAM,aAAa,EAAE,IAAI;AAAA,IAC1C,aAAa,KAAK,MAAM,cAAc,EAAE,IAAI;AAAA,IAC5C,WAAW,KAAK,MAAM,YAAY,EAAE,IAAI;AAAA,IACxC,cAAc,KAAK,MAAM,eAAe,GAAI,IAAI;AAAA,IAChD,iBAAiB,gBAAgB;AAAA,EACnC;AACF;AASO,SAAS,oBAAoB,SASX;AACvB,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,MAAI,eAAe;AAEnB,QAAM,QAAQ,YAAY,MAAM;AAC9B,UAAM,WAAW,kBAAkB,aAAa;AAEhD,QAAI,SAAS,mBAAmB,CAAC,cAAc;AAC7C,qBAAe;AACf,cAAQ,WAAW,QAAQ;AAAA,IAC7B,WAAW,CAAC,SAAS,mBAAmB,cAAc;AACpD,qBAAe;AACf,cAAQ,WAAW,QAAQ;AAAA,IAC7B;AAAA,EACF,GAAG,UAAU;AAGb,MAAI,OAAO,UAAU,YAAY,WAAW,OAAO;AACjD,UAAM,MAAM;AAAA,EACd;AAEA,SAAO;AAAA,IACL,OAAO;AACL,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AACF;;;AC5EO,SAAS,SACd,OACA,WACA,WAAW,UACH;AACR,MAAI,MAAM,UAAU,WAAW;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,YAAY,SAAS,MAAM,CAAC,CAAC,GAAG,QAAQ;AAC/E;AAMO,SAAS,SAAS,OAAkD;AACzE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;","names":[]}
1
+ {"version":3,"sources":["../src/core/memory.ts","../src/core/utils.ts"],"sourcesContent":["/**\n * Memory pressure monitoring utilities.\n *\n * Provides lightweight heap-usage checks that callers can use to\n * throttle work when the process is approaching memory limits.\n */\n\n/** Default threshold: pause work when heap usage exceeds 85% of the limit. */\nconst DEFAULT_PRESSURE_RATIO = 0.85;\n\nexport interface MemorySnapshot {\n heapUsedMB: number;\n heapTotalMB: number;\n rssUsedMB: number;\n /** Ratio of heapUsed / heapTotal (0–1). */\n heapPressure: number;\n /** True when heapPressure exceeds the configured threshold. */\n isUnderPressure: boolean;\n}\n\n/**\n * Take a snapshot of current memory usage.\n *\n * @param pressureRatio - Threshold ratio (0–1) above which `isUnderPressure`\n * is set to `true`. Defaults to 0.85.\n */\nexport function getMemorySnapshot(pressureRatio = DEFAULT_PRESSURE_RATIO): MemorySnapshot {\n const mem = process.memoryUsage();\n const heapUsedMB = mem.heapUsed / 1_048_576;\n const heapTotalMB = mem.heapTotal / 1_048_576;\n const rssUsedMB = mem.rss / 1_048_576;\n const heapPressure = mem.heapTotal > 0 ? mem.heapUsed / mem.heapTotal : 0;\n\n return {\n heapUsedMB: Math.round(heapUsedMB * 10) / 10,\n heapTotalMB: Math.round(heapTotalMB * 10) / 10,\n rssUsedMB: Math.round(rssUsedMB * 10) / 10,\n heapPressure: Math.round(heapPressure * 1000) / 1000,\n isUnderPressure: heapPressure >= pressureRatio,\n };\n}\n\n/**\n * Creates a monitor that periodically checks memory pressure and calls\n * `onPressure` when the threshold is exceeded. The monitor can be used\n * to pause a PQueue or reduce concurrency under load.\n *\n * Returns a `stop` function to clear the interval.\n */\nexport function createMemoryMonitor(options: {\n /** Polling interval in milliseconds (default: 5 000). */\n intervalMs?: number;\n /** Heap pressure ratio threshold (default: 0.85). */\n pressureRatio?: number;\n /** Called when heap pressure exceeds the threshold. */\n onPressure: (snapshot: MemorySnapshot) => void;\n /** Called when heap pressure drops back below the threshold. */\n onRelief?: (snapshot: MemorySnapshot) => void;\n}): { stop: () => void } {\n const intervalMs = options.intervalMs ?? 5_000;\n const pressureRatio = options.pressureRatio ?? DEFAULT_PRESSURE_RATIO;\n let wasPressured = false;\n\n const timer = setInterval(() => {\n const snapshot = getMemorySnapshot(pressureRatio);\n\n if (snapshot.isUnderPressure && !wasPressured) {\n wasPressured = true;\n options.onPressure(snapshot);\n } else if (!snapshot.isUnderPressure && wasPressured) {\n wasPressured = false;\n options.onRelief?.(snapshot);\n }\n }, intervalMs);\n\n // Unref so this doesn't keep the process alive\n if (typeof timer === \"object\" && \"unref\" in timer) {\n timer.unref();\n }\n\n return {\n stop() {\n clearInterval(timer);\n },\n };\n}\n","/**\n * Shared utility functions used across the codebase.\n */\n\n/**\n * Truncate a string to `maxLength`, appending an ellipsis when trimmed.\n * Defaults to the unicode ellipsis `\"…\"` (1 char). Pass `\"...\"` for the\n * three-dot ASCII variant.\n */\nexport function truncate(value: string, maxLength: number, ellipsis = \"…\"): string {\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, Math.max(0, maxLength - ellipsis.length))}${ellipsis}`;\n}\n\n/**\n * Type guard: returns `true` when `value` is a non-null object\n * (i.e.\\ a `Record<string, unknown>`).\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n"],"mappings":";AAQA,IAAM,yBAAyB;AAkBxB,SAAS,kBAAkB,gBAAgB,wBAAwC;AACxF,QAAM,MAAM,QAAQ,YAAY;AAChC,QAAM,aAAa,IAAI,WAAW;AAClC,QAAM,cAAc,IAAI,YAAY;AACpC,QAAM,YAAY,IAAI,MAAM;AAC5B,QAAM,eAAe,IAAI,YAAY,IAAI,IAAI,WAAW,IAAI,YAAY;AAExE,SAAO;AAAA,IACL,YAAY,KAAK,MAAM,aAAa,EAAE,IAAI;AAAA,IAC1C,aAAa,KAAK,MAAM,cAAc,EAAE,IAAI;AAAA,IAC5C,WAAW,KAAK,MAAM,YAAY,EAAE,IAAI;AAAA,IACxC,cAAc,KAAK,MAAM,eAAe,GAAI,IAAI;AAAA,IAChD,iBAAiB,gBAAgB;AAAA,EACnC;AACF;AASO,SAAS,oBAAoB,SASX;AACvB,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,MAAI,eAAe;AAEnB,QAAM,QAAQ,YAAY,MAAM;AAC9B,UAAM,WAAW,kBAAkB,aAAa;AAEhD,QAAI,SAAS,mBAAmB,CAAC,cAAc;AAC7C,qBAAe;AACf,cAAQ,WAAW,QAAQ;AAAA,IAC7B,WAAW,CAAC,SAAS,mBAAmB,cAAc;AACpD,qBAAe;AACf,cAAQ,WAAW,QAAQ;AAAA,IAC7B;AAAA,EACF,GAAG,UAAU;AAGb,MAAI,OAAO,UAAU,YAAY,WAAW,OAAO;AACjD,UAAM,MAAM;AAAA,EACd;AAEA,SAAO;AAAA,IACL,OAAO;AACL,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AACF;;;AC5EO,SAAS,SAAS,OAAe,WAAmB,WAAW,UAAa;AACjF,MAAI,MAAM,UAAU,WAAW;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,YAAY,SAAS,MAAM,CAAC,CAAC,GAAG,QAAQ;AAC/E;AAMO,SAAS,SAAS,OAAkD;AACzE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;","names":[]}
@@ -511,4 +511,4 @@ export {
511
511
  DEFAULT_REPO_CACHE_DIR,
512
512
  cloneRepo
513
513
  };
514
- //# sourceMappingURL=chunk-OS3XDHOJ.js.map
514
+ //# sourceMappingURL=chunk-UCYK4Z6O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/repo/resolver.ts","../src/repo/metadata-cache.ts","../src/repo/cloner.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Octokit } from \"@octokit/rest\";\nimport { MetadataCache } from \"./metadata-cache.js\";\nimport type { RepoPermissions, ResolvedRepo } from \"./types.js\";\n\nconst OWNER_REPO_PATTERN = /^(?<owner>[A-Za-z0-9_.-]+)\\/(?<repo>[A-Za-z0-9_.-]+?)(?:\\.git)?$/;\nconst GITHUB_SSH_PATTERN =\n /^git@github\\.com:(?<owner>[A-Za-z0-9_.-]+)\\/(?<repo>[A-Za-z0-9_.-]+?)(?:\\.git)?$/;\n\nexport type RepoResolutionErrorCode =\n | \"INVALID_INPUT\"\n | \"NOT_FOUND\"\n | \"FORBIDDEN\"\n | \"ARCHIVED\"\n | \"UNKNOWN\";\n\nexport class RepoResolutionError extends Error {\n public readonly code: RepoResolutionErrorCode;\n\n public constructor(message: string, code: RepoResolutionErrorCode, cause?: unknown) {\n super(message, { cause });\n this.name = \"RepoResolutionError\";\n this.code = code;\n }\n}\n\ninterface ParsedRepoInput {\n owner: string;\n name: string;\n}\n\nexport async function resolveRepo(input: string): Promise<ResolvedRepo> {\n const parsed = parseRepoInput(input);\n const cache = new MetadataCache();\n const cacheKey = `${parsed.owner}/${parsed.name}`;\n const cached = await cache.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const octokit = new Octokit({\n auth: resolveGitHubToken(),\n });\n\n const repoData = await fetchRepo(octokit, parsed.owner, parsed.name);\n if (repoData.archived) {\n throw new RepoResolutionError(\n `Repository \"${repoData.full_name}\" is archived and cannot be used for contributions.`,\n \"ARCHIVED\",\n );\n }\n\n const permissions = normalizePermissions(repoData.private, repoData.permissions);\n if (!permissions.pull) {\n throw new RepoResolutionError(\n `Missing pull permission for \"${repoData.full_name}\".`,\n \"FORBIDDEN\",\n );\n }\n\n const [languages, headSha] = await Promise.all([\n fetchLanguages(octokit, repoData.owner.login, repoData.name),\n fetchHeadSha(octokit, repoData.owner.login, repoData.name, repoData.default_branch),\n ]);\n\n const localPath = defaultLocalPath(repoData.owner.login, repoData.name);\n const resolved: ResolvedRepo = {\n fullName: repoData.full_name,\n owner: repoData.owner.login,\n name: repoData.name,\n localPath,\n worktreePath: join(localPath, \"..\", \".oac-worktrees\", repoData.default_branch),\n meta: {\n defaultBranch: repoData.default_branch,\n language: repoData.language,\n languages,\n size: repoData.size,\n stars: repoData.stargazers_count,\n openIssuesCount: repoData.open_issues_count,\n topics: repoData.topics ?? [],\n license: normalizeLicense(repoData.license?.spdx_id ?? null),\n isArchived: repoData.archived,\n isFork: repoData.fork,\n permissions,\n },\n git: {\n headSha,\n remoteUrl: repoData.clone_url ?? `https://github.com/${repoData.full_name}.git`,\n sshUrl: repoData.ssh_url ?? `git@github.com:${repoData.full_name}.git`,\n isShallowClone: true,\n },\n };\n\n await cache.set(resolved.fullName, resolved);\n return resolved;\n}\n\nfunction parseRepoInput(input: string): ParsedRepoInput {\n const normalized = input.trim();\n if (!normalized) {\n throw new RepoResolutionError(\"Repository input cannot be empty.\", \"INVALID_INPUT\");\n }\n\n const ownerRepoMatch = normalized.match(OWNER_REPO_PATTERN);\n if (ownerRepoMatch?.groups) {\n return {\n owner: ownerRepoMatch.groups.owner,\n name: ownerRepoMatch.groups.repo,\n };\n }\n\n const sshMatch = normalized.match(GITHUB_SSH_PATTERN);\n if (sshMatch?.groups) {\n return {\n owner: sshMatch.groups.owner,\n name: sshMatch.groups.repo,\n };\n }\n\n const normalizedUrlInput = normalized.startsWith(\"github.com/\")\n ? `https://${normalized}`\n : normalized;\n\n try {\n const url = new URL(normalizedUrlInput);\n if (!isGitHubHost(url.hostname)) {\n throw new RepoResolutionError(\n `Only github.com repository URLs are supported, received \"${url.hostname}\".`,\n \"INVALID_INPUT\",\n );\n }\n\n const pathParts = url.pathname.split(\"/\").filter(Boolean);\n if (pathParts.length < 2) {\n throw new RepoResolutionError(`Invalid GitHub repository URL \"${input}\".`, \"INVALID_INPUT\");\n }\n\n const owner = pathParts[0];\n const name = stripGitSuffix(pathParts[1]);\n if (!owner || !name) {\n throw new RepoResolutionError(`Invalid GitHub repository URL \"${input}\".`, \"INVALID_INPUT\");\n }\n\n return { owner, name };\n } catch (error) {\n if (error instanceof RepoResolutionError) {\n throw error;\n }\n\n throw new RepoResolutionError(\n `Expected \"owner/repo\" or a GitHub repository URL, received \"${input}\".`,\n \"INVALID_INPUT\",\n error,\n );\n }\n}\n\nasync function fetchRepo(octokit: Octokit, owner: string, repo: string) {\n try {\n return (await octokit.repos.get({ owner, repo })).data;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nasync function fetchLanguages(\n octokit: Octokit,\n owner: string,\n repo: string,\n): Promise<Record<string, number>> {\n try {\n const response = await octokit.repos.listLanguages({ owner, repo });\n return response.data;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nasync function fetchHeadSha(\n octokit: Octokit,\n owner: string,\n repo: string,\n defaultBranch: string,\n): Promise<string> {\n try {\n const branch = await octokit.repos.getBranch({\n owner,\n repo,\n branch: defaultBranch,\n });\n return branch.data.commit.sha;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nfunction toResolutionError(owner: string, repo: string, error: unknown): RepoResolutionError {\n const fullName = `${owner}/${repo}`;\n const status = isApiError(error) ? error.status : undefined;\n const message =\n typeof error === \"object\" && error && \"message\" in error\n ? String(error.message)\n : \"unknown error\";\n\n if (status === 404) {\n const hasToken = !!(process.env.GITHUB_TOKEN || process.env.GH_TOKEN);\n const hint = hasToken\n ? `If this is a private repo, ensure your token has the \"repo\" scope: gh auth refresh -s repo`\n : \"If this is a private repo, authenticate first: gh auth login\";\n return new RepoResolutionError(\n `Repository \"${fullName}\" was not found on GitHub. ${hint}`,\n \"NOT_FOUND\",\n error,\n );\n }\n\n if (status === 403) {\n return new RepoResolutionError(\n `Access denied for \"${fullName}\". Ensure your token has the \"repo\" scope: gh auth refresh -s repo`,\n \"FORBIDDEN\",\n error,\n );\n }\n\n return new RepoResolutionError(\n `Failed to resolve repository \"${fullName}\": ${message}`,\n \"UNKNOWN\",\n error,\n );\n}\n\nfunction normalizePermissions(\n isPrivateRepo: boolean,\n permissions:\n | {\n admin?: boolean;\n push?: boolean;\n pull?: boolean;\n }\n | undefined,\n): RepoPermissions {\n const pull = permissions?.pull ?? !isPrivateRepo;\n\n return {\n push: permissions?.push ?? false,\n pull,\n admin: permissions?.admin ?? false,\n };\n}\n\nfunction normalizeLicense(spdxId: string | null): string | null {\n if (!spdxId || spdxId === \"NOASSERTION\") {\n return null;\n }\n\n return spdxId;\n}\n\nfunction isGitHubHost(hostname: string): boolean {\n const normalized = hostname.toLowerCase();\n return normalized === \"github.com\" || normalized === \"www.github.com\";\n}\n\nfunction stripGitSuffix(repo: string): string {\n return repo.replace(/\\.git$/i, \"\");\n}\n\nfunction isApiError(error: unknown): error is { status?: number } {\n return typeof error === \"object\" && error !== null && \"status\" in error;\n}\n\nfunction defaultLocalPath(owner: string, name: string): string {\n return join(homedir(), \".oac\", \"cache\", \"repos\", owner, name);\n}\n\nfunction resolveGitHubToken(): string | undefined {\n const githubToken = process.env.GITHUB_TOKEN?.trim();\n if (githubToken) {\n process.env.GITHUB_TOKEN = githubToken;\n return githubToken;\n }\n\n const ghToken = process.env.GH_TOKEN?.trim();\n if (ghToken) {\n process.env.GITHUB_TOKEN = ghToken;\n return ghToken;\n }\n\n try {\n const token = execFileSync(\"gh\", [\"auth\", \"token\"], {\n timeout: 5_000,\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n\n if (token.length > 0) {\n process.env.GITHUB_TOKEN = token;\n return token;\n }\n } catch {\n // gh not installed or not authenticated\n }\n\n return undefined;\n}\n","import { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { ResolvedRepo } from \"./types.js\";\n\ninterface MetadataCacheEntry {\n cachedAt: number;\n repo: ResolvedRepo;\n}\n\ninterface MetadataCacheFile {\n version: 1;\n entries: Record<string, MetadataCacheEntry>;\n}\n\nexport interface MetadataCacheOptions {\n filePath?: string;\n ttlMs?: number;\n now?: () => number;\n}\n\nexport const DEFAULT_METADATA_CACHE_PATH = join(homedir(), \".oac\", \"cache\", \"repos.json\");\n\nexport const DEFAULT_METADATA_CACHE_TTL_MS = 60 * 60 * 1000;\n\nconst EMPTY_CACHE: MetadataCacheFile = {\n version: 1,\n entries: {},\n};\n\nexport class MetadataCache {\n private readonly filePath: string;\n private readonly ttlMs: number;\n private readonly now: () => number;\n\n public constructor(options: MetadataCacheOptions = {}) {\n this.filePath = expandHomePath(options.filePath ?? DEFAULT_METADATA_CACHE_PATH);\n this.ttlMs = options.ttlMs ?? DEFAULT_METADATA_CACHE_TTL_MS;\n this.now = options.now ?? Date.now;\n }\n\n public async get(fullName: string): Promise<ResolvedRepo | null> {\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n const entry = cache.entries[key];\n\n if (!entry) {\n return null;\n }\n\n if (this.now() - entry.cachedAt > this.ttlMs) {\n delete cache.entries[key];\n await this.writeCache(cache);\n return null;\n }\n\n return entry.repo;\n }\n\n public async set(fullName: string, repo: ResolvedRepo): Promise<void> {\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n cache.entries[key] = {\n cachedAt: this.now(),\n repo,\n };\n await this.writeCache(cache);\n }\n\n public async invalidate(fullName?: string): Promise<void> {\n if (!fullName) {\n await this.writeCache(EMPTY_CACHE);\n return;\n }\n\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n if (!(key in cache.entries)) {\n return;\n }\n\n delete cache.entries[key];\n await this.writeCache(cache);\n }\n\n private async readCache(): Promise<MetadataCacheFile> {\n if (!(await pathExists(this.filePath))) {\n return { ...EMPTY_CACHE, entries: {} };\n }\n\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<MetadataCacheFile>;\n\n if (parsed.version !== 1 || typeof parsed.entries !== \"object\") {\n return { ...EMPTY_CACHE, entries: {} };\n }\n\n return {\n version: 1,\n entries: parsed.entries as Record<string, MetadataCacheEntry>,\n };\n } catch {\n return { ...EMPTY_CACHE, entries: {} };\n }\n }\n\n private async writeCache(cache: MetadataCacheFile): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true });\n const tempPath = `${this.filePath}.tmp`;\n await writeFile(tempPath, JSON.stringify(cache, null, 2), \"utf8\");\n await rename(tempPath, this.filePath);\n }\n}\n\nfunction normalizeCacheKey(fullName: string): string {\n return fullName.trim().toLowerCase();\n}\n\nfunction expandHomePath(path: string): string {\n if (path === \"~\") {\n return homedir();\n }\n\n if (path.startsWith(\"~/\")) {\n return join(homedir(), path.slice(2));\n }\n\n return path;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir, rm } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport type { ResolvedRepo } from \"./types.js\";\n\nconst CLONE_RETRY_BACKOFF_MS = [1000, 4000, 16000] as const;\nconst GIT_CLONE_TIMEOUT_MS = 300_000; // 5 min rolling timeout for clone\nconst GIT_FETCH_TIMEOUT_MS = 120_000; // 2 min rolling timeout for fetch/sync\n\nexport const DEFAULT_REPO_CACHE_DIR = join(homedir(), \".oac\", \"cache\", \"repos\");\n\nexport async function cloneRepo(\n repo: ResolvedRepo,\n cacheDir: string = DEFAULT_REPO_CACHE_DIR,\n): Promise<string> {\n const cacheRoot = resolveCacheDir(cacheDir);\n const localPath = join(cacheRoot, repo.owner, repo.name);\n await mkdir(dirname(localPath), { recursive: true });\n\n if (await isGitRepository(localPath)) {\n await pullExistingClone(repo, localPath);\n } else if (await pathExists(localPath)) {\n throw new Error(\n `Cannot clone \"${repo.fullName}\" into \"${localPath}\" because the directory exists and is not a git repository.`,\n );\n } else {\n await cloneNewRepository(repo, localPath);\n }\n\n const git = createGit(localPath);\n repo.localPath = localPath;\n repo.worktreePath = join(localPath, \"..\", \".oac-worktrees\", repo.meta.defaultBranch);\n repo.git.headSha = (await git.revparse([\"HEAD\"])).trim();\n repo.git.isShallowClone = await isShallowClone(git);\n repo.git.remoteUrl = await getOriginUrl(git, repo.git.remoteUrl);\n\n return localPath;\n}\n\nasync function cloneNewRepository(repo: ResolvedRepo, localPath: string): Promise<void> {\n const git = createGit(undefined, GIT_CLONE_TIMEOUT_MS);\n const cloneArgs = [\"--depth\", \"1\", \"--branch\", repo.meta.defaultBranch];\n\n try {\n await retryGitOperation(\n () => git.clone(repo.git.remoteUrl, localPath, cloneArgs),\n `clone ${repo.fullName}`,\n );\n } catch (httpsError) {\n if (!repo.git.sshUrl) throw httpsError;\n\n // HTTPS failed — try SSH (e.g. user has SSH keys but no HTTPS credentials)\n await cleanPartialClone(localPath);\n try {\n await retryGitOperation(\n () => git.clone(repo.git.sshUrl!, localPath, cloneArgs),\n `clone ${repo.fullName} (SSH fallback)`,\n );\n } catch (sshError) {\n throw new Error(\n `Failed to clone \"${repo.fullName}\" via both HTTPS and SSH.\\nEnsure git credentials are configured: run \\`gh auth login\\` or set up SSH keys.\\nHTTPS error: ${httpsError instanceof Error ? httpsError.message : httpsError}\\nSSH error: ${sshError instanceof Error ? sshError.message : sshError}`,\n { cause: sshError },\n );\n }\n }\n}\n\nasync function pullExistingClone(repo: ResolvedRepo, localPath: string): Promise<void> {\n const git = createGit(localPath);\n await ensureOriginRemote(git, repo.git.remoteUrl);\n\n try {\n await retryGitOperation(\n () => git.fetch(\"origin\", repo.meta.defaultBranch, [\"--depth=1\", \"--prune\"]),\n `fetch ${repo.fullName}`,\n );\n } catch (fetchError) {\n if (!repo.git.sshUrl) throw fetchError;\n\n // HTTPS fetch failed — switch remote to SSH and retry\n await ensureOriginRemote(git, repo.git.sshUrl);\n await retryGitOperation(\n () => git.fetch(\"origin\", repo.meta.defaultBranch, [\"--depth=1\", \"--prune\"]),\n `fetch ${repo.fullName} (SSH fallback)`,\n );\n }\n\n await checkoutDefaultBranch(git, repo.meta.defaultBranch);\n\n await retryGitOperation(\n () => hardSyncDefaultBranch(git, repo.meta.defaultBranch),\n `sync ${repo.fullName}`,\n );\n}\n\nasync function checkoutDefaultBranch(git: SimpleGit, branchName: string): Promise<void> {\n try {\n await git.checkout(branchName);\n } catch {\n await git.raw([\"checkout\", \"-B\", branchName, `origin/${branchName}`]);\n }\n}\n\nasync function hardSyncDefaultBranch(git: SimpleGit, branchName: string): Promise<void> {\n // The cache clone is disposable, so force-align it with origin to avoid stale divergence.\n await git.raw([\"reset\", \"--hard\", `origin/${branchName}`]);\n await git.raw([\"clean\", \"-fd\"]);\n}\n\nasync function ensureOriginRemote(git: SimpleGit, remoteUrl: string): Promise<void> {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((remote) => remote.name === \"origin\");\n\n if (!origin) {\n await git.addRemote(\"origin\", remoteUrl);\n return;\n }\n\n if (origin.refs.fetch !== remoteUrl && origin.refs.push !== remoteUrl) {\n await git.remote([\"set-url\", \"origin\", remoteUrl]);\n }\n}\n\nasync function getOriginUrl(git: SimpleGit, fallbackUrl: string): Promise<string> {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((remote) => remote.name === \"origin\");\n return origin?.refs.fetch ?? fallbackUrl;\n}\n\nasync function isShallowClone(git: SimpleGit): Promise<boolean> {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n}\n\nasync function retryGitOperation<T>(\n operation: () => Promise<T>,\n operationName: string,\n): Promise<T> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= CLONE_RETRY_BACKOFF_MS.length; attempt += 1) {\n try {\n return await operation();\n } catch (error) {\n lastError = error;\n if (attempt === CLONE_RETRY_BACKOFF_MS.length) {\n break;\n }\n await sleep(CLONE_RETRY_BACKOFF_MS[attempt]);\n }\n }\n\n throw new Error(\n `Git operation failed after ${CLONE_RETRY_BACKOFF_MS.length + 1} attempts (${operationName}).`,\n { cause: lastError },\n );\n}\n\nfunction resolveCacheDir(cacheDir: string): string {\n const selected = cacheDir.trim().length > 0 ? cacheDir : DEFAULT_REPO_CACHE_DIR;\n return resolve(expandHomePath(selected));\n}\n\nfunction expandHomePath(path: string): string {\n if (path === \"~\") {\n return homedir();\n }\n\n if (path.startsWith(\"~/\")) {\n return join(homedir(), path.slice(2));\n }\n\n return path;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isGitRepository(path: string): Promise<boolean> {\n return pathExists(join(path, \".git\"));\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolvePromise) => {\n setTimeout(resolvePromise, ms);\n });\n}\n\n/**\n * Create a `SimpleGit` instance with `GIT_TERMINAL_PROMPT=0` (prevents\n * silent credential prompts that hang forever) and a rolling timeout that\n * kills the spawned process if it produces no output for `timeoutMs`.\n *\n * NOTE: `simple-git`'s `.env(key, value)` **replaces** the entire process\n * environment. We must spread `process.env` so the child git process still\n * has `HOME`, `PATH`, `SSH_AUTH_SOCK`, etc.\n */\nfunction createGit(baseDir?: string, timeoutMs = GIT_FETCH_TIMEOUT_MS): SimpleGit {\n return simpleGit({\n ...(baseDir ? { baseDir } : {}),\n timeout: { block: timeoutMs },\n }).env({ ...process.env, GIT_TERMINAL_PROMPT: \"0\" });\n}\n\nasync function cleanPartialClone(localPath: string): Promise<void> {\n try {\n await rm(localPath, { recursive: true, force: true });\n } catch {\n /* best-effort cleanup before SSH retry */\n }\n}\n"],"mappings":"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","names":["homedir","join","join","homedir","fsConstants","access","mkdir","homedir","dirname","join","pathExists","expandHomePath"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createMemoryMonitor,
3
3
  truncate
4
- } from "./chunk-6A37SKAJ.js";
4
+ } from "./chunk-JDFAJP45.js";
5
5
 
6
6
  // src/discovery/scanners/todo-scanner.ts
7
7
  import { spawn } from "child_process";
@@ -1811,8 +1811,8 @@ function clamp(value, min, max) {
1811
1811
  // src/discovery/analyzer.ts
1812
1812
  import { createReadStream } from "fs";
1813
1813
  import { mkdir, readFile as readFile5, readdir as readdir3, rename, stat as stat2, unlink, writeFile } from "fs/promises";
1814
- import { createInterface } from "readline";
1815
1814
  import { dirname, extname, join, relative as relative3, resolve as resolve5 } from "path";
1815
+ import { createInterface } from "readline";
1816
1816
  import PQueue from "p-queue";
1817
1817
  var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx"]);
1818
1818
  var DEFAULT_EXCLUDE_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", ".git", "coverage"]);
@@ -2420,4 +2420,4 @@ export {
2420
2420
  updateBacklog,
2421
2421
  getPendingEpics
2422
2422
  };
2423
- //# sourceMappingURL=chunk-OCCMKAJI.js.map
2423
+ //# sourceMappingURL=chunk-ZJBLRKCV.js.map