@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.
@@ -0,0 +1,809 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * AuditLogger 把开发流水线中的所有交互/执行动作记录到两份产物:
5
+ *
6
+ * - `docs/process_log.md` —— 人类可读的过程记录,用于交付时汇总。
7
+ * - `.xcompiler/audit.jsonl` —— 机器可读的逐行 JSON,便于后续分析与回放。
8
+ *
9
+ * 设计原则:
10
+ * - 追加写入,永不删除。
11
+ * - 失败时不影响主流程(写盘异常仅打印 warning)。
12
+ * - 每条事件都带 ts / kind / payload。
13
+ */
14
+ type AuditKind = 'session.start' | 'session.end' | 'user.input' | 'user.decision' | 'llm.request' | 'llm.response' | 'llm.error' | 'llm.score' | 'fs.write' | 'plan.persist' | 'topic.persist' | 'phase.start' | 'phase.end' | 'tool.call' | 'tool.result' | 'sandbox.exec' | 'executor.turn' | 'planner.thought' | 'conftest.autogen' | 'issue.record' | 'issue.route' | 'issue.resolve' | 'note';
15
+ interface AuditLoggerOptions {
16
+ /** workspace 根目录(绝对路径) */
17
+ root: string;
18
+ /** 命令名,例如 `xcompiler_build` / `xcompiler_run` */
19
+ command: string;
20
+ /** markdown 文件相对路径,默认 docs/process_log.md */
21
+ mdRelPath?: string;
22
+ /** jsonl 文件相对路径,默认 .xcompiler/audit.jsonl */
23
+ jsonlRelPath?: string;
24
+ /** full=完整内容;redacted=保留内容但遮蔽凭据(默认);metadata=仅保留长度与摘要。 */
25
+ contentMode?: AuditContentMode;
26
+ }
27
+ type AuditContentMode = 'full' | 'redacted' | 'metadata';
28
+ declare class AuditLogger {
29
+ private readonly mdAbs;
30
+ private readonly jsonlAbs;
31
+ private readonly command;
32
+ private readonly contentMode;
33
+ private startTs;
34
+ /** 串行化 markdown 追加,防止并发 appendFile 交错。 */
35
+ private mdQueue;
36
+ constructor(opts: AuditLoggerOptions);
37
+ start(meta?: Record<string, unknown>): Promise<void>;
38
+ end(summary?: Record<string, unknown>): Promise<void>;
39
+ /** 通用事件,jsonl + 简短 markdown 一行。 */
40
+ event(kind: AuditKind, message: string, data?: Record<string, unknown>): Promise<void>;
41
+ /** 用户输入 / 决策。会把内容以引用块写入 markdown。 */
42
+ userInput(label: string, content: string): Promise<void>;
43
+ userDecision(label: string, value: string): Promise<void>;
44
+ /** LLM 请求/响应:完整 prompt 与回包写入 markdown 折叠块。 */
45
+ llmRequest(role: string, model: string, messages: unknown, options?: unknown): Promise<void>;
46
+ llmResponse(role: string, model: string, content: string, meta?: Record<string, unknown>): Promise<void>;
47
+ llmError(role: string, model: string, err: unknown): Promise<void>;
48
+ /**
49
+ * 记录一轮 Executor 思考:thoughts 文本、计划调用的 actions、是否完成。
50
+ * 写入 jsonl + markdown 折叠块,交付时可作为"AI 思考过程完整记录"。
51
+ */
52
+ executorTurn(stepId: string, role: string, round: number, payload: {
53
+ thoughts?: string;
54
+ actions?: unknown[];
55
+ done?: boolean;
56
+ raw?: string;
57
+ provider?: string;
58
+ }): Promise<void>;
59
+ /** 记录 Planner 的思考阶段,比如 clarify / decompose 原始输出。 */
60
+ plannerThought(stage: string, content: string, meta?: Record<string, unknown> & {
61
+ provider?: string;
62
+ }): Promise<void>;
63
+ private ensureFiles;
64
+ private appendMd;
65
+ private appendJsonl;
66
+ }
67
+
68
+ type ChatRole = 'system' | 'user' | 'assistant';
69
+ interface ChatMessage {
70
+ role: ChatRole;
71
+ content: string;
72
+ }
73
+ interface ChatOptions {
74
+ temperature?: number;
75
+ maxTokens?: number;
76
+ /** Force JSON-only response if provider supports it. */
77
+ responseFormat?: 'text' | 'json';
78
+ /**
79
+ * 流式 token 回调。设置后 provider 会以增量方式推送 token;
80
+ * provider 仍会聚合并返回完整文本作为最终结果。
81
+ */
82
+ onToken?: (chunk: string) => void;
83
+ /**
84
+ * 流式模式下的“可提前结束”判定。用于兼容一些 provider:
85
+ * 输出内容本身已经完整,但既不及时发送 [DONE],也不主动断开连接。
86
+ * 返回 true 后 provider 应尽快结束本次流读取并返回当前 aggregate。
87
+ */
88
+ streamStopWhen?: (text: string) => boolean;
89
+ /**
90
+ * 可选验证钩子:provider 返回后调用。抛异常会被 FallbackClient
91
+ * 视为该 provider 失败,并切换到下一个。适用于:JSON 退化、
92
+ * 空输出、model token loop 等“表面成功但语义不可用”场景。
93
+ */
94
+ validate?: (text: string) => void;
95
+ /**
96
+ * 调用者可传入回调,与 LLM 输出一同拿到实际产出该响应的 provider 名。
97
+ * 主要用于追溯:在 FallbackClient 中服务于响应的是链中某一个后选 provider,
98
+ * 调用者(如 Executor)需要在审计 / Markdown 记录中为响应打上正确的“via 哪个模型”标签。
99
+ */
100
+ onProvider?: (name: string) => void;
101
+ /**
102
+ * 每次开始尝试候选 provider 时触发。用于 CLI 在等待首个 token 前显示
103
+ * 当前 provider 与模型;fallback 切换时会再次触发。
104
+ */
105
+ onProviderStart?: (name: string, model: string) => void;
106
+ }
107
+ interface LLMClient {
108
+ readonly name: string;
109
+ chat(messages: ChatMessage[], options?: ChatOptions): Promise<string>;
110
+ }
111
+
112
+ declare class Workspace {
113
+ readonly root: string;
114
+ constructor(root: string);
115
+ abs(...p: string[]): string;
116
+ ensure(dir: string): Promise<void>;
117
+ writeFile(rel: string, content: string): Promise<void>;
118
+ readFile(rel: string): Promise<string>;
119
+ exists(rel: string): Promise<boolean>;
120
+ remove(rel: string): Promise<void>;
121
+ }
122
+
123
+ interface ExecResult {
124
+ exitCode: number;
125
+ stdout: string;
126
+ stderr: string;
127
+ timedOut: boolean;
128
+ durationMs: number;
129
+ }
130
+ interface ExecExtra {
131
+ cwd?: string;
132
+ env?: Record<string, string>;
133
+ timeoutMs?: number;
134
+ }
135
+ /** 沙盒统一接口。任意 phase / tool 都通过此接口与运行时交互。 */
136
+ interface Sandbox {
137
+ /** 实现标识,便于审计与日志区分。 */
138
+ readonly kind: 'subprocess' | 'docker';
139
+ /**
140
+ * 构建/复用环境。
141
+ * - Python:`pip install -r requirements.txt` + venv。
142
+ * - TypeScript:`npm install`(依据 package.json)。
143
+ * manifestFile 为依赖清单在 workspace 内的相对路径;不存在则跳过安装。
144
+ * 返回是否真正重建。
145
+ */
146
+ build(manifestFile?: string): Promise<{
147
+ rebuilt: boolean;
148
+ reason: string;
149
+ }>;
150
+ /** 执行任意命令;cmd 视实现可能是宿主路径或容器内路径。 */
151
+ exec(cmd: string, argv: string[], extra?: ExecExtra): Promise<ExecResult>;
152
+ /**
153
+ * 运行工程入口程序。
154
+ * - Python:`python <args>`(自动选用 venv 内解释器)。
155
+ * - TypeScript:`npx tsx <args>`。
156
+ */
157
+ runProgram(args: string[], extra?: ExecExtra): Promise<ExecResult>;
158
+ /**
159
+ * 运行测试套件。
160
+ * - Python:`python -m pytest <args>`。
161
+ * - TypeScript:`npm test`(Vitest)。
162
+ */
163
+ runTests(args?: string[], extra?: ExecExtra): Promise<ExecResult>;
164
+ /**
165
+ * 安装额外依赖(不写入依赖清单)。
166
+ * - Python:`pip install <packages>`。
167
+ * - TypeScript:`npm install <packages>`。
168
+ */
169
+ installDeps(packages: string[]): Promise<ExecResult>;
170
+ }
171
+
172
+ /** Supported target languages for generated projects. */
173
+ declare const LANGUAGES: readonly ["python", "typescript"];
174
+ type Language = (typeof LANGUAGES)[number];
175
+ /** Plan intent: greenfield generation, incremental work, or isolated self-bootstrap. */
176
+ declare const PLAN_INTENTS: readonly ["greenfield", "feature", "refactor", "self"];
177
+ type PlanIntent = (typeof PLAN_INTENTS)[number];
178
+ declare const ROLES: readonly ["Planner", "Architect", "Coder", "Tester", "Debugger"];
179
+ type Role = (typeof ROLES)[number];
180
+ interface StepSubtask {
181
+ id: string;
182
+ title: string;
183
+ description: string;
184
+ acceptance?: string;
185
+ outputs?: string[];
186
+ subTasks?: StepSubtask[];
187
+ }
188
+ declare const StepSchema: z.ZodObject<{
189
+ id: z.ZodString;
190
+ iterationId: z.ZodDefault<z.ZodString>;
191
+ phase: z.ZodEnum<{
192
+ REQUIREMENT_ANALYSIS: "REQUIREMENT_ANALYSIS";
193
+ HIGH_LEVEL_DESIGN: "HIGH_LEVEL_DESIGN";
194
+ DETAILED_DESIGN: "DETAILED_DESIGN";
195
+ CODE: "CODE";
196
+ UNIT_TEST: "UNIT_TEST";
197
+ INTEGRATION_TEST: "INTEGRATION_TEST";
198
+ MODULE_TEST: "MODULE_TEST";
199
+ FUNCTIONAL_TEST: "FUNCTIONAL_TEST";
200
+ DEBUG: "DEBUG";
201
+ }>;
202
+ title: z.ZodString;
203
+ description: z.ZodString;
204
+ systemPrompt: z.ZodString;
205
+ role: z.ZodEnum<{
206
+ Planner: "Planner";
207
+ Architect: "Architect";
208
+ Coder: "Coder";
209
+ Tester: "Tester";
210
+ Debugger: "Debugger";
211
+ }>;
212
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
213
+ inputs: z.ZodDefault<z.ZodArray<z.ZodString>>;
214
+ outputs: z.ZodDefault<z.ZodArray<z.ZodString>>;
215
+ subTasks: z.ZodOptional<z.ZodArray<z.ZodType<StepSubtask, unknown, z.core.$ZodTypeInternals<StepSubtask, unknown>>>>;
216
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
217
+ acceptance: z.ZodString;
218
+ status: z.ZodDefault<z.ZodEnum<{
219
+ PENDING: "PENDING";
220
+ RUNNING: "RUNNING";
221
+ DONE: "DONE";
222
+ FAILED: "FAILED";
223
+ SKIPPED: "SKIPPED";
224
+ }>>;
225
+ retries: z.ZodDefault<z.ZodNumber>;
226
+ maxRetries: z.ZodDefault<z.ZodNumber>;
227
+ }, z.core.$strip>;
228
+ type Step = z.infer<typeof StepSchema>;
229
+ declare const PlanSchema: z.ZodPipe<z.ZodObject<{
230
+ version: z.ZodLiteral<"1">;
231
+ language: z.ZodDefault<z.ZodEnum<{
232
+ python: "python";
233
+ typescript: "typescript";
234
+ }>>;
235
+ intent: z.ZodDefault<z.ZodEnum<{
236
+ greenfield: "greenfield";
237
+ feature: "feature";
238
+ refactor: "refactor";
239
+ self: "self";
240
+ }>>;
241
+ projectType: z.ZodDefault<z.ZodEnum<{
242
+ application: "application";
243
+ library: "library";
244
+ mixed: "mixed";
245
+ }>>;
246
+ requirementDigest: z.ZodString;
247
+ complexityAssessment: z.ZodOptional<z.ZodObject<{
248
+ level: z.ZodEnum<{
249
+ simple: "simple";
250
+ moderate: "moderate";
251
+ complex: "complex";
252
+ }>;
253
+ rationale: z.ZodString;
254
+ splitRecommended: z.ZodDefault<z.ZodBoolean>;
255
+ userForcedPhaseSplit: z.ZodDefault<z.ZodBoolean>;
256
+ }, z.core.$strip>>;
257
+ implementationPhases: z.ZodOptional<z.ZodArray<z.ZodObject<{
258
+ id: z.ZodString;
259
+ title: z.ZodString;
260
+ objective: z.ZodString;
261
+ status: z.ZodDefault<z.ZodEnum<{
262
+ current: "current";
263
+ planned: "planned";
264
+ deferred: "deferred";
265
+ }>>;
266
+ scope: z.ZodDefault<z.ZodArray<z.ZodString>>;
267
+ deliverables: z.ZodDefault<z.ZodArray<z.ZodString>>;
268
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
269
+ verificationGate: z.ZodOptional<z.ZodObject<{
270
+ summary: z.ZodString;
271
+ checks: z.ZodArray<z.ZodString>;
272
+ failurePolicy: z.ZodString;
273
+ }, z.core.$strip>>;
274
+ }, z.core.$strip>>>;
275
+ architectureModules: z.ZodOptional<z.ZodArray<z.ZodObject<{
276
+ id: z.ZodString;
277
+ name: z.ZodString;
278
+ responsibility: z.ZodString;
279
+ sourcePaths: z.ZodArray<z.ZodString>;
280
+ testPaths: z.ZodArray<z.ZodString>;
281
+ dependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
282
+ }, z.core.$strip>>>;
283
+ globalPrompt: z.ZodDefault<z.ZodString>;
284
+ baselineSummary: z.ZodDefault<z.ZodString>;
285
+ dependencies: z.ZodOptional<z.ZodArray<z.ZodString>>;
286
+ pythonRequirements: z.ZodOptional<z.ZodArray<z.ZodString>>;
287
+ userAddenda: z.ZodDefault<z.ZodString>;
288
+ createdAt: z.ZodString;
289
+ steps: z.ZodArray<z.ZodObject<{
290
+ id: z.ZodString;
291
+ iterationId: z.ZodDefault<z.ZodString>;
292
+ phase: z.ZodEnum<{
293
+ REQUIREMENT_ANALYSIS: "REQUIREMENT_ANALYSIS";
294
+ HIGH_LEVEL_DESIGN: "HIGH_LEVEL_DESIGN";
295
+ DETAILED_DESIGN: "DETAILED_DESIGN";
296
+ CODE: "CODE";
297
+ UNIT_TEST: "UNIT_TEST";
298
+ INTEGRATION_TEST: "INTEGRATION_TEST";
299
+ MODULE_TEST: "MODULE_TEST";
300
+ FUNCTIONAL_TEST: "FUNCTIONAL_TEST";
301
+ DEBUG: "DEBUG";
302
+ }>;
303
+ title: z.ZodString;
304
+ description: z.ZodString;
305
+ systemPrompt: z.ZodString;
306
+ role: z.ZodEnum<{
307
+ Planner: "Planner";
308
+ Architect: "Architect";
309
+ Coder: "Coder";
310
+ Tester: "Tester";
311
+ Debugger: "Debugger";
312
+ }>;
313
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
314
+ inputs: z.ZodDefault<z.ZodArray<z.ZodString>>;
315
+ outputs: z.ZodDefault<z.ZodArray<z.ZodString>>;
316
+ subTasks: z.ZodOptional<z.ZodArray<z.ZodType<StepSubtask, unknown, z.core.$ZodTypeInternals<StepSubtask, unknown>>>>;
317
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
318
+ acceptance: z.ZodString;
319
+ status: z.ZodDefault<z.ZodEnum<{
320
+ PENDING: "PENDING";
321
+ RUNNING: "RUNNING";
322
+ DONE: "DONE";
323
+ FAILED: "FAILED";
324
+ SKIPPED: "SKIPPED";
325
+ }>>;
326
+ retries: z.ZodDefault<z.ZodNumber>;
327
+ maxRetries: z.ZodDefault<z.ZodNumber>;
328
+ }, z.core.$strip>>;
329
+ }, z.core.$strip>, z.ZodTransform<{
330
+ dependencies: string[];
331
+ version: "1";
332
+ language: "python" | "typescript";
333
+ intent: "greenfield" | "feature" | "refactor" | "self";
334
+ projectType: "application" | "library" | "mixed";
335
+ requirementDigest: string;
336
+ globalPrompt: string;
337
+ baselineSummary: string;
338
+ userAddenda: string;
339
+ createdAt: string;
340
+ steps: {
341
+ id: string;
342
+ iterationId: string;
343
+ phase: "REQUIREMENT_ANALYSIS" | "HIGH_LEVEL_DESIGN" | "DETAILED_DESIGN" | "CODE" | "UNIT_TEST" | "INTEGRATION_TEST" | "MODULE_TEST" | "FUNCTIONAL_TEST" | "DEBUG";
344
+ title: string;
345
+ description: string;
346
+ systemPrompt: string;
347
+ role: "Planner" | "Architect" | "Coder" | "Tester" | "Debugger";
348
+ tools: string[];
349
+ inputs: string[];
350
+ outputs: string[];
351
+ dependsOn: string[];
352
+ acceptance: string;
353
+ status: "PENDING" | "RUNNING" | "DONE" | "FAILED" | "SKIPPED";
354
+ retries: number;
355
+ maxRetries: number;
356
+ subTasks?: StepSubtask[] | undefined;
357
+ }[];
358
+ complexityAssessment?: {
359
+ level: "simple" | "moderate" | "complex";
360
+ rationale: string;
361
+ splitRecommended: boolean;
362
+ userForcedPhaseSplit: boolean;
363
+ } | undefined;
364
+ implementationPhases?: {
365
+ id: string;
366
+ title: string;
367
+ objective: string;
368
+ status: "current" | "planned" | "deferred";
369
+ scope: string[];
370
+ deliverables: string[];
371
+ dependsOn: string[];
372
+ verificationGate?: {
373
+ summary: string;
374
+ checks: string[];
375
+ failurePolicy: string;
376
+ } | undefined;
377
+ }[] | undefined;
378
+ architectureModules?: {
379
+ id: string;
380
+ name: string;
381
+ responsibility: string;
382
+ sourcePaths: string[];
383
+ testPaths: string[];
384
+ dependencies: string[];
385
+ }[] | undefined;
386
+ }, {
387
+ version: "1";
388
+ language: "python" | "typescript";
389
+ intent: "greenfield" | "feature" | "refactor" | "self";
390
+ projectType: "application" | "library" | "mixed";
391
+ requirementDigest: string;
392
+ globalPrompt: string;
393
+ baselineSummary: string;
394
+ userAddenda: string;
395
+ createdAt: string;
396
+ steps: {
397
+ id: string;
398
+ iterationId: string;
399
+ phase: "REQUIREMENT_ANALYSIS" | "HIGH_LEVEL_DESIGN" | "DETAILED_DESIGN" | "CODE" | "UNIT_TEST" | "INTEGRATION_TEST" | "MODULE_TEST" | "FUNCTIONAL_TEST" | "DEBUG";
400
+ title: string;
401
+ description: string;
402
+ systemPrompt: string;
403
+ role: "Planner" | "Architect" | "Coder" | "Tester" | "Debugger";
404
+ tools: string[];
405
+ inputs: string[];
406
+ outputs: string[];
407
+ dependsOn: string[];
408
+ acceptance: string;
409
+ status: "PENDING" | "RUNNING" | "DONE" | "FAILED" | "SKIPPED";
410
+ retries: number;
411
+ maxRetries: number;
412
+ subTasks?: StepSubtask[] | undefined;
413
+ }[];
414
+ complexityAssessment?: {
415
+ level: "simple" | "moderate" | "complex";
416
+ rationale: string;
417
+ splitRecommended: boolean;
418
+ userForcedPhaseSplit: boolean;
419
+ } | undefined;
420
+ implementationPhases?: {
421
+ id: string;
422
+ title: string;
423
+ objective: string;
424
+ status: "current" | "planned" | "deferred";
425
+ scope: string[];
426
+ deliverables: string[];
427
+ dependsOn: string[];
428
+ verificationGate?: {
429
+ summary: string;
430
+ checks: string[];
431
+ failurePolicy: string;
432
+ } | undefined;
433
+ }[] | undefined;
434
+ architectureModules?: {
435
+ id: string;
436
+ name: string;
437
+ responsibility: string;
438
+ sourcePaths: string[];
439
+ testPaths: string[];
440
+ dependencies: string[];
441
+ }[] | undefined;
442
+ dependencies?: string[] | undefined;
443
+ pythonRequirements?: string[] | undefined;
444
+ }>>;
445
+ type Plan = z.infer<typeof PlanSchema>;
446
+
447
+ type ToolPermissionOperation = 'shell_command' | 'file_write' | 'file_delete' | 'install_dependency' | 'config_change' | 'git_operation' | 'network_access' | 'test_command' | 'build_command' | 'external_read' | 'external_write';
448
+ interface ToolPermissionRequest {
449
+ id?: string;
450
+ operationType: ToolPermissionOperation;
451
+ target: string;
452
+ reason: string;
453
+ risk: string;
454
+ scope: string;
455
+ skippable: boolean;
456
+ denyBehavior: string;
457
+ stepId?: string;
458
+ tool?: string;
459
+ metadata?: Record<string, unknown>;
460
+ }
461
+ interface ToolPermissionDecision {
462
+ approved: boolean;
463
+ reason?: string;
464
+ }
465
+ type ToolPermissionRequester = (request: ToolPermissionRequest) => Promise<ToolPermissionDecision>;
466
+ interface ToolExecutionEvent {
467
+ status: 'started' | 'completed';
468
+ stepId: string;
469
+ tool: string;
470
+ target?: string;
471
+ args?: Record<string, unknown>;
472
+ ok?: boolean;
473
+ summary?: string;
474
+ error?: string;
475
+ changedFiles?: string[];
476
+ patch?: string;
477
+ }
478
+ type ToolExecutionReporter = (event: ToolExecutionEvent) => void | Promise<void>;
479
+ /** 工具调用的统一上下文。 */
480
+ interface ToolContext {
481
+ ws: Workspace;
482
+ sandbox: Sandbox;
483
+ audit?: AuditLogger;
484
+ /** 当前 Step 的 outputs 白名单(写操作必须落在白名单内)。 */
485
+ allowedWrites: string[];
486
+ /** 当前 Step 的 id(仅用于审计)。 */
487
+ stepId: string;
488
+ /** 目标语言(决定依赖清单文件等)。默认 python。 */
489
+ language?: Language;
490
+ /** 当前 Step 的 write_file / append_file 单次 content 字节预算。 */
491
+ writeChunkBytes?: number;
492
+ /** Optional protocol/UI permission hook for sensitive tool operations. */
493
+ requestPermission?: ToolPermissionRequester;
494
+ /** Optional protocol/UI event hook for tool calls and file changes. */
495
+ onToolEvent?: ToolExecutionReporter;
496
+ }
497
+ /** 单次工具调用的结果统一结构。 */
498
+ interface ToolResult<T = unknown> {
499
+ ok: boolean;
500
+ data?: T;
501
+ error?: string;
502
+ /** 用于摘要展示。 */
503
+ summary?: string;
504
+ }
505
+ interface Tool<A = unknown, R = unknown> {
506
+ readonly name: string;
507
+ readonly description: string;
508
+ /** 简要 JSON Schema 描述参数(仅用于 prompt,不强校验)。 */
509
+ readonly argsSchema: Record<string, unknown>;
510
+ run(args: A, ctx: ToolContext): Promise<ToolResult<R>>;
511
+ }
512
+
513
+ declare const CLARIFICATION_CATEGORIES: readonly ["functionality", "data", "acceptance", "boundary", "quality", "extensibility"];
514
+ type ClarificationCategory = (typeof CLARIFICATION_CATEGORIES)[number];
515
+ declare const CLARIFICATION_OPTION_LABELS: readonly ["A", "B", "C", "D", "E"];
516
+ type ClarificationOptionLabel = (typeof CLARIFICATION_OPTION_LABELS)[number];
517
+ interface ClarifyOption {
518
+ label: ClarificationOptionLabel;
519
+ answer: string;
520
+ }
521
+ interface ClarifyQuestion {
522
+ id: string;
523
+ category: ClarificationCategory;
524
+ question: string;
525
+ why: string;
526
+ options: ClarifyOption[];
527
+ }
528
+ interface PlannerInput {
529
+ rawRequirement: string;
530
+ clarifications: Array<{
531
+ question: string;
532
+ answer: string;
533
+ category?: ClarificationCategory;
534
+ why?: string;
535
+ options?: ClarifyOption[];
536
+ }>;
537
+ /** 用户在澄清问答后补充的自定义需求(可为空)。 */
538
+ userAddenda?: string;
539
+ /** 增量开发时,现有工程基线摘要(文档 / 计划 / 源码树)。 */
540
+ baselineContext?: string;
541
+ /** 计划意图:greenfield / feature / refactor / self。 */
542
+ intent?: PlanIntent;
543
+ }
544
+
545
+ /**
546
+ * Skill:把一组原子工具组合为面向 LLM 的"高阶能力"。
547
+ *
548
+ * 在 M3 阶段 Skill 是一层"语义包装"——执行器仍然按 step.tools 中的工具名调用具体 Tool,
549
+ * 但 Step 可以声明 `tools: ["skill:patcher"]`,Skill Registry 会展开为底层工具集合,
550
+ * 并把 Skill 的 `prompt` 注入 system prompt,提示 LLM 该如何组合这些工具。
551
+ */
552
+ interface Skill {
553
+ /** 形如 `patcher` / `tester` / `dep_resolver`。 */
554
+ readonly name: string;
555
+ /** 注入到 system prompt 的简短指引(中文一句话)。 */
556
+ readonly prompt: string;
557
+ /** 该 Skill 暴露给 LLM 的底层工具名集合。 */
558
+ readonly tools: string[];
559
+ }
560
+
561
+ interface EngineRunSummary {
562
+ totalSteps: number;
563
+ executedSteps: number;
564
+ failedStepId?: string;
565
+ failureLog?: string;
566
+ failureReason?: string;
567
+ }
568
+ interface StepAttemptOutcome {
569
+ ok: boolean;
570
+ failureLog: string;
571
+ reason?: string;
572
+ }
573
+ /**
574
+ * XCompiler 的公共生命周期 Hook。
575
+ *
576
+ * Context 对象会按顺序传给所有 handler;插件可以原位补充或调整字段,但不得替换
577
+ * workspace / audit 等核心服务。涉及文件写入时仍必须通过 Tool 与 EditGuard。
578
+ */
579
+ interface HookContextMap {
580
+ 'compile.start': {
581
+ workspace: string;
582
+ intent: PlanIntent;
583
+ topicMode: boolean;
584
+ };
585
+ 'compile.afterClarify': {
586
+ rawRequirement: string;
587
+ questions: ClarifyQuestion[];
588
+ clarifications: PlannerInput['clarifications'];
589
+ userAddenda: string;
590
+ };
591
+ 'compile.beforeDecompose': {
592
+ input: PlannerInput;
593
+ };
594
+ 'compile.afterPlan': {
595
+ plan: Plan;
596
+ };
597
+ 'compile.finish': {
598
+ plan: Plan;
599
+ planPath: string;
600
+ };
601
+ 'run.before': {
602
+ plan: Plan;
603
+ };
604
+ 'run.after': {
605
+ plan: Plan;
606
+ result: EngineRunSummary;
607
+ };
608
+ 'run.error': {
609
+ plan: Plan;
610
+ error: unknown;
611
+ };
612
+ 'step.before': {
613
+ plan: Plan;
614
+ step: Step;
615
+ };
616
+ 'step.after': {
617
+ plan: Plan;
618
+ step: Step;
619
+ ok: boolean;
620
+ };
621
+ 'step.error': {
622
+ plan: Plan;
623
+ step: Step;
624
+ error: unknown;
625
+ };
626
+ 'step.attempt.before': {
627
+ plan: Plan;
628
+ step: Step;
629
+ role: Role;
630
+ debug: boolean;
631
+ retry: number;
632
+ };
633
+ 'step.attempt.after': {
634
+ plan: Plan;
635
+ step: Step;
636
+ role: Role;
637
+ debug: boolean;
638
+ retry: number;
639
+ outcome: StepAttemptOutcome;
640
+ };
641
+ 'tool.before': {
642
+ stepId: string;
643
+ tool: string;
644
+ args: unknown;
645
+ context: ToolContext;
646
+ };
647
+ 'tool.after': {
648
+ stepId: string;
649
+ tool: string;
650
+ args: unknown;
651
+ context: ToolContext;
652
+ result: ToolResult;
653
+ };
654
+ 'tool.error': {
655
+ stepId: string;
656
+ tool: string;
657
+ args: unknown;
658
+ context: ToolContext;
659
+ error: unknown;
660
+ };
661
+ 'llm.before': {
662
+ role: string;
663
+ model: string;
664
+ messages: ChatMessage[];
665
+ options?: ChatOptions;
666
+ };
667
+ 'llm.after': {
668
+ role: string;
669
+ model: string;
670
+ messages: ChatMessage[];
671
+ response: string;
672
+ durationMs: number;
673
+ };
674
+ 'llm.error': {
675
+ role: string;
676
+ model: string;
677
+ messages: ChatMessage[];
678
+ error: unknown;
679
+ durationMs: number;
680
+ };
681
+ }
682
+ type HookName = keyof HookContextMap;
683
+ type HookHandler<K extends HookName> = (context: HookContextMap[K]) => void | Promise<void>;
684
+ interface HookRegistrationOptions {
685
+ /** 数值越大越先执行;相同优先级保持插件及注册顺序。 */
686
+ priority?: number;
687
+ }
688
+ interface PluginApi {
689
+ /** 当前 XCompiler 核心版本。 */
690
+ readonly xcompilerVersion: string;
691
+ /** 当前插件 API 主版本;仅同一主版本兼容。 */
692
+ readonly pluginApiVersion: number;
693
+ on<K extends HookName>(hook: K, handler: HookHandler<K>, options?: HookRegistrationOptions): () => void;
694
+ registerTool(tool: Tool): void;
695
+ registerSkill(skill: Skill): void;
696
+ }
697
+ /** 可序列化的插件清单;后续 registry / marketplace 不需要加载插件代码即可读取。 */
698
+ interface XCompilerPluginManifest {
699
+ /** 全局唯一且稳定的插件 ID,例如 `company.policy-checker`。 */
700
+ id: string;
701
+ /** 插件自身版本,必须是完整 SemVer。 */
702
+ version: string;
703
+ /** 插件编译时面向的 XCompiler Plugin API 主版本。 */
704
+ apiVersion: number;
705
+ /** 插件可运行的最低 XCompiler 核心版本;必填完整 SemVer。 */
706
+ minXCompilerVersion: string;
707
+ /** 以下字段用于插件目录展示,不参与运行时兼容判定。 */
708
+ displayName?: string;
709
+ description?: string;
710
+ license?: string;
711
+ homepage?: string;
712
+ keywords?: string[];
713
+ }
714
+ type PluginCompatibilityCode = 'compatible' | 'invalid-runtime-version' | 'invalid-id' | 'invalid-plugin-version' | 'invalid-min-xcompiler-version' | 'api-version-mismatch' | 'xcompiler-version-too-old';
715
+ interface PluginCompatibilityReport {
716
+ compatible: boolean;
717
+ code: PluginCompatibilityCode;
718
+ pluginId: string;
719
+ pluginVersion: string;
720
+ xcompilerVersion: string;
721
+ pluginApiVersion: number;
722
+ message?: string;
723
+ }
724
+ interface XCompilerPlugin {
725
+ manifest: XCompilerPluginManifest;
726
+ /** 默认 continue:记录错误但不拖垮核心流程。 */
727
+ failureMode?: 'continue' | 'fail';
728
+ setup(api: PluginApi): void | Promise<void>;
729
+ }
730
+ /** 插件磁盘来源;manifest 与可执行入口分离,兼容检查先于模块 import。 */
731
+ interface PluginSource {
732
+ manifestPath: string;
733
+ entryPath: string;
734
+ /** 模块导出名,默认 `default`。 */
735
+ exportName?: string;
736
+ }
737
+ interface PluginLoadOptions {
738
+ sources: PluginSource[];
739
+ baseDir?: string;
740
+ audit?: AuditLogger;
741
+ xcompilerVersion?: string;
742
+ pluginApiVersion?: number;
743
+ }
744
+ interface PluginHostOptions {
745
+ plugins?: XCompilerPlugin[];
746
+ /** 强制所有插件错误中断主流程,适合 CI / 合规插件。 */
747
+ strict?: boolean;
748
+ audit?: AuditLogger;
749
+ /** 嵌入式宿主可显式传入版本;一般应使用内置默认值。 */
750
+ xcompilerVersion?: string;
751
+ pluginApiVersion?: number;
752
+ }
753
+ interface PluginExtensionTarget {
754
+ tools: {
755
+ get(name: string): Tool | undefined;
756
+ register(tool: Tool): void;
757
+ };
758
+ skills: {
759
+ get(name: string): Skill | undefined;
760
+ register(skill: Skill): void;
761
+ };
762
+ }
763
+
764
+ /** 插件注册、扩展能力合并与生命周期 Hook 调度中心。 */
765
+ declare class PluginHost {
766
+ private readonly plugins;
767
+ private readonly strict;
768
+ private readonly xcompilerVersion;
769
+ private readonly pluginApiVersion;
770
+ private readonly hooks;
771
+ private readonly contributedTools;
772
+ private readonly contributedSkills;
773
+ private audit?;
774
+ private initialized;
775
+ private registrationOrder;
776
+ constructor(options?: PluginHostOptions);
777
+ get size(): number;
778
+ /** 返回只读清单快照,供诊断、插件目录和未来 registry 使用。 */
779
+ get manifests(): readonly XCompilerPluginManifest[];
780
+ setAudit(audit: AuditLogger): void;
781
+ initialize(): Promise<void>;
782
+ /** 把插件贡献的 Tool / Skill 合并到 Engine 的默认注册表;禁止静默覆盖核心能力。 */
783
+ applyExtensions(target: PluginExtensionTarget): void;
784
+ emit<K extends HookName>(hook: K, context: HookContextMap[K]): Promise<void>;
785
+ /** 在不绕过原 Tool / EditGuard 的前提下增加 before / after / error Hook。 */
786
+ wrapTool<A, R>(tool: Tool<A, R>): Tool<A, R>;
787
+ /** 包装完整 LLM 调用;response 可由 after Hook 做结构化后处理。 */
788
+ wrapLLM(client: LLMClient, role: string): LLMClient;
789
+ private createApi;
790
+ private handleFailure;
791
+ }
792
+
793
+ interface PluginRuntimeVersion {
794
+ xcompilerVersion?: string;
795
+ pluginApiVersion?: number;
796
+ }
797
+ /** 在加载插件代码前可独立调用的 manifest 兼容性检查。 */
798
+ declare function checkPluginCompatibility(manifest: XCompilerPluginManifest, runtime?: PluginRuntimeVersion): PluginCompatibilityReport;
799
+
800
+ /**
801
+ * 从磁盘加载插件。全部 manifest 会在任何插件模块 import 之前完成读取、兼容性与
802
+ * 重复 ID 检查,避免不兼容插件借助模块顶层代码绕过宿主版本门禁。
803
+ */
804
+ declare function loadPluginSources(options: PluginLoadOptions): Promise<XCompilerPlugin[]>;
805
+
806
+ declare const XCOMPILER_VERSION = "0.2.2";
807
+ declare const XCOMPILER_PLUGIN_API_VERSION = 1;
808
+
809
+ export { type EngineRunSummary, type HookContextMap, type HookHandler, type HookName, type HookRegistrationOptions, type PluginApi, type PluginCompatibilityCode, type PluginCompatibilityReport, type PluginExtensionTarget, PluginHost, type PluginHostOptions, type PluginLoadOptions, type PluginRuntimeVersion, type PluginSource, type Skill, type StepAttemptOutcome, type Tool, type ToolContext, type ToolResult, XCOMPILER_PLUGIN_API_VERSION, XCOMPILER_VERSION, type XCompilerPlugin, type XCompilerPluginManifest, checkPluginCompatibility, loadPluginSources };