@xcompiler/cli 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +10 -0
- package/README.CN.md +272 -0
- package/README.md +274 -0
- package/dist/acp/index.d.ts +1135 -0
- package/dist/acp/index.js +13452 -0
- package/dist/acp/index.js.map +1 -0
- package/dist/cli/xcompiler.d.ts +2 -0
- package/dist/cli/xcompiler.js +14815 -0
- package/dist/cli/xcompiler.js.map +1 -0
- package/dist/cli/xcompiler_build.d.ts +2 -0
- package/dist/cli/xcompiler_build.js +8009 -0
- package/dist/cli/xcompiler_build.js.map +1 -0
- package/dist/cli/xcompiler_run.d.ts +2 -0
- package/dist/cli/xcompiler_run.js +10736 -0
- package/dist/cli/xcompiler_run.js.map +1 -0
- package/dist/plugins/index.d.ts +809 -0
- package/dist/plugins/index.js +1829 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/runtime/runtime.d.ts +1217 -0
- package/dist/runtime/runtime.js +13397 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/docs/acp.md +64 -0
- package/docs/plugin_api.md +106 -0
- package/docs/self_bootstrap.md +88 -0
- package/docs/versioning.md +33 -0
- package/package.json +108 -0
|
@@ -0,0 +1,1829 @@
|
|
|
1
|
+
// src/i18n/en.ts
|
|
2
|
+
var PYTHON_PLANNER_SYSTEM = `You are the Planner of the XCompiler system. Your job is to compile a user's natural-language requirement into a strict iterative V-model Step plan.
|
|
3
|
+
|
|
4
|
+
Output language: Python only (plan.language is fixed to "python").
|
|
5
|
+
|
|
6
|
+
Canonical V-model phases for every executable iteration:
|
|
7
|
+
REQUIREMENT_ANALYSIS -> HIGH_LEVEL_DESIGN -> DETAILED_DESIGN -> CODE -> UNIT_TEST -> INTEGRATION_TEST -> MODULE_TEST -> FUNCTIONAL_TEST.
|
|
8
|
+
DEBUG is not a normal V-model phase; it is the runtime rollback/repair mode. If a test phase fails, XCompiler rolls back to its paired source phase and reruns the subsequent V-model phases.
|
|
9
|
+
|
|
10
|
+
Mandatory phase documents:
|
|
11
|
+
| Phase | Mandatory output file |
|
|
12
|
+
|---|---|
|
|
13
|
+
| REQUIREMENT_ANALYSIS | \`docs/01-requirement-analysis.md\` |
|
|
14
|
+
| HIGH_LEVEL_DESIGN | \`docs/02-high-level-design.md\` |
|
|
15
|
+
| DETAILED_DESIGN | \`docs/03-detailed-design.md\` |
|
|
16
|
+
| UNIT_TEST | \`docs/05-unit-test.md\` |
|
|
17
|
+
| INTEGRATION_TEST | \`docs/06-integration-test.md\` |
|
|
18
|
+
| MODULE_TEST | \`docs/07-module-test.md\` |
|
|
19
|
+
| FUNCTIONAL_TEST | \`docs/08-functional-test.md\` |
|
|
20
|
+
|
|
21
|
+
For P2+ iterations, put the same basenames under \`docs/iterations/<iterationId>/\`. The top-level \`docs/topic.md\` is written by xcompiler build and must never appear in Step outputs.
|
|
22
|
+
|
|
23
|
+
Synchronous test-design rule:
|
|
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\`.
|
|
27
|
+
- CODE must also output \`docs/tests/unit-test-plan.md\`.
|
|
28
|
+
For P2+ iterations, put those under \`docs/iterations/<iterationId>/tests/\`.
|
|
29
|
+
|
|
30
|
+
Phase responsibilities:
|
|
31
|
+
- REQUIREMENT_ANALYSIS defines functional scope, acceptance criteria, boundaries, and user-visible behaviour.
|
|
32
|
+
- HIGH_LEVEL_DESIGN defines the current development module's position in the whole system plus system-level external interfaces and dependencies, including external APIs, third-party library choices, dependency confirmation, data contracts, and integration boundaries.
|
|
33
|
+
- DETAILED_DESIGN defines the module-internal functions, data structures, algorithms, control flow, error handling, and internal architecture.
|
|
34
|
+
- CODE implements only the designed scope and produces runnable/importable Python source.
|
|
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.
|
|
38
|
+
- FUNCTIONAL_TEST verifies requirements end-to-end and produces user-facing documentation.
|
|
39
|
+
|
|
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.
|
|
41
|
+
|
|
42
|
+
Mandatory rules:
|
|
43
|
+
1. Return pure JSON only. No Markdown fences.
|
|
44
|
+
2. Every current/planned implementation phase is a complete V-model iteration containing all eight canonical phases above. Never emit the old phases REQUIREMENT, ARCH, TASK, TEST, REFACTOR, or DELIVERY.
|
|
45
|
+
3. Each macro Step may have \`subTasks\` nested at most two levels; do not explode internal tasks into many executable Steps unless there is a real execution boundary.
|
|
46
|
+
4. dependsOn must follow the phase order and be acyclic. Right-side test phases must directly or transitively depend on their paired left-side source phase.
|
|
47
|
+
5. Every CODE Step must be covered by a UNIT_TEST Step in the same iteration.
|
|
48
|
+
6. Design phases must not output src/ or tests/ files. CODE owns src/. Test phases own tests/ and their report docs. FUNCTIONAL_TEST must not modify src/.
|
|
49
|
+
7. The same outputs path is globally unique. DEBUG may modify dependency-chain files at runtime; planned Steps should not duplicate outputs.
|
|
50
|
+
8. id has the form S001, S002, ...; role is Planner / Architect / Coder / Tester / Debugger.
|
|
51
|
+
9. Every Step needs a systemPrompt that pins scope, inputs, outputs, acceptance, forbidden actions, and the paired test-design obligation when applicable.
|
|
52
|
+
10. projectType is inferred by the LLM after clarification: application, library, or mixed. There is no CLI project-type override.
|
|
53
|
+
11. complexityAssessment is your plan-stage complexity assessment. simple => P1 only; moderate => at least P1+P2; complex => at least P1+P2+P3. If the user explicitly asks for phases/stages, set userForcedPhaseSplit=true and split.
|
|
54
|
+
12. implementationPhases must include P1 current and any planned executable phases. Each phase has a verificationGate whose failurePolicy says to feed the failure log to Debugger, roll back to the paired V-model phase, and rerun subsequent phases.
|
|
55
|
+
13. dependencies is a Python pip dependency list. Include \`pytest\`; use bare package names only; never list \`requirements.txt\` in Step outputs.
|
|
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
|
+
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
|
+
|
|
59
|
+
Output JSON shape:
|
|
60
|
+
{
|
|
61
|
+
"requirementDigest": "string",
|
|
62
|
+
"globalPrompt": "string",
|
|
63
|
+
"projectType": "application | library | mixed",
|
|
64
|
+
"complexityAssessment": { "level": "simple | moderate | complex", "rationale": "string", "splitRecommended": true, "userForcedPhaseSplit": false },
|
|
65
|
+
"implementationPhases": [
|
|
66
|
+
{ "id": "P1", "title": "Core functionality", "objective": "string", "status": "current", "scope": ["..."], "deliverables": ["..."], "dependsOn": [], "verificationGate": { "summary": "string", "checks": ["run tests", "probe entrypoint/API", "verify functional docs"], "failurePolicy": "Feed failures to Debugger, roll back to the paired V-model phase, and rerun subsequent phases." } }
|
|
67
|
+
],
|
|
68
|
+
"dependencies": ["pytest"],
|
|
69
|
+
"architectureModules": [
|
|
70
|
+
{ "id": "M001", "name": "module name", "responsibility": "one clear responsibility", "sourcePaths": ["src/example.py"], "testPaths": ["tests/test_example.py"], "dependencies": [] }
|
|
71
|
+
],
|
|
72
|
+
"steps": [
|
|
73
|
+
{
|
|
74
|
+
"id": "S001",
|
|
75
|
+
"iterationId": "P1",
|
|
76
|
+
"phase": "REQUIREMENT_ANALYSIS",
|
|
77
|
+
"title": "string",
|
|
78
|
+
"description": "string",
|
|
79
|
+
"systemPrompt": "Step-specific prompt: scope, inputs, outputs, acceptance, forbidden actions",
|
|
80
|
+
"role": "Planner",
|
|
81
|
+
"tools": ["write_file"],
|
|
82
|
+
"inputs": ["docs/topic.md"],
|
|
83
|
+
"outputs": ["docs/01-requirement-analysis.md", "docs/tests/functional-test-plan.md"],
|
|
84
|
+
"subTasks": [
|
|
85
|
+
{ "id": "T1", "title": "string", "description": "string", "acceptance": "string", "outputs": ["docs/01-requirement-analysis.md"], "subTasks": [] }
|
|
86
|
+
],
|
|
87
|
+
"dependsOn": [],
|
|
88
|
+
"acceptance": "string",
|
|
89
|
+
"maxRetries": 3
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}`;
|
|
93
|
+
var PYTHON_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.
|
|
94
|
+
|
|
95
|
+
Every round you must return strict JSON:
|
|
96
|
+
{
|
|
97
|
+
"thoughts": "<one sentence describing this round's intent>",
|
|
98
|
+
"actions": [ { "tool": "<tool name>", "args": { ... } }, ... ],
|
|
99
|
+
"done": true | false
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
Rules:
|
|
103
|
+
1. Only call tools in the Step's authorised whitelist.
|
|
104
|
+
2. File writes must land within the Step's writable allowlist (other paths are rejected); required outputs are the final artifacts that must exist for acceptance.
|
|
105
|
+
For FUNCTIONAL_TEST documentation outputs, write the complete declared bundle in the active i18n language: P1 paths such as \`README.md\`, \`docs/quickstart.md\`, \`docs/08-functional-test.md\`, and \`docs/api-guide.md\` when present, or the declared iteration-scoped equivalents under \`docs/iterations/<iterationId>/\`. Do not set done=true while any declared documentation output is missing.
|
|
106
|
+
3. Generated code must follow the target language's best practice; modules importable, functions typed appropriately.
|
|
107
|
+
- [Import convention] When modules under src/ import each other, use "from <module> import \u2026" (sibling name).
|
|
108
|
+
**Never write "from src.<module> import \u2026".** If main.py needs to run from the project root, prepend
|
|
109
|
+
"sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))" before any import,
|
|
110
|
+
so that both "python src/main.py \u2026" and "python -m src.main \u2026" work.
|
|
111
|
+
- [Test convention] Files under tests/ also import targets via "from <module> import \u2026".
|
|
112
|
+
**XCompiler auto-generates tests/conftest.py to inject project-root and src/ into sys.path**,
|
|
113
|
+
so both pytest and "python tests/test_*.py" can resolve modules \u2014 test files
|
|
114
|
+
**must NOT** add their own sys.path.insert(...). If you create or edit conftest.py yourself,
|
|
115
|
+
keep the existing sys.path injection \u2014 do not delete it.
|
|
116
|
+
- [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**.
|
|
122
|
+
A test that references a file nobody created will trap the Debugger in an endless FileNotFoundError loop.
|
|
123
|
+
- [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
|
+
Never edit the implementation, the assertion, or mock out the parser to "fix" a parse error \u2014 fix the fixture first.
|
|
127
|
+
4. When all outputs files exist and self-check passes, set done = true with empty actions.
|
|
128
|
+
5. Correct any error in the next round's actions; never overstep authority or invent tools.
|
|
129
|
+
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.
|
|
130
|
+
- For larger files: in the same actions array, first write_file the head (imports + top-level constants + first function/class),
|
|
131
|
+
then several append_file calls each adding one function/class block (preserving trailing newlines).
|
|
132
|
+
- For complex projects, prefer multiple cohesive modules/files and separate CODE/UNIT_TEST/INTEGRATION_TEST/MODULE_TEST/FUNCTIONAL_TEST Steps over one giant file.
|
|
133
|
+
- The concatenated result must be valid Python; never split inside a function body.
|
|
134
|
+
- For partial edits to existing files, use replace_in_file / apply_patch \u2014 do not overwrite the whole file repeatedly.`;
|
|
135
|
+
var TYPESCRIPT_PLANNER_SYSTEM = `You are the Planner of the XCompiler system. Your job is to compile a user's natural-language requirement into a strict iterative V-model Step plan.
|
|
136
|
+
|
|
137
|
+
Output language: TypeScript / Node.js only (plan.language is fixed to "typescript").
|
|
138
|
+
|
|
139
|
+
Canonical V-model phases for every executable iteration:
|
|
140
|
+
REQUIREMENT_ANALYSIS -> HIGH_LEVEL_DESIGN -> DETAILED_DESIGN -> CODE -> UNIT_TEST -> INTEGRATION_TEST -> MODULE_TEST -> FUNCTIONAL_TEST.
|
|
141
|
+
DEBUG is runtime rollback/repair only. If a test phase fails, XCompiler rolls back to its paired source phase and reruns subsequent phases.
|
|
142
|
+
|
|
143
|
+
Use the same phase documents and synchronous test-design rule as the Python planner:
|
|
144
|
+
- 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\`.
|
|
147
|
+
- CODE: implementation outputs plus \`docs/tests/unit-test-plan.md\`.
|
|
148
|
+
- UNIT_TEST: \`docs/05-unit-test.md\`.
|
|
149
|
+
- INTEGRATION_TEST: \`docs/06-integration-test.md\`.
|
|
150
|
+
- MODULE_TEST: \`docs/07-module-test.md\`.
|
|
151
|
+
- FUNCTIONAL_TEST: \`docs/08-functional-test.md\`, \`README.md\`, \`docs/quickstart.md\`, and \`docs/api-guide.md\` for library/mixed projects.
|
|
152
|
+
For P2+ iterations, put phase docs under \`docs/iterations/<iterationId>/\` and test plans under \`docs/iterations/<iterationId>/tests/\`.
|
|
153
|
+
|
|
154
|
+
HIGH_LEVEL_DESIGN must place the current development module in the whole system and define system-level external interfaces and dependencies, including external APIs, third-party library choices, dependency confirmation, package.json scripts, package dependencies/devDependencies, tsconfig, data contracts, and integration boundaries.
|
|
155
|
+
DETAILED_DESIGN must define module-internal functions, types, data structures, algorithms, control flow, error handling, and internal architecture.
|
|
156
|
+
|
|
157
|
+
Mandatory rules:
|
|
158
|
+
1. Return pure JSON only. Never emit the old phases REQUIREMENT, ARCH, TASK, TEST, REFACTOR, or DELIVERY.
|
|
159
|
+
2. Every current/planned implementation phase is a complete V-model iteration containing all eight canonical phases.
|
|
160
|
+
3. Each macro Step may contain \`subTasks\` nested at most two levels.
|
|
161
|
+
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.
|
|
162
|
+
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
|
+
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
|
+
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.
|
|
165
|
+
8. dependencies is an advisory runtime npm package list; the authoritative manifest is \`package.json\` from HIGH_LEVEL_DESIGN. Do not invent package names.
|
|
166
|
+
9. Application/mixed projects need \`src/main.ts\` with a directly runnable \`main()\`; library/mixed projects need \`src/index.ts\` or equivalent public API plus API guide.
|
|
167
|
+
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
|
+
11. verificationGate failurePolicy must say: Feed failures to Debugger, roll back to the paired V-model phase, and rerun subsequent phases.
|
|
169
|
+
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.
|
|
170
|
+
|
|
171
|
+
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
|
+
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.
|
|
173
|
+
|
|
174
|
+
Every round you must return strict JSON:
|
|
175
|
+
{
|
|
176
|
+
"thoughts": "<one sentence describing this round's intent>",
|
|
177
|
+
"actions": [ { "tool": "<tool name>", "args": { ... } }, ... ],
|
|
178
|
+
"done": true | false
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
Rules:
|
|
182
|
+
1. Only call tools in the Step's authorised whitelist.
|
|
183
|
+
2. File writes must land within the Step's writable allowlist (other paths are rejected); required outputs are the final artifacts that must exist for acceptance.
|
|
184
|
+
For FUNCTIONAL_TEST documentation outputs, write the complete declared bundle in the active i18n language: P1 paths such as \`README.md\`, \`docs/quickstart.md\`, \`docs/08-functional-test.md\`, and \`docs/api-guide.md\` when present, or the declared iteration-scoped equivalents under \`docs/iterations/<iterationId>/\`. Do not set done=true while any declared documentation output is missing.
|
|
185
|
+
3. Generated code must follow TypeScript / Node.js best practice; modules importable, APIs typed, and runtime code directly runnable.
|
|
186
|
+
- [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
|
+
- [Test convention] Tests use Vitest: \`import { describe, it, expect } from "vitest";\`. Test files live under \`tests/**/*.test.ts\`.
|
|
188
|
+
- [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.
|
|
190
|
+
4. When all outputs files exist and self-check passes, set done = true with empty actions.
|
|
191
|
+
5. Correct any error in the next round's actions; never overstep authority or invent tools.
|
|
192
|
+
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.
|
|
193
|
+
- For larger files: in the same actions array, first write_file the head (imports + top-level constants + first function/class), then several append_file calls each adding one function/class block.
|
|
194
|
+
- For complex projects, prefer multiple cohesive modules/files and separate CODE/UNIT_TEST/INTEGRATION_TEST/MODULE_TEST/FUNCTIONAL_TEST Steps over one giant file.
|
|
195
|
+
- The concatenated result must be valid TypeScript; never split inside a function body.
|
|
196
|
+
- For partial edits to existing files, use replace_in_file / apply_patch \u2014 do not overwrite the whole file repeatedly.
|
|
197
|
+
7. package.json is the dependency manifest. Use add_dependency for npm packages; never write requirements.txt.
|
|
198
|
+
8. run_program runs the project entry with \`npx tsx\`, run_tests runs Vitest via \`npm test\`, and the final delivery gate also verifies the direct Node entry command.`;
|
|
199
|
+
var PLANNER_CLARIFY_SYSTEM = `You are the requirements analyst for XCompiler's V-model. Do not restate the topic; expose unresolved decisions that would change functional design, acceptance, or architecture boundaries.
|
|
200
|
+
Return strict JSON only. Each question must be directly answerable by a product owner, cover one decision, and avoid vague catch-all or implementation-stack questions.`;
|
|
201
|
+
function buildPlannerSystem(profile) {
|
|
202
|
+
return (profile.id === "typescript" ? TYPESCRIPT_PLANNER_SYSTEM : PYTHON_PLANNER_SYSTEM) + profile.plannerPromptOverride;
|
|
203
|
+
}
|
|
204
|
+
function buildExecutorSystem(profile) {
|
|
205
|
+
return (profile.id === "typescript" ? TYPESCRIPT_EXECUTOR_SYSTEM : PYTHON_EXECUTOR_SYSTEM) + profile.executorPromptOverride;
|
|
206
|
+
}
|
|
207
|
+
var messages = {
|
|
208
|
+
llm: {
|
|
209
|
+
coderDebuggerSameModel: (model, coderProvider, debuggerProvider) => `Model configuration advice: Coder (${coderProvider}) and Debugger (${debuggerProvider}) both use ${model}. Prefer different models so debugging provides an independent reasoning path.`,
|
|
210
|
+
invalidBaseUrl: (raw, fallback) => `[xcompiler] invalid base_url (${raw}); falling back to ${fallback}`,
|
|
211
|
+
providerValidationFailed: (role, model) => `[${role}] provider ${model} failed output validation; trying next`,
|
|
212
|
+
providerCallFailed: (role, model) => `[${role}] provider ${model} failed; trying next`,
|
|
213
|
+
scoreReadFailed: (p, message) => `failed to read ${p}: ${message}`,
|
|
214
|
+
scoreChanged: (provider, score, previous) => `score(${provider}) = ${score} (was ${previous})`,
|
|
215
|
+
scorePersistFailed: (message) => `failed to persist scores: ${message}`,
|
|
216
|
+
preflightOllamaReachable: (baseUrl, models) => `preflight: ollama ${baseUrl} reachable; found ${models} model(s)`,
|
|
217
|
+
preflightOllamaUnreachable: (baseUrl, message) => `preflight: ollama ${baseUrl} unreachable: ${message}`,
|
|
218
|
+
preflightAutoAdded: (providers, roles) => `preflight: auto-added ${providers} provider(s) for roles [${roles}]`,
|
|
219
|
+
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)."
|
|
221
|
+
},
|
|
222
|
+
system: {
|
|
223
|
+
configEnvMissing: (names) => `[xcompiler] unset config environment variables were replaced with empty strings: ${names}`,
|
|
224
|
+
unhandledError: (message) => `Unhandled error: ${message}`,
|
|
225
|
+
unsupportedPypiOnlyNetwork: "network=pypi-only is rejected because Docker cannot enforce a PyPI-only allowlist by itself. Use network=off for isolation or network=download-only for explicitly unrestricted outbound downloads.",
|
|
226
|
+
dockerInsideContainerUnsupported: "XCompiler is running inside a container, so sandbox=docker is unsupported because Docker-outside-of-Docker can mis-map bind mounts and docker.sock permissions. Use agent.sandbox=subprocess, run XCompiler on the host, or set XC_IN_CONTAINER=0 only in a controlled environment.",
|
|
227
|
+
firejailUnsupported: "sandbox=firejail is not implemented; use subprocess or docker.",
|
|
228
|
+
smokeHeader: (baseUrl) => `Smoke test against ${baseUrl} (streaming)`,
|
|
229
|
+
smokeOk: (model, totalMs, firstTokenMs, chunks, preview) => `[OK total=${totalMs}ms first-token=${firstTokenMs}ms chunks=${chunks}] ${model} -> ${preview}`,
|
|
230
|
+
smokeFail: (model, message) => `[FAIL] ${model} -> ${message}`
|
|
231
|
+
},
|
|
232
|
+
plugins: {
|
|
233
|
+
invalidId: (id) => `Plugin ID "${id}" is invalid; use lowercase letters, digits, dots, hyphens, or underscores.`,
|
|
234
|
+
duplicateId: (id) => `Duplicate plugin ID: ${id}`,
|
|
235
|
+
invalidVersion: (plugin, version) => `Plugin ${plugin} has an invalid SemVer version: ${version}`,
|
|
236
|
+
invalidCoreVersion: (version) => `XCompiler core has an invalid SemVer version: ${version}`,
|
|
237
|
+
apiVersionMismatch: (plugin, actual, expected) => `Plugin ${plugin} targets Plugin API ${actual}; this XCompiler runtime requires API ${expected}.`,
|
|
238
|
+
invalidMinimumVersion: (plugin, version) => `Plugin ${plugin} has an invalid minimum XCompiler version: ${version}`,
|
|
239
|
+
coreVersionTooOld: (plugin, minimum, actual) => `Plugin ${plugin} requires XCompiler >= ${minimum}; current version is ${actual}.`,
|
|
240
|
+
loaded: (plugin, version) => `Plugin ${plugin}@${version} loaded.`,
|
|
241
|
+
extensionConflict: (plugin, kind, name) => `Plugin ${plugin} cannot replace existing ${kind} "${name}".`,
|
|
242
|
+
hookFailed: (plugin, stage, message) => `Plugin ${plugin} failed during ${stage}: ${message}`,
|
|
243
|
+
manifestReadFailed: (path2, message) => `Cannot read plugin manifest ${path2}: ${message}`,
|
|
244
|
+
moduleLoadFailed: (plugin, path2, message) => `Cannot load plugin ${plugin} from ${path2}: ${message}`,
|
|
245
|
+
exportInvalid: (plugin, exportName) => `Plugin ${plugin} export ${exportName} is not a valid XCompiler plugin`,
|
|
246
|
+
manifestMismatch: (plugin) => `Plugin ${plugin} runtime manifest does not match its preflight manifest`
|
|
247
|
+
},
|
|
248
|
+
audit: {
|
|
249
|
+
processLogTitle: "# XCompiler Development Process Log",
|
|
250
|
+
processLogPreamble: "> Generated by XCompiler. Records CLI sessions, user input, LLM interactions, and execution actions for delivery traceability.",
|
|
251
|
+
sessionStart: (ts, command) => `## \u25B6 Session ${ts} \u2014 \`${command}\``,
|
|
252
|
+
sessionEnd: (ts) => `### \u25C0 Session end ${ts}`,
|
|
253
|
+
eventSessionStart: (command) => `start ${command}`,
|
|
254
|
+
eventSessionEnd: (command) => `end ${command}`,
|
|
255
|
+
userInput: (label) => `#### \u{1F464} User input \u2014 ${label}`,
|
|
256
|
+
llmRequest: (role, model) => `\u{1F916} LLM Request \u2014 <code>${role}</code> via <code>${model}</code>`,
|
|
257
|
+
llmResponse: (role, model) => `\u{1F4E9} LLM Response \u2014 <code>${role}</code> via <code>${model}</code>`,
|
|
258
|
+
executorTurn: (stepId, round, role, provider, actions, done) => `\u{1F9E0} Executor turn \u2014 <code>${stepId}</code> round ${round} / role <code>${role}</code>${provider ? ` \xB7 via <code>${provider}</code>` : ""} (actions=${actions}, done=${done})`,
|
|
259
|
+
thoughtsLabel: "**thoughts:**",
|
|
260
|
+
actionsLabel: "**actions:**",
|
|
261
|
+
noThoughts: "(no thoughts)",
|
|
262
|
+
plannerThought: (stage, provider) => `\u{1F9E9} Planner thought \u2014 ${stage}${provider ? ` \xB7 via <code>${provider}</code>` : ""}`,
|
|
263
|
+
markdownAppendFailed: (message) => `[audit] markdown append failed: ${message}`,
|
|
264
|
+
jsonlAppendFailed: (message) => `[audit] jsonl append failed: ${message}`,
|
|
265
|
+
traceLine: (kind, message) => `[audit] ${kind} ${message}`,
|
|
266
|
+
autoFixedSrcImport: (p) => `auto-fixed src import in ${p}`,
|
|
267
|
+
wroteFile: (p) => `wrote ${p}`,
|
|
268
|
+
userDecision: (label, value) => `${label} \u2192 ${value}`,
|
|
269
|
+
eventLlmRequest: (role, model) => `${role} \u2192 ${model}`,
|
|
270
|
+
eventLlmResponse: (role, model) => `${role} \u2190 ${model}`,
|
|
271
|
+
eventLlmError: (role, model, message) => `${role} via ${model}: ${message}`,
|
|
272
|
+
eventExecutorTurn: (stepId, round, role, provider) => `${stepId} round=${round} role=${role}${provider ? ` via ${provider}` : ""}`,
|
|
273
|
+
eventPlannerThought: (stage, provider) => `Planner ${stage}${provider ? ` via ${provider}` : ""}`,
|
|
274
|
+
llmChatFailedThought: (message) => `LLM chat failed: ${message}`,
|
|
275
|
+
llmChatAborted: (stepId, round, chars, message) => `${stepId} round ${round} aborted after ${chars} chars: ${message}`,
|
|
276
|
+
toolDenied: (tool) => `denied tool ${tool}`,
|
|
277
|
+
toolCalled: (tool) => `called tool ${tool}`,
|
|
278
|
+
toolResult: (tool, ok, detail) => `tool ${tool} ${ok ? "succeeded" : "failed"}: ${detail}`,
|
|
279
|
+
documentArchived: (from, to) => `archived ${from} \u2192 ${to}`,
|
|
280
|
+
documentArchiveFailed: (p, message) => `failed to archive ${p}: ${message}`,
|
|
281
|
+
httpFetchSaved: (method, url, p, bytes) => `http_fetch ${method} ${url} \u2192 ${p} (${bytes} B)`,
|
|
282
|
+
httpFetchResponse: (method, url, status, bytes) => `http_fetch ${method} ${url} \u2192 ${status} (${bytes} B)`,
|
|
283
|
+
partialFailureHeader: (message) => `# LLM chat failed: ${message}`,
|
|
284
|
+
streamLength: (chars) => `# Stream length: ${chars} chars`
|
|
285
|
+
},
|
|
286
|
+
stream: {
|
|
287
|
+
resolvingModel: "resolving-model",
|
|
288
|
+
waiting: "waiting",
|
|
289
|
+
streaming: "streaming",
|
|
290
|
+
done: "done",
|
|
291
|
+
failed: "failed",
|
|
292
|
+
chars: (n) => `${n} chars`,
|
|
293
|
+
toolRunner: "local-tool",
|
|
294
|
+
toolExecution: (stepId, tool) => `${stepId} tool ${tool}`
|
|
295
|
+
},
|
|
296
|
+
sandboxLog: {
|
|
297
|
+
subprocessBuilt: (deps) => `subprocess sandbox built (${deps ? "with dependencies" : "empty"})`,
|
|
298
|
+
subprocessNodeBuilt: "Node subprocess sandbox built (npm install)",
|
|
299
|
+
dockerBuilt: (deps) => `Docker sandbox built (${deps ? "with dependencies" : "empty"})`,
|
|
300
|
+
dockerNodeBuilt: "Docker Node sandbox built (npm install)",
|
|
301
|
+
command: (runtime, command) => `${runtime} ${command}`
|
|
302
|
+
},
|
|
303
|
+
cli: {
|
|
304
|
+
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)",
|
|
307
|
+
loadDescription: "Load a XXX.xc project file and continue its current plan",
|
|
308
|
+
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",
|
|
310
|
+
showDescription: "Print Step definition / status / outputs / recent audit",
|
|
311
|
+
optWorkspace: "workspace directory (alias of --output, defaults to current directory)",
|
|
312
|
+
optOutput: "project / workspace output directory (highest priority, alias of -w)",
|
|
313
|
+
optConfig: "path to config.yaml",
|
|
314
|
+
optInput: "read requirement from a file (non-interactive)",
|
|
315
|
+
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)",
|
|
317
|
+
optBaseDir: "project root output directory (creates <name> subdir under it)",
|
|
318
|
+
optName: "project name (default xcompiler-<timestamp>)",
|
|
319
|
+
optYes: "skip human confirmation (only meaningful with -i / -t)",
|
|
320
|
+
optForce: "force regenerate: override workspace lock and ignore existing plan.json",
|
|
321
|
+
optDryRun: "print topology only, do not execute",
|
|
322
|
+
optFrom: "start from the given Step (earlier ones are skipped)",
|
|
323
|
+
optPhase: "execute only the given phase (REQUIREMENT_ANALYSIS/HIGH_LEVEL_DESIGN/DETAILED_DESIGN/CODE/UNIT_TEST/INTEGRATION_TEST/MODULE_TEST/FUNCTIONAL_TEST/DEBUG)",
|
|
324
|
+
optReset: "reset all Step status to PENDING",
|
|
325
|
+
optMaxDepth: "maximum recursion depth",
|
|
326
|
+
optTail: "number of recent audit entries",
|
|
327
|
+
optPlan: "plan.json path, default <workspace>/plan.json",
|
|
328
|
+
optLang: "UI / prompt language: EN | CN (ISO 3166-1 Alpha-2)",
|
|
329
|
+
optIntent: "plan intent: greenfield | feature | refactor | self",
|
|
330
|
+
optBaselinePlan: "existing baseline plan.json path (default <workspace>/plan.json)",
|
|
331
|
+
optProjectFile: "XXX.xc project file path (default <workspace>/<name>.xc)",
|
|
332
|
+
argPlan: "plan.json path (default = <workspace>/plan.json)",
|
|
333
|
+
argProjectFile: "XXX.xc project file",
|
|
334
|
+
argStepId: "Step ID, e.g. S001",
|
|
335
|
+
evolveDescription: "Generate and execute an incremental feature/refactor plan on top of an existing workspace",
|
|
336
|
+
bootstrapDescription: "Build and qualify the next XCompiler generation in an isolated Git worktree",
|
|
337
|
+
optRepository: "XCompiler Git repository to bootstrap (default current directory)",
|
|
338
|
+
optPromote: "fast-forward the current branch after every qualification gate passes",
|
|
339
|
+
optCleanup: "remove the isolated worktree after writing the report (branch is retained)",
|
|
340
|
+
optDockerQualification: "use the experimental Docker runner for candidate qualification",
|
|
341
|
+
invalidLocale: (value) => `Unsupported language "${value}"; use EN or CN.`,
|
|
342
|
+
invalidIntent: (value, allowed) => `Invalid intent "${value}"; expected one of: ${allowed}.`,
|
|
343
|
+
invalidPhase: (value, allowed) => `Invalid phase "${value}"; expected one of: ${allowed}.`,
|
|
344
|
+
invalidStepId: (value) => `Invalid Step ID "${value}"; expected S followed by at least three digits.`,
|
|
345
|
+
invalidNonNegativeInteger: (value) => `Expected a non-negative integer, received "${value}".`,
|
|
346
|
+
helpUsage: "Usage:",
|
|
347
|
+
helpArguments: "Arguments:",
|
|
348
|
+
helpOptions: "Options:",
|
|
349
|
+
helpCommands: "Commands:",
|
|
350
|
+
helpOption: "display help for command",
|
|
351
|
+
versionOption: "output the version number",
|
|
352
|
+
defaultValue: (value) => `(default: ${value})`
|
|
353
|
+
},
|
|
354
|
+
bootstrap: {
|
|
355
|
+
notGitRepository: (p) => `Not a Git repository: ${p}`,
|
|
356
|
+
dirtyRepository: (files) => `Self-bootstrap requires a clean host repository. Pending paths: ${files}`,
|
|
357
|
+
worktreeReady: (p, branch) => `Bootstrap worktree ready: ${p} (${branch})`,
|
|
358
|
+
compileStarted: "Compiling the self-bootstrap V-model plan\u2026",
|
|
359
|
+
compileFailed: (code, message) => `Self-bootstrap compilation failed (exit=${code}): ${message}`,
|
|
360
|
+
compileCancelled: "Self-bootstrap compilation was cancelled before a plan was confirmed.",
|
|
361
|
+
executeStarted: "Executing the candidate generation in the isolated worktree\u2026",
|
|
362
|
+
executeFailed: (status) => `Candidate execution did not complete successfully (${status}).`,
|
|
363
|
+
qualificationStarted: "Running deterministic bootstrap qualification gates\u2026",
|
|
364
|
+
qualificationDockerExperimental: "Docker qualification is experimental and has not completed environment validation.",
|
|
365
|
+
missingScript: (name) => `required package.json script is missing: ${name}`,
|
|
366
|
+
missingBin: "package.json does not declare a CLI bin entry",
|
|
367
|
+
checkPassed: (name, ms) => `${name} passed (${ms}ms)`,
|
|
368
|
+
checkFailed: (name, code) => `${name} failed (exit=${code})`,
|
|
369
|
+
reportWritten: (p) => `Bootstrap report written: ${p}`,
|
|
370
|
+
candidateReady: (branch) => `Candidate is qualified on ${branch}; promotion still requires explicit --promote.`,
|
|
371
|
+
promoted: (branch) => `Bootstrap candidate promoted by fast-forward merge: ${branch}`,
|
|
372
|
+
cleanupDone: (p) => `Bootstrap worktree removed: ${p}`,
|
|
373
|
+
promotionBlocked: "Promotion blocked because one or more qualification gates failed.",
|
|
374
|
+
hostHeadChanged: "host HEAD changed during bootstrap",
|
|
375
|
+
candidateDirty: (files) => `Candidate worktree changed outside a committed generation: ${files}`,
|
|
376
|
+
candidateStatusUnknown: "(unknown path)",
|
|
377
|
+
candidateMoved: (expected, actual) => `Candidate commit changed after qualification (expected ${expected}, got ${actual}).`,
|
|
378
|
+
candidateNotBasedOnBase: (candidate, base) => `Candidate ${candidate} is not descended from bootstrap base ${base}.`,
|
|
379
|
+
promotionVerificationFailed: (expected, actual) => `Promotion verification failed (expected HEAD ${expected}, got ${actual}).`,
|
|
380
|
+
reportTitle: "XCompiler Self-Bootstrap Report",
|
|
381
|
+
reportNone: "(none)",
|
|
382
|
+
reportNextQualified: (repository, candidateCommit) => `git -C "${repository}" merge --ff-only "${candidateCommit}"`,
|
|
383
|
+
reportNextPromoted: "Run the next self-bootstrap request with the promoted generation.",
|
|
384
|
+
reportNextFailed: "Inspect the candidate worktree and fix the failed gate before promotion.",
|
|
385
|
+
reportLabels: {
|
|
386
|
+
status: "Status",
|
|
387
|
+
repository: "Repository",
|
|
388
|
+
baseCommit: "Base commit",
|
|
389
|
+
candidateCommit: "Candidate commit",
|
|
390
|
+
branch: "Candidate branch",
|
|
391
|
+
worktree: "Worktree",
|
|
392
|
+
createdAt: "Created at",
|
|
393
|
+
checks: "Qualification checks",
|
|
394
|
+
changedFiles: "Changed files",
|
|
395
|
+
nextStep: "Next step"
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
compile: {
|
|
399
|
+
workspaceReady: (p) => `Workspace: ${p}`,
|
|
400
|
+
forceOverride: "--force: overriding workspace lock and regenerating plan.",
|
|
401
|
+
topicInputConflict: "--topic and --input were both supplied; --topic wins and --input is ignored.",
|
|
402
|
+
auditTopicInput: "topic.md (--topic)",
|
|
403
|
+
auditOriginalRequirement: "Original requirement (Intake)",
|
|
404
|
+
auditUserAddenda: "User addenda",
|
|
405
|
+
auditEditedTopic: "Edited topic.md",
|
|
406
|
+
auditTopicPersisted: (p) => `topic.md written: ${p}`,
|
|
407
|
+
auditDecomposeFailed: "planner.decompose failed",
|
|
408
|
+
lintIssue: (id, message) => ` - [${id}] ${message}`,
|
|
409
|
+
planPreviewTruncated: "\u2026 (truncated; see docs/plan.md)",
|
|
410
|
+
auditPlanPersisted: (p) => `plan.json written: ${p}`,
|
|
411
|
+
projectFileWritten: (p) => `project file updated: ${p}`,
|
|
412
|
+
nextCommand: (command) => ` Next: ${command}`,
|
|
413
|
+
topicEmptyExit: "--topic file is empty, aborting.",
|
|
414
|
+
topicLoaded: (p) => `topic loaded: ${p} (skipping intake / clarify / Gate 1)`,
|
|
415
|
+
requirementEmptyExit: "requirement is empty, aborting.",
|
|
416
|
+
requirementInputHint: "Please describe your requirement (multi-line, blank line to finish):",
|
|
417
|
+
spinClarify: "Planner is clarifying the requirement\u2026",
|
|
418
|
+
clarifySucceed: (n) => `clarification questions: ${n}`,
|
|
419
|
+
clarifyFail: "clarification failed",
|
|
420
|
+
clarifyChoiceHint: (range) => `Reply with ${range} to choose a shown option, or type a custom answer.`,
|
|
421
|
+
addendaConfirm: "Any extra requirements to append? (Will be sent to Planner together with the clarification and kept in plan.userAddenda)",
|
|
422
|
+
addendaEditorMsg: "Enter custom addenda (multi-line, Markdown allowed)",
|
|
423
|
+
auditClarifyAnswer: (qid, q) => `clarify answer ${qid}: ${q}`,
|
|
424
|
+
spinDecompose: "Planner is decomposing along the V-model\u2026",
|
|
425
|
+
decomposeFail: "Planner decomposition failed",
|
|
426
|
+
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.",
|
|
429
|
+
decomposeSucceed: (n) => `generated ${n} Step(s)`,
|
|
430
|
+
schemaFail: "Plan schema validation failed:",
|
|
431
|
+
schemaInvalidSavedAt: (p) => ` full plan saved to: ${p}`,
|
|
432
|
+
lintFail: (n) => `Plan lint failed (${n}):`,
|
|
433
|
+
topicPreviewHeader: "\u2500\u2500\u2500 topic.md (preview) \u2500\u2500\u2500",
|
|
434
|
+
topicPreviewFooter: "\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\u2500\u2500\u2500\u2500\u2500",
|
|
435
|
+
gate1Confirm: "Does the requirement match expectations?",
|
|
436
|
+
gate1ChoiceConfirm: "\u2705 confirm \u2014 proceed to plan generation",
|
|
437
|
+
gate1ChoiceEdit: "\u270F\uFE0F edit \u2014 open editor to modify",
|
|
438
|
+
gate1ChoiceCancel: "\u274C cancel \u2014 abandon this session",
|
|
439
|
+
gate1AuditLabel: "Requirement Confirmation Gate (Gate 1)",
|
|
440
|
+
gate1Cancelled: "Cancelled, no files written.",
|
|
441
|
+
editTopicMsg: "Edit topic.md",
|
|
442
|
+
topicWritten: (p) => `topic written: ${p}`,
|
|
443
|
+
planWritten: (p) => `plan written: ${p}`,
|
|
444
|
+
planPreviewHeader: "\u2500\u2500\u2500 plan.md (preview) \u2500\u2500\u2500",
|
|
445
|
+
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)",
|
|
447
|
+
gate2AuditLabel: "Plan Confirmation Gate (Gate 2)",
|
|
448
|
+
gate2Rejected: "Not confirmed, abandoned. plan.json was not written.",
|
|
449
|
+
baselineLoaded: (kind, sources) => `loaded ${kind} baseline from: ${sources}`,
|
|
450
|
+
baselineMissing: (workspace) => `incremental mode requires an existing project baseline in ${workspace} (topic / docs / plan / src).`,
|
|
451
|
+
baselineLanguageOverride: (baseline, source, configured) => `incremental mode: using baseline language ${baseline} from ${source} instead of config language ${configured}.`,
|
|
452
|
+
topicTitle: "# Project Topic",
|
|
453
|
+
topicPreamble: "> This file is the project topic frozen after requirement clarification. All subsequent V-model decomposition and every phase output use this file as the sole requirement input.",
|
|
454
|
+
topicSecRequirement: "## Original requirement",
|
|
455
|
+
topicSecClarify: "## Clarification record",
|
|
456
|
+
topicSecAddenda: "## User addenda",
|
|
457
|
+
topicSecBaseline: "## Existing project baseline"
|
|
458
|
+
},
|
|
459
|
+
inspect: {
|
|
460
|
+
noPlanFound: "No plan.json found",
|
|
461
|
+
digestLabel: "digest:",
|
|
462
|
+
stepNotFound: (id) => `Step ${id} not found`,
|
|
463
|
+
secDescription: "\u2014 description \u2014",
|
|
464
|
+
secAcceptance: "\u2014 acceptance \u2014",
|
|
465
|
+
secSubtasks: "\u2014 subtasks \u2014",
|
|
466
|
+
secSystemPrompt: "\u2014 systemPrompt \u2014",
|
|
467
|
+
secOutputs: "\u2014 outputs \u2014",
|
|
468
|
+
secRecentAudit: (n) => `\u2014 recent audit (${n}) \u2014`,
|
|
469
|
+
planHeader: (p, language) => `${p} lang=${language}`,
|
|
470
|
+
planStatusSummary: (total, done, pending, failed, skipped, running) => `steps=${total} done=${done} pending=${pending} failed=${failed} skipped=${skipped} running=${running}`,
|
|
471
|
+
planReadFailed: (p, message) => `${p} \u2014 ${message}`,
|
|
472
|
+
stepHeader: (id, phase, title, status, retries, maxRetries) => `${id} ${phase} ${title} ${status} retries=${retries}/${maxRetries}`,
|
|
473
|
+
stepRoleTools: (role, tools) => `role=${role} tools=[${tools}]`,
|
|
474
|
+
stepDependsOn: (ids) => `dependsOn: ${ids}`,
|
|
475
|
+
outputStatus: (exists, p) => `${exists ? "\u2713" : "\u2717"} ${p}`,
|
|
476
|
+
auditEntry: (ts, kind, message) => `${ts} ${kind} ${message}`
|
|
477
|
+
},
|
|
478
|
+
execute: {
|
|
479
|
+
forceReset: "--force: resetting every Step to PENDING and overriding the workspace lock.",
|
|
480
|
+
manifestRecalibrated: (p) => `recalibrated ${p} (removed version pins / hallucinated names)`,
|
|
481
|
+
manifestSeeded: (p) => `seeded ${p} from plan.dependencies`,
|
|
482
|
+
auditPlanLoaded: (p) => `plan loaded: ${p}`,
|
|
483
|
+
planLoaded: (p) => `Plan loaded: ${p}`,
|
|
484
|
+
planSummary: (language, steps) => ` language=${language}, steps=${steps}`,
|
|
485
|
+
preflightModelMissing: (names) => `LLM preflight: missing models, disabled [${names}]`,
|
|
486
|
+
preflightAutoAdded: (n) => `LLM preflight: auto-injected ${n} provider(s) (from ollama /api/tags)`,
|
|
487
|
+
runInterrupted: (id, e, total) => `execution interrupted at ${id} (executed ${e}/${total})`,
|
|
488
|
+
runReasonLabel: " reason: ",
|
|
489
|
+
runFailureLogHeader: " --- failure log (tail, 40 lines) ---",
|
|
490
|
+
runAllDone: (e, total) => `Plan fully completed (${e}/${total})`,
|
|
491
|
+
projectAuditSummary: (errors, warnings) => `project audit: ${errors} error(s), ${warnings} warning(s)`,
|
|
492
|
+
projectMemoryRefreshFailed: (message) => `project memory refresh failed: ${message}`,
|
|
493
|
+
projectAuditCheck: (name, summary) => `[audit:${name}] ${summary}`,
|
|
494
|
+
auditDocPresent: (p) => `${p} present`,
|
|
495
|
+
auditDocMissing: (p) => `missing ${p}`,
|
|
496
|
+
auditDeliveryDocPresent: "delivery documentation present",
|
|
497
|
+
auditDeliveryDocMissing: "missing docs/08-functional-test.md",
|
|
498
|
+
auditTestFilesFound: (count) => `found ${count} concrete test file(s)`,
|
|
499
|
+
auditTestFilesMissing: "no concrete test files found under tests/",
|
|
500
|
+
auditEntrypointOk: (command) => `entrypoint ok: ${command}`,
|
|
501
|
+
auditEntrypointFailed: (command) => `entrypoint failed: ${command}`,
|
|
502
|
+
auditPackageJsonMissing: "missing package.json",
|
|
503
|
+
auditScriptMissing: (name) => `package.json has no ${name} script`,
|
|
504
|
+
auditCommandOk: (name) => `${name} ok`,
|
|
505
|
+
auditCommandFailed: (name, exitCode, timedOut) => `${name} failed (exit=${exitCode}${timedOut ? ", timeout" : ""})`
|
|
506
|
+
},
|
|
507
|
+
engine: {
|
|
508
|
+
spinSandboxBuild: (profile) => profile.id === "typescript" ? `building sandbox (npm install, ${profile.manifestFile})\u2026` : `building sandbox (pip install -r ${profile.manifestFile})\u2026`,
|
|
509
|
+
sandboxReady: (r) => `sandbox ready: ${r}`,
|
|
510
|
+
stepSkipDone: (id, phase) => ` \u21AA ${id} ${phase} already done, skipping`,
|
|
511
|
+
spinSandboxRebuild: (id, profile) => profile.id === "typescript" ? `Step ${id} wrote ${profile.manifestFile} \u2014 rebuilding npm sandbox\u2026` : `Step ${id} wrote ${profile.manifestFile} \u2014 rebuilding pip sandbox\u2026`,
|
|
512
|
+
sandboxStatus: (r) => `sandbox: ${r}`,
|
|
513
|
+
autoFixedSrcImports: (n, files) => ` \u26A0 auto-fixed sys.path bootstrap in ${n} entry file(s): ${files}`,
|
|
514
|
+
debugResumeNotice: (id, n) => ` \u21BB ${id} previous session ended FAILED (${n} attempts so far); first round of this run goes straight into Debugger mode.`,
|
|
515
|
+
spinDebugRetry: (id, attempt, budget, cap, reason) => `\u{1F6E0} ${id} DEBUG retry ${attempt}/${budget} (cap=${cap}) \u2014 ${reason}`,
|
|
516
|
+
retryException: (a, b, msg) => `retry ${a}/${b} threw: ${msg}`,
|
|
517
|
+
fixSucceeded: (id, a) => `${id} fix succeeded (retry=${a})`,
|
|
518
|
+
retryHealthyButFailed: (a, before, b, tag, reason) => `retry ${a}/${before}\u2192${b} still failing but healthy (expand window) \xB7 ${tag} \xB7 ${reason}`,
|
|
519
|
+
retryLowQuality: (a, before, b, tag, reason) => `retry ${a}/${before}\u2192${b} low-quality output (shrink window) \xB7 ${tag} \xB7 ${reason}`,
|
|
520
|
+
retryStillFailed: (a, b, tag, reason) => `retry ${a}/${b} still failing \xB7 ${tag} \xB7 ${reason}`,
|
|
521
|
+
earlyAbortLowQuality: (id, n) => ` \u26A1 ${id} ${n} consecutive low-quality rounds \u2014 early-aborting DEBUG retries`,
|
|
522
|
+
stepFinalFailed: (id, phase, role) => `\u2716 Step ${id} (${phase} / ${role}) finally failed`,
|
|
523
|
+
finalAttemptsLine: (a, b, c, ea) => ` attempts=${a} final_budget=${b} cap=${c}` + (ea ? " (early-abort: low-quality)" : ""),
|
|
524
|
+
finalMetricsLine: (h, p, r, tf, pr) => ` health=${h} parseFail=${p} repeat=${r} toolFail=${tf} progress=${pr}`,
|
|
525
|
+
reasonLabel: "reason: ",
|
|
526
|
+
failureLogHeader: "--- failure log (tail, max 80 lines) ---",
|
|
527
|
+
fixSuggestionsHeader: "--- fix suggestions (calibration) ---",
|
|
528
|
+
auditHint: (id) => ` audit: see .xcompiler/audit.jsonl and .xcompiler/llm-stream/${id}-*.txt for the raw stream`,
|
|
529
|
+
spinStepRunning: (id, phase, title) => `\u25B6 ${id} ${phase} ${title}`,
|
|
530
|
+
noFailureLog: "(no log captured)",
|
|
531
|
+
suggestionLine: (index, code, hint) => ` ${index}. [${code}] ${hint}`,
|
|
532
|
+
phaseStart: (id, phase, title) => `${id} ${phase} ${title}`,
|
|
533
|
+
phaseFailed: (id, debug, reason) => `${id} ${debug ? "DEBUG " : ""}FAILED \u2014 ${reason}`,
|
|
534
|
+
phaseDone: (id, rounds) => `${id} DONE (rounds=${rounds})`,
|
|
535
|
+
phaseException: (id, message) => `${id} FAILED (exception) \u2014 ${message}`,
|
|
536
|
+
archGateReason: (missing) => `HIGH_LEVEL_DESIGN gate: architecture contract missing ${missing} token(s)`,
|
|
537
|
+
archGateMissing: (tokens) => `missing module ids/paths: ${tokens}`,
|
|
538
|
+
archGateInstruction: (p) => `Update ${p} so every architectureModules item is traceable before CODE starts.`,
|
|
539
|
+
testGateReason: (exitCode, timedOut) => `Test gate: tests exit=${exitCode}${timedOut ? " (timeout)" : ""}`,
|
|
540
|
+
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",
|
|
542
|
+
missingTypeScriptEntrypoint: "missing TypeScript entrypoint: expected package.json start/bin or one of src/main.ts, src/index.ts, src/main.tsx",
|
|
543
|
+
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
|
+
entrypointHelpOutputMissing: (command) => `entrypoint probe \`${command}\` exited 0 but produced no meaningful help/usage text; implement --help instead of relying on an empty script exit.`,
|
|
545
|
+
reasonLine: (reason) => `reason: ${reason}`,
|
|
546
|
+
roundsLine: (rounds) => `rounds: ${rounds}`,
|
|
547
|
+
commandLine: (command) => `command: ${command}`,
|
|
548
|
+
stdoutTailHeader: "--- stdout (tail) ---",
|
|
549
|
+
stderrTailHeader: "--- stderr (tail) ---",
|
|
550
|
+
testStdoutTailHeader: "--- test stdout (tail) ---",
|
|
551
|
+
testStderrTailHeader: "--- test stderr (tail) ---",
|
|
552
|
+
outputsMissing: (paths) => `outputs missing: ${paths}`,
|
|
553
|
+
metricsLine: (health, parseFail, repeat, toolFail, progress) => `metrics: health=${health} parseFail=${parseFail} repeat=${repeat} toolFail=${toolFail} progress=${progress}`,
|
|
554
|
+
metricsUnavailable: "metrics: (n/a)",
|
|
555
|
+
toolCallsHeader: "tool calls:",
|
|
556
|
+
toolCallLine: (tool, ok, detail) => ` - ${tool} ${ok ? "OK" : "FAIL"} ${detail}`,
|
|
557
|
+
projectMemoryRefreshFailed: (message) => `project memory refresh failed: ${message}`,
|
|
558
|
+
deliveryFixHints: (language) => language === "typescript" ? [
|
|
559
|
+
"Fix directions (priority order):",
|
|
560
|
+
" 1. For module resolution / ERR_MODULE_NOT_FOUND in TypeScript source, use relative ESM imports with explicit .ts specifiers.",
|
|
561
|
+
" 2. For --help / unknown option, main() must support --help and exit 0.",
|
|
562
|
+
" 3. For application exceptions, fix the implementation and keep the entrypoint thin."
|
|
563
|
+
] : [
|
|
564
|
+
"Fix directions (priority order):",
|
|
565
|
+
" 1. For ModuleNotFoundError involving src, add the planner #19 sys.path bootstrap or remove the src. import prefix.",
|
|
566
|
+
' 2. main() must be a real CLI entrypoint: parse --help, call the project modules, print meaningful output, and use if __name__ == "__main__": main().',
|
|
567
|
+
" 3. For argparse errors, main() must support --help without other required arguments and exit 0.",
|
|
568
|
+
" 4. For business exceptions, fix the implementation and keep the entrypoint limited to parsing and dispatch."
|
|
569
|
+
]
|
|
570
|
+
},
|
|
571
|
+
render: {
|
|
572
|
+
sectionGlobalPrompt: "## Global prompt (injected into every Step's system prompt)",
|
|
573
|
+
sectionDependencies: (manifestFile) => `## Dependencies (written to ${manifestFile})`,
|
|
574
|
+
sectionBaselineSummary: "## Existing project baseline",
|
|
575
|
+
labelSystemPrompt: "**System prompt (sole mandate):**"
|
|
576
|
+
},
|
|
577
|
+
prompts: {
|
|
578
|
+
plannerSystem: (p) => buildPlannerSystem(p),
|
|
579
|
+
plannerSelfMode: `SELF-BOOTSTRAP OVERRIDE (takes precedence over conflicting greenfield rules above):
|
|
580
|
+
- 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
|
+
- Do not create src/main.ts merely to satisfy a greenfield entrypoint convention. Reuse the entrypoints declared by the existing package.json.
|
|
582
|
+
- Do not list package.json or tsconfig.json as HIGH_LEVEL_DESIGN outputs unless this change genuinely needs to modify them.
|
|
583
|
+
- Every CODE/test output must be scoped to the requested delta. Never rebuild or replace the repository wholesale.
|
|
584
|
+
- Treat the stable host binary as generation N and the worktree candidate as N+1; do not design in-process hot replacement.`,
|
|
585
|
+
plannerClarifySystem: PLANNER_CLARIFY_SYSTEM,
|
|
586
|
+
plannerClarify: (raw, opts = {}) => `The user's original requirement is:
|
|
587
|
+
|
|
588
|
+
"""
|
|
589
|
+
${raw}
|
|
590
|
+
"""
|
|
591
|
+
|
|
592
|
+
Generate ${opts.complex ? "8-10" : "7-10"} non-duplicate clarification questions about unresolved decisions whose answers materially affect implementation or acceptance. Never return an empty array; when the functional description is already detailed, ask for acceptance examples, failure behaviour, and explicit exclusions.
|
|
593
|
+
|
|
594
|
+
Return ONLY a JSON array. Every item must be shaped exactly as:
|
|
595
|
+
{"id":"Q1","category":"functionality|data|acceptance|boundary|quality|extensibility","question":"one concrete directly-answerable question","why":"what design or acceptance decision this answer affects","options":[{"label":"A","answer":"highest-priority feasible setting"},{"label":"B","answer":"second feasible setting"}]}
|
|
596
|
+
|
|
597
|
+
Question mix (functionality first):
|
|
598
|
+
- At least ${opts.complex ? "5" : "4"} function-focused questions categorized as functionality / data / acceptance, so functional questions remain the majority. Prioritize actors, core journeys, business rules and state transitions, inputs/outputs, failure behaviour, and verifiable acceptance examples.
|
|
599
|
+
- At least one boundary question defining in-scope, explicitly out-of-scope, external-system ownership, or compatibility limits.
|
|
600
|
+
- At least one quality question requesting measurable latency, throughput, volume, concurrency, accuracy, reliability, or security targets. Never ask only \u201CAny performance requirements?\u201D.
|
|
601
|
+
- 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
|
+
- 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.
|
|
603
|
+
- Order by blocking impact: core functional/data decisions first, then scope and quality, then future evolution.
|
|
604
|
+
- One primary decision per question. Include useful business choices/examples; do not join unrelated questions with \u201Cand/or\u201D.
|
|
605
|
+
- 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.
|
|
606
|
+
- Label options sequentially from A through the last generated option, for example A-B, A-C, A-D, or A-E. A should be the recommended/default setting when one is apparent. Options must be concrete business/product settings, not vague placeholders.
|
|
607
|
+
- Do not include \u201COther\u201D, \u201CCustom\u201D, or \u201CLet the user decide\u201D as an option. The CLI already allows the user to reply with one of the shown labels or enter a custom free-form answer.
|
|
608
|
+
${opts.projectShapeAmbiguous ? "- Required for this topic: ask the API library vs runnable application vs mixed-deliverable boundary explicitly.\n" : ""}
|
|
609
|
+
|
|
610
|
+
[Hard constraint] The implementation stack is already fixed by XCompiler config / the existing project baseline. Do not reopen language/runtime/package-manager decisions.
|
|
611
|
+
**Do NOT** ask questions of these forms:
|
|
612
|
+
- "Which programming language / framework / runtime should this use?"
|
|
613
|
+
- "Which test framework / build tool / package manager?"
|
|
614
|
+
- "Which OS is the target platform?"
|
|
615
|
+
${opts.intent && opts.intent !== "greenfield" ? `This is an incremental ${opts.intent} request against an existing project${opts.hasBaseline ? " with a separate baseline summary that will be provided during decomposition" : ""}. Ask ONLY delta questions; do not ask to rebuild the project from scratch.` : ""}The majority of questions must concern functional behaviour; performance, boundaries, and extensibility should eliminate ambiguities that affect this delivery.`,
|
|
616
|
+
plannerDecompose: (raw, qa, addenda, opts = {}) => `Original requirement:
|
|
617
|
+
"""
|
|
618
|
+
${raw}
|
|
619
|
+
"""
|
|
620
|
+
|
|
621
|
+
Clarification Q&A:
|
|
622
|
+
${qa || "(none)"}
|
|
623
|
+
|
|
624
|
+
${addenda ? `User addenda (must be strictly followed; takes priority over any vague parts of the original):
|
|
625
|
+
"""
|
|
626
|
+
${addenda}
|
|
627
|
+
"""
|
|
628
|
+
|
|
629
|
+
` : ""}${opts.intent && opts.intent !== "greenfield" ? `Incremental intent: ${opts.intent}
|
|
630
|
+
|
|
631
|
+
Generate an incremental ${opts.intent} plan on top of the existing project. Reuse the current architecture, files, tests and dependencies where possible instead of rebootstrapping the whole project. Outside the requested change, preserve existing behaviour.
|
|
632
|
+
|
|
633
|
+
Existing project baseline:
|
|
634
|
+
"""
|
|
635
|
+
${opts.baseline || "(missing baseline)"}
|
|
636
|
+
"""
|
|
637
|
+
|
|
638
|
+
` : ""}Planning depth rules:
|
|
639
|
+
- Unless the request is explicitly tiny (single function / toy script / one-file utility), do not collapse the solution into one source file and one test.
|
|
640
|
+
- If the requirement spans multiple concerns (domain logic, API/CLI surface, persistence, integration, orchestration, tests), reflect that with multiple architecture modules and Step.subTasks under CODE/MODULE_TEST macro Steps.
|
|
641
|
+
- Assess project complexity in the plan and size implementationPhases from that assessment: simple => P1 current only; moderate => P1 current + at least P2 planned; complex => P1 current + at least P2/P3 planned. If the user explicitly requested phases/stages, use at least P1+P2 and set userForcedPhaseSplit=true. Every current/planned implementation phase must be represented by a full V-model cycle in steps, with Step.iterationId pointing to that phase.
|
|
642
|
+
- Use HIGH_LEVEL_DESIGN/DETAILED_DESIGN steps to describe module boundaries, responsibilities, dependencies, and extension points that future incremental work can build on.
|
|
643
|
+
- When baseline files already exist, prefer editing/extending those modules over creating shadow implementations with duplicate behaviour.
|
|
644
|
+
|
|
645
|
+
Output a strict JSON plan per the system rules.`,
|
|
646
|
+
executorSystem: (p) => buildExecutorSystem(p),
|
|
647
|
+
executorDebugBlock: (reason, suggestions) => `
|
|
648
|
+
|
|
649
|
+
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 ? `
|
|
651
|
+
|
|
652
|
+
${suggestions}` : ""),
|
|
653
|
+
executorGlobalBlock: (globalPrompt) => `
|
|
654
|
+
|
|
655
|
+
## Project-wide constraints
|
|
656
|
+
${globalPrompt}`,
|
|
657
|
+
executorStepBlock: (sp) => `
|
|
658
|
+
|
|
659
|
+
## Current Step prompt (sole mission \u2014 do not drift across steps)
|
|
660
|
+
${sp}`,
|
|
661
|
+
executorUserPromptOutro: "Now return the first round of JSON per the protocol.",
|
|
662
|
+
executorFeedbackHeader: "Tool results this round:",
|
|
663
|
+
executorFeedbackVerifyOk: "outputs verified. If you are done, set done=true and actions=[].",
|
|
664
|
+
executorFeedbackVerifyMissing: (paths) => `outputs still missing: ${paths}. Please continue.`
|
|
665
|
+
},
|
|
666
|
+
skills: {
|
|
667
|
+
patcher: "Use apply_patch / replace_in_file for small in-place edits to existing files; never overwrite a whole file.",
|
|
668
|
+
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.`,
|
|
670
|
+
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.',
|
|
672
|
+
refactorer: "Refactors must preserve behaviour: run regression tests \u2192 modify \u2192 run regression tests again."
|
|
673
|
+
},
|
|
674
|
+
doctor: {
|
|
675
|
+
cliDescription: "check that config / LLM / sandbox / skills are ready",
|
|
676
|
+
optStrict: "treat warnings as failures (exit non-zero on any warn)",
|
|
677
|
+
header: "XCompiler environment check",
|
|
678
|
+
sectionConfig: "[config]",
|
|
679
|
+
sectionLLM: "[LLM]",
|
|
680
|
+
sectionSandbox: "[sandbox]",
|
|
681
|
+
sectionSkills: "[skills]",
|
|
682
|
+
summaryOk: "all checks passed.",
|
|
683
|
+
summaryWarn: (n) => `passed with ${n} warning(s).`,
|
|
684
|
+
summaryFail: (n) => `${n} failure(s) detected.`,
|
|
685
|
+
configLoadOk: (path2) => `config loaded: ${path2}`,
|
|
686
|
+
configLoadFail: (msg) => `failed to load config: ${msg}`,
|
|
687
|
+
configLocale: (locale) => `locale=${locale}`,
|
|
688
|
+
llmNoProviders: "no LLM providers defined in config.llm.providers",
|
|
689
|
+
llmProviderListed: (n) => `${n} provider(s) declared`,
|
|
690
|
+
ollamaUnreachable: (baseUrl, msg) => `ollama unreachable @ ${baseUrl} \u2014 ${msg}`,
|
|
691
|
+
ollamaReachable: (baseUrl, n) => `ollama reachable @ ${baseUrl} (${n} model(s))`,
|
|
692
|
+
ollamaModelMissing: (provider, model, baseUrl) => `provider "${provider}": model "${model}" NOT installed on ${baseUrl} (run \`ollama pull ${model}\`)`,
|
|
693
|
+
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)`,
|
|
695
|
+
openaiReachable: (provider, baseUrl) => `provider "${provider}": OpenAI endpoint reachable @ ${baseUrl}`,
|
|
696
|
+
openaiUnreachable: (provider, baseUrl, msg) => `provider "${provider}": OpenAI endpoint unreachable @ ${baseUrl} \u2014 ${msg}`,
|
|
697
|
+
openaiModelListMissing: (provider, model) => `provider "${provider}": model "${model}" not in /models response (it may still work if your account has access)`,
|
|
698
|
+
providerScoreZero: (provider) => `provider "${provider}" disabled (score=0)`,
|
|
699
|
+
roleNoLiveProvider: (role) => `role "${role}" has no live provider (no candidate is reachable & enabled)`,
|
|
700
|
+
roleOk: (role, provider) => `role "${role}" \u2192 ${provider}`,
|
|
701
|
+
sandboxKind: (kind) => `sandbox=${kind}`,
|
|
702
|
+
sandboxNetworkPolicy: (policy, ports) => `network=${policy}` + (ports.length ? ` (expose_ports=[${ports.join(", ")}])` : ""),
|
|
703
|
+
sandboxFullNoPorts: "network=full but no expose_ports configured \u2014 host-side cannot reach container services. Add `agent.sandbox_limits.expose_ports: [<port>]` in config.yaml.",
|
|
704
|
+
sandboxNodeMissing: "node not found on PATH (required by TypeScript subprocess sandbox)",
|
|
705
|
+
sandboxNodeOk: (version) => `node OK (${version})`,
|
|
706
|
+
sandboxNpmMissing: "npm not found on PATH (required by TypeScript subprocess sandbox)",
|
|
707
|
+
sandboxNpmOk: (version) => `npm OK (${version})`,
|
|
708
|
+
sandboxNpxMissing: "npx not found on PATH (required by TypeScript subprocess sandbox)",
|
|
709
|
+
sandboxNpxOk: (version) => `npx OK (${version})`,
|
|
710
|
+
sandboxPythonMissing: "python3 not found on PATH (required by subprocess sandbox)",
|
|
711
|
+
sandboxPythonOk: (version) => `python3 OK (${version})`,
|
|
712
|
+
sandboxVenvMissing: "python3 venv module unavailable (install python3-venv / python3-virtualenv)",
|
|
713
|
+
sandboxVenvOk: "python3 venv module OK",
|
|
714
|
+
sandboxDockerMissing: (bin) => `docker binary "${bin}" not found on PATH`,
|
|
715
|
+
sandboxDockerOk: (version) => `docker OK (${version})`,
|
|
716
|
+
sandboxDockerDaemonDown: (msg) => `docker daemon not reachable: ${msg}`,
|
|
717
|
+
sandboxInContainerWarn: "XCompiler appears to be running inside a container; sandbox=docker is unsupported in this mode (use subprocess).",
|
|
718
|
+
skillToolMissing: (skill, tool) => `skill "${skill}" references unknown tool "${tool}"`,
|
|
719
|
+
skillOk: (n, tools) => `${n} skill(s) registered, ${tools} underlying tool(s)`
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
var en_default = messages;
|
|
723
|
+
|
|
724
|
+
// src/i18n/zh.ts
|
|
725
|
+
var PYTHON_PLANNER_SYSTEM2 = `\u4F60\u662F XCompiler \u7CFB\u7EDF\u7684 Planner\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u628A\u7528\u6237\u7684\u81EA\u7136\u8BED\u8A00\u9700\u6C42\u7F16\u8BD1\u6210\u4E25\u683C\u7684\u201C\u8FED\u4EE3\u6A21\u578B + V \u6A21\u578B\u201DStep \u8BA1\u5212\u3002
|
|
726
|
+
|
|
727
|
+
\u8F93\u51FA\u8BED\u8A00\uFF1A\u4EC5 Python (plan.language \u56FA\u5B9A\u4E3A "python")\u3002
|
|
728
|
+
|
|
729
|
+
\u6BCF\u4E2A\u53EF\u6267\u884C\u8FED\u4EE3\u5468\u671F\u5FC5\u987B\u4F7F\u7528\u6807\u51C6 V \u6A21\u578B\u6D41\u7A0B\uFF1A
|
|
730
|
+
REQUIREMENT_ANALYSIS -> HIGH_LEVEL_DESIGN -> DETAILED_DESIGN -> CODE -> UNIT_TEST -> INTEGRATION_TEST -> MODULE_TEST -> FUNCTIONAL_TEST\u3002
|
|
731
|
+
DEBUG \u4E0D\u662F\u6B63\u5E38 V \u6A21\u578B\u9636\u6BB5\uFF0C\u53EA\u662F\u8FD0\u884C\u65F6\u5931\u8D25\u56DE\u9000/\u4FEE\u590D\u6A21\u5F0F\u3002\u4EFB\u610F\u6D4B\u8BD5\u9636\u6BB5\u5931\u8D25\u65F6\uFF0CXCompiler \u4F1A\u56DE\u9000\u5230\u8BE5\u6D4B\u8BD5\u5BF9\u5E94\u7684\u5DE6\u4FA7\u9636\u6BB5\u5F00\u59CB Debugger \u4FEE\u590D\uFF0C\u5E76\u91CD\u65B0\u6267\u884C\u540E\u7EED V \u6A21\u578B\u52A8\u4F5C\u3002
|
|
732
|
+
|
|
733
|
+
\u9636\u6BB5\u6587\u6863\uFF1A
|
|
734
|
+
| Phase | \u5FC5\u987B\u8F93\u51FA\u6587\u4EF6 |
|
|
735
|
+
|---|---|
|
|
736
|
+
| REQUIREMENT_ANALYSIS | \`docs/01-requirement-analysis.md\` |
|
|
737
|
+
| HIGH_LEVEL_DESIGN | \`docs/02-high-level-design.md\` |
|
|
738
|
+
| DETAILED_DESIGN | \`docs/03-detailed-design.md\` |
|
|
739
|
+
| UNIT_TEST | \`docs/05-unit-test.md\` |
|
|
740
|
+
| INTEGRATION_TEST | \`docs/06-integration-test.md\` |
|
|
741
|
+
| MODULE_TEST | \`docs/07-module-test.md\` |
|
|
742
|
+
| FUNCTIONAL_TEST | \`docs/08-functional-test.md\` |
|
|
743
|
+
|
|
744
|
+
P2+ \u8FED\u4EE3\u628A\u540C\u540D\u9636\u6BB5\u6587\u6863\u5199\u5165 \`docs/iterations/<iterationId>/\`\u3002\u9876\u5C42 \`docs/topic.md\` \u7531 xcompiler build \u5199\u5165\uFF0C\u4EFB\u4F55 Step \u90FD\u4E0D\u5F97\u628A\u5B83\u5217\u4E3A outputs\u3002
|
|
745
|
+
|
|
746
|
+
\u540C\u6B65\u6D4B\u8BD5\u8BBE\u8BA1\u89C4\u5219\uFF1A
|
|
747
|
+
- 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
|
|
750
|
+
- CODE \u540C\u6B65\u8F93\u51FA \`docs/tests/unit-test-plan.md\`\u3002
|
|
751
|
+
P2+ \u8FED\u4EE3\u628A\u8FD9\u4E9B\u6D4B\u8BD5\u8BA1\u5212\u5199\u5230 \`docs/iterations/<iterationId>/tests/\`\u3002
|
|
752
|
+
|
|
753
|
+
\u9636\u6BB5\u804C\u8D23\uFF1A
|
|
754
|
+
- 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\u3002
|
|
755
|
+
- HIGH_LEVEL_DESIGN \u8D1F\u8D23\u67B6\u6784\u8BBE\u8BA1\uFF0C\u8BF4\u660E\u5F53\u524D\u5F00\u53D1\u6A21\u5757\u5728\u6574\u4F53\u7CFB\u7EDF\u4E2D\u7684\u5B9A\u4F4D\uFF0C\u5E76\u5B9A\u4E49\u7CFB\u7EDF\u5C42\u9762\u7684\u5BF9\u5916\u63A5\u53E3\u548C\u4F9D\u8D56\uFF0C\u5305\u62EC\u5916\u90E8 API\u3001\u7B2C\u4E09\u65B9\u5E93\u9009\u578B\u3001\u4F9D\u8D56\u786E\u8BA4\u3001\u6570\u636E\u5951\u7EA6\u548C\u96C6\u6210\u8FB9\u754C\u3002
|
|
756
|
+
- 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
|
+
- CODE \u53EA\u5B9E\u73B0\u5DF2\u8BBE\u8BA1\u8303\u56F4\u5E76\u4EA7\u51FA\u53EF\u8FD0\u884C/\u53EF\u5BFC\u5165\u7684 Python \u6E90\u7801\u3002
|
|
758
|
+
- 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
|
|
761
|
+
- FUNCTIONAL_TEST \u6309\u9700\u6C42\u7AEF\u5230\u7AEF\u9A8C\u6536\uFF0C\u5E76\u4EA7\u51FA\u9762\u5411\u7528\u6237\u7684\u6587\u6863\u3002
|
|
762
|
+
|
|
763
|
+
\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
|
|
764
|
+
|
|
765
|
+
\u5F3A\u5236\u89C4\u5219\uFF1A
|
|
766
|
+
1. \u53EA\u8FD4\u56DE\u7EAF JSON\uFF0C\u7981\u6B62 Markdown \u4EE3\u7801\u5757\u548C\u89E3\u91CA\u6587\u5B57\u3002
|
|
767
|
+
2. \u6BCF\u4E2A current/planned implementation phase \u90FD\u662F\u5B8C\u6574 V \u6A21\u578B\u8FED\u4EE3\uFF0C\u5FC5\u987B\u5305\u542B\u4E0A\u8FF0 8 \u4E2A\u6807\u51C6\u9636\u6BB5\u3002\u7981\u6B62\u8F93\u51FA\u65E7\u9636\u6BB5 REQUIREMENT\u3001ARCH\u3001TASK\u3001TEST\u3001REFACTOR\u3001DELIVERY\u3002
|
|
768
|
+
3. \u6BCF\u4E2A\u5B8F Step \u7684 \`subTasks\` \u6700\u591A\u5D4C\u5957 2 \u5C42\uFF1B\u4E0D\u8981\u4E3A\u4E86\u5185\u90E8\u7EC6\u8282\u62C6\u51FA\u5927\u91CF\u53EF\u6267\u884C Step\u3002
|
|
769
|
+
4. dependsOn \u5FC5\u987B\u6309\u9636\u6BB5\u987A\u5E8F\u4E14\u65E0\u73AF\u3002\u53F3\u4FA7\u6D4B\u8BD5\u9636\u6BB5\u5FC5\u987B\u76F4\u63A5\u6216\u95F4\u63A5\u4F9D\u8D56\u5176\u5BF9\u5E94\u5DE6\u4FA7\u9636\u6BB5\u3002
|
|
770
|
+
5. \u6BCF\u4E2A CODE Step \u5FC5\u987B\u88AB\u540C\u8FED\u4EE3\u7684 UNIT_TEST Step \u8986\u76D6\u3002
|
|
771
|
+
6. \u9700\u6C42/\u8BBE\u8BA1\u9636\u6BB5\u4E0D\u5F97\u8F93\u51FA src/ \u6216 tests/ \u6587\u4EF6\uFF1BCODE \u4EA7\u51FA src/\uFF1B\u6D4B\u8BD5\u9636\u6BB5\u4EA7\u51FA tests/ \u548C\u62A5\u544A\u6587\u6863\uFF1BFUNCTIONAL_TEST \u4E0D\u5F97\u4FEE\u6539 src/\u3002
|
|
772
|
+
7. outputs \u8DEF\u5F84\u5168\u5C40\u552F\u4E00\u3002DEBUG \u8FD0\u884C\u65F6\u53EF\u4FEE\u6539\u4F9D\u8D56\u94FE\u6587\u4EF6\uFF0C\u8BA1\u5212 Step \u4E0D\u8981\u91CD\u590D\u58F0\u660E outputs\u3002
|
|
773
|
+
8. id \u5F62\u5982 S001\u3001S002\uFF1Brole \u53EA\u80FD\u662F Planner / Architect / Coder / Tester / Debugger\u3002
|
|
774
|
+
9. \u6BCF\u4E2A Step \u5FC5\u987B\u6709 systemPrompt\uFF0C\u660E\u786E\u8303\u56F4\u3001\u8F93\u5165\u3001\u4EA7\u51FA\u3001\u9A8C\u6536\u3001\u7981\u4EE4\uFF0C\u4EE5\u53CA\u5DE6\u4FA7\u9636\u6BB5\u7684\u540C\u6B65\u6D4B\u8BD5\u8BBE\u8BA1\u4E49\u52A1\u3002
|
|
775
|
+
10. projectType \u7531 LLM \u5728\u6F84\u6E05\u540E\u5224\u5B9A\uFF1Aapplication / library / mixed\uFF0C\u4E0D\u5B58\u5728\u547D\u4EE4\u884C project-type \u8986\u76D6\u3002
|
|
776
|
+
11. complexityAssessment \u7531 plan \u9636\u6BB5\u8BC4\u4F30\uFF1Asimple => P1\uFF1Bmoderate => \u81F3\u5C11 P1+P2\uFF1Bcomplex => \u81F3\u5C11 P1+P2+P3\u3002\u7528\u6237\u660E\u786E\u8981\u6C42\u5206\u9636\u6BB5\u65F6\u5FC5\u987B userForcedPhaseSplit=true\u3002
|
|
777
|
+
12. implementationPhases \u5FC5\u987B\u5305\u542B P1 current \u548C\u540E\u7EED planned \u53EF\u6267\u884C\u8FED\u4EE3\uFF1BverificationGate \u7684 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\u65B0\u6267\u884C\u540E\u7EED\u9636\u6BB5\u3002
|
|
778
|
+
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
|
+
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
|
+
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
|
|
781
|
+
|
|
782
|
+
\u8F93\u51FA JSON \u5F62\u5982\uFF1A
|
|
783
|
+
{
|
|
784
|
+
"requirementDigest": "string",
|
|
785
|
+
"globalPrompt": "string",
|
|
786
|
+
"projectType": "application | library | mixed",
|
|
787
|
+
"complexityAssessment": { "level": "simple | moderate | complex", "rationale": "string", "splitRecommended": true, "userForcedPhaseSplit": false },
|
|
788
|
+
"implementationPhases": [
|
|
789
|
+
{ "id": "P1", "title": "\u6838\u5FC3\u529F\u80FD", "objective": "string", "status": "current", "scope": ["..."], "deliverables": ["..."], "dependsOn": [], "verificationGate": { "summary": "string", "checks": ["run tests", "probe entrypoint/API", "verify functional docs"], "failurePolicy": "Feed failures to Debugger, roll back to the paired V-model phase, and rerun subsequent phases." } }
|
|
790
|
+
],
|
|
791
|
+
"dependencies": ["pytest"],
|
|
792
|
+
"architectureModules": [
|
|
793
|
+
{ "id": "M001", "name": "\u6A21\u5757\u540D", "responsibility": "\u5355\u4E00\u4E14\u660E\u786E\u7684\u6A21\u5757\u804C\u8D23", "sourcePaths": ["src/example.py"], "testPaths": ["tests/test_example.py"], "dependencies": [] }
|
|
794
|
+
],
|
|
795
|
+
"steps": [
|
|
796
|
+
{
|
|
797
|
+
"id": "S001",
|
|
798
|
+
"iterationId": "P1",
|
|
799
|
+
"phase": "REQUIREMENT_ANALYSIS",
|
|
800
|
+
"title": "string",
|
|
801
|
+
"description": "string",
|
|
802
|
+
"systemPrompt": "\u672C Step \u4E13\u5C5E\u63D0\u793A\uFF1A\u8303\u56F4\u3001\u8F93\u5165\u3001\u4EA7\u51FA\u3001\u9A8C\u6536\u3001\u7981\u4EE4",
|
|
803
|
+
"role": "Planner",
|
|
804
|
+
"tools": ["write_file"],
|
|
805
|
+
"inputs": ["docs/topic.md"],
|
|
806
|
+
"outputs": ["docs/01-requirement-analysis.md", "docs/tests/functional-test-plan.md"],
|
|
807
|
+
"subTasks": [
|
|
808
|
+
{ "id": "T1", "title": "string", "description": "string", "acceptance": "string", "outputs": ["docs/01-requirement-analysis.md"], "subTasks": [] }
|
|
809
|
+
],
|
|
810
|
+
"dependsOn": [],
|
|
811
|
+
"acceptance": "string",
|
|
812
|
+
"maxRetries": 3
|
|
813
|
+
}
|
|
814
|
+
]
|
|
815
|
+
}`;
|
|
816
|
+
var PYTHON_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
|
|
817
|
+
|
|
818
|
+
\u6BCF\u4E00\u8F6E\u4F60\u5FC5\u987B\u8FD4\u56DE\u4E25\u683C JSON\uFF1A
|
|
819
|
+
{
|
|
820
|
+
"thoughts": "<\u7528\u4E00\u53E5\u8BDD\u8BF4\u660E\u672C\u8F6E\u610F\u56FE>",
|
|
821
|
+
"actions": [ { "tool": "<\u5DE5\u5177\u540D>", "args": { ... } }, ... ],
|
|
822
|
+
"done": true | false
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
\u89C4\u5219\uFF1A
|
|
826
|
+
1. \u4EC5\u53EF\u8C03\u7528\u672C Step \u6388\u6743\u7684\u5DE5\u5177\u767D\u540D\u5355\u3002
|
|
827
|
+
2. \u5199\u5165\u6587\u4EF6\u5FC5\u987B\u843D\u5728\u672C Step \u7684 writable allowlist \u5185\uFF08\u5176\u5B83\u8DEF\u5F84\u4F1A\u88AB\u62D2\u7EDD\uFF09\uFF1Brequired outputs \u53EA\u662F\u6700\u7EC8\u5FC5\u987B\u5B58\u5728\u7684\u9A8C\u6536\u4EA7\u7269\u3002
|
|
828
|
+
\u5BF9 FUNCTIONAL_TEST \u6587\u6863\u4EA7\u7269\uFF0C\u5FC5\u987B\u6309\u5F53\u524D i18n \u8BED\u8A00\u5199\u5B8C\u6574\u58F0\u660E\u7684\u6587\u6863\u5305\uFF1AP1 \u8DEF\u5F84\u5982 \`README.md\`\u3001\`docs/quickstart.md\`\u3001\`docs/08-functional-test.md\`\uFF0C\u4EE5\u53CA outputs \u4E2D\u51FA\u73B0\u65F6\u7684 \`docs/api-guide.md\`\uFF1BP2+ \u5219\u5199 outputs \u58F0\u660E\u7684 \`docs/iterations/<iterationId>/\` \u7B49\u4EF7\u8DEF\u5F84\u3002\u4EFB\u4F55\u5DF2\u58F0\u660E\u6587\u6863\u7F3A\u5931\u65F6\u4E0D\u5F97\u8BBE\u7F6E done=true\u3002
|
|
829
|
+
3. \u5BF9\u751F\u6210\u4EE3\u7801\u9075\u5FAA\u76EE\u6807\u8BED\u8A00\u7684\u6700\u4F73\u5B9E\u8DF5\uFF1B\u6A21\u5757\u53EF\u5BFC\u5165\u3001\u51FD\u6570\u5E94\u5E26\u5408\u9002\u7684\u7C7B\u578B\u4FE1\u606F\u3002
|
|
830
|
+
- \u3010\u5BFC\u5165\u7EA6\u5B9A\u3011src/ \u4E0B\u7684\u6A21\u5757\u4E92\u76F8 import \u65F6\u4F7F\u7528 "from <module> import ..."\uFF08\u540C\u7EA7\u540D\u79F0\uFF09\uFF0C
|
|
831
|
+
**\u4E25\u7981\u5199\u6210 "from src.<module> import ..."**\u3002\u5982\u679C main.py \u9700\u8981\u4ECE\u9879\u76EE\u6839\u8FD0\u884C\uFF0C
|
|
832
|
+
\u5728 import \u4E4B\u524D\u52A0\u4E00\u884C\uFF1Asys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))\uFF0C
|
|
833
|
+
\u4EE5\u4FDD\u8BC1 "python src/main.py ..." \u548C "python -m src.main ..." \u4E24\u79CD\u8C03\u7528\u90FD\u80FD\u8D70\u901A\u3002
|
|
834
|
+
- \u3010\u6D4B\u8BD5\u7EA6\u5B9A\u3011tests/ \u4E0B\u7684\u6587\u4EF6\u540C\u6837\u4EE5 "from <module> import ..." \u5BFC\u5165\u88AB\u6D4B\u6A21\u5757\uFF1B
|
|
835
|
+
**XCompiler \u5DF2\u81EA\u52A8\u751F\u6210 tests/conftest.py \u628A\u9879\u76EE\u6839\u4E0E src/ \u6CE8\u5165 sys.path**\uFF0C
|
|
836
|
+
\u56E0\u6B64 pytest \u4E0E "python tests/test_*.py" \u4E24\u79CD\u6267\u884C\u65B9\u5F0F\u90FD\u80FD\u89E3\u6790\u6A21\u5757\uFF0C
|
|
837
|
+
\u6D4B\u8BD5\u6587\u4EF6\u5934\u90E8**\u65E0\u9700**\u518D\u5199 sys.path.insert(...)\uFF0C\u907F\u514D\u91CD\u590D\u6C61\u67D3\u3002
|
|
838
|
+
\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
|
|
844
|
+
\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
|
+
- \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
|
|
848
|
+
\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
|
+
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
|
+
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
|
|
851
|
+
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
|
|
852
|
+
- \u8D85\u8FC7\u65F6\u8BF7\u62C6\u5206\uFF1A\u540C\u4E00\u8F6E actions \u91CC\u5148\u4E00\u4E2A write_file \u5199\u9996\u6BB5\uFF08import + \u9876\u5C42\u5E38\u91CF + \u7B2C\u4E00\u4E2A\u51FD\u6570/\u7C7B\uFF09\uFF0C
|
|
853
|
+
\u7D27\u8DDF\u591A\u4E2A append_file \u9010\u6BB5\u8FFD\u52A0\uFF08\u6309\u51FD\u6570/\u7C7B\u8FB9\u754C\u5207\u5757\uFF0C\u6BCF\u6BB5\u6536\u5C3E\u4FDD\u7559\u6362\u884C\uFF09\u3002
|
|
854
|
+
- \u590D\u6742\u5DE5\u7A0B\u4F18\u5148\u62C6\u6210\u591A\u4E2A\u5185\u805A\u6A21\u5757/\u6587\u4EF6\uFF0C\u5E76\u7528\u72EC\u7ACB CODE/UNIT_TEST/INTEGRATION_TEST/MODULE_TEST/FUNCTIONAL_TEST Step \u589E\u91CF\u63A8\u8FDB\uFF0C\u4E0D\u8981\u5199\u4E00\u4E2A\u5DE8\u578B\u4E07\u80FD\u6587\u4EF6\u3002
|
|
855
|
+
- \u62C6\u5206\u5FC5\u987B\u4FDD\u8BC1\u62FC\u63A5\u540E\u4ED3 Python \u8BED\u6CD5\u5408\u6CD5\uFF1B\u4E25\u7981\u5728\u51FD\u6570\u4F53\u4E2D\u95F4\u62C6\u65AD\u3002
|
|
856
|
+
- \u5BF9\u5DF2\u5B58\u5728\u6587\u4EF6\u7684\u5C40\u90E8\u4FEE\u6539\u4F7F\u7528 replace_in_file / apply_patch\uFF0C\u4E0D\u8981\u91CD\u590D\u8986\u76D6\u6574\u4E2A\u6587\u4EF6\u3002`;
|
|
857
|
+
var TYPESCRIPT_PLANNER_SYSTEM2 = `\u4F60\u662F XCompiler \u7CFB\u7EDF\u7684 Planner\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u628A\u7528\u6237\u7684\u81EA\u7136\u8BED\u8A00\u9700\u6C42\u7F16\u8BD1\u6210\u4E25\u683C\u7684\u201C\u8FED\u4EE3\u6A21\u578B + V \u6A21\u578B\u201DStep \u8BA1\u5212\u3002
|
|
858
|
+
|
|
859
|
+
\u8F93\u51FA\u8BED\u8A00\uFF1A\u4EC5 TypeScript / Node.js\uFF08plan.language \u56FA\u5B9A\u4E3A "typescript"\uFF09\u3002
|
|
860
|
+
|
|
861
|
+
\u6BCF\u4E2A\u53EF\u6267\u884C\u8FED\u4EE3\u5468\u671F\u5FC5\u987B\u4F7F\u7528\u6807\u51C6 V \u6A21\u578B\u6D41\u7A0B\uFF1A
|
|
862
|
+
REQUIREMENT_ANALYSIS -> HIGH_LEVEL_DESIGN -> DETAILED_DESIGN -> CODE -> UNIT_TEST -> INTEGRATION_TEST -> MODULE_TEST -> FUNCTIONAL_TEST\u3002
|
|
863
|
+
DEBUG \u53EA\u662F\u8FD0\u884C\u65F6\u5931\u8D25\u56DE\u9000/\u4FEE\u590D\u6A21\u5F0F\u3002\u4EFB\u610F\u6D4B\u8BD5\u9636\u6BB5\u5931\u8D25\u65F6\uFF0CXCompiler \u4F1A\u56DE\u9000\u5230\u8BE5\u6D4B\u8BD5\u5BF9\u5E94\u7684\u5DE6\u4FA7\u9636\u6BB5\u5E76\u91CD\u65B0\u6267\u884C\u540E\u7EED\u9636\u6BB5\u3002
|
|
864
|
+
|
|
865
|
+
\u6CBF\u7528 Python Planner \u7684\u9636\u6BB5\u6587\u6863\u548C\u540C\u6B65\u6D4B\u8BD5\u8BBE\u8BA1\u89C4\u5219\uFF1A
|
|
866
|
+
- 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
|
|
869
|
+
- CODE\uFF1A\u5B9E\u73B0\u4EA7\u7269 + \`docs/tests/unit-test-plan.md\`\u3002
|
|
870
|
+
- UNIT_TEST\uFF1A\`docs/05-unit-test.md\`\u3002
|
|
871
|
+
- INTEGRATION_TEST\uFF1A\`docs/06-integration-test.md\`\u3002
|
|
872
|
+
- MODULE_TEST\uFF1A\`docs/07-module-test.md\`\u3002
|
|
873
|
+
- FUNCTIONAL_TEST\uFF1A\`docs/08-functional-test.md\`\u3001\`README.md\`\u3001\`docs/quickstart.md\`\uFF0Clibrary/mixed \u8FD8\u8981 \`docs/api-guide.md\`\u3002
|
|
874
|
+
P2+ \u8FED\u4EE3\u628A\u9636\u6BB5\u6587\u6863\u5199\u5230 \`docs/iterations/<iterationId>/\`\uFF0C\u6D4B\u8BD5\u8BA1\u5212\u5199\u5230 \`docs/iterations/<iterationId>/tests/\`\u3002
|
|
875
|
+
|
|
876
|
+
HIGH_LEVEL_DESIGN \u5FC5\u987B\u8BF4\u660E\u5F53\u524D\u5F00\u53D1\u6A21\u5757\u5728\u6574\u4F53\u7CFB\u7EDF\u4E2D\u7684\u5B9A\u4F4D\uFF0C\u5E76\u5B9A\u4E49\u7CFB\u7EDF\u5C42\u9762\u7684\u5BF9\u5916\u63A5\u53E3\u548C\u4F9D\u8D56\uFF0C\u5305\u62EC\u5916\u90E8 API\u3001\u7B2C\u4E09\u65B9\u5E93\u9009\u578B\u3001\u4F9D\u8D56\u786E\u8BA4\u3001package.json scripts\u3001dependencies/devDependencies\u3001tsconfig\u3001\u6570\u636E\u5951\u7EA6\u548C\u96C6\u6210\u8FB9\u754C\u3002
|
|
877
|
+
DETAILED_DESIGN \u5FC5\u987B\u5B9A\u4E49\u6A21\u5757\u5185\u90E8\u5177\u4F53\u529F\u80FD\u5B9E\u73B0\u548C\u67B6\u6784\uFF0C\u5305\u62EC\u51FD\u6570/\u7C7B\u578B\u3001\u6570\u636E\u7ED3\u6784\u3001\u7B97\u6CD5\u3001\u63A7\u5236\u6D41\u3001\u9519\u8BEF\u5904\u7406\u548C\u5185\u90E8\u534F\u4F5C\u3002
|
|
878
|
+
|
|
879
|
+
\u5F3A\u5236\u89C4\u5219\uFF1A
|
|
880
|
+
1. \u53EA\u8FD4\u56DE\u7EAF JSON\u3002\u7981\u6B62\u8F93\u51FA\u65E7\u9636\u6BB5 REQUIREMENT\u3001ARCH\u3001TASK\u3001TEST\u3001REFACTOR\u3001DELIVERY\u3002
|
|
881
|
+
2. \u6BCF\u4E2A current/planned implementation phase \u90FD\u5FC5\u987B\u5305\u542B\u5B8C\u6574 8 \u9636\u6BB5 V \u6A21\u578B\u3002
|
|
882
|
+
3. \u6BCF\u4E2A\u5B8F Step \u7684 \`subTasks\` \u6700\u591A\u5D4C\u5957 2 \u5C42\u3002
|
|
883
|
+
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
|
|
884
|
+
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
|
+
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
|
+
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
|
|
887
|
+
8. dependencies \u53EA\u662F\u8FD0\u884C\u65F6 npm \u5305\u5EFA\u8BAE\uFF1B\u771F\u6B63\u4F9D\u8D56\u6E05\u5355\u4EE5 HIGH_LEVEL_DESIGN \u4EA7\u51FA\u7684 \`package.json\` \u4E3A\u51C6\uFF0C\u4E0D\u8981\u7F16\u9020\u5305\u540D\u3002
|
|
888
|
+
9. application/mixed \u9700\u8981 \`src/main.ts\` \u4E14\u53EF\u76F4\u63A5 \`node src/main.ts --help\`\uFF1Blibrary/mixed \u9700\u8981 \`src/index.ts\` \u6216\u7B49\u4EF7\u516C\u5171 API \u5E76\u5199 API Guide\u3002
|
|
889
|
+
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
|
+
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
|
+
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
|
|
892
|
+
|
|
893
|
+
\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
|
+
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
|
|
895
|
+
|
|
896
|
+
\u6BCF\u4E00\u8F6E\u4F60\u5FC5\u987B\u8FD4\u56DE\u4E25\u683C JSON\uFF1A
|
|
897
|
+
{
|
|
898
|
+
"thoughts": "<\u7528\u4E00\u53E5\u8BDD\u8BF4\u660E\u672C\u8F6E\u610F\u56FE>",
|
|
899
|
+
"actions": [ { "tool": "<\u5DE5\u5177\u540D>", "args": { ... } }, ... ],
|
|
900
|
+
"done": true | false
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
\u89C4\u5219\uFF1A
|
|
904
|
+
1. \u4EC5\u53EF\u8C03\u7528\u672C Step \u6388\u6743\u7684\u5DE5\u5177\u767D\u540D\u5355\u3002
|
|
905
|
+
2. \u5199\u5165\u6587\u4EF6\u5FC5\u987B\u843D\u5728\u672C Step \u7684 writable allowlist \u5185\uFF08\u5176\u5B83\u8DEF\u5F84\u4F1A\u88AB\u62D2\u7EDD\uFF09\uFF1Brequired outputs \u53EA\u662F\u6700\u7EC8\u5FC5\u987B\u5B58\u5728\u7684\u9A8C\u6536\u4EA7\u7269\u3002
|
|
906
|
+
\u5BF9 FUNCTIONAL_TEST \u6587\u6863\u4EA7\u7269\uFF0C\u5FC5\u987B\u6309\u5F53\u524D i18n \u8BED\u8A00\u5199\u5B8C\u6574\u58F0\u660E\u7684\u6587\u6863\u5305\uFF1AP1 \u8DEF\u5F84\u5982 \`README.md\`\u3001\`docs/quickstart.md\`\u3001\`docs/08-functional-test.md\`\uFF0C\u4EE5\u53CA outputs \u4E2D\u51FA\u73B0\u65F6\u7684 \`docs/api-guide.md\`\uFF1BP2+ \u5219\u5199 outputs \u58F0\u660E\u7684 \`docs/iterations/<iterationId>/\` \u7B49\u4EF7\u8DEF\u5F84\u3002\u4EFB\u4F55\u5DF2\u58F0\u660E\u6587\u6863\u7F3A\u5931\u65F6\u4E0D\u5F97\u8BBE\u7F6E done=true\u3002
|
|
907
|
+
3. \u751F\u6210\u4EE3\u7801\u5FC5\u987B\u7B26\u5408 TypeScript / Node.js \u6700\u4F73\u5B9E\u8DF5\uFF1BAPI \u8981\u6709\u7C7B\u578B\uFF0C\u8FD0\u884C\u4EE3\u7801\u5FC5\u987B\u80FD\u76F4\u63A5\u6267\u884C\u3002
|
|
908
|
+
- \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
|
+
- \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
|
+
- \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
|
|
912
|
+
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
|
+
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
|
+
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
|
|
915
|
+
- \u8D85\u8FC7\u65F6\u8BF7\u62C6\u5206\uFF1A\u540C\u4E00\u8F6E actions \u91CC\u5148\u4E00\u4E2A write_file \u5199\u9996\u6BB5\uFF08import + \u9876\u5C42\u5E38\u91CF + \u7B2C\u4E00\u4E2A\u51FD\u6570/\u7C7B\uFF09\uFF0C\u7D27\u8DDF\u591A\u4E2A append_file \u9010\u6BB5\u8FFD\u52A0\u3002
|
|
916
|
+
- \u590D\u6742\u5DE5\u7A0B\u4F18\u5148\u62C6\u6210\u591A\u4E2A\u5185\u805A\u6A21\u5757/\u6587\u4EF6\uFF0C\u5E76\u7528\u72EC\u7ACB CODE/UNIT_TEST/INTEGRATION_TEST/MODULE_TEST/FUNCTIONAL_TEST Step \u589E\u91CF\u63A8\u8FDB\uFF0C\u4E0D\u8981\u5199\u4E00\u4E2A\u5DE8\u578B\u4E07\u80FD\u6587\u4EF6\u3002
|
|
917
|
+
- \u62C6\u5206\u5FC5\u987B\u4FDD\u8BC1\u62FC\u63A5\u540E TypeScript \u8BED\u6CD5\u5408\u6CD5\uFF1B\u4E25\u7981\u5728\u51FD\u6570\u4F53\u4E2D\u95F4\u62C6\u65AD\u3002
|
|
918
|
+
- \u5BF9\u5DF2\u5B58\u5728\u6587\u4EF6\u7684\u5C40\u90E8\u4FEE\u6539\u4F7F\u7528 replace_in_file / apply_patch\uFF0C\u4E0D\u8981\u91CD\u590D\u8986\u76D6\u6574\u4E2A\u6587\u4EF6\u3002
|
|
919
|
+
7. package.json \u662F\u4F9D\u8D56\u6E05\u5355\u3002\u65B0\u589E npm \u5305\u8981\u7528 add_dependency\uFF0C\u7981\u6B62\u53BB\u5199 requirements.txt\u3002
|
|
920
|
+
8. run_program \u4F1A\u901A\u8FC7 \`npx tsx\` \u8FD0\u884C\u5165\u53E3\uFF0Crun_tests \u4F1A\u901A\u8FC7 \`npm test\` \u8DD1 Vitest\uFF0C\u6700\u7EC8\u4EA4\u4ED8\u95E8\u7981\u8FD8\u4F1A\u9A8C\u8BC1 direct Node \u5165\u53E3\u547D\u4EE4\u3002`;
|
|
921
|
+
function buildPlannerSystem2(profile) {
|
|
922
|
+
return (profile.id === "typescript" ? TYPESCRIPT_PLANNER_SYSTEM2 : PYTHON_PLANNER_SYSTEM2) + profile.plannerPromptOverride;
|
|
923
|
+
}
|
|
924
|
+
function buildExecutorSystem2(profile) {
|
|
925
|
+
return (profile.id === "typescript" ? TYPESCRIPT_EXECUTOR_SYSTEM2 : PYTHON_EXECUTOR_SYSTEM2) + profile.executorPromptOverride;
|
|
926
|
+
}
|
|
927
|
+
var messages2 = {
|
|
928
|
+
llm: {
|
|
929
|
+
coderDebuggerSameModel: (model, coderProvider, debuggerProvider) => `\u6A21\u578B\u914D\u7F6E\u5EFA\u8BAE\uFF1ACoder\uFF08${coderProvider}\uFF09\u548C Debugger\uFF08${debuggerProvider}\uFF09\u5F53\u524D\u90FD\u4F7F\u7528 ${model}\u3002\u5EFA\u8BAE\u914D\u7F6E\u4E0D\u540C\u6A21\u578B\uFF0C\u8BA9\u8C03\u8BD5\u9636\u6BB5\u83B7\u5F97\u72EC\u7ACB\u7684\u63A8\u7406\u8DEF\u5F84\u3002`,
|
|
930
|
+
invalidBaseUrl: (raw, fallback) => `[xcompiler] base_url \u65E0\u6548\uFF08${raw}\uFF09\uFF0C\u56DE\u9000\u5230 ${fallback}`,
|
|
931
|
+
providerValidationFailed: (role, model) => `[${role}] provider ${model} \u8F93\u51FA\u9A8C\u8BC1\u5931\u8D25\uFF0C\u5207\u6362\u5230\u4E0B\u4E00\u4E2A`,
|
|
932
|
+
providerCallFailed: (role, model) => `[${role}] provider ${model} \u8C03\u7528\u5931\u8D25\uFF0C\u5207\u6362\u5230\u4E0B\u4E00\u4E2A`,
|
|
933
|
+
scoreReadFailed: (p, message) => `\u8BFB\u53D6 ${p} \u5931\u8D25\uFF1A${message}`,
|
|
934
|
+
scoreChanged: (provider, score, previous) => `\u8BC4\u5206\uFF08${provider}\uFF09=${score}\uFF08\u539F\u503C ${previous}\uFF09`,
|
|
935
|
+
scorePersistFailed: (message) => `\u6301\u4E45\u5316\u8BC4\u5206\u5931\u8D25\uFF1A${message}`,
|
|
936
|
+
preflightOllamaReachable: (baseUrl, models) => `\u9884\u68C0\uFF1AOllama ${baseUrl} \u53EF\u8FBE\uFF0C\u53D1\u73B0 ${models} \u4E2A\u6A21\u578B`,
|
|
937
|
+
preflightOllamaUnreachable: (baseUrl, message) => `\u9884\u68C0\uFF1AOllama ${baseUrl} \u4E0D\u53EF\u8FBE\uFF1A${message}`,
|
|
938
|
+
preflightAutoAdded: (providers, roles) => `\u9884\u68C0\uFF1A\u81EA\u52A8\u589E\u52A0 ${providers} \u4E2A provider\uFF0C\u8986\u76D6\u89D2\u8272 [${roles}]`,
|
|
939
|
+
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"
|
|
941
|
+
},
|
|
942
|
+
system: {
|
|
943
|
+
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}`,
|
|
944
|
+
unhandledError: (message) => `\u672A\u5904\u7406\u9519\u8BEF\uFF1A${message}`,
|
|
945
|
+
unsupportedPypiOnlyNetwork: "\u62D2\u7EDD network=pypi-only\uFF1ADocker \u672C\u8EAB\u65E0\u6CD5\u53EF\u9760\u6267\u884C\u201C\u4EC5 PyPI\u201D\u57DF\u540D\u767D\u540D\u5355\u3002\u9700\u8981\u9694\u79BB\u8BF7\u4F7F\u7528 network=off\uFF1B\u660E\u786E\u5141\u8BB8\u4EFB\u610F\u51FA\u7AD9\u4E0B\u8F7D\u65F6\u4F7F\u7528 network=download-only\u3002",
|
|
946
|
+
dockerInsideContainerUnsupported: "\u68C0\u6D4B\u5230 XCompiler \u8FD0\u884C\u5728\u5BB9\u5668\u5185\uFF0Csandbox=docker \u53EF\u80FD\u5BFC\u81F4 bind-mount \u8DEF\u5F84\u53CA docker.sock \u6743\u9650\u9519\u4F4D\uFF0C\u56E0\u6B64\u4E0D\u53D7\u652F\u6301\u3002\u8BF7\u4F7F\u7528 agent.sandbox=subprocess\u3001\u6539\u5728\u5BBF\u4E3B\u673A\u8FD0\u884C\uFF0C\u6216\u4EC5\u5728\u53D7\u63A7\u73AF\u5883\u8BBE\u7F6E XC_IN_CONTAINER=0\u3002",
|
|
947
|
+
firejailUnsupported: "\u5C1A\u672A\u5B9E\u73B0 sandbox=firejail\uFF0C\u8BF7\u4F7F\u7528 subprocess \u6216 docker\u3002",
|
|
948
|
+
smokeHeader: (baseUrl) => `\u6B63\u5728\u5BF9 ${baseUrl} \u6267\u884C\u6D41\u5F0F\u5192\u70DF\u6D4B\u8BD5`,
|
|
949
|
+
smokeOk: (model, totalMs, firstTokenMs, chunks, preview) => `[\u6210\u529F \u603B\u8017\u65F6=${totalMs}ms \u9996Token=${firstTokenMs}ms \u5206\u5757=${chunks}] ${model} -> ${preview}`,
|
|
950
|
+
smokeFail: (model, message) => `[\u5931\u8D25] ${model} -> ${message}`
|
|
951
|
+
},
|
|
952
|
+
plugins: {
|
|
953
|
+
invalidId: (id) => `\u63D2\u4EF6 ID\u201C${id}\u201D\u65E0\u6548\uFF1B\u4EC5\u5141\u8BB8\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u70B9\u3001\u8FDE\u5B57\u7B26\u6216\u4E0B\u5212\u7EBF\u3002`,
|
|
954
|
+
duplicateId: (id) => `\u63D2\u4EF6 ID \u91CD\u590D\uFF1A${id}`,
|
|
955
|
+
invalidVersion: (plugin, version) => `\u63D2\u4EF6 ${plugin} \u7684\u7248\u672C\u4E0D\u662F\u6709\u6548 SemVer\uFF1A${version}`,
|
|
956
|
+
invalidCoreVersion: (version) => `XCompiler \u6838\u5FC3\u7248\u672C\u4E0D\u662F\u6709\u6548 SemVer\uFF1A${version}`,
|
|
957
|
+
apiVersionMismatch: (plugin, actual, expected) => `\u63D2\u4EF6 ${plugin} \u9762\u5411 Plugin API ${actual}\uFF0C\u5F53\u524D XCompiler \u8FD0\u884C\u65F6\u8981\u6C42 API ${expected}\u3002`,
|
|
958
|
+
invalidMinimumVersion: (plugin, version) => `\u63D2\u4EF6 ${plugin} \u58F0\u660E\u7684\u6700\u4F4E XCompiler \u7248\u672C\u65E0\u6548\uFF1A${version}`,
|
|
959
|
+
coreVersionTooOld: (plugin, minimum, actual) => `\u63D2\u4EF6 ${plugin} \u8981\u6C42 XCompiler >= ${minimum}\uFF0C\u5F53\u524D\u7248\u672C\u4E3A ${actual}\u3002`,
|
|
960
|
+
loaded: (plugin, version) => `\u63D2\u4EF6 ${plugin}@${version} \u5DF2\u52A0\u8F7D\u3002`,
|
|
961
|
+
extensionConflict: (plugin, kind, name) => `\u63D2\u4EF6 ${plugin} \u4E0D\u80FD\u8986\u76D6\u5DF2\u6709 ${kind} \u201C${name}\u201D\u3002`,
|
|
962
|
+
hookFailed: (plugin, stage, message) => `\u63D2\u4EF6 ${plugin} \u5728 ${stage} \u9636\u6BB5\u6267\u884C\u5931\u8D25\uFF1A${message}`,
|
|
963
|
+
manifestReadFailed: (path2, message) => `\u65E0\u6CD5\u8BFB\u53D6\u63D2\u4EF6\u6E05\u5355 ${path2}\uFF1A${message}`,
|
|
964
|
+
moduleLoadFailed: (plugin, path2, message) => `\u65E0\u6CD5\u4ECE ${path2} \u52A0\u8F7D\u63D2\u4EF6 ${plugin}\uFF1A${message}`,
|
|
965
|
+
exportInvalid: (plugin, exportName) => `\u63D2\u4EF6 ${plugin} \u7684\u5BFC\u51FA ${exportName} \u4E0D\u662F\u6709\u6548 XCompiler \u63D2\u4EF6`,
|
|
966
|
+
manifestMismatch: (plugin) => `\u63D2\u4EF6 ${plugin} \u7684\u8FD0\u884C\u65F6\u6E05\u5355\u4E0E\u9884\u68C0\u6E05\u5355\u4E0D\u4E00\u81F4`
|
|
967
|
+
},
|
|
968
|
+
audit: {
|
|
969
|
+
processLogTitle: "# XCompiler \u5F00\u53D1\u8FC7\u7A0B\u8BB0\u5F55",
|
|
970
|
+
processLogPreamble: "> \u7531 XCompiler \u81EA\u52A8\u751F\u6210\uFF0C\u8BB0\u5F55 CLI \u4F1A\u8BDD\u3001\u7528\u6237\u8F93\u5165\u3001LLM \u4EA4\u4E92\u4E0E\u6267\u884C\u52A8\u4F5C\uFF0C\u7528\u4E8E\u4EA4\u4ED8\u8FFD\u8E2A\u3002",
|
|
971
|
+
sessionStart: (ts, command) => `## \u25B6 \u4F1A\u8BDD ${ts} \u2014 \`${command}\``,
|
|
972
|
+
sessionEnd: (ts) => `### \u25C0 \u4F1A\u8BDD\u7ED3\u675F ${ts}`,
|
|
973
|
+
eventSessionStart: (command) => `\u542F\u52A8 ${command}`,
|
|
974
|
+
eventSessionEnd: (command) => `\u7ED3\u675F ${command}`,
|
|
975
|
+
userInput: (label) => `#### \u{1F464} \u7528\u6237\u8F93\u5165 \u2014 ${label}`,
|
|
976
|
+
llmRequest: (role, model) => `\u{1F916} LLM \u8BF7\u6C42 \u2014 <code>${role}</code> \u4F7F\u7528 <code>${model}</code>`,
|
|
977
|
+
llmResponse: (role, model) => `\u{1F4E9} LLM \u54CD\u5E94 \u2014 <code>${role}</code> \u4F7F\u7528 <code>${model}</code>`,
|
|
978
|
+
executorTurn: (stepId, round, role, provider, actions, done) => `\u{1F9E0} \u6267\u884C\u8F6E\u6B21 \u2014 <code>${stepId}</code> \u7B2C ${round} \u8F6E / \u89D2\u8272 <code>${role}</code>${provider ? ` \xB7 \u4F7F\u7528 <code>${provider}</code>` : ""}\uFF08actions=${actions}, done=${done}\uFF09`,
|
|
979
|
+
thoughtsLabel: "**\u601D\u8003\uFF1A**",
|
|
980
|
+
actionsLabel: "**\u52A8\u4F5C\uFF1A**",
|
|
981
|
+
noThoughts: "\uFF08\u65E0\u601D\u8003\u5185\u5BB9\uFF09",
|
|
982
|
+
plannerThought: (stage, provider) => `\u{1F9E9} Planner \u601D\u8003 \u2014 ${stage}${provider ? ` \xB7 \u4F7F\u7528 <code>${provider}</code>` : ""}`,
|
|
983
|
+
markdownAppendFailed: (message) => `[audit] Markdown \u8FFD\u52A0\u5931\u8D25\uFF1A${message}`,
|
|
984
|
+
jsonlAppendFailed: (message) => `[audit] JSONL \u8FFD\u52A0\u5931\u8D25\uFF1A${message}`,
|
|
985
|
+
traceLine: (kind, message) => `[audit] ${kind} ${message}`,
|
|
986
|
+
autoFixedSrcImport: (p) => `\u5DF2\u81EA\u52A8\u4FEE\u590D ${p} \u4E2D\u7684 src import`,
|
|
987
|
+
wroteFile: (p) => `\u5DF2\u5199\u5165 ${p}`,
|
|
988
|
+
userDecision: (label, value) => `${label} \u2192 ${value}`,
|
|
989
|
+
eventLlmRequest: (role, model) => `${role} \u2192 ${model}`,
|
|
990
|
+
eventLlmResponse: (role, model) => `${role} \u2190 ${model}`,
|
|
991
|
+
eventLlmError: (role, model, message) => `${role} \u4F7F\u7528 ${model}\uFF1A${message}`,
|
|
992
|
+
eventExecutorTurn: (stepId, round, role, provider) => `${stepId} \u8F6E\u6B21=${round} \u89D2\u8272=${role}${provider ? ` \u4F7F\u7528 ${provider}` : ""}`,
|
|
993
|
+
eventPlannerThought: (stage, provider) => `Planner ${stage}${provider ? ` \u4F7F\u7528 ${provider}` : ""}`,
|
|
994
|
+
llmChatFailedThought: (message) => `LLM \u8C03\u7528\u5931\u8D25\uFF1A${message}`,
|
|
995
|
+
llmChatAborted: (stepId, round, chars, message) => `${stepId} \u7B2C ${round} \u8F6E\u5728\u6536\u5230 ${chars} \u5B57\u7B26\u540E\u4E2D\u6B62\uFF1A${message}`,
|
|
996
|
+
toolDenied: (tool) => `\u62D2\u7EDD\u8C03\u7528\u5DE5\u5177 ${tool}`,
|
|
997
|
+
toolCalled: (tool) => `\u8C03\u7528\u5DE5\u5177 ${tool}`,
|
|
998
|
+
toolResult: (tool, ok, detail) => `\u5DE5\u5177 ${tool}${ok ? "\u6267\u884C\u6210\u529F" : "\u6267\u884C\u5931\u8D25"}\uFF1A${detail}`,
|
|
999
|
+
documentArchived: (from, to) => `\u5DF2\u5F52\u6863 ${from} \u2192 ${to}`,
|
|
1000
|
+
documentArchiveFailed: (p, message) => `\u5F52\u6863 ${p} \u5931\u8D25\uFF1A${message}`,
|
|
1001
|
+
httpFetchSaved: (method, url, p, bytes) => `http_fetch ${method} ${url} \u2192 ${p}\uFF08${bytes} \u5B57\u8282\uFF09`,
|
|
1002
|
+
httpFetchResponse: (method, url, status, bytes) => `http_fetch ${method} ${url} \u2192 ${status}\uFF08${bytes} \u5B57\u8282\uFF09`,
|
|
1003
|
+
partialFailureHeader: (message) => `# LLM \u8C03\u7528\u5931\u8D25\uFF1A${message}`,
|
|
1004
|
+
streamLength: (chars) => `# \u6D41\u5F0F\u54CD\u5E94\u957F\u5EA6\uFF1A${chars} \u5B57\u7B26`
|
|
1005
|
+
},
|
|
1006
|
+
stream: {
|
|
1007
|
+
resolvingModel: "\u6B63\u5728\u89E3\u6790\u6A21\u578B",
|
|
1008
|
+
waiting: "\u7B49\u5F85\u54CD\u5E94",
|
|
1009
|
+
streaming: "\u6D41\u5F0F\u54CD\u5E94",
|
|
1010
|
+
done: "\u5B8C\u6210",
|
|
1011
|
+
failed: "\u5931\u8D25",
|
|
1012
|
+
chars: (n) => `${n} \u5B57\u7B26`,
|
|
1013
|
+
toolRunner: "\u672C\u5730\u5DE5\u5177",
|
|
1014
|
+
toolExecution: (stepId, tool) => `${stepId} \u5DE5\u5177 ${tool}`
|
|
1015
|
+
},
|
|
1016
|
+
sandboxLog: {
|
|
1017
|
+
subprocessBuilt: (deps) => `\u5B50\u8FDB\u7A0B\u6C99\u7BB1\u5DF2\u6784\u5EFA\uFF08${deps ? "\u542B\u4F9D\u8D56" : "\u7A7A\u73AF\u5883"}\uFF09`,
|
|
1018
|
+
subprocessNodeBuilt: "Node \u5B50\u8FDB\u7A0B\u6C99\u7BB1\u5DF2\u6784\u5EFA\uFF08npm install\uFF09",
|
|
1019
|
+
dockerBuilt: (deps) => `Docker \u6C99\u7BB1\u5DF2\u6784\u5EFA\uFF08${deps ? "\u542B\u4F9D\u8D56" : "\u7A7A\u73AF\u5883"}\uFF09`,
|
|
1020
|
+
dockerNodeBuilt: "Docker Node \u6C99\u7BB1\u5DF2\u6784\u5EFA\uFF08npm install\uFF09",
|
|
1021
|
+
command: (runtime, command) => `${runtime} ${command}`
|
|
1022
|
+
},
|
|
1023
|
+
cli: {
|
|
1024
|
+
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",
|
|
1027
|
+
loadDescription: "\u52A0\u8F7D XXX.xc \u5DE5\u7A0B\u6587\u4EF6\u5E76\u7EE7\u7EED\u5F53\u524D plan",
|
|
1028
|
+
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",
|
|
1030
|
+
showDescription: "\u6253\u5370 Step \u5B9A\u4E49 / \u72B6\u6001 / \u4EA7\u7269 / \u6700\u8FD1\u5BA1\u8BA1",
|
|
1031
|
+
optWorkspace: "workspace \u76EE\u5F55\uFF08\u540C --output\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55\uFF09",
|
|
1032
|
+
optOutput: "\u5DE5\u7A0B/workspace \u8F93\u51FA\u76EE\u5F55\uFF08\u4F18\u5148\u7EA7\u6700\u9AD8\uFF0C\u7B49\u4EF7\u4E8E -w\uFF09",
|
|
1033
|
+
optConfig: "config.yaml \u8DEF\u5F84",
|
|
1034
|
+
optInput: "\u4ECE\u9700\u6C42\u6587\u4EF6\u8BFB\u53D6\uFF08\u975E\u4EA4\u4E92\uFF09",
|
|
1035
|
+
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",
|
|
1037
|
+
optBaseDir: "\u9879\u76EE\u8F93\u51FA\u6839\u76EE\u5F55\uFF08\u5728\u5176\u4E0B\u521B\u5EFA <name> \u5B50\u76EE\u5F55\uFF09",
|
|
1038
|
+
optName: "\u9879\u76EE\u540D\uFF08\u9ED8\u8BA4 xcompiler-<\u65F6\u95F4\u6233>\uFF09",
|
|
1039
|
+
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",
|
|
1041
|
+
optDryRun: "\u4EC5\u6253\u5370\u62D3\u6251\u987A\u5E8F\uFF0C\u4E0D\u6267\u884C",
|
|
1042
|
+
optFrom: "\u4ECE\u6307\u5B9A Step \u5F00\u59CB\uFF08\u4E4B\u524D\u7684\u8DF3\u8FC7\uFF09",
|
|
1043
|
+
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
|
+
optReset: "\u91CD\u7F6E\u6240\u6709 Step \u72B6\u6001\u4E3A PENDING",
|
|
1045
|
+
optMaxDepth: "\u9012\u5F52\u6700\u5927\u6DF1\u5EA6",
|
|
1046
|
+
optTail: "\u6700\u8FD1\u5BA1\u8BA1\u6761\u6570",
|
|
1047
|
+
optPlan: "plan.json \u8DEF\u5F84\uFF0C\u9ED8\u8BA4 <workspace>/plan.json",
|
|
1048
|
+
optLang: "UI / \u63D0\u793A\u8BCD\u8BED\u8A00\uFF1AEN | CN\uFF08ISO 3166-1 Alpha-2\uFF09",
|
|
1049
|
+
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",
|
|
1051
|
+
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",
|
|
1053
|
+
argProjectFile: "XXX.xc \u5DE5\u7A0B\u6587\u4EF6",
|
|
1054
|
+
argStepId: "Step ID\uFF0C\u5982 S001",
|
|
1055
|
+
evolveDescription: "\u5728\u73B0\u6709 workspace \u57FA\u7840\u4E0A\u751F\u6210\u5E76\u6267\u884C\u589E\u91CF feature/refactor \u8BA1\u5212",
|
|
1056
|
+
bootstrapDescription: "\u5728\u9694\u79BB Git worktree \u4E2D\u6784\u5EFA\u5E76\u9A8C\u8BC1\u4E0B\u4E00\u4EE3 XCompiler",
|
|
1057
|
+
optRepository: "\u8981\u6267\u884C\u81EA\u4E3E\u7684 XCompiler Git \u4ED3\u5E93\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09",
|
|
1058
|
+
optPromote: "\u5168\u90E8\u8D28\u91CF\u95E8\u901A\u8FC7\u540E\uFF0C\u5FEB\u8FDB\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F",
|
|
1059
|
+
optCleanup: "\u5199\u5165\u62A5\u544A\u540E\u5220\u9664\u9694\u79BB worktree\uFF08\u4FDD\u7559\u5019\u9009\u5206\u652F\uFF09",
|
|
1060
|
+
optDockerQualification: "\u4F7F\u7528\u5C1A\u5904\u4E8E\u5B9E\u9A8C\u9636\u6BB5\u7684 Docker \u73AF\u5883\u6267\u884C\u5019\u9009\u8D28\u91CF\u95E8",
|
|
1061
|
+
invalidLocale: (value) => `\u4E0D\u652F\u6301\u7684\u8BED\u8A00\u201C${value}\u201D\uFF0C\u8BF7\u4F7F\u7528 EN \u6216 CN\u3002`,
|
|
1062
|
+
invalidIntent: (value, allowed) => `\u65E0\u6548 intent\u201C${value}\u201D\uFF0C\u53EF\u9009\u503C\uFF1A${allowed}\u3002`,
|
|
1063
|
+
invalidPhase: (value, allowed) => `\u65E0\u6548\u9636\u6BB5\u201C${value}\u201D\uFF0C\u53EF\u9009\u503C\uFF1A${allowed}\u3002`,
|
|
1064
|
+
invalidStepId: (value) => `\u65E0\u6548 Step ID\u201C${value}\u201D\uFF0C\u683C\u5F0F\u5E94\u4E3A S \u52A0\u81F3\u5C11\u4E09\u4F4D\u6570\u5B57\u3002`,
|
|
1065
|
+
invalidNonNegativeInteger: (value) => `\u53C2\u6570\u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570\uFF0C\u5F53\u524D\u503C\u4E3A\u201C${value}\u201D\u3002`,
|
|
1066
|
+
helpUsage: "\u7528\u6CD5\uFF1A",
|
|
1067
|
+
helpArguments: "\u53C2\u6570\uFF1A",
|
|
1068
|
+
helpOptions: "\u9009\u9879\uFF1A",
|
|
1069
|
+
helpCommands: "\u547D\u4EE4\uFF1A",
|
|
1070
|
+
helpOption: "\u663E\u793A\u547D\u4EE4\u5E2E\u52A9",
|
|
1071
|
+
versionOption: "\u8F93\u51FA\u7248\u672C\u53F7",
|
|
1072
|
+
defaultValue: (value) => `\uFF08\u9ED8\u8BA4\u503C\uFF1A${value}\uFF09`
|
|
1073
|
+
},
|
|
1074
|
+
bootstrap: {
|
|
1075
|
+
notGitRepository: (p) => `\u4E0D\u662F Git \u4ED3\u5E93\uFF1A${p}`,
|
|
1076
|
+
dirtyRepository: (files) => `\u529F\u80FD\u81EA\u4E3E\u8981\u6C42\u5BBF\u4E3B\u4ED3\u5E93\u4FDD\u6301\u5E72\u51C0\uFF0C\u5F85\u5904\u7406\u8DEF\u5F84\uFF1A${files}`,
|
|
1077
|
+
worktreeReady: (p, branch) => `\u81EA\u4E3E worktree \u5DF2\u5C31\u7EEA\uFF1A${p}\uFF08${branch}\uFF09`,
|
|
1078
|
+
compileStarted: "\u6B63\u5728\u7F16\u8BD1\u81EA\u4E3E V \u6A21\u578B\u8BA1\u5212\u2026",
|
|
1079
|
+
compileFailed: (code, message) => `\u81EA\u4E3E\u8BA1\u5212\u7F16\u8BD1\u5931\u8D25\uFF08exit=${code}\uFF09\uFF1A${message}`,
|
|
1080
|
+
compileCancelled: "\u81EA\u4E3E\u8BA1\u5212\u5C1A\u672A\u786E\u8BA4\uFF0C\u5DF2\u53D6\u6D88\u6267\u884C\u3002",
|
|
1081
|
+
executeStarted: "\u6B63\u5728\u9694\u79BB worktree \u4E2D\u6267\u884C\u5019\u9009\u7248\u672C\u2026",
|
|
1082
|
+
executeFailed: (status) => `\u5019\u9009\u7248\u672C\u6267\u884C\u672A\u6210\u529F\u5B8C\u6210\uFF08${status}\uFF09\u3002`,
|
|
1083
|
+
qualificationStarted: "\u6B63\u5728\u6267\u884C\u786E\u5B9A\u6027\u81EA\u4E3E\u8D28\u91CF\u95E8\u2026",
|
|
1084
|
+
qualificationDockerExperimental: "Docker \u8D28\u91CF\u95E8\u73AF\u5883\u5C1A\u672A\u5B8C\u6210\u9A8C\u8BC1\uFF0C\u672C\u6B21\u6309\u663E\u5F0F\u9009\u9879\u4EE5\u5B9E\u9A8C\u6A21\u5F0F\u6267\u884C\u3002",
|
|
1085
|
+
missingScript: (name) => `package.json \u7F3A\u5C11\u5FC5\u9009\u811A\u672C\uFF1A${name}`,
|
|
1086
|
+
missingBin: "package.json \u672A\u58F0\u660E CLI bin \u5165\u53E3",
|
|
1087
|
+
checkPassed: (name, ms) => `${name} \u901A\u8FC7\uFF08${ms}ms\uFF09`,
|
|
1088
|
+
checkFailed: (name, code) => `${name} \u5931\u8D25\uFF08exit=${code}\uFF09`,
|
|
1089
|
+
reportWritten: (p) => `\u81EA\u4E3E\u62A5\u544A\u5DF2\u5199\u5165\uFF1A${p}`,
|
|
1090
|
+
candidateReady: (branch) => `\u5019\u9009\u7248\u672C\u5DF2\u5728 ${branch} \u901A\u8FC7\u9A8C\u8BC1\uFF1B\u4ECD\u9700\u663E\u5F0F\u4F7F\u7528 --promote \u624D\u4F1A\u664B\u7EA7\u3002`,
|
|
1091
|
+
promoted: (branch) => `\u5019\u9009\u7248\u672C\u5DF2\u901A\u8FC7\u5FEB\u8FDB\u5408\u5E76\u5B8C\u6210\u664B\u7EA7\uFF1A${branch}`,
|
|
1092
|
+
cleanupDone: (p) => `\u81EA\u4E3E worktree \u5DF2\u5220\u9664\uFF1A${p}`,
|
|
1093
|
+
promotionBlocked: "\u5B58\u5728\u672A\u901A\u8FC7\u7684\u8D28\u91CF\u95E8\uFF0C\u7981\u6B62\u664B\u7EA7\u5019\u9009\u7248\u672C\u3002",
|
|
1094
|
+
hostHeadChanged: "\u81EA\u4E3E\u671F\u95F4\u5BBF\u4E3B HEAD \u5DF2\u53D8\u5316",
|
|
1095
|
+
candidateDirty: (files) => `\u5019\u9009 worktree \u5B58\u5728\u672A\u63D0\u4EA4\u53D8\u66F4\uFF1A${files}`,
|
|
1096
|
+
candidateStatusUnknown: "\uFF08\u672A\u77E5\u8DEF\u5F84\uFF09",
|
|
1097
|
+
candidateMoved: (expected, actual) => `\u8D28\u91CF\u95E8\u4E4B\u540E\u5019\u9009\u63D0\u4EA4\u53D1\u751F\u6F02\u79FB\uFF08\u9884\u671F ${expected}\uFF0C\u5B9E\u9645 ${actual}\uFF09\u3002`,
|
|
1098
|
+
candidateNotBasedOnBase: (candidate, base) => `\u5019\u9009\u63D0\u4EA4 ${candidate} \u4E0D\u662F\u81EA\u4E3E\u57FA\u7EBF ${base} \u7684\u540E\u4EE3\u3002`,
|
|
1099
|
+
promotionVerificationFailed: (expected, actual) => `\u664B\u7EA7\u540E HEAD \u6821\u9A8C\u5931\u8D25\uFF08\u9884\u671F ${expected}\uFF0C\u5B9E\u9645 ${actual}\uFF09\u3002`,
|
|
1100
|
+
reportTitle: "XCompiler \u529F\u80FD\u81EA\u4E3E\u62A5\u544A",
|
|
1101
|
+
reportNone: "\uFF08\u65E0\uFF09",
|
|
1102
|
+
reportNextQualified: (repository, candidateCommit) => `git -C "${repository}" merge --ff-only "${candidateCommit}"`,
|
|
1103
|
+
reportNextPromoted: "\u4F7F\u7528\u5DF2\u664B\u7EA7\u7248\u672C\u6267\u884C\u4E0B\u4E00\u8F6E\u529F\u80FD\u81EA\u4E3E\u3002",
|
|
1104
|
+
reportNextFailed: "\u68C0\u67E5\u5019\u9009 worktree\uFF0C\u4FEE\u590D\u5931\u8D25\u8D28\u91CF\u95E8\u540E\u518D\u664B\u7EA7\u3002",
|
|
1105
|
+
reportLabels: {
|
|
1106
|
+
status: "\u72B6\u6001",
|
|
1107
|
+
repository: "\u4ED3\u5E93",
|
|
1108
|
+
baseCommit: "\u57FA\u7EBF\u63D0\u4EA4",
|
|
1109
|
+
candidateCommit: "\u5019\u9009\u63D0\u4EA4",
|
|
1110
|
+
branch: "\u5019\u9009\u5206\u652F",
|
|
1111
|
+
worktree: "\u9694\u79BB\u5DE5\u4F5C\u533A",
|
|
1112
|
+
createdAt: "\u521B\u5EFA\u65F6\u95F4",
|
|
1113
|
+
checks: "\u8D28\u91CF\u95E8",
|
|
1114
|
+
changedFiles: "\u53D8\u66F4\u6587\u4EF6",
|
|
1115
|
+
nextStep: "\u4E0B\u4E00\u6B65"
|
|
1116
|
+
}
|
|
1117
|
+
},
|
|
1118
|
+
compile: {
|
|
1119
|
+
workspaceReady: (p) => `\u5DE5\u4F5C\u533A\uFF1A${p}`,
|
|
1120
|
+
forceOverride: "--force\uFF1A\u8986\u76D6\u5DE5\u4F5C\u533A\u9501\u5E76\u91CD\u65B0\u751F\u6210\u8BA1\u5212\u3002",
|
|
1121
|
+
topicInputConflict: "\u540C\u65F6\u63D0\u4F9B\u4E86 --topic \u548C --input\uFF1B\u4F18\u5148\u4F7F\u7528 --topic\uFF0C\u5FFD\u7565 --input\u3002",
|
|
1122
|
+
auditTopicInput: "topic.md\uFF08--topic\uFF09",
|
|
1123
|
+
auditOriginalRequirement: "\u539F\u59CB\u9700\u6C42\uFF08Intake\uFF09",
|
|
1124
|
+
auditUserAddenda: "\u7528\u6237\u8865\u5145\u9700\u6C42",
|
|
1125
|
+
auditEditedTopic: "\u5DF2\u7F16\u8F91 topic.md",
|
|
1126
|
+
auditTopicPersisted: (p) => `topic.md \u5DF2\u5199\u5165\uFF1A${p}`,
|
|
1127
|
+
auditDecomposeFailed: "planner.decompose \u5931\u8D25",
|
|
1128
|
+
lintIssue: (id, message) => ` - [${id}] ${message}`,
|
|
1129
|
+
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}`,
|
|
1131
|
+
projectFileWritten: (p) => `\u5DE5\u7A0B\u6587\u4EF6\u5DF2\u66F4\u65B0\uFF1A${p}`,
|
|
1132
|
+
nextCommand: (command) => ` \u4E0B\u4E00\u6B65\uFF1A${command}`,
|
|
1133
|
+
topicEmptyExit: "--topic \u6587\u4EF6\u4E3A\u7A7A\uFF0C\u5DF2\u9000\u51FA\u3002",
|
|
1134
|
+
topicLoaded: (p) => `\u5DF2\u52A0\u8F7D topic\uFF1A${p}\uFF08\u8DF3\u8FC7 intake / clarify / Gate 1\uFF09`,
|
|
1135
|
+
requirementEmptyExit: "\u9700\u6C42\u4E3A\u7A7A\uFF0C\u5DF2\u9000\u51FA\u3002",
|
|
1136
|
+
requirementInputHint: "\u8BF7\u63CF\u8FF0\u4F60\u7684\u9700\u6C42\uFF08\u591A\u884C\uFF0C\u8F93\u5165\u7A7A\u884C\u7ED3\u675F\uFF09:",
|
|
1137
|
+
spinClarify: "Planner \u6B63\u5728\u6F84\u6E05\u9700\u6C42\u2026",
|
|
1138
|
+
clarifySucceed: (n) => `\u6F84\u6E05\u95EE\u9898\uFF1A${n} \u6761`,
|
|
1139
|
+
clarifyFail: "\u6F84\u6E05\u5931\u8D25",
|
|
1140
|
+
clarifyChoiceHint: (range) => `\u8F93\u5165 ${range} \u9009\u62E9\u5DF2\u5C55\u793A\u9009\u9879\uFF0C\u6216\u76F4\u63A5\u8F93\u5165\u81EA\u5B9A\u4E49\u56DE\u7B54\u5185\u5BB9\u3002`,
|
|
1141
|
+
addendaConfirm: "\u662F\u5426\u6709\u8865\u5145\u9700\u6C42\u8981\u8FFD\u52A0\uFF1F\uFF08\u4F1A\u8FDE\u540C\u6F84\u6E05\u4E00\u8D77\u53D1\u7ED9 Planner\uFF0C\u5E76\u4FDD\u7559\u5728 plan.userAddenda \u5B57\u6BB5\uFF09",
|
|
1142
|
+
addendaEditorMsg: "\u8F93\u5165\u81EA\u5B9A\u4E49\u8865\u5145\u9700\u6C42\uFF08\u591A\u884C\u3001Markdown \u53EF\uFF09",
|
|
1143
|
+
auditClarifyAnswer: (qid, q) => `\u6F84\u6E05\u56DE\u7B54 ${qid}: ${q}`,
|
|
1144
|
+
spinDecompose: "Planner \u6B63\u5728\u6309 V \u6A21\u578B\u62C6\u89E3\u2026",
|
|
1145
|
+
decomposeFail: "Planner \u62C6\u89E3\u5931\u8D25",
|
|
1146
|
+
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",
|
|
1149
|
+
decomposeSucceed: (n) => `\u5DF2\u751F\u6210 ${n} \u4E2A Step`,
|
|
1150
|
+
schemaFail: "Plan schema \u6821\u9A8C\u5931\u8D25\uFF1A",
|
|
1151
|
+
schemaInvalidSavedAt: (p) => ` \u5B8C\u6574 plan \u5DF2\u843D\u76D8\uFF1A${p}`,
|
|
1152
|
+
lintFail: (n) => `Plan lint \u5931\u8D25\uFF08${n}\uFF09\uFF1A`,
|
|
1153
|
+
topicPreviewHeader: "\u2500\u2500\u2500 topic.md (preview) \u2500\u2500\u2500",
|
|
1154
|
+
topicPreviewFooter: "\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\u2500\u2500\u2500\u2500\u2500",
|
|
1155
|
+
gate1Confirm: "\u9700\u6C42\u662F\u5426\u7B26\u5408\u9884\u671F?",
|
|
1156
|
+
gate1ChoiceConfirm: "\u2705 confirm \u2014 \u8FDB\u5165\u8BA1\u5212\u751F\u6210",
|
|
1157
|
+
gate1ChoiceEdit: "\u270F\uFE0F edit \u2014 \u6253\u5F00\u7F16\u8F91\u5668\u4FEE\u6539",
|
|
1158
|
+
gate1ChoiceCancel: "\u274C cancel \u2014 \u653E\u5F03\u672C\u6B21\u4F1A\u8BDD",
|
|
1159
|
+
gate1AuditLabel: "\u9700\u6C42\u786E\u8BA4\u95E8 (Gate 1)",
|
|
1160
|
+
gate1Cancelled: "\u5DF2\u53D6\u6D88\uFF0C\u672A\u5199\u5165\u4EFB\u4F55\u6587\u4EF6\u3002",
|
|
1161
|
+
editTopicMsg: "\u7F16\u8F91 topic.md",
|
|
1162
|
+
topicWritten: (p) => `\u5DF2\u5199\u5165 ${p}`,
|
|
1163
|
+
planWritten: (p) => `plan \u5DF2\u5199\u5165 ${p}`,
|
|
1164
|
+
planPreviewHeader: "\u2500\u2500\u2500 plan.md (preview) \u2500\u2500\u2500",
|
|
1165
|
+
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)",
|
|
1167
|
+
gate2AuditLabel: "\u8BA1\u5212\u786E\u8BA4\u95E8 (Gate 2)",
|
|
1168
|
+
gate2Rejected: "\u672A\u786E\u8BA4\uFF0C\u5DF2\u653E\u5F03\u3002plan.json \u672A\u5199\u5165\u3002",
|
|
1169
|
+
baselineLoaded: (kind, sources) => `\u5DF2\u52A0\u8F7D ${kind} \u57FA\u7EBF\uFF1A${sources}`,
|
|
1170
|
+
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
|
+
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`,
|
|
1172
|
+
topicTitle: "# Project Topic (\u9879\u76EE\u9009\u9898)",
|
|
1173
|
+
topicPreamble: "> \u672C\u6587\u4EF6\u662F\u9700\u6C42\u6F84\u6E05\u540E\u51BB\u7ED3\u7684\u9879\u76EE\u9009\u9898\uFF0C\u540E\u7EED V \u6A21\u578B\u62C6\u89E3\u4E0E\u6240\u6709\u9636\u6BB5\u4EA7\u51FA\u7686\u4EE5\u672C\u6587\u4EF6\u4E3A\u552F\u4E00\u9700\u6C42\u8F93\u5165\u3002",
|
|
1174
|
+
topicSecRequirement: "## \u539F\u59CB\u9700\u6C42",
|
|
1175
|
+
topicSecClarify: "## \u6F84\u6E05\u8BB0\u5F55",
|
|
1176
|
+
topicSecAddenda: "## \u7528\u6237\u8865\u5145\u9700\u6C42 (Addenda)",
|
|
1177
|
+
topicSecBaseline: "## \u73B0\u6709\u5DE5\u7A0B\u57FA\u7EBF"
|
|
1178
|
+
},
|
|
1179
|
+
inspect: {
|
|
1180
|
+
noPlanFound: "\u672A\u627E\u5230\u4EFB\u4F55 plan.json",
|
|
1181
|
+
digestLabel: "digest:",
|
|
1182
|
+
stepNotFound: (id) => `Step ${id} \u672A\u627E\u5230`,
|
|
1183
|
+
secDescription: "\u2014 description \u2014",
|
|
1184
|
+
secAcceptance: "\u2014 acceptance \u2014",
|
|
1185
|
+
secSubtasks: "\u2014 subtasks \u2014",
|
|
1186
|
+
secSystemPrompt: "\u2014 systemPrompt \u2014",
|
|
1187
|
+
secOutputs: "\u2014 outputs \u2014",
|
|
1188
|
+
secRecentAudit: (n) => `\u2014 recent audit (${n}) \u2014`,
|
|
1189
|
+
planHeader: (p, language) => `${p} \u8BED\u8A00=${language}`,
|
|
1190
|
+
planStatusSummary: (total, done, pending, failed, skipped, running) => `\u6B65\u9AA4=${total} \u5B8C\u6210=${done} \u5F85\u6267\u884C=${pending} \u5931\u8D25=${failed} \u8DF3\u8FC7=${skipped} \u8FD0\u884C\u4E2D=${running}`,
|
|
1191
|
+
planReadFailed: (p, message) => `${p} \u2014 ${message}`,
|
|
1192
|
+
stepHeader: (id, phase, title, status, retries, maxRetries) => `${id} ${phase} ${title} ${status} \u91CD\u8BD5=${retries}/${maxRetries}`,
|
|
1193
|
+
stepRoleTools: (role, tools) => `\u89D2\u8272=${role} \u5DE5\u5177=[${tools}]`,
|
|
1194
|
+
stepDependsOn: (ids) => `\u4F9D\u8D56\uFF1A${ids}`,
|
|
1195
|
+
outputStatus: (exists, p) => `${exists ? "\u2713" : "\u2717"} ${p}`,
|
|
1196
|
+
auditEntry: (ts, kind, message) => `${ts} ${kind} ${message}`
|
|
1197
|
+
},
|
|
1198
|
+
execute: {
|
|
1199
|
+
forceReset: "--force\uFF1A\u91CD\u7F6E\u6240\u6709 Step \u4E3A PENDING\uFF0C\u5E76\u8986\u76D6\u5DE5\u4F5C\u533A\u9501\u3002",
|
|
1200
|
+
manifestRecalibrated: (p) => `\u5DF2\u91CD\u65B0\u6821\u51C6 ${p}\uFF08\u79FB\u9664\u7248\u672C\u9501\u548C\u5E7B\u89C9\u5305\u540D\uFF09`,
|
|
1201
|
+
manifestSeeded: (p) => `\u5DF2\u6839\u636E plan.dependencies \u751F\u6210 ${p}`,
|
|
1202
|
+
auditPlanLoaded: (p) => `\u5DF2\u52A0\u8F7D plan\uFF1A${p}`,
|
|
1203
|
+
planLoaded: (p) => `\u5DF2\u52A0\u8F7D Plan\uFF1A${p}`,
|
|
1204
|
+
planSummary: (language, steps) => ` \u8BED\u8A00=${language}\uFF0C\u6B65\u9AA4=${steps}`,
|
|
1205
|
+
preflightModelMissing: (names) => `LLM preflight: \u6A21\u578B\u7F3A\u5931\uFF0C\u5DF2\u7981\u7528 [${names}]`,
|
|
1206
|
+
preflightAutoAdded: (n) => `LLM preflight: \u81EA\u52A8\u6CE8\u5165 ${n} \u4E2A provider\uFF08\u6765\u81EA ollama /api/tags\uFF09`,
|
|
1207
|
+
runInterrupted: (id, e, total) => `\u6267\u884C\u4E2D\u65AD\u4E8E ${id}\uFF08\u5DF2\u6267\u884C ${e}/${total}\uFF09`,
|
|
1208
|
+
runReasonLabel: " \u539F\u56E0: ",
|
|
1209
|
+
runFailureLogHeader: " --- \u8BE6\u7EC6\u5931\u8D25\u65E5\u5FD7\uFF08tail 40 \u884C\uFF09 ---",
|
|
1210
|
+
runAllDone: (e, total) => `Plan \u5168\u90E8\u5B8C\u6210\uFF08${e}/${total}\uFF09`,
|
|
1211
|
+
projectAuditSummary: (errors, warnings) => `\u9879\u76EE\u5BA1\u8BA1\uFF1A${errors} \u4E2A\u9519\u8BEF\uFF0C${warnings} \u4E2A\u8B66\u544A`,
|
|
1212
|
+
projectMemoryRefreshFailed: (message) => `\u9879\u76EE\u8BB0\u5FC6\u5237\u65B0\u5931\u8D25\uFF1A${message}`,
|
|
1213
|
+
projectAuditCheck: (name, summary) => `[\u5BA1\u8BA1:${name}] ${summary}`,
|
|
1214
|
+
auditDocPresent: (p) => `${p} \u5B58\u5728`,
|
|
1215
|
+
auditDocMissing: (p) => `\u7F3A\u5C11 ${p}`,
|
|
1216
|
+
auditDeliveryDocPresent: "\u4EA4\u4ED8\u6587\u6863\u5B58\u5728",
|
|
1217
|
+
auditDeliveryDocMissing: "\u7F3A\u5C11 docs/08-functional-test.md",
|
|
1218
|
+
auditTestFilesFound: (count) => `\u53D1\u73B0 ${count} \u4E2A\u6709\u6548\u6D4B\u8BD5\u6587\u4EF6`,
|
|
1219
|
+
auditTestFilesMissing: "tests/ \u4E0B\u6CA1\u6709\u6709\u6548\u6D4B\u8BD5\u6587\u4EF6",
|
|
1220
|
+
auditEntrypointOk: (command) => `\u5165\u53E3\u9A8C\u8BC1\u901A\u8FC7\uFF1A${command}`,
|
|
1221
|
+
auditEntrypointFailed: (command) => `\u5165\u53E3\u9A8C\u8BC1\u5931\u8D25\uFF1A${command}`,
|
|
1222
|
+
auditPackageJsonMissing: "\u7F3A\u5C11 package.json",
|
|
1223
|
+
auditScriptMissing: (name) => `package.json \u7F3A\u5C11 ${name} \u811A\u672C`,
|
|
1224
|
+
auditCommandOk: (name) => `${name} \u901A\u8FC7`,
|
|
1225
|
+
auditCommandFailed: (name, exitCode, timedOut) => `${name} \u5931\u8D25\uFF08exit=${exitCode}${timedOut ? "\uFF0C\u8D85\u65F6" : ""}\uFF09`
|
|
1226
|
+
},
|
|
1227
|
+
engine: {
|
|
1228
|
+
spinSandboxBuild: (profile) => profile.id === "typescript" ? `\u6784\u5EFA\u6C99\u76D2\uFF08npm install\uFF0C${profile.manifestFile}\uFF09\u2026` : `\u6784\u5EFA\u6C99\u76D2\uFF08pip install -r ${profile.manifestFile}\uFF09\u2026`,
|
|
1229
|
+
sandboxReady: (r) => `\u6C99\u76D2\u5C31\u7EEA\uFF1A${r}`,
|
|
1230
|
+
stepSkipDone: (id, phase) => ` \u21AA ${id} ${phase} \u5DF2\u5B8C\u6210\uFF0C\u8DF3\u8FC7`,
|
|
1231
|
+
spinSandboxRebuild: (id, profile) => profile.id === "typescript" ? `Step ${id} \u5199\u5165 ${profile.manifestFile}\uFF0C\u91CD\u5EFA npm \u6C99\u76D2\u2026` : `Step ${id} \u5199\u5165 ${profile.manifestFile}\uFF0C\u91CD\u5EFA pip \u6C99\u76D2\u2026`,
|
|
1232
|
+
sandboxStatus: (r) => `\u6C99\u76D2\uFF1A${r}`,
|
|
1233
|
+
autoFixedSrcImports: (n, files) => ` \u26A0 auto-fixed sys.path bootstrap in ${n} \u4E2A\u5165\u53E3\u6587\u4EF6\uFF1A${files}`,
|
|
1234
|
+
debugResumeNotice: (id, n) => ` \u21BB ${id} \u68C0\u6D4B\u5230\u4E0A\u6B21\u4F1A\u8BDD\u4EE5 FAILED \u7ED3\u675F\uFF08\u5DF2\u7D2F\u79EF ${n} \u6B21\u5C1D\u8BD5\uFF09\uFF0C\u672C\u6B21\u9996\u8F6E\u76F4\u63A5\u8FDB\u5165 Debugger \u6A21\u5F0F\u3002`,
|
|
1235
|
+
spinDebugRetry: (id, attempt, budget, cap, reason) => `\u{1F6E0} ${id} DEBUG retry ${attempt}/${budget} (cap=${cap}) \u2014 ${reason}`,
|
|
1236
|
+
retryException: (a, b, msg) => `retry ${a}/${b} \u629B\u51FA\u5F02\u5E38\uFF1A${msg}`,
|
|
1237
|
+
fixSucceeded: (id, a) => `${id} \u4FEE\u590D\u6210\u529F (retry=${a})`,
|
|
1238
|
+
retryHealthyButFailed: (a, before, b, tag, reason) => `retry ${a}/${before}\u2192${b} \u4ECD\u5931\u8D25\u4F46\u5065\u5EB7\uFF08\u6269\u7A97\uFF09 \xB7 ${tag} \xB7 ${reason}`,
|
|
1239
|
+
retryLowQuality: (a, before, b, tag, reason) => `retry ${a}/${before}\u2192${b} \u4F4E\u8D28\u91CF\u8F93\u51FA\uFF08\u7F29\u7A97\uFF09 \xB7 ${tag} \xB7 ${reason}`,
|
|
1240
|
+
retryStillFailed: (a, b, tag, reason) => `retry ${a}/${b} \u4ECD\u5931\u8D25 \xB7 ${tag} \xB7 ${reason}`,
|
|
1241
|
+
earlyAbortLowQuality: (id, n) => ` \u26A1 ${id} \u68C0\u6D4B\u5230\u8FDE\u7EED ${n} \u6B21\u4F4E\u8D28\u91CF LLM \u8F93\u51FA\uFF08\u89E3\u6790\u5931\u8D25/\u91CD\u590D actions/\u65E0\u8FDB\u5C55\uFF09\uFF0C\u5FEB\u901F\u7EC8\u6B62 DEBUG \u91CD\u8BD5`,
|
|
1242
|
+
stepFinalFailed: (id, phase, role) => `\u2716 Step ${id} (${phase} / ${role}) \u6700\u7EC8\u5931\u8D25`,
|
|
1243
|
+
finalAttemptsLine: (a, b, c, ea) => ` attempts=${a} final_budget=${b} cap=${c}` + (ea ? " (early-abort: low-quality)" : ""),
|
|
1244
|
+
finalMetricsLine: (h, p, r, tf, pr) => ` health=${h} parseFail=${p} repeat=${r} toolFail=${tf} progress=${pr}`,
|
|
1245
|
+
reasonLabel: "reason: ",
|
|
1246
|
+
failureLogHeader: "--- failure log (tail, max 80 lines) ---",
|
|
1247
|
+
fixSuggestionsHeader: "--- \u4FEE\u590D\u5EFA\u8BAE\uFF08calibration\uFF09 ---",
|
|
1248
|
+
auditHint: (id) => ` \u5BA1\u8BA1: \u67E5\u770B .xcompiler/audit.jsonl \u4E0E .xcompiler/llm-stream/${id}-*.txt \u83B7\u53D6\u5B8C\u6574\u539F\u59CB\u6D41`,
|
|
1249
|
+
spinStepRunning: (id, phase, title) => `\u25B6 ${id} ${phase} ${title}`,
|
|
1250
|
+
noFailureLog: "\uFF08\u672A\u6355\u83B7\u65E5\u5FD7\uFF09",
|
|
1251
|
+
suggestionLine: (index, code, hint) => ` ${index}. [${code}] ${hint}`,
|
|
1252
|
+
phaseStart: (id, phase, title) => `${id} ${phase} ${title}`,
|
|
1253
|
+
phaseFailed: (id, debug, reason) => `${id} ${debug ? "DEBUG " : ""}\u5931\u8D25 \u2014 ${reason}`,
|
|
1254
|
+
phaseDone: (id, rounds) => `${id} \u5B8C\u6210\uFF08\u8F6E\u6B21=${rounds}\uFF09`,
|
|
1255
|
+
phaseException: (id, message) => `${id} \u5F02\u5E38\u5931\u8D25 \u2014 ${message}`,
|
|
1256
|
+
archGateReason: (missing) => `HIGH_LEVEL_DESIGN \u95E8\u7981\uFF1A\u67B6\u6784\u5951\u7EA6\u7F3A\u5C11 ${missing} \u4E2A\u6807\u8BB0`,
|
|
1257
|
+
archGateMissing: (tokens) => `\u7F3A\u5931\u6A21\u5757 ID/\u8DEF\u5F84\uFF1A${tokens}`,
|
|
1258
|
+
archGateInstruction: (p) => `\u8BF7\u66F4\u65B0 ${p}\uFF0C\u786E\u4FDD\u6BCF\u4E2A architectureModules \u9879\u5728\u8FDB\u5165 CODE \u524D\u5747\u53EF\u8FFD\u8E2A\u3002`,
|
|
1259
|
+
testGateReason: (exitCode, timedOut) => `\u6D4B\u8BD5\u95E8\u7981\uFF1A\u6D4B\u8BD5\u9000\u51FA\u7801=${exitCode}${timedOut ? "\uFF08\u8D85\u65F6\uFF09" : ""}`,
|
|
1260
|
+
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",
|
|
1262
|
+
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
|
+
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
|
+
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`,
|
|
1265
|
+
reasonLine: (reason) => `\u539F\u56E0\uFF1A${reason}`,
|
|
1266
|
+
roundsLine: (rounds) => `\u8F6E\u6B21\uFF1A${rounds}`,
|
|
1267
|
+
commandLine: (command) => `\u547D\u4EE4\uFF1A${command}`,
|
|
1268
|
+
stdoutTailHeader: "--- \u6807\u51C6\u8F93\u51FA\uFF08\u5C3E\u90E8\uFF09---",
|
|
1269
|
+
stderrTailHeader: "--- \u6807\u51C6\u9519\u8BEF\uFF08\u5C3E\u90E8\uFF09---",
|
|
1270
|
+
testStdoutTailHeader: "--- \u6D4B\u8BD5\u6807\u51C6\u8F93\u51FA\uFF08\u5C3E\u90E8\uFF09---",
|
|
1271
|
+
testStderrTailHeader: "--- \u6D4B\u8BD5\u6807\u51C6\u9519\u8BEF\uFF08\u5C3E\u90E8\uFF09---",
|
|
1272
|
+
outputsMissing: (paths) => `\u7F3A\u5931\u8F93\u51FA\uFF1A${paths}`,
|
|
1273
|
+
metricsLine: (health, parseFail, repeat, toolFail, progress) => `\u6307\u6807\uFF1A\u5065\u5EB7\u5EA6=${health} \u89E3\u6790\u5931\u8D25=${parseFail} \u91CD\u590D=${repeat} \u5DE5\u5177\u5931\u8D25=${toolFail} \u8FDB\u5EA6=${progress}`,
|
|
1274
|
+
metricsUnavailable: "\u6307\u6807\uFF1A\u65E0",
|
|
1275
|
+
toolCallsHeader: "\u5DE5\u5177\u8C03\u7528\uFF1A",
|
|
1276
|
+
toolCallLine: (tool, ok, detail) => ` - ${tool} ${ok ? "\u6210\u529F" : "\u5931\u8D25"} ${detail}`,
|
|
1277
|
+
projectMemoryRefreshFailed: (message) => `\u9879\u76EE\u8BB0\u5FC6\u5237\u65B0\u5931\u8D25\uFF1A${message}`,
|
|
1278
|
+
deliveryFixHints: (language) => language === "typescript" ? [
|
|
1279
|
+
"\u4FEE\u590D\u65B9\u5411\uFF08\u6309\u4F18\u5148\u7EA7\uFF09\uFF1A",
|
|
1280
|
+
" 1. \u82E5 TypeScript \u6E90\u7801\u51FA\u73B0\u6A21\u5757\u89E3\u6790\u6216 ERR_MODULE_NOT_FOUND\uFF0C\u4F7F\u7528\u5E26\u663E\u5F0F .ts \u540E\u7F00\u7684\u76F8\u5BF9 ESM import\u3002",
|
|
1281
|
+
" 2. \u82E5\u4E3A --help \u6216\u672A\u77E5\u9009\u9879\uFF0Cmain() \u5FC5\u987B\u652F\u6301 --help \u5E76\u4EE5 0 \u9000\u51FA\u3002",
|
|
1282
|
+
" 3. \u82E5\u4E3A\u5E94\u7528\u5F02\u5E38\uFF0C\u4FEE\u590D\u5B9E\u73B0\u5E76\u4FDD\u6301\u5165\u53E3\u8F7B\u91CF\u3002"
|
|
1283
|
+
] : [
|
|
1284
|
+
"\u4FEE\u590D\u65B9\u5411\uFF08\u6309\u4F18\u5148\u7EA7\uFF09\uFF1A",
|
|
1285
|
+
" 1. \u82E5\u4E3A src \u76F8\u5173 ModuleNotFoundError\uFF0C\u52A0\u5165 planner #19 \u7684 sys.path \u81EA\u4E3E\u6216\u79FB\u9664 import \u7684 src. \u524D\u7F00\u3002",
|
|
1286
|
+
' 2. main() \u5FC5\u987B\u662F\u771F\u5B9E CLI \u5165\u53E3\uFF1A\u89E3\u6790 --help\u3001\u8C03\u7528\u9879\u76EE\u6A21\u5757\u3001\u6253\u5370\u6709\u610F\u4E49\u8F93\u51FA\uFF0C\u5E76\u7528 if __name__ == "__main__": main() \u542F\u52A8\u3002',
|
|
1287
|
+
" 3. \u82E5\u4E3A argparse \u9519\u8BEF\uFF0Cmain() \u5FC5\u987B\u65E0\u9700\u5176\u4ED6\u5FC5\u586B\u53C2\u6570\u5373\u53EF\u652F\u6301 --help \u5E76\u4EE5 0 \u9000\u51FA\u3002",
|
|
1288
|
+
" 4. \u82E5\u4E3A\u4E1A\u52A1\u5F02\u5E38\uFF0C\u4FEE\u590D\u5B9E\u73B0\uFF1B\u5165\u53E3\u53EA\u8D1F\u8D23\u53C2\u6570\u89E3\u6790\u4E0E\u8C03\u7528\u3002"
|
|
1289
|
+
]
|
|
1290
|
+
},
|
|
1291
|
+
render: {
|
|
1292
|
+
sectionGlobalPrompt: "## Global prompt (\u6CE8\u5165\u6BCF\u4E2A Step \u7684 system prompt)",
|
|
1293
|
+
sectionDependencies: (manifestFile) => `## Dependencies (\u5C06\u5199\u5165 ${manifestFile})`,
|
|
1294
|
+
sectionBaselineSummary: "## \u73B0\u6709\u5DE5\u7A0B\u57FA\u7EBF",
|
|
1295
|
+
labelSystemPrompt: "**System prompt (\u552F\u4E00\u4F7F\u547D):**"
|
|
1296
|
+
},
|
|
1297
|
+
prompts: {
|
|
1298
|
+
plannerSystem: (p) => buildPlannerSystem2(p),
|
|
1299
|
+
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
|
+
- \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
|
+
- \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
|
|
1302
|
+
- \u9664\u975E\u672C\u6B21\u53D8\u66F4\u786E\u5B9E\u9700\u8981\u4FEE\u6539\uFF0C\u5426\u5219 HIGH_LEVEL_DESIGN outputs \u4E0D\u5F97\u5305\u542B package.json \u6216 tsconfig.json\u3002
|
|
1303
|
+
- \u6BCF\u4E2A CODE/\u6D4B\u8BD5\u4EA7\u7269\u5FC5\u987B\u4E25\u683C\u9650\u5B9A\u5728\u672C\u6B21\u589E\u91CF\u8303\u56F4\uFF0C\u7981\u6B62\u6574\u4F53\u91CD\u5EFA\u6216\u66FF\u6362\u4ED3\u5E93\u3002
|
|
1304
|
+
- \u5C06\u7A33\u5B9A\u5BBF\u4E3B\u89C6\u4E3A N \u4EE3\u3001\u9694\u79BB worktree \u4E2D\u7684\u5019\u9009\u7248\u672C\u89C6\u4E3A N+1 \u4EE3\uFF1B\u7981\u6B62\u8BBE\u8BA1\u8FDB\u7A0B\u5185\u70ED\u66FF\u6362\u3002`,
|
|
1305
|
+
plannerClarifySystem: `\u4F60\u662F XCompiler V \u6A21\u578B\u7684\u9700\u6C42\u5206\u6790\u5E08\u3002\u4F60\u7684\u804C\u8D23\u4E0D\u662F\u590D\u8FF0 topic\uFF0C\u800C\u662F\u53D1\u73B0\u4F1A\u6539\u53D8\u529F\u80FD\u8BBE\u8BA1\u3001\u9A8C\u6536\u7ED3\u679C\u6216\u67B6\u6784\u8FB9\u754C\u7684\u672A\u51B3\u4E8B\u9879\u3002
|
|
1306
|
+
\u53EA\u8FD4\u56DE\u4E25\u683C JSON\u3002\u95EE\u9898\u5FC5\u987B\u53EF\u7531\u4E1A\u52A1\u65B9\u76F4\u63A5\u4F5C\u7B54\u3001\u4E00\u6B21\u53EA\u786E\u8BA4\u4E00\u4E2A\u51B3\u7B56\uFF0C\u907F\u514D\u7A7A\u6CDB\u7684\u201C\u8FD8\u6709\u4EC0\u4E48\u8981\u6C42\u201D\u6216\u6280\u672F\u6808\u9009\u578B\u95EE\u9898\u3002`,
|
|
1307
|
+
plannerClarify: (raw, opts = {}) => `\u7528\u6237\u7684\u539F\u59CB\u9700\u6C42\u5982\u4E0B\uFF1A
|
|
1308
|
+
|
|
1309
|
+
"""
|
|
1310
|
+
${raw}
|
|
1311
|
+
"""
|
|
1312
|
+
|
|
1313
|
+
\u8BF7\u9488\u5BF9 topic \u4E2D\u5C1A\u672A\u660E\u786E\u3001\u4E14\u7B54\u6848\u4F1A\u5B9E\u8D28\u6539\u53D8\u5B9E\u73B0\u6216\u9A8C\u6536\u7684\u4E8B\u9879\uFF0C\u751F\u6210${opts.complex ? "8-10" : "7-10"}\u4E2A\u4E92\u4E0D\u91CD\u590D\u7684\u6F84\u6E05\u95EE\u9898\u3002\u4E0D\u5F97\u8FD4\u56DE\u7A7A\u6570\u7EC4\uFF1B\u5982\u679C\u529F\u80FD\u63CF\u8FF0\u5DF2\u7ECF\u8F83\u5B8C\u6574\uFF0C\u5C31\u8FFD\u95EE\u9A8C\u6536\u793A\u4F8B\u3001\u5931\u8D25\u884C\u4E3A\u548C\u660E\u786E\u7684\u4E0D\u505A\u8303\u56F4\u3002
|
|
1314
|
+
|
|
1315
|
+
\u4EC5\u8FD4\u56DE JSON \u6570\u7EC4\uFF0C\u6BCF\u9879\u4E25\u683C\u4E3A\uFF1A
|
|
1316
|
+
{"id":"Q1","category":"functionality|data|acceptance|boundary|quality|extensibility","question":"\u4E00\u4E2A\u53EF\u76F4\u63A5\u56DE\u7B54\u7684\u5177\u4F53\u95EE\u9898","why":"\u8BE5\u7B54\u6848\u4F1A\u5F71\u54CD\u4EC0\u4E48\u8BBE\u8BA1\u6216\u9A8C\u6536","options":[{"label":"A","answer":"\u6700\u9AD8\u4F18\u5148\u7EA7\u7684\u53EF\u884C\u8BBE\u5B9A"},{"label":"B","answer":"\u7B2C\u4E8C\u4E2A\u53EF\u884C\u8BBE\u5B9A"}]}
|
|
1317
|
+
|
|
1318
|
+
\u95EE\u9898\u7EC4\u5408\u8981\u6C42\uFF08\u529F\u80FD\u4F18\u5148\uFF09\uFF1A
|
|
1319
|
+
- \u81F3\u5C11 ${opts.complex ? "5" : "4"} \u4E2A\u529F\u80FD\u6027\u95EE\u9898\uFF0Ccategory \u4F7F\u7528 functionality / data / acceptance\uFF0C\u786E\u4FDD\u529F\u80FD\u95EE\u9898\u5360\u591A\u6570\u3002\u4F18\u5148\u8D28\u8BE2\uFF1A\u76EE\u6807\u7528\u6237\u4E0E\u89D2\u8272\u3001\u6838\u5FC3\u4F7F\u7528\u6D41\u7A0B\u3001\u529F\u80FD\u89C4\u5219\u4E0E\u72B6\u6001\u53D8\u5316\u3001\u8F93\u5165\u8F93\u51FA\u3001\u5931\u8D25/\u5F02\u5E38\u884C\u4E3A\u3001\u53EF\u9A8C\u8BC1\u9A8C\u6536\u793A\u4F8B\u3002
|
|
1320
|
+
- \u81F3\u5C11 1 \u4E2A boundary\uFF1A\u660E\u786E\u672C\u671F\u5FC5\u987B\u505A\u3001\u660E\u786E\u4E0D\u505A\u3001\u5916\u90E8\u7CFB\u7EDF\u8D23\u4EFB\u8FB9\u754C\u6216\u517C\u5BB9\u8303\u56F4\u3002
|
|
1321
|
+
- \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
|
+
- \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
|
+
- \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
|
|
1324
|
+
- \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
|
+
- \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
|
+
- \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
|
|
1327
|
+
- \u9009\u9879\u4ECE A \u5F00\u59CB\u8FDE\u7EED\u6807\u53F7\uFF0C\u5230\u5B9E\u9645\u6700\u540E\u4E00\u4E2A\u9009\u9879\u7ED3\u675F\uFF0C\u4F8B\u5982 A-B\u3001A-C\u3001A-D \u6216 A-E\uFF1B\u5982\u679C\u80FD\u5224\u65AD\u63A8\u8350/\u9ED8\u8BA4\u65B9\u6848\uFF0CA \u5E94\u662F\u6700\u9AD8\u4F18\u5148\u7EA7\u65B9\u6848\u3002\u9009\u9879\u5FC5\u987B\u662F\u5177\u4F53\u4E1A\u52A1/\u4EA7\u54C1\u8BBE\u5B9A\uFF0C\u4E0D\u8981\u5199\u6210\u7A7A\u6CDB\u5360\u4F4D\u3002
|
|
1328
|
+
- \u4E0D\u8981\u628A\u201C\u5176\u4ED6 / \u81EA\u5B9A\u4E49 / \u7528\u6237\u51B3\u5B9A\u201D\u4F5C\u4E3A\u9009\u9879\uFF1BCLI \u5DF2\u652F\u6301\u7528\u6237\u8F93\u5165\u5DF2\u5C55\u793A\u7684\u9009\u9879\u5B57\u6BCD\u6216\u76F4\u63A5\u8F93\u5165\u81EA\u5B9A\u4E49\u56DE\u7B54\u5185\u5BB9\u3002
|
|
1329
|
+
${opts.projectShapeAmbiguous ? "- \u672C topic \u5FC5\u95EE\uFF1A\u660E\u786E\u786E\u8BA4 API library / \u53EF\u8FD0\u884C\u5E94\u7528 / mixed \u4EA4\u4ED8\u8FB9\u754C\u3002\n" : ""}
|
|
1330
|
+
|
|
1331
|
+
\u3010\u786C\u7EA6\u675F\u3011\u5B9E\u73B0\u6280\u672F\u6808\u5DF2\u7ECF\u7531 XCompiler \u914D\u7F6E / \u73B0\u6709\u5DE5\u7A0B\u57FA\u7EBF\u56FA\u5B9A\uFF0C\u4E0D\u8981\u91CD\u65B0\u8BE2\u95EE\u8BED\u8A00\u3001\u8FD0\u884C\u65F6\u3001\u5305\u7BA1\u7406\u5668\u8FD9\u7C7B\u95EE\u9898\u3002
|
|
1332
|
+
**\u4E25\u7981**\u63D0\u51FA\u4EE5\u4E0B\u7C7B\u578B\u7684\u95EE\u9898\uFF1A
|
|
1333
|
+
- "\u5E0C\u671B\u7528\u4EC0\u4E48\u7F16\u7A0B\u8BED\u8A00 / \u6846\u67B6 / \u8FD0\u884C\u65F6\u5B9E\u73B0\uFF1F"
|
|
1334
|
+
- "\u9700\u8981\u54EA\u79CD\u6D4B\u8BD5\u6846\u67B6 / \u6784\u5EFA\u5DE5\u5177 / \u5305\u7BA1\u7406\u5668\uFF1F"
|
|
1335
|
+
- "\u76EE\u6807\u5E73\u53F0\u662F\u54EA\u79CD\u64CD\u4F5C\u7CFB\u7EDF\uFF1F"
|
|
1336
|
+
${opts.intent && opts.intent !== "greenfield" ? `\u8FD9\u662F\u4E00\u6761\u9488\u5BF9\u73B0\u6709\u5DE5\u7A0B\u7684\u589E\u91CF ${opts.intent} \u8BF7\u6C42${opts.hasBaseline ? "\uFF1B\u5206\u89E3\u9636\u6BB5\u8FD8\u4F1A\u63D0\u4F9B\u4E00\u4EFD\u57FA\u7EBF\u6458\u8981" : ""}\u3002\u8BF7\u53EA\u95EE\u201C\u53D8\u66F4\u589E\u91CF\u201D\u76F8\u5173\u95EE\u9898\uFF0C\u4E0D\u8981\u628A\u9879\u76EE\u5F53\u6210\u4ECE\u96F6\u5F00\u59CB\u91CD\u505A\u3002` : ""}\u95EE\u9898\u4E3B\u4F53\u5FC5\u987B\u805A\u7126\u529F\u80FD\u884C\u4E3A\uFF1B\u6027\u80FD\u3001\u8FB9\u754C\u548C\u6269\u5C55\u6027\u7528\u4E8E\u6D88\u9664\u4F1A\u5F71\u54CD\u672C\u671F\u8BBE\u8BA1\u7684\u5173\u952E\u6B67\u4E49\u3002`,
|
|
1337
|
+
plannerDecompose: (raw, qa, addenda, opts = {}) => `\u539F\u59CB\u9700\u6C42\uFF1A
|
|
1338
|
+
"""
|
|
1339
|
+
${raw}
|
|
1340
|
+
"""
|
|
1341
|
+
|
|
1342
|
+
\u6F84\u6E05\u95EE\u7B54\uFF1A
|
|
1343
|
+
${qa || "\uFF08\u65E0\uFF09"}
|
|
1344
|
+
|
|
1345
|
+
${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
|
|
1346
|
+
"""
|
|
1347
|
+
${addenda}
|
|
1348
|
+
"""
|
|
1349
|
+
|
|
1350
|
+
` : ""}${opts.intent && opts.intent !== "greenfield" ? `\u589E\u91CF\u610F\u56FE\uFF1A${opts.intent}
|
|
1351
|
+
|
|
1352
|
+
\u8BF7\u5728\u73B0\u6709\u5DE5\u7A0B\u57FA\u7840\u4E0A\u751F\u6210\u4E00\u4EFD\u589E\u91CF ${opts.intent} \u8BA1\u5212\uFF0C\u4F18\u5148\u590D\u7528\u5F53\u524D\u67B6\u6784\u3001\u6587\u4EF6\u3001\u6D4B\u8BD5\u4E0E\u4F9D\u8D56\uFF0C\u800C\u4E0D\u662F\u628A\u6574\u4E2A\u9879\u76EE\u91CD\u65B0\u642D\u4E00\u904D\u3002\u9664\u672C\u6B21\u9700\u6C42\u6D89\u53CA\u7684\u8303\u56F4\u5916\uFF0C\u9ED8\u8BA4\u4FDD\u6301\u65E2\u6709\u884C\u4E3A\u4E0D\u53D8\u3002
|
|
1353
|
+
|
|
1354
|
+
\u73B0\u6709\u5DE5\u7A0B\u57FA\u7EBF\uFF1A
|
|
1355
|
+
"""
|
|
1356
|
+
${opts.baseline || "\uFF08\u7F3A\u5C11\u57FA\u7EBF\u6458\u8981\uFF09"}
|
|
1357
|
+
"""
|
|
1358
|
+
|
|
1359
|
+
` : ""}\u89C4\u5212\u6DF1\u5EA6\u7EA6\u675F\uFF1A
|
|
1360
|
+
- \u9664\u975E\u9700\u6C42\u660E\u786E\u53EA\u662F\u4E00\u4E2A\u5F88\u5C0F\u7684\u5355\u51FD\u6570 / \u5355\u811A\u672C / \u5C0F\u5DE5\u5177\uFF0C\u5426\u5219\u4E0D\u8981\u628A\u65B9\u6848\u538B\u7F29\u6210\u201C\u4E00\u4E2A\u6E90\u7801\u6587\u4EF6 + \u4E00\u4E2A\u6D4B\u8BD5\u6587\u4EF6\u201D\u7684\u6700\u5C0F\u5B9E\u73B0\u3002
|
|
1361
|
+
- \u5982\u679C\u9700\u6C42\u6A2A\u8DE8\u591A\u4E2A\u5173\u6CE8\u70B9\uFF08\u9886\u57DF\u903B\u8F91\u3001API/CLI \u63A5\u53E3\u3001\u6301\u4E45\u5316\u3001\u5916\u90E8\u96C6\u6210\u3001\u6D41\u7A0B\u7F16\u6392\u3001\u6D4B\u8BD5\uFF09\uFF0C\u5FC5\u987B\u5728\u8BA1\u5212\u91CC\u4F53\u73B0\u4E3A\u591A\u4E2A\u67B6\u6784\u6A21\u5757\uFF0C\u5E76\u5728 CODE/MODULE_TEST \u5B8F Step \u7684 subTasks \u4E0B\u5206\u89E3\u6A21\u5757\u7EA7\u5DE5\u4F5C\u3002
|
|
1362
|
+
- \u5728 plan \u4E2D\u8BC4\u4F30\u9879\u76EE\u590D\u6742\u5EA6\uFF0C\u5E76\u6309\u8BC4\u4F30\u7ED3\u679C\u786E\u5B9A implementationPhases \u6570\u91CF\uFF1Asimple => \u53EA\u6709 P1 current\uFF1Bmoderate => P1 current + \u81F3\u5C11 P2 planned\uFF1Bcomplex => P1 current + \u81F3\u5C11 P2/P3 planned\u3002\u82E5\u7528\u6237\u660E\u786E\u8981\u6C42\u5206\u9636\u6BB5/\u91CC\u7A0B\u7891\uFF0C\u81F3\u5C11\u4F7F\u7528 P1+P2\uFF0C\u5E76\u8BBE\u7F6E userForcedPhaseSplit=true\u3002\u6BCF\u4E2A current/planned implementation phase \u90FD\u5FC5\u987B\u5728 steps \u4E2D\u62E5\u6709\u4E00\u5957\u5B8C\u6574 V \u6A21\u578B\uFF0C\u5E76\u8BA9 Step.iterationId \u6307\u5411\u5BF9\u5E94 phase\u3002
|
|
1363
|
+
- \u8BF7\u901A\u8FC7 HIGH_LEVEL_DESIGN / DETAILED_DESIGN Step \u660E\u786E\u6A21\u5757\u8FB9\u754C\u3001\u804C\u8D23\u5212\u5206\u3001\u4F9D\u8D56\u548C\u540E\u7EED\u53EF\u6269\u5C55\u70B9\uFF0C\u8BA9\u540E\u7EED\u589E\u91CF\u5F00\u53D1\u53EF\u4EE5\u6301\u7EED\u8FFD\u52A0\uFF0C\u800C\u4E0D\u662F\u6BCF\u6B21\u91CD\u5199\u3002
|
|
1364
|
+
- \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
|
+
|
|
1366
|
+
\u8BF7\u6309\u7CFB\u7EDF\u89C4\u5219\u8F93\u51FA\u4E25\u683C JSON \u8BA1\u5212\u3002`,
|
|
1367
|
+
executorSystem: (p) => buildExecutorSystem2(p),
|
|
1368
|
+
executorDebugBlock: (reason, suggestions) => `
|
|
1369
|
+
|
|
1370
|
+
\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 ? `
|
|
1372
|
+
|
|
1373
|
+
${suggestions}` : ""),
|
|
1374
|
+
executorGlobalBlock: (globalPrompt) => `
|
|
1375
|
+
|
|
1376
|
+
## \u9879\u76EE\u5168\u5C40\u7EA6\u675F
|
|
1377
|
+
${globalPrompt}`,
|
|
1378
|
+
executorStepBlock: (sp) => `
|
|
1379
|
+
|
|
1380
|
+
## \u5F53\u524D Step \u4E13\u5C5E\u63D0\u793A (\u552F\u4E00\u4F7F\u547D\uFF0C\u7981\u6B62\u8DE8 Step \u53D1\u6563)
|
|
1381
|
+
${sp}`,
|
|
1382
|
+
executorUserPromptOutro: "\u73B0\u5728\u6309\u534F\u8BAE\u8FD4\u56DE\u7B2C\u4E00\u8F6E JSON\u3002",
|
|
1383
|
+
executorFeedbackHeader: "\u672C\u8F6E\u5DE5\u5177\u7ED3\u679C\uFF1A",
|
|
1384
|
+
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`
|
|
1386
|
+
},
|
|
1387
|
+
skills: {
|
|
1388
|
+
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
|
+
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',
|
|
1391
|
+
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',
|
|
1393
|
+
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
|
+
},
|
|
1395
|
+
doctor: {
|
|
1396
|
+
cliDescription: "\u68C0\u67E5 config / LLM / sandbox / skills \u662F\u5426\u5C31\u7EEA",
|
|
1397
|
+
optStrict: "\u628A warning \u4E5F\u89C6\u4E3A\u5931\u8D25\uFF08\u4EFB\u4E00 warn \u5373\u975E\u96F6\u9000\u51FA\uFF09",
|
|
1398
|
+
header: "XCompiler \u542F\u52A8\u73AF\u5883\u81EA\u68C0",
|
|
1399
|
+
sectionConfig: "[\u914D\u7F6E]",
|
|
1400
|
+
sectionLLM: "[LLM]",
|
|
1401
|
+
sectionSandbox: "[\u6C99\u76D2]",
|
|
1402
|
+
sectionSkills: "[\u6280\u80FD]",
|
|
1403
|
+
summaryOk: "\u5168\u90E8\u68C0\u67E5\u901A\u8FC7\u3002",
|
|
1404
|
+
summaryWarn: (n) => `\u901A\u8FC7\uFF0C\u4F46\u6709 ${n} \u6761 warning\u3002`,
|
|
1405
|
+
summaryFail: (n) => `\u68C0\u6D4B\u5230 ${n} \u9879\u5931\u8D25\u3002`,
|
|
1406
|
+
configLoadOk: (path2) => `\u914D\u7F6E\u5DF2\u52A0\u8F7D\uFF1A${path2}`,
|
|
1407
|
+
configLoadFail: (msg) => `\u914D\u7F6E\u52A0\u8F7D\u5931\u8D25\uFF1A${msg}`,
|
|
1408
|
+
configLocale: (locale) => `locale=${locale}`,
|
|
1409
|
+
llmNoProviders: "config.llm.providers \u4E3A\u7A7A\uFF0C\u672A\u58F0\u660E\u4EFB\u4F55 provider",
|
|
1410
|
+
llmProviderListed: (n) => `\u5DF2\u58F0\u660E ${n} \u4E2A provider`,
|
|
1411
|
+
ollamaUnreachable: (baseUrl, msg) => `ollama \u4E0D\u53EF\u8FBE @ ${baseUrl} \u2014\u2014 ${msg}`,
|
|
1412
|
+
ollamaReachable: (baseUrl, n) => `ollama \u53EF\u8FBE @ ${baseUrl}\uFF08\u5171 ${n} \u4E2A\u6A21\u578B\uFF09`,
|
|
1413
|
+
ollamaModelMissing: (provider, model, baseUrl) => `provider "${provider}"\uFF1A\u6A21\u578B "${model}" \u672A\u5B89\u88C5\u4E8E ${baseUrl}\uFF08\u8BF7\u6267\u884C \`ollama pull ${model}\`\uFF09`,
|
|
1414
|
+
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`,
|
|
1416
|
+
openaiReachable: (provider, baseUrl) => `provider "${provider}"\uFF1AOpenAI \u7AEF\u70B9\u53EF\u8FBE @ ${baseUrl}`,
|
|
1417
|
+
openaiUnreachable: (provider, baseUrl, msg) => `provider "${provider}"\uFF1AOpenAI \u7AEF\u70B9\u4E0D\u53EF\u8FBE @ ${baseUrl} \u2014\u2014 ${msg}`,
|
|
1418
|
+
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`,
|
|
1419
|
+
providerScoreZero: (provider) => `provider "${provider}" \u5DF2\u7981\u7528\uFF08score=0\uFF09`,
|
|
1420
|
+
roleNoLiveProvider: (role) => `\u89D2\u8272 "${role}" \u6CA1\u6709\u53EF\u7528 provider\uFF08\u5019\u9009\u5217\u8868\u5168\u90E8\u4E0D\u53EF\u8FBE\u6216\u88AB\u7981\u7528\uFF09`,
|
|
1421
|
+
roleOk: (role, provider) => `\u89D2\u8272 "${role}" \u2192 ${provider}`,
|
|
1422
|
+
sandboxKind: (kind) => `sandbox=${kind}`,
|
|
1423
|
+
sandboxNetworkPolicy: (policy, ports) => `network=${policy}` + (ports.length ? `\uFF08expose_ports=[${ports.join(", ")}]\uFF09` : ""),
|
|
1424
|
+
sandboxFullNoPorts: "network=full \u4F46\u672A\u914D\u7F6E expose_ports\u2014\u5BBF\u4E3B\u4FA7\u65E0\u6CD5\u8BBF\u95EE\u5BB9\u5668\u5185\u670D\u52A1\u3002\u8BF7\u5728 config.yaml \u4E2D\u8BBE\u7F6E `agent.sandbox_limits.expose_ports: [<port>]`\u3002",
|
|
1425
|
+
sandboxNodeMissing: "PATH \u4E0A\u627E\u4E0D\u5230 node\uFF08TypeScript subprocess \u6C99\u76D2\u5FC5\u9700\uFF09",
|
|
1426
|
+
sandboxNodeOk: (version) => `node OK\uFF08${version}\uFF09`,
|
|
1427
|
+
sandboxNpmMissing: "PATH \u4E0A\u627E\u4E0D\u5230 npm\uFF08TypeScript subprocess \u6C99\u76D2\u5FC5\u9700\uFF09",
|
|
1428
|
+
sandboxNpmOk: (version) => `npm OK\uFF08${version}\uFF09`,
|
|
1429
|
+
sandboxNpxMissing: "PATH \u4E0A\u627E\u4E0D\u5230 npx\uFF08TypeScript subprocess \u6C99\u76D2\u5FC5\u9700\uFF09",
|
|
1430
|
+
sandboxNpxOk: (version) => `npx OK\uFF08${version}\uFF09`,
|
|
1431
|
+
sandboxPythonMissing: "PATH \u4E0A\u627E\u4E0D\u5230 python3\uFF08subprocess \u6C99\u76D2\u5FC5\u9700\uFF09",
|
|
1432
|
+
sandboxPythonOk: (version) => `python3 OK\uFF08${version}\uFF09`,
|
|
1433
|
+
sandboxVenvMissing: "python3 venv \u6A21\u5757\u4E0D\u53EF\u7528\uFF08\u8BF7\u5B89\u88C5 python3-venv / python3-virtualenv\uFF09",
|
|
1434
|
+
sandboxVenvOk: "python3 venv \u6A21\u5757 OK",
|
|
1435
|
+
sandboxDockerMissing: (bin) => `PATH \u4E0A\u627E\u4E0D\u5230 docker \u4E8C\u8FDB\u5236 "${bin}"`,
|
|
1436
|
+
sandboxDockerOk: (version) => `docker OK\uFF08${version}\uFF09`,
|
|
1437
|
+
sandboxDockerDaemonDown: (msg) => `docker daemon \u4E0D\u53EF\u8FBE\uFF1A${msg}`,
|
|
1438
|
+
sandboxInContainerWarn: "\u68C0\u6D4B\u5230 XCompiler \u8FD0\u884C\u5728\u5BB9\u5668\u5185\uFF0C\u6B64\u6A21\u5F0F\u4E0D\u652F\u6301 sandbox=docker\uFF08\u8BF7\u4F7F\u7528 subprocess\uFF09\u3002",
|
|
1439
|
+
skillToolMissing: (skill, tool) => `skill "${skill}" \u5F15\u7528\u4E86\u672A\u6CE8\u518C\u7684\u5DE5\u5177 "${tool}"`,
|
|
1440
|
+
skillOk: (n, tools) => `\u5DF2\u6CE8\u518C ${n} \u4E2A skill\uFF0C\u5BF9\u5E94 ${tools} \u4E2A\u5E95\u5C42\u5DE5\u5177`
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
var zh_default = messages2;
|
|
1444
|
+
|
|
1445
|
+
// src/i18n/index.ts
|
|
1446
|
+
var TABLES = { en: en_default, zh: zh_default };
|
|
1447
|
+
var current = "en";
|
|
1448
|
+
function t() {
|
|
1449
|
+
return TABLES[current];
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
// src/version.ts
|
|
1453
|
+
var XCOMPILER_VERSION = "0.2.2";
|
|
1454
|
+
var XCOMPILER_PLUGIN_API_VERSION = 1;
|
|
1455
|
+
|
|
1456
|
+
// src/plugins/compatibility.ts
|
|
1457
|
+
function checkPluginCompatibility(manifest, runtime = {}) {
|
|
1458
|
+
const candidate = manifest && typeof manifest === "object" ? manifest : {};
|
|
1459
|
+
const xcompilerVersion = runtime.xcompilerVersion ?? XCOMPILER_VERSION;
|
|
1460
|
+
const pluginApiVersion = runtime.pluginApiVersion ?? XCOMPILER_PLUGIN_API_VERSION;
|
|
1461
|
+
const pluginId = typeof candidate.id === "string" ? candidate.id.trim() : "";
|
|
1462
|
+
const pluginVersion = typeof candidate.version === "string" ? candidate.version : "";
|
|
1463
|
+
const base = { pluginId, pluginVersion, xcompilerVersion, pluginApiVersion };
|
|
1464
|
+
const reject = (code, message) => ({
|
|
1465
|
+
...base,
|
|
1466
|
+
compatible: false,
|
|
1467
|
+
code,
|
|
1468
|
+
message
|
|
1469
|
+
});
|
|
1470
|
+
const current2 = parseSemVer(xcompilerVersion);
|
|
1471
|
+
if (!current2) {
|
|
1472
|
+
return reject("invalid-runtime-version", t().plugins.invalidCoreVersion(xcompilerVersion));
|
|
1473
|
+
}
|
|
1474
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/u.test(pluginId)) {
|
|
1475
|
+
return reject("invalid-id", t().plugins.invalidId(pluginId));
|
|
1476
|
+
}
|
|
1477
|
+
if (!parseSemVer(pluginVersion)) {
|
|
1478
|
+
return reject("invalid-plugin-version", t().plugins.invalidVersion(pluginId, pluginVersion));
|
|
1479
|
+
}
|
|
1480
|
+
if (!Number.isInteger(candidate.apiVersion) || candidate.apiVersion !== pluginApiVersion) {
|
|
1481
|
+
return reject(
|
|
1482
|
+
"api-version-mismatch",
|
|
1483
|
+
t().plugins.apiVersionMismatch(pluginId, candidate.apiVersion, pluginApiVersion)
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
const minimum = parseSemVer(candidate.minXCompilerVersion);
|
|
1487
|
+
if (!minimum) {
|
|
1488
|
+
return reject(
|
|
1489
|
+
"invalid-min-xcompiler-version",
|
|
1490
|
+
t().plugins.invalidMinimumVersion(pluginId, String(candidate.minXCompilerVersion ?? ""))
|
|
1491
|
+
);
|
|
1492
|
+
}
|
|
1493
|
+
if (compareSemVer(current2, minimum) < 0) {
|
|
1494
|
+
return reject(
|
|
1495
|
+
"xcompiler-version-too-old",
|
|
1496
|
+
t().plugins.coreVersionTooOld(pluginId, candidate.minXCompilerVersion, xcompilerVersion)
|
|
1497
|
+
);
|
|
1498
|
+
}
|
|
1499
|
+
return { ...base, compatible: true, code: "compatible" };
|
|
1500
|
+
}
|
|
1501
|
+
function parseSemVer(value) {
|
|
1502
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.exec(value);
|
|
1503
|
+
if (!match) return void 0;
|
|
1504
|
+
const prereleaseParts = match[4]?.split(".") ?? [];
|
|
1505
|
+
if (prereleaseParts.some((part) => /^0\d+$/u.test(part))) return void 0;
|
|
1506
|
+
return {
|
|
1507
|
+
major: Number(match[1]),
|
|
1508
|
+
minor: Number(match[2]),
|
|
1509
|
+
patch: Number(match[3]),
|
|
1510
|
+
prerelease: prereleaseParts.map((part) => /^\d+$/.test(part) ? Number(part) : part)
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
function compareSemVer(a, b) {
|
|
1514
|
+
for (const key of ["major", "minor", "patch"]) {
|
|
1515
|
+
if (a[key] !== b[key]) return a[key] - b[key];
|
|
1516
|
+
}
|
|
1517
|
+
if (a.prerelease.length === 0 || b.prerelease.length === 0) {
|
|
1518
|
+
return a.prerelease.length === b.prerelease.length ? 0 : a.prerelease.length === 0 ? 1 : -1;
|
|
1519
|
+
}
|
|
1520
|
+
const length = Math.max(a.prerelease.length, b.prerelease.length);
|
|
1521
|
+
for (let index = 0; index < length; index++) {
|
|
1522
|
+
const left = a.prerelease[index];
|
|
1523
|
+
const right = b.prerelease[index];
|
|
1524
|
+
if (left === void 0 || right === void 0) return left === void 0 ? -1 : 1;
|
|
1525
|
+
if (left === right) continue;
|
|
1526
|
+
if (typeof left === "number" && typeof right === "number") return left - right;
|
|
1527
|
+
if (typeof left === "number") return -1;
|
|
1528
|
+
if (typeof right === "number") return 1;
|
|
1529
|
+
return left.localeCompare(right);
|
|
1530
|
+
}
|
|
1531
|
+
return 0;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
// src/plugins/host.ts
|
|
1535
|
+
var PluginHost = class {
|
|
1536
|
+
plugins;
|
|
1537
|
+
strict;
|
|
1538
|
+
xcompilerVersion;
|
|
1539
|
+
pluginApiVersion;
|
|
1540
|
+
hooks = /* @__PURE__ */ new Map();
|
|
1541
|
+
contributedTools = [];
|
|
1542
|
+
contributedSkills = [];
|
|
1543
|
+
audit;
|
|
1544
|
+
initialized = false;
|
|
1545
|
+
registrationOrder = 0;
|
|
1546
|
+
constructor(options = {}) {
|
|
1547
|
+
this.plugins = (options.plugins ?? []).map(snapshotPlugin);
|
|
1548
|
+
this.strict = options.strict ?? false;
|
|
1549
|
+
this.xcompilerVersion = options.xcompilerVersion ?? XCOMPILER_VERSION;
|
|
1550
|
+
this.pluginApiVersion = options.pluginApiVersion ?? XCOMPILER_PLUGIN_API_VERSION;
|
|
1551
|
+
this.audit = options.audit;
|
|
1552
|
+
assertPluginMetadata(this.plugins, this.xcompilerVersion, this.pluginApiVersion);
|
|
1553
|
+
}
|
|
1554
|
+
get size() {
|
|
1555
|
+
return this.plugins.length;
|
|
1556
|
+
}
|
|
1557
|
+
/** 返回只读清单快照,供诊断、插件目录和未来 registry 使用。 */
|
|
1558
|
+
get manifests() {
|
|
1559
|
+
return this.plugins.map((plugin) => snapshotManifest(plugin.manifest));
|
|
1560
|
+
}
|
|
1561
|
+
setAudit(audit) {
|
|
1562
|
+
this.audit = audit;
|
|
1563
|
+
}
|
|
1564
|
+
async initialize() {
|
|
1565
|
+
if (this.initialized) return;
|
|
1566
|
+
this.initialized = true;
|
|
1567
|
+
for (const plugin of this.plugins) {
|
|
1568
|
+
try {
|
|
1569
|
+
await plugin.setup(this.createApi(plugin));
|
|
1570
|
+
await this.audit?.event(
|
|
1571
|
+
"note",
|
|
1572
|
+
t().plugins.loaded(plugin.manifest.id, plugin.manifest.version),
|
|
1573
|
+
{
|
|
1574
|
+
messageId: "plugins.loaded",
|
|
1575
|
+
pluginId: plugin.manifest.id,
|
|
1576
|
+
pluginVersion: plugin.manifest.version,
|
|
1577
|
+
minXCompilerVersion: plugin.manifest.minXCompilerVersion,
|
|
1578
|
+
apiVersion: plugin.manifest.apiVersion
|
|
1579
|
+
}
|
|
1580
|
+
);
|
|
1581
|
+
} catch (error) {
|
|
1582
|
+
await this.handleFailure(plugin, "setup", error);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
/** 把插件贡献的 Tool / Skill 合并到 Engine 的默认注册表;禁止静默覆盖核心能力。 */
|
|
1587
|
+
applyExtensions(target) {
|
|
1588
|
+
for (const { plugin, tool } of this.contributedTools) {
|
|
1589
|
+
if (target.tools.get(tool.name)) {
|
|
1590
|
+
throw new Error(t().plugins.extensionConflict(plugin.manifest.id, "tool", tool.name));
|
|
1591
|
+
}
|
|
1592
|
+
target.tools.register(tool);
|
|
1593
|
+
}
|
|
1594
|
+
for (const { plugin, skill } of this.contributedSkills) {
|
|
1595
|
+
if (target.skills.get(skill.name)) {
|
|
1596
|
+
throw new Error(t().plugins.extensionConflict(plugin.manifest.id, "skill", skill.name));
|
|
1597
|
+
}
|
|
1598
|
+
target.skills.register(skill);
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
async emit(hook, context) {
|
|
1602
|
+
await this.initialize();
|
|
1603
|
+
const handlers = [...this.hooks.get(hook) ?? []].sort((a, b) => b.priority - a.priority || a.order - b.order);
|
|
1604
|
+
for (const registration of handlers) {
|
|
1605
|
+
try {
|
|
1606
|
+
await registration.handler(context);
|
|
1607
|
+
} catch (error) {
|
|
1608
|
+
await this.handleFailure(registration.plugin, hook, error);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
/** 在不绕过原 Tool / EditGuard 的前提下增加 before / after / error Hook。 */
|
|
1613
|
+
wrapTool(tool) {
|
|
1614
|
+
return {
|
|
1615
|
+
name: tool.name,
|
|
1616
|
+
description: tool.description,
|
|
1617
|
+
argsSchema: tool.argsSchema,
|
|
1618
|
+
run: async (args, context) => {
|
|
1619
|
+
const before = {
|
|
1620
|
+
stepId: context.stepId,
|
|
1621
|
+
tool: tool.name,
|
|
1622
|
+
args,
|
|
1623
|
+
context
|
|
1624
|
+
};
|
|
1625
|
+
await this.emit("tool.before", before);
|
|
1626
|
+
try {
|
|
1627
|
+
const result = await tool.run(before.args, context);
|
|
1628
|
+
const after = {
|
|
1629
|
+
...before,
|
|
1630
|
+
result
|
|
1631
|
+
};
|
|
1632
|
+
await this.emit("tool.after", after);
|
|
1633
|
+
return after.result;
|
|
1634
|
+
} catch (error) {
|
|
1635
|
+
await this.emit("tool.error", { ...before, error });
|
|
1636
|
+
throw error;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
};
|
|
1640
|
+
}
|
|
1641
|
+
/** 包装完整 LLM 调用;response 可由 after Hook 做结构化后处理。 */
|
|
1642
|
+
wrapLLM(client, role) {
|
|
1643
|
+
return {
|
|
1644
|
+
name: client.name,
|
|
1645
|
+
chat: async (messages3, options) => {
|
|
1646
|
+
const before = {
|
|
1647
|
+
role,
|
|
1648
|
+
model: client.name,
|
|
1649
|
+
messages: [...messages3],
|
|
1650
|
+
options: options ? { ...options } : void 0
|
|
1651
|
+
};
|
|
1652
|
+
await this.emit("llm.before", before);
|
|
1653
|
+
const startedAt = Date.now();
|
|
1654
|
+
try {
|
|
1655
|
+
const response = await client.chat(before.messages, before.options);
|
|
1656
|
+
const after = {
|
|
1657
|
+
role,
|
|
1658
|
+
model: client.name,
|
|
1659
|
+
messages: before.messages,
|
|
1660
|
+
response,
|
|
1661
|
+
durationMs: Date.now() - startedAt
|
|
1662
|
+
};
|
|
1663
|
+
await this.emit("llm.after", after);
|
|
1664
|
+
return after.response;
|
|
1665
|
+
} catch (error) {
|
|
1666
|
+
await this.emit("llm.error", {
|
|
1667
|
+
role,
|
|
1668
|
+
model: client.name,
|
|
1669
|
+
messages: before.messages,
|
|
1670
|
+
error,
|
|
1671
|
+
durationMs: Date.now() - startedAt
|
|
1672
|
+
});
|
|
1673
|
+
throw error;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
createApi(plugin) {
|
|
1679
|
+
return {
|
|
1680
|
+
xcompilerVersion: this.xcompilerVersion,
|
|
1681
|
+
pluginApiVersion: this.pluginApiVersion,
|
|
1682
|
+
on: (hook, handler, options = {}) => {
|
|
1683
|
+
const registration = {
|
|
1684
|
+
hook,
|
|
1685
|
+
plugin,
|
|
1686
|
+
handler: (context) => handler(context),
|
|
1687
|
+
priority: options.priority ?? 0,
|
|
1688
|
+
order: this.registrationOrder++
|
|
1689
|
+
};
|
|
1690
|
+
const list = this.hooks.get(hook) ?? [];
|
|
1691
|
+
list.push(registration);
|
|
1692
|
+
this.hooks.set(hook, list);
|
|
1693
|
+
return () => {
|
|
1694
|
+
const current2 = this.hooks.get(hook);
|
|
1695
|
+
if (!current2) return;
|
|
1696
|
+
const index = current2.indexOf(registration);
|
|
1697
|
+
if (index >= 0) current2.splice(index, 1);
|
|
1698
|
+
};
|
|
1699
|
+
},
|
|
1700
|
+
registerTool: (tool) => this.contributedTools.push({ plugin, tool }),
|
|
1701
|
+
registerSkill: (skill) => this.contributedSkills.push({ plugin, skill })
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
async handleFailure(plugin, stage, error) {
|
|
1705
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1706
|
+
const rendered = t().plugins.hookFailed(plugin.manifest.id, stage, message);
|
|
1707
|
+
await this.audit?.event("note", rendered, {
|
|
1708
|
+
messageId: "plugins.hook_failed",
|
|
1709
|
+
plugin: plugin.manifest.id,
|
|
1710
|
+
stage,
|
|
1711
|
+
error: message
|
|
1712
|
+
});
|
|
1713
|
+
if (this.strict || plugin.failureMode === "fail") throw error;
|
|
1714
|
+
console.warn(rendered);
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
function assertPluginMetadata(plugins, xcompilerVersion, pluginApiVersion) {
|
|
1718
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1719
|
+
for (const plugin of plugins) {
|
|
1720
|
+
const report = checkPluginCompatibility(plugin.manifest, { xcompilerVersion, pluginApiVersion });
|
|
1721
|
+
if (!report.compatible) throw new Error(report.message);
|
|
1722
|
+
if (seen.has(report.pluginId)) throw new Error(t().plugins.duplicateId(report.pluginId));
|
|
1723
|
+
seen.add(report.pluginId);
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
function snapshotPlugin(plugin) {
|
|
1727
|
+
return { ...plugin, manifest: snapshotManifest(plugin.manifest) };
|
|
1728
|
+
}
|
|
1729
|
+
function snapshotManifest(manifest) {
|
|
1730
|
+
if (!manifest) return {};
|
|
1731
|
+
return {
|
|
1732
|
+
...manifest,
|
|
1733
|
+
keywords: manifest.keywords ? [...manifest.keywords] : void 0
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
// src/plugins/loader.ts
|
|
1738
|
+
import { readFile } from "fs/promises";
|
|
1739
|
+
import path from "path";
|
|
1740
|
+
import { pathToFileURL } from "url";
|
|
1741
|
+
async function loadPluginSources(options) {
|
|
1742
|
+
const baseDir = path.resolve(options.baseDir ?? process.cwd());
|
|
1743
|
+
const runtime = {
|
|
1744
|
+
xcompilerVersion: options.xcompilerVersion ?? XCOMPILER_VERSION,
|
|
1745
|
+
pluginApiVersion: options.pluginApiVersion ?? XCOMPILER_PLUGIN_API_VERSION
|
|
1746
|
+
};
|
|
1747
|
+
const preflight = [];
|
|
1748
|
+
for (const source of options.sources) {
|
|
1749
|
+
const manifestPath = path.resolve(baseDir, source.manifestPath);
|
|
1750
|
+
const entryPath = path.resolve(baseDir, source.entryPath);
|
|
1751
|
+
let manifest;
|
|
1752
|
+
try {
|
|
1753
|
+
manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
const message = t().plugins.manifestReadFailed(manifestPath, errorMessage(error));
|
|
1756
|
+
await auditRejected(options, "", "manifest-read", message, { manifestPath, entryPath });
|
|
1757
|
+
throw new Error(message, { cause: error });
|
|
1758
|
+
}
|
|
1759
|
+
const report = checkPluginCompatibility(manifest, runtime);
|
|
1760
|
+
if (!report.compatible) {
|
|
1761
|
+
const message = report.message ?? report.code;
|
|
1762
|
+
await auditRejected(options, report.pluginId, "compatibility", message, { manifestPath, entryPath });
|
|
1763
|
+
throw new Error(message);
|
|
1764
|
+
}
|
|
1765
|
+
preflight.push({ source, manifest: snapshotManifest2(manifest), manifestPath, entryPath });
|
|
1766
|
+
}
|
|
1767
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1768
|
+
for (const item of preflight) {
|
|
1769
|
+
if (seen.has(item.manifest.id)) {
|
|
1770
|
+
const message = t().plugins.duplicateId(item.manifest.id);
|
|
1771
|
+
await auditRejected(options, item.manifest.id, "duplicate-id", message, item);
|
|
1772
|
+
throw new Error(message);
|
|
1773
|
+
}
|
|
1774
|
+
seen.add(item.manifest.id);
|
|
1775
|
+
}
|
|
1776
|
+
const plugins = [];
|
|
1777
|
+
for (const item of preflight) {
|
|
1778
|
+
const exportName = item.source.exportName ?? "default";
|
|
1779
|
+
let loaded;
|
|
1780
|
+
try {
|
|
1781
|
+
loaded = await import(pathToFileURL(item.entryPath).href);
|
|
1782
|
+
} catch (error) {
|
|
1783
|
+
const message = t().plugins.moduleLoadFailed(item.manifest.id, item.entryPath, errorMessage(error));
|
|
1784
|
+
await auditRejected(options, item.manifest.id, "module-load", message, item);
|
|
1785
|
+
throw new Error(message, { cause: error });
|
|
1786
|
+
}
|
|
1787
|
+
const plugin = loaded[exportName];
|
|
1788
|
+
if (!isPlugin(plugin)) {
|
|
1789
|
+
const message = t().plugins.exportInvalid(item.manifest.id, exportName);
|
|
1790
|
+
await auditRejected(options, item.manifest.id, "module-export", message, item);
|
|
1791
|
+
throw new Error(message);
|
|
1792
|
+
}
|
|
1793
|
+
if (!sameRuntimeManifest(plugin.manifest, item.manifest)) {
|
|
1794
|
+
const message = t().plugins.manifestMismatch(item.manifest.id);
|
|
1795
|
+
await auditRejected(options, item.manifest.id, "manifest-mismatch", message, item);
|
|
1796
|
+
throw new Error(message, { cause: new Error("plugin runtime manifest differs from preflight manifest") });
|
|
1797
|
+
}
|
|
1798
|
+
plugins.push({ ...plugin, manifest: snapshotManifest2(item.manifest) });
|
|
1799
|
+
}
|
|
1800
|
+
return plugins;
|
|
1801
|
+
}
|
|
1802
|
+
function isPlugin(value) {
|
|
1803
|
+
return !!value && typeof value === "object" && typeof value.setup === "function" && !!value.manifest;
|
|
1804
|
+
}
|
|
1805
|
+
function sameRuntimeManifest(actual, expected) {
|
|
1806
|
+
return actual.id === expected.id && actual.version === expected.version && actual.apiVersion === expected.apiVersion && actual.minXCompilerVersion === expected.minXCompilerVersion;
|
|
1807
|
+
}
|
|
1808
|
+
function snapshotManifest2(manifest) {
|
|
1809
|
+
return { ...manifest, keywords: manifest.keywords ? [...manifest.keywords] : void 0 };
|
|
1810
|
+
}
|
|
1811
|
+
function errorMessage(error) {
|
|
1812
|
+
return error instanceof Error ? error.message : String(error);
|
|
1813
|
+
}
|
|
1814
|
+
async function auditRejected(options, pluginId, stage, message, detail) {
|
|
1815
|
+
await options.audit?.event("note", message, {
|
|
1816
|
+
messageId: "plugins.load_rejected",
|
|
1817
|
+
pluginId,
|
|
1818
|
+
stage,
|
|
1819
|
+
detail
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1822
|
+
export {
|
|
1823
|
+
PluginHost,
|
|
1824
|
+
XCOMPILER_PLUGIN_API_VERSION,
|
|
1825
|
+
XCOMPILER_VERSION,
|
|
1826
|
+
checkPluginCompatibility,
|
|
1827
|
+
loadPluginSources
|
|
1828
|
+
};
|
|
1829
|
+
//# sourceMappingURL=index.js.map
|