@yuaone/core 0.9.43 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-affordance.d.ts +37 -0
- package/dist/agent-affordance.d.ts.map +1 -0
- package/dist/agent-affordance.js +139 -0
- package/dist/agent-affordance.js.map +1 -0
- package/dist/agent-decision-types.d.ts +262 -0
- package/dist/agent-decision-types.d.ts.map +1 -0
- package/dist/agent-decision-types.js +19 -0
- package/dist/agent-decision-types.js.map +1 -0
- package/dist/agent-decision.d.ts +52 -0
- package/dist/agent-decision.d.ts.map +1 -0
- package/dist/agent-decision.js +767 -0
- package/dist/agent-decision.js.map +1 -0
- package/dist/agent-loop.d.ts +37 -79
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +730 -586
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent-reasoning-engine.d.ts +48 -0
- package/dist/agent-reasoning-engine.d.ts.map +1 -0
- package/dist/agent-reasoning-engine.js +544 -0
- package/dist/agent-reasoning-engine.js.map +1 -0
- package/dist/codebase-context.d.ts +3 -0
- package/dist/codebase-context.d.ts.map +1 -1
- package/dist/codebase-context.js +15 -6
- package/dist/codebase-context.js.map +1 -1
- package/dist/command-plan-compiler.d.ts +43 -0
- package/dist/command-plan-compiler.d.ts.map +1 -0
- package/dist/command-plan-compiler.js +164 -0
- package/dist/command-plan-compiler.js.map +1 -0
- package/dist/dependency-guard.d.ts +18 -0
- package/dist/dependency-guard.d.ts.map +1 -0
- package/dist/dependency-guard.js +113 -0
- package/dist/dependency-guard.js.map +1 -0
- package/dist/execution-engine.d.ts +10 -1
- package/dist/execution-engine.d.ts.map +1 -1
- package/dist/execution-engine.js +162 -8
- package/dist/execution-engine.js.map +1 -1
- package/dist/execution-receipt.d.ts +62 -0
- package/dist/execution-receipt.d.ts.map +1 -0
- package/dist/execution-receipt.js +67 -0
- package/dist/execution-receipt.js.map +1 -0
- package/dist/failure-surface-writer.d.ts +13 -0
- package/dist/failure-surface-writer.d.ts.map +1 -0
- package/dist/failure-surface-writer.js +33 -0
- package/dist/failure-surface-writer.js.map +1 -0
- package/dist/file-chunker.d.ts +26 -0
- package/dist/file-chunker.d.ts.map +1 -0
- package/dist/file-chunker.js +103 -0
- package/dist/file-chunker.js.map +1 -0
- package/dist/image-observer.d.ts +22 -0
- package/dist/image-observer.d.ts.map +1 -0
- package/dist/image-observer.js +60 -0
- package/dist/image-observer.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -1
- package/dist/judgment-rules.d.ts +44 -0
- package/dist/judgment-rules.d.ts.map +1 -0
- package/dist/judgment-rules.js +185 -0
- package/dist/judgment-rules.js.map +1 -0
- package/dist/memory-decay.d.ts +41 -0
- package/dist/memory-decay.d.ts.map +1 -0
- package/dist/memory-decay.js +62 -0
- package/dist/memory-decay.js.map +1 -0
- package/dist/memory-manager.d.ts.map +1 -1
- package/dist/memory-manager.js +30 -0
- package/dist/memory-manager.js.map +1 -1
- package/dist/model-weakness-tracker.d.ts +42 -0
- package/dist/model-weakness-tracker.d.ts.map +1 -0
- package/dist/model-weakness-tracker.js +107 -0
- package/dist/model-weakness-tracker.js.map +1 -0
- package/dist/overhead-governor.d.ts +3 -1
- package/dist/overhead-governor.d.ts.map +1 -1
- package/dist/overhead-governor.js +5 -0
- package/dist/overhead-governor.js.map +1 -1
- package/dist/patch-scope-controller.d.ts +44 -0
- package/dist/patch-scope-controller.d.ts.map +1 -0
- package/dist/patch-scope-controller.js +107 -0
- package/dist/patch-scope-controller.js.map +1 -0
- package/dist/patch-transaction.d.ts +53 -0
- package/dist/patch-transaction.d.ts.map +1 -0
- package/dist/patch-transaction.js +119 -0
- package/dist/patch-transaction.js.map +1 -0
- package/dist/pre-write-validator.d.ts +29 -0
- package/dist/pre-write-validator.d.ts.map +1 -0
- package/dist/pre-write-validator.js +97 -0
- package/dist/pre-write-validator.js.map +1 -0
- package/dist/prompt-builder.d.ts +25 -0
- package/dist/prompt-builder.d.ts.map +1 -0
- package/dist/prompt-builder.js +93 -0
- package/dist/prompt-builder.js.map +1 -0
- package/dist/prompt-envelope.d.ts +40 -0
- package/dist/prompt-envelope.d.ts.map +1 -0
- package/dist/prompt-envelope.js +16 -0
- package/dist/prompt-envelope.js.map +1 -0
- package/dist/prompt-runtime.d.ts +66 -0
- package/dist/prompt-runtime.d.ts.map +1 -0
- package/dist/prompt-runtime.js +492 -0
- package/dist/prompt-runtime.js.map +1 -0
- package/dist/repo-capability-profile.d.ts +24 -0
- package/dist/repo-capability-profile.d.ts.map +1 -0
- package/dist/repo-capability-profile.js +113 -0
- package/dist/repo-capability-profile.js.map +1 -0
- package/dist/security-gate.d.ts +39 -0
- package/dist/security-gate.d.ts.map +1 -0
- package/dist/security-gate.js +121 -0
- package/dist/security-gate.js.map +1 -0
- package/dist/self-evaluation.d.ts +22 -0
- package/dist/self-evaluation.d.ts.map +1 -0
- package/dist/self-evaluation.js +43 -0
- package/dist/self-evaluation.js.map +1 -0
- package/dist/semantic-diff-reviewer.d.ts +28 -0
- package/dist/semantic-diff-reviewer.d.ts.map +1 -0
- package/dist/semantic-diff-reviewer.js +168 -0
- package/dist/semantic-diff-reviewer.js.map +1 -0
- package/dist/stall-detector.d.ts +26 -2
- package/dist/stall-detector.d.ts.map +1 -1
- package/dist/stall-detector.js +128 -3
- package/dist/stall-detector.js.map +1 -1
- package/dist/system-core.d.ts +27 -0
- package/dist/system-core.d.ts.map +1 -0
- package/dist/system-core.js +269 -0
- package/dist/system-core.js.map +1 -0
- package/dist/system-prompt.d.ts +4 -0
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +12 -218
- package/dist/system-prompt.js.map +1 -1
- package/dist/target-file-ranker.d.ts +38 -0
- package/dist/target-file-ranker.d.ts.map +1 -0
- package/dist/target-file-ranker.js +90 -0
- package/dist/target-file-ranker.js.map +1 -0
- package/dist/task-classifier.d.ts +6 -0
- package/dist/task-classifier.d.ts.map +1 -1
- package/dist/task-classifier.js +6 -0
- package/dist/task-classifier.js.map +1 -1
- package/dist/test-impact-planner.d.ts +16 -0
- package/dist/test-impact-planner.d.ts.map +1 -0
- package/dist/test-impact-planner.js +68 -0
- package/dist/test-impact-planner.js.map +1 -0
- package/dist/tool-outcome-cache.d.ts +41 -0
- package/dist/tool-outcome-cache.d.ts.map +1 -0
- package/dist/tool-outcome-cache.js +88 -0
- package/dist/tool-outcome-cache.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/verifier-rules.d.ts +15 -0
- package/dist/verifier-rules.d.ts.map +1 -0
- package/dist/verifier-rules.js +80 -0
- package/dist/verifier-rules.js.map +1 -0
- package/dist/workspace-mutation-policy.d.ts +28 -0
- package/dist/workspace-mutation-policy.d.ts.map +1 -0
- package/dist/workspace-mutation-policy.js +56 -0
- package/dist/workspace-mutation-policy.js.map +1 -0
- 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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"}
|
package/dist/stall-detector.d.ts
CHANGED
|
@@ -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
|
|
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
|
}
|