@mirnoorata/codexa 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +634 -0
- package/dist/artifacts.d.ts +2 -0
- package/dist/artifacts.js +375 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/autonomy.d.ts +17 -0
- package/dist/autonomy.js +124 -0
- package/dist/autonomy.js.map +1 -0
- package/dist/autoverify/policy.d.ts +5 -0
- package/dist/autoverify/policy.js +18 -0
- package/dist/autoverify/policy.js.map +1 -0
- package/dist/autoverify.d.ts +45 -0
- package/dist/autoverify.js +1041 -0
- package/dist/autoverify.js.map +1 -0
- package/dist/cache-lock.d.ts +16 -0
- package/dist/cache-lock.js +181 -0
- package/dist/cache-lock.js.map +1 -0
- package/dist/cli/hooks.d.ts +5 -0
- package/dist/cli/hooks.js +264 -0
- package/dist/cli/hooks.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1034 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-contract.d.ts +2 -0
- package/dist/codex-contract.js +78 -0
- package/dist/codex-contract.js.map +1 -0
- package/dist/command.d.ts +34 -0
- package/dist/command.js +162 -0
- package/dist/command.js.map +1 -0
- package/dist/doctor.d.ts +112 -0
- package/dist/doctor.js +518 -0
- package/dist/doctor.js.map +1 -0
- package/dist/eval/baseline.d.ts +7 -0
- package/dist/eval/baseline.js +146 -0
- package/dist/eval/baseline.js.map +1 -0
- package/dist/eval/historical.d.ts +4 -0
- package/dist/eval/historical.js +663 -0
- package/dist/eval/historical.js.map +1 -0
- package/dist/eval/render.d.ts +2 -0
- package/dist/eval/render.js +53 -0
- package/dist/eval/render.js.map +1 -0
- package/dist/eval/scoring.d.ts +21 -0
- package/dist/eval/scoring.js +618 -0
- package/dist/eval/scoring.js.map +1 -0
- package/dist/eval/synthetic.d.ts +36 -0
- package/dist/eval/synthetic.js +107 -0
- package/dist/eval/synthetic.js.map +1 -0
- package/dist/eval/types.d.ts +36 -0
- package/dist/eval/types.js +2 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/eval.d.ts +140 -0
- package/dist/eval.js +551 -0
- package/dist/eval.js.map +1 -0
- package/dist/git.d.ts +17 -0
- package/dist/git.js +189 -0
- package/dist/git.js.map +1 -0
- package/dist/github-release.d.ts +47 -0
- package/dist/github-release.js +610 -0
- package/dist/github-release.js.map +1 -0
- package/dist/github-sync.d.ts +68 -0
- package/dist/github-sync.js +345 -0
- package/dist/github-sync.js.map +1 -0
- package/dist/graph.d.ts +10 -0
- package/dist/graph.js +665 -0
- package/dist/graph.js.map +1 -0
- package/dist/indexer/aliases.d.ts +2 -0
- package/dist/indexer/aliases.js +190 -0
- package/dist/indexer/aliases.js.map +1 -0
- package/dist/indexer/artifact-writing.d.ts +3 -0
- package/dist/indexer/artifact-writing.js +79 -0
- package/dist/indexer/artifact-writing.js.map +1 -0
- package/dist/indexer/discovery.d.ts +2 -0
- package/dist/indexer/discovery.js +5 -0
- package/dist/indexer/discovery.js.map +1 -0
- package/dist/indexer/external-facts.d.ts +6 -0
- package/dist/indexer/external-facts.js +45 -0
- package/dist/indexer/external-facts.js.map +1 -0
- package/dist/indexer/freshness.d.ts +8 -0
- package/dist/indexer/freshness.js +56 -0
- package/dist/indexer/freshness.js.map +1 -0
- package/dist/indexer/graph-stage.d.ts +2 -0
- package/dist/indexer/graph-stage.js +21 -0
- package/dist/indexer/graph-stage.js.map +1 -0
- package/dist/indexer/parsing.d.ts +30 -0
- package/dist/indexer/parsing.js +177 -0
- package/dist/indexer/parsing.js.map +1 -0
- package/dist/indexer/pipeline.d.ts +5 -0
- package/dist/indexer/pipeline.js +8 -0
- package/dist/indexer/pipeline.js.map +1 -0
- package/dist/indexer/ranking.d.ts +4 -0
- package/dist/indexer/ranking.js +134 -0
- package/dist/indexer/ranking.js.map +1 -0
- package/dist/indexer.d.ts +13 -0
- package/dist/indexer.js +395 -0
- package/dist/indexer.js.map +1 -0
- package/dist/init.d.ts +24 -0
- package/dist/init.js +566 -0
- package/dist/init.js.map +1 -0
- package/dist/language.d.ts +8 -0
- package/dist/language.js +123 -0
- package/dist/language.js.map +1 -0
- package/dist/live-index.d.ts +68 -0
- package/dist/live-index.js +215 -0
- package/dist/live-index.js.map +1 -0
- package/dist/lsp/assist.d.ts +44 -0
- package/dist/lsp/assist.js +331 -0
- package/dist/lsp/assist.js.map +1 -0
- package/dist/lsp/client.d.ts +59 -0
- package/dist/lsp/client.js +208 -0
- package/dist/lsp/client.js.map +1 -0
- package/dist/mcp/compaction.d.ts +15 -0
- package/dist/mcp/compaction.js +1249 -0
- package/dist/mcp/compaction.js.map +1 -0
- package/dist/mcp/envelope.d.ts +44 -0
- package/dist/mcp/envelope.js +425 -0
- package/dist/mcp/envelope.js.map +1 -0
- package/dist/mcp/prompts.d.ts +2 -0
- package/dist/mcp/prompts.js +109 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/resources.d.ts +2 -0
- package/dist/mcp/resources.js +132 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/runtime.d.ts +15 -0
- package/dist/mcp/runtime.js +122 -0
- package/dist/mcp/runtime.js.map +1 -0
- package/dist/mcp/session-memory.d.ts +3 -0
- package/dist/mcp/session-memory.js +61 -0
- package/dist/mcp/session-memory.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +269 -0
- package/dist/mcp/tool-registry.js +284 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/mcp/tools.d.ts +53 -0
- package/dist/mcp/tools.js +372 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp-repo-root.d.ts +16 -0
- package/dist/mcp-repo-root.js +322 -0
- package/dist/mcp-repo-root.js.map +1 -0
- package/dist/mcp-tool-catalog.d.ts +2 -0
- package/dist/mcp-tool-catalog.js +2 -0
- package/dist/mcp-tool-catalog.js.map +1 -0
- package/dist/mcp.d.ts +11 -0
- package/dist/mcp.js +332 -0
- package/dist/mcp.js.map +1 -0
- package/dist/outcome-ranking.d.ts +5 -0
- package/dist/outcome-ranking.js +115 -0
- package/dist/outcome-ranking.js.map +1 -0
- package/dist/parser/context.d.ts +28 -0
- package/dist/parser/context.js +2 -0
- package/dist/parser/context.js.map +1 -0
- package/dist/parser/ecma.d.ts +5 -0
- package/dist/parser/ecma.js +388 -0
- package/dist/parser/ecma.js.map +1 -0
- package/dist/parser/facts.d.ts +12 -0
- package/dist/parser/facts.js +137 -0
- package/dist/parser/facts.js.map +1 -0
- package/dist/parser/json.d.ts +3 -0
- package/dist/parser/json.js +318 -0
- package/dist/parser/json.js.map +1 -0
- package/dist/parser/markdown.d.ts +3 -0
- package/dist/parser/markdown.js +180 -0
- package/dist/parser/markdown.js.map +1 -0
- package/dist/parser/nodes.d.ts +5 -0
- package/dist/parser/nodes.js +75 -0
- package/dist/parser/nodes.js.map +1 -0
- package/dist/parser/python.d.ts +2 -0
- package/dist/parser/python.js +307 -0
- package/dist/parser/python.js.map +1 -0
- package/dist/parser/references.d.ts +3 -0
- package/dist/parser/references.js +204 -0
- package/dist/parser/references.js.map +1 -0
- package/dist/parser/risks.d.ts +4 -0
- package/dist/parser/risks.js +62 -0
- package/dist/parser/risks.js.map +1 -0
- package/dist/parser/routes.d.ts +5 -0
- package/dist/parser/routes.js +97 -0
- package/dist/parser/routes.js.map +1 -0
- package/dist/parser/shallow.d.ts +3 -0
- package/dist/parser/shallow.js +545 -0
- package/dist/parser/shallow.js.map +1 -0
- package/dist/parser/source.d.ts +4 -0
- package/dist/parser/source.js +127 -0
- package/dist/parser/source.js.map +1 -0
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +2 -0
- package/dist/parser.js.map +1 -0
- package/dist/placeholder-signals.d.ts +15 -0
- package/dist/placeholder-signals.js +511 -0
- package/dist/placeholder-signals.js.map +1 -0
- package/dist/post-edit-outcomes.d.ts +167 -0
- package/dist/post-edit-outcomes.js +484 -0
- package/dist/post-edit-outcomes.js.map +1 -0
- package/dist/queries.d.ts +12 -0
- package/dist/queries.js +13 -0
- package/dist/queries.js.map +1 -0
- package/dist/query/change-plan.d.ts +48 -0
- package/dist/query/change-plan.js +858 -0
- package/dist/query/change-plan.js.map +1 -0
- package/dist/query/compact-data.d.ts +25 -0
- package/dist/query/compact-data.js +74 -0
- package/dist/query/compact-data.js.map +1 -0
- package/dist/query/context.d.ts +5 -0
- package/dist/query/context.js +1162 -0
- package/dist/query/context.js.map +1 -0
- package/dist/query/diff.d.ts +5 -0
- package/dist/query/diff.js +111 -0
- package/dist/query/diff.js.map +1 -0
- package/dist/query/edge-evidence.d.ts +3 -0
- package/dist/query/edge-evidence.js +36 -0
- package/dist/query/edge-evidence.js.map +1 -0
- package/dist/query/formatting.d.ts +14 -0
- package/dist/query/formatting.js +67 -0
- package/dist/query/formatting.js.map +1 -0
- package/dist/query/graph-traversal.d.ts +22 -0
- package/dist/query/graph-traversal.js +218 -0
- package/dist/query/graph-traversal.js.map +1 -0
- package/dist/query/graph.d.ts +14 -0
- package/dist/query/graph.js +102 -0
- package/dist/query/graph.js.map +1 -0
- package/dist/query/impact.d.ts +28 -0
- package/dist/query/impact.js +568 -0
- package/dist/query/impact.js.map +1 -0
- package/dist/query/inspection.d.ts +9 -0
- package/dist/query/inspection.js +290 -0
- package/dist/query/inspection.js.map +1 -0
- package/dist/query/next-tools.d.ts +3 -0
- package/dist/query/next-tools.js +25 -0
- package/dist/query/next-tools.js.map +1 -0
- package/dist/query/placeholders.d.ts +24 -0
- package/dist/query/placeholders.js +121 -0
- package/dist/query/placeholders.js.map +1 -0
- package/dist/query/post-edit/decision.d.ts +49 -0
- package/dist/query/post-edit/decision.js +130 -0
- package/dist/query/post-edit/decision.js.map +1 -0
- package/dist/query/post-edit/dirty-scope.d.ts +16 -0
- package/dist/query/post-edit/dirty-scope.js +21 -0
- package/dist/query/post-edit/dirty-scope.js.map +1 -0
- package/dist/query/post-edit/next-actions.d.ts +22 -0
- package/dist/query/post-edit/next-actions.js +44 -0
- package/dist/query/post-edit/next-actions.js.map +1 -0
- package/dist/query/post-edit/snapshot-contract.d.ts +8 -0
- package/dist/query/post-edit/snapshot-contract.js +111 -0
- package/dist/query/post-edit/snapshot-contract.js.map +1 -0
- package/dist/query/post-edit.d.ts +5 -0
- package/dist/query/post-edit.js +1108 -0
- package/dist/query/post-edit.js.map +1 -0
- package/dist/query/quality.d.ts +43 -0
- package/dist/query/quality.js +134 -0
- package/dist/query/quality.js.map +1 -0
- package/dist/query/raw-search.d.ts +23 -0
- package/dist/query/raw-search.js +147 -0
- package/dist/query/raw-search.js.map +1 -0
- package/dist/query/runtime.d.ts +11 -0
- package/dist/query/runtime.js +79 -0
- package/dist/query/runtime.js.map +1 -0
- package/dist/query/search.d.ts +25 -0
- package/dist/query/search.js +429 -0
- package/dist/query/search.js.map +1 -0
- package/dist/query/session-memory.d.ts +3 -0
- package/dist/query/session-memory.js +108 -0
- package/dist/query/session-memory.js.map +1 -0
- package/dist/query/session.d.ts +41 -0
- package/dist/query/session.js +90 -0
- package/dist/query/session.js.map +1 -0
- package/dist/query/targets.d.ts +25 -0
- package/dist/query/targets.js +97 -0
- package/dist/query/targets.js.map +1 -0
- package/dist/query/test-commands.d.ts +10 -0
- package/dist/query/test-commands.js +110 -0
- package/dist/query/test-commands.js.map +1 -0
- package/dist/query/test-plan.d.ts +6 -0
- package/dist/query/test-plan.js +104 -0
- package/dist/query/test-plan.js.map +1 -0
- package/dist/query/tests.d.ts +48 -0
- package/dist/query/tests.js +444 -0
- package/dist/query/tests.js.map +1 -0
- package/dist/query/verification/shell.d.ts +20 -0
- package/dist/query/verification/shell.js +164 -0
- package/dist/query/verification/shell.js.map +1 -0
- package/dist/query/verification.d.ts +47 -0
- package/dist/query/verification.js +1123 -0
- package/dist/query/verification.js.map +1 -0
- package/dist/query/workflow.d.ts +17 -0
- package/dist/query/workflow.js +252 -0
- package/dist/query/workflow.js.map +1 -0
- package/dist/query/workspace-guidance.d.ts +26 -0
- package/dist/query/workspace-guidance.js +214 -0
- package/dist/query/workspace-guidance.js.map +1 -0
- package/dist/query/worktree-state.d.ts +22 -0
- package/dist/query/worktree-state.js +32 -0
- package/dist/query/worktree-state.js.map +1 -0
- package/dist/query/worktree.d.ts +16 -0
- package/dist/query/worktree.js +194 -0
- package/dist/query/worktree.js.map +1 -0
- package/dist/query-data.d.ts +4 -0
- package/dist/query-data.js +112 -0
- package/dist/query-data.js.map +1 -0
- package/dist/repo-files.d.ts +24 -0
- package/dist/repo-files.js +105 -0
- package/dist/repo-files.js.map +1 -0
- package/dist/resolver.d.ts +9 -0
- package/dist/resolver.js +555 -0
- package/dist/resolver.js.map +1 -0
- package/dist/retrieval.d.ts +46 -0
- package/dist/retrieval.js +783 -0
- package/dist/retrieval.js.map +1 -0
- package/dist/risk-ingest.d.ts +16 -0
- package/dist/risk-ingest.js +458 -0
- package/dist/risk-ingest.js.map +1 -0
- package/dist/rules.d.ts +10 -0
- package/dist/rules.js +107 -0
- package/dist/rules.js.map +1 -0
- package/dist/semantic/python.d.ts +9 -0
- package/dist/semantic/python.js +817 -0
- package/dist/semantic/python.js.map +1 -0
- package/dist/semantic/typescript.d.ts +10 -0
- package/dist/semantic/typescript.js +714 -0
- package/dist/semantic/typescript.js.map +1 -0
- package/dist/semantic-retrieval.d.ts +53 -0
- package/dist/semantic-retrieval.js +673 -0
- package/dist/semantic-retrieval.js.map +1 -0
- package/dist/session-memory/derivation.d.ts +6 -0
- package/dist/session-memory/derivation.js +400 -0
- package/dist/session-memory/derivation.js.map +1 -0
- package/dist/session-memory/event-log.d.ts +23 -0
- package/dist/session-memory/event-log.js +126 -0
- package/dist/session-memory/event-log.js.map +1 -0
- package/dist/session-memory/formatting.d.ts +7 -0
- package/dist/session-memory/formatting.js +86 -0
- package/dist/session-memory/formatting.js.map +1 -0
- package/dist/session-memory/model.d.ts +94 -0
- package/dist/session-memory/model.js +17 -0
- package/dist/session-memory/model.js.map +1 -0
- package/dist/session-memory/runtime.d.ts +24 -0
- package/dist/session-memory/runtime.js +289 -0
- package/dist/session-memory/runtime.js.map +1 -0
- package/dist/session-memory/store.d.ts +27 -0
- package/dist/session-memory/store.js +447 -0
- package/dist/session-memory/store.js.map +1 -0
- package/dist/session-memory.d.ts +1 -0
- package/dist/session-memory.js +2 -0
- package/dist/session-memory.js.map +1 -0
- package/dist/static-analysis.d.ts +36 -0
- package/dist/static-analysis.js +505 -0
- package/dist/static-analysis.js.map +1 -0
- package/dist/symbol-report-ingest.d.ts +8 -0
- package/dist/symbol-report-ingest.js +504 -0
- package/dist/symbol-report-ingest.js.map +1 -0
- package/dist/task-snapshots.d.ts +41 -0
- package/dist/task-snapshots.js +430 -0
- package/dist/task-snapshots.js.map +1 -0
- package/dist/types.d.ts +848 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +11 -0
- package/dist/util.js +63 -0
- package/dist/util.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +81 -0
- package/plugins/codexa/.codex-plugin/plugin.json +38 -0
- package/plugins/codexa/.mcp.json +20 -0
- package/plugins/codexa/scripts/codexa-mcp.js +100 -0
- package/plugins/codexa/skills/codexa/SKILL.md +48 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { createCommandBudget, runCommand } from "../command.js";
|
|
3
|
+
import { getChangedFileEntries, getChangedSymbols } from "./worktree.js";
|
|
4
|
+
import { requireIndex } from "./runtime.js";
|
|
5
|
+
const DEFAULT_COMMAND_BUDGET_MS = 10_000;
|
|
6
|
+
const DEFAULT_MAX_RESULT_BYTES = 64 * 1024;
|
|
7
|
+
const DEFAULT_MAX_RESULTS = 50;
|
|
8
|
+
export async function createQuerySession(repoRoot, options = {}) {
|
|
9
|
+
const repo = path.resolve(repoRoot);
|
|
10
|
+
return createQuerySessionFromIndexState(repo, await requireIndex(repo, options), options);
|
|
11
|
+
}
|
|
12
|
+
export function createQuerySessionFromIndexState(repoRoot, state, options = {}) {
|
|
13
|
+
const repo = path.resolve(repoRoot);
|
|
14
|
+
const { index, freshness, refresh } = state;
|
|
15
|
+
const gitState = gitStateFromFreshness(repo, freshness);
|
|
16
|
+
const warnings = [];
|
|
17
|
+
const provenance = [
|
|
18
|
+
`index:${index.freshness.indexedAt}`,
|
|
19
|
+
`freshness:${freshness.reason}`,
|
|
20
|
+
`git:${gitState.headCommit ?? "none"}`
|
|
21
|
+
];
|
|
22
|
+
if (freshness.stale) {
|
|
23
|
+
warnings.push(`index stale: ${freshness.reason}`);
|
|
24
|
+
}
|
|
25
|
+
const commandBudget = createCommandBudget(positiveInt(options.commandBudgetMs, DEFAULT_COMMAND_BUDGET_MS), warnings, provenance);
|
|
26
|
+
let changedEntriesPromise;
|
|
27
|
+
let changedSymbolsPromise;
|
|
28
|
+
const worktreeDegradationReasons = [];
|
|
29
|
+
const recordWorktreeDegradation = (reason, subject) => {
|
|
30
|
+
if (!reason) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
worktreeDegradationReasons.push(reason);
|
|
34
|
+
warnings.push(`worktree ${subject} unavailable: ${reason}`);
|
|
35
|
+
provenance.push(`worktree-degraded:${subject}:${reason}`);
|
|
36
|
+
};
|
|
37
|
+
const session = {
|
|
38
|
+
repoRoot: repo,
|
|
39
|
+
options,
|
|
40
|
+
index,
|
|
41
|
+
freshness,
|
|
42
|
+
refresh,
|
|
43
|
+
gitState,
|
|
44
|
+
commandBudgetMs: commandBudget.totalMs,
|
|
45
|
+
commandBudget,
|
|
46
|
+
commandBudgetUsedMs: () => commandBudget.usedMs,
|
|
47
|
+
commandBudgetRemainingMs: () => commandBudget.remainingMs(),
|
|
48
|
+
maxResultBytes: positiveInt(options.maxResultBytes, DEFAULT_MAX_RESULT_BYTES),
|
|
49
|
+
maxResults: positiveInt(options.maxResults, DEFAULT_MAX_RESULTS),
|
|
50
|
+
warnings,
|
|
51
|
+
provenance,
|
|
52
|
+
worktreeDegradationReasons,
|
|
53
|
+
runCommand: async (command, args, runOptions = {}) => runCommand(command, args, { ...runOptions, budget: runOptions.budget ?? commandBudget }),
|
|
54
|
+
getChangedFileEntries: async () => {
|
|
55
|
+
changedEntriesPromise ??= getChangedFileEntries(repo, session.runCommand).then((result) => {
|
|
56
|
+
recordWorktreeDegradation(result.degradedReason, "status");
|
|
57
|
+
provenance.push(`changed-files:${result.entries.length}`);
|
|
58
|
+
return result.entries;
|
|
59
|
+
});
|
|
60
|
+
return changedEntriesPromise;
|
|
61
|
+
},
|
|
62
|
+
getChangedFiles: async () => (await session.getChangedFileEntries()).map((entry) => entry.path),
|
|
63
|
+
getChangedSymbols: async () => {
|
|
64
|
+
changedSymbolsPromise ??= getChangedSymbols(repo, index, session.runCommand).then((result) => {
|
|
65
|
+
recordWorktreeDegradation(result.degradedReason, "diff");
|
|
66
|
+
provenance.push(`changed-symbols:${result.symbols.length}`);
|
|
67
|
+
return result.symbols;
|
|
68
|
+
});
|
|
69
|
+
return changedSymbolsPromise;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
return session;
|
|
73
|
+
}
|
|
74
|
+
export async function ensureQuerySession(input, options = {}) {
|
|
75
|
+
return typeof input === "string" ? createQuerySession(input, options) : input;
|
|
76
|
+
}
|
|
77
|
+
function positiveInt(value, fallback) {
|
|
78
|
+
return Number.isFinite(value) && value !== undefined && value > 0 ? Math.trunc(value) : fallback;
|
|
79
|
+
}
|
|
80
|
+
function gitStateFromFreshness(repoRoot, freshness) {
|
|
81
|
+
return {
|
|
82
|
+
repoRoot,
|
|
83
|
+
gitRoot: freshness.gitRoot,
|
|
84
|
+
headCommit: freshness.headCommit,
|
|
85
|
+
files: [],
|
|
86
|
+
dirtyFiles: freshness.dirtyFiles,
|
|
87
|
+
churnByPath: new Map()
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/query/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CodexaIndex, FileFact, QueryResult, SymbolFact } from "../types.js";
|
|
2
|
+
export type ResolvedGraphTarget = {
|
|
3
|
+
label: string;
|
|
4
|
+
paths: Set<string>;
|
|
5
|
+
file?: FileFact;
|
|
6
|
+
symbol?: SymbolFact;
|
|
7
|
+
};
|
|
8
|
+
export declare function resolveSymbolTarget(index: CodexaIndex, symbolIdOrName: string): {
|
|
9
|
+
symbol?: SymbolFact;
|
|
10
|
+
ambiguous: SymbolFact[];
|
|
11
|
+
};
|
|
12
|
+
export declare function findFile(index: CodexaIndex, filePath: string): FileFact | undefined;
|
|
13
|
+
export declare function resolveFileTarget(index: CodexaIndex, filePath: string, repoRoot: string): {
|
|
14
|
+
file?: FileFact;
|
|
15
|
+
ambiguous: FileFact[];
|
|
16
|
+
};
|
|
17
|
+
export declare function normalizeInputPath(filePath: string, repoRoot: string): string | undefined;
|
|
18
|
+
export declare function normalizeInputPaths(filePaths: string[], repoRoot: string): string[];
|
|
19
|
+
export declare function resolveGraphTarget(index: CodexaIndex, repoRoot: string, input: {
|
|
20
|
+
file?: string;
|
|
21
|
+
symbol?: string;
|
|
22
|
+
}): ResolvedGraphTarget | {
|
|
23
|
+
result: QueryResult;
|
|
24
|
+
};
|
|
25
|
+
export declare function graphNodeIdsForTarget(index: CodexaIndex, target: ResolvedGraphTarget): Set<string>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { freshnessBanner, ambiguityResult } from "./runtime.js";
|
|
3
|
+
import { normalizePath } from "../util.js";
|
|
4
|
+
export function resolveSymbolTarget(index, symbolIdOrName) {
|
|
5
|
+
const byId = index.symbols.find((symbol) => symbol.id === symbolIdOrName);
|
|
6
|
+
if (byId) {
|
|
7
|
+
return { symbol: byId, ambiguous: [] };
|
|
8
|
+
}
|
|
9
|
+
const byQualified = index.symbols.filter((symbol) => symbol.qualifiedName === symbolIdOrName);
|
|
10
|
+
if (byQualified.length === 1) {
|
|
11
|
+
return { symbol: byQualified[0], ambiguous: [] };
|
|
12
|
+
}
|
|
13
|
+
if (byQualified.length > 1) {
|
|
14
|
+
return { ambiguous: byQualified };
|
|
15
|
+
}
|
|
16
|
+
const byName = index.symbols.filter((symbol) => symbol.name === symbolIdOrName);
|
|
17
|
+
if (byName.length === 1) {
|
|
18
|
+
return { symbol: byName[0], ambiguous: [] };
|
|
19
|
+
}
|
|
20
|
+
return { ambiguous: byName };
|
|
21
|
+
}
|
|
22
|
+
export function findFile(index, filePath) {
|
|
23
|
+
return index.files.find((file) => file.path === filePath);
|
|
24
|
+
}
|
|
25
|
+
export function resolveFileTarget(index, filePath, repoRoot) {
|
|
26
|
+
const normalized = normalizeInputPath(filePath, repoRoot);
|
|
27
|
+
if (!normalized) {
|
|
28
|
+
return { ambiguous: [] };
|
|
29
|
+
}
|
|
30
|
+
const exact = findFile(index, normalized);
|
|
31
|
+
if (exact) {
|
|
32
|
+
return { file: exact, ambiguous: [] };
|
|
33
|
+
}
|
|
34
|
+
return { ambiguous: index.files.filter((file) => file.path.endsWith(normalized)) };
|
|
35
|
+
}
|
|
36
|
+
export function normalizeInputPath(filePath, repoRoot) {
|
|
37
|
+
const normalized = filePath.split(path.sep).join("/");
|
|
38
|
+
if (path.isAbsolute(filePath)) {
|
|
39
|
+
const relative = path.relative(repoRoot, filePath).split(path.sep).join("/");
|
|
40
|
+
return relative && !relative.startsWith("..") ? relative : undefined;
|
|
41
|
+
}
|
|
42
|
+
return normalized && !normalized.startsWith("..") ? normalized : undefined;
|
|
43
|
+
}
|
|
44
|
+
export function normalizeInputPaths(filePaths, repoRoot) {
|
|
45
|
+
return filePaths.flatMap((filePath) => {
|
|
46
|
+
const normalized = normalizeInputPath(filePath, repoRoot);
|
|
47
|
+
return normalized ? [normalizePath(normalized)] : [];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function resolveGraphTarget(index, repoRoot, input) {
|
|
51
|
+
if (input.symbol) {
|
|
52
|
+
const resolved = resolveSymbolTarget(index, input.symbol);
|
|
53
|
+
if (resolved.ambiguous.length > 0) {
|
|
54
|
+
return { result: ambiguityResult(index.freshness, undefined, "symbol", input.symbol, resolved.ambiguous) };
|
|
55
|
+
}
|
|
56
|
+
if (resolved.symbol) {
|
|
57
|
+
return { label: `symbol ${resolved.symbol.qualifiedName}`, paths: new Set(), symbol: resolved.symbol };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (input.file) {
|
|
61
|
+
const resolved = resolveFileTarget(index, input.file, repoRoot);
|
|
62
|
+
if (resolved.ambiguous.length > 0) {
|
|
63
|
+
return { result: ambiguityResult(index.freshness, undefined, "file", input.file, resolved.ambiguous) };
|
|
64
|
+
}
|
|
65
|
+
if (resolved.file) {
|
|
66
|
+
return { label: `file ${resolved.file.path}`, paths: new Set([resolved.file.path]), file: resolved.file };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
result: {
|
|
71
|
+
freshness: index.freshness,
|
|
72
|
+
text: `${freshnessBanner(index.freshness)}\nNo graph target matched. Provide a file or symbol.`,
|
|
73
|
+
data: { target: null },
|
|
74
|
+
refresh: { refreshed: false }
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function graphNodeIdsForTarget(index, target) {
|
|
79
|
+
const ids = new Set();
|
|
80
|
+
if (target.file) {
|
|
81
|
+
ids.add(target.file.id);
|
|
82
|
+
for (const symbol of index.symbols.filter((candidate) => candidate.path === target.file.path)) {
|
|
83
|
+
ids.add(symbol.id);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (target.symbol) {
|
|
87
|
+
ids.add(target.symbol.id);
|
|
88
|
+
}
|
|
89
|
+
for (const filePath of target.paths) {
|
|
90
|
+
const file = findFile(index, filePath);
|
|
91
|
+
if (file) {
|
|
92
|
+
ids.add(file.id);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return ids;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.js","sourceRoot":"","sources":["../../src/query/targets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Confidence } from "../types.js";
|
|
2
|
+
export interface CandidateTestCommand {
|
|
3
|
+
command: string;
|
|
4
|
+
commandCwd: string;
|
|
5
|
+
commandExecutable: string;
|
|
6
|
+
commandArgs: string[];
|
|
7
|
+
source: string;
|
|
8
|
+
confidence: Confidence;
|
|
9
|
+
}
|
|
10
|
+
export declare function candidateTestCommand(repoRoot: string, testPath: string): CandidateTestCommand | undefined;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { shellQuote } from "./verification/shell.js";
|
|
4
|
+
export function candidateTestCommand(repoRoot, testPath) {
|
|
5
|
+
if (/\.py$/.test(testPath)) {
|
|
6
|
+
return pythonTestCommand(repoRoot, testPath);
|
|
7
|
+
}
|
|
8
|
+
if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(testPath)) {
|
|
9
|
+
const packageRoot = nearestPackageRoot(repoRoot, testPath);
|
|
10
|
+
const relativeTestPath = packageRoot === "." ? testPath : path.posix.relative(packageRoot, testPath);
|
|
11
|
+
return packageTestCommand(repoRoot, packageRoot, relativeTestPath);
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
function nearestPackageRoot(repoRoot, testPath) {
|
|
16
|
+
let dir = path.posix.dirname(testPath);
|
|
17
|
+
while (dir && dir !== ".") {
|
|
18
|
+
if (existsSync(path.join(repoRoot, dir, "package.json"))) {
|
|
19
|
+
return dir;
|
|
20
|
+
}
|
|
21
|
+
dir = path.posix.dirname(dir);
|
|
22
|
+
}
|
|
23
|
+
return ".";
|
|
24
|
+
}
|
|
25
|
+
function packageTestCommand(repoRoot, packageDir, relativeTestPath) {
|
|
26
|
+
const packageRoot = path.join(repoRoot, packageDir);
|
|
27
|
+
const packageJsonPath = path.join(packageRoot, "package.json");
|
|
28
|
+
if (!existsSync(packageJsonPath)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
33
|
+
const scripts = parsed.scripts ?? {};
|
|
34
|
+
const scriptName = scripts.test && /\b(vitest|jest|node --test|tsx|tsc)\b/.test(scripts.test)
|
|
35
|
+
? "test"
|
|
36
|
+
: Object.keys(scripts).find((name) => /^test:/u.test(name) && /\b(vitest|jest|node --test|tsx|tsc)\b/.test(scripts[name])) ?? (scripts.test ? "test" : undefined);
|
|
37
|
+
if (!scriptName) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const packageManager = packageManagerFor(packageRoot, repoRoot);
|
|
41
|
+
const cwd = packageDir === "." ? repoRoot : path.join(repoRoot, packageDir);
|
|
42
|
+
const runner = packageManager === "npm" ? ["npm", "run", scriptName] : [packageManager, "run", scriptName];
|
|
43
|
+
const args = [...runner.slice(1), "--", relativeTestPath];
|
|
44
|
+
return {
|
|
45
|
+
command: shellJoin(["cd", cwd]) + " && " + shellJoin([runner[0], ...args]),
|
|
46
|
+
commandCwd: cwd,
|
|
47
|
+
commandExecutable: runner[0],
|
|
48
|
+
commandArgs: args,
|
|
49
|
+
source: `${packageDir === "." ? "" : `${packageDir}/`}package.json#scripts.${scriptName}`,
|
|
50
|
+
confidence: "heuristic"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function packageManagerFor(packageRoot, repoRoot) {
|
|
58
|
+
if (existsSync(path.join(packageRoot, "pnpm-lock.yaml"))) {
|
|
59
|
+
return "pnpm";
|
|
60
|
+
}
|
|
61
|
+
if (existsSync(path.join(packageRoot, "yarn.lock"))) {
|
|
62
|
+
return "yarn";
|
|
63
|
+
}
|
|
64
|
+
if (packageRoot !== repoRoot && existsSync(path.join(repoRoot, "pnpm-lock.yaml"))) {
|
|
65
|
+
return "pnpm";
|
|
66
|
+
}
|
|
67
|
+
if (packageRoot !== repoRoot && existsSync(path.join(repoRoot, "yarn.lock"))) {
|
|
68
|
+
return "yarn";
|
|
69
|
+
}
|
|
70
|
+
return "npm";
|
|
71
|
+
}
|
|
72
|
+
function pythonTestCommand(repoRoot, testPath) {
|
|
73
|
+
const pyprojectPath = path.join(repoRoot, "pyproject.toml");
|
|
74
|
+
const pytestIniPath = path.join(repoRoot, "pytest.ini");
|
|
75
|
+
const toxIniPath = path.join(repoRoot, "tox.ini");
|
|
76
|
+
const setupCfgPath = path.join(repoRoot, "setup.cfg");
|
|
77
|
+
const requirements = ["requirements.txt", "requirements-dev.txt", "requirements-test.txt"]
|
|
78
|
+
.map((file) => path.join(repoRoot, file))
|
|
79
|
+
.filter((file) => existsSync(file));
|
|
80
|
+
const metadataSources = [];
|
|
81
|
+
let hasPytestEvidence = false;
|
|
82
|
+
for (const candidate of [pyprojectPath, pytestIniPath, toxIniPath, setupCfgPath, ...requirements]) {
|
|
83
|
+
if (!existsSync(candidate)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const relative = path.relative(repoRoot, candidate) || path.basename(candidate);
|
|
87
|
+
const text = readFileSync(candidate, "utf8");
|
|
88
|
+
if (/pytest/i.test(text) || path.basename(candidate) === "pytest.ini") {
|
|
89
|
+
hasPytestEvidence = true;
|
|
90
|
+
metadataSources.push(relative);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!hasPytestEvidence) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
const runner = existsSync(path.join(repoRoot, "uv.lock")) ? ["uv", "run", "pytest"] : ["pytest"];
|
|
97
|
+
const args = [...runner.slice(1), testPath];
|
|
98
|
+
return {
|
|
99
|
+
command: shellJoin(["cd", repoRoot]) + " && " + shellJoin([runner[0], ...args]),
|
|
100
|
+
commandCwd: repoRoot,
|
|
101
|
+
commandExecutable: runner[0],
|
|
102
|
+
commandArgs: args,
|
|
103
|
+
source: metadataSources.slice(0, 3).join(", "),
|
|
104
|
+
confidence: "heuristic"
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function shellJoin(parts) {
|
|
108
|
+
return parts.map(shellQuote).join(" ");
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=test-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-commands.js","sourceRoot":"","sources":["../../src/query/test-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type QuerySessionInput } from "./session.js";
|
|
2
|
+
import type { ChangeType, QueryOptions, QueryResult } from "../types.js";
|
|
3
|
+
export interface TestPlanOptions extends QueryOptions {
|
|
4
|
+
changeType?: ChangeType;
|
|
5
|
+
}
|
|
6
|
+
export declare function testPlanQuery(input: QuerySessionInput, diff?: boolean, options?: TestPlanOptions): Promise<QueryResult>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { formatDiffGroups, formatGaps, groupDiffImpact, indexGaps } from "./diff.js";
|
|
2
|
+
import { freshnessBanner } from "./runtime.js";
|
|
3
|
+
import { ensureQuerySession } from "./session.js";
|
|
4
|
+
import { formatOutcomeLearningRecommendations, formatTestRecommendations, outcomeLearningRecommendations, recommendTests } from "./tests.js";
|
|
5
|
+
import { compactChangedSymbol, compactDiffGroup } from "./compact-data.js";
|
|
6
|
+
import { compactWorktreeState, getWorktreeState, worktreeStateGaps, worktreeStateText } from "./worktree-state.js";
|
|
7
|
+
import { formatVerificationCoverage, formatVerificationLedger, verificationCommandPlan, verificationCommandsForContext, verificationLedgerForPostEdit } from "./verification.js";
|
|
8
|
+
import { CURRENT_VERIFICATION_PROVENANCE } from "../types.js";
|
|
9
|
+
import { limitText } from "../util.js";
|
|
10
|
+
export async function testPlanQuery(input, diff = true, options = {}) {
|
|
11
|
+
const session = await ensureQuerySession(input, options);
|
|
12
|
+
const { index, freshness, refresh, repoRoot } = session;
|
|
13
|
+
const indexedPaths = new Set(index.files.map((file) => file.path));
|
|
14
|
+
const worktree = diff ? await getWorktreeState(session) : undefined;
|
|
15
|
+
const changedEntries = worktree?.entries ?? [];
|
|
16
|
+
const changed = worktree?.files ?? [];
|
|
17
|
+
const changedSymbols = worktree?.symbols ?? [];
|
|
18
|
+
const unindexedChanged = changed.filter((file) => !indexedPaths.has(file));
|
|
19
|
+
const groups = groupDiffImpact(index, changedEntries, changedSymbols, unindexedChanged);
|
|
20
|
+
const gaps = [...indexGaps(index, freshness, unindexedChanged), ...(worktree ? worktreeStateGaps(worktree) : [])];
|
|
21
|
+
const changeType = options.changeType ?? "unknown";
|
|
22
|
+
const tests = recommendTests(index, changed.length > 0 ? changed : index.files.slice(0, 10).map((file) => file.path), repoRoot, changeType);
|
|
23
|
+
const outcomeLearning = outcomeLearningRecommendations(tests, 8);
|
|
24
|
+
const verificationCommands = verificationCommandsForContext(index, repoRoot, changed.length > 0 ? changed : index.files.slice(0, 10).map((file) => file.path), tests, 16);
|
|
25
|
+
const verificationPreview = verificationLedgerForPostEdit({
|
|
26
|
+
index,
|
|
27
|
+
tests,
|
|
28
|
+
ranTests: [],
|
|
29
|
+
ranCommands: verificationCommands,
|
|
30
|
+
repoRoot
|
|
31
|
+
});
|
|
32
|
+
const missingVerification = verificationLedgerForPostEdit({
|
|
33
|
+
index,
|
|
34
|
+
tests,
|
|
35
|
+
ranTests: [],
|
|
36
|
+
ranCommands: [],
|
|
37
|
+
repoRoot
|
|
38
|
+
});
|
|
39
|
+
const verificationCoverage = verificationPreview.coverage;
|
|
40
|
+
const commandPlan = verificationCommandPlan(verificationCoverage);
|
|
41
|
+
const verificationLedgerPreview = markLedgerAsPreview(verificationPreview.ledger);
|
|
42
|
+
const text = [
|
|
43
|
+
freshnessBanner(freshness, refresh),
|
|
44
|
+
`Test plan for ${changed.length > 0 ? `${changed.length} changed files` : "top-ranked files"}:`,
|
|
45
|
+
...(groups.length > 0 ? ["", "Change groups:", ...formatDiffGroups(groups.slice(0, 12))] : []),
|
|
46
|
+
"",
|
|
47
|
+
...(changedSymbols.length > 0
|
|
48
|
+
? [
|
|
49
|
+
"Changed symbols:",
|
|
50
|
+
...changedSymbols
|
|
51
|
+
.slice(0, 20)
|
|
52
|
+
.map((entry) => `- ${entry.symbol.qualifiedName} (${entry.symbol.kind}) at ${entry.symbol.path}:${entry.symbol.range?.startLine ?? 1}`)
|
|
53
|
+
]
|
|
54
|
+
: []),
|
|
55
|
+
...formatTestRecommendations(tests.slice(0, 30)),
|
|
56
|
+
...(outcomeLearning.length > 0 ? ["", "Outcome learning:", ...formatOutcomeLearningRecommendations(outcomeLearning)] : []),
|
|
57
|
+
"",
|
|
58
|
+
"If run, these commands would cover:",
|
|
59
|
+
...formatVerificationCoverage(verificationCoverage),
|
|
60
|
+
"",
|
|
61
|
+
"Verification ledger preview if recommended commands are run:",
|
|
62
|
+
...formatVerificationLedger(verificationLedgerPreview),
|
|
63
|
+
...(unindexedChanged.length > 0 ? ["", "Changed but not indexed:", ...unindexedChanged.slice(0, 20).map((file) => `- ${file}`)] : []),
|
|
64
|
+
"",
|
|
65
|
+
"Known gaps:",
|
|
66
|
+
...formatGaps(gaps),
|
|
67
|
+
...(worktree ? worktreeStateText(worktree) : [])
|
|
68
|
+
].join("\n");
|
|
69
|
+
return {
|
|
70
|
+
freshness,
|
|
71
|
+
refresh,
|
|
72
|
+
text: limitText(text, 6000),
|
|
73
|
+
data: {
|
|
74
|
+
mode: "test_plan",
|
|
75
|
+
changedFiles: changed.slice(0, 120),
|
|
76
|
+
changedEntries: changedEntries.slice(0, 120),
|
|
77
|
+
changedSymbols: changedSymbols.slice(0, 80).map(compactChangedSymbol),
|
|
78
|
+
unindexedChanged: unindexedChanged.slice(0, 80),
|
|
79
|
+
worktree: worktree ? compactWorktreeState(worktree) : undefined,
|
|
80
|
+
worktreeDegradationReasons: worktree?.degradedReasons ?? [],
|
|
81
|
+
groups: groups.slice(0, 20).map(compactDiffGroup),
|
|
82
|
+
tests: tests.slice(0, 30),
|
|
83
|
+
outcomeLearning,
|
|
84
|
+
verificationCommands: verificationCommands.slice(0, 30),
|
|
85
|
+
verificationCoverage: verificationCoverage.slice(0, 60),
|
|
86
|
+
commandEnvelopes: verificationPreview.commandEnvelopes.slice(0, 60),
|
|
87
|
+
verificationCommandPlan: commandPlan.slice(0, 40),
|
|
88
|
+
verificationLedgerPreview: verificationLedgerPreview.slice(0, 60),
|
|
89
|
+
verificationProvenance: CURRENT_VERIFICATION_PROVENANCE,
|
|
90
|
+
testsNotRun: missingVerification.testsNotRun.slice(0, 30),
|
|
91
|
+
gaps
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function markLedgerAsPreview(ledger) {
|
|
96
|
+
return ledger.map((entry) => entry.status === "covered"
|
|
97
|
+
? {
|
|
98
|
+
...entry,
|
|
99
|
+
status: "would_cover",
|
|
100
|
+
evidence: entry.evidence.map((item) => `would cover if run: ${item}`)
|
|
101
|
+
}
|
|
102
|
+
: entry);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=test-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-plan.js","sourceRoot":"","sources":["../../src/query/test-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ChangeType, CodexaIndex, TestRecommendation, TestRecommendationProvenanceSource } from "../types.js";
|
|
2
|
+
export interface OutcomeLearningRecommendation {
|
|
3
|
+
path: string;
|
|
4
|
+
rank: number;
|
|
5
|
+
reason: string;
|
|
6
|
+
command?: string;
|
|
7
|
+
targetPaths: string[];
|
|
8
|
+
sources: TestRecommendationProvenanceSource[];
|
|
9
|
+
evidence: string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Recommend tests to run for a set of changed paths.
|
|
13
|
+
*
|
|
14
|
+
* `changeType` narrows cross-language recommendations so editorial noise
|
|
15
|
+
* stays low:
|
|
16
|
+
*
|
|
17
|
+
* - "style" — the edit is a cosmetic/presentation change (CSS,
|
|
18
|
+
* Tailwind-class swap, template-only markup). Python pytest files are
|
|
19
|
+
* dropped from the recommendation list when no Python source was
|
|
20
|
+
* actually edited, because a style diff cannot break Python behavior.
|
|
21
|
+
* Likewise, TypeScript test files are dropped when no TS/JS source
|
|
22
|
+
* was edited.
|
|
23
|
+
* - "rename" / "delete" / "api" / "behavior" / "unknown" — today's
|
|
24
|
+
* behavior: surface everything the graph indicates.
|
|
25
|
+
*
|
|
26
|
+
* The filter only prunes authoritative/derived entries whose language
|
|
27
|
+
* demonstrably cannot be affected by the edited files. Heuristic/fallback
|
|
28
|
+
* entries already go through `compatibleKindWithTest()` for the same
|
|
29
|
+
* reason.
|
|
30
|
+
*/
|
|
31
|
+
export declare function recommendTests(index: CodexaIndex, paths: string[], repoRoot?: string, changeType?: ChangeType): TestRecommendation[];
|
|
32
|
+
/**
|
|
33
|
+
* Apply change-type narrowing to an already-merged test recommendation
|
|
34
|
+
* set (e.g. snapshot-planned + context-derived + freshly-recommended).
|
|
35
|
+
* Safe to run on any list; it's a no-op for change types other than
|
|
36
|
+
* style and it never drops authoritative/derived tier entries.
|
|
37
|
+
*
|
|
38
|
+
* Used by post-edit review to ensure that a snapshot saved WITHOUT a
|
|
39
|
+
* change-type — the common case when `/codexa-plan` runs before the
|
|
40
|
+
* user decides the edit is cosmetic — still produces a clean
|
|
41
|
+
* recommendation set when the user later runs `--change-type style`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function narrowTestRecommendationsByChangeType(results: TestRecommendation[], paths: string[], changeType: ChangeType): TestRecommendation[];
|
|
44
|
+
export declare function formatTestRecommendations(tests: TestRecommendation[]): string[];
|
|
45
|
+
export declare function outcomeLearningRecommendations(tests: TestRecommendation[], limit?: number): OutcomeLearningRecommendation[];
|
|
46
|
+
export declare function formatOutcomeLearningRecommendations(recommendations: OutcomeLearningRecommendation[]): string[];
|
|
47
|
+
export declare function uniqueTests(tests: TestRecommendation[]): TestRecommendation[];
|
|
48
|
+
export declare function wasTestRun(test: TestRecommendation, ranTests: string[]): boolean;
|