@open330/oac 2026.221.1 → 2026.222.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.
- package/dist/budget/index.js +1 -1
- package/dist/{chunk-5GAUWC3L.js → chunk-ALBVUNUY.js} +1 -1
- package/dist/chunk-ALBVUNUY.js.map +1 -0
- package/dist/{chunk-E2C46KPJ.js → chunk-GPHH2IYN.js} +81 -78
- package/dist/chunk-GPHH2IYN.js.map +1 -0
- package/dist/{chunk-6A37SKAJ.js → chunk-JDFAJP45.js} +1 -1
- package/dist/{chunk-6A37SKAJ.js.map → chunk-JDFAJP45.js.map} +1 -1
- package/dist/{chunk-EYUQMPVO.js → chunk-JROCVTM7.js} +51 -33
- package/dist/chunk-JROCVTM7.js.map +1 -0
- package/dist/{chunk-OS3XDHOJ.js → chunk-UCYK4Z6O.js} +1 -1
- package/dist/chunk-UCYK4Z6O.js.map +1 -0
- package/dist/{chunk-6JEFW6B7.js → chunk-ZJBLRKCV.js} +13 -4
- package/dist/chunk-ZJBLRKCV.js.map +1 -0
- package/dist/cli/cli.js +6 -6
- package/dist/cli/index.js +6 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/completion/index.js +1 -1
- package/dist/completion/index.js.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/dashboard/index.js +23 -20
- package/dist/dashboard/index.js.map +1 -1
- package/dist/discovery/index.d.ts +5 -0
- package/dist/discovery/index.js +2 -2
- package/dist/execution/index.js +2 -2
- package/dist/repo/index.js +1 -1
- package/package.json +13 -15
- package/dist/chunk-5GAUWC3L.js.map +0 -1
- package/dist/chunk-6JEFW6B7.js.map +0 -1
- package/dist/chunk-E2C46KPJ.js.map +0 -1
- package/dist/chunk-EYUQMPVO.js.map +0 -1
- package/dist/chunk-OS3XDHOJ.js.map +0 -1
package/dist/budget/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/budget/complexity.ts","../src/budget/estimator.ts","../src/budget/providers/claude-counter.ts","../src/budget/providers/codex-counter.ts","../src/budget/planner.ts"],"sourcesContent":["import type { Task, TaskComplexity, TaskSource } from \"./estimator.js\";\n\nconst SOURCE_LOC_BASELINE: Record<TaskSource, number> = {\n lint: 8,\n todo: 16,\n \"test-gap\": 48,\n \"dead-code\": 36,\n \"github-issue\": 88,\n custom: 40,\n};\n\nconst SOURCE_COMPLEXITY_SCORE: Record<TaskSource, number> = {\n lint: 0,\n todo: 0,\n \"test-gap\": 1,\n \"dead-code\": 1,\n \"github-issue\": 2,\n custom: 1,\n};\n\nconst ESTIMATED_LOC_KEYS = [\n \"estimatedLoc\",\n \"estimatedLOC\",\n \"estimatedLocChanges\",\n \"estimatedDiffSize\",\n \"loc\",\n \"locChanges\",\n \"linesChanged\",\n \"lineCount\",\n \"diffSize\",\n \"changeSize\",\n] as const;\n\nfunction parseNumericValue(value: unknown): number | undefined {\n if (typeof value === \"number\" && Number.isFinite(value) && value >= 0) {\n return value;\n }\n\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (Number.isFinite(parsed) && parsed >= 0) {\n return parsed;\n }\n }\n\n return undefined;\n}\n\nfunction readMetadataLocEstimate(metadata: Record<string, unknown>): number | undefined {\n for (const key of ESTIMATED_LOC_KEYS) {\n const directValue = parseNumericValue(metadata[key]);\n if (directValue !== undefined) {\n return directValue;\n }\n }\n\n const metrics = metadata.metrics;\n if (metrics && typeof metrics === \"object\" && !Array.isArray(metrics)) {\n const metricsRecord = metrics as Record<string, unknown>;\n for (const key of ESTIMATED_LOC_KEYS) {\n const metricValue = parseNumericValue(metricsRecord[key]);\n if (metricValue !== undefined) {\n return metricValue;\n }\n }\n }\n\n return undefined;\n}\n\nexport function estimateLocChanges(task: Task): number {\n const metadataEstimate = readMetadataLocEstimate(task.metadata);\n if (metadataEstimate !== undefined) {\n return Math.max(1, Math.round(metadataEstimate));\n }\n\n const sourceBaseline = SOURCE_LOC_BASELINE[task.source] ?? SOURCE_LOC_BASELINE.custom;\n const fileAdjustment = Math.max(task.targetFiles.length, 1) * 8;\n\n return Math.max(sourceBaseline, fileAdjustment);\n}\n\nexport function analyzeTaskComplexity(task: Task): TaskComplexity {\n const fileCount = task.targetFiles.length;\n const locChanges = estimateLocChanges(task);\n\n const fileScore = fileCount <= 1 ? 0 : fileCount <= 3 ? 1 : fileCount <= 6 ? 2 : 3;\n const locScore = locChanges <= 20 ? 0 : locChanges <= 80 ? 1 : locChanges <= 200 ? 2 : 3;\n const sourceScore = SOURCE_COMPLEXITY_SCORE[task.source] ?? SOURCE_COMPLEXITY_SCORE.custom;\n\n const totalScore = fileScore + locScore + sourceScore;\n\n if (totalScore <= 1) {\n return \"trivial\";\n }\n\n if (totalScore <= 3) {\n return \"simple\";\n }\n\n if (totalScore <= 6) {\n return \"moderate\";\n }\n\n return \"complex\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport { isAbsolute, resolve } from \"node:path\";\n\nimport PQueue from \"p-queue\";\nimport type { Epic } from \"../core/types.js\";\nimport { analyzeTaskComplexity } from \"./complexity.js\";\nimport { ClaudeTokenCounter } from \"./providers/claude-counter.js\";\nimport { CodexTokenCounter } from \"./providers/codex-counter.js\";\n\nexport type AgentProviderId = \"claude-code\" | \"codex\" | \"opencode\" | string;\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}\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 TokenCounter {\n countTokens(text: string): number;\n readonly invocationOverhead: number;\n readonly maxContextTokens: number;\n /** Free any cached resources (e.g. tiktoken encoders). Optional. */\n reset?(): void;\n}\n\ninterface TokenCountResult {\n tokens: number;\n usedFallback: boolean;\n}\n\ninterface ContextFileResult extends TokenCountResult {\n missing: boolean;\n}\n\nconst ESTIMATION_PADDING_MULTIPLIER = 1.2;\nconst FALLBACK_CONFIDENCE = 0.5;\n\nconst COMPLEXITY_MULTIPLIERS: Record<TaskComplexity, number> = {\n trivial: 0.5,\n simple: 1,\n moderate: 2,\n complex: 3.5,\n};\n\nconst COMPLEXITY_CONFIDENCE: Record<TaskComplexity, number> = {\n trivial: 0.9,\n simple: 0.75,\n moderate: 0.6,\n complex: 0.4,\n};\n\nconst COMPLEXITY_ORDER: Record<TaskComplexity, number> = {\n trivial: 0,\n simple: 1,\n moderate: 2,\n complex: 3,\n};\n\nconst claudeCounter = new ClaudeTokenCounter();\nconst codexCounter = new CodexTokenCounter();\n\n/**\n * Free cached tiktoken encoders held by the module-level counter singletons.\n * Useful for reclaiming memory in long-lived processes or between test runs.\n */\nexport function resetCounters(): void {\n claudeCounter.reset();\n codexCounter.reset();\n}\n\nfunction getTokenCounter(provider: AgentProviderId): TokenCounter {\n if (provider === \"claude-code\") {\n return claudeCounter;\n }\n\n return codexCounter;\n}\n\nfunction approximateTokenCount(text: string): number {\n if (text.length === 0) {\n return 0;\n }\n\n return Math.max(1, Math.ceil(text.length / 4));\n}\n\nfunction countTokensWithFallback(text: string, counter: TokenCounter): TokenCountResult {\n try {\n return {\n tokens: counter.countTokens(text),\n usedFallback: false,\n };\n } catch {\n return {\n tokens: approximateTokenCount(text),\n usedFallback: true,\n };\n }\n}\n\nfunction chooseConservativeComplexity(\n declaredComplexity: TaskComplexity,\n analyzedComplexity: TaskComplexity,\n): TaskComplexity {\n return COMPLEXITY_ORDER[declaredComplexity] >= COMPLEXITY_ORDER[analyzedComplexity]\n ? declaredComplexity\n : analyzedComplexity;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n if (value < min) {\n return min;\n }\n\n if (value > max) {\n return max;\n }\n\n return value;\n}\n\nfunction resolveTargetFilePath(targetFile: string): string {\n return isAbsolute(targetFile) ? targetFile : resolve(process.cwd(), targetFile);\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n const serialized = JSON.stringify(value);\n return serialized ?? \"null\";\n } catch {\n return \"[unserializable]\";\n }\n}\n\nasync function readContextFile(\n targetFile: string,\n counter: TokenCounter,\n): Promise<ContextFileResult> {\n const resolvedPath = resolveTargetFilePath(targetFile);\n\n try {\n const content = await readFile(resolvedPath, \"utf8\");\n const counted = countTokensWithFallback(content, counter);\n\n return {\n ...counted,\n missing: false,\n };\n } catch {\n return {\n tokens: 0,\n usedFallback: false,\n missing: true,\n };\n }\n}\n\nexport async function estimateTokens(\n task: Task,\n provider: AgentProviderId,\n): Promise<TokenEstimate> {\n const counter = getTokenCounter(provider);\n const uniqueTargetFiles = [...new Set(task.targetFiles)];\n\n const fileQueue = new PQueue({ concurrency: 50 });\n const fileResults = await Promise.all(\n uniqueTargetFiles.map(\n (targetFile) =>\n fileQueue.add(() => readContextFile(targetFile, counter)) as Promise<ContextFileResult>,\n ),\n );\n\n const repoStructureSeed = uniqueTargetFiles.join(\"\\n\");\n const repoStructureCount = countTokensWithFallback(repoStructureSeed, counter);\n\n const contextTokens =\n repoStructureCount.tokens + fileResults.reduce((sum, result) => sum + result.tokens, 0);\n\n const promptSeed = [\n `Task ID: ${task.id}`,\n `Title: ${task.title}`,\n `Source: ${task.source}`,\n `Priority: ${task.priority}`,\n `Description:\\n${task.description}`,\n `Target Files:\\n${uniqueTargetFiles.join(\"\\n\") || \"(none)\"}`,\n `Metadata: ${safeStringify(task.metadata)}`,\n ].join(\"\\n\\n\");\n\n const promptContentCount = countTokensWithFallback(promptSeed, counter);\n const promptTokens = counter.invocationOverhead + promptContentCount.tokens;\n\n const analyzedComplexity = analyzeTaskComplexity(task);\n const effectiveComplexity = chooseConservativeComplexity(task.complexity, analyzedComplexity);\n const expectedOutputTokens = Math.ceil(\n contextTokens * COMPLEXITY_MULTIPLIERS[effectiveComplexity],\n );\n\n const rawTotalTokens = contextTokens + promptTokens + expectedOutputTokens;\n const totalEstimatedTokens = Math.ceil(rawTotalTokens * ESTIMATION_PADDING_MULTIPLIER);\n\n const usedFallback =\n repoStructureCount.usedFallback ||\n promptContentCount.usedFallback ||\n fileResults.some((result) => result.usedFallback);\n\n const missingFileCount = fileResults.filter((result) => result.missing).length;\n\n let confidence = COMPLEXITY_CONFIDENCE[effectiveComplexity];\n if (usedFallback) {\n confidence = Math.min(confidence, FALLBACK_CONFIDENCE);\n }\n\n if (missingFileCount > 0) {\n confidence -= Math.min(0.25, missingFileCount * 0.05);\n }\n\n if (uniqueTargetFiles.length === 0) {\n confidence -= 0.1;\n }\n\n if (task.complexity !== analyzedComplexity) {\n confidence -= 0.05;\n }\n\n const feasible = totalEstimatedTokens <= counter.maxContextTokens;\n\n return {\n taskId: task.id,\n providerId: provider,\n contextTokens,\n promptTokens,\n expectedOutputTokens,\n totalEstimatedTokens,\n confidence: clamp(confidence, 0.1, 0.95),\n feasible,\n };\n}\n\n// ── Epic token estimation ────────────────────────────────────\n\nconst EPIC_CONTEXT_OVERHEAD = 1.2; // 20% overhead for shared module understanding\n\n/**\n * Estimate tokens for an entire epic by summing subtask estimates\n * plus a 20% context overhead for shared module understanding.\n */\nexport async function estimateEpicTokens(epic: Epic, provider: AgentProviderId): Promise<number> {\n if (epic.subtasks.length === 0) {\n return 0;\n }\n\n const epicQueue = new PQueue({ concurrency: 10 });\n const subtaskEstimates = await Promise.all(\n epic.subtasks.map(\n (task) => epicQueue.add(() => estimateTokens(task, provider)) as Promise<TokenEstimate>,\n ),\n );\n\n const subtaskTotal = subtaskEstimates.reduce(\n (sum, estimate) => sum + estimate.totalEstimatedTokens,\n 0,\n );\n\n return Math.ceil(subtaskTotal * EPIC_CONTEXT_OVERHEAD);\n}\n","import { type Tiktoken, get_encoding } from \"tiktoken\";\n\nconst CLAUDE_ENCODING = \"cl100k_base\";\nconst CLAUDE_INVOCATION_OVERHEAD = 1_500;\nconst CLAUDE_MAX_CONTEXT_TOKENS = 200_000;\n\nlet encoder: Tiktoken | undefined;\n\nfunction getEncoder(): Tiktoken {\n encoder ??= get_encoding(CLAUDE_ENCODING);\n return encoder;\n}\n\nexport class ClaudeTokenCounter {\n readonly invocationOverhead = CLAUDE_INVOCATION_OVERHEAD;\n readonly maxContextTokens = CLAUDE_MAX_CONTEXT_TOKENS;\n readonly encoding = CLAUDE_ENCODING;\n\n countTokens(text: string): number {\n return getEncoder().encode(text).length;\n }\n\n /** Free the cached tiktoken encoder so it can be re-created on next use. */\n reset(): void {\n if (encoder) {\n encoder.free();\n encoder = undefined;\n }\n }\n}\n","import { type Tiktoken, get_encoding } from \"tiktoken\";\n\nconst CODEX_INVOCATION_OVERHEAD = 1_000;\nconst CODEX_MAX_CONTEXT_TOKENS = 200_000;\nconst PRIMARY_ENCODING = \"o200k_base\";\nconst FALLBACK_ENCODING = \"cl100k_base\";\n\ntype SupportedCodexEncoding = typeof PRIMARY_ENCODING | typeof FALLBACK_ENCODING;\n\nlet encoder: Tiktoken | undefined;\nlet selectedEncoding: SupportedCodexEncoding | undefined;\n\nfunction getEncoder(): Tiktoken {\n if (encoder) {\n return encoder;\n }\n\n try {\n encoder = get_encoding(PRIMARY_ENCODING);\n selectedEncoding = PRIMARY_ENCODING;\n } catch {\n encoder = get_encoding(FALLBACK_ENCODING);\n selectedEncoding = FALLBACK_ENCODING;\n }\n\n return encoder;\n}\n\nexport class CodexTokenCounter {\n readonly invocationOverhead = CODEX_INVOCATION_OVERHEAD;\n readonly maxContextTokens = CODEX_MAX_CONTEXT_TOKENS;\n\n get encoding(): SupportedCodexEncoding {\n getEncoder();\n return selectedEncoding ?? FALLBACK_ENCODING;\n }\n\n countTokens(text: string): number {\n return getEncoder().encode(text).length;\n }\n\n /** Free the cached tiktoken encoder so it can be re-created on next use. */\n reset(): void {\n if (encoder) {\n encoder.free();\n encoder = undefined;\n }\n selectedEncoding = undefined;\n }\n}\n","import type { Epic } from \"../core/types.js\";\nimport type { AgentProviderId, Task, TokenEstimate } from \"./estimator.js\";\n\nconst DEFAULT_RESERVE_PERCENT = 0.1;\nconst MIN_CONFIDENCE_THRESHOLD = 0.5;\nconst TOO_COMPLEX_BUDGET_SHARE = 0.6;\n\ntype DeferredReason = \"budget_exceeded\" | \"low_confidence\" | \"too_complex\";\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: DeferredReason;\n }>;\n reserveTokens: number;\n remainingTokens: number;\n}\n\ninterface CandidateTask {\n task: Task;\n estimate: TokenEstimate;\n}\n\nfunction normalizeBudget(budget: number): number {\n if (!Number.isFinite(budget) || budget <= 0) {\n return 0;\n }\n\n return Math.floor(budget);\n}\n\nfunction getFallbackEstimate(task: Task): TokenEstimate {\n return {\n taskId: task.id,\n providerId: \"unknown\" as AgentProviderId,\n contextTokens: 0,\n promptTokens: 0,\n expectedOutputTokens: 0,\n totalEstimatedTokens: Number.MAX_SAFE_INTEGER,\n confidence: 0,\n feasible: false,\n };\n}\n\nfunction classifyDeferredReason(\n task: Task,\n estimate: TokenEstimate,\n effectiveBudget: number,\n): DeferredReason | undefined {\n if (!estimate.feasible) {\n return \"budget_exceeded\";\n }\n\n if (estimate.confidence < MIN_CONFIDENCE_THRESHOLD) {\n return \"low_confidence\";\n }\n\n if (\n task.complexity === \"complex\" &&\n effectiveBudget > 0 &&\n estimate.totalEstimatedTokens > effectiveBudget * TOO_COMPLEX_BUDGET_SHARE\n ) {\n return \"too_complex\";\n }\n\n return undefined;\n}\n\nfunction scoreByPriorityPerToken(task: Task, estimate: TokenEstimate): number {\n if (estimate.totalEstimatedTokens <= 0) {\n return task.priority;\n }\n\n return task.priority / estimate.totalEstimatedTokens;\n}\n\nexport function buildExecutionPlan(\n tasks: Task[],\n estimates: Map<string, TokenEstimate>,\n budget: number,\n): ExecutionPlan {\n const totalBudget = normalizeBudget(budget);\n const reserveTokens = Math.floor(totalBudget * DEFAULT_RESERVE_PERCENT);\n const effectiveBudget = Math.max(0, totalBudget - reserveTokens);\n\n const deferredTasks: ExecutionPlan[\"deferredTasks\"] = [];\n const candidates: CandidateTask[] = [];\n\n for (const task of tasks) {\n const estimate = estimates.get(task.id) ?? getFallbackEstimate(task);\n const reason = classifyDeferredReason(task, estimate, effectiveBudget);\n\n if (reason) {\n deferredTasks.push({ task, estimate, reason });\n continue;\n }\n\n candidates.push({ task, estimate });\n }\n\n candidates.sort((left, right) => {\n const ratioDifference =\n scoreByPriorityPerToken(right.task, right.estimate) -\n scoreByPriorityPerToken(left.task, left.estimate);\n\n if (ratioDifference !== 0) {\n return ratioDifference;\n }\n\n const priorityDifference = right.task.priority - left.task.priority;\n if (priorityDifference !== 0) {\n return priorityDifference;\n }\n\n return left.estimate.totalEstimatedTokens - right.estimate.totalEstimatedTokens;\n });\n\n const selectedTasks: ExecutionPlan[\"selectedTasks\"] = [];\n let budgetUsed = 0;\n\n for (const candidate of candidates) {\n const nextBudgetUsed = budgetUsed + candidate.estimate.totalEstimatedTokens;\n\n if (nextBudgetUsed <= effectiveBudget) {\n budgetUsed = nextBudgetUsed;\n selectedTasks.push({\n task: candidate.task,\n estimate: candidate.estimate,\n cumulativeBudgetUsed: budgetUsed,\n });\n continue;\n }\n\n deferredTasks.push({\n task: candidate.task,\n estimate: candidate.estimate,\n reason: \"budget_exceeded\",\n });\n }\n\n return {\n totalBudget,\n selectedTasks,\n deferredTasks,\n reserveTokens,\n remainingTokens: Math.max(0, effectiveBudget - budgetUsed),\n };\n}\n\n// ── Epic execution plan ─────────────────────────────────────\n\nexport interface EpicExecutionPlan {\n totalBudget: number;\n selectedEpics: Array<{\n epic: Epic;\n estimatedTokens: number;\n cumulativeBudgetUsed: number;\n }>;\n deferredEpics: Array<{\n epic: Epic;\n estimatedTokens: number;\n reason: \"budget_exceeded\";\n }>;\n reserveTokens: number;\n remainingTokens: number;\n}\n\n/**\n * Build an execution plan for epics. Unlike task-level planning, epics are\n * sorted purely by priority (not priority/tokens ratio) since they are\n * already coherent units of work.\n */\nexport function buildEpicExecutionPlan(epics: Epic[], budget: number): EpicExecutionPlan {\n const totalBudget = normalizeBudget(budget);\n const reserveTokens = Math.floor(totalBudget * DEFAULT_RESERVE_PERCENT);\n const effectiveBudget = Math.max(0, totalBudget - reserveTokens);\n\n // Sort by priority descending (highest priority first)\n const sorted = [...epics].sort((a, b) => b.priority - a.priority);\n\n const selectedEpics: EpicExecutionPlan[\"selectedEpics\"] = [];\n const deferredEpics: EpicExecutionPlan[\"deferredEpics\"] = [];\n let budgetUsed = 0;\n\n for (const epic of sorted) {\n const tokens = epic.estimatedTokens;\n const nextBudgetUsed = budgetUsed + tokens;\n\n if (nextBudgetUsed <= effectiveBudget) {\n budgetUsed = nextBudgetUsed;\n selectedEpics.push({\n epic,\n estimatedTokens: tokens,\n cumulativeBudgetUsed: budgetUsed,\n });\n } else {\n deferredEpics.push({\n epic,\n estimatedTokens: tokens,\n reason: \"budget_exceeded\",\n });\n }\n }\n\n return {\n totalBudget,\n selectedEpics,\n deferredEpics,\n reserveTokens,\n remainingTokens: Math.max(0, effectiveBudget - budgetUsed),\n };\n}\n"],"mappings":"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","names":["get_encoding","encoder","getEncoder"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cloneRepo,
|
|
3
3
|
resolveRepo
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UCYK4Z6O.js";
|
|
5
5
|
import {
|
|
6
6
|
CompositeScanner,
|
|
7
7
|
GitHubIssuesScanner,
|
|
@@ -20,19 +20,19 @@ import {
|
|
|
20
20
|
persistContext,
|
|
21
21
|
rankTasks,
|
|
22
22
|
updateBacklog
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-ZJBLRKCV.js";
|
|
24
24
|
import {
|
|
25
25
|
buildEpicExecutionPlan,
|
|
26
26
|
buildExecutionPlan,
|
|
27
27
|
estimateEpicTokens,
|
|
28
28
|
estimateTokens
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-ALBVUNUY.js";
|
|
30
30
|
import {
|
|
31
31
|
adapterRegistry,
|
|
32
32
|
createSandbox,
|
|
33
33
|
epicAsTask,
|
|
34
34
|
executeTask
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-JROCVTM7.js";
|
|
36
36
|
import {
|
|
37
37
|
UNLIMITED_BUDGET,
|
|
38
38
|
createEventBus,
|
|
@@ -41,18 +41,18 @@ import {
|
|
|
41
41
|
import {
|
|
42
42
|
isRecord,
|
|
43
43
|
truncate
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-JDFAJP45.js";
|
|
45
45
|
import {
|
|
46
46
|
contributionLogSchema,
|
|
47
47
|
writeContributionLog
|
|
48
48
|
} from "./chunk-LQC5DLT7.js";
|
|
49
49
|
|
|
50
50
|
// src/cli/cli.ts
|
|
51
|
-
import { Command as
|
|
51
|
+
import { Command as Command12 } from "commander";
|
|
52
52
|
|
|
53
53
|
// src/cli/commands/analyze.ts
|
|
54
54
|
import Table from "cli-table3";
|
|
55
|
-
import { Command
|
|
55
|
+
import { Command } from "commander";
|
|
56
56
|
|
|
57
57
|
// src/cli/github-auth.ts
|
|
58
58
|
import { execFileSync, spawnSync } from "child_process";
|
|
@@ -100,7 +100,6 @@ function checkGitHubScopes(required = ["repo"]) {
|
|
|
100
100
|
|
|
101
101
|
// src/cli/helpers.ts
|
|
102
102
|
import chalk, { Chalk } from "chalk";
|
|
103
|
-
import "commander";
|
|
104
103
|
import ora from "ora";
|
|
105
104
|
import PQueue from "p-queue";
|
|
106
105
|
|
|
@@ -269,10 +268,8 @@ async function estimateTaskMap(tasks, providerId, onProgress) {
|
|
|
269
268
|
|
|
270
269
|
// src/cli/commands/analyze.ts
|
|
271
270
|
function createAnalyzeCommand() {
|
|
272
|
-
const command = new
|
|
273
|
-
command.description(
|
|
274
|
-
"Deep codebase analysis \u2014 build module graph and group findings into epics"
|
|
275
|
-
).option("--repo <owner/repo>", "Target repository (owner/repo or GitHub URL)").option("--force", "Force re-analysis even if context is fresh", false).option("--format <format>", "Output format: table|json", "table").action(async (options, cmd) => {
|
|
271
|
+
const command = new Command("analyze");
|
|
272
|
+
command.description("Deep codebase analysis \u2014 build module graph and group findings into epics").option("--repo <owner/repo>", "Target repository (owner/repo or GitHub URL)").option("--force", "Force re-analysis even if context is fresh", false).option("--format <format>", "Output format: table|json", "table").action(async (options, cmd) => {
|
|
276
273
|
const globalOptions = getGlobalOptions(cmd);
|
|
277
274
|
const ui = createUi(globalOptions);
|
|
278
275
|
const outputJson = globalOptions.json || normalizeOutputFormat(options.format) === "json";
|
|
@@ -379,7 +376,7 @@ function buildScannerList(config, hasGitHubAuth) {
|
|
|
379
376
|
}
|
|
380
377
|
|
|
381
378
|
// src/cli/commands/completion.ts
|
|
382
|
-
import { Command as
|
|
379
|
+
import { Command as Command2 } from "commander";
|
|
383
380
|
var SUBCOMMANDS = [
|
|
384
381
|
"init",
|
|
385
382
|
"analyze",
|
|
@@ -392,7 +389,15 @@ var SUBCOMMANDS = [
|
|
|
392
389
|
"status",
|
|
393
390
|
"completion"
|
|
394
391
|
];
|
|
395
|
-
var GLOBAL_OPTIONS = [
|
|
392
|
+
var GLOBAL_OPTIONS = [
|
|
393
|
+
"--config",
|
|
394
|
+
"--verbose",
|
|
395
|
+
"--quiet",
|
|
396
|
+
"--json",
|
|
397
|
+
"--no-color",
|
|
398
|
+
"--help",
|
|
399
|
+
"--version"
|
|
400
|
+
];
|
|
396
401
|
var COMMAND_OPTIONS = {
|
|
397
402
|
run: [
|
|
398
403
|
"--repo",
|
|
@@ -477,17 +482,19 @@ function generateFish() {
|
|
|
477
482
|
for (const [cmd, opts] of Object.entries(COMMAND_OPTIONS)) {
|
|
478
483
|
for (const opt of opts) {
|
|
479
484
|
const long = opt.replace(/^--/, "");
|
|
480
|
-
lines.push(
|
|
481
|
-
`complete -c oac -n '__fish_seen_subcommand_from ${cmd}' -l '${long}'`
|
|
482
|
-
);
|
|
485
|
+
lines.push(`complete -c oac -n '__fish_seen_subcommand_from ${cmd}' -l '${long}'`);
|
|
483
486
|
}
|
|
484
487
|
}
|
|
485
488
|
return lines.join("\n");
|
|
486
489
|
}
|
|
487
490
|
function createCompletionCommand() {
|
|
488
|
-
const command = new
|
|
491
|
+
const command = new Command2("completion");
|
|
489
492
|
command.description("Generate shell completion scripts").argument("<shell>", "Shell type: bash, zsh, or fish").action((shell) => {
|
|
490
|
-
const generators = {
|
|
493
|
+
const generators = {
|
|
494
|
+
bash: generateBash,
|
|
495
|
+
zsh: generateZsh,
|
|
496
|
+
fish: generateFish
|
|
497
|
+
};
|
|
491
498
|
const gen = generators[shell];
|
|
492
499
|
if (!gen) {
|
|
493
500
|
throw new Error(`Unsupported shell "${shell}". Supported: bash, zsh, fish`);
|
|
@@ -506,10 +513,10 @@ Examples:
|
|
|
506
513
|
}
|
|
507
514
|
|
|
508
515
|
// src/cli/commands/doctor.ts
|
|
509
|
-
import { Command as
|
|
516
|
+
import { Command as Command3 } from "commander";
|
|
510
517
|
var MINIMUM_NODE_VERSION = "24.0.0";
|
|
511
518
|
function createDoctorCommand() {
|
|
512
|
-
const command = new
|
|
519
|
+
const command = new Command3("doctor");
|
|
513
520
|
command.description("Check local environment readiness").action(async (_options, cmd) => {
|
|
514
521
|
const globalOptions = getGlobalOptions(cmd);
|
|
515
522
|
const ui = createUi(globalOptions);
|
|
@@ -749,9 +756,9 @@ async function runCommand(command, args) {
|
|
|
749
756
|
|
|
750
757
|
// src/cli/commands/explain.ts
|
|
751
758
|
import { resolve as resolve2 } from "path";
|
|
752
|
-
import { Command as
|
|
759
|
+
import { Command as Command4 } from "commander";
|
|
753
760
|
function createExplainCommand() {
|
|
754
|
-
const command = new
|
|
761
|
+
const command = new Command4("explain");
|
|
755
762
|
command.description("Explain why a task or epic was selected and what the agent would do").argument("<id>", "Task or epic ID (from scan / analyze / run --dry-run output)").action(async (id, _options, cmd) => {
|
|
756
763
|
const globalOptions = getGlobalOptions(cmd);
|
|
757
764
|
const ui = createUi(globalOptions);
|
|
@@ -833,11 +840,13 @@ function createExplainCommand() {
|
|
|
833
840
|
console.log(` ${finding.description}`);
|
|
834
841
|
console.log("");
|
|
835
842
|
console.log(ui.dim("What the agent would do:"));
|
|
836
|
-
console.log(
|
|
837
|
-
console.log(
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
console.log(
|
|
843
|
+
console.log(" 1. Check out a clean branch for this task");
|
|
844
|
+
console.log(
|
|
845
|
+
` 2. Open ${finding.filePath}${finding.line ? ` at line ${finding.line}` : ""}`
|
|
846
|
+
);
|
|
847
|
+
console.log(" 3. Apply the fix described above");
|
|
848
|
+
console.log(" 4. Run tests and linters to verify");
|
|
849
|
+
console.log(" 5. Create a PR with the changes");
|
|
841
850
|
}
|
|
842
851
|
});
|
|
843
852
|
command.addHelpText(
|
|
@@ -878,7 +887,7 @@ import { constants as fsConstants2 } from "fs";
|
|
|
878
887
|
import { access as access2, mkdir, readFile as readFile2, writeFile } from "fs/promises";
|
|
879
888
|
import { resolve as resolve3 } from "path";
|
|
880
889
|
import { checkbox, confirm, input } from "@inquirer/prompts";
|
|
881
|
-
import { Command as
|
|
890
|
+
import { Command as Command5 } from "commander";
|
|
882
891
|
var OAC_LOGO = [
|
|
883
892
|
" ___ _ ___",
|
|
884
893
|
" / _ \\ /_\\ / __|",
|
|
@@ -887,7 +896,7 @@ var OAC_LOGO = [
|
|
|
887
896
|
].join("\n");
|
|
888
897
|
var OWNER_REPO_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\.git)?$/;
|
|
889
898
|
function createInitCommand() {
|
|
890
|
-
const command = new
|
|
899
|
+
const command = new Command5("init");
|
|
891
900
|
command.description("Initialize OAC in the current directory").option("--minimal", "Generate a bare-bones config without the interactive wizard").option("--repo <owner/repo>", "Repository in owner/repo format (required with --minimal)").action(async (options, cmd) => {
|
|
892
901
|
const globalOptions = getGlobalOptions(cmd);
|
|
893
902
|
const ui = createUi(globalOptions);
|
|
@@ -1124,9 +1133,9 @@ async function ensureGitignoreEntry(dir, entry) {
|
|
|
1124
1133
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
1125
1134
|
import { resolve as resolve4 } from "path";
|
|
1126
1135
|
import Table2 from "cli-table3";
|
|
1127
|
-
import { Command as
|
|
1136
|
+
import { Command as Command6 } from "commander";
|
|
1128
1137
|
function createLeaderboardCommand() {
|
|
1129
|
-
const command = new
|
|
1138
|
+
const command = new Command6("leaderboard");
|
|
1130
1139
|
command.description("Show contribution rankings").option("--limit <number>", "Max entries to show", parseInteger, 10).option("--sort <field>", "Sort by: runs, tasks, tokens, prs", "tasks").action(async (options, cmd) => {
|
|
1131
1140
|
if (options.limit <= 0) {
|
|
1132
1141
|
throw new Error("--limit must be a positive integer.");
|
|
@@ -1318,9 +1327,9 @@ function isFileNotFoundError(error) {
|
|
|
1318
1327
|
import { readFile as readFile4, readdir as readdir2 } from "fs/promises";
|
|
1319
1328
|
import { resolve as resolve5 } from "path";
|
|
1320
1329
|
import Table3 from "cli-table3";
|
|
1321
|
-
import { Command as
|
|
1330
|
+
import { Command as Command7 } from "commander";
|
|
1322
1331
|
function createLogCommand() {
|
|
1323
|
-
const command = new
|
|
1332
|
+
const command = new Command7("log");
|
|
1324
1333
|
command.description("View contribution history").option("--limit <number>", "Max entries to show", parseInteger, 20).option("--repo <name>", "Filter by repo name").option("--source <type>", "Filter by task source").option("--since <date>", "Filter contributions after date (ISO string)").action(async (options, cmd) => {
|
|
1325
1334
|
if (options.limit <= 0) {
|
|
1326
1335
|
throw new Error("--limit must be a positive integer.");
|
|
@@ -1438,9 +1447,9 @@ function isFileNotFoundError2(error) {
|
|
|
1438
1447
|
|
|
1439
1448
|
// src/cli/commands/plan.ts
|
|
1440
1449
|
import Table4 from "cli-table3";
|
|
1441
|
-
import { Command as
|
|
1450
|
+
import { Command as Command8 } from "commander";
|
|
1442
1451
|
function createPlanCommand() {
|
|
1443
|
-
const command = new
|
|
1452
|
+
const command = new Command8("plan");
|
|
1444
1453
|
command.description("Build an execution plan from discovered tasks").option("--repo <owner/repo>", "Target repository (owner/repo or GitHub URL)").option("--tokens <number>", "Token budget for planning", parseInteger).option("--provider <id>", "Agent provider id").action(async (options, cmd) => {
|
|
1445
1454
|
const globalOptions = getGlobalOptions(cmd);
|
|
1446
1455
|
const ui = createUi(globalOptions);
|
|
@@ -1465,6 +1474,7 @@ function createPlanCommand() {
|
|
|
1465
1474
|
const scannedTasks = await scannerSelection.scanner.scan(resolvedRepo.localPath, {
|
|
1466
1475
|
exclude: config?.discovery.exclude,
|
|
1467
1476
|
maxTasks: config?.discovery.maxTasks,
|
|
1477
|
+
issueLabels: config?.discovery.issueLabels,
|
|
1468
1478
|
repo: resolvedRepo
|
|
1469
1479
|
});
|
|
1470
1480
|
scanSpinner?.succeed(`Discovered ${scannedTasks.length} raw task(s)`);
|
|
@@ -1574,7 +1584,7 @@ function renderPlan(ui, data) {
|
|
|
1574
1584
|
}
|
|
1575
1585
|
|
|
1576
1586
|
// src/cli/commands/run/index.ts
|
|
1577
|
-
import { Command as
|
|
1587
|
+
import { Command as Command9 } from "commander";
|
|
1578
1588
|
|
|
1579
1589
|
// src/cli/commands/run/pipeline.ts
|
|
1580
1590
|
import { randomUUID } from "crypto";
|
|
@@ -1771,6 +1781,7 @@ async function discoverTasks(ctx, options, config, ghToken, resolvedRepo) {
|
|
|
1771
1781
|
const scannedTasks = await scannerSelection.scanner.scan(resolvedRepo.localPath, {
|
|
1772
1782
|
exclude: config?.discovery.exclude,
|
|
1773
1783
|
maxTasks: config?.discovery.maxTasks,
|
|
1784
|
+
issueLabels: config?.discovery.issueLabels,
|
|
1774
1785
|
repo: resolvedRepo
|
|
1775
1786
|
});
|
|
1776
1787
|
scanSpinner?.succeed(`Discovered ${scannedTasks.length} raw task(s)`);
|
|
@@ -1852,7 +1863,9 @@ function renderDryRunDiff(ui, plan) {
|
|
|
1852
1863
|
const sourceLabel = task.source.replace(/-/g, " ");
|
|
1853
1864
|
const complexityColor = task.complexity === "trivial" || task.complexity === "simple" ? ui.green : task.complexity === "moderate" ? ui.yellow : ui.red;
|
|
1854
1865
|
console.log(`${ui.green("+")} ${ui.bold(task.title)}`);
|
|
1855
|
-
console.log(
|
|
1866
|
+
console.log(
|
|
1867
|
+
` ${ui.dim(`source: ${sourceLabel} complexity: `)}${complexityColor(task.complexity)}`
|
|
1868
|
+
);
|
|
1856
1869
|
if (task.targetFiles.length > 0) {
|
|
1857
1870
|
for (const file of task.targetFiles.slice(0, 5)) {
|
|
1858
1871
|
console.log(` ${ui.yellow("~")} ${file}`);
|
|
@@ -1997,7 +2010,7 @@ async function executeWithAgent(input2) {
|
|
|
1997
2010
|
tokenBudget: input2.estimate.totalEstimatedTokens,
|
|
1998
2011
|
timeoutMs: input2.timeoutSeconds * 1e3
|
|
1999
2012
|
});
|
|
2000
|
-
const commitResult = await commitSandboxChanges(sandbox.path, input2.task);
|
|
2013
|
+
const commitResult = await commitSandboxChanges(sandbox.path, input2.task, input2.baseBranch);
|
|
2001
2014
|
const filesChanged = commitResult.filesChanged.length > 0 ? commitResult.filesChanged : result.filesChanged.length > 0 ? result.filesChanged : [];
|
|
2002
2015
|
return {
|
|
2003
2016
|
execution: {
|
|
@@ -2011,7 +2024,7 @@ async function executeWithAgent(input2) {
|
|
|
2011
2024
|
sandbox: sandboxInfo
|
|
2012
2025
|
};
|
|
2013
2026
|
} catch (error) {
|
|
2014
|
-
const commitResult = await commitSandboxChanges(sandbox.path, input2.task);
|
|
2027
|
+
const commitResult = await commitSandboxChanges(sandbox.path, input2.task, input2.baseBranch);
|
|
2015
2028
|
if (commitResult.hasChanges) {
|
|
2016
2029
|
return {
|
|
2017
2030
|
execution: {
|
|
@@ -2038,25 +2051,26 @@ async function executeWithAgent(input2) {
|
|
|
2038
2051
|
};
|
|
2039
2052
|
}
|
|
2040
2053
|
}
|
|
2041
|
-
async function commitSandboxChanges(sandboxPath, task) {
|
|
2054
|
+
async function commitSandboxChanges(sandboxPath, task, baseBranch) {
|
|
2042
2055
|
try {
|
|
2043
2056
|
const statusResult = await execa2("git", ["status", "--porcelain"], { cwd: sandboxPath });
|
|
2044
|
-
if (
|
|
2045
|
-
|
|
2057
|
+
if (statusResult.stdout.trim()) {
|
|
2058
|
+
await execa2("git", ["add", "-A"], { cwd: sandboxPath });
|
|
2059
|
+
await execa2(
|
|
2060
|
+
"git",
|
|
2061
|
+
["commit", "-m", `[OAC] ${task.title}
|
|
2062
|
+
|
|
2063
|
+
Automated contribution by OAC.`],
|
|
2064
|
+
{ cwd: sandboxPath }
|
|
2065
|
+
);
|
|
2046
2066
|
}
|
|
2047
|
-
await execa2(
|
|
2048
|
-
await execa2(
|
|
2067
|
+
const diffResult = await execa2(
|
|
2049
2068
|
"git",
|
|
2050
|
-
["
|
|
2051
|
-
|
|
2052
|
-
Automated contribution by OAC using Codex CLI.`],
|
|
2069
|
+
["diff", "--name-only", `origin/${baseBranch}`, "HEAD"],
|
|
2053
2070
|
{ cwd: sandboxPath }
|
|
2054
2071
|
);
|
|
2055
|
-
const diffResult = await execa2("git", ["diff", "--name-only", "HEAD~1", "HEAD"], {
|
|
2056
|
-
cwd: sandboxPath
|
|
2057
|
-
});
|
|
2058
2072
|
const changedFiles = diffResult.stdout.trim().split("\n").filter(Boolean);
|
|
2059
|
-
return { hasChanges:
|
|
2073
|
+
return { hasChanges: changedFiles.length > 0, filesChanged: changedFiles };
|
|
2060
2074
|
} catch {
|
|
2061
2075
|
return { hasChanges: false, filesChanged: [] };
|
|
2062
2076
|
}
|
|
@@ -2396,10 +2410,7 @@ async function runEpicPipeline(ctx, params) {
|
|
|
2396
2410
|
const { adapter } = await resolveAdapter(providerId);
|
|
2397
2411
|
let epicCompletedCount = 0;
|
|
2398
2412
|
const epicTotal = epicPlan.selectedEpics.length;
|
|
2399
|
-
const executionSpinner = createSpinner(
|
|
2400
|
-
ctx.suppressOutput,
|
|
2401
|
-
`Executing ${epicTotal} epic(s)...`
|
|
2402
|
-
);
|
|
2413
|
+
const executionSpinner = createSpinner(ctx.suppressOutput, `Executing ${epicTotal} epic(s)...`);
|
|
2403
2414
|
const epicQueue = new PQueue3({ concurrency });
|
|
2404
2415
|
const allTaskResults = await Promise.all(
|
|
2405
2416
|
epicPlan.selectedEpics.map(
|
|
@@ -2565,7 +2576,6 @@ async function readMostRecentContributionLog(repoPath) {
|
|
|
2565
2576
|
const parsed = contributionLogSchema.safeParse(JSON.parse(content));
|
|
2566
2577
|
if (parsed.success) return parsed.data;
|
|
2567
2578
|
} catch {
|
|
2568
|
-
continue;
|
|
2569
2579
|
}
|
|
2570
2580
|
}
|
|
2571
2581
|
return void 0;
|
|
@@ -2592,7 +2602,9 @@ async function runRetryPipeline(ctx, params) {
|
|
|
2592
2602
|
if (!log) {
|
|
2593
2603
|
retrySpinner?.fail("No contribution logs found in .oac/contributions/");
|
|
2594
2604
|
if (!ctx.suppressOutput) {
|
|
2595
|
-
console.log(
|
|
2605
|
+
console.log(
|
|
2606
|
+
ctx.ui.yellow("[oac] Run the pipeline at least once before using --retry-failed.")
|
|
2607
|
+
);
|
|
2596
2608
|
}
|
|
2597
2609
|
return [];
|
|
2598
2610
|
}
|
|
@@ -2818,10 +2830,8 @@ function parseTokens(value) {
|
|
|
2818
2830
|
return parseInteger(value);
|
|
2819
2831
|
}
|
|
2820
2832
|
function createRunCommand() {
|
|
2821
|
-
const command = new
|
|
2822
|
-
command.alias("r").description(
|
|
2823
|
-
"Run the full OAC pipeline \u2014 analyze, plan, and execute in one command"
|
|
2824
|
-
).option("--repo <owner/repo>", "Target repository (owner/repo or GitHub URL)").option("--tokens <value>", 'Token budget (number or "unlimited")', parseTokens).option("--provider <id>", "Agent provider id").option("--concurrency <number>", "Maximum parallel task executions", parseInteger).option("--dry-run", "Show plan without executing tasks", false).option("--mode <mode>", "Execution mode: new-pr|update-pr|direct-commit").option("--max-tasks <number>", "Maximum number of discovered tasks to consider", parseInteger).option("--timeout <seconds>", "Per-task timeout in seconds", parseInteger).option("--source <source>", "Filter tasks by source: lint, todo, github-issue, test-gap").option("--retry-failed", "Re-run only failed tasks from the most recent run", false).action(async (options, cmd) => {
|
|
2833
|
+
const command = new Command9("run");
|
|
2834
|
+
command.alias("r").description("Run the full OAC pipeline \u2014 analyze, plan, and execute in one command").option("--repo <owner/repo>", "Target repository (owner/repo or GitHub URL)").option("--tokens <value>", 'Token budget (number or "unlimited")', parseTokens).option("--provider <id>", "Agent provider id").option("--concurrency <number>", "Maximum parallel task executions", parseInteger).option("--dry-run", "Show plan without executing tasks", false).option("--mode <mode>", "Execution mode: new-pr|update-pr|direct-commit").option("--max-tasks <number>", "Maximum number of discovered tasks to consider", parseInteger).option("--timeout <seconds>", "Per-task timeout in seconds", parseInteger).option("--source <source>", "Filter tasks by source: lint, todo, github-issue, test-gap").option("--retry-failed", "Re-run only failed tasks from the most recent run", false).action(async (options, cmd) => {
|
|
2825
2835
|
const globalOptions = getGlobalOptions(cmd);
|
|
2826
2836
|
const ui = createUi(globalOptions);
|
|
2827
2837
|
validateRunOptions(options);
|
|
@@ -2855,10 +2865,10 @@ Exit Codes:
|
|
|
2855
2865
|
|
|
2856
2866
|
// src/cli/commands/scan.ts
|
|
2857
2867
|
import Table7 from "cli-table3";
|
|
2858
|
-
import { Command as
|
|
2868
|
+
import { Command as Command10 } from "commander";
|
|
2859
2869
|
var SUPPORTED_SCANNERS = ["lint", "todo", "github-issues", "test-gap"];
|
|
2860
2870
|
function createScanCommand() {
|
|
2861
|
-
const command = new
|
|
2871
|
+
const command = new Command10("scan");
|
|
2862
2872
|
command.description("Quick task discovery \u2014 list individual issues ranked by priority").option("--repo <owner/repo>", "Target repository (owner/repo or GitHub URL)").option("--scanners <names>", "Comma-separated scanner filter (lint,todo)").option("--min-priority <number>", "Minimum priority threshold (0-100)", parseInteger, 20).option("--format <format>", "Output format: table|json", "table").action(async (options, cmd) => {
|
|
2863
2873
|
const globalOptions = getGlobalOptions(cmd);
|
|
2864
2874
|
const ui = createUi(globalOptions);
|
|
@@ -2891,6 +2901,7 @@ function createScanCommand() {
|
|
|
2891
2901
|
const scannedTasks = await scannerSelection.scanner.scan(resolvedRepo.localPath, {
|
|
2892
2902
|
exclude: config?.discovery.exclude,
|
|
2893
2903
|
maxTasks: config?.discovery.maxTasks,
|
|
2904
|
+
issueLabels: config?.discovery.issueLabels,
|
|
2894
2905
|
repo: resolvedRepo
|
|
2895
2906
|
});
|
|
2896
2907
|
scanSpinner?.succeed(`Scanned ${resolvedRepo.fullName}`);
|
|
@@ -3021,10 +3032,10 @@ function parseCsv(value) {
|
|
|
3021
3032
|
// src/cli/commands/status.ts
|
|
3022
3033
|
import { readFile as readFile6 } from "fs/promises";
|
|
3023
3034
|
import { resolve as resolve7 } from "path";
|
|
3024
|
-
import { Command as
|
|
3035
|
+
import { Command as Command11 } from "commander";
|
|
3025
3036
|
var WATCH_INTERVAL_MS = 2e3;
|
|
3026
3037
|
function createStatusCommand() {
|
|
3027
|
-
const command = new
|
|
3038
|
+
const command = new Command11("status");
|
|
3028
3039
|
command.description("Show current job status").option("--watch", "Poll every 2 seconds", false).action(async (options, cmd) => {
|
|
3029
3040
|
const globalOptions = getGlobalOptions(cmd);
|
|
3030
3041
|
const render = async () => {
|
|
@@ -3200,21 +3211,13 @@ function registerCommands(program) {
|
|
|
3200
3211
|
program.addCommand(createExplainCommand());
|
|
3201
3212
|
}
|
|
3202
3213
|
async function createCliProgram() {
|
|
3203
|
-
const version = true ? "2026.
|
|
3204
|
-
const program = new
|
|
3214
|
+
const version = true ? "2026.222.1" : "0.0.0";
|
|
3215
|
+
const program = new Command12();
|
|
3205
3216
|
program.name("oac").description("Open Agent Contribution CLI").version(version).option("--config <path>", "Config file path", "oac.config.ts").option("--verbose", "Enable verbose logging", false).option("--quiet", "Suppress non-error output", false).option("--json", "Output machine-readable JSON", false).option("--no-color", "Disable ANSI colors");
|
|
3206
3217
|
registerCommands(program);
|
|
3207
3218
|
program.addHelpText(
|
|
3208
3219
|
"after",
|
|
3209
|
-
|
|
3210
|
-
Getting Started:
|
|
3211
|
-
$ oac init Set up your project configuration
|
|
3212
|
-
$ oac doctor Verify your environment is ready
|
|
3213
|
-
$ oac analyze Analyze codebase for contribution opportunities
|
|
3214
|
-
$ oac run Run the full contribution pipeline
|
|
3215
|
-
|
|
3216
|
-
Documentation: https://github.com/Open330/open-agent-contribution
|
|
3217
|
-
`
|
|
3220
|
+
"\nGetting Started:\n $ oac init Set up your project configuration\n $ oac doctor Verify your environment is ready\n $ oac analyze Analyze codebase for contribution opportunities\n $ oac run Run the full contribution pipeline\n\nDocumentation: https://github.com/Open330/open-agent-contribution\n"
|
|
3218
3221
|
);
|
|
3219
3222
|
return program;
|
|
3220
3223
|
}
|
|
@@ -3230,4 +3233,4 @@ export {
|
|
|
3230
3233
|
createCliProgram,
|
|
3231
3234
|
runCli
|
|
3232
3235
|
};
|
|
3233
|
-
//# sourceMappingURL=chunk-
|
|
3236
|
+
//# sourceMappingURL=chunk-GPHH2IYN.js.map
|