@open-cr-agent/core 0.1.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.
Files changed (163) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +3 -0
  3. package/dist/anchor/anchor.d.ts +24 -0
  4. package/dist/anchor/anchor.js +66 -0
  5. package/dist/anchor/index.d.ts +3 -0
  6. package/dist/anchor/index.js +3 -0
  7. package/dist/anchor/match.d.ts +22 -0
  8. package/dist/anchor/match.js +94 -0
  9. package/dist/anchor/relocate.d.ts +5 -0
  10. package/dist/anchor/relocate.js +38 -0
  11. package/dist/bundle/bundle.d.ts +22 -0
  12. package/dist/bundle/bundle.js +102 -0
  13. package/dist/bundle/grouping.d.ts +16 -0
  14. package/dist/bundle/grouping.js +25 -0
  15. package/dist/bundle/index.d.ts +3 -0
  16. package/dist/bundle/index.js +3 -0
  17. package/dist/contracts.d.ts +77 -0
  18. package/dist/contracts.js +2 -0
  19. package/dist/diff/hunks.d.ts +3 -0
  20. package/dist/diff/hunks.js +64 -0
  21. package/dist/diff/index.d.ts +3 -0
  22. package/dist/diff/index.js +3 -0
  23. package/dist/diff/parse.d.ts +3 -0
  24. package/dist/diff/parse.js +116 -0
  25. package/dist/diff/quoted-path.d.ts +6 -0
  26. package/dist/diff/quoted-path.js +46 -0
  27. package/dist/domain.d.ts +126 -0
  28. package/dist/domain.js +23 -0
  29. package/dist/errors.d.ts +8 -0
  30. package/dist/errors.js +16 -0
  31. package/dist/index.d.ts +18 -0
  32. package/dist/index.js +18 -0
  33. package/dist/judge/index.d.ts +4 -0
  34. package/dist/judge/index.js +4 -0
  35. package/dist/judge/judge.d.ts +46 -0
  36. package/dist/judge/judge.js +122 -0
  37. package/dist/judge/prompt.d.ts +25 -0
  38. package/dist/judge/prompt.js +62 -0
  39. package/dist/judge/verdict.d.ts +9 -0
  40. package/dist/judge/verdict.js +26 -0
  41. package/dist/memory/index.d.ts +2 -0
  42. package/dist/memory/index.js +2 -0
  43. package/dist/memory/memory.d.ts +19 -0
  44. package/dist/memory/memory.js +49 -0
  45. package/dist/pipeline/budget.d.ts +9 -0
  46. package/dist/pipeline/budget.js +19 -0
  47. package/dist/pipeline/context.d.ts +6 -0
  48. package/dist/pipeline/context.js +71 -0
  49. package/dist/pipeline/execute.d.ts +32 -0
  50. package/dist/pipeline/execute.js +122 -0
  51. package/dist/pipeline/findings.d.ts +6 -0
  52. package/dist/pipeline/findings.js +44 -0
  53. package/dist/pipeline/helpers.d.ts +6 -0
  54. package/dist/pipeline/helpers.js +32 -0
  55. package/dist/pipeline/index.d.ts +9 -0
  56. package/dist/pipeline/index.js +9 -0
  57. package/dist/pipeline/matrix.d.ts +38 -0
  58. package/dist/pipeline/matrix.js +93 -0
  59. package/dist/pipeline/output.d.ts +69 -0
  60. package/dist/pipeline/output.js +123 -0
  61. package/dist/pipeline/plan.d.ts +34 -0
  62. package/dist/pipeline/plan.js +68 -0
  63. package/dist/pipeline/pool.d.ts +2 -0
  64. package/dist/pipeline/pool.js +13 -0
  65. package/dist/pipeline/preview.d.ts +42 -0
  66. package/dist/pipeline/preview.js +73 -0
  67. package/dist/pipeline/report.d.ts +118 -0
  68. package/dist/pipeline/report.js +27 -0
  69. package/dist/pipeline/run.d.ts +36 -0
  70. package/dist/pipeline/run.js +301 -0
  71. package/dist/pipeline/task.d.ts +19 -0
  72. package/dist/pipeline/task.js +143 -0
  73. package/dist/pipeline/usage.d.ts +4 -0
  74. package/dist/pipeline/usage.js +13 -0
  75. package/dist/plugin/builtin.d.ts +14 -0
  76. package/dist/plugin/builtin.js +47 -0
  77. package/dist/plugin/host.d.ts +9 -0
  78. package/dist/plugin/host.js +78 -0
  79. package/dist/plugin/index.d.ts +5 -0
  80. package/dist/plugin/index.js +5 -0
  81. package/dist/plugin/registry.d.ts +37 -0
  82. package/dist/plugin/registry.js +104 -0
  83. package/dist/plugin/types.d.ts +53 -0
  84. package/dist/plugin/types.js +2 -0
  85. package/dist/rereview/index.d.ts +4 -0
  86. package/dist/rereview/index.js +4 -0
  87. package/dist/rereview/presence.d.ts +3 -0
  88. package/dist/rereview/presence.js +27 -0
  89. package/dist/rereview/quote.d.ts +4 -0
  90. package/dist/rereview/quote.js +28 -0
  91. package/dist/rereview/reconcile.d.ts +20 -0
  92. package/dist/rereview/reconcile.js +55 -0
  93. package/dist/review/impact.d.ts +11 -0
  94. package/dist/review/impact.js +53 -0
  95. package/dist/review/index.d.ts +10 -0
  96. package/dist/review/index.js +10 -0
  97. package/dist/review/plan-phase.d.ts +10 -0
  98. package/dist/review/plan-phase.js +33 -0
  99. package/dist/review/prompt-text.d.ts +16 -0
  100. package/dist/review/prompt-text.js +90 -0
  101. package/dist/review/prompt.d.ts +28 -0
  102. package/dist/review/prompt.js +85 -0
  103. package/dist/review/reviewer.d.ts +17 -0
  104. package/dist/review/reviewer.js +2 -0
  105. package/dist/review/reviewers/agents-md.d.ts +3 -0
  106. package/dist/review/reviewers/agents-md.js +45 -0
  107. package/dist/review/reviewers/correctness.d.ts +3 -0
  108. package/dist/review/reviewers/correctness.js +48 -0
  109. package/dist/review/reviewers/docs.d.ts +3 -0
  110. package/dist/review/reviewers/docs.js +47 -0
  111. package/dist/review/reviewers/performance.d.ts +3 -0
  112. package/dist/review/reviewers/performance.js +59 -0
  113. package/dist/review/reviewers/scopes.d.ts +3 -0
  114. package/dist/review/reviewers/scopes.js +9 -0
  115. package/dist/review/reviewers/security.d.ts +3 -0
  116. package/dist/review/reviewers/security.js +52 -0
  117. package/dist/review/tools.d.ts +9 -0
  118. package/dist/review/tools.js +8 -0
  119. package/dist/rules/builtin/general.d.ts +2 -0
  120. package/dist/rules/builtin/general.js +9 -0
  121. package/dist/rules/builtin/go.d.ts +2 -0
  122. package/dist/rules/builtin/go.js +9 -0
  123. package/dist/rules/builtin/index.d.ts +9 -0
  124. package/dist/rules/builtin/index.js +16 -0
  125. package/dist/rules/builtin/java.d.ts +2 -0
  126. package/dist/rules/builtin/java.js +9 -0
  127. package/dist/rules/builtin/performance.d.ts +2 -0
  128. package/dist/rules/builtin/performance.js +9 -0
  129. package/dist/rules/builtin/python.d.ts +2 -0
  130. package/dist/rules/builtin/python.js +9 -0
  131. package/dist/rules/builtin/security.d.ts +2 -0
  132. package/dist/rules/builtin/security.js +11 -0
  133. package/dist/rules/builtin/typescript.d.ts +2 -0
  134. package/dist/rules/builtin/typescript.js +9 -0
  135. package/dist/rules/index.d.ts +5 -0
  136. package/dist/rules/index.js +5 -0
  137. package/dist/rules/languages.d.ts +3 -0
  138. package/dist/rules/languages.js +20 -0
  139. package/dist/rules/repo-rules.d.ts +15 -0
  140. package/dist/rules/repo-rules.js +22 -0
  141. package/dist/rules/resolve.d.ts +4 -0
  142. package/dist/rules/resolve.js +27 -0
  143. package/dist/rules/rule-set.d.ts +6 -0
  144. package/dist/rules/rule-set.js +2 -0
  145. package/dist/select/index.d.ts +2 -0
  146. package/dist/select/index.js +2 -0
  147. package/dist/select/patterns.d.ts +6 -0
  148. package/dist/select/patterns.js +132 -0
  149. package/dist/select/select.d.ts +19 -0
  150. package/dist/select/select.js +52 -0
  151. package/dist/session/index.d.ts +2 -0
  152. package/dist/session/index.js +2 -0
  153. package/dist/session/jsonl.d.ts +11 -0
  154. package/dist/session/jsonl.js +57 -0
  155. package/dist/triage.d.ts +11 -0
  156. package/dist/triage.js +55 -0
  157. package/dist/verify/index.d.ts +3 -0
  158. package/dist/verify/index.js +3 -0
  159. package/dist/verify/prompt.d.ts +24 -0
  160. package/dist/verify/prompt.js +71 -0
  161. package/dist/verify/verify.d.ts +29 -0
  162. package/dist/verify/verify.js +98 -0
  163. package/package.json +40 -0
@@ -0,0 +1,2 @@
1
+ export declare const PERFORMANCE_RULES = "### Performance\n- Algorithmic complexity that grows with input the code cannot bound: nested loops over the same collections, repeated linear searches or `includes` inside loops where a set or map fits, sorting inside loops.\n- Round trips in loops: database queries, HTTP calls or file reads per item (N+1) where one batched call works; queries on new filters that fetch unbounded result sets without a limit or pagination.\n- Blocking work on latency-sensitive paths: synchronous file, network or CPU-heavy work in request handlers, event loops, UI threads or `async` functions.\n- Memory: whole files, streams or result sets buffered when their size is external; caches, maps or listener lists that grow without eviction or removal.\n- Repeated work on hot paths: recomputation or re-parsing inside loops, regular expressions or serializers rebuilt per call, React renders triggered by unstable dependencies or props.\n- Concurrency: independent I/O awaited one after another on a latency-critical path; unbounded parallelism that overwhelms a pool, a rate limit or memory.\n- Regressions of existing optimizations: removed indexes, caches, batching, streaming or early exits.";
2
+ //# sourceMappingURL=performance.d.ts.map
@@ -0,0 +1,9 @@
1
+ export const PERFORMANCE_RULES = `### Performance
2
+ - Algorithmic complexity that grows with input the code cannot bound: nested loops over the same collections, repeated linear searches or \`includes\` inside loops where a set or map fits, sorting inside loops.
3
+ - Round trips in loops: database queries, HTTP calls or file reads per item (N+1) where one batched call works; queries on new filters that fetch unbounded result sets without a limit or pagination.
4
+ - Blocking work on latency-sensitive paths: synchronous file, network or CPU-heavy work in request handlers, event loops, UI threads or \`async\` functions.
5
+ - Memory: whole files, streams or result sets buffered when their size is external; caches, maps or listener lists that grow without eviction or removal.
6
+ - Repeated work on hot paths: recomputation or re-parsing inside loops, regular expressions or serializers rebuilt per call, React renders triggered by unstable dependencies or props.
7
+ - Concurrency: independent I/O awaited one after another on a latency-critical path; unbounded parallelism that overwhelms a pool, a rate limit or memory.
8
+ - Regressions of existing optimizations: removed indexes, caches, batching, streaming or early exits.`;
9
+ //# sourceMappingURL=performance.js.map
@@ -0,0 +1,2 @@
1
+ export declare const PYTHON_RULES = "### Python\n- Mutable default arguments or class attributes shared across calls or instances when per-call state was intended.\n- Broad `except` (bare or `Exception`) that swallows errors, including `KeyboardInterrupt`/`SystemExit` via bare `except`, or re-raises without the original cause.\n- Resources opened without `with` or `try/finally` on paths that can raise.\n- Blocking calls inside `async def` code, coroutines that are never awaited, or tasks created without keeping a reference.\n- Truthiness checks that misclassify valid values (`0`, `\"\"`, empty collections) where `is None` was meant.\n- Late-binding closures in loops, iteration while mutating the same collection, integer vs float division mistakes.\n- SQL, shell or template strings built from input instead of parameters; `pickle`/`yaml.load` on untrusted data.";
2
+ //# sourceMappingURL=python.d.ts.map
@@ -0,0 +1,9 @@
1
+ export const PYTHON_RULES = `### Python
2
+ - Mutable default arguments or class attributes shared across calls or instances when per-call state was intended.
3
+ - Broad \`except\` (bare or \`Exception\`) that swallows errors, including \`KeyboardInterrupt\`/\`SystemExit\` via bare \`except\`, or re-raises without the original cause.
4
+ - Resources opened without \`with\` or \`try/finally\` on paths that can raise.
5
+ - Blocking calls inside \`async def\` code, coroutines that are never awaited, or tasks created without keeping a reference.
6
+ - Truthiness checks that misclassify valid values (\`0\`, \`""\`, empty collections) where \`is None\` was meant.
7
+ - Late-binding closures in loops, iteration while mutating the same collection, integer vs float division mistakes.
8
+ - SQL, shell or template strings built from input instead of parameters; \`pickle\`/\`yaml.load\` on untrusted data.`;
9
+ //# sourceMappingURL=python.js.map
@@ -0,0 +1,2 @@
1
+ export declare const SECURITY_RULES = "### Security\n- Injection from input that reaches an interpreter: SQL or NoSQL built from strings, shell commands, template rendering, LDAP or XPath, HTML without escaping (XSS), headers or log lines with raw newlines.\n- Server-side request forgery and path traversal: URLs, hosts or file paths built from input without an allow-list or containment check, including archive extraction.\n- Authentication and authorization: new routes, handlers, jobs or queries without the checks their neighbours apply; object access by id without an ownership or tenant check (IDOR); privilege or role checks that can be bypassed or were weakened.\n- Secrets and sensitive data: credentials or tokens in code or config, secrets or personal data written to logs, errors, analytics or responses; session tokens or API keys exposed to the client.\n- Cryptography: home-made crypto, weak or misused algorithms (MD5/SHA-1 for passwords, ECB, static IVs), non-cryptographic randomness for tokens, disabled certificate or signature verification, timing-unsafe secret comparison.\n- Unsafe parsing: deserialization of untrusted data (pickle, Java serialization, YAML full loaders), XML external entities, prototype pollution through deep merges, regular expressions with catastrophic backtracking on input.\n- Resource exhaustion from untrusted input: unbounded sizes, counts, recursion or allocation that an external caller controls.\n- Configuration: permissive CORS with credentials, cookies without Secure/HttpOnly/SameSite where they carry sessions, debug modes or verbose errors enabled in production paths, world-writable files.\n- CI and supply chain: untrusted pull request text or branch names interpolated into workflow `run:` steps, `pull_request_target` checking out untrusted code with secrets, broadened workflow permissions, new dependencies from unexpected sources or install scripts.";
2
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1,11 @@
1
+ export const SECURITY_RULES = `### Security
2
+ - Injection from input that reaches an interpreter: SQL or NoSQL built from strings, shell commands, template rendering, LDAP or XPath, HTML without escaping (XSS), headers or log lines with raw newlines.
3
+ - Server-side request forgery and path traversal: URLs, hosts or file paths built from input without an allow-list or containment check, including archive extraction.
4
+ - Authentication and authorization: new routes, handlers, jobs or queries without the checks their neighbours apply; object access by id without an ownership or tenant check (IDOR); privilege or role checks that can be bypassed or were weakened.
5
+ - Secrets and sensitive data: credentials or tokens in code or config, secrets or personal data written to logs, errors, analytics or responses; session tokens or API keys exposed to the client.
6
+ - Cryptography: home-made crypto, weak or misused algorithms (MD5/SHA-1 for passwords, ECB, static IVs), non-cryptographic randomness for tokens, disabled certificate or signature verification, timing-unsafe secret comparison.
7
+ - Unsafe parsing: deserialization of untrusted data (pickle, Java serialization, YAML full loaders), XML external entities, prototype pollution through deep merges, regular expressions with catastrophic backtracking on input.
8
+ - Resource exhaustion from untrusted input: unbounded sizes, counts, recursion or allocation that an external caller controls.
9
+ - Configuration: permissive CORS with credentials, cookies without Secure/HttpOnly/SameSite where they carry sessions, debug modes or verbose errors enabled in production paths, world-writable files.
10
+ - CI and supply chain: untrusted pull request text or branch names interpolated into workflow \`run:\` steps, \`pull_request_target\` checking out untrusted code with secrets, broadened workflow permissions, new dependencies from unexpected sources or install scripts.`;
11
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1,2 @@
1
+ export declare const TYPESCRIPT_RULES = "### TypeScript and JavaScript\n- Promises that are neither awaited, returned nor explicitly handled, so failures become unhandled rejections or ordering is lost; `forEach` with async callbacks that callers assume completed.\n- `await` inside loops where independent work was meant to run concurrently, or `Promise.all` over work that must be sequential or bounded.\n- Truthiness checks that misclassify valid values (`0`, `\"\"`, `NaN`, `false`) where `??` or an explicit comparison was needed; `==` comparisons with surprising coercion.\n- Type assertions (`as`, non-null `!`, `any`) that bypass a check the runtime data can actually fail; parsed external data used without validation.\n- Mutation of arguments, shared module state or React state/props in place; missing or wrong hook dependencies that cause stale values or infinite loops.\n- Floating timers, listeners or subscriptions without cleanup on unmount, abort or error.\n- `JSON.parse`, `new URL`, `BigInt` and similar calls on external input without handling their exceptions.";
2
+ //# sourceMappingURL=typescript.d.ts.map
@@ -0,0 +1,9 @@
1
+ export const TYPESCRIPT_RULES = `### TypeScript and JavaScript
2
+ - Promises that are neither awaited, returned nor explicitly handled, so failures become unhandled rejections or ordering is lost; \`forEach\` with async callbacks that callers assume completed.
3
+ - \`await\` inside loops where independent work was meant to run concurrently, or \`Promise.all\` over work that must be sequential or bounded.
4
+ - Truthiness checks that misclassify valid values (\`0\`, \`""\`, \`NaN\`, \`false\`) where \`??\` or an explicit comparison was needed; \`==\` comparisons with surprising coercion.
5
+ - Type assertions (\`as\`, non-null \`!\`, \`any\`) that bypass a check the runtime data can actually fail; parsed external data used without validation.
6
+ - Mutation of arguments, shared module state or React state/props in place; missing or wrong hook dependencies that cause stale values or infinite loops.
7
+ - Floating timers, listeners or subscriptions without cleanup on unmount, abort or error.
8
+ - \`JSON.parse\`, \`new URL\`, \`BigInt\` and similar calls on external input without handling their exceptions.`;
9
+ //# sourceMappingURL=typescript.js.map
@@ -0,0 +1,5 @@
1
+ export * from "./languages.js";
2
+ export * from "./repo-rules.js";
3
+ export * from "./resolve.js";
4
+ export * from "./rule-set.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,5 @@
1
+ export * from "./languages.js";
2
+ export * from "./repo-rules.js";
3
+ export * from "./resolve.js";
4
+ export * from "./rule-set.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ export type Language = "typescript" | "python" | "go" | "java";
2
+ export declare function detectLanguage(path: string): Language | undefined;
3
+ //# sourceMappingURL=languages.d.ts.map
@@ -0,0 +1,20 @@
1
+ const EXTENSIONS = {
2
+ ts: "typescript",
3
+ tsx: "typescript",
4
+ mts: "typescript",
5
+ cts: "typescript",
6
+ js: "typescript",
7
+ jsx: "typescript",
8
+ mjs: "typescript",
9
+ cjs: "typescript",
10
+ py: "python",
11
+ pyi: "python",
12
+ go: "go",
13
+ java: "java",
14
+ };
15
+ export function detectLanguage(path) {
16
+ const name = path.slice(path.lastIndexOf("/") + 1);
17
+ const dot = name.lastIndexOf(".");
18
+ return dot > 0 ? EXTENSIONS[name.slice(dot + 1).toLowerCase()] : undefined;
19
+ }
20
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export declare const repoRuleSchema: z.ZodObject<{
3
+ path: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
4
+ rule: z.ZodString;
5
+ }, z.core.$strip>;
6
+ export type RepoRule = z.infer<typeof repoRuleSchema>;
7
+ export declare const repoRulesFileSchema: z.ZodObject<{
8
+ rules: z.ZodArray<z.ZodObject<{
9
+ path: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
10
+ rule: z.ZodString;
11
+ }, z.core.$strip>>;
12
+ }, z.core.$strip>;
13
+ export declare const REPO_RULES_PATH = ".ocra/rules.json";
14
+ export declare function parseRepoRules(json: string): RepoRule[];
15
+ //# sourceMappingURL=repo-rules.d.ts.map
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ export const repoRuleSchema = z.object({
3
+ path: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]),
4
+ rule: z.string().min(1),
5
+ });
6
+ export const repoRulesFileSchema = z.object({ rules: z.array(repoRuleSchema) });
7
+ export const REPO_RULES_PATH = ".ocra/rules.json";
8
+ export function parseRepoRules(json) {
9
+ let data;
10
+ try {
11
+ data = JSON.parse(json);
12
+ }
13
+ catch (error) {
14
+ throw new Error(`${REPO_RULES_PATH} is not valid JSON: ${error.message}`);
15
+ }
16
+ const parsed = repoRulesFileSchema.safeParse(data);
17
+ if (!parsed.success) {
18
+ throw new Error(`${REPO_RULES_PATH} is invalid: ${z.prettifyError(parsed.error)}`);
19
+ }
20
+ return parsed.data.rules;
21
+ }
22
+ //# sourceMappingURL=repo-rules.js.map
@@ -0,0 +1,4 @@
1
+ import type { RepoRule } from "./repo-rules.js";
2
+ import type { RuleSet } from "./rule-set.js";
3
+ export declare function resolveRules(paths: readonly string[], repoRules: readonly RepoRule[], builtin?: RuleSet): string;
4
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1,27 @@
1
+ import picomatch from "picomatch";
2
+ import { detectLanguage } from "./languages.js";
3
+ export function resolveRules(paths, repoRules, builtin = {}) {
4
+ const languages = new Set();
5
+ for (const path of paths) {
6
+ const language = detectLanguage(path);
7
+ if (language)
8
+ languages.add(language);
9
+ }
10
+ const sections = [];
11
+ if (builtin.general)
12
+ sections.push(builtin.general);
13
+ for (const language of [...languages].sort()) {
14
+ const rules = builtin.languages?.[language];
15
+ if (rules)
16
+ sections.push(rules);
17
+ }
18
+ const matching = repoRules.filter((r) => {
19
+ const matches = picomatch(r.path, { dot: true });
20
+ return paths.some((p) => matches(p));
21
+ });
22
+ if (matching.length > 0) {
23
+ sections.push(`### Repository rules\n${matching.map((r) => r.rule.trim()).join("\n\n")}`);
24
+ }
25
+ return sections.join("\n\n");
26
+ }
27
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1,6 @@
1
+ import type { Language } from "./languages.js";
2
+ export interface RuleSet {
3
+ general?: string;
4
+ languages?: Partial<Record<Language, string>>;
5
+ }
6
+ //# sourceMappingURL=rule-set.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rule-set.js.map
@@ -0,0 +1,2 @@
1
+ export * from "./select.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from "./select.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,6 @@
1
+ export declare const SECRET_PATTERNS: string[];
2
+ export declare const ENV_TEMPLATE_PATTERNS: string[];
3
+ export declare const NON_REVIEWABLE_EXTENSIONS: string[];
4
+ export declare const GENERATED_PATTERNS: string[];
5
+ export declare const MIGRATION_PATTERNS: string[];
6
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1,132 @@
1
+ export const SECRET_PATTERNS = [
2
+ "**/.env",
3
+ "**/.env.*",
4
+ "**/*.env",
5
+ "**/.envrc",
6
+ "**/*.pem",
7
+ "**/*.key",
8
+ "**/*.p12",
9
+ "**/*.pfx",
10
+ "**/*.keystore",
11
+ "**/*.jks",
12
+ "**/id_rsa*",
13
+ "**/id_ed25519*",
14
+ "**/id_ecdsa*",
15
+ "**/id_dsa*",
16
+ "**/*.p8",
17
+ "**/.npmrc",
18
+ "**/.pypirc",
19
+ "**/.netrc",
20
+ "**/.pgpass",
21
+ "**/.htpasswd",
22
+ "**/.vault-token",
23
+ "**/.secrets",
24
+ "**/.streamlit/secrets.toml",
25
+ "**/*.keytab",
26
+ "**/credentials.json",
27
+ "**/application_default_credentials.json",
28
+ "**/serviceAccountKey*.json",
29
+ "**/*firebase-adminsdk*.json",
30
+ "**/gha-creds-*.json",
31
+ "**/service-account*.json",
32
+ "**/secrets.{yml,yaml,json}",
33
+ "**/.git-credentials",
34
+ "**/.aws/credentials",
35
+ "**/.kube/config",
36
+ "**/kubeconfig",
37
+ "**/.docker/config.json",
38
+ "**/.dockercfg",
39
+ "**/*.tfvars",
40
+ "**/*.tfvars.json",
41
+ "**/*.tfstate",
42
+ "**/*.tfstate.backup",
43
+ "**/.cargo/credentials",
44
+ "**/.cargo/credentials.toml",
45
+ "**/.config/gh/hosts.yml",
46
+ "**/*.ovpn",
47
+ ];
48
+ export const ENV_TEMPLATE_PATTERNS = ["**/.env.example", "**/.env.sample", "**/.env.template"];
49
+ export const NON_REVIEWABLE_EXTENSIONS = [
50
+ "png",
51
+ "jpg",
52
+ "jpeg",
53
+ "gif",
54
+ "webp",
55
+ "ico",
56
+ "bmp",
57
+ "tiff",
58
+ "psd",
59
+ "mp3",
60
+ "mp4",
61
+ "wav",
62
+ "ogg",
63
+ "mov",
64
+ "avi",
65
+ "webm",
66
+ "woff",
67
+ "woff2",
68
+ "ttf",
69
+ "otf",
70
+ "eot",
71
+ "zip",
72
+ "gz",
73
+ "tgz",
74
+ "bz2",
75
+ "xz",
76
+ "7z",
77
+ "rar",
78
+ "jar",
79
+ "war",
80
+ "pdf",
81
+ "doc",
82
+ "docx",
83
+ "xls",
84
+ "xlsx",
85
+ "ppt",
86
+ "pptx",
87
+ "exe",
88
+ "dll",
89
+ "so",
90
+ "dylib",
91
+ "a",
92
+ "o",
93
+ "class",
94
+ "pyc",
95
+ "wasm",
96
+ "csv",
97
+ "tsv",
98
+ "parquet",
99
+ "db",
100
+ "sqlite",
101
+ ];
102
+ export const GENERATED_PATTERNS = [
103
+ "**/package-lock.json",
104
+ "**/npm-shrinkwrap.json",
105
+ "**/yarn.lock",
106
+ "**/pnpm-lock.yaml",
107
+ "**/bun.lock",
108
+ "**/bun.lockb",
109
+ "**/Cargo.lock",
110
+ "**/Gemfile.lock",
111
+ "**/poetry.lock",
112
+ "**/uv.lock",
113
+ "**/Pipfile.lock",
114
+ "**/composer.lock",
115
+ "**/go.sum",
116
+ "**/flake.lock",
117
+ "**/node_modules/**",
118
+ "**/vendor/**",
119
+ "**/third_party/**",
120
+ "**/*.min.js",
121
+ "**/*.min.css",
122
+ "**/*.map",
123
+ "**/*.pb.go",
124
+ "**/*_pb2.py",
125
+ "**/*_pb2_grpc.py",
126
+ "**/*.pb.ts",
127
+ "**/*.generated.*",
128
+ "**/*.g.dart",
129
+ "**/__snapshots__/**",
130
+ ];
131
+ export const MIGRATION_PATTERNS = ["**/migrations/**", "**/migrate/**", "**/*.migration.*"];
132
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1,19 @@
1
+ import type { FileDiff } from "../domain.js";
2
+ export type ExclusionReason = "binary" | "secret" | "deleted" | "user_exclude" | "extension" | "generated" | "too_large";
3
+ export type FileDecision = {
4
+ diff: FileDiff;
5
+ selected: true;
6
+ } | {
7
+ diff: FileDiff;
8
+ selected: false;
9
+ reason: ExclusionReason;
10
+ };
11
+ export interface SelectionPolicy {
12
+ include: readonly string[];
13
+ exclude: readonly string[];
14
+ maxPatchChars: number;
15
+ }
16
+ export declare const defaultSelectionPolicy: SelectionPolicy;
17
+ export declare function isSecretPath(path: string): boolean;
18
+ export declare function selectFiles(diffs: readonly FileDiff[], policy?: SelectionPolicy): FileDecision[];
19
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1,52 @@
1
+ import picomatch from "picomatch";
2
+ import { ENV_TEMPLATE_PATTERNS, GENERATED_PATTERNS, MIGRATION_PATTERNS, NON_REVIEWABLE_EXTENSIONS, SECRET_PATTERNS, } from "./patterns.js";
3
+ export const defaultSelectionPolicy = {
4
+ include: [],
5
+ exclude: [],
6
+ maxPatchChars: 200_000,
7
+ };
8
+ const globOptions = { dot: true, nocase: true };
9
+ const isSecret = picomatch(SECRET_PATTERNS, { ...globOptions, ignore: ENV_TEMPLATE_PATTERNS });
10
+ const isGenerated = picomatch(GENERATED_PATTERNS, globOptions);
11
+ const isMigration = picomatch(MIGRATION_PATTERNS, globOptions);
12
+ const nonReviewableExtensions = new Set(NON_REVIEWABLE_EXTENSIONS);
13
+ export function isSecretPath(path) {
14
+ return isSecret(path);
15
+ }
16
+ export function selectFiles(diffs, policy = defaultSelectionPolicy) {
17
+ const isUserExcluded = matcher(policy.exclude);
18
+ const isUserIncluded = matcher(policy.include);
19
+ return diffs.map((diff) => {
20
+ const reason = exclusionReason(diff, policy, isUserExcluded, isUserIncluded);
21
+ return reason ? { diff, selected: false, reason } : { diff, selected: true };
22
+ });
23
+ }
24
+ function exclusionReason(diff, policy, isUserExcluded, isUserIncluded) {
25
+ const path = diff.newPath;
26
+ if (diff.isBinary)
27
+ return "binary";
28
+ if (isSecret(diff.oldPath) || isSecret(path))
29
+ return "secret";
30
+ if (diff.kind === "deleted")
31
+ return "deleted";
32
+ if (isUserExcluded(path))
33
+ return "user_exclude";
34
+ if (!isUserIncluded(path)) {
35
+ if (nonReviewableExtensions.has(extension(path)))
36
+ return "extension";
37
+ if (isGenerated(path) && !isMigration(path))
38
+ return "generated";
39
+ }
40
+ if (diff.patch.length > policy.maxPatchChars)
41
+ return "too_large";
42
+ return undefined;
43
+ }
44
+ function matcher(patterns) {
45
+ return patterns.length === 0 ? () => false : picomatch([...patterns], globOptions);
46
+ }
47
+ function extension(path) {
48
+ const name = path.slice(path.lastIndexOf("/") + 1);
49
+ const dot = name.lastIndexOf(".");
50
+ return dot > 0 ? name.slice(dot + 1).toLowerCase() : "";
51
+ }
52
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1,2 @@
1
+ export * from "./jsonl.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from "./jsonl.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ import type { ReviewEvent } from "../pipeline/report.js";
2
+ export declare const EVENTS_FILE = "events.jsonl";
3
+ export declare const REPORT_FILE = "report.json";
4
+ export declare function newSessionId(now?: Date): string;
5
+ export declare class JsonlSessionWriter {
6
+ readonly id: string;
7
+ readonly dir: string;
8
+ constructor(sessionsDir: string, id?: string);
9
+ write(event: ReviewEvent): void;
10
+ }
11
+ //# sourceMappingURL=jsonl.d.ts.map
@@ -0,0 +1,57 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { appendFileSync, closeSync, constants, lstatSync, mkdirSync, openSync, writeFileSync, writeSync, } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { serializeOutput, toReportOutput } from "../pipeline/output.js";
5
+ export const EVENTS_FILE = "events.jsonl";
6
+ export const REPORT_FILE = "report.json";
7
+ export function newSessionId(now = new Date()) {
8
+ const stamp = now
9
+ .toISOString()
10
+ .replace(/[-:]/g, "")
11
+ .replace(/\.\d+Z$/, "Z");
12
+ return `${stamp}-${randomBytes(3).toString("hex")}`;
13
+ }
14
+ // Events are appended synchronously, one JSON object per line, so the log
15
+ // stays valid and ordered even if the process dies mid-run.
16
+ export class JsonlSessionWriter {
17
+ id;
18
+ dir;
19
+ constructor(sessionsDir, id = newSessionId()) {
20
+ this.id = id;
21
+ // The sessions directory lives in the reviewed tree, which may carry
22
+ // links planted to send the logs, or the .gitignore write, elsewhere.
23
+ for (const dir of [dirname(sessionsDir), sessionsDir])
24
+ refuseSymlink(dir);
25
+ this.dir = join(sessionsDir, id);
26
+ mkdirSync(this.dir, { recursive: true });
27
+ // The directory is created before a workspace review reads its diff, and
28
+ // the logs hold code and findings: keep them out of git and out of reviews.
29
+ const fd = openSync(join(sessionsDir, ".gitignore"), constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | constants.O_NOFOLLOW);
30
+ try {
31
+ writeSync(fd, "*\n");
32
+ }
33
+ finally {
34
+ closeSync(fd);
35
+ }
36
+ }
37
+ write(event) {
38
+ const line = serializeOutput({ time: new Date().toISOString(), ...event }, 0);
39
+ appendFileSync(join(this.dir, EVENTS_FILE), `${line}\n`);
40
+ if (event.type === "run_finished") {
41
+ const report = toReportOutput(event.report);
42
+ writeFileSync(join(this.dir, REPORT_FILE), `${serializeOutput(report)}\n`);
43
+ }
44
+ }
45
+ }
46
+ function refuseSymlink(path) {
47
+ try {
48
+ if (lstatSync(path).isSymbolicLink()) {
49
+ throw new Error(`Refusing to write the session log through the symbolic link ${path}`);
50
+ }
51
+ }
52
+ catch (error) {
53
+ if (error.code !== "ENOENT")
54
+ throw error;
55
+ }
56
+ }
57
+ //# sourceMappingURL=jsonl.js.map
@@ -0,0 +1,11 @@
1
+ import type { FileDiff, RiskTier } from "./domain.js";
2
+ export interface TriagePolicy {
3
+ trivialMaxLines: number;
4
+ liteMaxLines: number;
5
+ maxFilesBeforeFull: number;
6
+ sensitivePathPatterns: RegExp[];
7
+ sensitivePathWords: ReadonlySet<string>;
8
+ }
9
+ export declare const defaultTriagePolicy: TriagePolicy;
10
+ export declare function triage(diffs: readonly FileDiff[], policy?: TriagePolicy): RiskTier;
11
+ //# sourceMappingURL=triage.d.ts.map
package/dist/triage.js ADDED
@@ -0,0 +1,55 @@
1
+ export const defaultTriagePolicy = {
2
+ trivialMaxLines: 10,
3
+ liteMaxLines: 100,
4
+ maxFilesBeforeFull: 20,
5
+ sensitivePathPatterns: [/(^|\/)\.github\/workflows\//],
6
+ // "token" and "session" are left out: lexers, parsers, tool and log
7
+ // sessions use them far more often than authentication does, and a false
8
+ // match costs a full-tier review.
9
+ sensitivePathWords: new Set([
10
+ "auth",
11
+ "authn",
12
+ "authz",
13
+ "authentication",
14
+ "authorization",
15
+ "oauth",
16
+ "saml",
17
+ "sso",
18
+ "jwt",
19
+ "crypto",
20
+ "security",
21
+ "identity",
22
+ "password",
23
+ "passwords",
24
+ "passwd",
25
+ "credential",
26
+ "credentials",
27
+ "secret",
28
+ "secrets",
29
+ "login",
30
+ "permission",
31
+ "permissions",
32
+ "acl",
33
+ "acls",
34
+ ]),
35
+ };
36
+ export function triage(diffs, policy = defaultTriagePolicy) {
37
+ const touchesSensitivePath = diffs.some((d) => isSensitivePath(d.newPath, policy) || isSensitivePath(d.oldPath, policy));
38
+ if (touchesSensitivePath || diffs.length > policy.maxFilesBeforeFull)
39
+ return "full";
40
+ const churn = diffs.reduce((sum, d) => sum + d.additions + d.deletions, 0);
41
+ if (churn <= policy.trivialMaxLines)
42
+ return "trivial";
43
+ if (churn <= policy.liteMaxLines)
44
+ return "lite";
45
+ return "full";
46
+ }
47
+ function isSensitivePath(path, policy) {
48
+ return (policy.sensitivePathPatterns.some((p) => p.test(path)) ||
49
+ pathWords(path).some((w) => policy.sensitivePathWords.has(w)));
50
+ }
51
+ // "src/OAuth2/PasswordHasher.cs" -> o, auth, 2, password, hasher, cs
52
+ function pathWords(path) {
53
+ return (path.match(/[A-Z]+(?![a-z])|[A-Z]?[a-z]+|\d+/g) ?? []).map((w) => w.toLowerCase());
54
+ }
55
+ //# sourceMappingURL=triage.js.map
@@ -0,0 +1,3 @@
1
+ export * from "./prompt.js";
2
+ export * from "./verify.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from "./prompt.js";
2
+ export * from "./verify.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import type { Finding } from "../domain.js";
3
+ export declare const verificationVerdictSchema: z.ZodEnum<{
4
+ confirmed: "confirmed";
5
+ refuted: "refuted";
6
+ uncertain: "uncertain";
7
+ }>;
8
+ export type VerificationVerdict = z.infer<typeof verificationVerdictSchema>;
9
+ export declare const verificationResponseSchema: z.ZodArray<z.ZodObject<{
10
+ index: z.ZodNumber;
11
+ verdict: z.ZodEnum<{
12
+ confirmed: "confirmed";
13
+ refuted: "refuted";
14
+ uncertain: "uncertain";
15
+ }>;
16
+ reason: z.ZodDefault<z.ZodString>;
17
+ }, z.core.$strip>>;
18
+ export interface VerificationPrompt {
19
+ system: string;
20
+ user: string;
21
+ }
22
+ export declare function buildVerificationPrompt(file: string, findings: readonly Finding[], patch: string, excerpt: string | undefined): VerificationPrompt;
23
+ export declare function fileExcerpt(content: string, findings: readonly Finding[]): string | undefined;
24
+ //# sourceMappingURL=prompt.d.ts.map