@xcompiler/cli 0.2.2 → 0.2.3

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.
@@ -22,8 +22,8 @@ For P2+ iterations, put the same basenames under \`docs/iterations/<iterationId>
22
22
 
23
23
  Synchronous test-design rule:
24
24
  - REQUIREMENT_ANALYSIS must also output \`docs/tests/functional-test-plan.md\`.
25
- - HIGH_LEVEL_DESIGN must also output \`docs/tests/integration-test-plan.md\`.
26
- - DETAILED_DESIGN must also output \`docs/tests/module-test-plan.md\`.
25
+ - HIGH_LEVEL_DESIGN must also output \`docs/tests/module-test-plan.md\`.
26
+ - DETAILED_DESIGN must also output \`docs/tests/integration-test-plan.md\`.
27
27
  - CODE must also output \`docs/tests/unit-test-plan.md\`.
28
28
  For P2+ iterations, put those under \`docs/iterations/<iterationId>/tests/\`.
29
29
 
@@ -33,8 +33,8 @@ Phase responsibilities:
33
33
  - DETAILED_DESIGN defines the module-internal functions, data structures, algorithms, control flow, error handling, and internal architecture.
34
34
  - CODE implements only the designed scope and produces runnable/importable Python source.
35
35
  - UNIT_TEST verifies CODE internals and public functions.
36
- - INTEGRATION_TEST verifies external interfaces, selected third-party libraries, dependency wiring, and API/client boundaries from HIGH_LEVEL_DESIGN.
37
- - MODULE_TEST verifies module-level behaviour and architecture from DETAILED_DESIGN.
36
+ - INTEGRATION_TEST verifies module-internal collaboration, data flow, and component integration from DETAILED_DESIGN.
37
+ - MODULE_TEST verifies the current module's position in the whole system, external interfaces, and dependency boundaries from HIGH_LEVEL_DESIGN.
38
38
  - FUNCTIONAL_TEST verifies requirements end-to-end and produces user-facing documentation.
39
39
 
40
40
  Functional documentation bundle: P1 FUNCTIONAL_TEST outputs must include \`README.md\`, \`docs/quickstart.md\`, and \`docs/08-functional-test.md\`; for \`projectType\` = \`library\` or \`mixed\`, also include \`docs/api-guide.md\`. P2+ uses \`docs/iterations/<iterationId>/08-functional-test.md\`, \`quickstart.md\`, and optional \`api-guide.md\`. Documentation must follow the active i18n language.
@@ -55,6 +55,7 @@ Mandatory rules:
55
55
  13. dependencies is a Python pip dependency list. Include \`pytest\`; use bare package names only; never list \`requirements.txt\` in Step outputs.
56
56
  14. Application/mixed projects need a directly executable Python entry point (\`src/main.py\` or package \`__main__.py\`) that reuses CODE modules. Library/mixed projects need a stable public API and \`docs/api-guide.md\`.
57
57
  15. Structured HIGH_LEVEL_DESIGN -> CODE -> MODULE_TEST contract: for non-trivial work, return \`architectureModules\` with each module's id, name, responsibility, sourcePaths, testPaths, and dependencies. CODE/MODULE_TEST Steps may cover multiple modules but must list module-level work in subTasks.
58
+ 16. Third-party library choices must match real APIs: HIGH_LEVEL_DESIGN must name the concrete entry point function/class or verification basis for the selected library in this requirement; do not invent parser/export APIs from package names alone.
58
59
 
59
60
  Output JSON shape:
60
61
  {
@@ -114,15 +115,18 @@ Rules:
114
115
  **must NOT** add their own sys.path.insert(...). If you create or edit conftest.py yourself,
115
116
  keep the existing sys.path injection \u2014 do not delete it.
116
117
  - [Self-contained tests] Tests **must NOT** open() a sample file that does not exist on disk
117
- (e.g. "test.dbc", "sample.csv"). When a target function needs file input, do exactly one of:
118
- (a) use pytest's tmp_path fixture inside the test, e.g. tmp_path.joinpath("x.dbc").write_text(...);
119
- (b) use write_file to put a fixture under tests/fixtures/<name> \u2014 test/DEBUG phases have
120
- write permission to tests/fixtures/ by default, sub-directories are auto-mkdir'd, and
121
- **fixture paths do NOT need to be pre-declared in outputs**.
118
+ (e.g. "sample.csv"). When a target function needs file input, choose in this priority order:
119
+ (a) first reuse a real sample supplied by the user or already present in the workspace, copying/referencing it under tests/fixtures/<name>;
120
+ (b) for third-party or industry-standard formats with no local sample, use http_fetch to obtain a small reference sample from official docs,
121
+ the upstream repository, or a public standard/example, save it under tests/fixtures/<name>, and record the source in the test report or comment;
122
+ (c) only for simple text formats such as CSV/JSON/INI, and only when you can immediately run_tests, construct a minimal sample with pytest tmp_path.
123
+ If the network is unavailable, no user sample exists, and the format standard cannot be confirmed, report a blocker asking the user for a sample.
122
124
  A test that references a file nobody created will trap the Debugger in an endless FileNotFoundError loop.
123
125
  - [Fixture iteration] When a test runs but the target function raises "Invalid syntax / Parse error / Malformed",
124
- the **fixture itself is malformed** (DBC/CSV/JSON/...), **not the implementation**.
125
- read_file the fixture \u2192 write_file a minimal valid sample for that format \u2192 run_tests again.
126
+ the **fixture itself is malformed**, **not the implementation**.
127
+ read_file the fixture, identify the format from the extension/parser/error, then prefer a user/workspace sample or an authoritative http_fetch reference;
128
+ rewrite the whole fixture with write_file and run_tests. After repeated failures on a complex domain format, stop inventing from memory and ask
129
+ for a user sample or network reference.
126
130
  Never edit the implementation, the assertion, or mock out the parser to "fix" a parse error \u2014 fix the fixture first.
127
131
  4. When all outputs files exist and self-check passes, set done = true with empty actions.
128
132
  5. Correct any error in the next round's actions; never overstep authority or invent tools.
@@ -142,8 +146,8 @@ DEBUG is runtime rollback/repair only. If a test phase fails, XCompiler rolls ba
142
146
 
143
147
  Use the same phase documents and synchronous test-design rule as the Python planner:
144
148
  - REQUIREMENT_ANALYSIS: \`docs/01-requirement-analysis.md\` plus \`docs/tests/functional-test-plan.md\`.
145
- - HIGH_LEVEL_DESIGN: \`docs/02-high-level-design.md\` plus \`docs/tests/integration-test-plan.md\`.
146
- - DETAILED_DESIGN: \`docs/03-detailed-design.md\` plus \`docs/tests/module-test-plan.md\`.
149
+ - HIGH_LEVEL_DESIGN: \`docs/02-high-level-design.md\` plus \`docs/tests/module-test-plan.md\`.
150
+ - DETAILED_DESIGN: \`docs/03-detailed-design.md\` plus \`docs/tests/integration-test-plan.md\`.
147
151
  - CODE: implementation outputs plus \`docs/tests/unit-test-plan.md\`.
148
152
  - UNIT_TEST: \`docs/05-unit-test.md\`.
149
153
  - INTEGRATION_TEST: \`docs/06-integration-test.md\`.
@@ -159,6 +163,7 @@ Mandatory rules:
159
163
  2. Every current/planned implementation phase is a complete V-model iteration containing all eight canonical phases.
160
164
  3. Each macro Step may contain \`subTasks\` nested at most two levels.
161
165
  4. Every CODE Step must be covered by a UNIT_TEST Step in the same iteration; module testPaths from architectureModules must be produced by MODULE_TEST.
166
+ CODE outputs must contain product source files under src/ plus docs/tests/unit-test-plan.md only; never list tests/**/*.test.ts or other tests/** files as CODE outputs.
162
167
  5. Design phases must not output src/ or tests/ files. HIGH_LEVEL_DESIGN is the only phase that may output \`package.json\` / \`tsconfig.json\`.
163
168
  6. Exactly one HIGH_LEVEL_DESIGN Step must output \`package.json\` for greenfield TypeScript plans; ensure one HIGH_LEVEL_DESIGN Step output \`package.json\`. It must include scripts for \`build\`, \`test\`, and preferably \`lint\`.
164
169
  7. Local TypeScript source imports must use explicit \`.ts\` ESM specifiers. Configure \`allowImportingTsExtensions: true\` and use \`tsc --noEmit\`. Generated TypeScript must be compatible with Node native type stripping: avoid enums, namespaces, parameter properties, and transform-required syntax.
@@ -167,6 +172,7 @@ Mandatory rules:
167
172
  10. complexityAssessment and implementationPhases follow the same rules as Python: simple => P1, moderate => at least P1+P2, complex => at least P1+P2+P3, forced phase split => set userForcedPhaseSplit=true.
168
173
  11. verificationGate failurePolicy must say: Feed failures to Debugger, roll back to the paired V-model phase, and rerun subsequent phases.
169
174
  12. For non-trivial work, return architectureModules with sourcePaths and testPaths; CODE/MODULE_TEST Steps may cover multiple modules but must list module-level work in subTasks.
175
+ 13. TypeScript tests must use Vitest only. Never request Jest, ts-jest, @types/jest, ts-node, or nodemon in Step prompts or package.json; package.json must use "test": "vitest run" and "build": "tsc --noEmit".
170
176
 
171
177
  Output JSON shape is identical to Python and must include \`"projectType": "application | library | mixed"\`, with TypeScript paths such as \`src/example.ts\` and \`tests/example.test.ts\`; the first Step phase must be \`REQUIREMENT_ANALYSIS\`, not \`REQUIREMENT\`. There is no CLI project-type override.`;
172
178
  var TYPESCRIPT_EXECUTOR_SYSTEM = `You are XCompiler's Step Executor. You may only interact with the system through JSON tool calls \u2014 no Markdown and no explanatory text.
@@ -186,7 +192,7 @@ Rules:
186
192
  - [Import convention] Local source modules under src/ use ESM relative imports with explicit ".ts" specifiers, e.g. \`import { x } from "./util.ts";\`. Keep code compatible with Node's native TypeScript type stripping: use erasable type syntax only, and avoid enums, namespaces, parameter properties, or other transform-required TS features. Never use Python-style imports, \`from src.<module>\`, or sys.path hacks.
187
193
  - [Test convention] Tests use Vitest: \`import { describe, it, expect } from "vitest";\`. Test files live under \`tests/**/*.test.ts\`.
188
194
  - [Self-contained tests] Tests **must NOT** read a sample file that does not exist on disk. When a target function needs file input, either create the content inside the test or write fixtures under \`tests/fixtures/<name>\`.
189
- - [Fixture iteration] When a test runs but the target function raises "Invalid syntax / Parse error / Malformed", the **fixture itself is malformed**. read_file the fixture \u2192 write_file a minimal valid sample \u2192 run_tests again. Never "fix" a parse error by weakening the implementation or the assertion.
195
+ - [Fixture iteration] When a test runs but the target function raises "Invalid syntax / Parse error / Malformed", the **fixture itself is malformed**. read_file the fixture, prefer a user/workspace sample; if none exists, use http_fetch to obtain an authoritative public reference; construct minimal samples only for simple text formats and immediately run_tests. Never weaken the implementation/assertion, and never repeatedly invent complex domain fixtures from memory.
190
196
  4. When all outputs files exist and self-check passes, set done = true with empty actions.
191
197
  5. Correct any error in the next round's actions; never overstep authority or invent tools.
192
198
  6. [Large-file chunked writes] write_file / append_file content must stay under the current Step's runtime chunk limit shown in the tool docs.
@@ -201,6 +207,78 @@ Return strict JSON only. Each question must be directly answerable by a product
201
207
  function buildPlannerSystem(profile) {
202
208
  return (profile.id === "typescript" ? TYPESCRIPT_PLANNER_SYSTEM : PYTHON_PLANNER_SYSTEM) + profile.plannerPromptOverride;
203
209
  }
210
+ function buildPlannerPhasePlanSystem(profile) {
211
+ return `You are the Planner of XCompiler. This is two-level planning, pass one: PhasePlan.
212
+
213
+ Target language: ${profile.displayName}.
214
+
215
+ Return only the project-level PhasePlan. Do not return steps, architectureModules, dependencies, or any individual V-model Step.
216
+
217
+ The PhasePlan must:
218
+ 1. Classify projectType: application / library / mixed.
219
+ 2. Assess complexityAssessment: simple / moderate / complex with rationale.
220
+ 3. Produce implementationPhases: P1 status=current; later P2/P3 status=planned. simple uses P1 only; moderate uses at least P1+P2; complex uses at least P1+P2+P3; user-forced staging uses at least P1+P2 and userForcedPhaseSplit=true.
221
+ 4. Give each phase objective, scope, deliverables, dependsOn, and verificationGate.
222
+ 5. Keep planned phases as goals and gates only. Do not expand any Step for them; a separate pass will generate a full V-model plan for one phase at a time.
223
+
224
+ Return strict JSON only:
225
+ {
226
+ "requirementDigest": "string",
227
+ "globalPrompt": "string",
228
+ "projectType": "application | library | mixed",
229
+ "complexityAssessment": { "level": "simple | moderate | complex", "rationale": "string", "splitRecommended": true, "userForcedPhaseSplit": false },
230
+ "implementationPhases": [
231
+ { "id": "P1", "title": "Core functionality", "objective": "string", "status": "current", "scope": ["..."], "deliverables": ["..."], "dependsOn": [], "verificationGate": { "summary": "string", "checks": ["..."], "failurePolicy": "Feed failures to Debugger, roll back to the paired V-model phase, and rerun subsequent phases." } }
232
+ ]
233
+ }
234
+
235
+ No Markdown, no explanatory prose, no steps, no source/test file inventory.` + profile.plannerPromptOverride;
236
+ }
237
+ function buildPlannerPhaseDecomposeSystem(profile) {
238
+ return `You are the Planner of XCompiler. This is two-level planning, pass two: generate a full V-model StepPlan for the requested phase.
239
+
240
+ Target language: ${profile.displayName}.
241
+
242
+ You will receive a frozen PhasePlan and a phaseId. Generate Steps only for that phaseId. Planned phases must not be expanded into this StepPlan.
243
+
244
+ Every current phase must use the canonical V-model:
245
+ REQUIREMENT_ANALYSIS -> HIGH_LEVEL_DESIGN -> DETAILED_DESIGN -> CODE -> UNIT_TEST -> INTEGRATION_TEST -> MODULE_TEST -> FUNCTIONAL_TEST.
246
+
247
+ Phase responsibilities:
248
+ - REQUIREMENT_ANALYSIS defines functional scope, acceptance, boundaries, and user-visible behaviour, and synchronously emits the functional test plan.
249
+ - HIGH_LEVEL_DESIGN defines system position, external interfaces, third-party library choices, dependency confirmation, and integration boundaries, and synchronously emits the integration test plan.
250
+ - DETAILED_DESIGN defines module-internal functions/classes, data structures, algorithms, control flow, error handling, and internal architecture, and synchronously emits the module test plan.
251
+ - CODE implements only the current phase and synchronously emits the unit test plan.
252
+ - UNIT_TEST / INTEGRATION_TEST / MODULE_TEST / FUNCTIONAL_TEST verify their paired left-side phases.
253
+
254
+ Strict output ownership:
255
+ - CODE outputs may include only product source files under src/ and the unit-test-plan document; do not put tests/** files in CODE outputs.
256
+ - UNIT_TEST owns unit test files; INTEGRATION_TEST owns integration test files; MODULE_TEST owns architectureModules.testPaths; FUNCTIONAL_TEST owns end-to-end/functional test files and delivery docs.
257
+ - For greenfield TypeScript, exactly one HIGH_LEVEL_DESIGN Step must output package.json with scripts, dependencies, and devDependencies. CODE must not output package.json.
258
+ - For TypeScript package.json, use Vitest only: "test": "vitest run", "build": "tsc --noEmit", devDependencies include typescript/tsx/vitest/@types/node. Do not mention or request Jest, ts-jest, @types/jest, ts-node, or nodemon.
259
+
260
+ Return only the current phase's dependencies, architectureModules, and steps. Complex or multi-concern work must declare architectureModules for the current phase and map module-level work under CODE/MODULE_TEST subTasks. Each Step's subTasks may nest at most two levels.
261
+
262
+ architectureModules may describe only product/business source modules for the current phase:
263
+ - sourcePaths must be target-language source files under src/. They must not be directories, tests/, docs/, README, fixtures, utils, or report files.
264
+ - testPaths must be target-language test files under tests/. They must not be directories.
265
+ - Test fixtures, test helpers, sample inputs, and temporary output files belong in test Step outputs or subTasks, not in architectureModules.
266
+
267
+ Return strict JSON only:
268
+ {
269
+ "requirementDigest": "string",
270
+ "globalPrompt": "string",
271
+ "dependencies": ["pytest"],
272
+ "architectureModules": [
273
+ { "id": "M001", "name": "module name", "responsibility": "one clear responsibility", "sourcePaths": ["src/example.py"], "testPaths": ["tests/test_example.py"], "dependencies": [] }
274
+ ],
275
+ "steps": [
276
+ { "id": "S001", "iterationId": "P1", "phase": "REQUIREMENT_ANALYSIS", "title": "string", "description": "string", "systemPrompt": "scope, inputs, outputs, acceptance, forbidden actions", "role": "Planner", "tools": ["write_file"], "inputs": ["docs/topic.md"], "outputs": ["docs/01-requirement-analysis.md", "docs/tests/functional-test-plan.md"], "subTasks": [], "dependsOn": [], "acceptance": "string", "maxRetries": 3 }
277
+ ]
278
+ }
279
+
280
+ Do not output Steps for future planned phases. Do not output requirements.txt. Design phases must not write src/tests. FUNCTIONAL_TEST must include README.md, docs/quickstart.md, and the functional validation document.` + profile.plannerPromptOverride;
281
+ }
204
282
  function buildExecutorSystem(profile) {
205
283
  return (profile.id === "typescript" ? TYPESCRIPT_EXECUTOR_SYSTEM : PYTHON_EXECUTOR_SYSTEM) + profile.executorPromptOverride;
206
284
  }
@@ -217,7 +295,7 @@ var messages = {
217
295
  preflightOllamaUnreachable: (baseUrl, message) => `preflight: ollama ${baseUrl} unreachable: ${message}`,
218
296
  preflightAutoAdded: (providers, roles) => `preflight: auto-added ${providers} provider(s) for roles [${roles}]`,
219
297
  scoreFileHeader: "# XCompiler LLM provider score snapshot (maintained automatically by ScoreStore; do not edit)",
220
- scoreFileSemantics: "# Scores: default 1.0; failure -0.5 (floor 0=disabled); success +0.1 (cap 10)."
298
+ scoreFileSemantics: "# Scores: default 1.0; automatic range 0.1-1.0; providers tagged cluster default to 0.2-0.5 unless llm.cluster_score_min/max widens it; failure -0.5; success +0.1; only user-configured score=0 disables a provider."
221
299
  },
222
300
  system: {
223
301
  configEnvMissing: (names) => `[xcompiler] unset config environment variables were replaced with empty strings: ${names}`,
@@ -302,34 +380,34 @@ var messages = {
302
380
  },
303
381
  cli: {
304
382
  rootDescription: "XCompiler \u2014 AI Software Factory CLI",
305
- compileDescription: "Interactively compile a requirement into plan.json (with mandatory human gates)",
306
- runDescription: "Execute a confirmed plan.json (supports phased runs: --phase / --from)",
383
+ compileDescription: "Interactively compile a requirement into phasePlan.json and the current phase plan (with mandatory human gates)",
384
+ runDescription: "Execute a confirmed phasePlan.json (supports phased runs: --phase / --from)",
307
385
  loadDescription: "Load a XXX.xc project file and continue its current plan",
308
386
  appendDescription: "Append a new requirement to an existing XXX.xc project through clarification and V-model execution",
309
- lsDescription: "Scan workspace and list every plan.json status summary",
387
+ lsDescription: "Scan workspace and list every phasePlan.json / legacy plan.json status summary",
310
388
  showDescription: "Print Step definition / status / outputs / recent audit",
311
389
  optWorkspace: "workspace directory (alias of --output, defaults to current directory)",
312
390
  optOutput: "project / workspace output directory (highest priority, alias of -w)",
313
391
  optConfig: "path to config.yaml",
314
392
  optInput: "read requirement from a file (non-interactive)",
315
393
  optTopic: "reuse an already-clarified topic.md as input: skip intake / clarify / addenda / Gate 1 and go straight to decompose",
316
- optPlanOut: "output path for plan.json (default <workspace>/plan.json)",
394
+ optPlanOut: "output path for phasePlan.json (default <workspace>/phasePlan.json)",
317
395
  optBaseDir: "project root output directory (creates <name> subdir under it)",
318
396
  optName: "project name (default xcompiler-<timestamp>)",
319
397
  optYes: "skip human confirmation (only meaningful with -i / -t)",
320
- optForce: "force regenerate: override workspace lock and ignore existing plan.json",
398
+ optForce: "force regenerate: override workspace lock and ignore existing plan files",
321
399
  optDryRun: "print topology only, do not execute",
322
400
  optFrom: "start from the given Step (earlier ones are skipped)",
323
401
  optPhase: "execute only the given phase (REQUIREMENT_ANALYSIS/HIGH_LEVEL_DESIGN/DETAILED_DESIGN/CODE/UNIT_TEST/INTEGRATION_TEST/MODULE_TEST/FUNCTIONAL_TEST/DEBUG)",
324
402
  optReset: "reset all Step status to PENDING",
325
403
  optMaxDepth: "maximum recursion depth",
326
404
  optTail: "number of recent audit entries",
327
- optPlan: "plan.json path, default <workspace>/plan.json",
405
+ optPlan: "phasePlan.json path, default <workspace>/phasePlan.json",
328
406
  optLang: "UI / prompt language: EN | CN (ISO 3166-1 Alpha-2)",
329
407
  optIntent: "plan intent: greenfield | feature | refactor | self",
330
- optBaselinePlan: "existing baseline plan.json path (default <workspace>/plan.json)",
408
+ optBaselinePlan: "existing baseline phasePlan.json / plan.json path (default <workspace>/phasePlan.json)",
331
409
  optProjectFile: "XXX.xc project file path (default <workspace>/<name>.xc)",
332
- argPlan: "plan.json path (default = <workspace>/plan.json)",
410
+ argPlan: "phasePlan.json or legacy plan.json path (default = <workspace>/phasePlan.json)",
333
411
  argProjectFile: "XXX.xc project file",
334
412
  argStepId: "Step ID, e.g. S001",
335
413
  evolveDescription: "Generate and execute an incremental feature/refactor plan on top of an existing workspace",
@@ -407,7 +485,7 @@ var messages = {
407
485
  auditDecomposeFailed: "planner.decompose failed",
408
486
  lintIssue: (id, message) => ` - [${id}] ${message}`,
409
487
  planPreviewTruncated: "\u2026 (truncated; see docs/plan.md)",
410
- auditPlanPersisted: (p) => `plan.json written: ${p}`,
488
+ auditPlanPersisted: (p) => `phase plan written: ${p}`,
411
489
  projectFileWritten: (p) => `project file updated: ${p}`,
412
490
  nextCommand: (command) => ` Next: ${command}`,
413
491
  topicEmptyExit: "--topic file is empty, aborting.",
@@ -424,8 +502,10 @@ var messages = {
424
502
  spinDecompose: "Planner is decomposing along the V-model\u2026",
425
503
  decomposeFail: "Planner decomposition failed",
426
504
  plannerInvalidPlan: "Planner could not produce a valid plan:",
427
- plannerInvalidPlanHint1: " Common cause: every LLM provider returned malformed/truncated JSON (e.g. token loop).",
428
- plannerInvalidPlanHint2: " Investigate: check llm.error / planner.thought entries in .xcompiler/audit.jsonl.",
505
+ plannerInvalidPlanHint1: " Common cause: the LLM output did not satisfy the XCompiler plan schema, V-model skeleton, or architecture contract; this error must not be skipped.",
506
+ plannerInvalidPlanHint2: " Investigate: check llm.error / planner.thought entries in .xcompiler/audit.jsonl and repair the Planner output against the contract.",
507
+ plannerTransportFailureHint1: " Common cause: the LLM provider connection failed, timed out, or the server closed the request; this is not a project plan/source defect.",
508
+ plannerTransportFailureHint2: " Investigate: check OPENAI_BASE_URL / provider base_url, model service reachability, network permissions, and timeout settings, then rerun build.",
429
509
  decomposeSucceed: (n) => `generated ${n} Step(s)`,
430
510
  schemaFail: "Plan schema validation failed:",
431
511
  schemaInvalidSavedAt: (p) => ` full plan saved to: ${p}`,
@@ -440,12 +520,13 @@ var messages = {
440
520
  gate1Cancelled: "Cancelled, no files written.",
441
521
  editTopicMsg: "Edit topic.md",
442
522
  topicWritten: (p) => `topic written: ${p}`,
443
- planWritten: (p) => `plan written: ${p}`,
523
+ planWritten: (p) => `phase plan written: ${p}`,
524
+ phasePlanWritten: (p) => `phasePlan written: ${p}`,
444
525
  planPreviewHeader: "\u2500\u2500\u2500 plan.md (preview) \u2500\u2500\u2500",
445
526
  planPreviewFooter: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
446
- gate2Confirm: "Confirm this plan? (Final confirmation \u2014 confirms write to plan.json)",
527
+ gate2Confirm: "Confirm this plan? (Final confirmation \u2014 writes phasePlan.json and the current phase plan)",
447
528
  gate2AuditLabel: "Plan Confirmation Gate (Gate 2)",
448
- gate2Rejected: "Not confirmed, abandoned. plan.json was not written.",
529
+ gate2Rejected: "Not confirmed, abandoned. phasePlan.json was not written.",
449
530
  baselineLoaded: (kind, sources) => `loaded ${kind} baseline from: ${sources}`,
450
531
  baselineMissing: (workspace) => `incremental mode requires an existing project baseline in ${workspace} (topic / docs / plan / src).`,
451
532
  baselineLanguageOverride: (baseline, source, configured) => `incremental mode: using baseline language ${baseline} from ${source} instead of config language ${configured}.`,
@@ -457,7 +538,7 @@ var messages = {
457
538
  topicSecBaseline: "## Existing project baseline"
458
539
  },
459
540
  inspect: {
460
- noPlanFound: "No plan.json found",
541
+ noPlanFound: "No phasePlan.json / plan.json found",
461
542
  digestLabel: "digest:",
462
543
  stepNotFound: (id) => `Step ${id} not found`,
463
544
  secDescription: "\u2014 description \u2014",
@@ -482,7 +563,7 @@ var messages = {
482
563
  auditPlanLoaded: (p) => `plan loaded: ${p}`,
483
564
  planLoaded: (p) => `Plan loaded: ${p}`,
484
565
  planSummary: (language, steps) => ` language=${language}, steps=${steps}`,
485
- preflightModelMissing: (names) => `LLM preflight: missing models, disabled [${names}]`,
566
+ preflightModelMissing: (names) => `LLM preflight: missing models, skipped for this run and lowered to the minimum dynamic score [${names}]`,
486
567
  preflightAutoAdded: (n) => `LLM preflight: auto-injected ${n} provider(s) (from ollama /api/tags)`,
487
568
  runInterrupted: (id, e, total) => `execution interrupted at ${id} (executed ${e}/${total})`,
488
569
  runReasonLabel: " reason: ",
@@ -538,7 +619,7 @@ var messages = {
538
619
  archGateInstruction: (p) => `Update ${p} so every architectureModules item is traceable before CODE starts.`,
539
620
  testGateReason: (exitCode, timedOut) => `Test gate: tests exit=${exitCode}${timedOut ? " (timeout)" : ""}`,
540
621
  deliveryGateReason: (command, exitCode, timedOut) => `FUNCTIONAL_TEST gate: \`${command}\` exit=${exitCode}${timedOut ? " (timeout)" : ""}`,
541
- missingPythonEntrypoint: "missing Python entrypoint: expected src/main.py or src/<package>/__main__.py",
622
+ missingPythonEntrypoint: "missing Python entrypoint: expected src/main.py, src/<package>/__main__.py, or an explicit CLI file such as src/cli.py",
542
623
  missingTypeScriptEntrypoint: "missing TypeScript entrypoint: expected package.json start/bin or one of src/main.ts, src/index.ts, src/main.tsx",
543
624
  invalidPythonEntrypointSource: (path2) => `invalid Python entrypoint source in ${path2}: expected a real CLI entry structure such as def main(...), argparse.ArgumentParser, or if __name__ == "__main__"; placeholder/import-only files are not runnable applications.`,
544
625
  entrypointHelpOutputMissing: (command) => `entrypoint probe \`${command}\` exited 0 but produced no meaningful help/usage text; implement --help instead of relying on an empty script exit.`,
@@ -576,6 +657,8 @@ var messages = {
576
657
  },
577
658
  prompts: {
578
659
  plannerSystem: (p) => buildPlannerSystem(p),
660
+ plannerPhasePlanSystem: (p) => buildPlannerPhasePlanSystem(p),
661
+ plannerPhaseDecomposeSystem: (p) => buildPlannerPhaseDecomposeSystem(p),
579
662
  plannerSelfMode: `SELF-BOOTSTRAP OVERRIDE (takes precedence over conflicting greenfield rules above):
580
663
  - The target is the existing XCompiler repository. Preserve its current package.json, tsconfig, bin entries, CLI entrypoints, module layout, public exports, and documentation unless the requirement explicitly changes them.
581
664
  - Do not create src/main.ts merely to satisfy a greenfield entrypoint convention. Reuse the entrypoints declared by the existing package.json.
@@ -600,6 +683,7 @@ Question mix (functionality first):
600
683
  - At least one quality question requesting measurable latency, throughput, volume, concurrency, accuracy, reliability, or security targets. Never ask only \u201CAny performance requirements?\u201D.
601
684
  - At least one extensibility question identifying the most likely future business capability, extension axis, or interface that must remain stable. Never ask only \u201CShould it be extensible?\u201D.
602
685
  - If the deliverable shape is unclear, include one boundary question asking whether this should be an API library/SDK/package, a runnable application/CLI/service, or a mixed deliverable with both.
686
+ - If the requirement needs access to external APIs, URLs, or third-party data sources, include one data or boundary question asking whether the user already has a usable API, key, token, or auth method. If they do not, the default for this delivery is to choose a public, no-key/no-token, verifiable API; do not generate placeholder URLs.
603
687
  - Order by blocking impact: core functional/data decisions first, then scope and quality, then future evolution.
604
688
  - One primary decision per question. Include useful business choices/examples; do not join unrelated questions with \u201Cand/or\u201D.
605
689
  - For every question, generate 2-5 feasible answer options ordered by priority. The option count is not fixed: use 2 for binary choices, 3 for common defaults, and 4-5 only when there are genuinely distinct viable settings. Do not pad or force every question to exactly 3 options.
@@ -643,11 +727,77 @@ ${opts.baseline || "(missing baseline)"}
643
727
  - When baseline files already exist, prefer editing/extending those modules over creating shadow implementations with duplicate behaviour.
644
728
 
645
729
  Output a strict JSON plan per the system rules.`,
730
+ plannerPhasePlan: (raw, qa, addenda, opts = {}) => `Original requirement:
731
+ """
732
+ ${raw}
733
+ """
734
+
735
+ Clarification Q&A:
736
+ ${qa || "(none)"}
737
+
738
+ ${addenda ? `User addenda (must be strictly followed; takes priority over vague original wording):
739
+ """
740
+ ${addenda}
741
+ """
742
+
743
+ ` : ""}${opts.intent && opts.intent !== "greenfield" ? `Incremental intent: ${opts.intent}
744
+
745
+ Generate a PhasePlan on top of the existing project. Reuse current architecture, files, tests, and dependencies where possible. Preserve existing behaviour outside the requested change.
746
+
747
+ Existing project baseline:
748
+ """
749
+ ${opts.baseline || "(missing baseline)"}
750
+ """
751
+
752
+ ` : ""}First generate only the high-level PhasePlan:
753
+ - Assess complexity and choose phase count: simple => P1 current only; moderate => P1 current + at least P2 planned; complex => P1 current + at least P2/P3 planned.
754
+ - P1 objective must be an independently deliverable and verifiable core slice.
755
+ - P2/P3 should contain only future enhancement goals, scope, deliverables, and verification gates. Do not expand any V-model Step.
756
+ - Every phase verificationGate must say failures are fed to Debugger, rolled back to the paired V-model phase, and followed by rerunning subsequent phases.
757
+ - Return only PhasePlan JSON. Do not include steps, architectureModules, or dependencies.`,
758
+ plannerPhaseDecompose: (raw, qa, addenda, opts) => `Original requirement:
759
+ """
760
+ ${raw}
761
+ """
762
+
763
+ Clarification Q&A:
764
+ ${qa || "(none)"}
765
+
766
+ ${addenda ? `User addenda (must be strictly followed; takes priority over vague original wording):
767
+ """
768
+ ${addenda}
769
+ """
770
+
771
+ ` : ""}${opts.intent && opts.intent !== "greenfield" ? `Incremental intent: ${opts.intent}
772
+
773
+ Generate the current phase's incremental V-model StepPlan on top of the existing project. Reuse current architecture, files, tests, and dependencies where possible.
774
+
775
+ Existing project baseline:
776
+ """
777
+ ${opts.baseline || "(missing baseline)"}
778
+ """
779
+
780
+ ` : ""}Frozen PhasePlan:
781
+ """
782
+ ${opts.phasePlan}
783
+ """
784
+
785
+ Phase to expand now: ${opts.phaseId}
786
+
787
+ Return a full V-model StepPlan only for ${opts.phaseId}:
788
+ - Every Step.iterationId must equal "${opts.phaseId}".
789
+ - Do not output Steps for any other planned phase; P2/P3 detailed plans are generated only when they become the current phase.
790
+ - If ${opts.phaseId} spans multiple concerns (domain logic, CLI/API, file I/O, external integration, orchestration, tests), declare architectureModules for this phase and map module-level work under CODE/MODULE_TEST subTasks.
791
+ - architectureModules.sourcePaths may only contain product source files under src/. Do not register tests/fixtures, tests/utils, sample files, directories, or docs as architecture modules.
792
+ - dependencies contains only packages required by this phase; Python must include pytest; never output requirements.txt.
793
+ - This phase must contain the canonical eight V-model macro Steps and synchronous paired test-design outputs.
794
+
795
+ Return strict JSON StepPlan for the current phase only.`,
646
796
  executorSystem: (p) => buildExecutorSystem(p),
647
797
  executorDebugBlock: (reason, suggestions) => `
648
798
 
649
799
  You are now in DEBUG retry mode. Previous failure reason: ${reason}
650
- DEBUG may edit upstream source files and tests within the current allowedWrites. If the failure reveals a real implementation, contract, or downstream integration mismatch, fix that real defect; do not pass by weakening assertions, skipping tests, deleting failing cases, or merely accommodating an incorrect test. Begin with read_file / code_search to localise the issue, then make the smallest possible fix via apply_patch / replace_in_file / add_dependency, and finally run_tests to verify. If the failure log shows a network/API failure, do not stop at probing endpoints: use at most two consecutive http_fetch probes, reject 2xx responses with empty or unusable bodies, then patch the real integration and verify with run_program plus run_tests. Do not set done=true while the entrypoint still reports a network/API failure.` + (suggestions ? `
800
+ DEBUG may edit upstream source files and tests within the current allowedWrites. If the failure reveals a real implementation, contract, or downstream integration mismatch, fix that real defect; do not pass by weakening assertions, skipping tests, deleting failing cases, or merely accommodating an incorrect test. If this rollback is in a design/requirements step and the concrete code change belongs to a later V-model step outside the current allowedWrites, update the current contract, test plan, or diagnostic artifact and finish this step so the later CODE step can implement it; do not attempt denied writes. If the failure is a missing third-party dependency or wrong library choice, use add_dependency with the real package name or change the source back to the real library selected by HIGH_LEVEL_DESIGN; never add try/except ImportError fake modules, fake classes/functions, empty implementations, or fallback mocks in production src/ code to bypass the error. Begin with read_file / code_search to localise the issue, then make the smallest possible fix via apply_patch / replace_in_file / add_dependency, and finally run_tests to verify. A DEBUG retry cannot be marked complete from read-only inspection alone: it must produce a successful repair action or a successful verification command in this retry. If the previous failure reason mentions repeated read-only/probe actions, use the existing failure log as sufficient context and make the next action a patch/write/dependency change or a verification command. When a test executes and fails an assertion about returned behaviour, do not repeatedly rewrite fixtures or samples. Only edit fixtures when the evidence is missing-file, malformed-fixture, or parse-error in the fixture itself; otherwise patch the implementation, interface contract, dependency choice, or test expectation that is actually wrong. If the failure log shows a network/API failure, do not stop at probing endpoints: use at most two consecutive http_fetch probes, reject 2xx responses with empty or unusable bodies, then patch the real integration and verify with run_program plus run_tests. Do not set done=true while the entrypoint still reports a network/API failure.` + (suggestions ? `
651
801
 
652
802
  ${suggestions}` : ""),
653
803
  executorGlobalBlock: (globalPrompt) => `
@@ -661,14 +811,17 @@ ${sp}`,
661
811
  executorUserPromptOutro: "Now return the first round of JSON per the protocol.",
662
812
  executorFeedbackHeader: "Tool results this round:",
663
813
  executorFeedbackVerifyOk: "outputs verified. If you are done, set done=true and actions=[].",
664
- executorFeedbackVerifyMissing: (paths) => `outputs still missing: ${paths}. Please continue.`
814
+ executorFeedbackVerifyMissing: (paths) => `outputs still missing: ${paths}. Please continue.`,
815
+ executorFeedbackReadOnlyLoopWarning: (rounds, targets) => `Loop guard warning: the last ${rounds} round(s) used only read/probe tools` + (targets ? ` (${targets})` : "") + ". Next response must include a successful repair action (apply_patch / replace_in_file / write_file / add_dependency) or a concrete verification action (run_tests / run_program). Do not continue with only read_file, list_dir, code_search, or http_fetch.",
816
+ executorFeedbackReadOnlyRecoveryRequired: "Read-only recovery mode is active because the previous attempt already failed from probing. The next response must use existing failure evidence to patch/write/change dependency or run verification; one more read-only-only response will fail this retry.",
817
+ executorFeedbackRepairEvidenceMissing: "Invalid DEBUG completion: this retry has not produced repair evidence yet. Before done=true, perform at least one successful repair action or successful verification run; otherwise stop only with a concrete blocker in thoughts."
665
818
  },
666
819
  skills: {
667
820
  patcher: "Use apply_patch / replace_in_file for small in-place edits to existing files; never overwrite a whole file.",
668
821
  author: "Use write_file to create new files; prefer paths inside the current Step writable allowlist.",
669
- tester: `Write and run pytest tests verifying function behaviour; on failure parse with analyze_error. [Self-contained fixtures] Tests **must NOT** open() a sample file that does not exist on disk (e.g. "test.dbc"); when the target function needs file input, either use pytest tmp_path to construct content inside the test, or use write_file to put a fixture under tests/fixtures/<name> \u2014 test/DEBUG phases already grant write permission to that directory, sub-dirs are auto-mkdir'd, and **fixture paths do NOT need to be pre-declared in outputs**. When generating tests, always emit every dependent resource so the Debugger does not loop on FileNotFoundError. [Fixture iteration] If a running test raises "Invalid syntax / Parse error / Malformed" from the target function, your fixture content does not match the format spec: read_file to inspect, write_file to rewrite a minimal valid sample, then run_tests. Never edit the implementation or assertions to "fix" a parse error.`,
822
+ tester: `Write and run pytest tests verifying function behaviour; on failure parse with analyze_error. [Self-contained fixtures] Tests **must NOT** open() a sample file that does not exist on disk. When the target function needs file input, first reuse a real user/workspace sample; if none exists, use http_fetch to get a small reference sample from official docs, the upstream repository, or a public standard/example, save it under tests/fixtures/<name>, and record the source. Only for simple text formats such as CSV/JSON/INI may you construct a minimal pytest tmp_path sample and immediately run_tests. Test/DEBUG phases already grant write permission to tests/fixtures/, sub-dirs are auto-mkdir'd, and **fixture paths do NOT need to be pre-declared in outputs**. When generating tests, always emit every dependent resource so the Debugger does not loop on FileNotFoundError. [Fixture iteration] If a running test raises "Invalid syntax / Parse error / Malformed" from the target function, your fixture content does not match the format spec: read_file to inspect, then prefer a user sample or authoritative http_fetch reference before rewriting and running tests. After repeated failures on a complex domain format, stop inventing from memory and ask for a user sample or network reference. Never edit the implementation or assertions to "fix" a parse error.`,
670
823
  dep_resolver: "On ModuleNotFoundError, use add_dependency to write the package back into requirements.txt and rebuild the sandbox.",
671
- debugger: 'First run_tests / run_python to reproduce the error \u2192 analyze_error \u2192 patch / replace_in_file to fix \u2192 run_tests again. Make the smallest possible change each round. [Network/API failures] Locate the failing URL, try only a small number of replacement API probes, then patch the source and run_program to prove the entrypoint no longer emits API failure. [Important] If replace_in_file on the same file fails \u2265 2 times in a row, switch to read_file and then patch or rewrite within the current runtime chunk limit; stop guessing the find string. [No no-ops] replace_in_file find and replace must differ \u2014 if you only want to "verify" a snippet, use read_file; do not submit identical-string replacements.',
824
+ debugger: 'First run_tests / run_python to reproduce the error \u2192 analyze_error \u2192 patch / replace_in_file / add_dependency to fix \u2192 run_tests again. Make the smallest possible change each round. [Missing dependencies] Add the real dependency or use the real library selected by the design; never fake modules/classes/functions, empty implementations, or fallback mocks in production src/ code. [Fixture discipline] If tests fail with behavioural assertions, do not keep rewriting fixtures. Only change fixtures for clear missing-file, malformed-fixture, or fixture parse errors; otherwise fix source code, contracts, dependencies, or the incorrect assertion. [Network/API failures] Locate the failing URL, try only a small number of replacement API probes, then patch the source and run_program to prove the entrypoint no longer emits API failure. [Important] If replace_in_file on the same file fails \u2265 2 times in a row, switch to read_file and then patch or rewrite within the current runtime chunk limit; stop guessing the find string. [No no-ops] replace_in_file find and replace must differ \u2014 if you only want to "verify" a snippet, use read_file; do not submit identical-string replacements.',
672
825
  refactorer: "Refactors must preserve behaviour: run regression tests \u2192 modify \u2192 run regression tests again."
673
826
  },
674
827
  doctor: {
@@ -691,7 +844,7 @@ ${sp}`,
691
844
  ollamaReachable: (baseUrl, n) => `ollama reachable @ ${baseUrl} (${n} model(s))`,
692
845
  ollamaModelMissing: (provider, model, baseUrl) => `provider "${provider}": model "${model}" NOT installed on ${baseUrl} (run \`ollama pull ${model}\`)`,
693
846
  ollamaModelOk: (provider, model) => `provider "${provider}": model "${model}" available`,
694
- openaiKeyMissing: (provider) => `provider "${provider}": api_key empty (set OPENAI_API_KEY or config.llm.providers.${provider}.api_key)`,
847
+ openaiKeyMissing: (provider) => `provider "${provider}": api_key empty (set the provider env var such as OPENROUTER_API_KEY, or config.llm.providers.${provider}.api_key)`,
695
848
  openaiReachable: (provider, baseUrl) => `provider "${provider}": OpenAI endpoint reachable @ ${baseUrl}`,
696
849
  openaiUnreachable: (provider, baseUrl, msg) => `provider "${provider}": OpenAI endpoint unreachable @ ${baseUrl} \u2014 ${msg}`,
697
850
  openaiModelListMissing: (provider, model) => `provider "${provider}": model "${model}" not in /models response (it may still work if your account has access)`,
@@ -745,8 +898,8 @@ P2+ \u8FED\u4EE3\u628A\u540C\u540D\u9636\u6BB5\u6587\u6863\u5199\u5165 \`docs/it
745
898
 
746
899
  \u540C\u6B65\u6D4B\u8BD5\u8BBE\u8BA1\u89C4\u5219\uFF1A
747
900
  - REQUIREMENT_ANALYSIS \u540C\u6B65\u8F93\u51FA \`docs/tests/functional-test-plan.md\`\u3002
748
- - HIGH_LEVEL_DESIGN \u540C\u6B65\u8F93\u51FA \`docs/tests/integration-test-plan.md\`\u3002
749
- - DETAILED_DESIGN \u540C\u6B65\u8F93\u51FA \`docs/tests/module-test-plan.md\`\u3002
901
+ - HIGH_LEVEL_DESIGN \u540C\u6B65\u8F93\u51FA \`docs/tests/module-test-plan.md\`\u3002
902
+ - DETAILED_DESIGN \u540C\u6B65\u8F93\u51FA \`docs/tests/integration-test-plan.md\`\u3002
750
903
  - CODE \u540C\u6B65\u8F93\u51FA \`docs/tests/unit-test-plan.md\`\u3002
751
904
  P2+ \u8FED\u4EE3\u628A\u8FD9\u4E9B\u6D4B\u8BD5\u8BA1\u5212\u5199\u5230 \`docs/iterations/<iterationId>/tests/\`\u3002
752
905
 
@@ -756,8 +909,8 @@ P2+ \u8FED\u4EE3\u628A\u8FD9\u4E9B\u6D4B\u8BD5\u8BA1\u5212\u5199\u5230 \`docs/it
756
909
  - DETAILED_DESIGN \u5B9A\u4E49\u6A21\u5757\u5185\u90E8\u7684\u5177\u4F53\u529F\u80FD\u5B9E\u73B0\u548C\u67B6\u6784\uFF0C\u5305\u62EC\u51FD\u6570/\u7C7B\u3001\u6570\u636E\u7ED3\u6784\u3001\u7B97\u6CD5\u3001\u63A7\u5236\u6D41\u3001\u9519\u8BEF\u5904\u7406\u548C\u5185\u90E8\u534F\u4F5C\u3002
757
910
  - CODE \u53EA\u5B9E\u73B0\u5DF2\u8BBE\u8BA1\u8303\u56F4\u5E76\u4EA7\u51FA\u53EF\u8FD0\u884C/\u53EF\u5BFC\u5165\u7684 Python \u6E90\u7801\u3002
758
911
  - UNIT_TEST \u9A8C\u8BC1 CODE \u7684\u5185\u90E8\u51FD\u6570\u548C\u516C\u5F00 API\u3002
759
- - INTEGRATION_TEST \u9A8C\u8BC1 HIGH_LEVEL_DESIGN \u4E2D\u7684\u5916\u90E8\u63A5\u53E3\u3001\u7B2C\u4E09\u65B9\u5E93\u3001\u4F9D\u8D56\u63A5\u7EBF\u548C API/client \u8FB9\u754C\u3002
760
- - MODULE_TEST \u9A8C\u8BC1 DETAILED_DESIGN \u4E2D\u7684\u6A21\u5757\u7EA7\u884C\u4E3A\u548C\u5185\u90E8\u67B6\u6784\u3002
912
+ - INTEGRATION_TEST \u9A8C\u8BC1 DETAILED_DESIGN \u4E2D\u5B9A\u4E49\u7684\u6A21\u5757\u5185\u90E8\u534F\u4F5C\u3001\u6570\u636E\u6D41\u548C\u7EC4\u4EF6\u96C6\u6210\u3002
913
+ - MODULE_TEST \u9A8C\u8BC1 HIGH_LEVEL_DESIGN \u4E2D\u5F53\u524D\u5F00\u53D1\u6A21\u5757\u5728\u6574\u4F53\u7CFB\u7EDF\u4E2D\u7684\u5B9A\u4F4D\u3001\u5BF9\u5916\u63A5\u53E3\u548C\u4F9D\u8D56\u8FB9\u754C\u3002
761
914
  - FUNCTIONAL_TEST \u6309\u9700\u6C42\u7AEF\u5230\u7AEF\u9A8C\u6536\uFF0C\u5E76\u4EA7\u51FA\u9762\u5411\u7528\u6237\u7684\u6587\u6863\u3002
762
915
 
763
916
  \u529F\u80FD\u9A8C\u6536\u6587\u6863\u5305\uFF1AP1 FUNCTIONAL_TEST outputs \u5FC5\u987B\u5305\u542B \`README.md\`\u3001\`docs/quickstart.md\`\u3001\`docs/08-functional-test.md\`\uFF1B\u5F53 \`projectType\` \u4E3A \`library\` \u6216 \`mixed\` \u65F6\u8FD8\u5FC5\u987B\u5305\u542B \`docs/api-guide.md\`\u3002P2+ \u4F7F\u7528 \`docs/iterations/<iterationId>/08-functional-test.md\`\u3001\`quickstart.md\` \u548C\u53EF\u9009 \`api-guide.md\`\u3002\u6587\u6863\u8BED\u8A00\u9075\u5FAA\u5F53\u524D i18n\u3002
@@ -778,6 +931,7 @@ P2+ \u8FED\u4EE3\u628A\u8FD9\u4E9B\u6D4B\u8BD5\u8BA1\u5212\u5199\u5230 \`docs/it
778
931
  13. dependencies \u662F Python pip \u4F9D\u8D56\u5217\u8868\uFF1B\u5FC5\u987B\u5305\u542B \`pytest\`\uFF1B\u53EA\u5199\u88F8\u5305\u540D\uFF1B\u4EFB\u4F55 Step \u90FD\u4E0D\u8981\u8F93\u51FA \`requirements.txt\`\u3002
779
932
  14. application/mixed \u9879\u76EE\u9700\u8981\u53EF\u76F4\u63A5\u8FD0\u884C\u7684 Python \u5165\u53E3\uFF08\`src/main.py\` \u6216\u5305 \`__main__.py\`\uFF09\u5E76\u590D\u7528 CODE \u6A21\u5757\uFF1Blibrary/mixed \u9879\u76EE\u9700\u8981\u7A33\u5B9A\u516C\u5F00 API \u548C \`docs/api-guide.md\`\u3002
780
933
  15. \u590D\u6742\u9700\u6C42\u5FC5\u987B\u8FD4\u56DE \`architectureModules\`\uFF1A\u6BCF\u4E2A\u6A21\u5757\u5305\u542B id\u3001name\u3001responsibility\u3001sourcePaths\u3001testPaths\u3001dependencies\u3002CODE/MODULE_TEST Step \u53EF\u8986\u76D6\u591A\u4E2A\u6A21\u5757\uFF0C\u4F46\u5FC5\u987B\u5728 subTasks \u4E2D\u5217\u51FA\u6A21\u5757\u7EA7\u5DE5\u4F5C\u3002
934
+ 16. \u7B2C\u4E09\u65B9\u5E93\u9009\u578B\u5FC5\u987B\u5339\u914D\u771F\u5B9E API\uFF1AHIGH_LEVEL_DESIGN \u5FC5\u987B\u5199\u660E\u9009\u5B9A\u5E93\u7528\u4E8E\u672C\u9700\u6C42\u7684\u5177\u4F53\u5165\u53E3\u51FD\u6570/\u7C7B\u6216\u9A8C\u8BC1\u4F9D\u636E\uFF1B\u7981\u6B62\u4EC5\u51ED\u5305\u540D\u81C6\u9020\u4E0D\u5B58\u5728\u7684\u89E3\u6790/\u5BFC\u51FA API\u3002
781
935
 
782
936
  \u8F93\u51FA JSON \u5F62\u5982\uFF1A
783
937
  {
@@ -836,15 +990,18 @@ var PYTHON_EXECUTOR_SYSTEM2 = `\u4F60\u662F XCompiler \u7684 Step Executor\u3002
836
990
  \u56E0\u6B64 pytest \u4E0E "python tests/test_*.py" \u4E24\u79CD\u6267\u884C\u65B9\u5F0F\u90FD\u80FD\u89E3\u6790\u6A21\u5757\uFF0C
837
991
  \u6D4B\u8BD5\u6587\u4EF6\u5934\u90E8**\u65E0\u9700**\u518D\u5199 sys.path.insert(...)\uFF0C\u907F\u514D\u91CD\u590D\u6C61\u67D3\u3002
838
992
  \u5982\u679C LLM \u81EA\u5DF1\u989D\u5916\u521B\u5EFA/\u7F16\u8F91 conftest.py\uFF0C\u5FC5\u987B\u4FDD\u7559\u4E0A\u9762 sys.path \u6CE8\u5165\u903B\u8F91\uFF0C\u7981\u6B62\u5220\u9664\u3002
839
- - \u3010\u6D4B\u8BD5\u81EA\u5305\u542B\u3011\u6D4B\u8BD5**\u4E25\u7981**\u76F4\u63A5 open() \u4E00\u4E2A\u78C1\u76D8\u4E0A\u4E0D\u5B58\u5728\u7684\u6837\u4F8B\u6587\u4EF6\uFF08\u5982 "test.dbc"\u3001"sample.csv"\uFF09\uFF1B
840
- \u5F53\u88AB\u6D4B\u51FD\u6570\u9700\u8981\u6587\u4EF6\u8F93\u5165\u65F6\uFF0C\u5FC5\u987B\u4E8C\u9009\u4E00\uFF1A
841
- (a) \u7528 pytest \u7684 tmp_path fixture \u5728\u6D4B\u8BD5\u51FD\u6570\u5185 tmp_path.joinpath("x.dbc").write_text(...) \u6784\u9020\u5185\u5BB9\u5E76\u4F20\u5165\uFF1B
842
- (b) \u7528 write_file \u628A\u6837\u4F8B\u5199\u5230 tests/fixtures/<name>\u2014\u2014\u6D4B\u8BD5/DEBUG \u9636\u6BB5 tests/fixtures/ \u5DF2\u9ED8\u8BA4\u653E\u5F00\u5199\u6743\u9650\uFF0C
843
- \u5B50\u76EE\u5F55\u4F1A\u81EA\u52A8 mkdir -p\uFF0C**\u65E0\u9700**\u63D0\u524D\u5728 outputs \u767B\u8BB0 fixture \u8DEF\u5F84\u3002
993
+ - \u3010\u6D4B\u8BD5\u81EA\u5305\u542B\u3011\u6D4B\u8BD5**\u4E25\u7981**\u76F4\u63A5 open() \u4E00\u4E2A\u78C1\u76D8\u4E0A\u4E0D\u5B58\u5728\u7684\u6837\u4F8B\u6587\u4EF6\uFF08\u5982 "sample.csv"\uFF09\uFF1B
994
+ \u5F53\u88AB\u6D4B\u51FD\u6570\u9700\u8981\u6587\u4EF6\u8F93\u5165\u65F6\uFF0C\u5FC5\u987B\u6309\u4F18\u5148\u7EA7\u9009\u62E9\uFF1A
995
+ (a) \u4F18\u5148\u590D\u7528\u7528\u6237\u6216\u5DE5\u4F5C\u533A\u5DF2\u63D0\u4F9B\u7684\u771F\u5B9E\u6837\u4F8B\uFF0C\u7528 read_file \u8BFB\u53D6\u540E\u590D\u5236/\u5F15\u7528\u5230 tests/fixtures/<name>\uFF1B
996
+ (b) \u82E5\u662F\u7B2C\u4E09\u65B9/\u884C\u4E1A\u6807\u51C6\u683C\u5F0F\u4E14\u5DE5\u4F5C\u533A\u65E0\u6837\u4F8B\uFF0C\u7528 http_fetch \u83B7\u53D6\u5B98\u65B9\u6587\u6863\u3001\u4E0A\u6E38\u4ED3\u5E93\u6216\u516C\u5F00\u6807\u51C6\u4E2D\u7684\u5C0F\u578B\u53C2\u8003\u6837\u4F8B\uFF0C
997
+ \u4FDD\u5B58\u5230 tests/fixtures/<name>\uFF0C\u5E76\u5728\u6D4B\u8BD5\u62A5\u544A\u6216\u6CE8\u91CA\u4E2D\u8BB0\u5F55\u6765\u6E90\uFF1B
998
+ (c) \u53EA\u6709 CSV/JSON/INI \u7B49\u7B80\u5355\u6587\u672C\u683C\u5F0F\uFF0C\u4E14\u80FD\u7ACB\u523B run_tests \u9A8C\u8BC1\u65F6\uFF0C\u624D\u53EF\u5728 pytest tmp_path \u4E2D\u6784\u9020\u6700\u5C0F\u6837\u4F8B\u3002
999
+ \u7F51\u7EDC\u4E0D\u53EF\u7528\u3001\u7528\u6237\u672A\u63D0\u4F9B\u6837\u4F8B\u4E14\u65E0\u6CD5\u786E\u8BA4\u683C\u5F0F\u6807\u51C6\u65F6\uFF0C\u5E94\u660E\u786E\u62A5\u544A blocker \u8BF7\u6C42\u7528\u6237\u63D0\u4F9B\u6837\u4F8B\u3002
844
1000
  \u7EDD\u4E0D\u5141\u8BB8\u51FA\u73B0"\u6D4B\u8BD5\u4EE3\u7801\u5F15\u7528\u4E86\u4E00\u4E2A\u8C01\u90FD\u6CA1\u521B\u5EFA\u7684\u6587\u4EF6"\u2014\u2014\u8FD9\u4F1A\u8BA9 Debugger \u53CD\u590D FileNotFoundError \u6B7B\u5FAA\u73AF\u3002
845
1001
  - \u3010fixture \u8FED\u4EE3\u3011\u5F53\u6D4B\u8BD5\u5DF2\u7ECF\u80FD\u8FD0\u884C\u4F46\u88AB\u6D4B\u51FD\u6570\u62A5"Invalid syntax / Parse error / Malformed"\u7B49\u89E3\u6790\u5931\u8D25\u9519\u8BEF\uFF0C
846
- \u8BF4\u660E fixture \u6587\u4EF6\u672C\u8EAB\u683C\u5F0F\u4E0D\u5408\u6CD5\uFF08DBC/CSV/JSON/...\uFF09\uFF0C**\u4E0D\u662F\u88AB\u6D4B\u4EE3\u7801\u7684 bug**\u3002
847
- \u5FC5\u987B read_file \u770B\u6E05\u5F53\u524D fixture \u5185\u5BB9 \u2192 write_file \u6309\u76EE\u6807\u683C\u5F0F\u7684\u6700\u5C0F\u5408\u6CD5\u6837\u4F8B**\u6574\u6587\u4EF6\u91CD\u5199** \u2192 \u518D run_tests\u3002
1002
+ \u8BF4\u660E fixture \u6587\u4EF6\u672C\u8EAB\u683C\u5F0F\u4E0D\u5408\u6CD5\uFF0C**\u4E0D\u662F\u88AB\u6D4B\u4EE3\u7801\u7684 bug**\u3002
1003
+ \u5FC5\u987B read_file \u770B\u6E05\u5F53\u524D fixture \u5185\u5BB9\uFF0C\u6309\u6269\u5C55\u540D/\u89E3\u6790\u5E93\u786E\u8BA4\u683C\u5F0F\u6807\u51C6\uFF1B\u4F18\u5148\u4F7F\u7528\u7528\u6237\u6837\u4F8B\u6216 http_fetch \u4E0B\u8F7D\u7684\u6743\u5A01\u53C2\u8003\u6837\u4F8B\uFF0C
1004
+ \u518D write_file \u6574\u6587\u4EF6\u91CD\u5199\u5E76 run_tests\u3002\u590D\u6742\u9886\u57DF\u683C\u5F0F\u8FDE\u7EED\u5931\u8D25\u540E\u5FC5\u987B\u505C\u6B62\u51ED\u8BB0\u5FC6\u751F\u6210\uFF0C\u6539\u4E3A\u8BF7\u6C42\u7528\u6237\u6837\u4F8B\u6216\u7F51\u7EDC\u53C2\u8003\u3002
848
1005
  \u4E25\u7981\u56E0\u4E3A\u89E3\u6790\u9519\u8BEF\u5C31\u53BB\u6539\u88AB\u6D4B\u6A21\u5757\u3001\u6D4B\u8BD5\u65AD\u8A00\u6216 mock \u6389\u89E3\u6790\u903B\u8F91\u2014\u2014\u5148\u628A fixture \u4FEE\u5BF9\u518D\u8BF4\u3002
849
1006
  4. \u5F53\u6240\u6709 outputs \u6587\u4EF6\u5747\u5DF2\u751F\u6210\u4E14\u81EA\u68C0\u901A\u8FC7\uFF0C\u628A done \u8BBE\u4E3A true \u4E14 actions \u4E3A\u7A7A\u3002
850
1007
  5. \u4EFB\u4F55\u9519\u8BEF\u90FD\u901A\u8FC7\u4E0B\u4E00\u8F6E\u7684 actions \u4FEE\u6B63\uFF1B\u4E0D\u8981\u5C1D\u8BD5\u8D8A\u6743\u6216\u634F\u9020\u5DE5\u5177\u3002
@@ -864,8 +1021,8 @@ DEBUG \u53EA\u662F\u8FD0\u884C\u65F6\u5931\u8D25\u56DE\u9000/\u4FEE\u590D\u6A21\
864
1021
 
865
1022
  \u6CBF\u7528 Python Planner \u7684\u9636\u6BB5\u6587\u6863\u548C\u540C\u6B65\u6D4B\u8BD5\u8BBE\u8BA1\u89C4\u5219\uFF1A
866
1023
  - REQUIREMENT_ANALYSIS\uFF1A\`docs/01-requirement-analysis.md\` + \`docs/tests/functional-test-plan.md\`\u3002
867
- - HIGH_LEVEL_DESIGN\uFF1A\`docs/02-high-level-design.md\` + \`docs/tests/integration-test-plan.md\`\u3002
868
- - DETAILED_DESIGN\uFF1A\`docs/03-detailed-design.md\` + \`docs/tests/module-test-plan.md\`\u3002
1024
+ - HIGH_LEVEL_DESIGN\uFF1A\`docs/02-high-level-design.md\` + \`docs/tests/module-test-plan.md\`\u3002
1025
+ - DETAILED_DESIGN\uFF1A\`docs/03-detailed-design.md\` + \`docs/tests/integration-test-plan.md\`\u3002
869
1026
  - CODE\uFF1A\u5B9E\u73B0\u4EA7\u7269 + \`docs/tests/unit-test-plan.md\`\u3002
870
1027
  - UNIT_TEST\uFF1A\`docs/05-unit-test.md\`\u3002
871
1028
  - INTEGRATION_TEST\uFF1A\`docs/06-integration-test.md\`\u3002
@@ -881,6 +1038,7 @@ DETAILED_DESIGN \u5FC5\u987B\u5B9A\u4E49\u6A21\u5757\u5185\u90E8\u5177\u4F53\u52
881
1038
  2. \u6BCF\u4E2A current/planned implementation phase \u90FD\u5FC5\u987B\u5305\u542B\u5B8C\u6574 8 \u9636\u6BB5 V \u6A21\u578B\u3002
882
1039
  3. \u6BCF\u4E2A\u5B8F Step \u7684 \`subTasks\` \u6700\u591A\u5D4C\u5957 2 \u5C42\u3002
883
1040
  4. \u6BCF\u4E2A CODE Step \u5FC5\u987B\u88AB\u540C\u8FED\u4EE3 UNIT_TEST \u8986\u76D6\uFF1BarchitectureModules \u7684 testPaths \u5FC5\u987B\u7531 MODULE_TEST \u4EA7\u51FA\u3002
1041
+ CODE outputs \u53EA\u80FD\u5305\u542B src/ \u4E0B\u7684\u4EA7\u54C1\u6E90\u7801\u6587\u4EF6\u548C docs/tests/unit-test-plan.md\uFF1B\u7981\u6B62\u628A tests/**/*.test.ts \u6216\u5176\u4ED6 tests/** \u6587\u4EF6\u5217\u4E3A CODE outputs\u3002
884
1042
  5. \u8BBE\u8BA1\u9636\u6BB5\u4E0D\u5F97\u8F93\u51FA src/ \u6216 tests/ \u6587\u4EF6\uFF1BHIGH_LEVEL_DESIGN \u662F\u552F\u4E00\u53EF\u8F93\u51FA \`package.json\` / \`tsconfig.json\` \u7684\u9636\u6BB5\u3002
885
1043
  6. TypeScript greenfield \u8BA1\u5212\u5FC5\u987B\u4E14\u53EA\u80FD\u6709\u4E00\u4E2A HIGH_LEVEL_DESIGN Step \u8F93\u51FA \`package.json\`\uFF0C\u5E76\u786E\u4FDD one HIGH_LEVEL_DESIGN Step output \`package.json\`\uFF0C\u5305\u542B \`build\`\u3001\`test\`\u3001\u6700\u597D\u8FD8\u6709 \`lint\` \u811A\u672C\u3002
886
1044
  7. \u672C\u5730 TypeScript \u6E90\u7801\u6A21\u5757\u5FC5\u987B\u4F7F\u7528\u5E26\u663E\u5F0F \`.ts\` \u540E\u7F00\u7684 ESM \u76F8\u5BF9\u5BFC\u5165\uFF1B\u914D\u7F6E \`allowImportingTsExtensions: true\`\uFF0Cbuild/lint \u4F7F\u7528 \`tsc --noEmit\`\u3002\u4EE3\u7801\u5FC5\u987B\u517C\u5BB9 Node \u539F\u751F type stripping\uFF0C\u907F\u514D enum\u3001namespace\u3001\u53C2\u6570\u5C5E\u6027\u7B49\u9700\u8F6C\u8BD1\u8BED\u6CD5\u3002
@@ -889,6 +1047,7 @@ DETAILED_DESIGN \u5FC5\u987B\u5B9A\u4E49\u6A21\u5757\u5185\u90E8\u5177\u4F53\u52
889
1047
  10. complexityAssessment \u548C implementationPhases \u89C4\u5219\u540C Python\uFF1Asimple=>P1\uFF0Cmoderate => \u81F3\u5C11 P1+P2\uFF0Ccomplex => \u81F3\u5C11 P1+P2+P3\uFF0C\u7528\u6237\u5F3A\u5236\u5206\u9636\u6BB5\u65F6 userForcedPhaseSplit=true\u3002
890
1048
  11. verificationGate failurePolicy \u5FC5\u987B\u8BF4\u660E\u628A\u5931\u8D25\u65E5\u5FD7\u4F20\u7ED9 Debugger\uFF0C\u56DE\u9000\u5230\u5BF9\u5E94 V \u6A21\u578B\u9636\u6BB5\u5E76\u91CD\u8DD1\u540E\u7EED\u9636\u6BB5\u3002
891
1049
  12. \u590D\u6742\u9700\u6C42\u8FD4\u56DE architectureModules\uFF1BCODE/MODULE_TEST Step \u53EF\u8986\u76D6\u591A\u4E2A\u6A21\u5757\uFF0C\u4F46\u5FC5\u987B\u5728 subTasks \u4E2D\u5217\u51FA\u6A21\u5757\u7EA7\u5DE5\u4F5C\u3002
1050
+ 13. TypeScript \u6D4B\u8BD5\u5FC5\u987B\u53EA\u4F7F\u7528 Vitest\u3002Step prompt \u6216 package.json \u4E2D\u7981\u6B62\u8981\u6C42 Jest\u3001ts-jest\u3001@types/jest\u3001ts-node\u3001nodemon\uFF1Bpackage.json \u5FC5\u987B\u4F7F\u7528 "test": "vitest run" \u548C "build": "tsc --noEmit"\u3002
892
1051
 
893
1052
  \u8F93\u51FA JSON \u7ED3\u6784\u540C Python\uFF0C\u5FC5\u987B\u5305\u542B \`"projectType": "application | library | mixed"\`\uFF0C\u8DEF\u5F84\u4F7F\u7528 \`src/example.ts\` \u548C \`tests/example.test.ts\`\uFF1B\u7B2C\u4E00\u4E2A Step phase \u5FC5\u987B\u662F \`REQUIREMENT_ANALYSIS\`\uFF0C\u4E0D\u662F \`REQUIREMENT\`\u3002\u4E0D\u5B58\u5728\u547D\u4EE4\u884C project-type \u8986\u76D6\u3002`;
894
1053
  var TYPESCRIPT_EXECUTOR_SYSTEM2 = `\u4F60\u662F XCompiler \u7684 Step Executor\u3002\u4F60\u53EA\u80FD\u901A\u8FC7 JSON \u5DE5\u5177\u8C03\u7528\u4E0E\u7CFB\u7EDF\u4EA4\u4E92\uFF0C\u7981\u6B62\u4EFB\u4F55 Markdown \u6216\u89E3\u91CA\u6027\u6587\u672C\u3002
@@ -908,7 +1067,7 @@ var TYPESCRIPT_EXECUTOR_SYSTEM2 = `\u4F60\u662F XCompiler \u7684 Step Executor\u
908
1067
  - \u3010\u5BFC\u5165\u7EA6\u5B9A\u3011src/ \u4E0B\u7684\u672C\u5730\u6E90\u7801\u6A21\u5757\u4F7F\u7528\u5E26\u663E\u5F0F ".ts" \u540E\u7F00\u7684 ESM \u76F8\u5BF9\u5BFC\u5165\uFF0C\u4F8B\u5982 \`import { x } from "./util.ts";\`\u3002\u4EE3\u7801\u5FC5\u987B\u517C\u5BB9 Node \u539F\u751F TypeScript type stripping\uFF1A\u53EA\u4F7F\u7528\u53EF\u64E6\u9664\u7C7B\u578B\u8BED\u6CD5\uFF0C\u907F\u514D enum\u3001namespace\u3001\u53C2\u6570\u5C5E\u6027\u7B49\u9700\u8981\u8F6C\u8BD1\u7684 TS \u7279\u6027\u3002\u7981\u6B62\u4F7F\u7528 Python \u98CE\u683C import\u3001\`from src.<module>\` \u6216\u4EFB\u4F55 sys.path hack\u3002
909
1068
  - \u3010\u6D4B\u8BD5\u7EA6\u5B9A\u3011\u6D4B\u8BD5\u4F7F\u7528 Vitest\uFF1A\`import { describe, it, expect } from "vitest";\`\uFF0C\u6D4B\u8BD5\u6587\u4EF6\u653E\u5728 \`tests/**/*.test.ts\`\u3002
910
1069
  - \u3010\u6D4B\u8BD5\u81EA\u5305\u542B\u3011\u6D4B\u8BD5**\u4E25\u7981**\u8BFB\u53D6\u4E00\u4E2A\u78C1\u76D8\u4E0A\u4E0D\u5B58\u5728\u7684\u6837\u4F8B\u6587\u4EF6\uFF1B\u5F53\u88AB\u6D4B\u51FD\u6570\u9700\u8981\u6587\u4EF6\u8F93\u5165\u65F6\uFF0C\u8981\u4E48\u5728\u6D4B\u8BD5\u91CC\u6784\u9020\u5185\u5BB9\uFF0C\u8981\u4E48\u5199\u5165 \`tests/fixtures/<name>\`\u3002
911
- - \u3010fixture \u8FED\u4EE3\u3011\u5F53\u6D4B\u8BD5\u5DF2\u7ECF\u80FD\u8FD0\u884C\u4F46\u88AB\u6D4B\u51FD\u6570\u62A5"Invalid syntax / Parse error / Malformed"\u7B49\u89E3\u6790\u5931\u8D25\u9519\u8BEF\uFF0C\u8BF4\u660E fixture \u6587\u4EF6\u672C\u8EAB\u683C\u5F0F\u4E0D\u5408\u6CD5\u3002\u5FC5\u987B read_file \u770B\u6E05\u5F53\u524D fixture \u5185\u5BB9 \u2192 write_file \u6309\u76EE\u6807\u683C\u5F0F\u7684\u6700\u5C0F\u5408\u6CD5\u6837\u4F8B\u6574\u6587\u4EF6\u91CD\u5199 \u2192 \u518D run_tests\u3002\u4E25\u7981\u56E0\u4E3A\u89E3\u6790\u9519\u8BEF\u53BB\u5F31\u5316\u5B9E\u73B0\u6216\u65AD\u8A00\u3002
1070
+ - \u3010fixture \u8FED\u4EE3\u3011\u5F53\u6D4B\u8BD5\u5DF2\u7ECF\u80FD\u8FD0\u884C\u4F46\u88AB\u6D4B\u51FD\u6570\u62A5"Invalid syntax / Parse error / Malformed"\u7B49\u89E3\u6790\u5931\u8D25\u9519\u8BEF\uFF0C\u8BF4\u660E fixture \u6587\u4EF6\u672C\u8EAB\u683C\u5F0F\u4E0D\u5408\u6CD5\u3002\u5FC5\u987B read_file \u770B\u6E05\u5F53\u524D fixture \u5185\u5BB9\uFF0C\u4F18\u5148\u4F7F\u7528\u7528\u6237/\u5DE5\u4F5C\u533A\u6837\u4F8B\uFF1B\u6CA1\u6709\u6837\u4F8B\u65F6\u7528 http_fetch \u62C9\u53D6\u6743\u5A01\u516C\u5F00\u53C2\u8003\uFF1B\u53EA\u6709\u7B80\u5355\u6587\u672C\u683C\u5F0F\u624D\u53EF\u6784\u9020\u6700\u5C0F\u6837\u4F8B\u5E76\u7ACB\u5373 run_tests\u3002\u4E25\u7981\u56E0\u4E3A\u89E3\u6790\u9519\u8BEF\u53BB\u5F31\u5316\u5B9E\u73B0\u6216\u65AD\u8A00\uFF0C\u4E5F\u4E25\u7981\u53CD\u590D\u51ED\u8BB0\u5FC6\u751F\u6210\u590D\u6742\u683C\u5F0F fixture\u3002
912
1071
  4. \u5F53\u6240\u6709 outputs \u6587\u4EF6\u5747\u5DF2\u751F\u6210\u4E14\u81EA\u68C0\u901A\u8FC7\uFF0C\u628A done \u8BBE\u4E3A true \u4E14 actions \u4E3A\u7A7A\u3002
913
1072
  5. \u4EFB\u4F55\u9519\u8BEF\u90FD\u901A\u8FC7\u4E0B\u4E00\u8F6E\u7684 actions \u4FEE\u6B63\uFF1B\u4E0D\u8981\u5C1D\u8BD5\u8D8A\u6743\u6216\u634F\u9020\u5DE5\u5177\u3002
914
1073
  6. \u3010\u5927\u6587\u4EF6\u62C6\u5757\u5199\u5165\u3011write_file / append_file \u5355\u6B21 content \u5FC5\u987B\u4F4E\u4E8E\u5DE5\u5177\u6587\u6863\u5C55\u793A\u7684\u5F53\u524D Step \u8FD0\u884C\u65F6 chunk limit\u3002
@@ -921,6 +1080,78 @@ var TYPESCRIPT_EXECUTOR_SYSTEM2 = `\u4F60\u662F XCompiler \u7684 Step Executor\u
921
1080
  function buildPlannerSystem2(profile) {
922
1081
  return (profile.id === "typescript" ? TYPESCRIPT_PLANNER_SYSTEM2 : PYTHON_PLANNER_SYSTEM2) + profile.plannerPromptOverride;
923
1082
  }
1083
+ function buildPlannerPhasePlanSystem2(profile) {
1084
+ return `\u4F60\u662F XCompiler \u7CFB\u7EDF\u7684 Planner\uFF0C\u5F53\u524D\u6267\u884C\u201C\u4E24\u7EA7\u89C4\u5212\u201D\u7684\u7B2C\u4E00\u6B65\uFF1APhasePlan\u3002
1085
+
1086
+ \u76EE\u6807\u8BED\u8A00\uFF1A${profile.displayName}\u3002
1087
+
1088
+ \u53EA\u8F93\u51FA\u9879\u76EE\u7EA7 PhasePlan\uFF0C\u4E0D\u8F93\u51FA steps\u3001architectureModules\u3001dependencies \u6216\u4EFB\u4F55\u5355\u4E2A V \u6A21\u578B Step\u3002
1089
+
1090
+ PhasePlan \u5FC5\u987B\u5B8C\u6210\uFF1A
1091
+ 1. \u5224\u5B9A projectType\uFF1Aapplication / library / mixed\u3002
1092
+ 2. \u5224\u5B9A complexityAssessment\uFF1Asimple / moderate / complex\uFF0C\u5E76\u8BF4\u660E rationale\u3002
1093
+ 3. \u751F\u6210 implementationPhases\uFF1AP1 status=current\uFF1B\u540E\u7EED P2/P3 status=planned\u3002simple \u53EA\u9700\u8981 P1\uFF1Bmoderate \u81F3\u5C11 P1+P2\uFF1Bcomplex \u81F3\u5C11 P1+P2+P3\uFF1B\u7528\u6237\u5F3A\u5236\u5206\u9636\u6BB5\u65F6\u81F3\u5C11 P1+P2 \u4E14 userForcedPhaseSplit=true\u3002
1094
+ 4. \u6BCF\u4E2A phase \u5FC5\u987B\u5305\u542B objective\u3001scope\u3001deliverables\u3001dependsOn \u548C verificationGate\u3002
1095
+ 5. planned phase \u53EA\u8BB0\u5F55\u76EE\u6807\u548C\u95E8\u7981\uFF0C\u4E0D\u80FD\u5C55\u5F00\u4EFB\u4F55 Step\u3002\u540E\u7EED\u4F1A\u57FA\u4E8E\u5355\u4E2A phase \u53E6\u884C\u751F\u6210\u5B8C\u6574 V \u6A21\u578B\u8BA1\u5212\u3002
1096
+
1097
+ \u53EA\u8FD4\u56DE\u4E25\u683C JSON\uFF1A
1098
+ {
1099
+ "requirementDigest": "string",
1100
+ "globalPrompt": "string",
1101
+ "projectType": "application | library | mixed",
1102
+ "complexityAssessment": { "level": "simple | moderate | complex", "rationale": "string", "splitRecommended": true, "userForcedPhaseSplit": false },
1103
+ "implementationPhases": [
1104
+ { "id": "P1", "title": "\u6838\u5FC3\u529F\u80FD", "objective": "string", "status": "current", "scope": ["..."], "deliverables": ["..."], "dependsOn": [], "verificationGate": { "summary": "string", "checks": ["..."], "failurePolicy": "Feed failures to Debugger, roll back to the paired V-model phase, and rerun subsequent phases." } }
1105
+ ]
1106
+ }
1107
+
1108
+ \u7981\u6B62\u8F93\u51FA Markdown\u3001\u89E3\u91CA\u6587\u5B57\u3001steps\u3001src/test \u6587\u4EF6\u6E05\u5355\u3002` + profile.plannerPromptOverride;
1109
+ }
1110
+ function buildPlannerPhaseDecomposeSystem2(profile) {
1111
+ return `\u4F60\u662F XCompiler \u7CFB\u7EDF\u7684 Planner\uFF0C\u5F53\u524D\u6267\u884C\u201C\u4E24\u7EA7\u89C4\u5212\u201D\u7684\u7B2C\u4E8C\u6B65\uFF1A\u4E3A\u6307\u5B9A phase \u751F\u6210\u5B8C\u6574 V \u6A21\u578B StepPlan\u3002
1112
+
1113
+ \u76EE\u6807\u8BED\u8A00\uFF1A${profile.displayName}\u3002
1114
+
1115
+ \u4F60\u4F1A\u6536\u5230\u5DF2\u7ECF\u51BB\u7ED3\u7684 PhasePlan \u548C\u4E00\u4E2A phaseId\u3002\u53EA\u5141\u8BB8\u4E3A\u8BE5 phaseId \u751F\u6210 Step\uFF1Bplanned phase \u4E0D\u5F97\u5C55\u5F00\u5230\u672C\u6B21 steps \u4E2D\u3002
1116
+
1117
+ \u6BCF\u4E2A\u5F53\u524D phase \u5FC5\u987B\u4F7F\u7528\u5B8C\u6574\u6807\u51C6 V \u6A21\u578B\uFF1A
1118
+ REQUIREMENT_ANALYSIS -> HIGH_LEVEL_DESIGN -> DETAILED_DESIGN -> CODE -> UNIT_TEST -> INTEGRATION_TEST -> MODULE_TEST -> FUNCTIONAL_TEST\u3002
1119
+
1120
+ \u9636\u6BB5\u804C\u8D23\uFF1A
1121
+ - REQUIREMENT_ANALYSIS \u5B9A\u4E49\u529F\u80FD\u8303\u56F4\u3001\u9A8C\u6536\u6807\u51C6\u3001\u8FB9\u754C\u6761\u4EF6\u548C\u7528\u6237\u53EF\u89C1\u884C\u4E3A\uFF0C\u5E76\u540C\u6B65\u8F93\u51FA\u529F\u80FD\u6D4B\u8BD5\u8BA1\u5212\u3002
1122
+ - HIGH_LEVEL_DESIGN \u5B9A\u4E49\u7CFB\u7EDF\u5B9A\u4F4D\u3001\u5916\u90E8\u63A5\u53E3\u3001\u7B2C\u4E09\u65B9\u5E93\u9009\u578B\u3001\u4F9D\u8D56\u786E\u8BA4\u548C\u96C6\u6210\u8FB9\u754C\uFF0C\u5E76\u540C\u6B65\u8F93\u51FA\u96C6\u6210\u6D4B\u8BD5\u8BA1\u5212\u3002
1123
+ - DETAILED_DESIGN \u5B9A\u4E49\u6A21\u5757\u5185\u90E8\u51FD\u6570/\u7C7B\u3001\u6570\u636E\u7ED3\u6784\u3001\u7B97\u6CD5\u3001\u63A7\u5236\u6D41\u3001\u9519\u8BEF\u5904\u7406\u548C\u5185\u90E8\u67B6\u6784\uFF0C\u5E76\u540C\u6B65\u8F93\u51FA\u6A21\u5757\u6D4B\u8BD5\u8BA1\u5212\u3002
1124
+ - CODE \u53EA\u5B9E\u73B0\u5F53\u524D phase \u8303\u56F4\u5E76\u540C\u6B65\u8F93\u51FA\u5355\u5143\u6D4B\u8BD5\u8BA1\u5212\u3002
1125
+ - UNIT_TEST / INTEGRATION_TEST / MODULE_TEST / FUNCTIONAL_TEST \u5206\u522B\u9A8C\u8BC1\u5BF9\u5E94\u5DE6\u4FA7\u9636\u6BB5\u3002
1126
+
1127
+ \u4E25\u683C\u4EA7\u7269\u5F52\u5C5E\uFF1A
1128
+ - CODE outputs \u53EA\u80FD\u5305\u542B src/ \u4E0B\u7684\u4EA7\u54C1\u6E90\u7801\u6587\u4EF6\u548C\u5355\u5143\u6D4B\u8BD5\u8BA1\u5212\u6587\u6863\uFF1B\u4E0D\u5F97\u628A tests/** \u6587\u4EF6\u653E\u5230 CODE outputs\u3002
1129
+ - UNIT_TEST \u62E5\u6709\u5355\u5143\u6D4B\u8BD5\u6587\u4EF6\uFF1BINTEGRATION_TEST \u62E5\u6709\u96C6\u6210\u6D4B\u8BD5\u6587\u4EF6\uFF1BMODULE_TEST \u62E5\u6709 architectureModules.testPaths\uFF1BFUNCTIONAL_TEST \u62E5\u6709\u7AEF\u5230\u7AEF/\u529F\u80FD\u6D4B\u8BD5\u6587\u4EF6\u548C\u4EA4\u4ED8\u6587\u6863\u3002
1130
+ - TypeScript greenfield \u5FC5\u987B\u4E14\u53EA\u80FD\u6709\u4E00\u4E2A HIGH_LEVEL_DESIGN Step \u8F93\u51FA package.json\uFF0C\u5305\u542B scripts\u3001dependencies\u3001devDependencies\u3002CODE \u4E0D\u5F97\u8F93\u51FA package.json\u3002
1131
+ - TypeScript package.json \u53EA\u80FD\u4F7F\u7528 Vitest\uFF1A"test": "vitest run"\uFF0C"build": "tsc --noEmit"\uFF0CdevDependencies \u5305\u542B typescript/tsx/vitest/@types/node\u3002\u7981\u6B62\u63D0\u53CA\u6216\u8981\u6C42 Jest\u3001ts-jest\u3001@types/jest\u3001ts-node\u3001nodemon\u3002
1132
+
1133
+ \u8F93\u51FA\u5FC5\u987B\u53EA\u5305\u542B\u5F53\u524D phase \u7684 dependencies\u3001architectureModules \u548C steps\u3002\u590D\u6742/\u591A\u5173\u6CE8\u70B9\u4EFB\u52A1\u5FC5\u987B\u7528 architectureModules \u8868\u8FBE\u5F53\u524D phase \u7684\u6A21\u5757\u8FB9\u754C\uFF0C\u5E76\u5728 CODE/MODULE_TEST \u7684 subTasks \u4E2D\u6620\u5C04\u6A21\u5757\u7EA7\u5DE5\u4F5C\u3002\u6BCF\u4E2A Step \u7684 subTasks \u6700\u591A\u5D4C\u5957 2 \u5C42\u3002
1134
+
1135
+ architectureModules \u53EA\u80FD\u63CF\u8FF0\u5F53\u524D phase \u7684\u4EA7\u54C1/\u4E1A\u52A1\u6E90\u7801\u6A21\u5757\uFF1A
1136
+ - sourcePaths \u5FC5\u987B\u662F src/ \u4E0B\u7684\u76EE\u6807\u8BED\u8A00\u6E90\u7801\u6587\u4EF6\uFF0C\u4E0D\u80FD\u662F\u76EE\u5F55\uFF0C\u4E0D\u80FD\u662F tests/\u3001docs/\u3001README\u3001fixtures\u3001utils \u6216\u62A5\u544A\u6587\u4EF6\u3002
1137
+ - testPaths \u5FC5\u987B\u662F tests/ \u4E0B\u7684\u76EE\u6807\u8BED\u8A00\u6D4B\u8BD5\u6587\u4EF6\uFF0C\u4E0D\u80FD\u662F\u76EE\u5F55\u3002
1138
+ - \u6D4B\u8BD5 fixtures\u3001\u6D4B\u8BD5\u5DE5\u5177\u3001\u9886\u57DF\u6837\u4F8B\u8F93\u5165\u3001\u4E34\u65F6\u8F93\u51FA\u6587\u4EF6\u5E94\u653E\u5728\u5BF9\u5E94\u6D4B\u8BD5 Step \u7684 outputs \u6216 subTasks \u4E2D\uFF0C\u4E0D\u5F97\u767B\u8BB0\u4E3A architectureModules\u3002
1139
+
1140
+ \u53EA\u8FD4\u56DE\u4E25\u683C JSON\uFF1A
1141
+ {
1142
+ "requirementDigest": "string",
1143
+ "globalPrompt": "string",
1144
+ "dependencies": ["pytest"],
1145
+ "architectureModules": [
1146
+ { "id": "M001", "name": "\u6A21\u5757\u540D", "responsibility": "\u5355\u4E00\u660E\u786E\u804C\u8D23", "sourcePaths": ["src/example.py"], "testPaths": ["tests/test_example.py"], "dependencies": [] }
1147
+ ],
1148
+ "steps": [
1149
+ { "id": "S001", "iterationId": "P1", "phase": "REQUIREMENT_ANALYSIS", "title": "string", "description": "string", "systemPrompt": "\u8303\u56F4\u3001\u8F93\u5165\u3001\u4EA7\u51FA\u3001\u9A8C\u6536\u3001\u7981\u4EE4", "role": "Planner", "tools": ["write_file"], "inputs": ["docs/topic.md"], "outputs": ["docs/01-requirement-analysis.md", "docs/tests/functional-test-plan.md"], "subTasks": [], "dependsOn": [], "acceptance": "string", "maxRetries": 3 }
1150
+ ]
1151
+ }
1152
+
1153
+ \u7981\u6B62\u8F93\u51FA\u672A\u6765 planned phase \u7684 Step\uFF1B\u7981\u6B62\u8F93\u51FA requirements.txt\uFF1B\u7981\u6B62\u8BA9\u9700\u6C42/\u8BBE\u8BA1\u9636\u6BB5\u5199 src/tests\uFF1BFUNCTIONAL_TEST \u5FC5\u987B\u5305\u542B README.md\u3001docs/quickstart.md \u548C\u529F\u80FD\u9A8C\u6536\u6587\u6863\u3002` + profile.plannerPromptOverride;
1154
+ }
924
1155
  function buildExecutorSystem2(profile) {
925
1156
  return (profile.id === "typescript" ? TYPESCRIPT_EXECUTOR_SYSTEM2 : PYTHON_EXECUTOR_SYSTEM2) + profile.executorPromptOverride;
926
1157
  }
@@ -937,7 +1168,7 @@ var messages2 = {
937
1168
  preflightOllamaUnreachable: (baseUrl, message) => `\u9884\u68C0\uFF1AOllama ${baseUrl} \u4E0D\u53EF\u8FBE\uFF1A${message}`,
938
1169
  preflightAutoAdded: (providers, roles) => `\u9884\u68C0\uFF1A\u81EA\u52A8\u589E\u52A0 ${providers} \u4E2A provider\uFF0C\u8986\u76D6\u89D2\u8272 [${roles}]`,
939
1170
  scoreFileHeader: "# XCompiler LLM provider \u8BC4\u5206\u5FEB\u7167\uFF08\u7531 ScoreStore \u81EA\u52A8\u7EF4\u62A4\uFF0C\u8BF7\u52FF\u624B\u5DE5\u7F16\u8F91\uFF09",
940
- scoreFileSemantics: "# \u8BC4\u5206\u8BED\u4E49\uFF1A\u9ED8\u8BA4 1.0\uFF1B\u5931\u8D25 -0.5\uFF08\u4E0B\u9650 0=\u7981\u7528\uFF09\uFF1B\u6210\u529F +0.1\uFF08\u4E0A\u9650 10\uFF09\u3002"
1171
+ scoreFileSemantics: "# \u8BC4\u5206\u8BED\u4E49\uFF1A\u9ED8\u8BA4 1.0\uFF1B\u81EA\u52A8\u8BC4\u5206\u8303\u56F4 0.1\uFF5E1.0\uFF1Btags: [cluster] \u7684 provider \u9ED8\u8BA4 0.2\uFF5E0.5\uFF0C\u9664\u975E llm.cluster_score_min/max \u6269\u5BBD\uFF1B\u5931\u8D25 -0.5\uFF1B\u6210\u529F +0.1\uFF1B\u53EA\u6709\u7528\u6237\u914D\u7F6E score=0 \u8868\u793A\u7981\u7528\u3002"
941
1172
  },
942
1173
  system: {
943
1174
  configEnvMissing: (names) => `[xcompiler] \u914D\u7F6E\u4E2D\u7684\u73AF\u5883\u53D8\u91CF\u672A\u8BBE\u7F6E\uFF0C\u5DF2\u66FF\u6362\u4E3A\u7A7A\u5B57\u7B26\u4E32\uFF1A${names}`,
@@ -1022,34 +1253,34 @@ var messages2 = {
1022
1253
  },
1023
1254
  cli: {
1024
1255
  rootDescription: "XCompiler \u2014 AI Software Factory CLI",
1025
- compileDescription: "\u4EA4\u4E92\u5F0F\u7F16\u8BD1\u9700\u6C42\u4E3A plan.json\uFF08\u542B\u5F3A\u5236\u4EBA\u5DE5\u786E\u8BA4\uFF09",
1026
- runDescription: "\u6267\u884C\u5DF2\u786E\u8BA4\u7684 plan.json\uFF08\u652F\u6301\u5206\u9636\u6BB5\u8FD0\u884C\uFF1A--phase / --from\uFF09",
1256
+ compileDescription: "\u4EA4\u4E92\u5F0F\u7F16\u8BD1\u9700\u6C42\u4E3A phasePlan.json \u4E0E\u5F53\u524D\u9636\u6BB5\u8BA1\u5212\uFF08\u542B\u5F3A\u5236\u4EBA\u5DE5\u786E\u8BA4\uFF09",
1257
+ runDescription: "\u6267\u884C\u5DF2\u786E\u8BA4\u7684 phasePlan.json\uFF08\u652F\u6301\u5206\u9636\u6BB5\u8FD0\u884C\uFF1A--phase / --from\uFF09",
1027
1258
  loadDescription: "\u52A0\u8F7D XXX.xc \u5DE5\u7A0B\u6587\u4EF6\u5E76\u7EE7\u7EED\u5F53\u524D plan",
1028
1259
  appendDescription: "\u5728\u5DF2\u6709 XXX.xc \u5DE5\u7A0B\u57FA\u7840\u4E0A\u8FFD\u52A0\u65B0\u9700\u6C42\uFF0C\u5E76\u91CD\u65B0\u8D70\u6F84\u6E05\u4E0E V \u6A21\u578B\u6267\u884C",
1029
- lsDescription: "\u626B\u63CF workspace \u5217\u51FA\u6240\u6709 plan.json \u72B6\u6001\u6458\u8981",
1260
+ lsDescription: "\u626B\u63CF workspace \u5217\u51FA\u6240\u6709 phasePlan.json / \u5386\u53F2 plan.json \u72B6\u6001\u6458\u8981",
1030
1261
  showDescription: "\u6253\u5370 Step \u5B9A\u4E49 / \u72B6\u6001 / \u4EA7\u7269 / \u6700\u8FD1\u5BA1\u8BA1",
1031
1262
  optWorkspace: "workspace \u76EE\u5F55\uFF08\u540C --output\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55\uFF09",
1032
1263
  optOutput: "\u5DE5\u7A0B/workspace \u8F93\u51FA\u76EE\u5F55\uFF08\u4F18\u5148\u7EA7\u6700\u9AD8\uFF0C\u7B49\u4EF7\u4E8E -w\uFF09",
1033
1264
  optConfig: "config.yaml \u8DEF\u5F84",
1034
1265
  optInput: "\u4ECE\u9700\u6C42\u6587\u4EF6\u8BFB\u53D6\uFF08\u975E\u4EA4\u4E92\uFF09",
1035
1266
  optTopic: "\u76F4\u63A5\u4F7F\u7528\u5DF2\u6F84\u6E05\u7684 topic.md \u4F5C\u4E3A\u8F93\u5165\uFF1A\u8DF3\u8FC7 intake / clarify / Addenda / Gate 1\uFF0C\u76F4\u63A5\u8FDB\u5165 decompose",
1036
- optPlanOut: "\u6307\u5B9A plan.json \u8F93\u51FA\u6587\u4EF6\uFF08\u9ED8\u8BA4 <workspace>/plan.json\uFF09",
1267
+ optPlanOut: "\u6307\u5B9A phasePlan.json \u8F93\u51FA\u6587\u4EF6\uFF08\u9ED8\u8BA4 <workspace>/phasePlan.json\uFF09",
1037
1268
  optBaseDir: "\u9879\u76EE\u8F93\u51FA\u6839\u76EE\u5F55\uFF08\u5728\u5176\u4E0B\u521B\u5EFA <name> \u5B50\u76EE\u5F55\uFF09",
1038
1269
  optName: "\u9879\u76EE\u540D\uFF08\u9ED8\u8BA4 xcompiler-<\u65F6\u95F4\u6233>\uFF09",
1039
1270
  optYes: "\u8DF3\u8FC7\u4EBA\u5DE5\u786E\u8BA4\uFF08\u4EC5\u5728 -i / -t \u63D0\u4F9B\u65F6\u6709\u610F\u4E49\uFF09",
1040
- optForce: "\u5F3A\u5236\u91CD\u65B0\u751F\u6210\uFF1A\u8986\u5199 workspace \u9501\u3001\u5FFD\u7565\u65E7 plan.json",
1271
+ optForce: "\u5F3A\u5236\u91CD\u65B0\u751F\u6210\uFF1A\u8986\u5199 workspace \u9501\u3001\u5FFD\u7565\u65E7\u8BA1\u5212\u6587\u4EF6",
1041
1272
  optDryRun: "\u4EC5\u6253\u5370\u62D3\u6251\u987A\u5E8F\uFF0C\u4E0D\u6267\u884C",
1042
1273
  optFrom: "\u4ECE\u6307\u5B9A Step \u5F00\u59CB\uFF08\u4E4B\u524D\u7684\u8DF3\u8FC7\uFF09",
1043
1274
  optPhase: "\u4EC5\u6267\u884C\u6307\u5B9A phase\uFF08REQUIREMENT_ANALYSIS/HIGH_LEVEL_DESIGN/DETAILED_DESIGN/CODE/UNIT_TEST/INTEGRATION_TEST/MODULE_TEST/FUNCTIONAL_TEST/DEBUG\uFF09",
1044
1275
  optReset: "\u91CD\u7F6E\u6240\u6709 Step \u72B6\u6001\u4E3A PENDING",
1045
1276
  optMaxDepth: "\u9012\u5F52\u6700\u5927\u6DF1\u5EA6",
1046
1277
  optTail: "\u6700\u8FD1\u5BA1\u8BA1\u6761\u6570",
1047
- optPlan: "plan.json \u8DEF\u5F84\uFF0C\u9ED8\u8BA4 <workspace>/plan.json",
1278
+ optPlan: "phasePlan.json \u8DEF\u5F84\uFF0C\u9ED8\u8BA4 <workspace>/phasePlan.json",
1048
1279
  optLang: "UI / \u63D0\u793A\u8BCD\u8BED\u8A00\uFF1AEN | CN\uFF08ISO 3166-1 Alpha-2\uFF09",
1049
1280
  optIntent: "\u8BA1\u5212\u610F\u56FE\uFF1Agreenfield | feature | refactor | self",
1050
- optBaselinePlan: "\u5DF2\u6709\u57FA\u7EBF plan.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 <workspace>/plan.json\uFF09",
1281
+ optBaselinePlan: "\u5DF2\u6709\u57FA\u7EBF phasePlan.json / plan.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 <workspace>/phasePlan.json\uFF09",
1051
1282
  optProjectFile: "XXX.xc \u5DE5\u7A0B\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4 <workspace>/<name>.xc\uFF09",
1052
- argPlan: "plan.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 = <workspace>/plan.json\uFF09",
1283
+ argPlan: "phasePlan.json \u6216\u5386\u53F2 plan.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 = <workspace>/phasePlan.json\uFF09",
1053
1284
  argProjectFile: "XXX.xc \u5DE5\u7A0B\u6587\u4EF6",
1054
1285
  argStepId: "Step ID\uFF0C\u5982 S001",
1055
1286
  evolveDescription: "\u5728\u73B0\u6709 workspace \u57FA\u7840\u4E0A\u751F\u6210\u5E76\u6267\u884C\u589E\u91CF feature/refactor \u8BA1\u5212",
@@ -1127,7 +1358,7 @@ var messages2 = {
1127
1358
  auditDecomposeFailed: "planner.decompose \u5931\u8D25",
1128
1359
  lintIssue: (id, message) => ` - [${id}] ${message}`,
1129
1360
  planPreviewTruncated: "\u2026\uFF08\u5DF2\u622A\u65AD\uFF0C\u5B8C\u6574\u5185\u5BB9\u89C1 docs/plan.md\uFF09",
1130
- auditPlanPersisted: (p) => `plan.json \u5DF2\u5199\u5165\uFF1A${p}`,
1361
+ auditPlanPersisted: (p) => `\u9636\u6BB5 plan \u5DF2\u5199\u5165\uFF1A${p}`,
1131
1362
  projectFileWritten: (p) => `\u5DE5\u7A0B\u6587\u4EF6\u5DF2\u66F4\u65B0\uFF1A${p}`,
1132
1363
  nextCommand: (command) => ` \u4E0B\u4E00\u6B65\uFF1A${command}`,
1133
1364
  topicEmptyExit: "--topic \u6587\u4EF6\u4E3A\u7A7A\uFF0C\u5DF2\u9000\u51FA\u3002",
@@ -1144,8 +1375,10 @@ var messages2 = {
1144
1375
  spinDecompose: "Planner \u6B63\u5728\u6309 V \u6A21\u578B\u62C6\u89E3\u2026",
1145
1376
  decomposeFail: "Planner \u62C6\u89E3\u5931\u8D25",
1146
1377
  plannerInvalidPlan: "Planner \u65E0\u6CD5\u751F\u6210\u6709\u6548 plan\uFF1A",
1147
- plannerInvalidPlanHint1: " \u5E38\u89C1\u539F\u56E0\uFF1A\u6240\u6709 LLM provider \u90FD\u8FD4\u56DE\u4E86\u975E\u6CD5/\u622A\u65AD JSON\uFF08\u5982 token loop\uFF09\u3002",
1148
- plannerInvalidPlanHint2: " \u6392\u67E5\uFF1A\u68C0\u67E5 .xcompiler/audit.jsonl \u4E2D\u7684 llm.error / planner.thought \u539F\u6587\u3002",
1378
+ plannerInvalidPlanHint1: " \u5E38\u89C1\u539F\u56E0\uFF1ALLM \u8F93\u51FA\u672A\u6EE1\u8DB3 XCompiler \u8BA1\u5212 schema\u3001V \u6A21\u578B\u9AA8\u67B6\u6216\u67B6\u6784\u5951\u7EA6\uFF1B\u4E0D\u80FD\u8DF3\u8FC7\u8BE5\u9519\u8BEF\u3002",
1379
+ plannerInvalidPlanHint2: " \u6392\u67E5\uFF1A\u68C0\u67E5 .xcompiler/audit.jsonl \u4E2D\u7684 llm.error / planner.thought \u539F\u6587\uFF0C\u6309\u5951\u7EA6\u9519\u8BEF\u4FEE\u6B63 Planner \u8F93\u51FA\u3002",
1380
+ plannerTransportFailureHint1: " \u5E38\u89C1\u539F\u56E0\uFF1ALLM provider \u8FDE\u63A5\u5931\u8D25\u3001\u8BF7\u6C42\u8D85\u65F6\u6216\u670D\u52A1\u7AEF\u4E2D\u65AD\uFF1B\u8FD9\u4E0D\u662F\u9879\u76EE plan/\u6E90\u7801\u7F3A\u9677\u3002",
1381
+ plannerTransportFailureHint2: " \u6392\u67E5\uFF1A\u68C0\u67E5 OPENAI_BASE_URL / provider base_url\u3001\u6A21\u578B\u670D\u52A1\u662F\u5426\u53EF\u8FBE\u3001\u7F51\u7EDC\u6743\u9650\u548C\u8D85\u65F6\u8BBE\u7F6E\uFF0C\u7136\u540E\u91CD\u8DD1 build\u3002",
1149
1382
  decomposeSucceed: (n) => `\u5DF2\u751F\u6210 ${n} \u4E2A Step`,
1150
1383
  schemaFail: "Plan schema \u6821\u9A8C\u5931\u8D25\uFF1A",
1151
1384
  schemaInvalidSavedAt: (p) => ` \u5B8C\u6574 plan \u5DF2\u843D\u76D8\uFF1A${p}`,
@@ -1160,12 +1393,13 @@ var messages2 = {
1160
1393
  gate1Cancelled: "\u5DF2\u53D6\u6D88\uFF0C\u672A\u5199\u5165\u4EFB\u4F55\u6587\u4EF6\u3002",
1161
1394
  editTopicMsg: "\u7F16\u8F91 topic.md",
1162
1395
  topicWritten: (p) => `\u5DF2\u5199\u5165 ${p}`,
1163
- planWritten: (p) => `plan \u5DF2\u5199\u5165 ${p}`,
1396
+ planWritten: (p) => `\u9636\u6BB5 plan \u5DF2\u5199\u5165 ${p}`,
1397
+ phasePlanWritten: (p) => `phasePlan \u5DF2\u5199\u5165 ${p}`,
1164
1398
  planPreviewHeader: "\u2500\u2500\u2500 plan.md (preview) \u2500\u2500\u2500",
1165
1399
  planPreviewFooter: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
1166
- gate2Confirm: "\u662F\u5426\u786E\u8BA4\u8BE5\u8BA1\u5212? (\u6B64\u4E3A\u6700\u7EC8\u786E\u8BA4\uFF0C\u786E\u8BA4\u540E\u5C06\u5199\u5165 plan.json)",
1400
+ gate2Confirm: "\u662F\u5426\u786E\u8BA4\u8BE5\u8BA1\u5212? (\u6B64\u4E3A\u6700\u7EC8\u786E\u8BA4\uFF0C\u786E\u8BA4\u540E\u5C06\u5199\u5165 phasePlan.json \u548C\u5F53\u524D\u9636\u6BB5\u8BA1\u5212)",
1167
1401
  gate2AuditLabel: "\u8BA1\u5212\u786E\u8BA4\u95E8 (Gate 2)",
1168
- gate2Rejected: "\u672A\u786E\u8BA4\uFF0C\u5DF2\u653E\u5F03\u3002plan.json \u672A\u5199\u5165\u3002",
1402
+ gate2Rejected: "\u672A\u786E\u8BA4\uFF0C\u5DF2\u653E\u5F03\u3002phasePlan.json \u672A\u5199\u5165\u3002",
1169
1403
  baselineLoaded: (kind, sources) => `\u5DF2\u52A0\u8F7D ${kind} \u57FA\u7EBF\uFF1A${sources}`,
1170
1404
  baselineMissing: (workspace) => `\u589E\u91CF\u6A21\u5F0F\u9700\u8981\u5728 ${workspace} \u4E2D\u627E\u5230\u5DF2\u6709\u5DE5\u7A0B\u57FA\u7EBF\uFF08topic / docs / plan / src\uFF09\u3002`,
1171
1405
  baselineLanguageOverride: (baseline, source, configured) => `\u589E\u91CF\u6A21\u5F0F\u5C06\u6CBF\u7528\u57FA\u7EBF\u8BED\u8A00 ${baseline}\uFF08\u6765\u6E90\uFF1A${source}\uFF09\uFF0C\u800C\u4E0D\u662F\u914D\u7F6E\u4E2D\u7684 ${configured}\u3002`,
@@ -1177,7 +1411,7 @@ var messages2 = {
1177
1411
  topicSecBaseline: "## \u73B0\u6709\u5DE5\u7A0B\u57FA\u7EBF"
1178
1412
  },
1179
1413
  inspect: {
1180
- noPlanFound: "\u672A\u627E\u5230\u4EFB\u4F55 plan.json",
1414
+ noPlanFound: "\u672A\u627E\u5230\u4EFB\u4F55 phasePlan.json / plan.json",
1181
1415
  digestLabel: "digest:",
1182
1416
  stepNotFound: (id) => `Step ${id} \u672A\u627E\u5230`,
1183
1417
  secDescription: "\u2014 description \u2014",
@@ -1202,7 +1436,7 @@ var messages2 = {
1202
1436
  auditPlanLoaded: (p) => `\u5DF2\u52A0\u8F7D plan\uFF1A${p}`,
1203
1437
  planLoaded: (p) => `\u5DF2\u52A0\u8F7D Plan\uFF1A${p}`,
1204
1438
  planSummary: (language, steps) => ` \u8BED\u8A00=${language}\uFF0C\u6B65\u9AA4=${steps}`,
1205
- preflightModelMissing: (names) => `LLM preflight: \u6A21\u578B\u7F3A\u5931\uFF0C\u5DF2\u7981\u7528 [${names}]`,
1439
+ preflightModelMissing: (names) => `LLM preflight: \u6A21\u578B\u7F3A\u5931\uFF0C\u5F53\u524D\u8FD0\u884C\u5DF2\u8DF3\u8FC7 [${names}]\uFF0C\u5E76\u5C06\u52A8\u6001\u8BC4\u5206\u964D\u5230\u6700\u4F4E\u503C`,
1206
1440
  preflightAutoAdded: (n) => `LLM preflight: \u81EA\u52A8\u6CE8\u5165 ${n} \u4E2A provider\uFF08\u6765\u81EA ollama /api/tags\uFF09`,
1207
1441
  runInterrupted: (id, e, total) => `\u6267\u884C\u4E2D\u65AD\u4E8E ${id}\uFF08\u5DF2\u6267\u884C ${e}/${total}\uFF09`,
1208
1442
  runReasonLabel: " \u539F\u56E0: ",
@@ -1258,7 +1492,7 @@ var messages2 = {
1258
1492
  archGateInstruction: (p) => `\u8BF7\u66F4\u65B0 ${p}\uFF0C\u786E\u4FDD\u6BCF\u4E2A architectureModules \u9879\u5728\u8FDB\u5165 CODE \u524D\u5747\u53EF\u8FFD\u8E2A\u3002`,
1259
1493
  testGateReason: (exitCode, timedOut) => `\u6D4B\u8BD5\u95E8\u7981\uFF1A\u6D4B\u8BD5\u9000\u51FA\u7801=${exitCode}${timedOut ? "\uFF08\u8D85\u65F6\uFF09" : ""}`,
1260
1494
  deliveryGateReason: (command, exitCode, timedOut) => `FUNCTIONAL_TEST \u95E8\u7981\uFF1A\`${command}\` \u9000\u51FA\u7801=${exitCode}${timedOut ? "\uFF08\u8D85\u65F6\uFF09" : ""}`,
1261
- missingPythonEntrypoint: "\u7F3A\u5C11 Python \u5165\u53E3\uFF1A\u9700\u8981 src/main.py \u6216 src/<package>/__main__.py",
1495
+ missingPythonEntrypoint: "\u7F3A\u5C11 Python \u5165\u53E3\uFF1A\u9700\u8981 src/main.py\u3001src/<package>/__main__.py\uFF0C\u6216 src/cli.py \u7B49\u663E\u5F0F CLI \u6587\u4EF6",
1262
1496
  missingTypeScriptEntrypoint: "\u7F3A\u5C11 TypeScript \u5165\u53E3\uFF1A\u9700\u8981 package.json start/bin \u6216 src/main.ts\u3001src/index.ts\u3001src/main.tsx \u4E4B\u4E00",
1263
1497
  invalidPythonEntrypointSource: (path2) => `Python \u5165\u53E3\u6E90\u7801\u65E0\u6548\uFF1A${path2} \u5FC5\u987B\u662F\u771F\u5B9E CLI \u5165\u53E3\uFF0C\u81F3\u5C11\u5305\u542B def main(...)\u3001argparse.ArgumentParser \u6216 if __name__ == "__main__" \u8FD9\u7C7B\u5165\u53E3\u7ED3\u6784\uFF1B\u4EC5 import/comment \u7684\u5360\u4F4D\u6587\u4EF6\u4E0D\u80FD\u7B97\u53EF\u8FD0\u884C\u5E94\u7528\u3002`,
1264
1498
  entrypointHelpOutputMissing: (command) => `\u5165\u53E3\u63A2\u6D4B \`${command}\` \u867D\u7136\u9000\u51FA\u7801\u4E3A 0\uFF0C\u4F46\u6CA1\u6709\u8F93\u51FA\u6709\u610F\u4E49\u7684 help/usage \u6587\u672C\uFF1B\u5FC5\u987B\u5B9E\u73B0 --help\uFF0C\u4E0D\u80FD\u9760\u7A7A\u811A\u672C\u81EA\u7136\u9000\u51FA\u8FC7\u5173\u3002`,
@@ -1296,6 +1530,8 @@ var messages2 = {
1296
1530
  },
1297
1531
  prompts: {
1298
1532
  plannerSystem: (p) => buildPlannerSystem2(p),
1533
+ plannerPhasePlanSystem: (p) => buildPlannerPhasePlanSystem2(p),
1534
+ plannerPhaseDecomposeSystem: (p) => buildPlannerPhaseDecomposeSystem2(p),
1299
1535
  plannerSelfMode: `\u81EA\u4E3E\u6A21\u5F0F\u8986\u76D6\u89C4\u5219\uFF08\u4F18\u5148\u7EA7\u9AD8\u4E8E\u4E0A\u65B9\u4E0E\u4E4B\u51B2\u7A81\u7684 greenfield \u89C4\u5219\uFF09\uFF1A
1300
1536
  - \u76EE\u6807\u662F\u73B0\u6709 XCompiler \u4ED3\u5E93\u3002\u9664\u975E\u9700\u6C42\u660E\u786E\u8981\u6C42\u4FEE\u6539\uFF0C\u5426\u5219\u5FC5\u987B\u4FDD\u7559\u5F53\u524D package.json\u3001tsconfig\u3001bin\u3001CLI \u5165\u53E3\u3001\u6A21\u5757\u7ED3\u6784\u3001\u516C\u5171\u5BFC\u51FA\u548C\u8BBE\u8BA1\u6587\u6863\u3002
1301
1537
  - \u4E0D\u5F97\u4E3A\u4E86\u6EE1\u8DB3\u65B0\u5EFA\u5DE5\u7A0B\u5165\u53E3\u7EA6\u5B9A\u800C\u521B\u5EFA src/main.ts\uFF1B\u5FC5\u987B\u590D\u7528\u73B0\u6709 package.json \u58F0\u660E\u7684\u5165\u53E3\u3002
@@ -1321,6 +1557,7 @@ ${raw}
1321
1557
  - \u81F3\u5C11 1 \u4E2A quality\uFF1A\u8BE2\u95EE\u53EF\u91CF\u5316\u7684\u6027\u80FD\u3001\u5BB9\u91CF\u3001\u5E76\u53D1\u3001\u65F6\u5EF6\u3001\u51C6\u786E\u6027\u3001\u53EF\u9760\u6027\u6216\u5B89\u5168\u6307\u6807\uFF1B\u4E0D\u8981\u53EA\u95EE\u201C\u6027\u80FD\u6709\u4EC0\u4E48\u8981\u6C42\u201D\u3002
1322
1558
  - \u81F3\u5C11 1 \u4E2A extensibility\uFF1A\u8BE2\u95EE\u6700\u53EF\u80FD\u65B0\u589E\u7684\u4E1A\u52A1\u80FD\u529B\u3001\u6269\u5C55\u7EF4\u5EA6\u6216\u9700\u8981\u7A33\u5B9A\u4FDD\u7559\u7684\u63A5\u53E3\uFF0C\u4E0D\u8981\u6CDB\u95EE\u201C\u662F\u5426\u9700\u8981\u6269\u5C55\u6027\u201D\u3002
1323
1559
  - \u5982\u679C\u4EA4\u4ED8\u5F62\u6001\u4E0D\u660E\u786E\uFF0C\u5FC5\u987B\u5305\u542B 1 \u4E2A boundary \u95EE\u9898\uFF0C\u786E\u8BA4\u672C\u9879\u76EE\u5E94\u662F API library/SDK/\u8F6F\u4EF6\u5305\u3001\u53EF\u8FD0\u884C\u5E94\u7528/CLI/\u670D\u52A1\uFF0C\u8FD8\u662F\u4E8C\u8005\u517C\u5177\u7684 mixed \u4EA4\u4ED8\u3002
1560
+ - \u5982\u679C\u9700\u6C42\u9700\u8981\u8BBF\u95EE\u5916\u90E8 API/URL/\u7B2C\u4E09\u65B9\u6570\u636E\u6E90\uFF0C\u5FC5\u987B\u5305\u542B 1 \u4E2A data \u6216 boundary \u95EE\u9898\uFF0C\u786E\u8BA4\u7528\u6237\u662F\u5426\u5DF2\u6709\u53EF\u7528 API\u3001key\u3001token \u6216\u9274\u6743\u65B9\u5F0F\uFF1B\u82E5\u7528\u6237\u6CA1\u6709\u51ED\u8BC1\uFF0C\u672C\u671F\u9ED8\u8BA4\u4F18\u5148\u9009\u62E9\u516C\u5F00\u3001\u514D key/token\u3001\u53EF\u9A8C\u8BC1\u7684\u63A5\u53E3\uFF0C\u4E0D\u8981\u751F\u6210\u5360\u4F4D URL\u3002
1324
1561
  - \u6309\u963B\u585E\u7A0B\u5EA6\u6392\u5E8F\uFF1A\u5148\u95EE\u4F1A\u6539\u53D8\u6838\u5FC3\u529F\u80FD/\u6570\u636E\u6A21\u578B\u7684\u95EE\u9898\uFF0C\u518D\u95EE\u8303\u56F4\u4E0E\u8D28\u91CF\uFF0C\u6700\u540E\u95EE\u672A\u6765\u6269\u5C55\u3002
1325
1562
  - \u4E00\u9898\u53EA\u5305\u542B\u4E00\u4E2A\u4E3B\u8981\u51B3\u7B56\uFF0C\u7ED9\u51FA\u5FC5\u8981\u7684\u4E1A\u52A1\u9009\u9879\u6216\u793A\u4F8B\uFF0C\u7981\u6B62\u628A\u591A\u4E2A\u65E0\u5173\u95EE\u9898\u7528\u201C\u4EE5\u53CA/\u6216\u8005\u201D\u62FC\u6210\u4E00\u9898\u3002
1326
1563
  - \u6BCF\u4E2A\u95EE\u9898\u90FD\u5FC5\u987B\u9884\u751F\u6210 2-5 \u4E2A\u53EF\u884C\u56DE\u7B54\u8BBE\u5B9A\uFF0C\u6309\u4F18\u5148\u7EA7\u6392\u5E8F\u3002\u9009\u9879\u6570\u91CF\u4E0D\u662F\u56FA\u5B9A\u503C\uFF1A\u4E8C\u9009\u4E00\u573A\u666F\u7528 2 \u4E2A\uFF0C\u5E38\u89C1\u9ED8\u8BA4\u8BBE\u5B9A\u7528 3 \u4E2A\uFF0C\u53EA\u6709\u786E\u5B9E\u5B58\u5728 4-5 \u4E2A\u5F7C\u6B64\u4E0D\u540C\u7684\u53EF\u884C\u8BBE\u5B9A\u65F6\u624D\u751F\u6210 4-5 \u4E2A\uFF1B\u4E0D\u8981\u586B\u5145\u6216\u5F3A\u5236\u6BCF\u9898\u90FD\u662F 3 \u4E2A\u9009\u9879\u3002
@@ -1364,11 +1601,77 @@ ${opts.baseline || "\uFF08\u7F3A\u5C11\u57FA\u7EBF\u6458\u8981\uFF09"}
1364
1601
  - \u5982\u679C\u57FA\u7EBF\u91CC\u5DF2\u7ECF\u5B58\u5728\u76F8\u5173\u6587\u4EF6\uFF0C\u4F18\u5148\u5728\u539F\u6A21\u5757\u4E0A\u6269\u5C55/\u91CD\u6784\uFF0C\u4E0D\u8981\u65B0\u9020\u4E00\u5957\u884C\u4E3A\u91CD\u590D\u7684\u5F71\u5B50\u5B9E\u73B0\u3002
1365
1602
 
1366
1603
  \u8BF7\u6309\u7CFB\u7EDF\u89C4\u5219\u8F93\u51FA\u4E25\u683C JSON \u8BA1\u5212\u3002`,
1604
+ plannerPhasePlan: (raw, qa, addenda, opts = {}) => `\u539F\u59CB\u9700\u6C42\uFF1A
1605
+ """
1606
+ ${raw}
1607
+ """
1608
+
1609
+ \u6F84\u6E05\u95EE\u7B54\uFF1A
1610
+ ${qa || "\uFF08\u65E0\uFF09"}
1611
+
1612
+ ${addenda ? `\u7528\u6237\u8865\u5145\u9700\u6C42\uFF08\u9700\u4E25\u683C\u9075\u5B88\uFF0C\u4F18\u5148\u7EA7\u9AD8\u4E8E\u539F\u59CB\u63CF\u8FF0\u4E2D\u6A21\u7CCA\u7684\u90E8\u5206\uFF09\uFF1A
1613
+ """
1614
+ ${addenda}
1615
+ """
1616
+
1617
+ ` : ""}${opts.intent && opts.intent !== "greenfield" ? `\u589E\u91CF\u610F\u56FE\uFF1A${opts.intent}
1618
+
1619
+ \u8BF7\u5728\u73B0\u6709\u5DE5\u7A0B\u57FA\u7840\u4E0A\u751F\u6210 PhasePlan\uFF0C\u4F18\u5148\u590D\u7528\u5F53\u524D\u67B6\u6784\u3001\u6587\u4EF6\u3001\u6D4B\u8BD5\u4E0E\u4F9D\u8D56\u3002\u9664\u672C\u6B21\u9700\u6C42\u6D89\u53CA\u7684\u8303\u56F4\u5916\uFF0C\u9ED8\u8BA4\u4FDD\u6301\u65E2\u6709\u884C\u4E3A\u4E0D\u53D8\u3002
1620
+
1621
+ \u73B0\u6709\u5DE5\u7A0B\u57FA\u7EBF\uFF1A
1622
+ """
1623
+ ${opts.baseline || "\uFF08\u7F3A\u5C11\u57FA\u7EBF\u6458\u8981\uFF09"}
1624
+ """
1625
+
1626
+ ` : ""}\u8BF7\u5148\u53EA\u751F\u6210\u5927\u7684 PhasePlan\uFF1A
1627
+ - \u8BC4\u4F30\u9879\u76EE\u590D\u6742\u5EA6\u5E76\u51B3\u5B9A phase \u6570\u91CF\uFF1Asimple => \u53EA\u6709 P1 current\uFF1Bmoderate => P1 current + \u81F3\u5C11 P2 planned\uFF1Bcomplex => P1 current + \u81F3\u5C11 P2/P3 planned\u3002
1628
+ - P1 objective \u5FC5\u987B\u662F\u53EF\u72EC\u7ACB\u4EA4\u4ED8\u3001\u53EF\u9A8C\u8BC1\u7684\u6838\u5FC3\u529F\u80FD\u3002
1629
+ - P2/P3 \u53EA\u5199\u540E\u7EED\u589E\u5F3A\u76EE\u6807\u3001\u8303\u56F4\u3001\u4EA4\u4ED8\u7269\u548C\u9A8C\u8BC1\u95E8\u7981\uFF1B\u4E0D\u8981\u5C55\u5F00\u4EFB\u4F55 V \u6A21\u578B Step\u3002
1630
+ - \u6BCF\u4E2A phase \u7684 verificationGate \u5FC5\u987B\u8BF4\u660E\u5931\u8D25\u65F6\u628A\u5B8C\u6574\u9519\u8BEF\u65E5\u5FD7\u4EA4\u7ED9 Debugger\uFF0C\u5E76\u56DE\u9000\u5230\u5BF9\u5E94 V \u6A21\u578B\u9636\u6BB5\u540E\u91CD\u8DD1\u540E\u7EED\u9636\u6BB5\u3002
1631
+ - \u53EA\u8FD4\u56DE PhasePlan JSON\uFF0C\u7981\u6B62\u5305\u542B steps / architectureModules / dependencies\u3002`,
1632
+ plannerPhaseDecompose: (raw, qa, addenda, opts) => `\u539F\u59CB\u9700\u6C42\uFF1A
1633
+ """
1634
+ ${raw}
1635
+ """
1636
+
1637
+ \u6F84\u6E05\u95EE\u7B54\uFF1A
1638
+ ${qa || "\uFF08\u65E0\uFF09"}
1639
+
1640
+ ${addenda ? `\u7528\u6237\u8865\u5145\u9700\u6C42\uFF08\u9700\u4E25\u683C\u9075\u5B88\uFF0C\u4F18\u5148\u7EA7\u9AD8\u4E8E\u539F\u59CB\u63CF\u8FF0\u4E2D\u6A21\u7CCA\u7684\u90E8\u5206\uFF09\uFF1A
1641
+ """
1642
+ ${addenda}
1643
+ """
1644
+
1645
+ ` : ""}${opts.intent && opts.intent !== "greenfield" ? `\u589E\u91CF\u610F\u56FE\uFF1A${opts.intent}
1646
+
1647
+ \u8BF7\u5728\u73B0\u6709\u5DE5\u7A0B\u57FA\u7840\u4E0A\u751F\u6210\u5F53\u524D phase \u7684\u589E\u91CF V \u6A21\u578B StepPlan\uFF0C\u4F18\u5148\u590D\u7528\u5F53\u524D\u67B6\u6784\u3001\u6587\u4EF6\u3001\u6D4B\u8BD5\u4E0E\u4F9D\u8D56\u3002
1648
+
1649
+ \u73B0\u6709\u5DE5\u7A0B\u57FA\u7EBF\uFF1A
1650
+ """
1651
+ ${opts.baseline || "\uFF08\u7F3A\u5C11\u57FA\u7EBF\u6458\u8981\uFF09"}
1652
+ """
1653
+
1654
+ ` : ""}\u5DF2\u786E\u8BA4\u7684 PhasePlan\uFF1A
1655
+ """
1656
+ ${opts.phasePlan}
1657
+ """
1658
+
1659
+ \u5F53\u524D\u9700\u8981\u5C55\u5F00\u7684 phaseId\uFF1A${opts.phaseId}
1660
+
1661
+ \u8BF7\u53EA\u4E3A ${opts.phaseId} \u8F93\u51FA\u5B8C\u6574 V \u6A21\u578B StepPlan\uFF1A
1662
+ - steps \u4E2D\u6BCF\u4E2A Step.iterationId \u5FC5\u987B\u7B49\u4E8E "${opts.phaseId}"\u3002
1663
+ - \u7981\u6B62\u8F93\u51FA\u5176\u4ED6 planned phase \u7684 Step\uFF1BP2/P3 \u7684\u8BE6\u7EC6\u8BA1\u5212\u7559\u5230\u5B83\u4EEC\u6210\u4E3A current phase \u65F6\u518D\u751F\u6210\u3002
1664
+ - \u5982\u679C ${opts.phaseId} \u6A2A\u8DE8\u591A\u4E2A\u5173\u6CE8\u70B9\uFF08\u9886\u57DF\u903B\u8F91\u3001CLI/API\u3001\u6587\u4EF6 I/O\u3001\u5916\u90E8\u96C6\u6210\u3001\u6D41\u7A0B\u7F16\u6392\u3001\u6D4B\u8BD5\uFF09\uFF0C\u5FC5\u987B\u5728 architectureModules \u4E2D\u4F53\u73B0\u5F53\u524D phase \u7684\u6A21\u5757\u8FB9\u754C\uFF0C\u5E76\u5728 CODE/MODULE_TEST \u7684 subTasks \u4E0B\u5206\u89E3\u6A21\u5757\u7EA7\u5DE5\u4F5C\u3002
1665
+ - architectureModules.sourcePaths \u53EA\u80FD\u662F src/ \u4E0B\u7684\u4EA7\u54C1\u6E90\u7801\u6587\u4EF6\uFF1B\u4E0D\u8981\u628A tests/fixtures\u3001tests/utils\u3001\u6837\u4F8B\u6587\u4EF6\u3001\u76EE\u5F55\u6216\u6587\u6863\u767B\u8BB0\u4E3A\u67B6\u6784\u6A21\u5757\u3002
1666
+ - dependencies \u53EA\u5199\u5F53\u524D phase \u9700\u8981\u7684\u5305\u540D\uFF1BPython \u5FC5\u987B\u5305\u542B pytest\uFF1B\u4E0D\u8981\u8F93\u51FA requirements.txt\u3002
1667
+ - \u5F53\u524D phase \u5FC5\u987B\u5305\u542B\u6807\u51C6 V \u6A21\u578B 8 \u4E2A\u5B8F Step\uFF0C\u5E76\u6EE1\u8DB3\u540C\u6B65\u6D4B\u8BD5\u8BBE\u8BA1\u89C4\u5219\u3002
1668
+
1669
+ \u53EA\u8FD4\u56DE\u5F53\u524D phase \u7684\u4E25\u683C JSON StepPlan\u3002`,
1367
1670
  executorSystem: (p) => buildExecutorSystem2(p),
1368
1671
  executorDebugBlock: (reason, suggestions) => `
1369
1672
 
1370
1673
  \u6B63\u5904\u4E8E DEBUG \u91CD\u8BD5\u6A21\u5F0F\u3002\u4E0A\u4E00\u8F6E\u5931\u8D25\u539F\u56E0: ${reason}
1371
- DEBUG \u53EF\u4EE5\u4FEE\u6539\u5F53\u524D allowedWrites \u5185\u7684\u4E0A\u6E38\u6E90\u7801\u4E0E\u6D4B\u8BD5\u6587\u4EF6\uFF1B\u82E5\u5931\u8D25\u66B4\u9732\u7684\u662F\u5B9E\u73B0\u3001\u5951\u7EA6\u6216\u4E0B\u6E38\u8C03\u7528\u4E0D\u4E00\u81F4\uFF0C\u5FC5\u987B\u4FEE\u771F\u5B9E\u7F3A\u9677\uFF0C\u7981\u6B62\u901A\u8FC7\u524A\u5F31\u65AD\u8A00\u3001\u8DF3\u8FC7\u6D4B\u8BD5\u3001\u5220\u9664\u5931\u8D25\u7528\u4F8B\u6216\u53EA\u8FCE\u5408\u9519\u8BEF\u6D4B\u8BD5\u6765\u8FC7\u5173\u3002\u8BF7\u5305\u542B read_file/code_search \u5148\u5B9A\u4F4D\u95EE\u9898\uFF0C\u518D\u4EE5 apply_patch / replace_in_file / add_dependency \u4F5C\u6700\u5C0F\u4FEE\u6539\uFF0C\u6700\u540E run_tests \u9A8C\u8BC1\u3002\u5982\u679C\u5931\u8D25\u65E5\u5FD7\u663E\u793A\u7F51\u7EDC/API \u8C03\u7528\u5931\u8D25\uFF0C\u4E0D\u5141\u8BB8\u53EA\u505C\u7559\u5728\u63A2\u6D4B\u63A5\u53E3\uFF1A\u6700\u591A\u8FDE\u7EED\u6267\u884C 2 \u6B21 http_fetch \u63A2\u6D4B\uFF1BHTTP 2xx \u4F46 body \u4E3A\u7A7A\u6216\u683C\u5F0F\u4E0D\u53EF\u7528\u4E0D\u7B97\u53EF\u7528\u63A5\u53E3\uFF1B\u968F\u540E\u5FC5\u987B patch \u771F\u5B9E\u96C6\u6210\u4EE3\u7801\uFF0C\u5E76\u7528 run_program \u548C run_tests \u9A8C\u8BC1\u3002\u5165\u53E3\u4ECD\u8F93\u51FA\u7F51\u7EDC/API \u5931\u8D25\u65F6\u4E0D\u5F97 done=true\u3002` + (suggestions ? `
1674
+ DEBUG \u53EF\u4EE5\u4FEE\u6539\u5F53\u524D allowedWrites \u5185\u7684\u4E0A\u6E38\u6E90\u7801\u4E0E\u6D4B\u8BD5\u6587\u4EF6\uFF1B\u82E5\u5931\u8D25\u66B4\u9732\u7684\u662F\u5B9E\u73B0\u3001\u5951\u7EA6\u6216\u4E0B\u6E38\u8C03\u7528\u4E0D\u4E00\u81F4\uFF0C\u5FC5\u987B\u4FEE\u771F\u5B9E\u7F3A\u9677\uFF0C\u7981\u6B62\u901A\u8FC7\u524A\u5F31\u65AD\u8A00\u3001\u8DF3\u8FC7\u6D4B\u8BD5\u3001\u5220\u9664\u5931\u8D25\u7528\u4F8B\u6216\u53EA\u8FCE\u5408\u9519\u8BEF\u6D4B\u8BD5\u6765\u8FC7\u5173\u3002\u5982\u679C\u672C\u6B21\u56DE\u9000\u5904\u4E8E\u9700\u6C42/\u8BBE\u8BA1\u9636\u6BB5\uFF0C\u800C\u5177\u4F53\u6E90\u7801\u4FEE\u6539\u5C5E\u4E8E\u540E\u7EED V \u6A21\u578B Step \u4E14\u76EE\u6807\u6587\u4EF6\u4E0D\u5728\u5F53\u524D allowedWrites \u5185\uFF0C\u5E94\u66F4\u65B0\u5F53\u524D\u5951\u7EA6\u3001\u6D4B\u8BD5\u8BA1\u5212\u6216\u8BCA\u65AD\u4EA7\u7269\u5E76\u5B8C\u6210\u5F53\u524D Step\uFF0C\u8BA9\u540E\u7EED CODE Step \u5B9E\u73B0\uFF1B\u4E0D\u8981\u5C1D\u8BD5\u88AB\u62D2\u7EDD\u7684\u8D8A\u6743\u5199\u5165\u3002\u82E5\u5931\u8D25\u662F\u7B2C\u4E09\u65B9\u4F9D\u8D56\u7F3A\u5931\u6216\u5E93\u9009\u578B\u9519\u8BEF\uFF0C\u5FC5\u987B\u7528 add_dependency \u5199\u5165\u771F\u5B9E\u5305\u540D\uFF0C\u6216\u628A\u6E90\u7801\u6539\u56DE HIGH_LEVEL_DESIGN \u9009\u5B9A\u7684\u771F\u5B9E\u5E93\uFF1B\u4E25\u7981\u5728 src/ \u751F\u4EA7\u4EE3\u7801\u91CC try/except ImportError \u540E\u4F2A\u9020 module\u3001fake class/function\u3001\u7A7A\u5B9E\u73B0\u6216 fallback mock \u6765\u7ED5\u8FC7\u9519\u8BEF\u3002\u8BF7\u5305\u542B read_file/code_search \u5148\u5B9A\u4F4D\u95EE\u9898\uFF0C\u518D\u4EE5 apply_patch / replace_in_file / add_dependency \u4F5C\u6700\u5C0F\u4FEE\u6539\uFF0C\u6700\u540E run_tests \u9A8C\u8BC1\u3002DEBUG \u91CD\u8BD5\u4E0D\u80FD\u53EA\u9760\u53EA\u8BFB\u68C0\u67E5\u5C31\u6807\u8BB0\u5B8C\u6210\uFF1A\u672C\u6B21\u91CD\u8BD5\u5FC5\u987B\u4EA7\u751F\u4E00\u6B21\u6210\u529F\u7684\u4FEE\u590D\u52A8\u4F5C\uFF0C\u6216\u4E00\u6B21\u6210\u529F\u7684\u9A8C\u8BC1\u547D\u4EE4\u3002\u5982\u679C\u4E0A\u4E00\u8F6E\u5931\u8D25\u539F\u56E0\u5305\u542B repeated read-only/probe actions\uFF0C\u8BF7\u628A\u5DF2\u6709 failure log \u89C6\u4E3A\u8DB3\u591F\u4E0A\u4E0B\u6587\uFF0C\u4E0B\u4E00\u6B65\u76F4\u63A5 patch/write/\u6539\u4F9D\u8D56\u6216\u6267\u884C\u9A8C\u8BC1\u547D\u4EE4\u3002\u5F53\u6D4B\u8BD5\u5DF2\u6B63\u5E38\u6267\u884C\u4F46\u5931\u8D25\u70B9\u662F\u8FD4\u56DE\u884C\u4E3A\u65AD\u8A00\u65F6\uFF0C\u7981\u6B62\u53CD\u590D\u91CD\u5199 fixture \u6216\u6837\u4F8B\u3002\u53EA\u6709\u8BC1\u636E\u660E\u786E\u662F\u6587\u4EF6\u7F3A\u5931\u3001fixture \u683C\u5F0F\u9519\u8BEF\u6216 fixture \u672C\u8EAB\u89E3\u6790\u5931\u8D25\u65F6\u624D\u4FEE\u6539 fixture\uFF1B\u5426\u5219\u5E94\u4FEE\u5B9E\u73B0\u3001\u63A5\u53E3\u5951\u7EA6\u3001\u4F9D\u8D56\u9009\u578B\u6216\u786E\u5B9E\u9519\u8BEF\u7684\u65AD\u8A00\u3002\u5982\u679C\u5931\u8D25\u65E5\u5FD7\u663E\u793A\u7F51\u7EDC/API \u8C03\u7528\u5931\u8D25\uFF0C\u4E0D\u5141\u8BB8\u53EA\u505C\u7559\u5728\u63A2\u6D4B\u63A5\u53E3\uFF1A\u6700\u591A\u8FDE\u7EED\u6267\u884C 2 \u6B21 http_fetch \u63A2\u6D4B\uFF1BHTTP 2xx \u4F46 body \u4E3A\u7A7A\u6216\u683C\u5F0F\u4E0D\u53EF\u7528\u4E0D\u7B97\u53EF\u7528\u63A5\u53E3\uFF1B\u968F\u540E\u5FC5\u987B patch \u771F\u5B9E\u96C6\u6210\u4EE3\u7801\uFF0C\u5E76\u7528 run_program \u548C run_tests \u9A8C\u8BC1\u3002\u5165\u53E3\u4ECD\u8F93\u51FA\u7F51\u7EDC/API \u5931\u8D25\u65F6\u4E0D\u5F97 done=true\u3002` + (suggestions ? `
1372
1675
 
1373
1676
  ${suggestions}` : ""),
1374
1677
  executorGlobalBlock: (globalPrompt) => `
@@ -1382,14 +1685,17 @@ ${sp}`,
1382
1685
  executorUserPromptOutro: "\u73B0\u5728\u6309\u534F\u8BAE\u8FD4\u56DE\u7B2C\u4E00\u8F6E JSON\u3002",
1383
1686
  executorFeedbackHeader: "\u672C\u8F6E\u5DE5\u5177\u7ED3\u679C\uFF1A",
1384
1687
  executorFeedbackVerifyOk: "outputs \u6821\u9A8C\u901A\u8FC7\u3002\u5982\u5DF2\u5B8C\u6210\uFF0C\u8BF7\u628A done \u8BBE\u4E3A true \u4E14 actions=[]\u3002",
1385
- executorFeedbackVerifyMissing: (paths) => `outputs \u4ECD\u7F3A\u5931\uFF1A${paths}\u3002\u8BF7\u7EE7\u7EED\u3002`
1688
+ executorFeedbackVerifyMissing: (paths) => `outputs \u4ECD\u7F3A\u5931\uFF1A${paths}\u3002\u8BF7\u7EE7\u7EED\u3002`,
1689
+ executorFeedbackReadOnlyLoopWarning: (rounds, targets) => `\u5FAA\u73AF\u95E8\u7981\u8B66\u544A\uFF1A\u6700\u8FD1 ${rounds} \u8F6E\u53EA\u8C03\u7528\u4E86\u8BFB\u53D6/\u63A2\u6D4B\u5DE5\u5177` + (targets ? `\uFF08${targets}\uFF09` : "") + "\u3002\u4E0B\u4E00\u8F6E\u5FC5\u987B\u5305\u542B\u4E00\u6B21\u6210\u529F\u7684\u4FEE\u590D\u52A8\u4F5C\uFF08apply_patch / replace_in_file / write_file / add_dependency\uFF09\u6216\u660E\u786E\u7684\u9A8C\u8BC1\u52A8\u4F5C\uFF08run_tests / run_program\uFF09\u3002\u4E0D\u8981\u7EE7\u7EED\u53EA\u8C03\u7528 read_file\u3001list_dir\u3001code_search \u6216 http_fetch\u3002",
1690
+ executorFeedbackReadOnlyRecoveryRequired: "\u53EA\u8BFB\u6062\u590D\u6A21\u5F0F\u5DF2\u542F\u7528\uFF1A\u4E0A\u4E00\u8F6E\u5DF2\u7ECF\u56E0\u4E3A\u6301\u7EED\u63A2\u6D4B\u5931\u8D25\u3002\u672C\u8F6E\u5FC5\u987B\u57FA\u4E8E\u5DF2\u6709 failure log \u76F4\u63A5 patch/write/\u6539\u4F9D\u8D56\u6216\u6267\u884C\u9A8C\u8BC1\uFF1B\u5982\u679C\u4E0B\u4E00\u8F6E\u4ECD\u7136\u53EA\u6709\u53EA\u8BFB/\u63A2\u6D4B\u52A8\u4F5C\uFF0C\u672C\u6B21\u91CD\u8BD5\u4F1A\u5931\u8D25\u5E76\u56DE\u9000\u3002",
1691
+ executorFeedbackRepairEvidenceMissing: "DEBUG \u5B8C\u6210\u65E0\u6548\uFF1A\u672C\u6B21\u91CD\u8BD5\u8FD8\u6CA1\u6709\u4EA7\u751F\u4FEE\u590D\u8BC1\u636E\u3002\u8BBE\u7F6E done=true \u524D\uFF0C\u5FC5\u987B\u81F3\u5C11\u5B8C\u6210\u4E00\u6B21\u6210\u529F\u7684\u4FEE\u590D\u52A8\u4F5C\u6216\u6210\u529F\u7684\u9A8C\u8BC1\u8FD0\u884C\uFF1B\u5426\u5219\u53EA\u80FD\u5728 thoughts \u4E2D\u7ED9\u51FA\u5177\u4F53 blocker \u540E\u505C\u6B62\u3002"
1386
1692
  },
1387
1693
  skills: {
1388
1694
  patcher: "\u901A\u8FC7 apply_patch / replace_in_file \u5BF9\u5DF2\u6709\u6587\u4EF6\u505A\u5C0F\u6539\u52A8\uFF0C\u7981\u6B62\u6574\u6587\u4EF6\u8986\u76D6\u3002",
1389
1695
  author: "\u901A\u8FC7 write_file \u521B\u5EFA\u65B0\u6587\u4EF6\uFF1B\u4F18\u5148\u653E\u5728\u5F53\u524D Step writable allowlist \u5185\u3002",
1390
- tester: '\u7F16\u5199\u5E76\u8FD0\u884C pytest \u6D4B\u8BD5\uFF0C\u9A8C\u8BC1\u51FD\u6570\u884C\u4E3A\uFF1B\u5931\u8D25\u65F6\u901A\u8FC7 analyze_error \u89E3\u6790\u3002\u3010fixture \u81EA\u5305\u542B\u3011\u6D4B\u8BD5**\u4E25\u7981**\u76F4\u63A5 open() \u78C1\u76D8\u4E0A\u4E0D\u5B58\u5728\u7684\u6837\u4F8B\u6587\u4EF6\uFF08\u5982 "test.dbc"\uFF09\uFF1B\u82E5\u88AB\u6D4B\u51FD\u6570\u9700\u8981\u6587\u4EF6\u8F93\u5165\uFF0C\u8BF7\u7528 pytest \u7684 tmp_path fixture \u5728\u6D4B\u8BD5\u91CC\u4E34\u65F6\u6784\u9020\u5185\u5BB9\uFF0C\u6216\u7528 write_file \u76F4\u63A5\u5199\u5230 tests/fixtures/<name>\u2014\u2014\u6D4B\u8BD5/DEBUG \u9636\u6BB5\u8BE5\u76EE\u5F55\u5DF2\u9ED8\u8BA4\u653E\u5F00\u5199\u6743\u9650\uFF0C\u5B50\u76EE\u5F55\u81EA\u52A8 mkdir -p\uFF0C**\u65E0\u9700**\u63D0\u524D\u628A fixture \u8DEF\u5F84\u767B\u8BB0\u5230 outputs\u3002\u751F\u6210\u6D4B\u8BD5\u65F6\u52A1\u5FC5\u540C\u65F6\u8F93\u51FA\u5168\u90E8\u4F9D\u8D56\u8D44\u6E90\uFF0C\u907F\u514D\u540E\u7EED Debugger \u56E0 FileNotFoundError \u53CD\u590D\u91CD\u8BD5\u3002\u3010fixture \u8FED\u4EE3\u3011\u82E5\u6D4B\u8BD5\u8FD0\u884C\u4E2D\u88AB\u6D4B\u51FD\u6570\u62A5"Invalid syntax / Parse error / Malformed"\u7B49\u89E3\u6790\u9519\u8BEF\uFF0C\u8BF4\u660E\u4F60\u5199\u51FA\u7684 fixture \u5185\u5BB9\u4E0D\u5408\u8BE5\u683C\u5F0F spec\uFF1Aread_file \u770B\u6E05\uFF0Cwrite_file \u6574\u6587\u4EF6\u91CD\u5199\u4E3A\u5408\u6CD5\u6837\u4F8B\uFF0C\u518D run_tests\uFF0C\u4E25\u7981\u53BB\u6539\u88AB\u6D4B\u6A21\u5757\u6216\u65AD\u8A00\u3002',
1696
+ tester: '\u7F16\u5199\u5E76\u8FD0\u884C pytest \u6D4B\u8BD5\uFF0C\u9A8C\u8BC1\u51FD\u6570\u884C\u4E3A\uFF1B\u5931\u8D25\u65F6\u901A\u8FC7 analyze_error \u89E3\u6790\u3002\u3010fixture \u81EA\u5305\u542B\u3011\u6D4B\u8BD5**\u4E25\u7981**\u76F4\u63A5 open() \u78C1\u76D8\u4E0A\u4E0D\u5B58\u5728\u7684\u6837\u4F8B\u6587\u4EF6\u3002\u82E5\u88AB\u6D4B\u51FD\u6570\u9700\u8981\u6587\u4EF6\u8F93\u5165\uFF0C\u4F18\u5148\u590D\u7528\u7528\u6237/\u5DE5\u4F5C\u533A\u771F\u5B9E\u6837\u4F8B\uFF1B\u6CA1\u6709\u6837\u4F8B\u65F6\u7528 http_fetch \u83B7\u53D6\u5B98\u65B9\u6587\u6863\u3001\u4E0A\u6E38\u4ED3\u5E93\u6216\u516C\u5F00\u6807\u51C6\u4E2D\u7684\u5C0F\u578B\u53C2\u8003\u6837\u4F8B\uFF0C\u4FDD\u5B58\u5230 tests/fixtures/<name> \u5E76\u8BB0\u5F55\u6765\u6E90\uFF1B\u53EA\u6709 CSV/JSON/INI \u7B49\u7B80\u5355\u6587\u672C\u683C\u5F0F\u624D\u53EF\u5728 pytest tmp_path \u4E2D\u6784\u9020\u6700\u5C0F\u6837\u4F8B\u5E76\u7ACB\u523B run_tests\u3002\u6D4B\u8BD5/DEBUG \u9636\u6BB5 tests/fixtures/ \u5DF2\u9ED8\u8BA4\u653E\u5F00\u5199\u6743\u9650\uFF0C\u5B50\u76EE\u5F55\u81EA\u52A8 mkdir -p\uFF0C**\u65E0\u9700**\u63D0\u524D\u628A fixture \u8DEF\u5F84\u767B\u8BB0\u5230 outputs\u3002\u751F\u6210\u6D4B\u8BD5\u65F6\u52A1\u5FC5\u540C\u65F6\u8F93\u51FA\u5168\u90E8\u4F9D\u8D56\u8D44\u6E90\uFF0C\u907F\u514D\u540E\u7EED Debugger \u56E0 FileNotFoundError \u53CD\u590D\u91CD\u8BD5\u3002\u3010fixture \u8FED\u4EE3\u3011\u82E5\u6D4B\u8BD5\u8FD0\u884C\u4E2D\u88AB\u6D4B\u51FD\u6570\u62A5"Invalid syntax / Parse error / Malformed"\u7B49\u89E3\u6790\u9519\u8BEF\uFF0C\u8BF4\u660E\u4F60\u5199\u51FA\u7684 fixture \u5185\u5BB9\u4E0D\u5408\u8BE5\u683C\u5F0F spec\uFF1Aread_file \u770B\u6E05\u540E\uFF0C\u4F18\u5148\u4F7F\u7528\u7528\u6237\u6837\u4F8B\u6216 http_fetch \u62C9\u53D6\u7684\u6743\u5A01\u53C2\u8003\u6837\u4F8B\u91CD\u5199\uFF0C\u518D run_tests\u3002\u590D\u6742\u9886\u57DF\u683C\u5F0F\u8FDE\u7EED\u5931\u8D25\u540E\u5FC5\u987B\u505C\u6B62\u51ED\u8BB0\u5FC6\u751F\u6210\uFF0C\u6539\u4E3A\u8BF7\u6C42\u7528\u6237\u6837\u4F8B\u6216\u7F51\u7EDC\u53C2\u8003\uFF1B\u4E25\u7981\u53BB\u6539\u88AB\u6D4B\u6A21\u5757\u6216\u65AD\u8A00\u3002',
1391
1697
  dep_resolver: "\u5F53\u51FA\u73B0 ModuleNotFoundError \u65F6\uFF0C\u7528 add_dependency \u5199\u56DE requirements.txt \u5E76\u91CD\u5EFA\u6C99\u76D2\u3002",
1392
- debugger: '\u5148 run_tests / run_python \u590D\u73B0\u9519\u8BEF \u2192 analyze_error \u2192 patch/replace_in_file \u4FEE\u590D \u2192 \u518D\u6B21 run_tests\u3002\u6BCF\u6B21\u53EA\u505A\u6700\u5C0F\u4FEE\u6539\u3002\u3010\u7F51\u7EDC/API \u5931\u8D25\u3011\u5B9A\u4F4D\u5931\u8D25 URL \u540E\uFF0C\u53EA\u5141\u8BB8\u5C11\u91CF\u63A2\u6D4B\u66FF\u4EE3 API\uFF0C\u968F\u540E\u5FC5\u987B patch \u6E90\u7801\u5E76\u7528 run_program \u8BC1\u660E\u5165\u53E3\u4E0D\u518D\u8F93\u51FA API \u5931\u8D25\u3002\u3010\u91CD\u8981\u3011\u540C\u4E00\u6587\u4EF6\u4E0A replace_in_file \u8FDE\u7EED\u5931\u8D25 2 \u6B21\u4EE5\u4E0A\u8BF7\u7ACB\u5373 read_file\uFF0C\u518D\u7528 patch \u6216\u5728\u5F53\u524D\u8FD0\u884C\u65F6 chunk limit \u5185\u6574\u6587\u4EF6\u91CD\u5199\uFF0C\u4E0D\u8981\u53CD\u590D\u731C\u6D4B find \u5B57\u7B26\u4E32\u3002\u3010\u7981\u6B62 no-op\u3011replace_in_file \u7684 find \u4E0E replace \u5FC5\u987B\u4E0D\u540C\u2014\u2014\u82E5\u4F60\u53EA\u662F\u60F3"\u786E\u8BA4"\u67D0\u6BB5\u4EE3\u7801\uFF0C\u8BF7\u7528 read_file\uFF0C\u4E0D\u8981\u63D0\u4EA4\u76F8\u540C\u5B57\u7B26\u4E32\u7684\u66FF\u6362\u3002',
1698
+ debugger: '\u5148 run_tests / run_python \u590D\u73B0\u9519\u8BEF \u2192 analyze_error \u2192 patch/replace_in_file/add_dependency \u4FEE\u590D \u2192 \u518D\u6B21 run_tests\u3002\u6BCF\u6B21\u53EA\u505A\u6700\u5C0F\u4FEE\u6539\u3002\u3010\u4F9D\u8D56\u7F3A\u5931\u3011\u5FC5\u987B\u6DFB\u52A0\u771F\u5B9E\u4F9D\u8D56\u6216\u6539\u7528\u8BBE\u8BA1\u9009\u5B9A\u7684\u771F\u5B9E\u5E93\uFF0C\u7981\u6B62\u5728 src/ \u751F\u4EA7\u4EE3\u7801\u91CC\u4F2A\u9020 module\u3001fake class/function\u3001\u7A7A\u5B9E\u73B0\u6216 fallback mock\u3002\u3010Fixture \u7EAA\u5F8B\u3011\u5982\u679C\u6D4B\u8BD5\u5931\u8D25\u662F\u884C\u4E3A\u65AD\u8A00\u5931\u8D25\uFF0C\u4E0D\u8981\u6301\u7EED\u91CD\u5199 fixture\uFF1B\u53EA\u6709\u660E\u786E\u7F3A\u6587\u4EF6\u3001fixture \u683C\u5F0F\u9519\u8BEF\u6216 fixture \u89E3\u6790\u9519\u8BEF\u65F6\u624D\u6539 fixture\uFF0C\u5426\u5219\u4FEE\u6E90\u7801\u3001\u5951\u7EA6\u3001\u4F9D\u8D56\u6216\u9519\u8BEF\u65AD\u8A00\u3002\u3010\u7F51\u7EDC/API \u5931\u8D25\u3011\u5B9A\u4F4D\u5931\u8D25 URL \u540E\uFF0C\u53EA\u5141\u8BB8\u5C11\u91CF\u63A2\u6D4B\u66FF\u4EE3 API\uFF0C\u968F\u540E\u5FC5\u987B patch \u6E90\u7801\u5E76\u7528 run_program \u8BC1\u660E\u5165\u53E3\u4E0D\u518D\u8F93\u51FA API \u5931\u8D25\u3002\u3010\u91CD\u8981\u3011\u540C\u4E00\u6587\u4EF6\u4E0A replace_in_file \u8FDE\u7EED\u5931\u8D25 2 \u6B21\u4EE5\u4E0A\u8BF7\u7ACB\u5373 read_file\uFF0C\u518D\u7528 patch \u6216\u5728\u5F53\u524D\u8FD0\u884C\u65F6 chunk limit \u5185\u6574\u6587\u4EF6\u91CD\u5199\uFF0C\u4E0D\u8981\u53CD\u590D\u731C\u6D4B find \u5B57\u7B26\u4E32\u3002\u3010\u7981\u6B62 no-op\u3011replace_in_file \u7684 find \u4E0E replace \u5FC5\u987B\u4E0D\u540C\u2014\u2014\u82E5\u4F60\u53EA\u662F\u60F3"\u786E\u8BA4"\u67D0\u6BB5\u4EE3\u7801\uFF0C\u8BF7\u7528 read_file\uFF0C\u4E0D\u8981\u63D0\u4EA4\u76F8\u540C\u5B57\u7B26\u4E32\u7684\u66FF\u6362\u3002',
1393
1699
  refactorer: "\u91CD\u6784\u5FC5\u987B\u4FDD\u8BC1\u884C\u4E3A\u4E0D\u53D8\uFF1B\u5148\u8DD1\u56DE\u5F52\u6D4B\u8BD5 \u2192 \u4FEE\u6539 \u2192 \u518D\u8DD1\u56DE\u5F52\u6D4B\u8BD5\u3002"
1394
1700
  },
1395
1701
  doctor: {
@@ -1412,7 +1718,7 @@ ${sp}`,
1412
1718
  ollamaReachable: (baseUrl, n) => `ollama \u53EF\u8FBE @ ${baseUrl}\uFF08\u5171 ${n} \u4E2A\u6A21\u578B\uFF09`,
1413
1719
  ollamaModelMissing: (provider, model, baseUrl) => `provider "${provider}"\uFF1A\u6A21\u578B "${model}" \u672A\u5B89\u88C5\u4E8E ${baseUrl}\uFF08\u8BF7\u6267\u884C \`ollama pull ${model}\`\uFF09`,
1414
1720
  ollamaModelOk: (provider, model) => `provider "${provider}"\uFF1A\u6A21\u578B "${model}" \u53EF\u7528`,
1415
- openaiKeyMissing: (provider) => `provider "${provider}"\uFF1Aapi_key \u4E3A\u7A7A\uFF08\u8BF7\u8BBE\u7F6E OPENAI_API_KEY \u6216 config.llm.providers.${provider}.api_key\uFF09`,
1721
+ openaiKeyMissing: (provider) => `provider "${provider}"\uFF1Aapi_key \u4E3A\u7A7A\uFF08\u8BF7\u8BBE\u7F6E\u8BE5 provider \u5BF9\u5E94\u7684\u73AF\u5883\u53D8\u91CF\uFF0C\u4F8B\u5982 OPENROUTER_API_KEY\uFF0C\u6216 config.llm.providers.${provider}.api_key\uFF09`,
1416
1722
  openaiReachable: (provider, baseUrl) => `provider "${provider}"\uFF1AOpenAI \u7AEF\u70B9\u53EF\u8FBE @ ${baseUrl}`,
1417
1723
  openaiUnreachable: (provider, baseUrl, msg) => `provider "${provider}"\uFF1AOpenAI \u7AEF\u70B9\u4E0D\u53EF\u8FBE @ ${baseUrl} \u2014\u2014 ${msg}`,
1418
1724
  openaiModelListMissing: (provider, model) => `provider "${provider}"\uFF1A/models \u54CD\u5E94\u4E2D\u672A\u5217\u51FA "${model}"\uFF08\u82E5\u4F60\u7684\u8D26\u53F7\u6709\u8BBF\u95EE\u6743\u9650\u4ECD\u53EF\u6B63\u5E38\u8C03\u7528\uFF09`,
@@ -1450,7 +1756,7 @@ function t() {
1450
1756
  }
1451
1757
 
1452
1758
  // src/version.ts
1453
- var XCOMPILER_VERSION = "0.2.2";
1759
+ var XCOMPILER_VERSION = "0.2.3";
1454
1760
  var XCOMPILER_PLUGIN_API_VERSION = 1;
1455
1761
 
1456
1762
  // src/plugins/compatibility.ts