soloforge 1.4.6 → 1.4.8

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 (57) hide show
  1. package/README.md +44 -4
  2. package/dist/adapters/claude_code/tools.d.ts.map +1 -1
  3. package/dist/adapters/claude_code/tools.js +129 -10
  4. package/dist/adapters/claude_code/tools.js.map +1 -1
  5. package/dist/bin/soloforge.d.ts.map +1 -1
  6. package/dist/bin/soloforge.js +3 -2
  7. package/dist/bin/soloforge.js.map +1 -1
  8. package/dist/engine/change_coordinator.d.ts.map +1 -1
  9. package/dist/engine/change_coordinator.js +2 -1
  10. package/dist/engine/change_coordinator.js.map +1 -1
  11. package/dist/engine/core_engineering_principles.d.ts.map +1 -1
  12. package/dist/engine/core_engineering_principles.js +2 -1
  13. package/dist/engine/core_engineering_principles.js.map +1 -1
  14. package/dist/engine/enforcement_guard.d.ts.map +1 -1
  15. package/dist/engine/enforcement_guard.js +2 -1
  16. package/dist/engine/enforcement_guard.js.map +1 -1
  17. package/dist/engine/extension_platform_contracts.d.ts +6 -0
  18. package/dist/engine/extension_platform_contracts.d.ts.map +1 -1
  19. package/dist/engine/extension_platform_contracts.js.map +1 -1
  20. package/dist/engine/impact_analyzer.d.ts.map +1 -1
  21. package/dist/engine/impact_analyzer.js +5 -23
  22. package/dist/engine/impact_analyzer.js.map +1 -1
  23. package/dist/engine/intent_expander.d.ts.map +1 -1
  24. package/dist/engine/intent_expander.js +9 -46
  25. package/dist/engine/intent_expander.js.map +1 -1
  26. package/dist/engine/onboarding.d.ts.map +1 -1
  27. package/dist/engine/onboarding.js +2 -1
  28. package/dist/engine/onboarding.js.map +1 -1
  29. package/dist/engine/path_scope_utils.d.ts +21 -0
  30. package/dist/engine/path_scope_utils.d.ts.map +1 -0
  31. package/dist/engine/path_scope_utils.js +126 -0
  32. package/dist/engine/path_scope_utils.js.map +1 -0
  33. package/dist/engine/plan_proposal_gate.d.ts.map +1 -1
  34. package/dist/engine/plan_proposal_gate.js +2 -1
  35. package/dist/engine/plan_proposal_gate.js.map +1 -1
  36. package/dist/engine/release_readiness_gate.d.ts.map +1 -1
  37. package/dist/engine/release_readiness_gate.js +15 -0
  38. package/dist/engine/release_readiness_gate.js.map +1 -1
  39. package/dist/engine/scope_controller.d.ts.map +1 -1
  40. package/dist/engine/scope_controller.js +5 -7
  41. package/dist/engine/scope_controller.js.map +1 -1
  42. package/dist/engine/scope_lease.d.ts.map +1 -1
  43. package/dist/engine/scope_lease.js +2 -2
  44. package/dist/engine/scope_lease.js.map +1 -1
  45. package/dist/engine/scope_resolver.d.ts +11 -0
  46. package/dist/engine/scope_resolver.d.ts.map +1 -0
  47. package/dist/engine/scope_resolver.js +526 -0
  48. package/dist/engine/scope_resolver.js.map +1 -0
  49. package/dist/engine/workspace_lease.d.ts.map +1 -1
  50. package/dist/engine/workspace_lease.js +6 -5
  51. package/dist/engine/workspace_lease.js.map +1 -1
  52. package/dist/knowledge/index_manager.d.ts.map +1 -1
  53. package/dist/knowledge/index_manager.js +2 -1
  54. package/dist/knowledge/index_manager.js.map +1 -1
  55. package/dist/types.d.ts +45 -0
  56. package/dist/types.d.ts.map +1 -1
  57. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"scope_controller.d.ts","sourceRoot":"","sources":["../../src/engine/scope_controller.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA4EpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,gBAAgB,CAwDlB"}
1
+ {"version":3,"file":"scope_controller.d.ts","sourceRoot":"","sources":["../../src/engine/scope_controller.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA6EpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,gBAAgB,CAuDlB"}
@@ -2,6 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { execFileSync } from "node:child_process";
4
4
  import { debugLog } from "./debug_log.js";
5
+ import { hasGlobPattern, isPathInScope } from "./path_scope_utils.js";
5
6
  /**
6
7
  * 作用域控制器 — 检查文件路径是否在允许范围内,并检测敏感信息泄露。
7
8
  *
@@ -93,13 +94,10 @@ export function checkScope(filePath, allowedPaths, content) {
93
94
  const resolvedPath = realPath(filePath);
94
95
  // 检查路径是否在允许的 scope 内(防止路径穿越攻击)
95
96
  const inScope = allowedPaths.some((allowed) => {
96
- const resolved = realPath(allowed);
97
- if (!resolvedPath.startsWith(resolved))
98
- return false;
99
- // 目录边界检查:匹配后的下一个字符必须是 / 或已到末尾
100
- if (resolvedPath.length === resolved.length)
101
- return true;
102
- return resolvedPath[resolved.length] === "/";
97
+ const resolved = hasGlobPattern(allowed)
98
+ ? (path.isAbsolute(allowed) ? allowed : path.resolve(allowed))
99
+ : realPath(allowed);
100
+ return isPathInScope(resolvedPath, resolved);
103
101
  });
104
102
  if (!inScope) {
105
103
  debugLog(`作用域检查: 文件 ${filePath} 不在允许的 scope 内`);
@@ -1 +1 @@
1
- {"version":3,"file":"scope_controller.js","sourceRoot":"","sources":["../../src/engine/scope_controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope_controller.js","sourceRoot":"","sources":["../../src/engine/scope_controller.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope_lease.d.ts","sourceRoot":"","sources":["../../src/engine/scope_lease.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,WAAW;AACX,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,WAAW;AACX,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC1C;AAED,aAAa;AACb,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,MAAM,CAAS;IAEvB;;;OAGG;gBACS,QAAQ,EAAE,MAAM;IAM5B,2BAA2B;IAC3B,OAAO,CAAC,YAAY;IAgBpB,kBAAkB;IAClB,OAAO,CAAC,OAAO;IAOf;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU;IAexD;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAW1C;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAoBlE;;;OAGG;IACH,eAAe,IAAI,UAAU,EAAE;IAK/B;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAKlD;;;OAGG;IACH,UAAU,IAAI,YAAY;IAe1B;;OAEG;IACH,KAAK,IAAI,IAAI;CAMd"}
1
+ {"version":3,"file":"scope_lease.d.ts","sourceRoot":"","sources":["../../src/engine/scope_lease.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,WAAW;AACX,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,WAAW;AACX,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC1C;AAED,aAAa;AACb,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,MAAM,CAAS;IAEvB;;;OAGG;gBACS,QAAQ,EAAE,MAAM;IAM5B,2BAA2B;IAC3B,OAAO,CAAC,YAAY;IAgBpB,kBAAkB;IAClB,OAAO,CAAC,OAAO;IAOf;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU;IAexD;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAW1C;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAoBlE;;;OAGG;IACH,eAAe,IAAI,UAAU,EAAE;IAK/B;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAKlD;;;OAGG;IACH,UAAU,IAAI,YAAY;IAe1B;;OAEG;IACH,KAAK,IAAI,IAAI;CAMd"}
@@ -12,6 +12,7 @@
12
12
  import fs from "node:fs";
13
13
  import path from "node:path";
14
14
  import { debug } from "./logger.js";
15
+ import { isPathInScope } from "./path_scope_utils.js";
15
16
  /** 范围租约存储 */
16
17
  export class ScopeLeaseStore {
17
18
  filePath;
@@ -160,7 +161,6 @@ export class ScopeLeaseStore {
160
161
  }
161
162
  /** 判断 child 路径是否在 parent 路径下 */
162
163
  function isParentPath(parent, child) {
163
- const rel = path.relative(parent, child);
164
- return rel.length > 0 && !rel.startsWith("..");
164
+ return isPathInScope(child, parent, { caseSensitive: true });
165
165
  }
166
166
  //# sourceMappingURL=scope_lease.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope_lease.js","sourceRoot":"","sources":["../../src/engine/scope_lease.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope_lease.js","sourceRoot":"","sources":["../../src/engine/scope_lease.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ClassifyResult, ProjectConfig, ScopeResult } from "../types.js";
2
+ import type { IntentRouteDecision } from "./intent_router.js";
3
+ export interface ResolveTaskScopeInput {
4
+ projectPath: string;
5
+ config: ProjectConfig;
6
+ classification: ClassifyResult;
7
+ degraded: boolean;
8
+ routeDecision?: IntentRouteDecision;
9
+ }
10
+ export declare function resolveTaskScope(input: ResolveTaskScopeInput): ScopeResult;
11
+ //# sourceMappingURL=scope_resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope_resolver.d.ts","sourceRoot":"","sources":["../../src/engine/scope_resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAIb,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAW9D,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAigBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,WAAW,CA6F1E"}
@@ -0,0 +1,526 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { ensureTrailingSlash, hasGlobPattern, isPathInScope, isSameOrDescendantPath, matchesScopePattern, normalizeScopePattern, toPosixPath, } from "./path_scope_utils.js";
4
+ const IGNORED_DIRS = new Set([
5
+ ".claude",
6
+ ".codex",
7
+ ".git",
8
+ ".soloforge",
9
+ ".trae",
10
+ "build",
11
+ "coverage",
12
+ "dist",
13
+ "node_modules",
14
+ "out",
15
+ "target",
16
+ ]);
17
+ const BACKEND_HINTS = [
18
+ "backend",
19
+ "server",
20
+ "service",
21
+ "services",
22
+ "api",
23
+ "web",
24
+ "model",
25
+ "dao",
26
+ "repository",
27
+ ];
28
+ const FRONTEND_HINTS = [
29
+ "frontend",
30
+ "client",
31
+ "webapp",
32
+ "ui",
33
+ "portal",
34
+ "platform",
35
+ "institution",
36
+ ];
37
+ const KNOWN_SOURCE_ROOT_PATTERN = /^(?:src|[^/]+\/src|[^/]+\/[^/]+\/src|[^/]+\/[^/]+\/[^/]+\/src)\/$/;
38
+ const PATH_CASE_SENSITIVE = process.platform !== "win32" && process.platform !== "darwin";
39
+ function pathExists(projectPath, relativePath) {
40
+ try {
41
+ return fs.existsSync(path.join(projectPath, relativePath));
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ function isDirectory(projectPath, relativePath) {
48
+ try {
49
+ return fs.statSync(path.join(projectPath, relativePath)).isDirectory();
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ function readDirSafe(projectPath, relativePath) {
56
+ try {
57
+ return fs.readdirSync(path.join(projectPath, relativePath), { withFileTypes: true });
58
+ }
59
+ catch {
60
+ return [];
61
+ }
62
+ }
63
+ function normalizeRelPath(rawPath, basePath) {
64
+ const normalized = String(rawPath ?? "").replace(/\\/g, "/").trim();
65
+ if (!normalized || normalized === ".")
66
+ return normalizeScopePattern(basePath ?? ".");
67
+ const combined = basePath && basePath !== "."
68
+ ? path.posix.normalize(path.posix.join(toPosixPath(basePath), normalized))
69
+ : path.posix.normalize(normalized);
70
+ return normalizeScopePattern(combined);
71
+ }
72
+ function dedupePreserveOrder(paths) {
73
+ const seen = new Set();
74
+ const result = [];
75
+ for (const raw of paths) {
76
+ const normalized = normalizeScopePattern(raw);
77
+ if (!normalized || seen.has(normalized))
78
+ continue;
79
+ seen.add(normalized);
80
+ result.push(normalized);
81
+ }
82
+ return result;
83
+ }
84
+ function removeNestedBroadDuplicates(paths) {
85
+ const sorted = dedupePreserveOrder(paths).sort((a, b) => a.length - b.length);
86
+ const result = [];
87
+ for (const candidate of sorted) {
88
+ if (hasGlobPattern(candidate)) {
89
+ result.push(candidate);
90
+ continue;
91
+ }
92
+ if (KNOWN_SOURCE_ROOT_PATTERN.test(candidate)) {
93
+ for (let i = result.length - 1; i >= 0; i -= 1) {
94
+ const existing = result[i];
95
+ if (!hasGlobPattern(existing)
96
+ && KNOWN_SOURCE_ROOT_PATTERN.test(existing)
97
+ && isSameOrDescendantPath(candidate, existing, { caseSensitive: PATH_CASE_SENSITIVE })) {
98
+ result.splice(i, 1);
99
+ }
100
+ }
101
+ }
102
+ if (result.some((existing) => !hasGlobPattern(existing)
103
+ && isSameOrDescendantPath(candidate, existing, { caseSensitive: PATH_CASE_SENSITIVE }))) {
104
+ continue;
105
+ }
106
+ result.push(candidate);
107
+ }
108
+ return result;
109
+ }
110
+ function getAffectedRepos(classification) {
111
+ return Array.isArray(classification?.affected_repos)
112
+ ? classification.affected_repos.filter((repo) => typeof repo === "string" && repo.length > 0)
113
+ : [];
114
+ }
115
+ function taskNeedsBackend(input) {
116
+ const affected = getAffectedRepos(input.classification).join(" ").toLowerCase();
117
+ const intent = `${input.classification.task_type} ${input.routeDecision?.workflow_intent ?? ""} ${affected}`;
118
+ if (/backend|server|api|java|spring|数据库|接口|后端|服务|mapper|controller|service/i.test(intent))
119
+ return true;
120
+ if (input.config.tech_stack.backend?.framework && input.config.tech_stack.backend.framework !== "unknown") {
121
+ return affected.length === 0 || /backend|server|api|service|web|model/.test(affected);
122
+ }
123
+ return false;
124
+ }
125
+ function taskNeedsFrontend(input) {
126
+ const affected = getAffectedRepos(input.classification).join(" ").toLowerCase();
127
+ const intent = `${input.classification.task_type} ${input.routeDecision?.workflow_intent ?? ""} ${affected}`;
128
+ if (/frontend|client|react|vue|页面|前端|component|route|ui/i.test(intent))
129
+ return true;
130
+ if (input.config.tech_stack.frontend?.framework && input.config.tech_stack.frontend.framework !== "unknown") {
131
+ return affected.length === 0 || /frontend|client|ui|app|web|platform|institution/.test(affected);
132
+ }
133
+ return false;
134
+ }
135
+ function roleFromPath(relativePath) {
136
+ const lower = relativePath.toLowerCase();
137
+ if (FRONTEND_HINTS.some((hint) => lower.split("/").includes(hint) || lower.includes(`/${hint}/`)))
138
+ return "frontend";
139
+ if (BACKEND_HINTS.some((hint) => lower.split("/").includes(hint) || lower.includes(`/${hint}/`)))
140
+ return "backend";
141
+ if (/(?:^|\/)src\/main\/(?:java|kotlin|scala)(?:\/|$)/.test(lower))
142
+ return "backend";
143
+ if (/(?:^|\/)(?:src|app)\/(?:pages|components|views|router|routes)(?:\/|$)/.test(lower))
144
+ return "frontend";
145
+ return "shared";
146
+ }
147
+ function addSourceRoot(roots, root) {
148
+ const normalized = ensureTrailingSlash(root.path);
149
+ if (!normalized || normalized === "./")
150
+ return;
151
+ const existing = roots.get(normalized);
152
+ if (existing) {
153
+ existing.evidence.push(...root.evidence.filter((item) => !existing.evidence.includes(item)));
154
+ if (existing.role === "shared" && root.role !== "shared")
155
+ existing.role = root.role;
156
+ return;
157
+ }
158
+ roots.set(normalized, { ...root, path: normalized });
159
+ }
160
+ function discoverMavenRoots(projectPath, roots) {
161
+ const stack = [""];
162
+ while (stack.length > 0) {
163
+ const current = stack.pop();
164
+ const entries = readDirSafe(projectPath, current);
165
+ for (const entry of entries) {
166
+ if (!entry.isDirectory() || IGNORED_DIRS.has(entry.name))
167
+ continue;
168
+ const child = current ? `${current}/${entry.name}` : entry.name;
169
+ const depth = child.split("/").length;
170
+ if (depth <= 4)
171
+ stack.push(child);
172
+ }
173
+ const hasJavaSource = isDirectory(projectPath, path.posix.join(current, "src/main/java"))
174
+ || isDirectory(projectPath, path.posix.join(current, "src/main/kotlin"));
175
+ const hasBuildFile = pathExists(projectPath, path.posix.join(current, "pom.xml"))
176
+ || pathExists(projectPath, path.posix.join(current, "build.gradle"))
177
+ || pathExists(projectPath, path.posix.join(current, "build.gradle.kts"));
178
+ const currentIsSourceLayer = /(?:^|\/)src(?:\/main)?$/i.test(current);
179
+ if (!currentIsSourceLayer && (hasJavaSource || (hasBuildFile && isDirectory(projectPath, path.posix.join(current, "src"))))) {
180
+ addSourceRoot(roots, {
181
+ path: current ? `${current}/src/` : "src/",
182
+ role: "backend",
183
+ evidence: [
184
+ hasJavaSource ? "detected src/main Java/Kotlin source tree" : "detected JVM build file with src directory",
185
+ ],
186
+ });
187
+ }
188
+ }
189
+ }
190
+ function discoverFrontendRoots(projectPath, roots) {
191
+ const containerNames = new Set(["apps", "packages", "modules", "services", "clients", "frontends", "workspaces"]);
192
+ const stack = [""];
193
+ while (stack.length > 0) {
194
+ const current = stack.pop();
195
+ for (const entry of readDirSafe(projectPath, current)) {
196
+ if (!entry.isDirectory() || IGNORED_DIRS.has(entry.name))
197
+ continue;
198
+ const child = current ? `${current}/${entry.name}` : entry.name;
199
+ const depth = child.split("/").length;
200
+ if (depth <= 3)
201
+ stack.push(child);
202
+ }
203
+ const srcCandidate = current ? `${current}/src` : "src";
204
+ if (isDirectory(projectPath, srcCandidate)) {
205
+ addSourceRoot(roots, {
206
+ path: `${srcCandidate}/`,
207
+ role: roleFromPath(srcCandidate),
208
+ evidence: ["detected frontend source directory candidate"],
209
+ });
210
+ }
211
+ if (containerNames.has(path.posix.basename(current))) {
212
+ for (const entry of readDirSafe(projectPath, current)) {
213
+ if (!entry.isDirectory() || IGNORED_DIRS.has(entry.name))
214
+ continue;
215
+ const src = current ? `${current}/${entry.name}/src` : `${entry.name}/src`;
216
+ if (!isDirectory(projectPath, src))
217
+ continue;
218
+ addSourceRoot(roots, {
219
+ path: `${src}/`,
220
+ role: "frontend",
221
+ evidence: [`detected workspace package source: ${current || "."}/*/src`],
222
+ });
223
+ }
224
+ }
225
+ }
226
+ }
227
+ function discoverSourceRoots(projectPath) {
228
+ const roots = new Map();
229
+ discoverMavenRoots(projectPath, roots);
230
+ discoverFrontendRoots(projectPath, roots);
231
+ for (const topLevel of readDirSafe(projectPath, "")) {
232
+ if (!topLevel.isDirectory() || IGNORED_DIRS.has(topLevel.name))
233
+ continue;
234
+ const directSrc = `${topLevel.name}/src`;
235
+ if (isDirectory(projectPath, directSrc)) {
236
+ addSourceRoot(roots, {
237
+ path: `${directSrc}/`,
238
+ role: roleFromPath(directSrc),
239
+ evidence: ["detected top-level module src directory"],
240
+ });
241
+ }
242
+ }
243
+ return [...roots.values()].sort((a, b) => a.path.localeCompare(b.path));
244
+ }
245
+ function expandWeakPath(projectPath, declaredPath, role, discoveredRoots, warnings) {
246
+ const normalized = normalizeRelPath(declaredPath);
247
+ if (pathExists(projectPath, normalized))
248
+ return [normalized];
249
+ const basename = normalized.replace(/\/$/, "");
250
+ if (basename === "src" || basename.endsWith("/src")) {
251
+ const matchingRoots = discoveredRoots
252
+ .filter((root) => role === "shared" || root.role === role || root.role === "shared")
253
+ .map((root) => root.path);
254
+ if (matchingRoots.length > 0) {
255
+ warnings.push(`scope ${declaredPath} 在项目根不存在,已按真实多模块源码树展开为 ${matchingRoots.join(", ")}`);
256
+ return matchingRoots;
257
+ }
258
+ }
259
+ warnings.push(`配置 scope ${declaredPath} 在项目中不存在,保留为声明路径但标记为低置信`);
260
+ return [normalized];
261
+ }
262
+ function addCandidate(candidates, candidate) {
263
+ for (const resolved of candidate.evidence.length > 0 ? [candidate] : [candidate]) {
264
+ candidates.push({
265
+ ...resolved,
266
+ path: normalizeScopePattern(resolved.path),
267
+ });
268
+ }
269
+ }
270
+ function addConfigScopeCandidates(input, discoveredRoots, candidates, warnings) {
271
+ const needsBackend = taskNeedsBackend(input);
272
+ const needsFrontend = taskNeedsFrontend(input);
273
+ if (needsBackend) {
274
+ for (const declared of input.config.scope?.backend ?? []) {
275
+ for (const expanded of expandWeakPath(input.projectPath, declared, "backend", discoveredRoots, warnings)) {
276
+ addCandidate(candidates, {
277
+ path: expanded,
278
+ source: "config.scope.backend",
279
+ confidence: pathExists(input.projectPath, expanded) ? "high" : "low",
280
+ role: "backend",
281
+ declared_path: declared,
282
+ evidence: ["configured backend scope"],
283
+ });
284
+ }
285
+ }
286
+ }
287
+ if (needsFrontend) {
288
+ for (const declared of input.config.scope?.frontend ?? []) {
289
+ for (const expanded of expandWeakPath(input.projectPath, declared, "frontend", discoveredRoots, warnings)) {
290
+ addCandidate(candidates, {
291
+ path: expanded,
292
+ source: "config.scope.frontend",
293
+ confidence: pathExists(input.projectPath, expanded) ? "high" : "low",
294
+ role: "frontend",
295
+ declared_path: declared,
296
+ evidence: ["configured frontend scope"],
297
+ });
298
+ }
299
+ }
300
+ }
301
+ }
302
+ function repoMatches(repo, affectedRepos) {
303
+ if (affectedRepos.length === 0)
304
+ return true;
305
+ const name = repo.name.toLowerCase();
306
+ const repoPath = repo.path.toLowerCase();
307
+ return affectedRepos.some((affected) => {
308
+ const normalized = affected.toLowerCase();
309
+ return normalized === name
310
+ || name.includes(normalized)
311
+ || normalized.includes(name)
312
+ || repoPath.includes(normalized);
313
+ });
314
+ }
315
+ function repoRole(repo) {
316
+ const combined = `${repo.name} ${repo.path} ${repo.lang} ${repo.framework}`.toLowerCase();
317
+ if (/react|vue|angular|frontend|client|ui|typescript/.test(combined))
318
+ return "frontend";
319
+ if (/spring|java|backend|server|api|service|go|python|node/.test(combined))
320
+ return "backend";
321
+ return "shared";
322
+ }
323
+ function addRepoCandidates(input, discoveredRoots, candidates, warnings) {
324
+ const affectedRepos = getAffectedRepos(input.classification);
325
+ for (const repo of input.config.repos ?? []) {
326
+ if (!repoMatches(repo, affectedRepos))
327
+ continue;
328
+ const role = repoRole(repo);
329
+ for (const declaredScope of repo.scope ?? []) {
330
+ const scopeLooksProjectRelative = declaredScope.replace(/\\/g, "/").startsWith(`${repo.path.replace(/\\/g, "/").replace(/\/$/, "")}/`);
331
+ const declared = scopeLooksProjectRelative
332
+ ? normalizeRelPath(declaredScope)
333
+ : normalizeRelPath(declaredScope, repo.path);
334
+ const expandedPaths = pathExists(input.projectPath, declared)
335
+ ? [declared]
336
+ : expandWeakPath(input.projectPath, declared, role, discoveredRoots, warnings);
337
+ for (const expanded of expandedPaths) {
338
+ addCandidate(candidates, {
339
+ path: expanded,
340
+ source: "config.repos.scope",
341
+ confidence: pathExists(input.projectPath, expanded) ? "high" : "medium",
342
+ role,
343
+ repo_name: repo.name,
344
+ base_path: normalizeRelPath(repo.path),
345
+ declared_path: declaredScope,
346
+ evidence: [`repo ${repo.name} scope`],
347
+ });
348
+ }
349
+ }
350
+ }
351
+ }
352
+ function addRouteCandidates(input, candidates) {
353
+ for (const routePath of input.routeDecision?.scope?.allowed_paths ?? []) {
354
+ addCandidate(candidates, {
355
+ path: normalizeRelPath(routePath),
356
+ source: "route_decision.scope.allowed_paths",
357
+ confidence: "high",
358
+ role: "shared",
359
+ declared_path: routePath,
360
+ evidence: ["explicit route scope"],
361
+ });
362
+ }
363
+ }
364
+ function addFingerprintCandidates(input, discoveredRoots, candidates) {
365
+ const needsBackend = taskNeedsBackend(input);
366
+ const needsFrontend = taskNeedsFrontend(input);
367
+ for (const root of discoveredRoots) {
368
+ if ((root.role === "backend" && !needsBackend) || (root.role === "frontend" && !needsFrontend))
369
+ continue;
370
+ addCandidate(candidates, {
371
+ path: root.path,
372
+ source: "project_fingerprint.source_roots",
373
+ confidence: "medium",
374
+ role: root.role,
375
+ evidence: root.evidence,
376
+ });
377
+ }
378
+ }
379
+ function buildSources(candidates, selectedPaths) {
380
+ const grouped = new Map();
381
+ for (const candidate of candidates) {
382
+ if (!selectedPaths.includes(candidate.path))
383
+ continue;
384
+ const key = [
385
+ candidate.source,
386
+ candidate.role,
387
+ candidate.repo_name ?? "",
388
+ candidate.base_path ?? "",
389
+ candidate.declared_path ?? candidate.path,
390
+ ].join("|");
391
+ const current = grouped.get(key);
392
+ if (current) {
393
+ if (!current.resolved_paths.includes(candidate.path))
394
+ current.resolved_paths.push(candidate.path);
395
+ current.evidence.push(...candidate.evidence.filter((item) => !current.evidence.includes(item)));
396
+ }
397
+ else {
398
+ grouped.set(key, {
399
+ source: candidate.source,
400
+ confidence: candidate.confidence,
401
+ role: candidate.role,
402
+ repo_name: candidate.repo_name,
403
+ base_path: candidate.base_path,
404
+ declared_paths: [candidate.declared_path ?? candidate.path],
405
+ resolved_paths: [candidate.path],
406
+ evidence: [...candidate.evidence],
407
+ });
408
+ }
409
+ }
410
+ return [...grouped.values()];
411
+ }
412
+ function readonlyFromRepos(input) {
413
+ const affected = getAffectedRepos(input.classification);
414
+ const readonly = [];
415
+ for (const repo of input.config.repos ?? []) {
416
+ if (repoMatches(repo, affected))
417
+ continue;
418
+ for (const scope of repo.scope ?? []) {
419
+ readonly.push(normalizeRelPath(scope, repo.path));
420
+ }
421
+ }
422
+ return dedupePreserveOrder(readonly);
423
+ }
424
+ function isBroadRootOnly(paths) {
425
+ return paths.length === 1 && (paths[0] === "." || paths[0] === "./");
426
+ }
427
+ function buildReport(input, allowedPaths, readonlyPaths, newFilesAllowed, candidates, discoveredRoots, warnings, conflicts, status) {
428
+ return {
429
+ status,
430
+ project_root: input.projectPath,
431
+ path_semantics: {
432
+ storage_format: "project_relative_posix",
433
+ host_platform: process.platform,
434
+ case_sensitive: process.platform !== "win32" && process.platform !== "darwin",
435
+ },
436
+ allowed_paths: allowedPaths,
437
+ readonly_paths: readonlyPaths,
438
+ new_files_allowed: newFilesAllowed,
439
+ sources: buildSources(candidates, allowedPaths),
440
+ discovered_source_roots: discoveredRoots.map((root) => root.path),
441
+ warnings: [...new Set(warnings)],
442
+ conflicts: [...new Set(conflicts)],
443
+ recovery_commands: [
444
+ "soloforge doctor",
445
+ "soloforge config repair --dry-run",
446
+ "soloforge init --interactive",
447
+ "soloforge sync-templates",
448
+ "soloforge sync-adapters",
449
+ ],
450
+ };
451
+ }
452
+ export function resolveTaskScope(input) {
453
+ if (input.routeDecision && !input.routeDecision.mutation_allowed) {
454
+ const outputArtifact = input.routeDecision.output_artifact;
455
+ const allowedPaths = [];
456
+ if (outputArtifact?.path) {
457
+ const dir = outputArtifact.path.replace(/\\/g, "/").replace(/\/[^/]+$/, "");
458
+ allowedPaths.push(ensureTrailingSlash(dir || "."));
459
+ }
460
+ else {
461
+ allowedPaths.push(".soloforge/output/");
462
+ }
463
+ const readonlyPaths = dedupePreserveOrder(input.config.repos.flatMap((repo) => (repo.scope ?? []).map((scope) => normalizeRelPath(scope, repo.path))));
464
+ const candidates = allowedPaths.map((allowed) => ({
465
+ path: allowed,
466
+ source: "route_decision.output_artifact",
467
+ confidence: "high",
468
+ role: "output",
469
+ evidence: ["read-only route may only write declared output artifact directory"],
470
+ }));
471
+ return {
472
+ allowed_paths: allowedPaths,
473
+ readonly_paths: readonlyPaths,
474
+ new_files_allowed: true,
475
+ new_file_patterns: ["*.md"],
476
+ resolution: buildReport(input, allowedPaths, readonlyPaths, true, candidates, [], [], [], "resolved"),
477
+ };
478
+ }
479
+ const warnings = [];
480
+ const conflicts = [];
481
+ const candidates = [];
482
+ const discoveredRoots = discoverSourceRoots(input.projectPath);
483
+ addRouteCandidates(input, candidates);
484
+ addRepoCandidates(input, discoveredRoots, candidates, warnings);
485
+ addConfigScopeCandidates(input, discoveredRoots, candidates, warnings);
486
+ addFingerprintCandidates(input, discoveredRoots, candidates);
487
+ const selected = removeNestedBroadDuplicates(candidates
488
+ .filter((candidate) => candidate.confidence !== "low" || pathExists(input.projectPath, candidate.path))
489
+ .map((candidate) => candidate.path));
490
+ let allowedPaths = selected;
491
+ let status = "resolved";
492
+ if (allowedPaths.length === 0) {
493
+ allowedPaths = discoveredRoots.map((root) => root.path);
494
+ if (allowedPaths.length > 0) {
495
+ status = "fallback";
496
+ warnings.push("未从配置得到可信 scope,已退回真实项目源码树;建议运行 soloforge doctor 并修复 config scope。");
497
+ }
498
+ else {
499
+ allowedPaths = ["."];
500
+ status = "blocked";
501
+ conflicts.push("无法从配置或项目指纹推断源码 scope;请运行 soloforge init --interactive 确认项目结构。");
502
+ }
503
+ }
504
+ if (isBroadRootOnly(allowedPaths) && discoveredRoots.length > 0) {
505
+ allowedPaths = discoveredRoots.map((root) => root.path);
506
+ status = "fallback";
507
+ warnings.push("scope 仅为项目根,已收窄为真实源码根,避免过宽写入范围。");
508
+ }
509
+ const readonlyPaths = readonlyFromRepos(input)
510
+ .filter((readonly) => !allowedPaths.some((allowed) => matchesScopePattern(readonly, allowed)
511
+ || matchesScopePattern(allowed, readonly)
512
+ || isPathInScope(readonly, allowed, { caseSensitive: PATH_CASE_SENSITIVE })
513
+ || isPathInScope(allowed, readonly, { caseSensitive: PATH_CASE_SENSITIVE })));
514
+ const newFilesAllowed = !input.degraded && status !== "blocked";
515
+ const report = buildReport(input, allowedPaths, readonlyPaths, newFilesAllowed, candidates, discoveredRoots, warnings, conflicts, status);
516
+ return {
517
+ allowed_paths: allowedPaths,
518
+ readonly_paths: readonlyPaths,
519
+ new_files_allowed: newFilesAllowed,
520
+ new_file_patterns: newFilesAllowed && input.classification.strategy === "full_pipeline"
521
+ ? ["**/*"]
522
+ : undefined,
523
+ resolution: report,
524
+ };
525
+ }
526
+ //# sourceMappingURL=scope_resolver.js.map