@yuaone/core 0.9.43 → 1.0.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 (154) hide show
  1. package/dist/agent-affordance.d.ts +37 -0
  2. package/dist/agent-affordance.d.ts.map +1 -0
  3. package/dist/agent-affordance.js +139 -0
  4. package/dist/agent-affordance.js.map +1 -0
  5. package/dist/agent-decision-types.d.ts +262 -0
  6. package/dist/agent-decision-types.d.ts.map +1 -0
  7. package/dist/agent-decision-types.js +19 -0
  8. package/dist/agent-decision-types.js.map +1 -0
  9. package/dist/agent-decision.d.ts +52 -0
  10. package/dist/agent-decision.d.ts.map +1 -0
  11. package/dist/agent-decision.js +767 -0
  12. package/dist/agent-decision.js.map +1 -0
  13. package/dist/agent-loop.d.ts +37 -79
  14. package/dist/agent-loop.d.ts.map +1 -1
  15. package/dist/agent-loop.js +730 -586
  16. package/dist/agent-loop.js.map +1 -1
  17. package/dist/agent-reasoning-engine.d.ts +48 -0
  18. package/dist/agent-reasoning-engine.d.ts.map +1 -0
  19. package/dist/agent-reasoning-engine.js +544 -0
  20. package/dist/agent-reasoning-engine.js.map +1 -0
  21. package/dist/codebase-context.d.ts +3 -0
  22. package/dist/codebase-context.d.ts.map +1 -1
  23. package/dist/codebase-context.js +15 -6
  24. package/dist/codebase-context.js.map +1 -1
  25. package/dist/command-plan-compiler.d.ts +43 -0
  26. package/dist/command-plan-compiler.d.ts.map +1 -0
  27. package/dist/command-plan-compiler.js +164 -0
  28. package/dist/command-plan-compiler.js.map +1 -0
  29. package/dist/dependency-guard.d.ts +18 -0
  30. package/dist/dependency-guard.d.ts.map +1 -0
  31. package/dist/dependency-guard.js +113 -0
  32. package/dist/dependency-guard.js.map +1 -0
  33. package/dist/execution-engine.d.ts +10 -1
  34. package/dist/execution-engine.d.ts.map +1 -1
  35. package/dist/execution-engine.js +162 -8
  36. package/dist/execution-engine.js.map +1 -1
  37. package/dist/execution-receipt.d.ts +62 -0
  38. package/dist/execution-receipt.d.ts.map +1 -0
  39. package/dist/execution-receipt.js +67 -0
  40. package/dist/execution-receipt.js.map +1 -0
  41. package/dist/failure-surface-writer.d.ts +13 -0
  42. package/dist/failure-surface-writer.d.ts.map +1 -0
  43. package/dist/failure-surface-writer.js +33 -0
  44. package/dist/failure-surface-writer.js.map +1 -0
  45. package/dist/file-chunker.d.ts +26 -0
  46. package/dist/file-chunker.d.ts.map +1 -0
  47. package/dist/file-chunker.js +103 -0
  48. package/dist/file-chunker.js.map +1 -0
  49. package/dist/image-observer.d.ts +22 -0
  50. package/dist/image-observer.d.ts.map +1 -0
  51. package/dist/image-observer.js +60 -0
  52. package/dist/image-observer.js.map +1 -0
  53. package/dist/index.d.ts +55 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +53 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/judgment-rules.d.ts +44 -0
  58. package/dist/judgment-rules.d.ts.map +1 -0
  59. package/dist/judgment-rules.js +185 -0
  60. package/dist/judgment-rules.js.map +1 -0
  61. package/dist/memory-decay.d.ts +41 -0
  62. package/dist/memory-decay.d.ts.map +1 -0
  63. package/dist/memory-decay.js +62 -0
  64. package/dist/memory-decay.js.map +1 -0
  65. package/dist/memory-manager.d.ts.map +1 -1
  66. package/dist/memory-manager.js +30 -0
  67. package/dist/memory-manager.js.map +1 -1
  68. package/dist/model-weakness-tracker.d.ts +42 -0
  69. package/dist/model-weakness-tracker.d.ts.map +1 -0
  70. package/dist/model-weakness-tracker.js +107 -0
  71. package/dist/model-weakness-tracker.js.map +1 -0
  72. package/dist/overhead-governor.d.ts +3 -1
  73. package/dist/overhead-governor.d.ts.map +1 -1
  74. package/dist/overhead-governor.js +5 -0
  75. package/dist/overhead-governor.js.map +1 -1
  76. package/dist/patch-scope-controller.d.ts +44 -0
  77. package/dist/patch-scope-controller.d.ts.map +1 -0
  78. package/dist/patch-scope-controller.js +107 -0
  79. package/dist/patch-scope-controller.js.map +1 -0
  80. package/dist/patch-transaction.d.ts +53 -0
  81. package/dist/patch-transaction.d.ts.map +1 -0
  82. package/dist/patch-transaction.js +119 -0
  83. package/dist/patch-transaction.js.map +1 -0
  84. package/dist/pre-write-validator.d.ts +29 -0
  85. package/dist/pre-write-validator.d.ts.map +1 -0
  86. package/dist/pre-write-validator.js +97 -0
  87. package/dist/pre-write-validator.js.map +1 -0
  88. package/dist/prompt-builder.d.ts +25 -0
  89. package/dist/prompt-builder.d.ts.map +1 -0
  90. package/dist/prompt-builder.js +93 -0
  91. package/dist/prompt-builder.js.map +1 -0
  92. package/dist/prompt-envelope.d.ts +40 -0
  93. package/dist/prompt-envelope.d.ts.map +1 -0
  94. package/dist/prompt-envelope.js +16 -0
  95. package/dist/prompt-envelope.js.map +1 -0
  96. package/dist/prompt-runtime.d.ts +66 -0
  97. package/dist/prompt-runtime.d.ts.map +1 -0
  98. package/dist/prompt-runtime.js +492 -0
  99. package/dist/prompt-runtime.js.map +1 -0
  100. package/dist/repo-capability-profile.d.ts +24 -0
  101. package/dist/repo-capability-profile.d.ts.map +1 -0
  102. package/dist/repo-capability-profile.js +113 -0
  103. package/dist/repo-capability-profile.js.map +1 -0
  104. package/dist/security-gate.d.ts +39 -0
  105. package/dist/security-gate.d.ts.map +1 -0
  106. package/dist/security-gate.js +121 -0
  107. package/dist/security-gate.js.map +1 -0
  108. package/dist/self-evaluation.d.ts +22 -0
  109. package/dist/self-evaluation.d.ts.map +1 -0
  110. package/dist/self-evaluation.js +43 -0
  111. package/dist/self-evaluation.js.map +1 -0
  112. package/dist/semantic-diff-reviewer.d.ts +28 -0
  113. package/dist/semantic-diff-reviewer.d.ts.map +1 -0
  114. package/dist/semantic-diff-reviewer.js +168 -0
  115. package/dist/semantic-diff-reviewer.js.map +1 -0
  116. package/dist/stall-detector.d.ts +26 -2
  117. package/dist/stall-detector.d.ts.map +1 -1
  118. package/dist/stall-detector.js +128 -3
  119. package/dist/stall-detector.js.map +1 -1
  120. package/dist/system-core.d.ts +27 -0
  121. package/dist/system-core.d.ts.map +1 -0
  122. package/dist/system-core.js +269 -0
  123. package/dist/system-core.js.map +1 -0
  124. package/dist/system-prompt.d.ts +4 -0
  125. package/dist/system-prompt.d.ts.map +1 -1
  126. package/dist/system-prompt.js +12 -218
  127. package/dist/system-prompt.js.map +1 -1
  128. package/dist/target-file-ranker.d.ts +38 -0
  129. package/dist/target-file-ranker.d.ts.map +1 -0
  130. package/dist/target-file-ranker.js +90 -0
  131. package/dist/target-file-ranker.js.map +1 -0
  132. package/dist/task-classifier.d.ts +6 -0
  133. package/dist/task-classifier.d.ts.map +1 -1
  134. package/dist/task-classifier.js +6 -0
  135. package/dist/task-classifier.js.map +1 -1
  136. package/dist/test-impact-planner.d.ts +16 -0
  137. package/dist/test-impact-planner.d.ts.map +1 -0
  138. package/dist/test-impact-planner.js +68 -0
  139. package/dist/test-impact-planner.js.map +1 -0
  140. package/dist/tool-outcome-cache.d.ts +41 -0
  141. package/dist/tool-outcome-cache.d.ts.map +1 -0
  142. package/dist/tool-outcome-cache.js +88 -0
  143. package/dist/tool-outcome-cache.js.map +1 -0
  144. package/dist/types.d.ts +39 -0
  145. package/dist/types.d.ts.map +1 -1
  146. package/dist/verifier-rules.d.ts +15 -0
  147. package/dist/verifier-rules.d.ts.map +1 -0
  148. package/dist/verifier-rules.js +80 -0
  149. package/dist/verifier-rules.js.map +1 -0
  150. package/dist/workspace-mutation-policy.d.ts +28 -0
  151. package/dist/workspace-mutation-policy.d.ts.map +1 -0
  152. package/dist/workspace-mutation-policy.js +56 -0
  153. package/dist/workspace-mutation-policy.js.map +1 -0
  154. package/package.json +1 -1
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @module repo-capability-profile
3
+ * @description One-time scan of repository capabilities.
4
+ * Detects: package manager, build tool, test framework, monorepo, language, generated paths.
5
+ * Cached in .yuan/cache/repo-capability-profile.json.
6
+ * NO LLM, filesystem-based detection.
7
+ */
8
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, statSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ export function scanRepoCapability(projectPath) {
11
+ const has = (f) => existsSync(join(projectPath, f));
12
+ const read = (f) => { try {
13
+ return readFileSync(join(projectPath, f), "utf-8");
14
+ }
15
+ catch {
16
+ return "";
17
+ } };
18
+ // Package manager
19
+ const packageManager = has("pnpm-lock.yaml") ? "pnpm"
20
+ : has("yarn.lock") ? "yarn"
21
+ : has("bun.lockb") ? "bun"
22
+ : has("package-lock.json") ? "npm"
23
+ : "unknown";
24
+ // Monorepo detection
25
+ const hasPnpmWorkspace = has("pnpm-workspace.yaml");
26
+ const hasLernaJson = has("lerna.json");
27
+ let packages = [];
28
+ let repoType = "single";
29
+ if (hasPnpmWorkspace || hasLernaJson) {
30
+ repoType = "monorepo";
31
+ try {
32
+ const dirs = readdirSync(join(projectPath, "packages")).filter(d => {
33
+ try {
34
+ return statSync(join(projectPath, "packages", d)).isDirectory();
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ });
40
+ packages = dirs;
41
+ }
42
+ catch { /* no packages dir */ }
43
+ }
44
+ // Build tool
45
+ const buildTool = has("webpack.config.js") || has("webpack.config.ts") ? "webpack"
46
+ : has("vite.config.ts") || has("vite.config.js") ? "vite"
47
+ : has("esbuild.config.js") ? "esbuild"
48
+ : has("rollup.config.js") ? "rollup"
49
+ : has("tsconfig.json") ? "tsc"
50
+ : "unknown";
51
+ // Test framework
52
+ const testFramework = has("vitest.config.ts") || has("vitest.config.js") ? "vitest"
53
+ : has("jest.config.ts") || has("jest.config.js") || has("jest.config.json") ? "jest"
54
+ : has(".mocharc.yml") || has(".mocharc.json") ? "mocha"
55
+ : has("pytest.ini") || has("setup.py") ? "pytest"
56
+ : "unknown";
57
+ // Language
58
+ const pkgJson = read("package.json");
59
+ const hasTS = has("tsconfig.json");
60
+ const primaryLanguage = hasTS ? "typescript" : pkgJson ? "javascript" : has("Cargo.toml") ? "rust" : has("go.mod") ? "go" : has("requirements.txt") ? "python" : "unknown";
61
+ // Strict mode
62
+ let hasStrictMode = false;
63
+ if (hasTS) {
64
+ const tsconfig = read("tsconfig.json");
65
+ hasStrictMode = /"strict"\s*:\s*true/.test(tsconfig);
66
+ }
67
+ // Generated paths (don't modify these)
68
+ const generatedPaths = ["dist/", "build/", ".next/", "node_modules/", "__pycache__/", "target/", ".output/"]
69
+ .filter(p => has(p));
70
+ // Protected files
71
+ const protectedFiles = ["package.json", "tsconfig.json", "pnpm-lock.yaml", "package-lock.json", ".env", ".gitignore"]
72
+ .filter(p => has(p));
73
+ // Speed estimation (heuristic)
74
+ const buildSpeed = buildTool === "esbuild" || buildTool === "vite" ? "fast" : buildTool === "webpack" ? "slow" : "normal";
75
+ const testSpeed = testFramework === "vitest" ? "fast" : testFramework === "jest" ? "normal" : "normal";
76
+ // Detect library vs CLI vs fullstack
77
+ if (repoType === "single") {
78
+ try {
79
+ const pkg = pkgJson ? JSON.parse(pkgJson) : {};
80
+ if (pkg.bin)
81
+ repoType = "cli";
82
+ else if (pkg.main || pkg.module || pkg.types)
83
+ repoType = "library";
84
+ else if (has("src/app") || has("src/pages") || has("app/"))
85
+ repoType = "fullstack";
86
+ }
87
+ catch { /* invalid package.json */ }
88
+ }
89
+ return {
90
+ repoType, packages, packageManager, buildTool, testFramework,
91
+ primaryLanguage, hasStrictMode, generatedPaths, protectedFiles,
92
+ buildSpeed, testSpeed, scannedAt: Date.now(),
93
+ };
94
+ }
95
+ export function loadOrScanProfile(projectPath) {
96
+ const cachePath = join(projectPath, ".yuan", "cache", "repo-capability-profile.json");
97
+ try {
98
+ const cached = JSON.parse(readFileSync(cachePath, "utf-8"));
99
+ // Invalidate if older than 1 hour
100
+ if (Date.now() - cached.scannedAt < 3600_000)
101
+ return cached;
102
+ }
103
+ catch { /* no cache or invalid */ }
104
+ const profile = scanRepoCapability(projectPath);
105
+ // Save cache
106
+ try {
107
+ mkdirSync(join(projectPath, ".yuan", "cache"), { recursive: true });
108
+ writeFileSync(cachePath, JSON.stringify(profile, null, 2));
109
+ }
110
+ catch { /* non-fatal */ }
111
+ return profile;
112
+ }
113
+ //# sourceMappingURL=repo-capability-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-capability-profile.js","sourceRoot":"","sources":["../src/repo-capability-profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @module security-gate
3
+ * @description Deterministic security gate for tool inputs.
4
+ * Prevents shell injection, dangerous commands, and credential leaks.
5
+ * NO LLM, pure pattern matching.
6
+ *
7
+ * Unlike security.ts (which provides general blocked-executable lists and
8
+ * path validators), this module provides pre-execution checks for tool
9
+ * call arguments — catching injection patterns, reverse shells, and
10
+ * credential leaks that slip past simple executable blocking.
11
+ */
12
+ export type SecurityVerdict = "ALLOW" | "WARN" | "BLOCK";
13
+ export interface SecurityCheckResult {
14
+ verdict: SecurityVerdict;
15
+ reason?: string;
16
+ pattern?: string;
17
+ }
18
+ /**
19
+ * Check a shell command string against dangerous patterns.
20
+ * Returns BLOCK if a dangerous pattern is matched, ALLOW otherwise.
21
+ */
22
+ export declare function checkShellSecurity(command: string): SecurityCheckResult;
23
+ /**
24
+ * Check a file path (and optional content) against dangerous patterns.
25
+ * Returns WARN for dangerous paths or credential-containing content,
26
+ * ALLOW otherwise. File operations are WARN (not BLOCK) to allow
27
+ * the agent to proceed with caution when necessary.
28
+ */
29
+ export declare function checkFileSecurity(filePath: string, content?: string): SecurityCheckResult;
30
+ /**
31
+ * Main entry: check any tool call for security violations.
32
+ *
33
+ * - shell_exec / bash → check command against shell block patterns
34
+ * - file_write / file_edit → check path + content against file/credential patterns
35
+ * - git_ops → synthesize git command and check against shell block patterns
36
+ * - All other tools → ALLOW
37
+ */
38
+ export declare function securityCheck(toolName: string, args: Record<string, unknown>): SecurityCheckResult;
39
+ //# sourceMappingURL=security-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-gate.d.ts","sourceRoot":"","sources":["../src/security-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA0DD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAOvE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAgBzF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAgBlG"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @module security-gate
3
+ * @description Deterministic security gate for tool inputs.
4
+ * Prevents shell injection, dangerous commands, and credential leaks.
5
+ * NO LLM, pure pattern matching.
6
+ *
7
+ * Unlike security.ts (which provides general blocked-executable lists and
8
+ * path validators), this module provides pre-execution checks for tool
9
+ * call arguments — catching injection patterns, reverse shells, and
10
+ * credential leaks that slip past simple executable blocking.
11
+ */
12
+ // ─── Dangerous shell patterns ──────────────────────────────────────────────
13
+ const SHELL_BLOCK_PATTERNS = [
14
+ // Destructive commands
15
+ { pattern: /\brm\s+(-rf|-fr|--force)\b/i, reason: "Destructive recursive delete" },
16
+ { pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*f/i, reason: "Destructive recursive delete" },
17
+ { pattern: /\bmkfs\b/i, reason: "Filesystem format" },
18
+ { pattern: /\bdd\s+if=/i, reason: "Direct disk write" },
19
+ // Network exfiltration
20
+ { pattern: /\bcurl\b.*\|\s*\b(sh|bash|zsh)\b/i, reason: "Remote code execution via pipe" },
21
+ { pattern: /\bwget\b.*\|\s*\b(sh|bash|zsh)\b/i, reason: "Remote code execution via pipe" },
22
+ { pattern: /\bcurl\b.*-o\s*\//, reason: "Download to system path" },
23
+ // Reverse shells
24
+ { pattern: /\bnc\b.*-[elp]/i, reason: "Netcat listener (possible reverse shell)" },
25
+ { pattern: /\/dev\/tcp\//i, reason: "Bash TCP redirect (reverse shell)" },
26
+ { pattern: /\bsocat\b/i, reason: "Socket relay (possible reverse shell)" },
27
+ // Privilege escalation
28
+ { pattern: /\bsudo\b/i, reason: "Privilege escalation" },
29
+ { pattern: /\bchmod\s+[0-7]*7[0-7]*\b/i, reason: "World-writable permission" },
30
+ { pattern: /\bchown\b.*root/i, reason: "Ownership change to root" },
31
+ // Git destructive
32
+ { pattern: /\bgit\s+push\s+.*--force\b/i, reason: "Force push" },
33
+ { pattern: /\bgit\s+reset\s+--hard\b/i, reason: "Hard reset" },
34
+ { pattern: /\bgit\s+clean\s+-[a-zA-Z]*f/i, reason: "Force clean" },
35
+ // Environment manipulation
36
+ { pattern: /\bexport\s+.*(?:PATH|LD_LIBRARY|LD_PRELOAD)\s*=/i, reason: "Environment path manipulation" },
37
+ // SQL injection in shell
38
+ { pattern: /;\s*(DROP|DELETE|TRUNCATE|ALTER)\s/i, reason: "SQL injection pattern" },
39
+ ];
40
+ // ─── Dangerous file paths ──────────────────────────────────────────────────
41
+ const FILE_BLOCK_PATTERNS = [
42
+ { pattern: /^\/etc\//i, reason: "System config modification" },
43
+ { pattern: /^\/usr\//i, reason: "System binary modification" },
44
+ { pattern: /^\/var\/log\//i, reason: "System log modification" },
45
+ { pattern: /^\/root\//i, reason: "Root home modification" },
46
+ { pattern: /^\/(bin|sbin)\//i, reason: "System binary modification" },
47
+ { pattern: /\.ssh\//i, reason: "SSH key modification" },
48
+ { pattern: /\.env$/i, reason: "Environment file (may contain secrets)" },
49
+ { pattern: /\.npmrc$/i, reason: "NPM config (may contain tokens)" },
50
+ ];
51
+ // ─── Credential patterns in content ────────────────────────────────────────
52
+ const CREDENTIAL_PATTERNS = [
53
+ { pattern: /(?:api[_-]?key|apikey|secret[_-]?key|auth[_-]?token|access[_-]?token)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{20,}/i, reason: "API key/token detected" },
54
+ { pattern: /(?:password|passwd|pwd)\s*[:=]\s*['"]?[^\s'"]{8,}/i, reason: "Password detected" },
55
+ { pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/i, reason: "Private key detected" },
56
+ { pattern: /ghp_[a-zA-Z0-9]{36}/i, reason: "GitHub personal access token" },
57
+ { pattern: /sk-[a-zA-Z0-9]{48,}/i, reason: "OpenAI/Anthropic API key" },
58
+ { pattern: /AIza[a-zA-Z0-9_\-]{35}/i, reason: "Google API key" },
59
+ ];
60
+ // ─── Check functions ───────────────────────────────────────────────────────
61
+ /**
62
+ * Check a shell command string against dangerous patterns.
63
+ * Returns BLOCK if a dangerous pattern is matched, ALLOW otherwise.
64
+ */
65
+ export function checkShellSecurity(command) {
66
+ for (const { pattern, reason } of SHELL_BLOCK_PATTERNS) {
67
+ if (pattern.test(command)) {
68
+ return { verdict: "BLOCK", reason, pattern: pattern.source };
69
+ }
70
+ }
71
+ return { verdict: "ALLOW" };
72
+ }
73
+ /**
74
+ * Check a file path (and optional content) against dangerous patterns.
75
+ * Returns WARN for dangerous paths or credential-containing content,
76
+ * ALLOW otherwise. File operations are WARN (not BLOCK) to allow
77
+ * the agent to proceed with caution when necessary.
78
+ */
79
+ export function checkFileSecurity(filePath, content) {
80
+ // Check path
81
+ for (const { pattern, reason } of FILE_BLOCK_PATTERNS) {
82
+ if (pattern.test(filePath)) {
83
+ return { verdict: "WARN", reason, pattern: pattern.source };
84
+ }
85
+ }
86
+ // Check content for credentials
87
+ if (content) {
88
+ for (const { pattern, reason } of CREDENTIAL_PATTERNS) {
89
+ if (pattern.test(content)) {
90
+ return { verdict: "WARN", reason, pattern: pattern.source };
91
+ }
92
+ }
93
+ }
94
+ return { verdict: "ALLOW" };
95
+ }
96
+ /**
97
+ * Main entry: check any tool call for security violations.
98
+ *
99
+ * - shell_exec / bash → check command against shell block patterns
100
+ * - file_write / file_edit → check path + content against file/credential patterns
101
+ * - git_ops → synthesize git command and check against shell block patterns
102
+ * - All other tools → ALLOW
103
+ */
104
+ export function securityCheck(toolName, args) {
105
+ if (toolName === "shell_exec" || toolName === "bash") {
106
+ const cmd = String(args.command ?? args.script ?? "");
107
+ return checkShellSecurity(cmd);
108
+ }
109
+ if (toolName === "file_write" || toolName === "file_edit") {
110
+ const path = String(args.path ?? args.file_path ?? "");
111
+ const content = String(args.content ?? args.new_string ?? "");
112
+ return checkFileSecurity(path, content);
113
+ }
114
+ if (toolName === "git_ops") {
115
+ const op = String(args.operation ?? "");
116
+ const opArgs = String(args.args ?? "");
117
+ return checkShellSecurity(`git ${op} ${opArgs}`);
118
+ }
119
+ return { verdict: "ALLOW" };
120
+ }
121
+ //# sourceMappingURL=security-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-gate.js","sourceRoot":"","sources":["../src/security-gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module self-evaluation
3
+ * @description Lightweight self-evaluation before reporting success.
4
+ * Checks: files actually changed, build not broken, no pending errors.
5
+ * NO LLM, deterministic checks only.
6
+ */
7
+ export interface SelfEvalResult {
8
+ passed: boolean;
9
+ score: number;
10
+ issues: string[];
11
+ recommendation: "report_success" | "run_verification" | "report_partial";
12
+ }
13
+ export declare function selfEvaluate(params: {
14
+ changedFiles: string[];
15
+ toolErrors: number;
16
+ toolSuccesses: number;
17
+ verificationRan: boolean;
18
+ verificationPassed: boolean;
19
+ iterationCount: number;
20
+ maxIterations: number;
21
+ }): SelfEvalResult;
22
+ //# sourceMappingURL=self-evaluation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-evaluation.d.ts","sourceRoot":"","sources":["../src/self-evaluation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;CAC1E;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,cAAc,CA4CjB"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @module self-evaluation
3
+ * @description Lightweight self-evaluation before reporting success.
4
+ * Checks: files actually changed, build not broken, no pending errors.
5
+ * NO LLM, deterministic checks only.
6
+ */
7
+ export function selfEvaluate(params) {
8
+ const { changedFiles, toolErrors, toolSuccesses, verificationRan, verificationPassed, iterationCount, maxIterations } = params;
9
+ const issues = [];
10
+ let score = 1.0;
11
+ // No changes made
12
+ if (changedFiles.length === 0) {
13
+ issues.push("No files were changed");
14
+ score -= 0.3;
15
+ }
16
+ // High error rate
17
+ const totalTools = toolErrors + toolSuccesses;
18
+ if (totalTools > 0 && toolErrors / totalTools > 0.3) {
19
+ issues.push(`High tool error rate: ${toolErrors}/${totalTools}`);
20
+ score -= 0.2;
21
+ }
22
+ // Verification not run
23
+ if (changedFiles.length > 0 && !verificationRan) {
24
+ issues.push("Files changed but no verification was run");
25
+ score -= 0.2;
26
+ }
27
+ // Verification failed
28
+ if (verificationRan && !verificationPassed) {
29
+ issues.push("Verification failed");
30
+ score -= 0.4;
31
+ }
32
+ // Used too many iterations (possible struggle)
33
+ if (iterationCount > maxIterations * 0.8) {
34
+ issues.push("Used most of iteration budget — may have struggled");
35
+ score -= 0.1;
36
+ }
37
+ score = Math.max(0, Math.min(1, score));
38
+ const recommendation = score >= 0.7 ? "report_success"
39
+ : !verificationRan && changedFiles.length > 0 ? "run_verification"
40
+ : "report_partial";
41
+ return { passed: score >= 0.5, score, issues, recommendation };
42
+ }
43
+ //# sourceMappingURL=self-evaluation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-evaluation.js","sourceRoot":"","sources":["../src/self-evaluation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,UAAU,YAAY,CAAC,MAQ5B;IACC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IAC/H,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,kBAAkB;IAClB,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrC,KAAK,IAAI,GAAG,CAAC;IACf,CAAC;IAED,kBAAkB;IAClB,MAAM,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IAC9C,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,UAAU,GAAG,GAAG,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,yBAAyB,UAAU,IAAI,UAAU,EAAE,CAAC,CAAC;QACjE,KAAK,IAAI,GAAG,CAAC;IACf,CAAC;IAED,uBAAuB;IACvB,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACzD,KAAK,IAAI,GAAG,CAAC;IACf,CAAC;IAED,sBAAsB;IACtB,IAAI,eAAe,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACnC,KAAK,IAAI,GAAG,CAAC;IACf,CAAC;IAED,+CAA+C;IAC/C,IAAI,cAAc,GAAG,aAAa,GAAG,GAAG,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;QAClE,KAAK,IAAI,GAAG,CAAC;IACf,CAAC;IAED,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAExC,MAAM,cAAc,GAClB,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB;QAC/B,CAAC,CAAC,CAAC,eAAe,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;YAClE,CAAC,CAAC,gBAAgB,CAAC;IAErB,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;AACjE,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @module semantic-diff-reviewer
3
+ * @description Classifies the semantic meaning of code changes.
4
+ * Determines: was this a style change? behavior change? signature change?
5
+ * Role: RECOMMENDER only. Outputs recommendedVerifyDepth, NOT final decision.
6
+ * Language-aware: TS/JS primary, other languages use conservative fallback.
7
+ */
8
+ export type SemanticChangeKind = "SIGNATURE_CHANGE" | "CONTROL_FLOW_CHANGE" | "IMPORT_CHANGE" | "CONFIG_CHANGE" | "TEST_ONLY" | "BEHAVIOR_CHANGE" | "STYLE_ONLY";
9
+ export interface SemanticDiffReview {
10
+ path: string;
11
+ changes: SemanticChangeKind[];
12
+ recommendedRiskBoost: number;
13
+ recommendedVerifyDepth: "skip" | "quick" | "thorough";
14
+ }
15
+ /** Analyze a file's changes semantically */
16
+ export declare function reviewFileDiff(params: {
17
+ path: string;
18
+ oldContent: string;
19
+ newContent: string;
20
+ language?: string;
21
+ }): SemanticDiffReview;
22
+ /** Review multiple files and produce aggregate recommendation */
23
+ export declare function reviewDiffBatch(reviews: SemanticDiffReview[]): {
24
+ overallRiskBoost: number;
25
+ overallVerifyRecommendation: "skip" | "quick" | "thorough";
26
+ summary: string;
27
+ };
28
+ //# sourceMappingURL=semantic-diff-reviewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-diff-reviewer.d.ts","sourceRoot":"","sources":["../src/semantic-diff-reviewer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,kBAAkB,GAC1B,kBAAkB,GAClB,qBAAqB,GACrB,eAAe,GACf,eAAe,GACf,WAAW,GACX,iBAAiB,GACjB,YAAY,CAAC;AAEjB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;CACvD;AAuDD,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,kBAAkB,CAyFrB;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,2BAA2B,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IAC3D,OAAO,EAAE,MAAM,CAAC;CACjB,CAqCA"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * @module semantic-diff-reviewer
3
+ * @description Classifies the semantic meaning of code changes.
4
+ * Determines: was this a style change? behavior change? signature change?
5
+ * Role: RECOMMENDER only. Outputs recommendedVerifyDepth, NOT final decision.
6
+ * Language-aware: TS/JS primary, other languages use conservative fallback.
7
+ */
8
+ // ─── Internal Detection Patterns ───
9
+ /** Detect signature-level changes (function/class/interface/type declarations) */
10
+ const SIGNATURE_PATTERNS = [
11
+ /^\s*(export\s+)?(function|class|interface|type|enum)\s+\w+/,
12
+ /^\s*(export\s+)?(const|let|var)\s+\w+\s*[=:]\s*(async\s+)?\(/,
13
+ /^\s*(public|private|protected|static|readonly|async)\s+\w+\s*\(/,
14
+ /^\s*constructor\s*\(/,
15
+ ];
16
+ /** Detect control flow structures */
17
+ const CONTROL_FLOW_PATTERNS = [
18
+ /^\s*(if|else\s+if|else|for|while|do|switch|case|try|catch|finally)\b/,
19
+ /^\s*return\b/,
20
+ /^\s*throw\b/,
21
+ /\?\s*\w+.*:/, // ternary
22
+ ];
23
+ /** Detect import/export lines */
24
+ const IMPORT_PATTERNS = [
25
+ /^\s*(import|export)\s+/,
26
+ /^\s*require\s*\(/,
27
+ /^\s*module\.exports\s*/,
28
+ ];
29
+ /** Lines that are purely style (comments, whitespace) */
30
+ function isStyleOnlyLine(line) {
31
+ const trimmed = line.trim();
32
+ if (trimmed === "")
33
+ return true;
34
+ if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*"))
35
+ return true;
36
+ return false;
37
+ }
38
+ /** Compute a simple line-level diff: lines unique to old vs new */
39
+ function diffLines(oldLines, newLines) {
40
+ const oldSet = new Set(oldLines.map(l => l.trim()));
41
+ const newSet = new Set(newLines.map(l => l.trim()));
42
+ const removed = oldLines.filter(l => !newSet.has(l.trim()));
43
+ const added = newLines.filter(l => !oldSet.has(l.trim()));
44
+ return { removed, added };
45
+ }
46
+ /** Check if a language is TS/JS family */
47
+ function isTsJs(language) {
48
+ if (!language)
49
+ return true; // default: assume TS/JS
50
+ const lang = language.toLowerCase();
51
+ return /typescript|javascript|tsx?|jsx?/.test(lang);
52
+ }
53
+ // ─── Public API ───
54
+ /** Analyze a file's changes semantically */
55
+ export function reviewFileDiff(params) {
56
+ const { path, oldContent, newContent, language } = params;
57
+ const changes = [];
58
+ // Test-only detection
59
+ if (/\.(test|spec)\.[jt]sx?$/.test(path) || /\/__tests__\//.test(path)) {
60
+ return { path, changes: ["TEST_ONLY"], recommendedRiskBoost: 0, recommendedVerifyDepth: "skip" };
61
+ }
62
+ // Config detection
63
+ if (/(tsconfig|package\.json|\.eslintrc|jest\.config|vitest\.config|rollup\.config|webpack\.config|vite\.config|\.prettierrc|\.babelrc)/.test(path)) {
64
+ return { path, changes: ["CONFIG_CHANGE"], recommendedRiskBoost: 0.15, recommendedVerifyDepth: "thorough" };
65
+ }
66
+ // If not TS/JS, use conservative fallback
67
+ if (!isTsJs(language)) {
68
+ // Cannot reliably classify — assume behavior change
69
+ return { path, changes: ["BEHAVIOR_CHANGE"], recommendedRiskBoost: 0.2, recommendedVerifyDepth: "thorough" };
70
+ }
71
+ // Diff the old vs new content
72
+ const oldLines = oldContent.split("\n");
73
+ const newLines = newContent.split("\n");
74
+ const { removed, added } = diffLines(oldLines, newLines);
75
+ const changedLines = [...removed, ...added];
76
+ // No changes at all
77
+ if (changedLines.length === 0) {
78
+ return { path, changes: ["STYLE_ONLY"], recommendedRiskBoost: 0, recommendedVerifyDepth: "skip" };
79
+ }
80
+ // Check if ALL changed lines are style-only
81
+ const allStyle = changedLines.every(l => isStyleOnlyLine(l));
82
+ if (allStyle) {
83
+ changes.push("STYLE_ONLY");
84
+ return { path, changes, recommendedRiskBoost: 0, recommendedVerifyDepth: "skip" };
85
+ }
86
+ // Detect specific change kinds from changed lines
87
+ let hasSignature = false;
88
+ let hasControlFlow = false;
89
+ let hasImport = false;
90
+ for (const line of changedLines) {
91
+ if (!hasSignature && SIGNATURE_PATTERNS.some(p => p.test(line))) {
92
+ hasSignature = true;
93
+ }
94
+ if (!hasControlFlow && CONTROL_FLOW_PATTERNS.some(p => p.test(line))) {
95
+ hasControlFlow = true;
96
+ }
97
+ if (!hasImport && IMPORT_PATTERNS.some(p => p.test(line))) {
98
+ hasImport = true;
99
+ }
100
+ }
101
+ if (hasSignature)
102
+ changes.push("SIGNATURE_CHANGE");
103
+ if (hasControlFlow)
104
+ changes.push("CONTROL_FLOW_CHANGE");
105
+ if (hasImport)
106
+ changes.push("IMPORT_CHANGE");
107
+ // If none of the specific patterns matched but we have non-style changes, it's behavior
108
+ if (changes.length === 0) {
109
+ changes.push("BEHAVIOR_CHANGE");
110
+ }
111
+ // Calculate risk boost and verify recommendation
112
+ let riskBoost = 0;
113
+ let verifyDepth = "quick";
114
+ if (changes.includes("SIGNATURE_CHANGE")) {
115
+ riskBoost = Math.max(riskBoost, 0.25);
116
+ verifyDepth = "thorough";
117
+ }
118
+ if (changes.includes("CONTROL_FLOW_CHANGE")) {
119
+ riskBoost = Math.max(riskBoost, 0.2);
120
+ verifyDepth = "thorough";
121
+ }
122
+ if (changes.includes("BEHAVIOR_CHANGE")) {
123
+ riskBoost = Math.max(riskBoost, 0.15);
124
+ verifyDepth = "thorough";
125
+ }
126
+ if (changes.includes("IMPORT_CHANGE")) {
127
+ riskBoost = Math.max(riskBoost, 0.1);
128
+ if (verifyDepth !== "thorough")
129
+ verifyDepth = "quick";
130
+ }
131
+ // Clamp risk boost to 0~0.3
132
+ riskBoost = Math.min(riskBoost, 0.3);
133
+ return { path, changes, recommendedRiskBoost: riskBoost, recommendedVerifyDepth: verifyDepth };
134
+ }
135
+ /** Review multiple files and produce aggregate recommendation */
136
+ export function reviewDiffBatch(reviews) {
137
+ if (reviews.length === 0) {
138
+ return { overallRiskBoost: 0, overallVerifyRecommendation: "skip", summary: "No files to review" };
139
+ }
140
+ // Aggregate: worst-case verify depth, max risk boost
141
+ let overallRiskBoost = 0;
142
+ let overallVerify = "skip";
143
+ const depthOrder = { skip: 0, quick: 1, thorough: 2 };
144
+ const depthReverse = ["skip", "quick", "thorough"];
145
+ const kindCounts = {};
146
+ for (const review of reviews) {
147
+ overallRiskBoost = Math.max(overallRiskBoost, review.recommendedRiskBoost);
148
+ if (depthOrder[review.recommendedVerifyDepth] > depthOrder[overallVerify]) {
149
+ overallVerify = review.recommendedVerifyDepth;
150
+ }
151
+ for (const kind of review.changes) {
152
+ kindCounts[kind] = (kindCounts[kind] ?? 0) + 1;
153
+ }
154
+ }
155
+ // Ensure the result is typed correctly
156
+ const overallVerifyRecommendation = depthReverse[depthOrder[overallVerify]];
157
+ // Build summary
158
+ const parts = [`${reviews.length} files reviewed`];
159
+ for (const [kind, count] of Object.entries(kindCounts)) {
160
+ parts.push(`${kind}: ${count}`);
161
+ }
162
+ return {
163
+ overallRiskBoost: Math.min(overallRiskBoost, 0.3),
164
+ overallVerifyRecommendation,
165
+ summary: parts.join(", "),
166
+ };
167
+ }
168
+ //# sourceMappingURL=semantic-diff-reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-diff-reviewer.js","sourceRoot":"","sources":["../src/semantic-diff-reviewer.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@
11
11
  * Design: purely stateful observer — does NOT affect the main loop.
12
12
  * Call check() each iteration. It returns a StallReason or null.
13
13
  */
14
- export type StallReason = "iteration_overrun" | "repeated_errors" | "no_progress" | "patch_entropy";
14
+ export type StallReason = "iteration_overrun" | "repeated_errors" | "no_progress" | "patch_entropy" | "read_loop" | "search_spiral" | "approval_block" | "environment_block" | "budget_corner" | "tool_gate_thrash";
15
15
  export interface StallCheckResult {
16
16
  stalled: boolean;
17
17
  reason: StallReason | null;
@@ -31,6 +31,16 @@ export interface StallDetectorConfig {
31
31
  patchEntropyWindow?: number;
32
32
  /** default 3 (same file+lines modified 3+ times) */
33
33
  patchEntropyThreshold?: number;
34
+ /** default 3 (same file read 3+ times) */
35
+ readLoopThreshold?: number;
36
+ /** default 5 iterations for read_loop window */
37
+ readLoopWindow?: number;
38
+ /** default 2 (same search pattern repeated 2+ times) */
39
+ searchSpiralThreshold?: number;
40
+ /** default 2 (blocked tool called 2+ times) */
41
+ toolGateThrashThreshold?: number;
42
+ /** default 0.9 (budget usage ratio to trigger budget_corner) */
43
+ budgetCornerRatio?: number;
34
44
  }
35
45
  export declare class StallDetector {
36
46
  private estimatedIterations;
@@ -40,6 +50,11 @@ export declare class StallDetector {
40
50
  private noProgressWindow;
41
51
  private patchEntropyWindow;
42
52
  private patchEntropyThreshold;
53
+ private readLoopThreshold;
54
+ private readLoopWindow;
55
+ private searchSpiralThreshold;
56
+ private toolGateThrashThreshold;
57
+ private budgetCornerRatio;
43
58
  private history;
44
59
  constructor(estimatedIterations: number, config?: StallDetectorConfig);
45
60
  /**
@@ -48,8 +63,17 @@ export declare class StallDetector {
48
63
  * @param changedFiles files changed this iteration
49
64
  * @param errorSignature current repeated error signature (or undefined)
50
65
  * @param editedLines optional: Map<filePath, Set<lineNumber>> for patch entropy detection
66
+ * @param extra optional: additional tracking data for new stall types
51
67
  */
52
- check(iteration: number, changedFiles: string[], errorSignature: string | undefined, editedLines?: Map<string, Set<number>>): StallCheckResult;
68
+ check(iteration: number, changedFiles: string[], errorSignature: string | undefined, editedLines?: Map<string, Set<number>>, extra?: {
69
+ readFiles?: string[];
70
+ searchPatterns?: string[];
71
+ searchResultHashes?: string[];
72
+ blockedTools?: string[];
73
+ pendingApproval?: boolean;
74
+ environmentBlocked?: boolean;
75
+ budgetUsageRatio?: number;
76
+ }): StallCheckResult;
53
77
  /** Reset state (call when task changes or goal changes) */
54
78
  reset(): void;
55
79
  }