@nick848/fet 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,101 +1,265 @@
1
1
  # FET
2
2
 
3
- FET is a frontend workflow orchestration CLI built around OpenSpec. It does not generate business code itself. Instead, it proxies OpenSpec commands, maintains local workflow state, generates auditable context files, and helps AI coding tools read the right project context.
3
+ FET 是一个围绕 OpenSpec 构建的前端开发工作流编排 CLI。它不会直接生成业务代码,而是代理 OpenSpec 命令、维护本地工作流状态、生成可审计的项目上下文,并帮助 Cursor AI 编程工具读取正确的项目资料。
4
4
 
5
- ## Status
5
+ ### 作用
6
6
 
7
- This package is currently `0.3.0-dev`: a development build aimed at stabilizing the MVP before a public stable release. The supported surface includes:
7
+ - 统一入口:用 `fet <command>` 包装 OpenSpec 工作流,避免用户和 AI 工具绕过 FET 的状态记录。
8
+ - 生成上下文:扫描项目并生成 `AGENTS.md` 与 `openspec/config.yaml` 中的 `fet:` 配置。
9
+ - 管理状态:记录 active change、任务同步、手动验证声明、工具适配状态等本地工作流信息。
10
+ - 集成 AI 工具:为 Cursor 生成项目规则和 Skill 说明,引导 AI 读取 OpenSpec 规划产物和项目上下文。
11
+ - 保护关键阶段:在 `sync` / `archive` 前检查 FET 的 verify 状态,降低未验证变更被归档的风险。
8
12
 
9
- - `fet init`
10
- - `fet update-context`
11
- - `fet doctor`
12
- - OpenSpec proxy commands such as `fet propose`, `fet apply`, `fet sync`, `fet archive`
13
- - manual verification with `fet verify` and `fet verify --done`
14
- - Cursor project files generation and doctor checks
15
- - scanner support for package manager conflicts, TypeScript, basic workspaces, and common frontend frameworks
13
+ ### 基本原理
16
14
 
17
- `fet verify --auto` currently generates and optionally records an approved execution plan only. It does not run project scripts yet.
15
+ FET OpenSpec 的透明代理和本地编排层。用户运行 `fet apply`、`fet archive` 等命令时,FET 会先读取项目状态和 change 状态,执行必要的 pre-hook,再调用真实的 `openspec` CLI,最后根据 OpenSpec 的结果更新 FET 状态。
18
16
 
19
- Not stable yet:
17
+ 对于 OpenSpec 1.2.x,FET 会把部分高层命令映射到真实 OpenSpec 命令。例如 `fet apply` 会调用 `openspec instructions apply --change <id>` 输出实施指令,`fet sync` 会调用 `openspec validate <change> --type change --strict` 做归档前校验。
20
18
 
21
- - Real OpenSpec compatibility is still limited to the currently tested command lifecycle.
22
- - Cursor integration writes project files and includes best-effort rule/skill guidance, but users should confirm their Cursor version recognizes the generated format.
23
- - CI configuration is included for Windows/macOS/Linux and Node 18/20/22; it still needs to run in a hosted repository before stable release.
19
+ ### 环境要求
24
20
 
25
- ## Requirements
21
+ - Node.js 18 或更高版本
22
+ - OpenSpec CLI 在 `PATH` 中可用
23
+
24
+ 安装 OpenSpec:
25
+
26
+ ```sh
27
+ npm install -g @fission-ai/openspec
28
+ ```
29
+
30
+ ### 安装 FET
31
+
32
+ ```sh
33
+ npm install -g @nick848/fet
34
+ ```
35
+
36
+ 安装后检查:
37
+
38
+ ```sh
39
+ fet --version
40
+ fet --help
41
+ ```
42
+
43
+ ### 快速开始
44
+
45
+ 在需要接入 OpenSpec 的项目根目录运行:
46
+
47
+ ```sh
48
+ fet init
49
+ fet doctor
50
+ ```
51
+
52
+ 典型流程:
53
+
54
+ ```sh
55
+ fet new my-change
56
+ fet apply --change my-change
57
+ fet verify --change my-change
58
+ fet verify --done --change my-change
59
+ fet sync --change my-change
60
+ fet archive --change my-change
61
+ ```
62
+
63
+ ### 全局参数
64
+
65
+ | 参数 | 说明 | 示例 |
66
+ |------|------|------|
67
+ | `--cwd <path>` | 指定项目根目录,默认当前目录。 | `fet doctor --cwd ./app` |
68
+ | `--change <id>` | 指定 OpenSpec change。 | `fet apply --change add-login` |
69
+ | `--yes` | 对低风险确认使用默认同意。 | `fet init --yes` |
70
+ | `--json` | 输出机器可读 JSON。 | `fet doctor --json` |
71
+ | `--verbose` | 输出更多诊断信息。 | `fet doctor --verbose` |
72
+ | `--no-color` | 禁用终端颜色。 | `fet --no-color doctor` |
73
+
74
+ ### 命令列表
75
+
76
+ | 命令 | 用法 | 说明 |
77
+ |------|------|------|
78
+ | `fet init` | `fet init [--yes]` | 初始化 FET 和 OpenSpec;生成上下文文件、状态文件、Cursor 规则和 Skill。 |
79
+ | `fet update-context` | `fet update-context [--yes]` | 重新扫描项目并更新 `AGENTS.md` 与 `openspec/config.yaml` 的 FET 托管区域。 |
80
+ | `fet doctor` | `fet doctor [--fix-lock]` | 诊断 OpenSpec、FET 状态、上下文文件、Cursor 集成和锁文件。 |
81
+ | `fet explore` | `fet explore --change <id>` | 输出探索/提案相关 OpenSpec 指令,帮助 AI 讨论需求。 |
82
+ | `fet propose` | `fet propose <change-id>` | 创建新的 OpenSpec change;等价于 FET 高层提案入口。 |
83
+ | `fet new` | `fet new <change-id>` | 创建新的 OpenSpec change。 |
84
+ | `fet continue` | `fet continue [artifact] --change <id>` | 输出指定 artifact 的 OpenSpec 指令,默认 `proposal`。 |
85
+ | `fet ff` | `fet ff --change <id>` | 查看当前 change 的 OpenSpec artifact 状态。 |
86
+ | `fet apply` | `fet apply --change <id>` | 输出实施当前 change 的 OpenSpec apply 指令,并同步 FET 状态。 |
87
+ | `fet verify` | `fet verify --change <id>` | 生成 `.fet/verify-instructions.md` 手动验证指令。 |
88
+ | `fet verify --done` | `fet verify --done --change <id>` | 声明已完成手动验证,允许后续 `sync` / `archive`。 |
89
+ | `fet verify --auto` | `fet verify --auto [--yes]` | 生成自动验证执行计划;当前版本不执行项目脚本,`--yes` 会记录授权计划指纹。 |
90
+ | `fet sync` | `fet sync --change <id>` | 在 FET verify gate 通过后,调用 OpenSpec 严格校验 change。 |
91
+ | `fet archive` | `fet archive --change <id>` | 在 FET verify gate 通过后,归档 change 并更新 OpenSpec 主规范。 |
92
+ | `fet bulk-archive` | `fet bulk-archive` | 当前 OpenSpec 1.2.x 无对应顶层命令;请逐个执行 `fet archive --change <id>`。 |
93
+ | `fet onboard` | `fet onboard` | 输出 OpenSpec onboarding / instruction 信息。 |
94
+ | `fet passthrough` | `fet passthrough <command> [...args]` | 透传暂未接管的 OpenSpec 命令,不更新 FET 生命周期状态。 |
95
+
96
+ ### 生成文件
97
+
98
+ FET 可能创建或更新:
99
+
100
+ - `AGENTS.md`
101
+ - `openspec/config.yaml` 的 `fet:` 命名空间
102
+ - `openspec/fet-state.json`
103
+ - `openspec/changes/<change-id>/fet-state.json`
104
+ - `openspec/changes/<change-id>/.fet/verify-instructions.md`
105
+ - `.cursor/skills/fet-*/SKILL.md`
106
+ - `.cursor/rules/fet-context.mdc`
107
+
108
+ FET 只拥有明确标记的托管区域,托管区域之外的用户内容应被保留。`fet init` 还会向 `.gitignore` 添加 FET 本地状态块,避免把锁文件和本地状态误提交。
109
+
110
+ ### 安全边界
111
+
112
+ FET 是本地工作流辅助工具,不是沙箱、CI 强制 gate 或密码学审计系统。直接调用 `openspec` 可以绕过 FET 的本地 gate。团队如果需要强制执行验证,应在 CI、分支保护或代码审查规则中重复校验。
113
+
114
+ ### 开发
115
+
116
+ ```sh
117
+ npm install
118
+ npm run typecheck
119
+ npm run test
120
+ npm run build
121
+ npm run release:check
122
+ ```
123
+
124
+ 运行真实 OpenSpec 烟测:
125
+
126
+ ```powershell
127
+ $env:FET_REAL_OPENSPEC='1'; npm run test:real-openspec
128
+ ```
129
+
130
+ ### 许可证
131
+
132
+ MIT
133
+
134
+ ## English
135
+
136
+ FET is a frontend development workflow orchestration CLI built around OpenSpec. It does not generate business code directly. Instead, it proxies OpenSpec commands, maintains local workflow state, generates auditable project context, and helps AI coding tools such as Cursor load the right files.
137
+
138
+ ### What It Does
139
+
140
+ - Provides one entry point through `fet <command>` for OpenSpec workflows.
141
+ - Generates `AGENTS.md` and the `fet:` namespace in `openspec/config.yaml`.
142
+ - Tracks local workflow state such as active changes, synced tasks, manual verification declarations, and tool adapter state.
143
+ - Integrates with AI tools by generating Cursor project rules and Skill instructions.
144
+ - Guards important stages by checking FET verification state before `sync` and `archive`.
145
+
146
+ ### How It Works
147
+
148
+ FET is a transparent proxy and local orchestration layer for OpenSpec. When you run commands such as `fet apply` or `fet archive`, FET loads project and change state, runs pre-hooks, calls the real `openspec` CLI, and then updates FET state based on the result.
149
+
150
+ For OpenSpec 1.2.x, some high-level FET commands are mapped to the actual OpenSpec command surface. For example, `fet apply` calls `openspec instructions apply --change <id>`, and `fet sync` calls `openspec validate <change> --type change --strict`.
151
+
152
+ ### Requirements
26
153
 
27
154
  - Node.js 18 or newer
28
155
  - OpenSpec CLI available on `PATH`
29
156
 
30
- Install OpenSpec if needed:
157
+ Install OpenSpec:
31
158
 
32
159
  ```sh
33
160
  npm install -g @fission-ai/openspec
34
161
  ```
35
162
 
36
- ## Installation
163
+ ### Installation
37
164
 
38
165
  ```sh
39
166
  npm install -g @nick848/fet
40
167
  ```
41
168
 
42
- For local development:
169
+ Check the installation:
43
170
 
44
171
  ```sh
45
- npm install
46
- npm run build
47
- node dist/cli/index.js --help
172
+ fet --version
173
+ fet --help
48
174
  ```
49
175
 
50
- ## Quick Start
176
+ ### Quick Start
51
177
 
52
- In a project that should use OpenSpec:
178
+ Run this in a project root:
53
179
 
54
180
  ```sh
55
181
  fet init
56
182
  fet doctor
57
183
  ```
58
184
 
59
- Then follow your OpenSpec workflow:
185
+ Typical workflow:
60
186
 
61
187
  ```sh
62
- fet propose
63
- fet apply
64
- fet verify
65
- fet verify --done
66
- fet sync
67
- fet archive
188
+ fet new my-change
189
+ fet apply --change my-change
190
+ fet verify --change my-change
191
+ fet verify --done --change my-change
192
+ fet sync --change my-change
193
+ fet archive --change my-change
68
194
  ```
69
195
 
70
- ## Generated Files
196
+ ### Global Options
197
+
198
+ | Option | Description | Example |
199
+ |--------|-------------|---------|
200
+ | `--cwd <path>` | Set project root. Defaults to current directory. | `fet doctor --cwd ./app` |
201
+ | `--change <id>` | Select an OpenSpec change. | `fet apply --change add-login` |
202
+ | `--yes` | Accept low-risk confirmations. | `fet init --yes` |
203
+ | `--json` | Print machine-readable JSON. | `fet doctor --json` |
204
+ | `--verbose` | Print more diagnostics. | `fet doctor --verbose` |
205
+ | `--no-color` | Disable terminal colors. | `fet --no-color doctor` |
206
+
207
+ ### Commands
208
+
209
+ | Command | Usage | Description |
210
+ |---------|-------|-------------|
211
+ | `fet init` | `fet init [--yes]` | Initialize FET and OpenSpec; generate context, state, Cursor rules, and Skills. |
212
+ | `fet update-context` | `fet update-context [--yes]` | Rescan the project and update FET-managed regions in `AGENTS.md` and `openspec/config.yaml`. |
213
+ | `fet doctor` | `fet doctor [--fix-lock]` | Diagnose OpenSpec, FET state, context files, Cursor integration, and lock files. |
214
+ | `fet explore` | `fet explore --change <id>` | Print OpenSpec exploration/proposal instructions for discussing requirements. |
215
+ | `fet propose` | `fet propose <change-id>` | Create a new OpenSpec change through FET's proposal entry point. |
216
+ | `fet new` | `fet new <change-id>` | Create a new OpenSpec change. |
217
+ | `fet continue` | `fet continue [artifact] --change <id>` | Print OpenSpec instructions for an artifact. Defaults to `proposal`. |
218
+ | `fet ff` | `fet ff --change <id>` | Show OpenSpec artifact status for a change. |
219
+ | `fet apply` | `fet apply --change <id>` | Print OpenSpec apply instructions and update FET state. |
220
+ | `fet verify` | `fet verify --change <id>` | Generate `.fet/verify-instructions.md` for manual verification. |
221
+ | `fet verify --done` | `fet verify --done --change <id>` | Declare manual verification complete and allow `sync` / `archive`. |
222
+ | `fet verify --auto` | `fet verify --auto [--yes]` | Generate an automatic verification plan. This version does not run project scripts; `--yes` records the plan fingerprint. |
223
+ | `fet sync` | `fet sync --change <id>` | After FET verify gate passes, run strict OpenSpec validation for the change. |
224
+ | `fet archive` | `fet archive --change <id>` | After FET verify gate passes, archive the change and update main OpenSpec specs. |
225
+ | `fet bulk-archive` | `fet bulk-archive` | Not supported by OpenSpec 1.2.x as a top-level command. Archive changes one by one. |
226
+ | `fet onboard` | `fet onboard` | Print OpenSpec onboarding / instruction information. |
227
+ | `fet passthrough` | `fet passthrough <command> [...args]` | Pass through unmanaged OpenSpec commands without updating FET lifecycle state. |
228
+
229
+ ### Generated Files
71
230
 
72
231
  FET may create or update:
73
232
 
74
233
  - `AGENTS.md`
75
- - `openspec/config.yaml` under the `fet:` namespace
234
+ - the `fet:` namespace in `openspec/config.yaml`
76
235
  - `openspec/fet-state.json`
77
236
  - `openspec/changes/<change-id>/fet-state.json`
78
237
  - `openspec/changes/<change-id>/.fet/verify-instructions.md`
79
238
  - `.cursor/skills/fet-*/SKILL.md`
80
239
  - `.cursor/rules/fet-context.mdc`
81
240
 
82
- FET only owns marked managed regions. User content outside managed regions should be preserved.
83
-
84
- During `fet init`, FET also adds a managed block to `.gitignore` for local workflow state such as `openspec/fet-state.json`, lock files, and generated verify instructions.
241
+ FET only owns explicitly marked managed regions. User content outside those regions should be preserved. During `fet init`, FET also adds a managed `.gitignore` block for local workflow state.
85
242
 
86
- ## Safety Model
243
+ ### Safety Model
87
244
 
88
- FET is a local workflow helper. It is not a sandbox, CI gate, or cryptographic audit system. Direct `openspec` calls can bypass FET workflow gates. Teams that require enforcement should repeat validation in CI and branch protection rules.
245
+ FET is a local workflow helper. It is not a sandbox, mandatory CI gate, or cryptographic audit system. Direct `openspec` calls can bypass FET local gates. Teams that require enforcement should repeat validation in CI, branch protection, or review policy.
89
246
 
90
- ## Development
247
+ ### Development
91
248
 
92
249
  ```sh
250
+ npm install
93
251
  npm run typecheck
94
252
  npm run test
95
253
  npm run build
96
254
  npm run release:check
97
255
  ```
98
256
 
99
- ## License
257
+ Run the real OpenSpec smoke test:
258
+
259
+ ```powershell
260
+ $env:FET_REAL_OPENSPEC='1'; npm run test:real-openspec
261
+ ```
262
+
263
+ ### License
100
264
 
101
265
  MIT
package/dist/cli/index.js CHANGED
@@ -9,7 +9,7 @@ import { Command } from "commander";
9
9
 
10
10
  // src/commands/init.ts
11
11
  import { readFile as readFile5, stat as stat2 } from "fs/promises";
12
- import { join as join5 } from "path";
12
+ import { join as join6 } from "path";
13
13
 
14
14
  // src/fs/atomic-write.ts
15
15
  import { dirname } from "path";
@@ -116,7 +116,28 @@ async function writeInitJournal(projectRoot, journal) {
116
116
  }
117
117
 
118
118
  // src/version.ts
119
- var FET_VERSION = "0.3.0-dev";
119
+ import { existsSync, readFileSync } from "fs";
120
+ import { dirname as dirname4, join as join4, parse } from "path";
121
+ import { fileURLToPath } from "url";
122
+ var FET_VERSION = readPackageVersion();
123
+ function readPackageVersion() {
124
+ let currentDir = dirname4(fileURLToPath(import.meta.url));
125
+ const root = parse(currentDir).root;
126
+ while (true) {
127
+ const packageJsonPath = join4(currentDir, "package.json");
128
+ if (existsSync(packageJsonPath)) {
129
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
130
+ if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
131
+ return packageJson.version;
132
+ }
133
+ throw new Error(`package.json \u7F3A\u5C11\u6709\u6548\u7684 version \u5B57\u6BB5: ${packageJsonPath}`);
134
+ }
135
+ if (currentDir === root) {
136
+ throw new Error("\u65E0\u6CD5\u5B9A\u4F4D FET package.json");
137
+ }
138
+ currentDir = dirname4(currentDir);
139
+ }
140
+ }
120
141
 
121
142
  // src/templates/markers.ts
122
143
  var AUTO_BEGIN = "<!-- FET:BEGIN AUTO -->";
@@ -305,7 +326,7 @@ ${block}
305
326
 
306
327
  // src/commands/update-context.ts
307
328
  import { readFile as readFile4 } from "fs/promises";
308
- import { join as join4 } from "path";
329
+ import { join as join5 } from "path";
309
330
 
310
331
  // src/config/yaml.ts
311
332
  import { readFile as readFile3 } from "fs/promises";
@@ -339,8 +360,8 @@ async function updateContextCommand(ctx) {
339
360
  }
340
361
  async function updateContextFiles(ctx) {
341
362
  const scan = await ctx.scanner.scan(ctx.projectRoot, {});
342
- const agentsPath = join4(ctx.projectRoot, "AGENTS.md");
343
- const configPath = join4(ctx.projectRoot, "openspec", "config.yaml");
363
+ const agentsPath = join5(ctx.projectRoot, "AGENTS.md");
364
+ const configPath = join5(ctx.projectRoot, "openspec", "config.yaml");
344
365
  const existingAgents = await readOptional(agentsPath);
345
366
  const warnings = [...scan.warnings];
346
367
  if (existingAgents && hasInvalidManagedAutoRegion(existingAgents)) {
@@ -357,7 +378,7 @@ async function updateContextFiles(ctx) {
357
378
  code: "TOOL_ADAPTER_CONFLICT" /* ToolAdapterConflict */,
358
379
  message: "AGENTS.md \u5DF2\u5B58\u5728\u4E14\u4E0D\u5305\u542B FET \u6258\u7BA1\u533A\u57DF",
359
380
  details: { path: "AGENTS.md" },
360
- suggestedCommand: "\u786E\u8BA4\u53EF\u5907\u4EFD\u5E76\u66FF\u6362\u540E\u8FD0\u884C fet update-context --yes"
381
+ suggestedCommand: ctx.command === "init" ? "\u786E\u8BA4\u53EF\u5907\u4EFD\u5E76\u66FF\u6362\u540E\u8FD0\u884C fet init --yes" : "\u786E\u8BA4\u53EF\u5907\u4EFD\u5E76\u66FF\u6362\u540E\u8FD0\u884C fet update-context --yes"
361
382
  });
362
383
  }
363
384
  const backupPath = await createBackup(agentsPath);
@@ -386,7 +407,7 @@ async function readOptional(path) {
386
407
 
387
408
  // src/commands/init.ts
388
409
  async function initCommand(ctx) {
389
- const alreadyInitialized = await exists(join5(ctx.projectRoot, "openspec", "config.yaml"));
410
+ const alreadyInitialized = await exists(join6(ctx.projectRoot, "openspec", "config.yaml"));
390
411
  await withProjectLock(
391
412
  ctx.projectRoot,
392
413
  { command: "init", cwd: ctx.cwd, fetVersion: ctx.fetVersion },
@@ -431,7 +452,7 @@ async function initCommand(ctx) {
431
452
  });
432
453
  }
433
454
  async function ensureGitignore(ctx) {
434
- const gitignorePath = join5(ctx.projectRoot, ".gitignore");
455
+ const gitignorePath = join6(ctx.projectRoot, ".gitignore");
435
456
  const existing = await readOptional2(gitignorePath);
436
457
  await atomicWrite(gitignorePath, mergeGitignore(existing));
437
458
  }
@@ -453,17 +474,17 @@ async function exists(path) {
453
474
 
454
475
  // src/commands/doctor.ts
455
476
  import { stat as stat3 } from "fs/promises";
456
- import { join as join6 } from "path";
477
+ import { join as join7 } from "path";
457
478
  async function doctorCommand(ctx, options = {}) {
458
479
  const checks = [];
459
480
  checks.push(await checkOpenSpec(ctx));
460
481
  checks.push(await checkState(ctx));
461
- checks.push(await checkFile("agents", join6(ctx.projectRoot, "AGENTS.md"), "AGENTS.md \u7F3A\u5931", "fet update-context"));
462
- checks.push(await checkFile("config", join6(ctx.projectRoot, "openspec", "config.yaml"), "openspec/config.yaml \u7F3A\u5931", "fet init"));
482
+ checks.push(await checkFile("agents", join7(ctx.projectRoot, "AGENTS.md"), "AGENTS.md \u7F3A\u5931", "fet update-context"));
483
+ checks.push(await checkFile("config", join7(ctx.projectRoot, "openspec", "config.yaml"), "openspec/config.yaml \u7F3A\u5931", "fet init"));
463
484
  for (const adapter of ctx.toolAdapters) {
464
485
  checks.push(...await adapter.doctor(ctx.projectRoot));
465
486
  }
466
- const lockPath = join6(ctx.projectRoot, "openspec", ".fet.lock");
487
+ const lockPath = join7(ctx.projectRoot, "openspec", ".fet.lock");
467
488
  if (await exists2(lockPath)) {
468
489
  if (options.fixLock) {
469
490
  await clearLock(ctx.projectRoot);
@@ -537,7 +558,7 @@ async function git(cwd, args) {
537
558
 
538
559
  // src/state/store.ts
539
560
  import { mkdir as mkdir3, readFile as readFile6 } from "fs/promises";
540
- import { join as join7 } from "path";
561
+ import { join as join8 } from "path";
541
562
 
542
563
  // src/state/schema.ts
543
564
  var phases = ["explore", "propose", "implement", "verify", "sync", "archive"];
@@ -645,7 +666,7 @@ var StateStore = class {
645
666
  }
646
667
  async writeGlobal(state) {
647
668
  state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
648
- await mkdir3(join7(this.projectRoot, "openspec"), { recursive: true });
669
+ await mkdir3(join8(this.projectRoot, "openspec"), { recursive: true });
649
670
  await atomicWrite(this.globalPath(), `${JSON.stringify(state, null, 2)}
650
671
  `);
651
672
  }
@@ -666,15 +687,15 @@ var StateStore = class {
666
687
  }
667
688
  async writeChange(state) {
668
689
  state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
669
- await mkdir3(join7(this.projectRoot, "openspec", "changes", state.changeId), { recursive: true });
690
+ await mkdir3(join8(this.projectRoot, "openspec", "changes", state.changeId), { recursive: true });
670
691
  await atomicWrite(this.changePath(state.changeId), `${JSON.stringify(state, null, 2)}
671
692
  `);
672
693
  }
673
694
  globalPath() {
674
- return join7(this.projectRoot, "openspec", "fet-state.json");
695
+ return join8(this.projectRoot, "openspec", "fet-state.json");
675
696
  }
676
697
  changePath(changeId) {
677
- return join7(this.projectRoot, "openspec", "changes", changeId, "fet-state.json");
698
+ return join8(this.projectRoot, "openspec", "changes", changeId, "fet-state.json");
678
699
  }
679
700
  };
680
701
  function isNotFound(error) {
@@ -886,7 +907,7 @@ async function assertVerified(ctx) {
886
907
  // src/commands/verify.ts
887
908
  import { createHash } from "crypto";
888
909
  import { mkdir as mkdir4, readFile as readFile8, stat as stat4 } from "fs/promises";
889
- import { join as join8 } from "path";
910
+ import { join as join9 } from "path";
890
911
  async function verifyCommand(ctx, options) {
891
912
  if (options.auto) {
892
913
  const scan = await ctx.scanner.scan(ctx.projectRoot, {});
@@ -953,8 +974,8 @@ async function verifyCommand(ctx, options) {
953
974
  async function writeInstructions(ctx, changeId) {
954
975
  await assertChangeExists(ctx, changeId);
955
976
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
956
- const dir = join8(ctx.projectRoot, "openspec", "changes", changeId, ".fet");
957
- const instructionsPath = join8(dir, "verify-instructions.md");
977
+ const dir = join9(ctx.projectRoot, "openspec", "changes", changeId, ".fet");
978
+ const instructionsPath = join9(dir, "verify-instructions.md");
958
979
  await mkdir4(dir, { recursive: true });
959
980
  await atomicWrite(instructionsPath, renderVerifyInstructions(changeId, generatedAt));
960
981
  const state = await ctx.stateStore.getOrCreateChange(changeId, "verify");
@@ -971,7 +992,7 @@ async function writeInstructions(ctx, changeId) {
971
992
  async function markDone(ctx, changeId) {
972
993
  await assertChangeExists(ctx, changeId);
973
994
  const declaredAt = (/* @__PURE__ */ new Date()).toISOString();
974
- const instructionsPath = join8(ctx.projectRoot, "openspec", "changes", changeId, ".fet", "verify-instructions.md");
995
+ const instructionsPath = join9(ctx.projectRoot, "openspec", "changes", changeId, ".fet", "verify-instructions.md");
975
996
  const instructions = await readInstructions(instructionsPath, changeId);
976
997
  const instructionsGeneratedAt = readFrontMatterValue(instructions, "generatedAt") ?? declaredAt;
977
998
  const state = await ctx.stateStore.getOrCreateChange(changeId, "verify");
@@ -1062,7 +1083,7 @@ import { resolve } from "path";
1062
1083
 
1063
1084
  // src/adapters/cursor/index.ts
1064
1085
  import { mkdir as mkdir5, readFile as readFile9, stat as stat5 } from "fs/promises";
1065
- import { dirname as dirname4, join as join9 } from "path";
1086
+ import { dirname as dirname5, join as join10 } from "path";
1066
1087
 
1067
1088
  // src/adapters/cursor/templates.ts
1068
1089
  var commands = [
@@ -1142,7 +1163,7 @@ var CursorAdapter = class {
1142
1163
  adapterVersion = 1;
1143
1164
  async detect(projectRoot) {
1144
1165
  return {
1145
- detected: await exists3(join9(projectRoot, ".cursor")),
1166
+ detected: await exists3(join10(projectRoot, ".cursor")),
1146
1167
  reason: "Cursor adapter is available for any project"
1147
1168
  };
1148
1169
  }
@@ -1159,7 +1180,7 @@ var CursorAdapter = class {
1159
1180
  const written = [];
1160
1181
  const skipped = [];
1161
1182
  for (const file of plan.files) {
1162
- const target = join9(projectRoot, file.path);
1183
+ const target = join10(projectRoot, file.path);
1163
1184
  const existing = await readExisting(target);
1164
1185
  if (existing && !existing.includes("FET:MANAGED") && !force) {
1165
1186
  throw new FetError({
@@ -1172,7 +1193,7 @@ var CursorAdapter = class {
1172
1193
  if (existing && !existing.includes("FET:MANAGED") && force) {
1173
1194
  await createBackup(target);
1174
1195
  }
1175
- await mkdir5(dirname4(target), { recursive: true });
1196
+ await mkdir5(dirname5(target), { recursive: true });
1176
1197
  await atomicWrite(target, file.content);
1177
1198
  written.push(file.path);
1178
1199
  }
@@ -1182,7 +1203,7 @@ var CursorAdapter = class {
1182
1203
  const plan = await this.planInstall(projectRoot);
1183
1204
  const checks = [];
1184
1205
  for (const file of plan.files) {
1185
- const target = join9(projectRoot, file.path);
1206
+ const target = join10(projectRoot, file.path);
1186
1207
  const content = await readExisting(target);
1187
1208
  const managed = Boolean(content?.includes("FET:MANAGED"));
1188
1209
  const versionMatches = Boolean(content?.includes(`adapterVersion: ${this.adapterVersion}`));
@@ -1218,11 +1239,11 @@ import { promisify as promisify3 } from "util";
1218
1239
 
1219
1240
  // src/openspec/inspector.ts
1220
1241
  import { readdir, stat as stat6 } from "fs/promises";
1221
- import { join as join10 } from "path";
1242
+ import { join as join11 } from "path";
1222
1243
  async function inspectOpenSpecProject(projectRoot) {
1223
- const openspecPath = join10(projectRoot, "openspec");
1224
- const changesPath = join10(openspecPath, "changes");
1225
- const archivePath = join10(openspecPath, "archive");
1244
+ const openspecPath = join11(projectRoot, "openspec");
1245
+ const changesPath = join11(openspecPath, "changes");
1246
+ const archivePath = join11(openspecPath, "archive");
1226
1247
  return {
1227
1248
  exists: await exists4(openspecPath),
1228
1249
  changes: await listDirectories(changesPath),
@@ -1230,13 +1251,13 @@ async function inspectOpenSpecProject(projectRoot) {
1230
1251
  };
1231
1252
  }
1232
1253
  async function inspectOpenSpecChange(projectRoot, changeId) {
1233
- const changePath = join10(projectRoot, "openspec", "changes", changeId);
1234
- const tasksPath = join10(changePath, "tasks.md");
1235
- const specsPath = join10(changePath, "specs");
1254
+ const changePath = join11(projectRoot, "openspec", "changes", changeId);
1255
+ const tasksPath = join11(changePath, "tasks.md");
1256
+ const specsPath = join11(changePath, "specs");
1236
1257
  return {
1237
1258
  changeId,
1238
1259
  exists: await exists4(changePath),
1239
- hasProposal: await exists4(join10(changePath, "proposal.md")),
1260
+ hasProposal: await exists4(join11(changePath, "proposal.md")),
1240
1261
  hasTasks: await exists4(tasksPath),
1241
1262
  hasSpecs: await exists4(specsPath),
1242
1263
  tasksPath,
@@ -1413,11 +1434,11 @@ function parseCommands(help) {
1413
1434
 
1414
1435
  // src/scanner/package.ts
1415
1436
  import { readFile as readFile10, stat as stat7 } from "fs/promises";
1416
- import { join as join11 } from "path";
1417
- import { parse } from "yaml";
1437
+ import { join as join12 } from "path";
1438
+ import { parse as parse2 } from "yaml";
1418
1439
  async function readPackageJson(projectRoot) {
1419
1440
  try {
1420
- return JSON.parse(await readFile10(join11(projectRoot, "package.json"), "utf8"));
1441
+ return JSON.parse(await readFile10(join12(projectRoot, "package.json"), "utf8"));
1421
1442
  } catch {
1422
1443
  return null;
1423
1444
  }
@@ -1483,7 +1504,7 @@ function detectFramework(pkg) {
1483
1504
  }
1484
1505
  async function detectLanguage(projectRoot, pkg) {
1485
1506
  const deps = { ...pkg?.dependencies ?? {}, ...pkg?.devDependencies ?? {} };
1486
- if (deps.typescript || await exists5(join11(projectRoot, "tsconfig.json"))) {
1507
+ if (deps.typescript || await exists5(join12(projectRoot, "tsconfig.json"))) {
1487
1508
  return "typescript";
1488
1509
  }
1489
1510
  return "javascript";
@@ -1498,7 +1519,7 @@ async function detectWorkspaces(projectRoot, pkg) {
1498
1519
  return packageWorkspaces;
1499
1520
  }
1500
1521
  try {
1501
- const workspace = parse(await readFile10(join11(projectRoot, "pnpm-workspace.yaml"), "utf8"));
1522
+ const workspace = parse2(await readFile10(join12(projectRoot, "pnpm-workspace.yaml"), "utf8"));
1502
1523
  return (workspace?.packages ?? []).map((path) => ({
1503
1524
  name: path,
1504
1525
  path,
@@ -1518,7 +1539,7 @@ async function detectLockManagers(projectRoot) {
1518
1539
  ];
1519
1540
  const found = [];
1520
1541
  for (const [file, manager] of lockFiles) {
1521
- if (await exists5(join11(projectRoot, file))) {
1542
+ if (await exists5(join12(projectRoot, file))) {
1522
1543
  found.push(manager);
1523
1544
  }
1524
1545
  }
@@ -1544,12 +1565,12 @@ async function exists5(path) {
1544
1565
 
1545
1566
  // src/scanner/routes.ts
1546
1567
  import { readdir as readdir2, stat as stat8 } from "fs/promises";
1547
- import { join as join12, relative, sep } from "path";
1568
+ import { join as join13, relative, sep } from "path";
1548
1569
  async function scanRoutes(projectRoot) {
1549
1570
  const candidates = ["src/routes", "src/pages", "app", "pages"];
1550
1571
  const routes = [];
1551
1572
  for (const candidate of candidates) {
1552
- const root = join12(projectRoot, candidate);
1573
+ const root = join13(projectRoot, candidate);
1553
1574
  if (!await exists6(root)) {
1554
1575
  continue;
1555
1576
  }
@@ -1577,7 +1598,7 @@ async function listFiles(root) {
1577
1598
  const entries = await readdir2(root, { withFileTypes: true });
1578
1599
  const files = [];
1579
1600
  for (const entry of entries) {
1580
- const path = join12(root, entry.name);
1601
+ const path = join13(root, entry.name);
1581
1602
  if (entry.isDirectory()) {
1582
1603
  files.push(...await listFiles(path));
1583
1604
  } else {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/commands/init.ts","../../src/fs/atomic-write.ts","../../src/fs/backup.ts","../../src/fs/lock.ts","../../src/fs/journal.ts","../../src/version.ts","../../src/templates/markers.ts","../../src/templates/agents-md.ts","../../src/templates/config-yaml.ts","../../src/templates/verify-instructions.ts","../../src/templates/gitignore.ts","../../src/commands/update-context.ts","../../src/config/yaml.ts","../../src/commands/doctor.ts","../../src/state/project.ts","../../src/state/store.ts","../../src/state/schema.ts","../../src/state/tasks.ts","../../src/commands/proxy.ts","../../src/commands/verify.ts","../../src/cli/context.ts","../../src/adapters/cursor/index.ts","../../src/adapters/cursor/templates.ts","../../src/openspec/adapter.ts","../../src/openspec/inspector.ts","../../src/openspec/resolver.ts","../../src/openspec/runner.ts","../../src/scanner/package.ts","../../src/scanner/routes.ts","../../src/scanner/index.ts","../../src/cli/output.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"../commands/init.js\";\nimport { doctorCommand } from \"../commands/doctor.js\";\nimport { proxyCommand, passthroughCommand } from \"../commands/proxy.js\";\nimport { updateContextCommand } from \"../commands/update-context.js\";\nimport { verifyCommand } from \"../commands/verify.js\";\nimport { toFetError } from \"../errors/fet-error.js\";\nimport { FET_VERSION } from \"../version.js\";\nimport { createCommandContext, type GlobalOptions } from \"./context.js\";\nimport { OutputWriter } from \"./output.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"fet\")\n .description(\"Frontend workflow orchestration tool built around OpenSpec.\")\n .enablePositionalOptions()\n .version(FET_VERSION)\n .option(\"--cwd <path>\", \"指定项目根目录\")\n .option(\"--change <id>\", \"指定 OpenSpec change\")\n .option(\"--yes\", \"对低风险确认使用默认同意\")\n .option(\"--json\", \"输出机器可读 JSON\")\n .option(\"--verbose\", \"输出诊断细节\")\n .option(\"--no-color\", \"禁用终端颜色\");\n\naddGlobalOptions(program.command(\"init\")).description(\"初始化 FET + OpenSpec\").action(wrap(\"init\", initCommand));\naddGlobalOptions(program.command(\"update-context\")).description(\"更新项目上下文\").action(wrap(\"update-context\", updateContextCommand));\naddGlobalOptions(program\n .command(\"doctor\")\n .description(\"诊断状态、配置与一致性\")\n .option(\"--fix-lock\", \"清理 FET 锁文件\"))\n .action(\n wrap(\"doctor\", (ctx, options: { fixLock?: boolean }) => doctorCommand(ctx, { fixLock: Boolean(options.fixLock) }))\n );\n\naddGlobalOptions(program\n .command(\"verify\")\n .description(\"最终质量验证\")\n .option(\"--done\", \"声明手动验证已完成\")\n .option(\"--auto\", \"生成或执行自动验证计划\"))\n .action(wrap(\"verify\", verifyCommand));\n\nfor (const command of [\"explore\", \"propose\", \"new\", \"continue\", \"ff\", \"apply\", \"sync\", \"archive\", \"bulk-archive\", \"onboard\"]) {\n addGlobalOptions(program\n .command(`${command} [args...]`)\n .description(`代理执行 openspec ${command}`)\n .allowUnknownOption(true)\n .passThroughOptions())\n .action(wrap(command, (ctx, args: string[] = []) => proxyCommand(ctx, command, args)));\n}\n\naddGlobalOptions(program\n .command(\"passthrough <command> [args...]\")\n .description(\"透传暂未接管的 OpenSpec 命令\")\n .allowUnknownOption(true)\n .passThroughOptions())\n .action(wrap(\"passthrough\", (ctx, command: string, args: string[] = []) => passthroughCommand(ctx, command, args)));\n\nprogram.parseAsync(process.argv).catch((error) => {\n const json = process.argv.includes(\"--json\");\n const output = new OutputWriter(json);\n const fetError = toFetError(error);\n output.error(fetError);\n process.exitCode = fetError.exitCode;\n});\n\nfunction wrap<T extends unknown[]>(\n command: string,\n handler: (ctx: Awaited<ReturnType<typeof createCommandContext>>, ...args: T) => Promise<void>\n) {\n return async (...args: T) => {\n const maybeCommand = args[args.length - 1] as unknown;\n const opts = isCommandLike(maybeCommand)\n ? ({ ...(maybeCommand.parent?.opts() as GlobalOptions), ...(maybeCommand.opts() as GlobalOptions) } as GlobalOptions)\n : (program.opts() as GlobalOptions);\n const ctx = await createCommandContext(command, { ...opts, ...extractGlobalOptions(args) });\n try {\n await handler(ctx, ...args);\n } catch (error) {\n const fetError = toFetError(error);\n ctx.output.error(fetError);\n process.exitCode = fetError.exitCode;\n }\n };\n}\n\nfunction isCommandLike(value: unknown): value is Command {\n return value instanceof Command;\n}\n\nfunction addGlobalOptions(command: Command): Command {\n return command\n .option(\"--cwd <path>\", \"指定项目根目录\")\n .option(\"--change <id>\", \"指定 OpenSpec change\")\n .option(\"--yes\", \"对低风险确认使用默认同意\")\n .option(\"--json\", \"输出机器可读 JSON\")\n .option(\"--verbose\", \"输出诊断细节\")\n .option(\"--no-color\", \"禁用终端颜色\");\n}\n\nfunction extractGlobalOptions(args: unknown[]): GlobalOptions {\n const values = args.flatMap((arg) => (Array.isArray(arg) ? arg : []));\n const options: GlobalOptions = {};\n for (let index = 0; index < values.length; index += 1) {\n const value = values[index];\n if (typeof value !== \"string\") {\n continue;\n }\n if (value === \"--cwd\" && typeof values[index + 1] === \"string\") {\n options.cwd = values[index + 1];\n index += 1;\n } else if (value.startsWith(\"--cwd=\")) {\n options.cwd = value.slice(\"--cwd=\".length);\n } else if (value === \"--change\" && typeof values[index + 1] === \"string\") {\n options.change = values[index + 1];\n index += 1;\n } else if (value.startsWith(\"--change=\")) {\n options.change = value.slice(\"--change=\".length);\n } else if (value === \"--yes\") {\n options.yes = true;\n } else if (value === \"--json\") {\n options.json = true;\n } else if (value === \"--verbose\") {\n options.verbose = true;\n }\n }\n return options;\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { FetCommandContext } from \"../cli/context.js\";\nimport { atomicWrite, createInitJournal, withProjectLock, writeInitJournal } from \"../fs/index.js\";\nimport { mergeGitignore } from \"../templates/index.js\";\nimport { updateContextFiles } from \"./update-context.js\";\n\nexport async function initCommand(ctx: FetCommandContext): Promise<void> {\n const alreadyInitialized = await exists(join(ctx.projectRoot, \"openspec\", \"config.yaml\"));\n await withProjectLock(\n ctx.projectRoot,\n { command: \"init\", cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => {\n const journal = createInitJournal(ctx.fetVersion);\n await writeInitJournal(ctx.projectRoot, journal);\n\n const identity = await ctx.openSpec.resolveExecutable();\n if (!alreadyInitialized) {\n const result = await ctx.openSpec.run(\"init\", [\"--tools\", \"none\"], { cwd: ctx.projectRoot, stdio: \"inherit\" });\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n return;\n }\n }\n\n const contextResult = await updateContextFiles(ctx);\n await ensureGitignore(ctx);\n\n const state = await ctx.stateStore.getOrCreateGlobal();\n state.openspec = identity;\n\n for (const adapter of ctx.toolAdapters) {\n const plan = await adapter.planInstall(ctx.projectRoot);\n const result = await adapter.install(ctx.projectRoot, plan, ctx.yes);\n state.toolAdapters[adapter.tool] = {\n adapterVersion: adapter.adapterVersion,\n installed: true,\n updatedAt: new Date().toISOString()\n };\n journal.steps.push(...result.written.map((path) => ({ operation: \"write\" as const, path, status: \"done\" as const })));\n }\n\n journal.completedAt = new Date().toISOString();\n await writeInitJournal(ctx.projectRoot, journal);\n await ctx.stateStore.writeGlobal(state);\n for (const warning of contextResult.warnings) {\n ctx.output.warn(warning);\n }\n }\n );\n\n ctx.output.result({\n ok: true,\n command: \"init\",\n summary: \"FET 初始化完成。\",\n nextSteps: [\"使用 fet propose/new 创建 OpenSpec change\", \"使用 fet doctor 检查项目状态\"]\n });\n}\n\nasync function ensureGitignore(ctx: FetCommandContext): Promise<void> {\n const gitignorePath = join(ctx.projectRoot, \".gitignore\");\n const existing = await readOptional(gitignorePath);\n await atomicWrite(gitignorePath, mergeGitignore(existing));\n}\n\nasync function readOptional(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { dirname } from \"node:path\";\nimport { open, rename, mkdir } from \"node:fs/promises\";\n\nexport interface AtomicWriteResult {\n path: string;\n tempPath: string;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array\n): Promise<AtomicWriteResult> {\n await mkdir(dirname(targetPath), { recursive: true });\n const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;\n const handle = await open(tempPath, \"wx\");\n\n try {\n await handle.writeFile(content);\n await handle.sync();\n } finally {\n await handle.close();\n }\n\n await rename(tempPath, targetPath);\n return { path: targetPath, tempPath };\n}\n","import { copyFile, stat } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\n\nexport async function createBackup(filePath: string): Promise<string | null> {\n try {\n await stat(filePath);\n } catch {\n return null;\n }\n\n const timestamp = new Date()\n .toISOString()\n .replace(/[-:]/g, \"\")\n .replace(/\\..+$/, \"\")\n .replace(\"T\", \"-\");\n const backupPath = join(dirname(filePath), `${basename(filePath)}.fet-backup-${timestamp}`);\n await copyFile(filePath, backupPath);\n return backupPath;\n}\n","import { hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { mkdir, open, readFile, rm } from \"node:fs/promises\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\n\nexport interface LockMetadata {\n command: string;\n cwd: string;\n fetVersion: string;\n}\n\ninterface LockFile {\n pid: number;\n hostname: string;\n cwd: string;\n command: string;\n startedAt: string;\n fetVersion: string;\n}\n\nexport async function withProjectLock<T>(\n projectRoot: string,\n metadata: LockMetadata,\n fn: () => Promise<T>\n): Promise<T> {\n const lockPath = join(projectRoot, \"openspec\", \".fet.lock\");\n const lock: LockFile = {\n pid: process.pid,\n hostname: hostname(),\n cwd: metadata.cwd,\n command: metadata.command,\n startedAt: new Date().toISOString(),\n fetVersion: metadata.fetVersion\n };\n\n let handle;\n try {\n await mkdir(dirname(lockPath), { recursive: true });\n handle = await open(lockPath, \"wx\");\n await handle.writeFile(JSON.stringify(lock, null, 2));\n } catch {\n throw new FetError({\n code: ErrorCode.LockHeld,\n message: \"另一个 FET 写命令正在运行\",\n details: await readExistingLock(lockPath),\n suggestedCommand: \"fet doctor --fix-lock\"\n });\n } finally {\n await handle?.close();\n }\n\n try {\n return await fn();\n } finally {\n await rm(lockPath, { force: true });\n }\n}\n\nasync function readExistingLock(lockPath: string): Promise<unknown> {\n try {\n return JSON.parse(await readFile(lockPath, \"utf8\"));\n } catch {\n return { path: lockPath };\n }\n}\n\nexport async function clearLock(projectRoot: string): Promise<boolean> {\n const lockPath = join(projectRoot, \"openspec\", \".fet.lock\");\n try {\n await rm(lockPath);\n return true;\n } catch {\n return false;\n }\n}\n","import { join } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { atomicWrite } from \"./atomic-write.js\";\n\nexport interface JournalStep {\n operation: \"write\" | \"backup\" | \"mkdir\" | \"skip\";\n path: string;\n backupPath?: string | null;\n status: \"done\" | \"failed\" | \"skipped\";\n message?: string;\n}\n\nexport interface InitJournal {\n schemaVersion: 1;\n startedAt: string;\n completedAt: string | null;\n fetVersion: string;\n steps: JournalStep[];\n}\n\nexport function createInitJournal(fetVersion: string): InitJournal {\n return {\n schemaVersion: 1,\n startedAt: new Date().toISOString(),\n completedAt: null,\n fetVersion,\n steps: []\n };\n}\n\nexport async function writeInitJournal(projectRoot: string, journal: InitJournal): Promise<void> {\n await atomicWrite(\n join(projectRoot, \"openspec\", \".fet-init-journal.json\"),\n `${JSON.stringify(journal, null, 2)}\\n`\n );\n}\n\nexport async function readInitJournal(projectRoot: string): Promise<InitJournal | null> {\n try {\n return JSON.parse(await readFile(join(projectRoot, \"openspec\", \".fet-init-journal.json\"), \"utf8\"));\n } catch {\n return null;\n }\n}\n","export const FET_VERSION = \"0.3.0-dev\";\n","export const AUTO_BEGIN = \"<!-- FET:BEGIN AUTO -->\";\nexport const AUTO_END = \"<!-- FET:END AUTO -->\";\nexport const USER_BEGIN = \"<!-- FET:BEGIN USER -->\";\nexport const USER_END = \"<!-- FET:END USER -->\";\n\nexport function hasManagedAutoRegion(content: string): boolean {\n return count(content, AUTO_BEGIN) === 1 && count(content, AUTO_END) === 1 && content.indexOf(AUTO_BEGIN) < content.indexOf(AUTO_END);\n}\n\nexport function hasInvalidManagedAutoRegion(content: string): boolean {\n const beginCount = count(content, AUTO_BEGIN);\n const endCount = count(content, AUTO_END);\n return beginCount !== endCount || beginCount > 1 || endCount > 1 || (beginCount === 1 && content.indexOf(AUTO_BEGIN) > content.indexOf(AUTO_END));\n}\n\nexport function replaceManagedRegion(existing: string | null, generated: string): string {\n if (!existing) {\n return generated;\n }\n\n const start = existing.indexOf(AUTO_BEGIN);\n const end = existing.indexOf(AUTO_END);\n if (start === -1 || end === -1 || end < start) {\n return generated;\n }\n\n const before = existing.slice(0, start);\n const after = existing.slice(end + AUTO_END.length);\n const generatedAuto = extractAuto(generated);\n return `${before}${AUTO_BEGIN}\\n${generatedAuto}\\n${AUTO_END}${after}`;\n}\n\nfunction extractAuto(content: string): string {\n const start = content.indexOf(AUTO_BEGIN);\n const end = content.indexOf(AUTO_END);\n if (start === -1 || end === -1 || end < start) {\n return content.trim();\n }\n return content.slice(start + AUTO_BEGIN.length, end).trim();\n}\n\nfunction count(content: string, needle: string): number {\n return content.split(needle).length - 1;\n}\n","import type { ProjectScanResult } from \"../scanner/index.js\";\nimport { FET_VERSION } from \"../version.js\";\nimport { AUTO_BEGIN, AUTO_END, USER_BEGIN, USER_END } from \"./markers.js\";\n\nexport function renderAgentsMd(scan: ProjectScanResult): string {\n const commands = Object.entries(scan.commands)\n .map(([name, command]) => `| ${name} | \\`${command.command}\\` | ${command.source} |`)\n .join(\"\\n\");\n const routes = scan.routes\n .map((route) => `| ${route.path} | ${route.source} | ${route.confidence}${route.inferred ? \" inferred\" : \"\"} |`)\n .join(\"\\n\");\n const workspaces = scan.project.workspaces.map((workspace) => `| ${workspace.name} | ${workspace.path} | ${workspace.source} |`).join(\"\\n\");\n\n return `# Project Context\n\n${AUTO_BEGIN}\n## Project Snapshot\n\n- Name: ${scan.project.name}\n- Package Manager: ${scan.project.packageManager} (${scan.project.packageManagerConfidence})\n- Framework: ${scan.project.framework.name} (${scan.project.framework.confidence})\n- Language: ${scan.project.language}\n- Monorepo: ${scan.project.monorepo ? \"yes\" : \"no\"}\n\n## Workspaces\n\n| Name | Path | Source |\n|------|------|--------|\n${workspaces || \"| root | . | inferred |\"}\n\n## Commands\n\n| Name | Command | Source |\n|------|---------|--------|\n${commands || \"| [NEEDS LLM INPUT] | [NEEDS LLM INPUT] | [NEEDS LLM INPUT] |\"}\n\n## Structure\n\n[NEEDS LLM INPUT]\n\n## Routes\n\n| Route | Source | Confidence |\n|-------|--------|------------|\n${routes || \"| [NEEDS LLM INPUT] | [NEEDS LLM INPUT] | low |\"}\n\n## Conventions\n\n[NEEDS LLM INPUT]\n\n## Scanner Metadata\n\n- Generated At: ${scan.generatedAt}\n- FET Version: ${FET_VERSION}\n- Scanner Version: ${scan.scannerVersion}\n- Warnings: ${scan.warnings.length ? scan.warnings.join(\"; \") : \"none\"}\n${AUTO_END}\n\n${USER_BEGIN}\n## Notes For AI\n\n[NEEDS LLM INPUT]\n${USER_END}\n`;\n}\n","import { stringify } from \"yaml\";\nimport type { ProjectScanResult } from \"../scanner/index.js\";\nimport { FET_VERSION } from \"../version.js\";\n\nexport function renderFetConfig(scan: ProjectScanResult): string {\n return stringify({\n fet: {\n schemaVersion: 1,\n generatedAt: scan.generatedAt,\n fetVersion: FET_VERSION,\n scannerVersion: scan.scannerVersion,\n project: {\n packageManager: scan.project.packageManager,\n packageManagerConfidence: scan.project.packageManagerConfidence,\n framework: scan.project.framework,\n language: scan.project.language,\n monorepo: scan.project.monorepo,\n workspaces: scan.project.workspaces\n },\n commands: scan.commands,\n validation: {\n monorepo: scan.project.monorepo,\n missing: {\n lint: \"warn\",\n typecheck: \"warn\",\n test: \"warn\"\n },\n workspaces: scan.project.workspaces\n }\n }\n });\n}\n","import { FET_VERSION } from \"../version.js\";\n\nexport function renderVerifyInstructions(changeId: string, generatedAt = new Date().toISOString()): string {\n return `---\nschemaVersion: 1\nfetVersion: ${FET_VERSION}\ngeneratedAt: ${generatedAt}\nchangeId: ${changeId}\npurpose: manual-verify\n---\n\n# Verify Instructions\n\n请按顺序完成以下检查:\n\n1. 运行 OpenSpec 规范校验:\\`openspec verify\\`\n2. 按项目约定运行 lint、typecheck、test。\n3. 检查本次 change 的 \\`tasks.md\\` 是否与实现状态一致。\n\n完成后运行:\n\n\\`\\`\\`sh\nfet verify --done --change ${changeId}\n\\`\\`\\`\n`;\n}\n","const BEGIN = \"# FET:BEGIN LOCAL STATE\";\nconst END = \"# FET:END LOCAL STATE\";\n\nconst RULES = [\n \"openspec/fet-state.json\",\n \"openspec/.fet.lock\",\n \"openspec/.fet-init-journal.json\",\n \"openspec/changes/*/fet-state.json\",\n \"openspec/changes/*/.fet/\"\n];\n\nexport function mergeGitignore(existing: string | null): string {\n const block = `${BEGIN}\\n${RULES.join(\"\\n\")}\\n${END}`;\n if (!existing || !existing.trim()) {\n return `${block}\\n`;\n }\n\n const start = existing.indexOf(BEGIN);\n const end = existing.indexOf(END);\n if (start !== -1 && end !== -1 && end > start) {\n return `${existing.slice(0, start)}${block}${existing.slice(end + END.length)}`;\n }\n\n return `${existing.replace(/\\s*$/, \"\")}\\n\\n${block}\\n`;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { mergeFetConfig } from \"../config/index.js\";\nimport { atomicWrite, createBackup, withProjectLock } from \"../fs/index.js\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport { hasInvalidManagedAutoRegion, hasManagedAutoRegion, renderAgentsMd, renderFetConfig, replaceManagedRegion } from \"../templates/index.js\";\nimport type { FetCommandContext } from \"../cli/context.js\";\n\nexport async function updateContextCommand(ctx: FetCommandContext): Promise<void> {\n await withProjectLock(\n ctx.projectRoot,\n { command: \"update-context\", cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => updateContextFiles(ctx)\n );\n\n ctx.output.result({\n ok: true,\n command: \"update-context\",\n summary: \"已更新 AGENTS.md 与 openspec/config.yaml 的 FET 托管区域。\"\n });\n}\n\nexport async function updateContextFiles(ctx: FetCommandContext): Promise<{ warnings: string[] }> {\n const scan = await ctx.scanner.scan(ctx.projectRoot, {});\n const agentsPath = join(ctx.projectRoot, \"AGENTS.md\");\n const configPath = join(ctx.projectRoot, \"openspec\", \"config.yaml\");\n\n const existingAgents = await readOptional(agentsPath);\n const warnings = [...scan.warnings];\n if (existingAgents && hasInvalidManagedAutoRegion(existingAgents)) {\n throw new FetError({\n code: ErrorCode.ConfigInvalid,\n message: \"AGENTS.md 的 FET 托管标记损坏或重复\",\n details: { path: \"AGENTS.md\" },\n suggestedCommand: \"手动修复 FET:BEGIN AUTO / FET:END AUTO 标记后重试\"\n });\n }\n if (existingAgents && !hasManagedAutoRegion(existingAgents)) {\n if (!ctx.yes) {\n throw new FetError({\n code: ErrorCode.ToolAdapterConflict,\n message: \"AGENTS.md 已存在且不包含 FET 托管区域\",\n details: { path: \"AGENTS.md\" },\n suggestedCommand: \"确认可备份并替换后运行 fet update-context --yes\"\n });\n }\n const backupPath = await createBackup(agentsPath);\n if (backupPath) {\n warnings.push(`已备份非托管 AGENTS.md 到 ${backupPath}`);\n }\n }\n await atomicWrite(agentsPath, replaceManagedRegion(existingAgents, renderAgentsMd(scan)));\n await atomicWrite(configPath, await mergeFetConfig(configPath, renderFetConfig(scan)));\n\n const state = await ctx.stateStore.getOrCreateGlobal();\n state.context = {\n agentsMdUpdatedAt: scan.generatedAt,\n configUpdatedAt: scan.generatedAt,\n scannerVersion: scan.scannerVersion\n };\n await ctx.stateStore.writeGlobal(state);\n\n return { warnings };\n}\n\nasync function readOptional(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { parseDocument } from \"yaml\";\n\nexport async function mergeFetConfig(configPath: string, renderedFetYaml: string): Promise<string> {\n const fetDoc = parseDocument(renderedFetYaml);\n const nextFet = fetDoc.get(\"fet\", true);\n\n let existing = \"\";\n try {\n existing = await readFile(configPath, \"utf8\");\n } catch {\n return renderedFetYaml;\n }\n\n const doc = parseDocument(existing || \"{}\");\n doc.set(\"fet\", nextFet);\n return doc.toString();\n}\n","import { stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { FetCommandContext } from \"../cli/context.js\";\nimport { clearLock } from \"../fs/index.js\";\nimport type { DoctorCheck } from \"../adapters/index.js\";\n\nexport async function doctorCommand(ctx: FetCommandContext, options: { fixLock?: boolean } = {}): Promise<void> {\n const checks: DoctorCheck[] = [];\n\n checks.push(await checkOpenSpec(ctx));\n checks.push(await checkState(ctx));\n checks.push(await checkFile(\"agents\", join(ctx.projectRoot, \"AGENTS.md\"), \"AGENTS.md 缺失\", \"fet update-context\"));\n checks.push(await checkFile(\"config\", join(ctx.projectRoot, \"openspec\", \"config.yaml\"), \"openspec/config.yaml 缺失\", \"fet init\"));\n\n for (const adapter of ctx.toolAdapters) {\n checks.push(...(await adapter.doctor(ctx.projectRoot)));\n }\n\n const lockPath = join(ctx.projectRoot, \"openspec\", \".fet.lock\");\n if (await exists(lockPath)) {\n if (options.fixLock) {\n await clearLock(ctx.projectRoot);\n checks.push({ id: \"lock\", status: \"pass\", message: \"已清理 openspec/.fet.lock\" });\n } else {\n checks.push({ id: \"lock\", status: \"warn\", message: \"存在 openspec/.fet.lock\", suggestedCommand: \"fet doctor --fix-lock\" });\n }\n }\n\n const warnings = checks.filter((check) => check.status !== \"pass\").map((check) => check.message);\n ctx.output.result({\n ok: true,\n command: \"doctor\",\n summary: warnings.length ? `诊断完成,发现 ${warnings.length} 个需要关注的问题。` : \"诊断完成,未发现明显问题。\",\n warnings,\n data: checks\n });\n}\n\nasync function checkOpenSpec(ctx: FetCommandContext): Promise<DoctorCheck> {\n try {\n const identity = await ctx.openSpec.resolveExecutable();\n return { id: \"openspec\", status: \"pass\", message: `OpenSpec: ${identity.executablePath} (${identity.version})` };\n } catch (error) {\n return { id: \"openspec\", status: \"fail\", message: error instanceof Error ? error.message : \"OpenSpec 检测失败\" };\n }\n}\n\nasync function checkState(ctx: FetCommandContext): Promise<DoctorCheck> {\n try {\n const state = await ctx.stateStore.readGlobal();\n return state\n ? { id: \"state\", status: \"pass\", message: \"FET 全局状态可读取\" }\n : { id: \"state\", status: \"warn\", message: \"FET 全局状态尚未初始化\", suggestedCommand: \"fet init\" };\n } catch (error) {\n return { id: \"state\", status: \"fail\", message: error instanceof Error ? error.message : \"FET 状态读取失败\" };\n }\n}\n\nasync function checkFile(id: string, path: string, missing: string, suggestedCommand: string): Promise<DoctorCheck> {\n return (await exists(path))\n ? { id, status: \"pass\", message: `${id} 存在` }\n : { id, status: \"warn\", message: missing, suggestedCommand };\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { ProjectIdentity } from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function detectProjectIdentity(projectRoot: string): Promise<ProjectIdentity> {\n const [gitRoot, branch, headCommit] = await Promise.all([\n git(projectRoot, [\"rev-parse\", \"--show-toplevel\"]),\n git(projectRoot, [\"branch\", \"--show-current\"]),\n git(projectRoot, [\"rev-parse\", \"HEAD\"])\n ]);\n\n return {\n gitRoot,\n worktreePath: projectRoot,\n branch,\n headCommit\n };\n}\n\nasync function git(cwd: string, args: string[]): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n}\n","import { mkdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { atomicWrite } from \"../fs/atomic-write.js\";\nimport { assertChangeState, assertGlobalState, createChangeState, createGlobalState } from \"./schema.js\";\nimport type { ChangePhase, ChangeState, GlobalState, ProjectIdentity } from \"./types.js\";\n\nexport class StateStore {\n constructor(\n private readonly projectRoot: string,\n private readonly fetVersion: string,\n private readonly project: ProjectIdentity\n ) {}\n\n async readGlobal(): Promise<GlobalState | null> {\n try {\n const value = JSON.parse(await readFile(this.globalPath(), \"utf8\"));\n assertGlobalState(value);\n return value;\n } catch (error) {\n if (isNotFound(error)) {\n return null;\n }\n throw error;\n }\n }\n\n async getOrCreateGlobal(): Promise<GlobalState> {\n return (await this.readGlobal()) ?? createGlobalState(this.fetVersion, this.project);\n }\n\n async writeGlobal(state: GlobalState): Promise<void> {\n state.updatedAt = new Date().toISOString();\n await mkdir(join(this.projectRoot, \"openspec\"), { recursive: true });\n await atomicWrite(this.globalPath(), `${JSON.stringify(state, null, 2)}\\n`);\n }\n\n async readChange(changeId: string): Promise<ChangeState | null> {\n try {\n const value = JSON.parse(await readFile(this.changePath(changeId), \"utf8\"));\n assertChangeState(value);\n return value;\n } catch (error) {\n if (isNotFound(error)) {\n return null;\n }\n throw error;\n }\n }\n\n async getOrCreateChange(changeId: string, phase: ChangePhase): Promise<ChangeState> {\n return (await this.readChange(changeId)) ?? createChangeState(this.fetVersion, changeId, phase);\n }\n\n async writeChange(state: ChangeState): Promise<void> {\n state.updatedAt = new Date().toISOString();\n await mkdir(join(this.projectRoot, \"openspec\", \"changes\", state.changeId), { recursive: true });\n await atomicWrite(this.changePath(state.changeId), `${JSON.stringify(state, null, 2)}\\n`);\n }\n\n private globalPath(): string {\n return join(this.projectRoot, \"openspec\", \"fet-state.json\");\n }\n\n private changePath(changeId: string): string {\n return join(this.projectRoot, \"openspec\", \"changes\", changeId, \"fet-state.json\");\n }\n}\n\nfunction isNotFound(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\";\n}\n","import { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport type { ChangePhase, ChangeState, GlobalState, ProjectIdentity } from \"./types.js\";\n\nconst phases: ChangePhase[] = [\"explore\", \"propose\", \"implement\", \"verify\", \"sync\", \"archive\"];\n\nexport function createGlobalState(fetVersion: string, project: ProjectIdentity): GlobalState {\n const now = new Date().toISOString();\n return {\n schemaVersion: 1,\n fetVersion,\n createdAt: now,\n updatedAt: now,\n project,\n openspec: null,\n activeChangeId: null,\n openChangeIds: [],\n context: {\n agentsMdUpdatedAt: null,\n configUpdatedAt: null,\n scannerVersion: 1\n },\n toolAdapters: {},\n verifyAuthorization: null,\n lastDoctor: null\n };\n}\n\nexport function createChangeState(fetVersion: string, changeId: string, phase: ChangePhase): ChangeState {\n const now = new Date().toISOString();\n return {\n schemaVersion: 1,\n fetVersion,\n changeId,\n createdAt: now,\n updatedAt: now,\n currentPhase: phase,\n phases: Object.fromEntries(\n phases.map((item) => [item, { status: item === phase ? \"in_progress\" : \"not_started\" }])\n ) as ChangeState[\"phases\"],\n tasks: {\n source: \"tasks.md\",\n completedIds: [],\n lastSyncedAt: null\n },\n manualVerify: null,\n lastOpenSpecCommand: null,\n warnings: []\n };\n}\n\nexport function assertGlobalState(value: unknown): asserts value is GlobalState {\n if (!isRecord(value) || value.schemaVersion !== 1) {\n throw unsupportedSchema(\"全局状态 schema 不受支持\");\n }\n if (typeof value.fetVersion !== \"string\" || !isRecord(value.project)) {\n throw corruptedState(\"全局状态缺少必填字段\");\n }\n}\n\nexport function assertChangeState(value: unknown): asserts value is ChangeState {\n if (!isRecord(value) || value.schemaVersion !== 1) {\n throw unsupportedSchema(\"变更状态 schema 不受支持\");\n }\n if (typeof value.fetVersion !== \"string\" || typeof value.changeId !== \"string\") {\n throw corruptedState(\"变更状态缺少必填字段\");\n }\n}\n\nfunction unsupportedSchema(message: string): FetError {\n return new FetError({\n code: ErrorCode.StateSchemaUnsupported,\n message,\n suggestedCommand: \"npm update -g @nick848/fet\"\n });\n}\n\nfunction corruptedState(message: string): FetError {\n return new FetError({\n code: ErrorCode.StateCorrupted,\n message,\n suggestedCommand: \"fet doctor --fix\"\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { readFile } from \"node:fs/promises\";\n\nexport async function readCompletedTaskIds(tasksPath: string): Promise<string[]> {\n let content: string;\n try {\n content = await readFile(tasksPath, \"utf8\");\n } catch {\n return [];\n }\n\n const completed: string[] = [];\n const pattern = /^\\s*[-*]\\s+\\[[xX]\\]\\s+([0-9]+(?:\\.[0-9]+)*)/gm;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(content))) {\n if (match[1]) {\n completed.push(match[1]);\n }\n }\n return completed;\n}\n","import { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport { withProjectLock } from \"../fs/index.js\";\nimport { readCompletedTaskIds, type ChangePhase } from \"../state/index.js\";\nimport type { FetCommandContext } from \"../cli/context.js\";\n\nconst phaseByCommand: Record<string, ChangePhase> = {\n explore: \"explore\",\n propose: \"propose\",\n new: \"propose\",\n continue: \"propose\",\n ff: \"propose\",\n apply: \"implement\",\n verify: \"verify\",\n sync: \"sync\",\n archive: \"archive\",\n \"bulk-archive\": \"archive\",\n onboard: \"explore\"\n};\n\nexport async function proxyCommand(ctx: FetCommandContext, command: string, args: string[]): Promise<void> {\n const openSpecArgs = stripFetOptions(args);\n await withProjectLock(\n ctx.projectRoot,\n { command, cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => {\n if ([\"sync\", \"archive\", \"bulk-archive\"].includes(command)) {\n await assertVerified(ctx);\n }\n\n const mapped = await mapOpenSpecCommand(ctx, command, openSpecArgs);\n const result = await ctx.openSpec.run(mapped.command, mapped.args, { cwd: ctx.projectRoot, stdio: ctx.json ? \"pipe\" : \"inherit\" });\n if (result.exitCode !== 0) {\n throw new FetError({\n code: ErrorCode.OpenSpecCommandFailed,\n message: `OpenSpec ${command} 执行失败`,\n details: result,\n recoverable: true\n });\n }\n\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n const state = await ctx.stateStore.getOrCreateGlobal();\n state.openChangeIds = inspection.changes;\n if (ctx.changeId && inspection.changes.includes(ctx.changeId)) {\n state.activeChangeId = ctx.changeId;\n } else if (state.activeChangeId && !inspection.changes.includes(state.activeChangeId)) {\n state.activeChangeId = inspection.changes.length === 1 ? (inspection.changes[0] ?? null) : null;\n } else if (!state.activeChangeId && inspection.changes.length === 1) {\n state.activeChangeId = inspection.changes[0] ?? null;\n }\n await ctx.stateStore.writeGlobal(state);\n\n const changeId = ctx.changeId ?? state.activeChangeId;\n if (changeId && inspection.changes.includes(changeId)) {\n const changeInspection = await ctx.openSpec.inspectChange(ctx.projectRoot, changeId);\n const changeState = await ctx.stateStore.getOrCreateChange(changeId, phaseByCommand[command] ?? \"propose\");\n changeState.currentPhase = phaseByCommand[command] ?? changeState.currentPhase;\n changeState.phases[changeState.currentPhase] = {\n status: \"done\",\n updatedAt: new Date().toISOString()\n };\n changeState.lastOpenSpecCommand = {\n command: mapped.command,\n args: mapped.args,\n exitCode: result.exitCode,\n ranAt: new Date().toISOString()\n };\n changeState.tasks.completedIds = await readCompletedTaskIds(changeInspection.tasksPath);\n changeState.tasks.lastSyncedAt = new Date().toISOString();\n await ctx.stateStore.writeChange(changeState);\n }\n }\n );\n\n ctx.output.result({\n ok: true,\n command,\n summary: `fet ${command} 完成。`\n });\n}\n\nexport async function passthroughCommand(ctx: FetCommandContext, command: string, args: string[]): Promise<void> {\n const result = await ctx.openSpec.run(command, stripFetOptions(args), { cwd: ctx.projectRoot, stdio: ctx.json ? \"pipe\" : \"inherit\" });\n if (result.exitCode !== 0) {\n throw new FetError({\n code: ErrorCode.OpenSpecCommandFailed,\n message: `OpenSpec ${command} 执行失败`,\n details: result\n });\n }\n}\n\nfunction stripFetOptions(args: string[]): string[] {\n const result: string[] = [];\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg === \"--cwd\" || arg === \"--change\") {\n index += 1;\n continue;\n }\n if (arg?.startsWith(\"--cwd=\") || arg?.startsWith(\"--change=\")) {\n continue;\n }\n if (arg === \"--yes\" || arg === \"--json\" || arg === \"--verbose\" || arg === \"--no-color\") {\n continue;\n }\n if (arg) {\n result.push(arg);\n }\n }\n return result;\n}\n\nasync function mapOpenSpecCommand(\n ctx: FetCommandContext,\n command: string,\n args: string[]\n): Promise<{ command: string; args: string[] }> {\n switch (command) {\n case \"propose\":\n case \"new\":\n return { command: \"new\", args: args[0] === \"change\" ? args : [\"change\", ...args] };\n case \"continue\":\n return { command: \"instructions\", args: [...withoutUndefined(args[0] ? [args[0]] : [\"proposal\"]), \"--change\", await requireChangeId(ctx)] };\n case \"ff\":\n return { command: \"status\", args: [\"--change\", await requireChangeId(ctx)] };\n case \"apply\":\n return { command: \"instructions\", args: [\"apply\", \"--change\", await requireChangeId(ctx)] };\n case \"sync\":\n return { command: \"validate\", args: [ctx.changeId ?? args[0] ?? (await requireChangeId(ctx)), \"--type\", \"change\", \"--strict\"] };\n case \"archive\":\n return { command: \"archive\", args: [ctx.changeId ?? args[0] ?? (await requireChangeId(ctx)), ...args.slice(ctx.changeId ? 0 : 1)] };\n case \"bulk-archive\":\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"OpenSpec 1.2.0 不提供 bulk-archive 顶层命令\",\n suggestedCommand: \"逐个执行 fet archive --change <change-id>\"\n });\n case \"explore\":\n return { command: \"instructions\", args: [\"proposal\", \"--change\", await requireChangeId(ctx)] };\n case \"onboard\":\n return { command: \"instructions\", args: [] };\n default:\n return { command, args };\n }\n}\n\nasync function requireChangeId(ctx: FetCommandContext): Promise<string> {\n if (ctx.changeId) {\n return ctx.changeId;\n }\n const state = await ctx.stateStore.getOrCreateGlobal();\n if (state.activeChangeId) {\n return state.activeChangeId;\n }\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n if (inspection.changes.length === 1 && inspection.changes[0]) {\n return inspection.changes[0];\n }\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"该命令需要明确的 change\",\n details: { openChangeIds: inspection.changes },\n suggestedCommand: \"添加 --change <change-id>\"\n });\n}\n\nfunction withoutUndefined(values: string[]): string[] {\n return values.filter(Boolean);\n}\n\nasync function assertVerified(ctx: FetCommandContext): Promise<void> {\n const global = await ctx.stateStore.getOrCreateGlobal();\n const changeId = ctx.changeId ?? global.activeChangeId;\n if (!changeId) {\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"未指定 change,无法检查 verify 状态\",\n suggestedCommand: \"fet verify --done --change <change-id>\"\n });\n }\n const change = await ctx.stateStore.readChange(changeId);\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n if (!inspection.changes.includes(changeId)) {\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"指定的 change 不存在或已归档\",\n details: { changeId, openChangeIds: inspection.changes },\n suggestedCommand: \"fet doctor\"\n });\n }\n if (change?.manualVerify?.status !== \"declared_done\") {\n throw new FetError({\n code: ErrorCode.StateCorrupted,\n message: \"当前 change 尚未通过 FET verify\",\n details: { changeId },\n suggestedCommand: `fet verify --change ${changeId}`\n });\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { FetCommandContext } from \"../cli/context.js\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport { atomicWrite, withProjectLock } from \"../fs/index.js\";\nimport { renderVerifyInstructions } from \"../templates/index.js\";\n\nexport async function verifyCommand(ctx: FetCommandContext, options: { done?: boolean; auto?: boolean }): Promise<void> {\n if (options.auto) {\n const scan = await ctx.scanner.scan(ctx.projectRoot, {});\n const plan = {\n schemaVersion: 1,\n packageManager: scan.project.packageManager,\n workspaces: [\n {\n name: \"root\",\n cwd: \".\",\n commands: Object.entries(scan.commands)\n .filter(([name]) => [\"lint\", \"typecheck\", \"test\"].includes(name))\n .map(([dimension, command]) => ({\n dimension,\n command: command.command,\n source: command.source,\n required: command.required,\n statusIfMissing: command.required ? \"fail\" : \"warn\"\n }))\n }\n ],\n missing: [\"lint\", \"typecheck\", \"test\"].filter((name) => !scan.commands[name])\n };\n if (ctx.yes) {\n const global = await ctx.stateStore.getOrCreateGlobal();\n global.verifyAuthorization = {\n schemaVersion: 1,\n approvedAt: new Date().toISOString(),\n commandFingerprint: fingerprint(plan),\n packageManager: plan.packageManager,\n plan: plan.workspaces.flatMap((workspace) =>\n workspace.commands.map((command) => ({\n cwd: workspace.cwd,\n dimension: command.dimension,\n command: command.command,\n source: command.source,\n required: command.required\n }))\n )\n };\n await ctx.stateStore.writeGlobal(global);\n }\n\n ctx.output.result({\n ok: true,\n command: \"verify\",\n summary: ctx.yes ? \"已确认 verify --auto 执行计划;MVP 暂不执行仓库脚本。\" : \"已生成 verify --auto 执行计划;MVP 暂不执行仓库脚本。\",\n warnings: plan.missing.map((name) => `未发现 ${name} 脚本,将在自动执行版本中按配置处理。`),\n data: plan,\n nextSteps: ctx.yes ? [\"当前版本请运行 fet verify 进入手动验证模式\"] : [\"审核执行计划\", \"确认计划后可运行 fet verify --auto --yes\", \"当前版本请运行 fet verify 进入手动验证模式\"]\n });\n return;\n }\n\n await withProjectLock(\n ctx.projectRoot,\n { command: \"verify\", cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => {\n const changeId = await resolveChangeId(ctx);\n if (options.done) {\n await markDone(ctx, changeId);\n } else {\n await writeInstructions(ctx, changeId);\n }\n }\n );\n}\n\nasync function writeInstructions(ctx: FetCommandContext, changeId: string): Promise<void> {\n await assertChangeExists(ctx, changeId);\n const generatedAt = new Date().toISOString();\n const dir = join(ctx.projectRoot, \"openspec\", \"changes\", changeId, \".fet\");\n const instructionsPath = join(dir, \"verify-instructions.md\");\n await mkdir(dir, { recursive: true });\n await atomicWrite(instructionsPath, renderVerifyInstructions(changeId, generatedAt));\n\n const state = await ctx.stateStore.getOrCreateChange(changeId, \"verify\");\n state.currentPhase = \"verify\";\n state.phases.verify = { status: \"in_progress\", updatedAt: generatedAt };\n await ctx.stateStore.writeChange(state);\n\n ctx.output.result({\n ok: true,\n command: \"verify\",\n summary: \"已生成手动验证指令。\",\n nextSteps: [`阅读 openspec/changes/${changeId}/.fet/verify-instructions.md`, `完成后运行 fet verify --done --change ${changeId}`]\n });\n}\n\nasync function markDone(ctx: FetCommandContext, changeId: string): Promise<void> {\n await assertChangeExists(ctx, changeId);\n const declaredAt = new Date().toISOString();\n const instructionsPath = join(ctx.projectRoot, \"openspec\", \"changes\", changeId, \".fet\", \"verify-instructions.md\");\n const instructions = await readInstructions(instructionsPath, changeId);\n const instructionsGeneratedAt = readFrontMatterValue(instructions, \"generatedAt\") ?? declaredAt;\n const state = await ctx.stateStore.getOrCreateChange(changeId, \"verify\");\n state.currentPhase = \"verify\";\n state.phases.verify = { status: \"done\", updatedAt: declaredAt };\n state.manualVerify = {\n mode: \"manual\",\n status: \"declared_done\",\n declaredAt,\n instructionsPath: `openspec/changes/${changeId}/.fet/verify-instructions.md`,\n instructionsGeneratedAt,\n evidence: null\n };\n await ctx.stateStore.writeChange(state);\n\n ctx.output.result({\n ok: true,\n command: \"verify\",\n summary: \"已记录手动验证完成声明。\",\n nextSteps: [`fet sync --change ${changeId}`, `fet archive --change ${changeId}`]\n });\n}\n\nasync function assertChangeExists(ctx: FetCommandContext, changeId: string): Promise<void> {\n const inspection = await ctx.openSpec.inspectChange(ctx.projectRoot, changeId);\n if (!inspection.exists) {\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"指定的 change 不存在\",\n details: { changeId },\n suggestedCommand: \"fet verify --change <change-id>\"\n });\n }\n}\n\nasync function readInstructions(path: string, changeId: string): Promise<string> {\n try {\n await stat(path);\n const content = await readFile(path, \"utf8\");\n const fileChangeId = readFrontMatterValue(content, \"changeId\");\n if (fileChangeId !== changeId) {\n throw new FetError({\n code: ErrorCode.StateCorrupted,\n message: \"验证指令文件与当前 change 不匹配\",\n details: { expected: changeId, actual: fileChangeId },\n suggestedCommand: `fet verify --change ${changeId}`\n });\n }\n return content;\n } catch (error) {\n if (error instanceof FetError) {\n throw error;\n }\n throw new FetError({\n code: ErrorCode.StateCorrupted,\n message: \"验证指令文件不存在或无法读取\",\n details: { path },\n suggestedCommand: `fet verify --change ${changeId}`\n });\n }\n}\n\nfunction readFrontMatterValue(content: string, key: string): string | null {\n const match = content.match(new RegExp(`^${key}:\\\\s*(.+)$`, \"m\"));\n return match?.[1]?.trim() ?? null;\n}\n\nfunction fingerprint(value: unknown): string {\n return `sha256:${createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\")}`;\n}\n\nasync function resolveChangeId(ctx: FetCommandContext): Promise<string> {\n if (ctx.changeId) {\n return ctx.changeId;\n }\n\n const global = await ctx.stateStore.getOrCreateGlobal();\n if (global.activeChangeId) {\n return global.activeChangeId;\n }\n\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n if (inspection.changes.length === 1 && inspection.changes[0]) {\n return inspection.changes[0];\n }\n\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"无法确定要验证的 change\",\n details: { openChangeIds: inspection.changes },\n suggestedCommand: \"fet verify --change <change-id>\"\n });\n}\n","import { resolve } from \"node:path\";\nimport { CursorAdapter } from \"../adapters/index.js\";\nimport { DefaultOpenSpecAdapter } from \"../openspec/index.js\";\nimport { ProjectScanner } from \"../scanner/index.js\";\nimport { detectProjectIdentity, StateStore } from \"../state/index.js\";\nimport { FET_VERSION } from \"../version.js\";\nimport { OutputWriter } from \"./output.js\";\n\nexport interface GlobalOptions {\n cwd?: string;\n json?: boolean;\n verbose?: boolean;\n yes?: boolean;\n change?: string;\n}\n\nexport async function createCommandContext(command: string, options: GlobalOptions) {\n const projectRoot = resolve(options.cwd ?? process.cwd());\n const project = await detectProjectIdentity(projectRoot);\n const output = new OutputWriter(Boolean(options.json));\n\n return {\n command,\n cwd: projectRoot,\n projectRoot,\n isTty: Boolean(process.stdout.isTTY),\n json: Boolean(options.json),\n verbose: Boolean(options.verbose),\n yes: Boolean(options.yes),\n changeId: options.change,\n fetVersion: FET_VERSION,\n output,\n stateStore: new StateStore(projectRoot, FET_VERSION, project),\n openSpec: new DefaultOpenSpecAdapter(),\n scanner: new ProjectScanner(),\n toolAdapters: [new CursorAdapter()]\n };\n}\n\nexport type FetCommandContext = Awaited<ReturnType<typeof createCommandContext>>;\n","import { mkdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { ErrorCode } from \"../../errors/codes.js\";\nimport { FetError } from \"../../errors/fet-error.js\";\nimport { atomicWrite } from \"../../fs/atomic-write.js\";\nimport { createBackup } from \"../../fs/backup.js\";\nimport type { DoctorCheck, ToolAdapter, ToolInstallPlan, ToolInstallResult } from \"../types.js\";\nimport { cursorRuleFile, cursorSkillFiles } from \"./templates.js\";\n\nexport class CursorAdapter implements ToolAdapter {\n readonly tool = \"cursor\";\n readonly adapterVersion = 1;\n\n async detect(projectRoot: string) {\n return {\n detected: await exists(join(projectRoot, \".cursor\")),\n reason: \"Cursor adapter is available for any project\"\n };\n }\n\n async planInstall(_projectRoot: string): Promise<ToolInstallPlan> {\n return {\n tool: this.tool,\n files: [...cursorSkillFiles(), cursorRuleFile()].map((file) => ({\n ...file,\n managed: true\n }))\n };\n }\n\n async install(projectRoot: string, plan: ToolInstallPlan, force = false): Promise<ToolInstallResult> {\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const file of plan.files) {\n const target = join(projectRoot, file.path);\n const existing = await readExisting(target);\n if (existing && !existing.includes(\"FET:MANAGED\") && !force) {\n throw new FetError({\n code: ErrorCode.ToolAdapterConflict,\n message: \"Cursor 配置文件已存在且不归 FET 管理\",\n details: { path: file.path },\n suggestedCommand: \"fet init --yes\"\n });\n }\n if (existing && !existing.includes(\"FET:MANAGED\") && force) {\n await createBackup(target);\n }\n await mkdir(dirname(target), { recursive: true });\n await atomicWrite(target, file.content);\n written.push(file.path);\n }\n\n return { tool: this.tool, written, skipped };\n }\n\n async doctor(projectRoot: string): Promise<DoctorCheck[]> {\n const plan = await this.planInstall(projectRoot);\n const checks: DoctorCheck[] = [];\n for (const file of plan.files) {\n const target = join(projectRoot, file.path);\n const content = await readExisting(target);\n const managed = Boolean(content?.includes(\"FET:MANAGED\"));\n const versionMatches = Boolean(content?.includes(`adapterVersion: ${this.adapterVersion}`));\n checks.push({\n id: `cursor:${file.path}`,\n status: !content ? \"warn\" : managed && versionMatches ? \"pass\" : \"warn\",\n message: !content\n ? `${file.path} 缺失`\n : !managed\n ? `${file.path} 存在但不归 FET 管理`\n : !versionMatches\n ? `${file.path} adapterVersion 已过期`\n : `${file.path} 存在且版本匹配`,\n suggestedCommand: !content || !managed || !versionMatches ? \"fet init\" : undefined\n });\n }\n return checks;\n }\n}\n\nasync function readExisting(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { FET_VERSION } from \"../../version.js\";\n\nconst commands = [\n \"explore\",\n \"propose\",\n \"new\",\n \"continue\",\n \"ff\",\n \"apply\",\n \"verify\",\n \"sync\",\n \"archive\",\n \"bulk-archive\",\n \"onboard\"\n];\n\nexport function cursorSkillFiles(): Array<{ path: string; content: string }> {\n return commands.map((command) => ({\n path: `.cursor/skills/fet-${command}/SKILL.md`,\n content: renderSkill(command)\n }));\n}\n\nexport function cursorRuleFile(): { path: string; content: string } {\n return {\n path: \".cursor/rules/fet-context.mdc\",\n content: `<!-- FET:MANAGED\nschemaVersion: 1\nfetVersion: ${FET_VERSION}\ngenerator: cursor-adapter\nadapterVersion: 1\nFET:END -->\n\n---\ndescription: Load FET project context for implementation tasks\nalwaysApply: false\n---\n\n当用户请求修改项目、实现 OpenSpec change、运行 FET 工作流或解释项目结构时,优先阅读:\n\n- AGENTS.md\n- openspec/config.yaml\n- 当前 change 目录下的 OpenSpec 规划产物\n\n如果用户输入类似 \\`/fet apply\\` 的请求,Cursor 当前版本未必会把本文件注册为原生 slash command。此时请把它当作工作流意图,并提示用户在终端执行对应的 \\`fet <cmd>\\` 命令。\n`\n };\n}\n\nfunction renderSkill(command: string): string {\n return `<!-- FET:MANAGED\nschemaVersion: 1\nfetVersion: ${FET_VERSION}\ngenerator: cursor-adapter\nadapterVersion: 1\ncommand: fet ${command}\nFET:END -->\n\n---\nname: fet-${command}\ndescription: Run FET-managed OpenSpec ${command} workflow from the terminal\ndisable-model-invocation: true\n---\n\n注意:此文件采用 Cursor Skill 目录结构。它提供 \\`/fet-${command}\\` 风格的工作流说明,不承诺注册 \\`/fet ${command}\\` 这种带空格的原生 slash command。\n\n请在终端中执行:\n\n\\`\\`\\`sh\nfet ${command}\n\\`\\`\\`\n\n执行前请确认已阅读 AGENTS.md 与 openspec/config.yaml。\n`;\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { OpenSpecIdentity } from \"../state/types.js\";\nimport { inspectOpenSpecChange, inspectOpenSpecProject } from \"./inspector.js\";\nimport { resolveOpenSpecExecutable } from \"./resolver.js\";\nimport { runOpenSpec } from \"./runner.js\";\nimport type {\n OpenSpecAdapter,\n OpenSpecCapabilities,\n OpenSpecChangeInspection,\n OpenSpecProjectInspection,\n OpenSpecRunOptions,\n OpenSpecRunResult\n} from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport class DefaultOpenSpecAdapter implements OpenSpecAdapter {\n private identity?: OpenSpecIdentity;\n\n async resolveExecutable(): Promise<OpenSpecIdentity> {\n this.identity ??= await resolveOpenSpecExecutable();\n return this.identity;\n }\n\n async getCapabilities(): Promise<OpenSpecCapabilities> {\n const identity = await this.resolveExecutable();\n const executable = identity.executablePath === \"npx openspec\" ? \"npx\" : identity.executablePath;\n const args = identity.executablePath === \"npx openspec\" ? [\"openspec\", \"--help\"] : [\"--help\"];\n\n try {\n const { stdout } = await execFileAsync(executable, args, { shell: process.platform === \"win32\" });\n return {\n version: identity.version,\n commands: parseCommands(stdout),\n supported: true\n };\n } catch {\n return {\n version: identity.version,\n commands: [],\n supported: false\n };\n }\n }\n\n async run(command: string, args: string[], options: OpenSpecRunOptions): Promise<OpenSpecRunResult> {\n const identity = await this.resolveExecutable();\n return runOpenSpec(identity.executablePath, command, args, options);\n }\n\n inspectProject(projectRoot: string): Promise<OpenSpecProjectInspection> {\n return inspectOpenSpecProject(projectRoot);\n }\n\n inspectChange(projectRoot: string, changeId: string): Promise<OpenSpecChangeInspection> {\n return inspectOpenSpecChange(projectRoot, changeId);\n }\n}\n\nfunction parseCommands(help: string): string[] {\n const known = [\n \"init\",\n \"explore\",\n \"propose\",\n \"new\",\n \"continue\",\n \"ff\",\n \"apply\",\n \"verify\",\n \"sync\",\n \"archive\",\n \"bulk-archive\",\n \"onboard\"\n ];\n return known.filter((command) => help.includes(command));\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { OpenSpecChangeInspection, OpenSpecProjectInspection } from \"./types.js\";\n\nexport async function inspectOpenSpecProject(projectRoot: string): Promise<OpenSpecProjectInspection> {\n const openspecPath = join(projectRoot, \"openspec\");\n const changesPath = join(openspecPath, \"changes\");\n const archivePath = join(openspecPath, \"archive\");\n\n return {\n exists: await exists(openspecPath),\n changes: await listDirectories(changesPath),\n archived: await listDirectories(archivePath)\n };\n}\n\nexport async function inspectOpenSpecChange(\n projectRoot: string,\n changeId: string\n): Promise<OpenSpecChangeInspection> {\n const changePath = join(projectRoot, \"openspec\", \"changes\", changeId);\n const tasksPath = join(changePath, \"tasks.md\");\n const specsPath = join(changePath, \"specs\");\n\n return {\n changeId,\n exists: await exists(changePath),\n hasProposal: await exists(join(changePath, \"proposal.md\")),\n hasTasks: await exists(tasksPath),\n hasSpecs: await exists(specsPath),\n tasksPath,\n changePath\n };\n}\n\nasync function listDirectories(path: string): Promise<string[]> {\n try {\n const entries = await readdir(path, { withFileTypes: true });\n return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);\n } catch {\n return [];\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport type { OpenSpecIdentity } from \"../state/types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function resolveOpenSpecExecutable(): Promise<OpenSpecIdentity> {\n const executablePath = await findExecutable();\n const version = await readVersion(executablePath);\n return {\n executablePath,\n version,\n adapterVersion: 1\n };\n}\n\nasync function findExecutable(): Promise<string> {\n const command = process.platform === \"win32\" ? \"where.exe\" : \"which\";\n try {\n const { stdout } = await exec(command, [\"openspec\"]);\n const first = stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .find(Boolean);\n if (first) {\n return first;\n }\n } catch {\n // Try npx below.\n }\n\n try {\n await exec(\"npx\", [\"openspec\", \"--version\"]);\n return \"npx openspec\";\n } catch {\n throw new FetError({\n code: ErrorCode.OpenSpecNotFound,\n message: \"OpenSpec CLI 未安装\",\n suggestedCommand: \"npm install -g @fission-ai/openspec\"\n });\n }\n}\n\nasync function readVersion(executablePath: string): Promise<string> {\n const command = executablePath === \"npx openspec\" ? \"npx\" : executablePath;\n const args = executablePath === \"npx openspec\" ? [\"openspec\", \"--version\"] : [\"--version\"];\n try {\n const { stdout, stderr } = await exec(command, args);\n return stdout.trim() || stderr.trim() || \"unknown\";\n } catch (error) {\n throw new FetError({\n code: ErrorCode.OpenSpecUnsupportedVersion,\n message: \"无法读取 OpenSpec 版本\",\n details: { executablePath },\n cause: error\n });\n }\n}\n\nfunction exec(command: string, args: string[]) {\n return execFileAsync(command, args, { shell: process.platform === \"win32\" });\n}\n","import { spawn } from \"node:child_process\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport type { OpenSpecRunOptions, OpenSpecRunResult } from \"./types.js\";\n\nexport async function runOpenSpec(\n executablePath: string,\n command: string,\n args: string[],\n options: OpenSpecRunOptions\n): Promise<OpenSpecRunResult> {\n const spawnCommand = executablePath === \"npx openspec\" ? \"npx\" : executablePath;\n const spawnArgs = executablePath === \"npx openspec\" ? [\"openspec\", command, ...args] : [command, ...args];\n\n return new Promise((resolve, reject) => {\n const stdout: Buffer[] = [];\n const stderr: Buffer[] = [];\n const child = spawn(spawnCommand, spawnArgs, {\n cwd: options.cwd,\n stdio: options.stdio ?? \"inherit\",\n shell: process.platform === \"win32\"\n });\n\n if (child.stdout) {\n child.stdout.on(\"data\", (chunk: Buffer) => stdout.push(chunk));\n }\n if (child.stderr) {\n child.stderr.on(\"data\", (chunk: Buffer) => stderr.push(chunk));\n }\n\n child.on(\"error\", (error) => {\n reject(\n new FetError({\n code: ErrorCode.OpenSpecCommandFailed,\n message: \"OpenSpec 命令启动失败\",\n details: { command, args },\n cause: error\n })\n );\n });\n\n child.on(\"close\", (exitCode, signal) => {\n resolve({\n command,\n args,\n exitCode: exitCode ?? 1,\n signal,\n stdout: stdout.length ? Buffer.concat(stdout).toString(\"utf8\") : undefined,\n stderr: stderr.length ? Buffer.concat(stderr).toString(\"utf8\") : undefined\n });\n });\n });\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport type { ScannedCommand, ScannedWorkspace } from \"./types.js\";\n\ninterface PackageJson {\n name?: string;\n packageManager?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n workspaces?: string[] | { packages?: string[] };\n}\n\nexport async function readPackageJson(projectRoot: string): Promise<PackageJson | null> {\n try {\n return JSON.parse(await readFile(join(projectRoot, \"package.json\"), \"utf8\"));\n } catch {\n return null;\n }\n}\n\nexport interface PackageManagerDetection {\n manager: string;\n confidence: \"high\" | \"medium\" | \"low\";\n warnings: string[];\n}\n\nexport async function detectPackageManager(projectRoot: string, pkg: PackageJson | null): Promise<PackageManagerDetection> {\n const warnings: string[] = [];\n if (pkg?.packageManager) {\n const declared = pkg.packageManager.split(\"@\")[0] ?? \"unknown\";\n const locks = await detectLockManagers(projectRoot);\n const conflicting = locks.filter((item) => item !== declared);\n if (conflicting.length) {\n warnings.push(`packageManager 声明为 ${declared},但同时发现锁文件:${conflicting.join(\", \")}`);\n }\n return { manager: declared, confidence: \"high\", warnings };\n }\n\n const locks = await detectLockManagers(projectRoot);\n if (locks.length > 1) {\n warnings.push(`发现多个包管理器锁文件:${locks.join(\", \")},默认使用 ${locks[0]}`);\n return { manager: locks[0] ?? \"npm\", confidence: \"medium\", warnings };\n }\n if (locks[0]) {\n return { manager: locks[0], confidence: \"high\", warnings };\n }\n return { manager: \"npm\", confidence: \"low\", warnings };\n}\n\nexport function extractCommands(pkg: PackageJson | null, packageManager: string): Record<string, ScannedCommand> {\n const scripts = pkg?.scripts ?? {};\n const result: Record<string, ScannedCommand> = {};\n const scriptNames = [\"dev\", \"build\", \"lint\", \"typecheck\", \"check\", \"test\", \"test:unit\"];\n\n for (const name of scriptNames) {\n if (scripts[name]) {\n const dimension = name === \"check\" ? \"typecheck\" : name === \"test:unit\" ? \"test\" : name;\n if (result[dimension]) {\n continue;\n }\n result[dimension] = {\n command: scriptCommand(packageManager, name),\n source: `package.json:scripts.${name}`,\n required: name === \"build\"\n };\n }\n }\n\n return result;\n}\n\nexport function detectFramework(pkg: PackageJson | null): { name: string; confidence: \"high\" | \"medium\" | \"low\"; sources: string[] } {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n const candidates: Array<[string, string[]]> = [\n [\"next\", [\"next\"]],\n [\"nuxt\", [\"nuxt\"]],\n [\"vite\", [\"vite\"]],\n [\"sveltekit\", [\"@sveltejs/kit\"]],\n [\"angular\", [\"@angular/core\", \"@angular/cli\"]],\n [\"react\", [\"react\"]],\n [\"vue\", [\"vue\"]],\n [\"svelte\", [\"svelte\"]]\n ];\n for (const [candidate, packages] of candidates) {\n if (packages.some((name) => deps[name])) {\n return { name: candidate, confidence: \"high\", sources: [\"package.json\"] };\n }\n }\n return { name: \"unknown\", confidence: \"low\", sources: [] };\n}\n\nexport async function detectLanguage(projectRoot: string, pkg: PackageJson | null): Promise<string> {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n if (deps.typescript || (await exists(join(projectRoot, \"tsconfig.json\")))) {\n return \"typescript\";\n }\n return \"javascript\";\n}\n\nexport async function detectWorkspaces(projectRoot: string, pkg: PackageJson | null): Promise<ScannedWorkspace[]> {\n const packageWorkspaces = normalizeWorkspaces(pkg?.workspaces).map((path) => ({\n name: path,\n path,\n source: \"package.json:workspaces\"\n }));\n if (packageWorkspaces.length) {\n return packageWorkspaces;\n }\n\n try {\n const workspace = parse(await readFile(join(projectRoot, \"pnpm-workspace.yaml\"), \"utf8\")) as { packages?: string[] } | null;\n return (workspace?.packages ?? []).map((path) => ({\n name: path,\n path,\n source: \"pnpm-workspace.yaml:packages\"\n }));\n } catch {\n return [];\n }\n}\n\nasync function detectLockManagers(projectRoot: string): Promise<string[]> {\n const lockFiles: Array<[string, string]> = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"bun.lockb\", \"bun\"],\n [\"bun.lock\", \"bun\"],\n [\"package-lock.json\", \"npm\"]\n ];\n const found: string[] = [];\n for (const [file, manager] of lockFiles) {\n if (await exists(join(projectRoot, file))) {\n found.push(manager);\n }\n }\n return found;\n}\n\nfunction normalizeWorkspaces(workspaces: PackageJson[\"workspaces\"]): string[] {\n if (Array.isArray(workspaces)) {\n return workspaces;\n }\n return workspaces?.packages ?? [];\n}\n\nfunction scriptCommand(packageManager: string, name: string): string {\n return packageManager === \"npm\" ? `npm run ${name}` : `${packageManager} ${name}`;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\nimport type { ScannedRoute } from \"./types.js\";\n\nexport async function scanRoutes(projectRoot: string): Promise<ScannedRoute[]> {\n const candidates = [\"src/routes\", \"src/pages\", \"app\", \"pages\"];\n const routes: ScannedRoute[] = [];\n\n for (const candidate of candidates) {\n const root = join(projectRoot, candidate);\n if (!(await exists(root))) {\n continue;\n }\n for (const file of await listFiles(root)) {\n if (!/\\.(tsx?|jsx?|vue|svelte)$/.test(file)) {\n continue;\n }\n routes.push({\n path: inferRoutePath(relative(root, file)),\n source: relative(projectRoot, file).split(sep).join(\"/\"),\n inferred: true,\n confidence: \"medium\"\n });\n }\n }\n\n return routes.slice(0, 100);\n}\n\nfunction inferRoutePath(relativePath: string): string {\n const normalized = relativePath.split(sep).join(\"/\");\n const withoutExt = normalized.replace(/\\.(tsx?|jsx?|vue|svelte)$/, \"\");\n const withoutIndex = withoutExt.replace(/\\/index$/, \"\").replace(/^index$/, \"\");\n return `/${withoutIndex}`.replace(/\\/+/g, \"/\");\n}\n\nasync function listFiles(root: string): Promise<string[]> {\n const entries = await readdir(root, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const path = join(root, entry.name);\n if (entry.isDirectory()) {\n files.push(...(await listFiles(path)));\n } else {\n files.push(path);\n }\n }\n return files;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { detectFramework, detectLanguage, detectPackageManager, detectWorkspaces, extractCommands, readPackageJson } from \"./package.js\";\nimport { scanRoutes } from \"./routes.js\";\nimport type { ProjectScanResult, ScanOptions } from \"./types.js\";\n\nexport class ProjectScanner {\n async scan(projectRoot: string, _options: ScanOptions = {}): Promise<ProjectScanResult> {\n const pkg = await readPackageJson(projectRoot);\n const packageManager = await detectPackageManager(projectRoot, pkg);\n const framework = detectFramework(pkg);\n const workspaces = await detectWorkspaces(projectRoot, pkg);\n const language = await detectLanguage(projectRoot, pkg);\n const warnings = [...packageManager.warnings];\n if (framework.name === \"unknown\") {\n warnings.push(\"未能从 package.json 识别主要框架\");\n }\n\n return {\n generatedAt: new Date().toISOString(),\n scannerVersion: 1,\n project: {\n name: pkg?.name ?? \"unknown\",\n packageManager: packageManager.manager,\n packageManagerConfidence: packageManager.confidence,\n framework,\n language,\n monorepo: workspaces.length > 0,\n workspaces\n },\n commands: extractCommands(pkg, packageManager.manager),\n routes: await scanRoutes(projectRoot),\n conventions: [],\n skippedFiles: [],\n warnings\n };\n }\n}\n\nexport type {\n ProjectScanResult,\n ScanOptions,\n ScannedCommand,\n ScannedConvention,\n ScannedProjectMetadata,\n ScannedRoute,\n ScannedWorkspace,\n SkippedFile\n} from \"./types.js\";\n","import { FetError } from \"../errors/fet-error.js\";\n\nexport interface CommandResult {\n ok: true;\n command: string;\n summary: string;\n warnings?: string[];\n nextSteps?: string[];\n data?: unknown;\n}\n\nexport class OutputWriter {\n constructor(private readonly json: boolean) {}\n\n info(message: string, details?: unknown): void {\n if (!this.json) {\n process.stdout.write(`${message}${formatDetails(details)}\\n`);\n }\n }\n\n warn(message: string, details?: unknown): void {\n if (!this.json) {\n process.stderr.write(`警告:${message}${formatDetails(details)}\\n`);\n }\n }\n\n error(error: FetError): void {\n if (this.json) {\n process.stderr.write(`${JSON.stringify({ ok: false, error: error.toJSON() }, null, 2)}\\n`);\n return;\n }\n\n process.stderr.write(`FET 无法继续:${error.message}\\n`);\n if (error.details !== undefined) {\n process.stderr.write(`\\n详情:\\n${formatBlock(error.details)}\\n`);\n }\n if (error.suggestedCommand) {\n process.stderr.write(`\\n建议:\\n ${error.suggestedCommand}\\n`);\n }\n }\n\n result(result: CommandResult): void {\n if (this.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n return;\n }\n\n process.stdout.write(`${result.summary}\\n`);\n for (const warning of result.warnings ?? []) {\n process.stdout.write(`警告:${warning}\\n`);\n }\n if (result.nextSteps?.length) {\n process.stdout.write(\"\\n下一步:\\n\");\n for (const step of result.nextSteps) {\n process.stdout.write(` ${step}\\n`);\n }\n }\n }\n}\n\nfunction formatDetails(details: unknown): string {\n if (details === undefined) {\n return \"\";\n }\n return ` ${JSON.stringify(details)}`;\n}\n\nfunction formatBlock(details: unknown): string {\n if (typeof details === \"string\") {\n return ` ${details}`;\n }\n return JSON.stringify(details, null, 2)\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\");\n}\n"],"mappings":"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","names":["readFile","stat","join","dirname","dirname","join","mkdir","open","join","mkdir","dirname","open","join","readFile","join","commands","readFile","join","readFile","join","readFile","join","readOptional","readFile","stat","stat","join","join","exists","stat","mkdir","readFile","join","readFile","mkdir","join","readFile","mkdir","readFile","stat","join","join","mkdir","stat","readFile","mkdir","readFile","stat","dirname","join","exists","join","mkdir","dirname","readFile","stat","execFile","promisify","stat","join","exists","execFile","promisify","execFileAsync","promisify","execFile","resolve","execFileAsync","promisify","execFile","readFile","stat","join","locks","exists","readdir","stat","join","exists"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/commands/init.ts","../../src/fs/atomic-write.ts","../../src/fs/backup.ts","../../src/fs/lock.ts","../../src/fs/journal.ts","../../src/version.ts","../../src/templates/markers.ts","../../src/templates/agents-md.ts","../../src/templates/config-yaml.ts","../../src/templates/verify-instructions.ts","../../src/templates/gitignore.ts","../../src/commands/update-context.ts","../../src/config/yaml.ts","../../src/commands/doctor.ts","../../src/state/project.ts","../../src/state/store.ts","../../src/state/schema.ts","../../src/state/tasks.ts","../../src/commands/proxy.ts","../../src/commands/verify.ts","../../src/cli/context.ts","../../src/adapters/cursor/index.ts","../../src/adapters/cursor/templates.ts","../../src/openspec/adapter.ts","../../src/openspec/inspector.ts","../../src/openspec/resolver.ts","../../src/openspec/runner.ts","../../src/scanner/package.ts","../../src/scanner/routes.ts","../../src/scanner/index.ts","../../src/cli/output.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"../commands/init.js\";\nimport { doctorCommand } from \"../commands/doctor.js\";\nimport { proxyCommand, passthroughCommand } from \"../commands/proxy.js\";\nimport { updateContextCommand } from \"../commands/update-context.js\";\nimport { verifyCommand } from \"../commands/verify.js\";\nimport { toFetError } from \"../errors/fet-error.js\";\nimport { FET_VERSION } from \"../version.js\";\nimport { createCommandContext, type GlobalOptions } from \"./context.js\";\nimport { OutputWriter } from \"./output.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"fet\")\n .description(\"Frontend workflow orchestration tool built around OpenSpec.\")\n .enablePositionalOptions()\n .version(FET_VERSION)\n .option(\"--cwd <path>\", \"指定项目根目录\")\n .option(\"--change <id>\", \"指定 OpenSpec change\")\n .option(\"--yes\", \"对低风险确认使用默认同意\")\n .option(\"--json\", \"输出机器可读 JSON\")\n .option(\"--verbose\", \"输出诊断细节\")\n .option(\"--no-color\", \"禁用终端颜色\");\n\naddGlobalOptions(program.command(\"init\")).description(\"初始化 FET + OpenSpec\").action(wrap(\"init\", initCommand));\naddGlobalOptions(program.command(\"update-context\")).description(\"更新项目上下文\").action(wrap(\"update-context\", updateContextCommand));\naddGlobalOptions(program\n .command(\"doctor\")\n .description(\"诊断状态、配置与一致性\")\n .option(\"--fix-lock\", \"清理 FET 锁文件\"))\n .action(\n wrap(\"doctor\", (ctx, options: { fixLock?: boolean }) => doctorCommand(ctx, { fixLock: Boolean(options.fixLock) }))\n );\n\naddGlobalOptions(program\n .command(\"verify\")\n .description(\"最终质量验证\")\n .option(\"--done\", \"声明手动验证已完成\")\n .option(\"--auto\", \"生成或执行自动验证计划\"))\n .action(wrap(\"verify\", verifyCommand));\n\nfor (const command of [\"explore\", \"propose\", \"new\", \"continue\", \"ff\", \"apply\", \"sync\", \"archive\", \"bulk-archive\", \"onboard\"]) {\n addGlobalOptions(program\n .command(`${command} [args...]`)\n .description(`代理执行 openspec ${command}`)\n .allowUnknownOption(true)\n .passThroughOptions())\n .action(wrap(command, (ctx, args: string[] = []) => proxyCommand(ctx, command, args)));\n}\n\naddGlobalOptions(program\n .command(\"passthrough <command> [args...]\")\n .description(\"透传暂未接管的 OpenSpec 命令\")\n .allowUnknownOption(true)\n .passThroughOptions())\n .action(wrap(\"passthrough\", (ctx, command: string, args: string[] = []) => passthroughCommand(ctx, command, args)));\n\nprogram.parseAsync(process.argv).catch((error) => {\n const json = process.argv.includes(\"--json\");\n const output = new OutputWriter(json);\n const fetError = toFetError(error);\n output.error(fetError);\n process.exitCode = fetError.exitCode;\n});\n\nfunction wrap<T extends unknown[]>(\n command: string,\n handler: (ctx: Awaited<ReturnType<typeof createCommandContext>>, ...args: T) => Promise<void>\n) {\n return async (...args: T) => {\n const maybeCommand = args[args.length - 1] as unknown;\n const opts = isCommandLike(maybeCommand)\n ? ({ ...(maybeCommand.parent?.opts() as GlobalOptions), ...(maybeCommand.opts() as GlobalOptions) } as GlobalOptions)\n : (program.opts() as GlobalOptions);\n const ctx = await createCommandContext(command, { ...opts, ...extractGlobalOptions(args) });\n try {\n await handler(ctx, ...args);\n } catch (error) {\n const fetError = toFetError(error);\n ctx.output.error(fetError);\n process.exitCode = fetError.exitCode;\n }\n };\n}\n\nfunction isCommandLike(value: unknown): value is Command {\n return value instanceof Command;\n}\n\nfunction addGlobalOptions(command: Command): Command {\n return command\n .option(\"--cwd <path>\", \"指定项目根目录\")\n .option(\"--change <id>\", \"指定 OpenSpec change\")\n .option(\"--yes\", \"对低风险确认使用默认同意\")\n .option(\"--json\", \"输出机器可读 JSON\")\n .option(\"--verbose\", \"输出诊断细节\")\n .option(\"--no-color\", \"禁用终端颜色\");\n}\n\nfunction extractGlobalOptions(args: unknown[]): GlobalOptions {\n const values = args.flatMap((arg) => (Array.isArray(arg) ? arg : []));\n const options: GlobalOptions = {};\n for (let index = 0; index < values.length; index += 1) {\n const value = values[index];\n if (typeof value !== \"string\") {\n continue;\n }\n if (value === \"--cwd\" && typeof values[index + 1] === \"string\") {\n options.cwd = values[index + 1];\n index += 1;\n } else if (value.startsWith(\"--cwd=\")) {\n options.cwd = value.slice(\"--cwd=\".length);\n } else if (value === \"--change\" && typeof values[index + 1] === \"string\") {\n options.change = values[index + 1];\n index += 1;\n } else if (value.startsWith(\"--change=\")) {\n options.change = value.slice(\"--change=\".length);\n } else if (value === \"--yes\") {\n options.yes = true;\n } else if (value === \"--json\") {\n options.json = true;\n } else if (value === \"--verbose\") {\n options.verbose = true;\n }\n }\n return options;\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { FetCommandContext } from \"../cli/context.js\";\nimport { atomicWrite, createInitJournal, withProjectLock, writeInitJournal } from \"../fs/index.js\";\nimport { mergeGitignore } from \"../templates/index.js\";\nimport { updateContextFiles } from \"./update-context.js\";\n\nexport async function initCommand(ctx: FetCommandContext): Promise<void> {\n const alreadyInitialized = await exists(join(ctx.projectRoot, \"openspec\", \"config.yaml\"));\n await withProjectLock(\n ctx.projectRoot,\n { command: \"init\", cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => {\n const journal = createInitJournal(ctx.fetVersion);\n await writeInitJournal(ctx.projectRoot, journal);\n\n const identity = await ctx.openSpec.resolveExecutable();\n if (!alreadyInitialized) {\n const result = await ctx.openSpec.run(\"init\", [\"--tools\", \"none\"], { cwd: ctx.projectRoot, stdio: \"inherit\" });\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n return;\n }\n }\n\n const contextResult = await updateContextFiles(ctx);\n await ensureGitignore(ctx);\n\n const state = await ctx.stateStore.getOrCreateGlobal();\n state.openspec = identity;\n\n for (const adapter of ctx.toolAdapters) {\n const plan = await adapter.planInstall(ctx.projectRoot);\n const result = await adapter.install(ctx.projectRoot, plan, ctx.yes);\n state.toolAdapters[adapter.tool] = {\n adapterVersion: adapter.adapterVersion,\n installed: true,\n updatedAt: new Date().toISOString()\n };\n journal.steps.push(...result.written.map((path) => ({ operation: \"write\" as const, path, status: \"done\" as const })));\n }\n\n journal.completedAt = new Date().toISOString();\n await writeInitJournal(ctx.projectRoot, journal);\n await ctx.stateStore.writeGlobal(state);\n for (const warning of contextResult.warnings) {\n ctx.output.warn(warning);\n }\n }\n );\n\n ctx.output.result({\n ok: true,\n command: \"init\",\n summary: \"FET 初始化完成。\",\n nextSteps: [\"使用 fet propose/new 创建 OpenSpec change\", \"使用 fet doctor 检查项目状态\"]\n });\n}\n\nasync function ensureGitignore(ctx: FetCommandContext): Promise<void> {\n const gitignorePath = join(ctx.projectRoot, \".gitignore\");\n const existing = await readOptional(gitignorePath);\n await atomicWrite(gitignorePath, mergeGitignore(existing));\n}\n\nasync function readOptional(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { dirname } from \"node:path\";\nimport { open, rename, mkdir } from \"node:fs/promises\";\n\nexport interface AtomicWriteResult {\n path: string;\n tempPath: string;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array\n): Promise<AtomicWriteResult> {\n await mkdir(dirname(targetPath), { recursive: true });\n const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;\n const handle = await open(tempPath, \"wx\");\n\n try {\n await handle.writeFile(content);\n await handle.sync();\n } finally {\n await handle.close();\n }\n\n await rename(tempPath, targetPath);\n return { path: targetPath, tempPath };\n}\n","import { copyFile, stat } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\n\nexport async function createBackup(filePath: string): Promise<string | null> {\n try {\n await stat(filePath);\n } catch {\n return null;\n }\n\n const timestamp = new Date()\n .toISOString()\n .replace(/[-:]/g, \"\")\n .replace(/\\..+$/, \"\")\n .replace(\"T\", \"-\");\n const backupPath = join(dirname(filePath), `${basename(filePath)}.fet-backup-${timestamp}`);\n await copyFile(filePath, backupPath);\n return backupPath;\n}\n","import { hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { mkdir, open, readFile, rm } from \"node:fs/promises\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\n\nexport interface LockMetadata {\n command: string;\n cwd: string;\n fetVersion: string;\n}\n\ninterface LockFile {\n pid: number;\n hostname: string;\n cwd: string;\n command: string;\n startedAt: string;\n fetVersion: string;\n}\n\nexport async function withProjectLock<T>(\n projectRoot: string,\n metadata: LockMetadata,\n fn: () => Promise<T>\n): Promise<T> {\n const lockPath = join(projectRoot, \"openspec\", \".fet.lock\");\n const lock: LockFile = {\n pid: process.pid,\n hostname: hostname(),\n cwd: metadata.cwd,\n command: metadata.command,\n startedAt: new Date().toISOString(),\n fetVersion: metadata.fetVersion\n };\n\n let handle;\n try {\n await mkdir(dirname(lockPath), { recursive: true });\n handle = await open(lockPath, \"wx\");\n await handle.writeFile(JSON.stringify(lock, null, 2));\n } catch {\n throw new FetError({\n code: ErrorCode.LockHeld,\n message: \"另一个 FET 写命令正在运行\",\n details: await readExistingLock(lockPath),\n suggestedCommand: \"fet doctor --fix-lock\"\n });\n } finally {\n await handle?.close();\n }\n\n try {\n return await fn();\n } finally {\n await rm(lockPath, { force: true });\n }\n}\n\nasync function readExistingLock(lockPath: string): Promise<unknown> {\n try {\n return JSON.parse(await readFile(lockPath, \"utf8\"));\n } catch {\n return { path: lockPath };\n }\n}\n\nexport async function clearLock(projectRoot: string): Promise<boolean> {\n const lockPath = join(projectRoot, \"openspec\", \".fet.lock\");\n try {\n await rm(lockPath);\n return true;\n } catch {\n return false;\n }\n}\n","import { join } from \"node:path\";\nimport { readFile } from \"node:fs/promises\";\nimport { atomicWrite } from \"./atomic-write.js\";\n\nexport interface JournalStep {\n operation: \"write\" | \"backup\" | \"mkdir\" | \"skip\";\n path: string;\n backupPath?: string | null;\n status: \"done\" | \"failed\" | \"skipped\";\n message?: string;\n}\n\nexport interface InitJournal {\n schemaVersion: 1;\n startedAt: string;\n completedAt: string | null;\n fetVersion: string;\n steps: JournalStep[];\n}\n\nexport function createInitJournal(fetVersion: string): InitJournal {\n return {\n schemaVersion: 1,\n startedAt: new Date().toISOString(),\n completedAt: null,\n fetVersion,\n steps: []\n };\n}\n\nexport async function writeInitJournal(projectRoot: string, journal: InitJournal): Promise<void> {\n await atomicWrite(\n join(projectRoot, \"openspec\", \".fet-init-journal.json\"),\n `${JSON.stringify(journal, null, 2)}\\n`\n );\n}\n\nexport async function readInitJournal(projectRoot: string): Promise<InitJournal | null> {\n try {\n return JSON.parse(await readFile(join(projectRoot, \"openspec\", \".fet-init-journal.json\"), \"utf8\"));\n } catch {\n return null;\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join, parse } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport const FET_VERSION = readPackageVersion();\n\nfunction readPackageVersion(): string {\n let currentDir = dirname(fileURLToPath(import.meta.url));\n const root = parse(currentDir).root;\n\n while (true) {\n const packageJsonPath = join(currentDir, \"package.json\");\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n if (typeof packageJson.version === \"string\" && packageJson.version.length > 0) {\n return packageJson.version;\n }\n throw new Error(`package.json 缺少有效的 version 字段: ${packageJsonPath}`);\n }\n\n if (currentDir === root) {\n throw new Error(\"无法定位 FET package.json\");\n }\n currentDir = dirname(currentDir);\n }\n}\n","export const AUTO_BEGIN = \"<!-- FET:BEGIN AUTO -->\";\nexport const AUTO_END = \"<!-- FET:END AUTO -->\";\nexport const USER_BEGIN = \"<!-- FET:BEGIN USER -->\";\nexport const USER_END = \"<!-- FET:END USER -->\";\n\nexport function hasManagedAutoRegion(content: string): boolean {\n return count(content, AUTO_BEGIN) === 1 && count(content, AUTO_END) === 1 && content.indexOf(AUTO_BEGIN) < content.indexOf(AUTO_END);\n}\n\nexport function hasInvalidManagedAutoRegion(content: string): boolean {\n const beginCount = count(content, AUTO_BEGIN);\n const endCount = count(content, AUTO_END);\n return beginCount !== endCount || beginCount > 1 || endCount > 1 || (beginCount === 1 && content.indexOf(AUTO_BEGIN) > content.indexOf(AUTO_END));\n}\n\nexport function replaceManagedRegion(existing: string | null, generated: string): string {\n if (!existing) {\n return generated;\n }\n\n const start = existing.indexOf(AUTO_BEGIN);\n const end = existing.indexOf(AUTO_END);\n if (start === -1 || end === -1 || end < start) {\n return generated;\n }\n\n const before = existing.slice(0, start);\n const after = existing.slice(end + AUTO_END.length);\n const generatedAuto = extractAuto(generated);\n return `${before}${AUTO_BEGIN}\\n${generatedAuto}\\n${AUTO_END}${after}`;\n}\n\nfunction extractAuto(content: string): string {\n const start = content.indexOf(AUTO_BEGIN);\n const end = content.indexOf(AUTO_END);\n if (start === -1 || end === -1 || end < start) {\n return content.trim();\n }\n return content.slice(start + AUTO_BEGIN.length, end).trim();\n}\n\nfunction count(content: string, needle: string): number {\n return content.split(needle).length - 1;\n}\n","import type { ProjectScanResult } from \"../scanner/index.js\";\nimport { FET_VERSION } from \"../version.js\";\nimport { AUTO_BEGIN, AUTO_END, USER_BEGIN, USER_END } from \"./markers.js\";\n\nexport function renderAgentsMd(scan: ProjectScanResult): string {\n const commands = Object.entries(scan.commands)\n .map(([name, command]) => `| ${name} | \\`${command.command}\\` | ${command.source} |`)\n .join(\"\\n\");\n const routes = scan.routes\n .map((route) => `| ${route.path} | ${route.source} | ${route.confidence}${route.inferred ? \" inferred\" : \"\"} |`)\n .join(\"\\n\");\n const workspaces = scan.project.workspaces.map((workspace) => `| ${workspace.name} | ${workspace.path} | ${workspace.source} |`).join(\"\\n\");\n\n return `# Project Context\n\n${AUTO_BEGIN}\n## Project Snapshot\n\n- Name: ${scan.project.name}\n- Package Manager: ${scan.project.packageManager} (${scan.project.packageManagerConfidence})\n- Framework: ${scan.project.framework.name} (${scan.project.framework.confidence})\n- Language: ${scan.project.language}\n- Monorepo: ${scan.project.monorepo ? \"yes\" : \"no\"}\n\n## Workspaces\n\n| Name | Path | Source |\n|------|------|--------|\n${workspaces || \"| root | . | inferred |\"}\n\n## Commands\n\n| Name | Command | Source |\n|------|---------|--------|\n${commands || \"| [NEEDS LLM INPUT] | [NEEDS LLM INPUT] | [NEEDS LLM INPUT] |\"}\n\n## Structure\n\n[NEEDS LLM INPUT]\n\n## Routes\n\n| Route | Source | Confidence |\n|-------|--------|------------|\n${routes || \"| [NEEDS LLM INPUT] | [NEEDS LLM INPUT] | low |\"}\n\n## Conventions\n\n[NEEDS LLM INPUT]\n\n## Scanner Metadata\n\n- Generated At: ${scan.generatedAt}\n- FET Version: ${FET_VERSION}\n- Scanner Version: ${scan.scannerVersion}\n- Warnings: ${scan.warnings.length ? scan.warnings.join(\"; \") : \"none\"}\n${AUTO_END}\n\n${USER_BEGIN}\n## Notes For AI\n\n[NEEDS LLM INPUT]\n${USER_END}\n`;\n}\n","import { stringify } from \"yaml\";\nimport type { ProjectScanResult } from \"../scanner/index.js\";\nimport { FET_VERSION } from \"../version.js\";\n\nexport function renderFetConfig(scan: ProjectScanResult): string {\n return stringify({\n fet: {\n schemaVersion: 1,\n generatedAt: scan.generatedAt,\n fetVersion: FET_VERSION,\n scannerVersion: scan.scannerVersion,\n project: {\n packageManager: scan.project.packageManager,\n packageManagerConfidence: scan.project.packageManagerConfidence,\n framework: scan.project.framework,\n language: scan.project.language,\n monorepo: scan.project.monorepo,\n workspaces: scan.project.workspaces\n },\n commands: scan.commands,\n validation: {\n monorepo: scan.project.monorepo,\n missing: {\n lint: \"warn\",\n typecheck: \"warn\",\n test: \"warn\"\n },\n workspaces: scan.project.workspaces\n }\n }\n });\n}\n","import { FET_VERSION } from \"../version.js\";\n\nexport function renderVerifyInstructions(changeId: string, generatedAt = new Date().toISOString()): string {\n return `---\nschemaVersion: 1\nfetVersion: ${FET_VERSION}\ngeneratedAt: ${generatedAt}\nchangeId: ${changeId}\npurpose: manual-verify\n---\n\n# Verify Instructions\n\n请按顺序完成以下检查:\n\n1. 运行 OpenSpec 规范校验:\\`openspec verify\\`\n2. 按项目约定运行 lint、typecheck、test。\n3. 检查本次 change 的 \\`tasks.md\\` 是否与实现状态一致。\n\n完成后运行:\n\n\\`\\`\\`sh\nfet verify --done --change ${changeId}\n\\`\\`\\`\n`;\n}\n","const BEGIN = \"# FET:BEGIN LOCAL STATE\";\nconst END = \"# FET:END LOCAL STATE\";\n\nconst RULES = [\n \"openspec/fet-state.json\",\n \"openspec/.fet.lock\",\n \"openspec/.fet-init-journal.json\",\n \"openspec/changes/*/fet-state.json\",\n \"openspec/changes/*/.fet/\"\n];\n\nexport function mergeGitignore(existing: string | null): string {\n const block = `${BEGIN}\\n${RULES.join(\"\\n\")}\\n${END}`;\n if (!existing || !existing.trim()) {\n return `${block}\\n`;\n }\n\n const start = existing.indexOf(BEGIN);\n const end = existing.indexOf(END);\n if (start !== -1 && end !== -1 && end > start) {\n return `${existing.slice(0, start)}${block}${existing.slice(end + END.length)}`;\n }\n\n return `${existing.replace(/\\s*$/, \"\")}\\n\\n${block}\\n`;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { mergeFetConfig } from \"../config/index.js\";\nimport { atomicWrite, createBackup, withProjectLock } from \"../fs/index.js\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport { hasInvalidManagedAutoRegion, hasManagedAutoRegion, renderAgentsMd, renderFetConfig, replaceManagedRegion } from \"../templates/index.js\";\nimport type { FetCommandContext } from \"../cli/context.js\";\n\nexport async function updateContextCommand(ctx: FetCommandContext): Promise<void> {\n await withProjectLock(\n ctx.projectRoot,\n { command: \"update-context\", cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => updateContextFiles(ctx)\n );\n\n ctx.output.result({\n ok: true,\n command: \"update-context\",\n summary: \"已更新 AGENTS.md 与 openspec/config.yaml 的 FET 托管区域。\"\n });\n}\n\nexport async function updateContextFiles(ctx: FetCommandContext): Promise<{ warnings: string[] }> {\n const scan = await ctx.scanner.scan(ctx.projectRoot, {});\n const agentsPath = join(ctx.projectRoot, \"AGENTS.md\");\n const configPath = join(ctx.projectRoot, \"openspec\", \"config.yaml\");\n\n const existingAgents = await readOptional(agentsPath);\n const warnings = [...scan.warnings];\n if (existingAgents && hasInvalidManagedAutoRegion(existingAgents)) {\n throw new FetError({\n code: ErrorCode.ConfigInvalid,\n message: \"AGENTS.md 的 FET 托管标记损坏或重复\",\n details: { path: \"AGENTS.md\" },\n suggestedCommand: \"手动修复 FET:BEGIN AUTO / FET:END AUTO 标记后重试\"\n });\n }\n if (existingAgents && !hasManagedAutoRegion(existingAgents)) {\n if (!ctx.yes) {\n throw new FetError({\n code: ErrorCode.ToolAdapterConflict,\n message: \"AGENTS.md 已存在且不包含 FET 托管区域\",\n details: { path: \"AGENTS.md\" },\n suggestedCommand:\n ctx.command === \"init\"\n ? \"确认可备份并替换后运行 fet init --yes\"\n : \"确认可备份并替换后运行 fet update-context --yes\"\n });\n }\n const backupPath = await createBackup(agentsPath);\n if (backupPath) {\n warnings.push(`已备份非托管 AGENTS.md 到 ${backupPath}`);\n }\n }\n await atomicWrite(agentsPath, replaceManagedRegion(existingAgents, renderAgentsMd(scan)));\n await atomicWrite(configPath, await mergeFetConfig(configPath, renderFetConfig(scan)));\n\n const state = await ctx.stateStore.getOrCreateGlobal();\n state.context = {\n agentsMdUpdatedAt: scan.generatedAt,\n configUpdatedAt: scan.generatedAt,\n scannerVersion: scan.scannerVersion\n };\n await ctx.stateStore.writeGlobal(state);\n\n return { warnings };\n}\n\nasync function readOptional(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { parseDocument } from \"yaml\";\n\nexport async function mergeFetConfig(configPath: string, renderedFetYaml: string): Promise<string> {\n const fetDoc = parseDocument(renderedFetYaml);\n const nextFet = fetDoc.get(\"fet\", true);\n\n let existing = \"\";\n try {\n existing = await readFile(configPath, \"utf8\");\n } catch {\n return renderedFetYaml;\n }\n\n const doc = parseDocument(existing || \"{}\");\n doc.set(\"fet\", nextFet);\n return doc.toString();\n}\n","import { stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { FetCommandContext } from \"../cli/context.js\";\nimport { clearLock } from \"../fs/index.js\";\nimport type { DoctorCheck } from \"../adapters/index.js\";\n\nexport async function doctorCommand(ctx: FetCommandContext, options: { fixLock?: boolean } = {}): Promise<void> {\n const checks: DoctorCheck[] = [];\n\n checks.push(await checkOpenSpec(ctx));\n checks.push(await checkState(ctx));\n checks.push(await checkFile(\"agents\", join(ctx.projectRoot, \"AGENTS.md\"), \"AGENTS.md 缺失\", \"fet update-context\"));\n checks.push(await checkFile(\"config\", join(ctx.projectRoot, \"openspec\", \"config.yaml\"), \"openspec/config.yaml 缺失\", \"fet init\"));\n\n for (const adapter of ctx.toolAdapters) {\n checks.push(...(await adapter.doctor(ctx.projectRoot)));\n }\n\n const lockPath = join(ctx.projectRoot, \"openspec\", \".fet.lock\");\n if (await exists(lockPath)) {\n if (options.fixLock) {\n await clearLock(ctx.projectRoot);\n checks.push({ id: \"lock\", status: \"pass\", message: \"已清理 openspec/.fet.lock\" });\n } else {\n checks.push({ id: \"lock\", status: \"warn\", message: \"存在 openspec/.fet.lock\", suggestedCommand: \"fet doctor --fix-lock\" });\n }\n }\n\n const warnings = checks.filter((check) => check.status !== \"pass\").map((check) => check.message);\n ctx.output.result({\n ok: true,\n command: \"doctor\",\n summary: warnings.length ? `诊断完成,发现 ${warnings.length} 个需要关注的问题。` : \"诊断完成,未发现明显问题。\",\n warnings,\n data: checks\n });\n}\n\nasync function checkOpenSpec(ctx: FetCommandContext): Promise<DoctorCheck> {\n try {\n const identity = await ctx.openSpec.resolveExecutable();\n return { id: \"openspec\", status: \"pass\", message: `OpenSpec: ${identity.executablePath} (${identity.version})` };\n } catch (error) {\n return { id: \"openspec\", status: \"fail\", message: error instanceof Error ? error.message : \"OpenSpec 检测失败\" };\n }\n}\n\nasync function checkState(ctx: FetCommandContext): Promise<DoctorCheck> {\n try {\n const state = await ctx.stateStore.readGlobal();\n return state\n ? { id: \"state\", status: \"pass\", message: \"FET 全局状态可读取\" }\n : { id: \"state\", status: \"warn\", message: \"FET 全局状态尚未初始化\", suggestedCommand: \"fet init\" };\n } catch (error) {\n return { id: \"state\", status: \"fail\", message: error instanceof Error ? error.message : \"FET 状态读取失败\" };\n }\n}\n\nasync function checkFile(id: string, path: string, missing: string, suggestedCommand: string): Promise<DoctorCheck> {\n return (await exists(path))\n ? { id, status: \"pass\", message: `${id} 存在` }\n : { id, status: \"warn\", message: missing, suggestedCommand };\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { ProjectIdentity } from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function detectProjectIdentity(projectRoot: string): Promise<ProjectIdentity> {\n const [gitRoot, branch, headCommit] = await Promise.all([\n git(projectRoot, [\"rev-parse\", \"--show-toplevel\"]),\n git(projectRoot, [\"branch\", \"--show-current\"]),\n git(projectRoot, [\"rev-parse\", \"HEAD\"])\n ]);\n\n return {\n gitRoot,\n worktreePath: projectRoot,\n branch,\n headCommit\n };\n}\n\nasync function git(cwd: string, args: string[]): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n}\n","import { mkdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { atomicWrite } from \"../fs/atomic-write.js\";\nimport { assertChangeState, assertGlobalState, createChangeState, createGlobalState } from \"./schema.js\";\nimport type { ChangePhase, ChangeState, GlobalState, ProjectIdentity } from \"./types.js\";\n\nexport class StateStore {\n constructor(\n private readonly projectRoot: string,\n private readonly fetVersion: string,\n private readonly project: ProjectIdentity\n ) {}\n\n async readGlobal(): Promise<GlobalState | null> {\n try {\n const value = JSON.parse(await readFile(this.globalPath(), \"utf8\"));\n assertGlobalState(value);\n return value;\n } catch (error) {\n if (isNotFound(error)) {\n return null;\n }\n throw error;\n }\n }\n\n async getOrCreateGlobal(): Promise<GlobalState> {\n return (await this.readGlobal()) ?? createGlobalState(this.fetVersion, this.project);\n }\n\n async writeGlobal(state: GlobalState): Promise<void> {\n state.updatedAt = new Date().toISOString();\n await mkdir(join(this.projectRoot, \"openspec\"), { recursive: true });\n await atomicWrite(this.globalPath(), `${JSON.stringify(state, null, 2)}\\n`);\n }\n\n async readChange(changeId: string): Promise<ChangeState | null> {\n try {\n const value = JSON.parse(await readFile(this.changePath(changeId), \"utf8\"));\n assertChangeState(value);\n return value;\n } catch (error) {\n if (isNotFound(error)) {\n return null;\n }\n throw error;\n }\n }\n\n async getOrCreateChange(changeId: string, phase: ChangePhase): Promise<ChangeState> {\n return (await this.readChange(changeId)) ?? createChangeState(this.fetVersion, changeId, phase);\n }\n\n async writeChange(state: ChangeState): Promise<void> {\n state.updatedAt = new Date().toISOString();\n await mkdir(join(this.projectRoot, \"openspec\", \"changes\", state.changeId), { recursive: true });\n await atomicWrite(this.changePath(state.changeId), `${JSON.stringify(state, null, 2)}\\n`);\n }\n\n private globalPath(): string {\n return join(this.projectRoot, \"openspec\", \"fet-state.json\");\n }\n\n private changePath(changeId: string): string {\n return join(this.projectRoot, \"openspec\", \"changes\", changeId, \"fet-state.json\");\n }\n}\n\nfunction isNotFound(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\";\n}\n","import { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport type { ChangePhase, ChangeState, GlobalState, ProjectIdentity } from \"./types.js\";\n\nconst phases: ChangePhase[] = [\"explore\", \"propose\", \"implement\", \"verify\", \"sync\", \"archive\"];\n\nexport function createGlobalState(fetVersion: string, project: ProjectIdentity): GlobalState {\n const now = new Date().toISOString();\n return {\n schemaVersion: 1,\n fetVersion,\n createdAt: now,\n updatedAt: now,\n project,\n openspec: null,\n activeChangeId: null,\n openChangeIds: [],\n context: {\n agentsMdUpdatedAt: null,\n configUpdatedAt: null,\n scannerVersion: 1\n },\n toolAdapters: {},\n verifyAuthorization: null,\n lastDoctor: null\n };\n}\n\nexport function createChangeState(fetVersion: string, changeId: string, phase: ChangePhase): ChangeState {\n const now = new Date().toISOString();\n return {\n schemaVersion: 1,\n fetVersion,\n changeId,\n createdAt: now,\n updatedAt: now,\n currentPhase: phase,\n phases: Object.fromEntries(\n phases.map((item) => [item, { status: item === phase ? \"in_progress\" : \"not_started\" }])\n ) as ChangeState[\"phases\"],\n tasks: {\n source: \"tasks.md\",\n completedIds: [],\n lastSyncedAt: null\n },\n manualVerify: null,\n lastOpenSpecCommand: null,\n warnings: []\n };\n}\n\nexport function assertGlobalState(value: unknown): asserts value is GlobalState {\n if (!isRecord(value) || value.schemaVersion !== 1) {\n throw unsupportedSchema(\"全局状态 schema 不受支持\");\n }\n if (typeof value.fetVersion !== \"string\" || !isRecord(value.project)) {\n throw corruptedState(\"全局状态缺少必填字段\");\n }\n}\n\nexport function assertChangeState(value: unknown): asserts value is ChangeState {\n if (!isRecord(value) || value.schemaVersion !== 1) {\n throw unsupportedSchema(\"变更状态 schema 不受支持\");\n }\n if (typeof value.fetVersion !== \"string\" || typeof value.changeId !== \"string\") {\n throw corruptedState(\"变更状态缺少必填字段\");\n }\n}\n\nfunction unsupportedSchema(message: string): FetError {\n return new FetError({\n code: ErrorCode.StateSchemaUnsupported,\n message,\n suggestedCommand: \"npm update -g @nick848/fet\"\n });\n}\n\nfunction corruptedState(message: string): FetError {\n return new FetError({\n code: ErrorCode.StateCorrupted,\n message,\n suggestedCommand: \"fet doctor --fix\"\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { readFile } from \"node:fs/promises\";\n\nexport async function readCompletedTaskIds(tasksPath: string): Promise<string[]> {\n let content: string;\n try {\n content = await readFile(tasksPath, \"utf8\");\n } catch {\n return [];\n }\n\n const completed: string[] = [];\n const pattern = /^\\s*[-*]\\s+\\[[xX]\\]\\s+([0-9]+(?:\\.[0-9]+)*)/gm;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(content))) {\n if (match[1]) {\n completed.push(match[1]);\n }\n }\n return completed;\n}\n","import { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport { withProjectLock } from \"../fs/index.js\";\nimport { readCompletedTaskIds, type ChangePhase } from \"../state/index.js\";\nimport type { FetCommandContext } from \"../cli/context.js\";\n\nconst phaseByCommand: Record<string, ChangePhase> = {\n explore: \"explore\",\n propose: \"propose\",\n new: \"propose\",\n continue: \"propose\",\n ff: \"propose\",\n apply: \"implement\",\n verify: \"verify\",\n sync: \"sync\",\n archive: \"archive\",\n \"bulk-archive\": \"archive\",\n onboard: \"explore\"\n};\n\nexport async function proxyCommand(ctx: FetCommandContext, command: string, args: string[]): Promise<void> {\n const openSpecArgs = stripFetOptions(args);\n await withProjectLock(\n ctx.projectRoot,\n { command, cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => {\n if ([\"sync\", \"archive\", \"bulk-archive\"].includes(command)) {\n await assertVerified(ctx);\n }\n\n const mapped = await mapOpenSpecCommand(ctx, command, openSpecArgs);\n const result = await ctx.openSpec.run(mapped.command, mapped.args, { cwd: ctx.projectRoot, stdio: ctx.json ? \"pipe\" : \"inherit\" });\n if (result.exitCode !== 0) {\n throw new FetError({\n code: ErrorCode.OpenSpecCommandFailed,\n message: `OpenSpec ${command} 执行失败`,\n details: result,\n recoverable: true\n });\n }\n\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n const state = await ctx.stateStore.getOrCreateGlobal();\n state.openChangeIds = inspection.changes;\n if (ctx.changeId && inspection.changes.includes(ctx.changeId)) {\n state.activeChangeId = ctx.changeId;\n } else if (state.activeChangeId && !inspection.changes.includes(state.activeChangeId)) {\n state.activeChangeId = inspection.changes.length === 1 ? (inspection.changes[0] ?? null) : null;\n } else if (!state.activeChangeId && inspection.changes.length === 1) {\n state.activeChangeId = inspection.changes[0] ?? null;\n }\n await ctx.stateStore.writeGlobal(state);\n\n const changeId = ctx.changeId ?? state.activeChangeId;\n if (changeId && inspection.changes.includes(changeId)) {\n const changeInspection = await ctx.openSpec.inspectChange(ctx.projectRoot, changeId);\n const changeState = await ctx.stateStore.getOrCreateChange(changeId, phaseByCommand[command] ?? \"propose\");\n changeState.currentPhase = phaseByCommand[command] ?? changeState.currentPhase;\n changeState.phases[changeState.currentPhase] = {\n status: \"done\",\n updatedAt: new Date().toISOString()\n };\n changeState.lastOpenSpecCommand = {\n command: mapped.command,\n args: mapped.args,\n exitCode: result.exitCode,\n ranAt: new Date().toISOString()\n };\n changeState.tasks.completedIds = await readCompletedTaskIds(changeInspection.tasksPath);\n changeState.tasks.lastSyncedAt = new Date().toISOString();\n await ctx.stateStore.writeChange(changeState);\n }\n }\n );\n\n ctx.output.result({\n ok: true,\n command,\n summary: `fet ${command} 完成。`\n });\n}\n\nexport async function passthroughCommand(ctx: FetCommandContext, command: string, args: string[]): Promise<void> {\n const result = await ctx.openSpec.run(command, stripFetOptions(args), { cwd: ctx.projectRoot, stdio: ctx.json ? \"pipe\" : \"inherit\" });\n if (result.exitCode !== 0) {\n throw new FetError({\n code: ErrorCode.OpenSpecCommandFailed,\n message: `OpenSpec ${command} 执行失败`,\n details: result\n });\n }\n}\n\nfunction stripFetOptions(args: string[]): string[] {\n const result: string[] = [];\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg === \"--cwd\" || arg === \"--change\") {\n index += 1;\n continue;\n }\n if (arg?.startsWith(\"--cwd=\") || arg?.startsWith(\"--change=\")) {\n continue;\n }\n if (arg === \"--yes\" || arg === \"--json\" || arg === \"--verbose\" || arg === \"--no-color\") {\n continue;\n }\n if (arg) {\n result.push(arg);\n }\n }\n return result;\n}\n\nasync function mapOpenSpecCommand(\n ctx: FetCommandContext,\n command: string,\n args: string[]\n): Promise<{ command: string; args: string[] }> {\n switch (command) {\n case \"propose\":\n case \"new\":\n return { command: \"new\", args: args[0] === \"change\" ? args : [\"change\", ...args] };\n case \"continue\":\n return { command: \"instructions\", args: [...withoutUndefined(args[0] ? [args[0]] : [\"proposal\"]), \"--change\", await requireChangeId(ctx)] };\n case \"ff\":\n return { command: \"status\", args: [\"--change\", await requireChangeId(ctx)] };\n case \"apply\":\n return { command: \"instructions\", args: [\"apply\", \"--change\", await requireChangeId(ctx)] };\n case \"sync\":\n return { command: \"validate\", args: [ctx.changeId ?? args[0] ?? (await requireChangeId(ctx)), \"--type\", \"change\", \"--strict\"] };\n case \"archive\":\n return { command: \"archive\", args: [ctx.changeId ?? args[0] ?? (await requireChangeId(ctx)), ...args.slice(ctx.changeId ? 0 : 1)] };\n case \"bulk-archive\":\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"OpenSpec 1.2.0 不提供 bulk-archive 顶层命令\",\n suggestedCommand: \"逐个执行 fet archive --change <change-id>\"\n });\n case \"explore\":\n return { command: \"instructions\", args: [\"proposal\", \"--change\", await requireChangeId(ctx)] };\n case \"onboard\":\n return { command: \"instructions\", args: [] };\n default:\n return { command, args };\n }\n}\n\nasync function requireChangeId(ctx: FetCommandContext): Promise<string> {\n if (ctx.changeId) {\n return ctx.changeId;\n }\n const state = await ctx.stateStore.getOrCreateGlobal();\n if (state.activeChangeId) {\n return state.activeChangeId;\n }\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n if (inspection.changes.length === 1 && inspection.changes[0]) {\n return inspection.changes[0];\n }\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"该命令需要明确的 change\",\n details: { openChangeIds: inspection.changes },\n suggestedCommand: \"添加 --change <change-id>\"\n });\n}\n\nfunction withoutUndefined(values: string[]): string[] {\n return values.filter(Boolean);\n}\n\nasync function assertVerified(ctx: FetCommandContext): Promise<void> {\n const global = await ctx.stateStore.getOrCreateGlobal();\n const changeId = ctx.changeId ?? global.activeChangeId;\n if (!changeId) {\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"未指定 change,无法检查 verify 状态\",\n suggestedCommand: \"fet verify --done --change <change-id>\"\n });\n }\n const change = await ctx.stateStore.readChange(changeId);\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n if (!inspection.changes.includes(changeId)) {\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"指定的 change 不存在或已归档\",\n details: { changeId, openChangeIds: inspection.changes },\n suggestedCommand: \"fet doctor\"\n });\n }\n if (change?.manualVerify?.status !== \"declared_done\") {\n throw new FetError({\n code: ErrorCode.StateCorrupted,\n message: \"当前 change 尚未通过 FET verify\",\n details: { changeId },\n suggestedCommand: `fet verify --change ${changeId}`\n });\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { FetCommandContext } from \"../cli/context.js\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport { atomicWrite, withProjectLock } from \"../fs/index.js\";\nimport { renderVerifyInstructions } from \"../templates/index.js\";\n\nexport async function verifyCommand(ctx: FetCommandContext, options: { done?: boolean; auto?: boolean }): Promise<void> {\n if (options.auto) {\n const scan = await ctx.scanner.scan(ctx.projectRoot, {});\n const plan = {\n schemaVersion: 1,\n packageManager: scan.project.packageManager,\n workspaces: [\n {\n name: \"root\",\n cwd: \".\",\n commands: Object.entries(scan.commands)\n .filter(([name]) => [\"lint\", \"typecheck\", \"test\"].includes(name))\n .map(([dimension, command]) => ({\n dimension,\n command: command.command,\n source: command.source,\n required: command.required,\n statusIfMissing: command.required ? \"fail\" : \"warn\"\n }))\n }\n ],\n missing: [\"lint\", \"typecheck\", \"test\"].filter((name) => !scan.commands[name])\n };\n if (ctx.yes) {\n const global = await ctx.stateStore.getOrCreateGlobal();\n global.verifyAuthorization = {\n schemaVersion: 1,\n approvedAt: new Date().toISOString(),\n commandFingerprint: fingerprint(plan),\n packageManager: plan.packageManager,\n plan: plan.workspaces.flatMap((workspace) =>\n workspace.commands.map((command) => ({\n cwd: workspace.cwd,\n dimension: command.dimension,\n command: command.command,\n source: command.source,\n required: command.required\n }))\n )\n };\n await ctx.stateStore.writeGlobal(global);\n }\n\n ctx.output.result({\n ok: true,\n command: \"verify\",\n summary: ctx.yes ? \"已确认 verify --auto 执行计划;MVP 暂不执行仓库脚本。\" : \"已生成 verify --auto 执行计划;MVP 暂不执行仓库脚本。\",\n warnings: plan.missing.map((name) => `未发现 ${name} 脚本,将在自动执行版本中按配置处理。`),\n data: plan,\n nextSteps: ctx.yes ? [\"当前版本请运行 fet verify 进入手动验证模式\"] : [\"审核执行计划\", \"确认计划后可运行 fet verify --auto --yes\", \"当前版本请运行 fet verify 进入手动验证模式\"]\n });\n return;\n }\n\n await withProjectLock(\n ctx.projectRoot,\n { command: \"verify\", cwd: ctx.cwd, fetVersion: ctx.fetVersion },\n async () => {\n const changeId = await resolveChangeId(ctx);\n if (options.done) {\n await markDone(ctx, changeId);\n } else {\n await writeInstructions(ctx, changeId);\n }\n }\n );\n}\n\nasync function writeInstructions(ctx: FetCommandContext, changeId: string): Promise<void> {\n await assertChangeExists(ctx, changeId);\n const generatedAt = new Date().toISOString();\n const dir = join(ctx.projectRoot, \"openspec\", \"changes\", changeId, \".fet\");\n const instructionsPath = join(dir, \"verify-instructions.md\");\n await mkdir(dir, { recursive: true });\n await atomicWrite(instructionsPath, renderVerifyInstructions(changeId, generatedAt));\n\n const state = await ctx.stateStore.getOrCreateChange(changeId, \"verify\");\n state.currentPhase = \"verify\";\n state.phases.verify = { status: \"in_progress\", updatedAt: generatedAt };\n await ctx.stateStore.writeChange(state);\n\n ctx.output.result({\n ok: true,\n command: \"verify\",\n summary: \"已生成手动验证指令。\",\n nextSteps: [`阅读 openspec/changes/${changeId}/.fet/verify-instructions.md`, `完成后运行 fet verify --done --change ${changeId}`]\n });\n}\n\nasync function markDone(ctx: FetCommandContext, changeId: string): Promise<void> {\n await assertChangeExists(ctx, changeId);\n const declaredAt = new Date().toISOString();\n const instructionsPath = join(ctx.projectRoot, \"openspec\", \"changes\", changeId, \".fet\", \"verify-instructions.md\");\n const instructions = await readInstructions(instructionsPath, changeId);\n const instructionsGeneratedAt = readFrontMatterValue(instructions, \"generatedAt\") ?? declaredAt;\n const state = await ctx.stateStore.getOrCreateChange(changeId, \"verify\");\n state.currentPhase = \"verify\";\n state.phases.verify = { status: \"done\", updatedAt: declaredAt };\n state.manualVerify = {\n mode: \"manual\",\n status: \"declared_done\",\n declaredAt,\n instructionsPath: `openspec/changes/${changeId}/.fet/verify-instructions.md`,\n instructionsGeneratedAt,\n evidence: null\n };\n await ctx.stateStore.writeChange(state);\n\n ctx.output.result({\n ok: true,\n command: \"verify\",\n summary: \"已记录手动验证完成声明。\",\n nextSteps: [`fet sync --change ${changeId}`, `fet archive --change ${changeId}`]\n });\n}\n\nasync function assertChangeExists(ctx: FetCommandContext, changeId: string): Promise<void> {\n const inspection = await ctx.openSpec.inspectChange(ctx.projectRoot, changeId);\n if (!inspection.exists) {\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"指定的 change 不存在\",\n details: { changeId },\n suggestedCommand: \"fet verify --change <change-id>\"\n });\n }\n}\n\nasync function readInstructions(path: string, changeId: string): Promise<string> {\n try {\n await stat(path);\n const content = await readFile(path, \"utf8\");\n const fileChangeId = readFrontMatterValue(content, \"changeId\");\n if (fileChangeId !== changeId) {\n throw new FetError({\n code: ErrorCode.StateCorrupted,\n message: \"验证指令文件与当前 change 不匹配\",\n details: { expected: changeId, actual: fileChangeId },\n suggestedCommand: `fet verify --change ${changeId}`\n });\n }\n return content;\n } catch (error) {\n if (error instanceof FetError) {\n throw error;\n }\n throw new FetError({\n code: ErrorCode.StateCorrupted,\n message: \"验证指令文件不存在或无法读取\",\n details: { path },\n suggestedCommand: `fet verify --change ${changeId}`\n });\n }\n}\n\nfunction readFrontMatterValue(content: string, key: string): string | null {\n const match = content.match(new RegExp(`^${key}:\\\\s*(.+)$`, \"m\"));\n return match?.[1]?.trim() ?? null;\n}\n\nfunction fingerprint(value: unknown): string {\n return `sha256:${createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\")}`;\n}\n\nasync function resolveChangeId(ctx: FetCommandContext): Promise<string> {\n if (ctx.changeId) {\n return ctx.changeId;\n }\n\n const global = await ctx.stateStore.getOrCreateGlobal();\n if (global.activeChangeId) {\n return global.activeChangeId;\n }\n\n const inspection = await ctx.openSpec.inspectProject(ctx.projectRoot);\n if (inspection.changes.length === 1 && inspection.changes[0]) {\n return inspection.changes[0];\n }\n\n throw new FetError({\n code: ErrorCode.InvalidArguments,\n message: \"无法确定要验证的 change\",\n details: { openChangeIds: inspection.changes },\n suggestedCommand: \"fet verify --change <change-id>\"\n });\n}\n","import { resolve } from \"node:path\";\nimport { CursorAdapter } from \"../adapters/index.js\";\nimport { DefaultOpenSpecAdapter } from \"../openspec/index.js\";\nimport { ProjectScanner } from \"../scanner/index.js\";\nimport { detectProjectIdentity, StateStore } from \"../state/index.js\";\nimport { FET_VERSION } from \"../version.js\";\nimport { OutputWriter } from \"./output.js\";\n\nexport interface GlobalOptions {\n cwd?: string;\n json?: boolean;\n verbose?: boolean;\n yes?: boolean;\n change?: string;\n}\n\nexport async function createCommandContext(command: string, options: GlobalOptions) {\n const projectRoot = resolve(options.cwd ?? process.cwd());\n const project = await detectProjectIdentity(projectRoot);\n const output = new OutputWriter(Boolean(options.json));\n\n return {\n command,\n cwd: projectRoot,\n projectRoot,\n isTty: Boolean(process.stdout.isTTY),\n json: Boolean(options.json),\n verbose: Boolean(options.verbose),\n yes: Boolean(options.yes),\n changeId: options.change,\n fetVersion: FET_VERSION,\n output,\n stateStore: new StateStore(projectRoot, FET_VERSION, project),\n openSpec: new DefaultOpenSpecAdapter(),\n scanner: new ProjectScanner(),\n toolAdapters: [new CursorAdapter()]\n };\n}\n\nexport type FetCommandContext = Awaited<ReturnType<typeof createCommandContext>>;\n","import { mkdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { ErrorCode } from \"../../errors/codes.js\";\nimport { FetError } from \"../../errors/fet-error.js\";\nimport { atomicWrite } from \"../../fs/atomic-write.js\";\nimport { createBackup } from \"../../fs/backup.js\";\nimport type { DoctorCheck, ToolAdapter, ToolInstallPlan, ToolInstallResult } from \"../types.js\";\nimport { cursorRuleFile, cursorSkillFiles } from \"./templates.js\";\n\nexport class CursorAdapter implements ToolAdapter {\n readonly tool = \"cursor\";\n readonly adapterVersion = 1;\n\n async detect(projectRoot: string) {\n return {\n detected: await exists(join(projectRoot, \".cursor\")),\n reason: \"Cursor adapter is available for any project\"\n };\n }\n\n async planInstall(_projectRoot: string): Promise<ToolInstallPlan> {\n return {\n tool: this.tool,\n files: [...cursorSkillFiles(), cursorRuleFile()].map((file) => ({\n ...file,\n managed: true\n }))\n };\n }\n\n async install(projectRoot: string, plan: ToolInstallPlan, force = false): Promise<ToolInstallResult> {\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const file of plan.files) {\n const target = join(projectRoot, file.path);\n const existing = await readExisting(target);\n if (existing && !existing.includes(\"FET:MANAGED\") && !force) {\n throw new FetError({\n code: ErrorCode.ToolAdapterConflict,\n message: \"Cursor 配置文件已存在且不归 FET 管理\",\n details: { path: file.path },\n suggestedCommand: \"fet init --yes\"\n });\n }\n if (existing && !existing.includes(\"FET:MANAGED\") && force) {\n await createBackup(target);\n }\n await mkdir(dirname(target), { recursive: true });\n await atomicWrite(target, file.content);\n written.push(file.path);\n }\n\n return { tool: this.tool, written, skipped };\n }\n\n async doctor(projectRoot: string): Promise<DoctorCheck[]> {\n const plan = await this.planInstall(projectRoot);\n const checks: DoctorCheck[] = [];\n for (const file of plan.files) {\n const target = join(projectRoot, file.path);\n const content = await readExisting(target);\n const managed = Boolean(content?.includes(\"FET:MANAGED\"));\n const versionMatches = Boolean(content?.includes(`adapterVersion: ${this.adapterVersion}`));\n checks.push({\n id: `cursor:${file.path}`,\n status: !content ? \"warn\" : managed && versionMatches ? \"pass\" : \"warn\",\n message: !content\n ? `${file.path} 缺失`\n : !managed\n ? `${file.path} 存在但不归 FET 管理`\n : !versionMatches\n ? `${file.path} adapterVersion 已过期`\n : `${file.path} 存在且版本匹配`,\n suggestedCommand: !content || !managed || !versionMatches ? \"fet init\" : undefined\n });\n }\n return checks;\n }\n}\n\nasync function readExisting(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { FET_VERSION } from \"../../version.js\";\n\nconst commands = [\n \"explore\",\n \"propose\",\n \"new\",\n \"continue\",\n \"ff\",\n \"apply\",\n \"verify\",\n \"sync\",\n \"archive\",\n \"bulk-archive\",\n \"onboard\"\n];\n\nexport function cursorSkillFiles(): Array<{ path: string; content: string }> {\n return commands.map((command) => ({\n path: `.cursor/skills/fet-${command}/SKILL.md`,\n content: renderSkill(command)\n }));\n}\n\nexport function cursorRuleFile(): { path: string; content: string } {\n return {\n path: \".cursor/rules/fet-context.mdc\",\n content: `<!-- FET:MANAGED\nschemaVersion: 1\nfetVersion: ${FET_VERSION}\ngenerator: cursor-adapter\nadapterVersion: 1\nFET:END -->\n\n---\ndescription: Load FET project context for implementation tasks\nalwaysApply: false\n---\n\n当用户请求修改项目、实现 OpenSpec change、运行 FET 工作流或解释项目结构时,优先阅读:\n\n- AGENTS.md\n- openspec/config.yaml\n- 当前 change 目录下的 OpenSpec 规划产物\n\n如果用户输入类似 \\`/fet apply\\` 的请求,Cursor 当前版本未必会把本文件注册为原生 slash command。此时请把它当作工作流意图,并提示用户在终端执行对应的 \\`fet <cmd>\\` 命令。\n`\n };\n}\n\nfunction renderSkill(command: string): string {\n return `<!-- FET:MANAGED\nschemaVersion: 1\nfetVersion: ${FET_VERSION}\ngenerator: cursor-adapter\nadapterVersion: 1\ncommand: fet ${command}\nFET:END -->\n\n---\nname: fet-${command}\ndescription: Run FET-managed OpenSpec ${command} workflow from the terminal\ndisable-model-invocation: true\n---\n\n注意:此文件采用 Cursor Skill 目录结构。它提供 \\`/fet-${command}\\` 风格的工作流说明,不承诺注册 \\`/fet ${command}\\` 这种带空格的原生 slash command。\n\n请在终端中执行:\n\n\\`\\`\\`sh\nfet ${command}\n\\`\\`\\`\n\n执行前请确认已阅读 AGENTS.md 与 openspec/config.yaml。\n`;\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { OpenSpecIdentity } from \"../state/types.js\";\nimport { inspectOpenSpecChange, inspectOpenSpecProject } from \"./inspector.js\";\nimport { resolveOpenSpecExecutable } from \"./resolver.js\";\nimport { runOpenSpec } from \"./runner.js\";\nimport type {\n OpenSpecAdapter,\n OpenSpecCapabilities,\n OpenSpecChangeInspection,\n OpenSpecProjectInspection,\n OpenSpecRunOptions,\n OpenSpecRunResult\n} from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport class DefaultOpenSpecAdapter implements OpenSpecAdapter {\n private identity?: OpenSpecIdentity;\n\n async resolveExecutable(): Promise<OpenSpecIdentity> {\n this.identity ??= await resolveOpenSpecExecutable();\n return this.identity;\n }\n\n async getCapabilities(): Promise<OpenSpecCapabilities> {\n const identity = await this.resolveExecutable();\n const executable = identity.executablePath === \"npx openspec\" ? \"npx\" : identity.executablePath;\n const args = identity.executablePath === \"npx openspec\" ? [\"openspec\", \"--help\"] : [\"--help\"];\n\n try {\n const { stdout } = await execFileAsync(executable, args, { shell: process.platform === \"win32\" });\n return {\n version: identity.version,\n commands: parseCommands(stdout),\n supported: true\n };\n } catch {\n return {\n version: identity.version,\n commands: [],\n supported: false\n };\n }\n }\n\n async run(command: string, args: string[], options: OpenSpecRunOptions): Promise<OpenSpecRunResult> {\n const identity = await this.resolveExecutable();\n return runOpenSpec(identity.executablePath, command, args, options);\n }\n\n inspectProject(projectRoot: string): Promise<OpenSpecProjectInspection> {\n return inspectOpenSpecProject(projectRoot);\n }\n\n inspectChange(projectRoot: string, changeId: string): Promise<OpenSpecChangeInspection> {\n return inspectOpenSpecChange(projectRoot, changeId);\n }\n}\n\nfunction parseCommands(help: string): string[] {\n const known = [\n \"init\",\n \"explore\",\n \"propose\",\n \"new\",\n \"continue\",\n \"ff\",\n \"apply\",\n \"verify\",\n \"sync\",\n \"archive\",\n \"bulk-archive\",\n \"onboard\"\n ];\n return known.filter((command) => help.includes(command));\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { OpenSpecChangeInspection, OpenSpecProjectInspection } from \"./types.js\";\n\nexport async function inspectOpenSpecProject(projectRoot: string): Promise<OpenSpecProjectInspection> {\n const openspecPath = join(projectRoot, \"openspec\");\n const changesPath = join(openspecPath, \"changes\");\n const archivePath = join(openspecPath, \"archive\");\n\n return {\n exists: await exists(openspecPath),\n changes: await listDirectories(changesPath),\n archived: await listDirectories(archivePath)\n };\n}\n\nexport async function inspectOpenSpecChange(\n projectRoot: string,\n changeId: string\n): Promise<OpenSpecChangeInspection> {\n const changePath = join(projectRoot, \"openspec\", \"changes\", changeId);\n const tasksPath = join(changePath, \"tasks.md\");\n const specsPath = join(changePath, \"specs\");\n\n return {\n changeId,\n exists: await exists(changePath),\n hasProposal: await exists(join(changePath, \"proposal.md\")),\n hasTasks: await exists(tasksPath),\n hasSpecs: await exists(specsPath),\n tasksPath,\n changePath\n };\n}\n\nasync function listDirectories(path: string): Promise<string[]> {\n try {\n const entries = await readdir(path, { withFileTypes: true });\n return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);\n } catch {\n return [];\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport type { OpenSpecIdentity } from \"../state/types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport async function resolveOpenSpecExecutable(): Promise<OpenSpecIdentity> {\n const executablePath = await findExecutable();\n const version = await readVersion(executablePath);\n return {\n executablePath,\n version,\n adapterVersion: 1\n };\n}\n\nasync function findExecutable(): Promise<string> {\n const command = process.platform === \"win32\" ? \"where.exe\" : \"which\";\n try {\n const { stdout } = await exec(command, [\"openspec\"]);\n const first = stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .find(Boolean);\n if (first) {\n return first;\n }\n } catch {\n // Try npx below.\n }\n\n try {\n await exec(\"npx\", [\"openspec\", \"--version\"]);\n return \"npx openspec\";\n } catch {\n throw new FetError({\n code: ErrorCode.OpenSpecNotFound,\n message: \"OpenSpec CLI 未安装\",\n suggestedCommand: \"npm install -g @fission-ai/openspec\"\n });\n }\n}\n\nasync function readVersion(executablePath: string): Promise<string> {\n const command = executablePath === \"npx openspec\" ? \"npx\" : executablePath;\n const args = executablePath === \"npx openspec\" ? [\"openspec\", \"--version\"] : [\"--version\"];\n try {\n const { stdout, stderr } = await exec(command, args);\n return stdout.trim() || stderr.trim() || \"unknown\";\n } catch (error) {\n throw new FetError({\n code: ErrorCode.OpenSpecUnsupportedVersion,\n message: \"无法读取 OpenSpec 版本\",\n details: { executablePath },\n cause: error\n });\n }\n}\n\nfunction exec(command: string, args: string[]) {\n return execFileAsync(command, args, { shell: process.platform === \"win32\" });\n}\n","import { spawn } from \"node:child_process\";\nimport { ErrorCode } from \"../errors/codes.js\";\nimport { FetError } from \"../errors/fet-error.js\";\nimport type { OpenSpecRunOptions, OpenSpecRunResult } from \"./types.js\";\n\nexport async function runOpenSpec(\n executablePath: string,\n command: string,\n args: string[],\n options: OpenSpecRunOptions\n): Promise<OpenSpecRunResult> {\n const spawnCommand = executablePath === \"npx openspec\" ? \"npx\" : executablePath;\n const spawnArgs = executablePath === \"npx openspec\" ? [\"openspec\", command, ...args] : [command, ...args];\n\n return new Promise((resolve, reject) => {\n const stdout: Buffer[] = [];\n const stderr: Buffer[] = [];\n const child = spawn(spawnCommand, spawnArgs, {\n cwd: options.cwd,\n stdio: options.stdio ?? \"inherit\",\n shell: process.platform === \"win32\"\n });\n\n if (child.stdout) {\n child.stdout.on(\"data\", (chunk: Buffer) => stdout.push(chunk));\n }\n if (child.stderr) {\n child.stderr.on(\"data\", (chunk: Buffer) => stderr.push(chunk));\n }\n\n child.on(\"error\", (error) => {\n reject(\n new FetError({\n code: ErrorCode.OpenSpecCommandFailed,\n message: \"OpenSpec 命令启动失败\",\n details: { command, args },\n cause: error\n })\n );\n });\n\n child.on(\"close\", (exitCode, signal) => {\n resolve({\n command,\n args,\n exitCode: exitCode ?? 1,\n signal,\n stdout: stdout.length ? Buffer.concat(stdout).toString(\"utf8\") : undefined,\n stderr: stderr.length ? Buffer.concat(stderr).toString(\"utf8\") : undefined\n });\n });\n });\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parse } from \"yaml\";\nimport type { ScannedCommand, ScannedWorkspace } from \"./types.js\";\n\ninterface PackageJson {\n name?: string;\n packageManager?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n workspaces?: string[] | { packages?: string[] };\n}\n\nexport async function readPackageJson(projectRoot: string): Promise<PackageJson | null> {\n try {\n return JSON.parse(await readFile(join(projectRoot, \"package.json\"), \"utf8\"));\n } catch {\n return null;\n }\n}\n\nexport interface PackageManagerDetection {\n manager: string;\n confidence: \"high\" | \"medium\" | \"low\";\n warnings: string[];\n}\n\nexport async function detectPackageManager(projectRoot: string, pkg: PackageJson | null): Promise<PackageManagerDetection> {\n const warnings: string[] = [];\n if (pkg?.packageManager) {\n const declared = pkg.packageManager.split(\"@\")[0] ?? \"unknown\";\n const locks = await detectLockManagers(projectRoot);\n const conflicting = locks.filter((item) => item !== declared);\n if (conflicting.length) {\n warnings.push(`packageManager 声明为 ${declared},但同时发现锁文件:${conflicting.join(\", \")}`);\n }\n return { manager: declared, confidence: \"high\", warnings };\n }\n\n const locks = await detectLockManagers(projectRoot);\n if (locks.length > 1) {\n warnings.push(`发现多个包管理器锁文件:${locks.join(\", \")},默认使用 ${locks[0]}`);\n return { manager: locks[0] ?? \"npm\", confidence: \"medium\", warnings };\n }\n if (locks[0]) {\n return { manager: locks[0], confidence: \"high\", warnings };\n }\n return { manager: \"npm\", confidence: \"low\", warnings };\n}\n\nexport function extractCommands(pkg: PackageJson | null, packageManager: string): Record<string, ScannedCommand> {\n const scripts = pkg?.scripts ?? {};\n const result: Record<string, ScannedCommand> = {};\n const scriptNames = [\"dev\", \"build\", \"lint\", \"typecheck\", \"check\", \"test\", \"test:unit\"];\n\n for (const name of scriptNames) {\n if (scripts[name]) {\n const dimension = name === \"check\" ? \"typecheck\" : name === \"test:unit\" ? \"test\" : name;\n if (result[dimension]) {\n continue;\n }\n result[dimension] = {\n command: scriptCommand(packageManager, name),\n source: `package.json:scripts.${name}`,\n required: name === \"build\"\n };\n }\n }\n\n return result;\n}\n\nexport function detectFramework(pkg: PackageJson | null): { name: string; confidence: \"high\" | \"medium\" | \"low\"; sources: string[] } {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n const candidates: Array<[string, string[]]> = [\n [\"next\", [\"next\"]],\n [\"nuxt\", [\"nuxt\"]],\n [\"vite\", [\"vite\"]],\n [\"sveltekit\", [\"@sveltejs/kit\"]],\n [\"angular\", [\"@angular/core\", \"@angular/cli\"]],\n [\"react\", [\"react\"]],\n [\"vue\", [\"vue\"]],\n [\"svelte\", [\"svelte\"]]\n ];\n for (const [candidate, packages] of candidates) {\n if (packages.some((name) => deps[name])) {\n return { name: candidate, confidence: \"high\", sources: [\"package.json\"] };\n }\n }\n return { name: \"unknown\", confidence: \"low\", sources: [] };\n}\n\nexport async function detectLanguage(projectRoot: string, pkg: PackageJson | null): Promise<string> {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n if (deps.typescript || (await exists(join(projectRoot, \"tsconfig.json\")))) {\n return \"typescript\";\n }\n return \"javascript\";\n}\n\nexport async function detectWorkspaces(projectRoot: string, pkg: PackageJson | null): Promise<ScannedWorkspace[]> {\n const packageWorkspaces = normalizeWorkspaces(pkg?.workspaces).map((path) => ({\n name: path,\n path,\n source: \"package.json:workspaces\"\n }));\n if (packageWorkspaces.length) {\n return packageWorkspaces;\n }\n\n try {\n const workspace = parse(await readFile(join(projectRoot, \"pnpm-workspace.yaml\"), \"utf8\")) as { packages?: string[] } | null;\n return (workspace?.packages ?? []).map((path) => ({\n name: path,\n path,\n source: \"pnpm-workspace.yaml:packages\"\n }));\n } catch {\n return [];\n }\n}\n\nasync function detectLockManagers(projectRoot: string): Promise<string[]> {\n const lockFiles: Array<[string, string]> = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"bun.lockb\", \"bun\"],\n [\"bun.lock\", \"bun\"],\n [\"package-lock.json\", \"npm\"]\n ];\n const found: string[] = [];\n for (const [file, manager] of lockFiles) {\n if (await exists(join(projectRoot, file))) {\n found.push(manager);\n }\n }\n return found;\n}\n\nfunction normalizeWorkspaces(workspaces: PackageJson[\"workspaces\"]): string[] {\n if (Array.isArray(workspaces)) {\n return workspaces;\n }\n return workspaces?.packages ?? [];\n}\n\nfunction scriptCommand(packageManager: string, name: string): string {\n return packageManager === \"npm\" ? `npm run ${name}` : `${packageManager} ${name}`;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\nimport type { ScannedRoute } from \"./types.js\";\n\nexport async function scanRoutes(projectRoot: string): Promise<ScannedRoute[]> {\n const candidates = [\"src/routes\", \"src/pages\", \"app\", \"pages\"];\n const routes: ScannedRoute[] = [];\n\n for (const candidate of candidates) {\n const root = join(projectRoot, candidate);\n if (!(await exists(root))) {\n continue;\n }\n for (const file of await listFiles(root)) {\n if (!/\\.(tsx?|jsx?|vue|svelte)$/.test(file)) {\n continue;\n }\n routes.push({\n path: inferRoutePath(relative(root, file)),\n source: relative(projectRoot, file).split(sep).join(\"/\"),\n inferred: true,\n confidence: \"medium\"\n });\n }\n }\n\n return routes.slice(0, 100);\n}\n\nfunction inferRoutePath(relativePath: string): string {\n const normalized = relativePath.split(sep).join(\"/\");\n const withoutExt = normalized.replace(/\\.(tsx?|jsx?|vue|svelte)$/, \"\");\n const withoutIndex = withoutExt.replace(/\\/index$/, \"\").replace(/^index$/, \"\");\n return `/${withoutIndex}`.replace(/\\/+/g, \"/\");\n}\n\nasync function listFiles(root: string): Promise<string[]> {\n const entries = await readdir(root, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const path = join(root, entry.name);\n if (entry.isDirectory()) {\n files.push(...(await listFiles(path)));\n } else {\n files.push(path);\n }\n }\n return files;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n","import { detectFramework, detectLanguage, detectPackageManager, detectWorkspaces, extractCommands, readPackageJson } from \"./package.js\";\nimport { scanRoutes } from \"./routes.js\";\nimport type { ProjectScanResult, ScanOptions } from \"./types.js\";\n\nexport class ProjectScanner {\n async scan(projectRoot: string, _options: ScanOptions = {}): Promise<ProjectScanResult> {\n const pkg = await readPackageJson(projectRoot);\n const packageManager = await detectPackageManager(projectRoot, pkg);\n const framework = detectFramework(pkg);\n const workspaces = await detectWorkspaces(projectRoot, pkg);\n const language = await detectLanguage(projectRoot, pkg);\n const warnings = [...packageManager.warnings];\n if (framework.name === \"unknown\") {\n warnings.push(\"未能从 package.json 识别主要框架\");\n }\n\n return {\n generatedAt: new Date().toISOString(),\n scannerVersion: 1,\n project: {\n name: pkg?.name ?? \"unknown\",\n packageManager: packageManager.manager,\n packageManagerConfidence: packageManager.confidence,\n framework,\n language,\n monorepo: workspaces.length > 0,\n workspaces\n },\n commands: extractCommands(pkg, packageManager.manager),\n routes: await scanRoutes(projectRoot),\n conventions: [],\n skippedFiles: [],\n warnings\n };\n }\n}\n\nexport type {\n ProjectScanResult,\n ScanOptions,\n ScannedCommand,\n ScannedConvention,\n ScannedProjectMetadata,\n ScannedRoute,\n ScannedWorkspace,\n SkippedFile\n} from \"./types.js\";\n","import { FetError } from \"../errors/fet-error.js\";\n\nexport interface CommandResult {\n ok: true;\n command: string;\n summary: string;\n warnings?: string[];\n nextSteps?: string[];\n data?: unknown;\n}\n\nexport class OutputWriter {\n constructor(private readonly json: boolean) {}\n\n info(message: string, details?: unknown): void {\n if (!this.json) {\n process.stdout.write(`${message}${formatDetails(details)}\\n`);\n }\n }\n\n warn(message: string, details?: unknown): void {\n if (!this.json) {\n process.stderr.write(`警告:${message}${formatDetails(details)}\\n`);\n }\n }\n\n error(error: FetError): void {\n if (this.json) {\n process.stderr.write(`${JSON.stringify({ ok: false, error: error.toJSON() }, null, 2)}\\n`);\n return;\n }\n\n process.stderr.write(`FET 无法继续:${error.message}\\n`);\n if (error.details !== undefined) {\n process.stderr.write(`\\n详情:\\n${formatBlock(error.details)}\\n`);\n }\n if (error.suggestedCommand) {\n process.stderr.write(`\\n建议:\\n ${error.suggestedCommand}\\n`);\n }\n }\n\n result(result: CommandResult): void {\n if (this.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n return;\n }\n\n process.stdout.write(`${result.summary}\\n`);\n for (const warning of result.warnings ?? []) {\n process.stdout.write(`警告:${warning}\\n`);\n }\n if (result.nextSteps?.length) {\n process.stdout.write(\"\\n下一步:\\n\");\n for (const step of result.nextSteps) {\n process.stdout.write(` ${step}\\n`);\n }\n }\n }\n}\n\nfunction formatDetails(details: unknown): string {\n if (details === undefined) {\n return \"\";\n }\n return ` ${JSON.stringify(details)}`;\n}\n\nfunction formatBlock(details: unknown): string {\n if (typeof details === \"string\") {\n return ` ${details}`;\n }\n return JSON.stringify(details, null, 2)\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAAA,SAAS,eAAe;;;ACAxB,SAAS,YAAAA,WAAU,QAAAC,aAAY;AAC/B,SAAS,QAAAC,aAAY;;;ACDrB,SAAS,eAAe;AACxB,SAAS,MAAM,QAAQ,aAAa;AAOpC,eAAsB,YACpB,YACA,SAC4B;AAC5B,QAAM,MAAM,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,QAAM,WAAW,GAAG,UAAU,QAAQ,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;AAC/D,QAAM,SAAS,MAAM,KAAK,UAAU,IAAI;AAExC,MAAI;AACF,UAAM,OAAO,UAAU,OAAO;AAC9B,UAAM,OAAO,KAAK;AAAA,EACpB,UAAE;AACA,UAAM,OAAO,MAAM;AAAA,EACrB;AAEA,QAAM,OAAO,UAAU,UAAU;AACjC,SAAO,EAAE,MAAM,YAAY,SAAS;AACtC;;;ACzBA,SAAS,UAAU,YAAY;AAC/B,SAAS,UAAU,WAAAC,UAAS,YAAY;AAExC,eAAsB,aAAa,UAA0C;AAC3E,MAAI;AACF,UAAM,KAAK,QAAQ;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,aAAY,oBAAI,KAAK,GACxB,YAAY,EACZ,QAAQ,SAAS,EAAE,EACnB,QAAQ,SAAS,EAAE,EACnB,QAAQ,KAAK,GAAG;AACnB,QAAM,aAAa,KAAKA,SAAQ,QAAQ,GAAG,GAAG,SAAS,QAAQ,CAAC,eAAe,SAAS,EAAE;AAC1F,QAAM,SAAS,UAAU,UAAU;AACnC,SAAO;AACT;;;AClBA,SAAS,gBAAgB;AACzB,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,SAAAC,QAAO,QAAAC,OAAM,UAAU,UAAU;AAmB1C,eAAsB,gBACpB,aACA,UACA,IACY;AACZ,QAAM,WAAWC,MAAK,aAAa,YAAY,WAAW;AAC1D,QAAM,OAAiB;AAAA,IACrB,KAAK,QAAQ;AAAA,IACb,UAAU,SAAS;AAAA,IACnB,KAAK,SAAS;AAAA,IACd,SAAS,SAAS;AAAA,IAClB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,YAAY,SAAS;AAAA,EACvB;AAEA,MAAI;AACJ,MAAI;AACF,UAAMC,OAAMC,SAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,aAAS,MAAMC,MAAK,UAAU,IAAI;AAClC,UAAM,OAAO,UAAU,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,EACtD,QAAQ;AACN,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,SAAS,MAAM,iBAAiB,QAAQ;AAAA,MACxC,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH,UAAE;AACA,UAAM,QAAQ,MAAM;AAAA,EACtB;AAEA,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,UAAE;AACA,UAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,EACpC;AACF;AAEA,eAAe,iBAAiB,UAAoC;AAClE,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,SAAS,UAAU,MAAM,CAAC;AAAA,EACpD,QAAQ;AACN,WAAO,EAAE,MAAM,SAAS;AAAA,EAC1B;AACF;AAEA,eAAsB,UAAU,aAAuC;AACrE,QAAM,WAAWH,MAAK,aAAa,YAAY,WAAW;AAC1D,MAAI;AACF,UAAM,GAAG,QAAQ;AACjB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC3EA,SAAS,QAAAI,aAAY;AACrB,SAAS,YAAAC,iBAAgB;AAmBlB,SAAS,kBAAkB,YAAiC;AACjE,SAAO;AAAA,IACL,eAAe;AAAA,IACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,aAAa;AAAA,IACb;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,iBAAiB,aAAqB,SAAqC;AAC/F,QAAM;AAAA,IACJC,MAAK,aAAa,YAAY,wBAAwB;AAAA,IACtD,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA;AAAA,EACrC;AACF;;;ACnCA,SAAS,YAAY,oBAAoB;AACzC,SAAS,WAAAC,UAAS,QAAAC,OAAM,aAAa;AACrC,SAAS,qBAAqB;AAEvB,IAAM,cAAc,mBAAmB;AAE9C,SAAS,qBAA6B;AACpC,MAAI,aAAaD,SAAQ,cAAc,YAAY,GAAG,CAAC;AACvD,QAAM,OAAO,MAAM,UAAU,EAAE;AAE/B,SAAO,MAAM;AACX,UAAM,kBAAkBC,MAAK,YAAY,cAAc;AACvD,QAAI,WAAW,eAAe,GAAG;AAC/B,YAAM,cAAc,KAAK,MAAM,aAAa,iBAAiB,MAAM,CAAC;AACpE,UAAI,OAAO,YAAY,YAAY,YAAY,YAAY,QAAQ,SAAS,GAAG;AAC7E,eAAO,YAAY;AAAA,MACrB;AACA,YAAM,IAAI,MAAM,qEAAkC,eAAe,EAAE;AAAA,IACrE;AAEA,QAAI,eAAe,MAAM;AACvB,YAAM,IAAI,MAAM,2CAAuB;AAAA,IACzC;AACA,iBAAaD,SAAQ,UAAU;AAAA,EACjC;AACF;;;ACzBO,IAAM,aAAa;AACnB,IAAM,WAAW;AACjB,IAAM,aAAa;AACnB,IAAM,WAAW;AAEjB,SAAS,qBAAqB,SAA0B;AAC7D,SAAO,MAAM,SAAS,UAAU,MAAM,KAAK,MAAM,SAAS,QAAQ,MAAM,KAAK,QAAQ,QAAQ,UAAU,IAAI,QAAQ,QAAQ,QAAQ;AACrI;AAEO,SAAS,4BAA4B,SAA0B;AACpE,QAAM,aAAa,MAAM,SAAS,UAAU;AAC5C,QAAM,WAAW,MAAM,SAAS,QAAQ;AACxC,SAAO,eAAe,YAAY,aAAa,KAAK,WAAW,KAAM,eAAe,KAAK,QAAQ,QAAQ,UAAU,IAAI,QAAQ,QAAQ,QAAQ;AACjJ;AAEO,SAAS,qBAAqB,UAAyB,WAA2B;AACvF,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,SAAS,QAAQ,UAAU;AACzC,QAAM,MAAM,SAAS,QAAQ,QAAQ;AACrC,MAAI,UAAU,MAAM,QAAQ,MAAM,MAAM,OAAO;AAC7C,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,SAAS,MAAM,GAAG,KAAK;AACtC,QAAM,QAAQ,SAAS,MAAM,MAAM,SAAS,MAAM;AAClD,QAAM,gBAAgB,YAAY,SAAS;AAC3C,SAAO,GAAG,MAAM,GAAG,UAAU;AAAA,EAAK,aAAa;AAAA,EAAK,QAAQ,GAAG,KAAK;AACtE;AAEA,SAAS,YAAY,SAAyB;AAC5C,QAAM,QAAQ,QAAQ,QAAQ,UAAU;AACxC,QAAM,MAAM,QAAQ,QAAQ,QAAQ;AACpC,MAAI,UAAU,MAAM,QAAQ,MAAM,MAAM,OAAO;AAC7C,WAAO,QAAQ,KAAK;AAAA,EACtB;AACA,SAAO,QAAQ,MAAM,QAAQ,WAAW,QAAQ,GAAG,EAAE,KAAK;AAC5D;AAEA,SAAS,MAAM,SAAiB,QAAwB;AACtD,SAAO,QAAQ,MAAM,MAAM,EAAE,SAAS;AACxC;;;ACvCO,SAAS,eAAe,MAAiC;AAC9D,QAAME,YAAW,OAAO,QAAQ,KAAK,QAAQ,EAC1C,IAAI,CAAC,CAAC,MAAM,OAAO,MAAM,KAAK,IAAI,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,MAAM,IAAI,EACnF,KAAK,IAAI;AACZ,QAAM,SAAS,KAAK,OACjB,IAAI,CAAC,UAAU,KAAK,MAAM,IAAI,MAAM,MAAM,MAAM,MAAM,MAAM,UAAU,GAAG,MAAM,WAAW,cAAc,EAAE,IAAI,EAC9G,KAAK,IAAI;AACZ,QAAM,aAAa,KAAK,QAAQ,WAAW,IAAI,CAAC,cAAc,KAAK,UAAU,IAAI,MAAM,UAAU,IAAI,MAAM,UAAU,MAAM,IAAI,EAAE,KAAK,IAAI;AAE1I,SAAO;AAAA;AAAA,EAEP,UAAU;AAAA;AAAA;AAAA,UAGF,KAAK,QAAQ,IAAI;AAAA,qBACN,KAAK,QAAQ,cAAc,KAAK,KAAK,QAAQ,wBAAwB;AAAA,eAC3E,KAAK,QAAQ,UAAU,IAAI,KAAK,KAAK,QAAQ,UAAU,UAAU;AAAA,cAClE,KAAK,QAAQ,QAAQ;AAAA,cACrB,KAAK,QAAQ,WAAW,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhD,cAAc,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvCA,aAAY,+DAA+D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU3E,UAAU,iDAAiD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAQ3C,KAAK,WAAW;AAAA,iBACjB,WAAW;AAAA,qBACP,KAAK,cAAc;AAAA,cAC1B,KAAK,SAAS,SAAS,KAAK,SAAS,KAAK,IAAI,IAAI,MAAM;AAAA,EACpE,QAAQ;AAAA;AAAA,EAER,UAAU;AAAA;AAAA;AAAA;AAAA,EAIV,QAAQ;AAAA;AAEV;;;AChEA,SAAS,iBAAiB;AAInB,SAAS,gBAAgB,MAAiC;AAC/D,SAAO,UAAU;AAAA,IACf,KAAK;AAAA,MACH,eAAe;AAAA,MACf,aAAa,KAAK;AAAA,MAClB,YAAY;AAAA,MACZ,gBAAgB,KAAK;AAAA,MACrB,SAAS;AAAA,QACP,gBAAgB,KAAK,QAAQ;AAAA,QAC7B,0BAA0B,KAAK,QAAQ;AAAA,QACvC,WAAW,KAAK,QAAQ;AAAA,QACxB,UAAU,KAAK,QAAQ;AAAA,QACvB,UAAU,KAAK,QAAQ;AAAA,QACvB,YAAY,KAAK,QAAQ;AAAA,MAC3B;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,QACV,UAAU,KAAK,QAAQ;AAAA,QACvB,SAAS;AAAA,UACP,MAAM;AAAA,UACN,WAAW;AAAA,UACX,MAAM;AAAA,QACR;AAAA,QACA,YAAY,KAAK,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AC7BO,SAAS,yBAAyB,UAAkB,eAAc,oBAAI,KAAK,GAAE,YAAY,GAAW;AACzG,SAAO;AAAA;AAAA,cAEK,WAAW;AAAA,eACV,WAAW;AAAA,YACd,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAeS,QAAQ;AAAA;AAAA;AAGrC;;;ACzBA,IAAM,QAAQ;AACd,IAAM,MAAM;AAEZ,IAAM,QAAQ;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,eAAe,UAAiC;AAC9D,QAAM,QAAQ,GAAG,KAAK;AAAA,EAAK,MAAM,KAAK,IAAI,CAAC;AAAA,EAAK,GAAG;AACnD,MAAI,CAAC,YAAY,CAAC,SAAS,KAAK,GAAG;AACjC,WAAO,GAAG,KAAK;AAAA;AAAA,EACjB;AAEA,QAAM,QAAQ,SAAS,QAAQ,KAAK;AACpC,QAAM,MAAM,SAAS,QAAQ,GAAG;AAChC,MAAI,UAAU,MAAM,QAAQ,MAAM,MAAM,OAAO;AAC7C,WAAO,GAAG,SAAS,MAAM,GAAG,KAAK,CAAC,GAAG,KAAK,GAAG,SAAS,MAAM,MAAM,IAAI,MAAM,CAAC;AAAA,EAC/E;AAEA,SAAO,GAAG,SAAS,QAAQ,QAAQ,EAAE,CAAC;AAAA;AAAA,EAAO,KAAK;AAAA;AACpD;;;ACxBA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,QAAAC,aAAY;;;ACDrB,SAAS,YAAAC,iBAAgB;AACzB,SAAS,qBAAqB;AAE9B,eAAsB,eAAe,YAAoB,iBAA0C;AACjG,QAAM,SAAS,cAAc,eAAe;AAC5C,QAAM,UAAU,OAAO,IAAI,OAAO,IAAI;AAEtC,MAAI,WAAW;AACf,MAAI;AACF,eAAW,MAAMA,UAAS,YAAY,MAAM;AAAA,EAC9C,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,cAAc,YAAY,IAAI;AAC1C,MAAI,IAAI,OAAO,OAAO;AACtB,SAAO,IAAI,SAAS;AACtB;;;ADRA,eAAsB,qBAAqB,KAAuC;AAChF,QAAM;AAAA,IACJ,IAAI;AAAA,IACJ,EAAE,SAAS,kBAAkB,KAAK,IAAI,KAAK,YAAY,IAAI,WAAW;AAAA,IACtE,YAAY,mBAAmB,GAAG;AAAA,EACpC;AAEA,MAAI,OAAO,OAAO;AAAA,IAChB,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AACH;AAEA,eAAsB,mBAAmB,KAAyD;AAChG,QAAM,OAAO,MAAM,IAAI,QAAQ,KAAK,IAAI,aAAa,CAAC,CAAC;AACvD,QAAM,aAAaC,MAAK,IAAI,aAAa,WAAW;AACpD,QAAM,aAAaA,MAAK,IAAI,aAAa,YAAY,aAAa;AAElE,QAAM,iBAAiB,MAAM,aAAa,UAAU;AACpD,QAAM,WAAW,CAAC,GAAG,KAAK,QAAQ;AAClC,MAAI,kBAAkB,4BAA4B,cAAc,GAAG;AACjE,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,SAAS,EAAE,MAAM,YAAY;AAAA,MAC7B,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACA,MAAI,kBAAkB,CAAC,qBAAqB,cAAc,GAAG;AAC3D,QAAI,CAAC,IAAI,KAAK;AACZ,YAAM,IAAI,SAAS;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,SAAS,EAAE,MAAM,YAAY;AAAA,QAC7B,kBACE,IAAI,YAAY,SACZ,sFACA;AAAA,MACR,CAAC;AAAA,IACH;AACA,UAAM,aAAa,MAAM,aAAa,UAAU;AAChD,QAAI,YAAY;AACd,eAAS,KAAK,yDAAsB,UAAU,EAAE;AAAA,IAClD;AAAA,EACF;AACA,QAAM,YAAY,YAAY,qBAAqB,gBAAgB,eAAe,IAAI,CAAC,CAAC;AACxF,QAAM,YAAY,YAAY,MAAM,eAAe,YAAY,gBAAgB,IAAI,CAAC,CAAC;AAErF,QAAM,QAAQ,MAAM,IAAI,WAAW,kBAAkB;AACrD,QAAM,UAAU;AAAA,IACd,mBAAmB,KAAK;AAAA,IACxB,iBAAiB,KAAK;AAAA,IACtB,gBAAgB,KAAK;AAAA,EACvB;AACA,QAAM,IAAI,WAAW,YAAY,KAAK;AAEtC,SAAO,EAAE,SAAS;AACpB;AAEA,eAAe,aAAa,MAAsC;AAChE,MAAI;AACF,WAAO,MAAMC,UAAS,MAAM,MAAM;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AXpEA,eAAsB,YAAY,KAAuC;AACvE,QAAM,qBAAqB,MAAM,OAAOC,MAAK,IAAI,aAAa,YAAY,aAAa,CAAC;AACxF,QAAM;AAAA,IACJ,IAAI;AAAA,IACJ,EAAE,SAAS,QAAQ,KAAK,IAAI,KAAK,YAAY,IAAI,WAAW;AAAA,IAC5D,YAAY;AACV,YAAM,UAAU,kBAAkB,IAAI,UAAU;AAChD,YAAM,iBAAiB,IAAI,aAAa,OAAO;AAE/C,YAAM,WAAW,MAAM,IAAI,SAAS,kBAAkB;AACtD,UAAI,CAAC,oBAAoB;AACvB,cAAM,SAAS,MAAM,IAAI,SAAS,IAAI,QAAQ,CAAC,WAAW,MAAM,GAAG,EAAE,KAAK,IAAI,aAAa,OAAO,UAAU,CAAC;AAC7G,YAAI,OAAO,aAAa,GAAG;AACzB,kBAAQ,WAAW,OAAO;AAC1B;AAAA,QACF;AAAA,MACF;AAEA,YAAM,gBAAgB,MAAM,mBAAmB,GAAG;AAClD,YAAM,gBAAgB,GAAG;AAEzB,YAAM,QAAQ,MAAM,IAAI,WAAW,kBAAkB;AACrD,YAAM,WAAW;AAEjB,iBAAW,WAAW,IAAI,cAAc;AACtC,cAAM,OAAO,MAAM,QAAQ,YAAY,IAAI,WAAW;AACtD,cAAM,SAAS,MAAM,QAAQ,QAAQ,IAAI,aAAa,MAAM,IAAI,GAAG;AACnE,cAAM,aAAa,QAAQ,IAAI,IAAI;AAAA,UACjC,gBAAgB,QAAQ;AAAA,UACxB,WAAW;AAAA,UACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AACA,gBAAQ,MAAM,KAAK,GAAG,OAAO,QAAQ,IAAI,CAAC,UAAU,EAAE,WAAW,SAAkB,MAAM,QAAQ,OAAgB,EAAE,CAAC;AAAA,MACtH;AAEA,cAAQ,eAAc,oBAAI,KAAK,GAAE,YAAY;AAC7C,YAAM,iBAAiB,IAAI,aAAa,OAAO;AAC/C,YAAM,IAAI,WAAW,YAAY,KAAK;AACtC,iBAAW,WAAW,cAAc,UAAU;AAC5C,YAAI,OAAO,KAAK,OAAO;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,OAAO;AAAA,IAChB,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,6DAAyC,8DAAsB;AAAA,EAC7E,CAAC;AACH;AAEA,eAAe,gBAAgB,KAAuC;AACpE,QAAM,gBAAgBA,MAAK,IAAI,aAAa,YAAY;AACxD,QAAM,WAAW,MAAMC,cAAa,aAAa;AACjD,QAAM,YAAY,eAAe,eAAe,QAAQ,CAAC;AAC3D;AAEA,eAAeA,cAAa,MAAsC;AAChE,MAAI;AACF,WAAO,MAAMC,UAAS,MAAM,MAAM;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,OAAO,MAAgC;AACpD,MAAI;AACF,UAAMC,MAAK,IAAI;AACf,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AahFA,SAAS,QAAAC,aAAY;AACrB,SAAS,QAAAC,aAAY;AAKrB,eAAsB,cAAc,KAAwB,UAAiC,CAAC,GAAkB;AAC9G,QAAM,SAAwB,CAAC;AAE/B,SAAO,KAAK,MAAM,cAAc,GAAG,CAAC;AACpC,SAAO,KAAK,MAAM,WAAW,GAAG,CAAC;AACjC,SAAO,KAAK,MAAM,UAAU,UAAUC,MAAK,IAAI,aAAa,WAAW,GAAG,0BAAgB,oBAAoB,CAAC;AAC/G,SAAO,KAAK,MAAM,UAAU,UAAUA,MAAK,IAAI,aAAa,YAAY,aAAa,GAAG,qCAA2B,UAAU,CAAC;AAE9H,aAAW,WAAW,IAAI,cAAc;AACtC,WAAO,KAAK,GAAI,MAAM,QAAQ,OAAO,IAAI,WAAW,CAAE;AAAA,EACxD;AAEA,QAAM,WAAWA,MAAK,IAAI,aAAa,YAAY,WAAW;AAC9D,MAAI,MAAMC,QAAO,QAAQ,GAAG;AAC1B,QAAI,QAAQ,SAAS;AACnB,YAAM,UAAU,IAAI,WAAW;AAC/B,aAAO,KAAK,EAAE,IAAI,QAAQ,QAAQ,QAAQ,SAAS,wCAAyB,CAAC;AAAA,IAC/E,OAAO;AACL,aAAO,KAAK,EAAE,IAAI,QAAQ,QAAQ,QAAQ,SAAS,mCAAyB,kBAAkB,wBAAwB,CAAC;AAAA,IACzH;AAAA,EACF;AAEA,QAAM,WAAW,OAAO,OAAO,CAAC,UAAU,MAAM,WAAW,MAAM,EAAE,IAAI,CAAC,UAAU,MAAM,OAAO;AAC/F,MAAI,OAAO,OAAO;AAAA,IAChB,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,SAAS,SAAS,SAAS,8CAAW,SAAS,MAAM,4DAAe;AAAA,IACpE;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AACH;AAEA,eAAe,cAAc,KAA8C;AACzE,MAAI;AACF,UAAM,WAAW,MAAM,IAAI,SAAS,kBAAkB;AACtD,WAAO,EAAE,IAAI,YAAY,QAAQ,QAAQ,SAAS,aAAa,SAAS,cAAc,KAAK,SAAS,OAAO,IAAI;AAAA,EACjH,SAAS,OAAO;AACd,WAAO,EAAE,IAAI,YAAY,QAAQ,QAAQ,SAAS,iBAAiB,QAAQ,MAAM,UAAU,oCAAgB;AAAA,EAC7G;AACF;AAEA,eAAe,WAAW,KAA8C;AACtE,MAAI;AACF,UAAM,QAAQ,MAAM,IAAI,WAAW,WAAW;AAC9C,WAAO,QACH,EAAE,IAAI,SAAS,QAAQ,QAAQ,SAAS,iDAAc,IACtD,EAAE,IAAI,SAAS,QAAQ,QAAQ,SAAS,8DAAiB,kBAAkB,WAAW;AAAA,EAC5F,SAAS,OAAO;AACd,WAAO,EAAE,IAAI,SAAS,QAAQ,QAAQ,SAAS,iBAAiB,QAAQ,MAAM,UAAU,2CAAa;AAAA,EACvG;AACF;AAEA,eAAe,UAAU,IAAY,MAAc,SAAiB,kBAAgD;AAClH,SAAQ,MAAMA,QAAO,IAAI,IACrB,EAAE,IAAI,QAAQ,QAAQ,SAAS,GAAG,EAAE,gBAAM,IAC1C,EAAE,IAAI,QAAQ,QAAQ,SAAS,SAAS,iBAAiB;AAC/D;AAEA,eAAeA,QAAO,MAAgC;AACpD,MAAI;AACF,UAAMC,MAAK,IAAI;AACf,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACvEA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAG1B,IAAM,gBAAgB,UAAU,QAAQ;AAExC,eAAsB,sBAAsB,aAA+C;AACzF,QAAM,CAAC,SAAS,QAAQ,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,IACtD,IAAI,aAAa,CAAC,aAAa,iBAAiB,CAAC;AAAA,IACjD,IAAI,aAAa,CAAC,UAAU,gBAAgB,CAAC;AAAA,IAC7C,IAAI,aAAa,CAAC,aAAa,MAAM,CAAC;AAAA,EACxC,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,IAAI,KAAa,MAAwC;AACtE,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,cAAc,OAAO,MAAM,EAAE,IAAI,CAAC;AAC3D,WAAO,OAAO,KAAK,KAAK;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC5BA,SAAS,SAAAC,QAAO,YAAAC,iBAAgB;AAChC,SAAS,QAAAC,aAAY;;;ACGrB,IAAM,SAAwB,CAAC,WAAW,WAAW,aAAa,UAAU,QAAQ,SAAS;AAEtF,SAAS,kBAAkB,YAAoB,SAAuC;AAC3F,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA,WAAW;AAAA,IACX,WAAW;AAAA,IACX;AAAA,IACA,UAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,eAAe,CAAC;AAAA,IAChB,SAAS;AAAA,MACP,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,IAClB;AAAA,IACA,cAAc,CAAC;AAAA,IACf,qBAAqB;AAAA,IACrB,YAAY;AAAA,EACd;AACF;AAEO,SAAS,kBAAkB,YAAoB,UAAkB,OAAiC;AACvG,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,QAAQ,OAAO;AAAA,MACb,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,SAAS,QAAQ,gBAAgB,cAAc,CAAC,CAAC;AAAA,IACzF;AAAA,IACA,OAAO;AAAA,MACL,QAAQ;AAAA,MACR,cAAc,CAAC;AAAA,MACf,cAAc;AAAA,IAChB;AAAA,IACA,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,UAAU,CAAC;AAAA,EACb;AACF;AAEO,SAAS,kBAAkB,OAA8C;AAC9E,MAAI,CAAC,SAAS,KAAK,KAAK,MAAM,kBAAkB,GAAG;AACjD,UAAM,kBAAkB,0DAAkB;AAAA,EAC5C;AACA,MAAI,OAAO,MAAM,eAAe,YAAY,CAAC,SAAS,MAAM,OAAO,GAAG;AACpE,UAAM,eAAe,8DAAY;AAAA,EACnC;AACF;AAEO,SAAS,kBAAkB,OAA8C;AAC9E,MAAI,CAAC,SAAS,KAAK,KAAK,MAAM,kBAAkB,GAAG;AACjD,UAAM,kBAAkB,0DAAkB;AAAA,EAC5C;AACA,MAAI,OAAO,MAAM,eAAe,YAAY,OAAO,MAAM,aAAa,UAAU;AAC9E,UAAM,eAAe,8DAAY;AAAA,EACnC;AACF;AAEA,SAAS,kBAAkB,SAA2B;AACpD,SAAO,IAAI,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AACH;AAEA,SAAS,eAAe,SAA2B;AACjD,SAAO,IAAI,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AACH;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;ADjFO,IAAM,aAAN,MAAiB;AAAA,EACtB,YACmB,aACA,YACA,SACjB;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAHgB;AAAA,EACA;AAAA,EACA;AAAA,EAGnB,MAAM,aAA0C;AAC9C,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,MAAMC,UAAS,KAAK,WAAW,GAAG,MAAM,CAAC;AAClE,wBAAkB,KAAK;AACvB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,WAAW,KAAK,GAAG;AACrB,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,oBAA0C;AAC9C,WAAQ,MAAM,KAAK,WAAW,KAAM,kBAAkB,KAAK,YAAY,KAAK,OAAO;AAAA,EACrF;AAAA,EAEA,MAAM,YAAY,OAAmC;AACnD,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAMC,OAAMC,MAAK,KAAK,aAAa,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACnE,UAAM,YAAY,KAAK,WAAW,GAAG,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EAC5E;AAAA,EAEA,MAAM,WAAW,UAA+C;AAC9D,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,MAAMF,UAAS,KAAK,WAAW,QAAQ,GAAG,MAAM,CAAC;AAC1E,wBAAkB,KAAK;AACvB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,WAAW,KAAK,GAAG;AACrB,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,UAAkB,OAA0C;AAClF,WAAQ,MAAM,KAAK,WAAW,QAAQ,KAAM,kBAAkB,KAAK,YAAY,UAAU,KAAK;AAAA,EAChG;AAAA,EAEA,MAAM,YAAY,OAAmC;AACnD,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAMC,OAAMC,MAAK,KAAK,aAAa,YAAY,WAAW,MAAM,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9F,UAAM,YAAY,KAAK,WAAW,MAAM,QAAQ,GAAG,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EAC1F;AAAA,EAEQ,aAAqB;AAC3B,WAAOA,MAAK,KAAK,aAAa,YAAY,gBAAgB;AAAA,EAC5D;AAAA,EAEQ,WAAW,UAA0B;AAC3C,WAAOA,MAAK,KAAK,aAAa,YAAY,WAAW,UAAU,gBAAgB;AAAA,EACjF;AACF;AAEA,SAAS,WAAW,OAAyB;AAC3C,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,MAAM,SAAS;AAC1F;;;AEtEA,SAAS,YAAAC,iBAAgB;AAEzB,eAAsB,qBAAqB,WAAsC;AAC/E,MAAI;AACJ,MAAI;AACF,cAAU,MAAMA,UAAS,WAAW,MAAM;AAAA,EAC5C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAsB,CAAC;AAC7B,QAAM,UAAU;AAChB,MAAI;AACJ,SAAQ,QAAQ,QAAQ,KAAK,OAAO,GAAI;AACtC,QAAI,MAAM,CAAC,GAAG;AACZ,gBAAU,KAAK,MAAM,CAAC,CAAC;AAAA,IACzB;AAAA,EACF;AACA,SAAO;AACT;;;ACbA,IAAM,iBAA8C;AAAA,EAClD,SAAS;AAAA,EACT,SAAS;AAAA,EACT,KAAK;AAAA,EACL,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,SAAS;AACX;AAEA,eAAsB,aAAa,KAAwB,SAAiB,MAA+B;AACzG,QAAM,eAAe,gBAAgB,IAAI;AACzC,QAAM;AAAA,IACJ,IAAI;AAAA,IACJ,EAAE,SAAS,KAAK,IAAI,KAAK,YAAY,IAAI,WAAW;AAAA,IACpD,YAAY;AACV,UAAI,CAAC,QAAQ,WAAW,cAAc,EAAE,SAAS,OAAO,GAAG;AACzD,cAAM,eAAe,GAAG;AAAA,MAC1B;AAEA,YAAM,SAAS,MAAM,mBAAmB,KAAK,SAAS,YAAY;AAClE,YAAM,SAAS,MAAM,IAAI,SAAS,IAAI,OAAO,SAAS,OAAO,MAAM,EAAE,KAAK,IAAI,aAAa,OAAO,IAAI,OAAO,SAAS,UAAU,CAAC;AACjI,UAAI,OAAO,aAAa,GAAG;AACzB,cAAM,IAAI,SAAS;AAAA,UACjB;AAAA,UACA,SAAS,YAAY,OAAO;AAAA,UAC5B,SAAS;AAAA,UACT,aAAa;AAAA,QACf,CAAC;AAAA,MACH;AAEA,YAAM,aAAa,MAAM,IAAI,SAAS,eAAe,IAAI,WAAW;AACpE,YAAM,QAAQ,MAAM,IAAI,WAAW,kBAAkB;AACrD,YAAM,gBAAgB,WAAW;AACjC,UAAI,IAAI,YAAY,WAAW,QAAQ,SAAS,IAAI,QAAQ,GAAG;AAC7D,cAAM,iBAAiB,IAAI;AAAA,MAC7B,WAAW,MAAM,kBAAkB,CAAC,WAAW,QAAQ,SAAS,MAAM,cAAc,GAAG;AACrF,cAAM,iBAAiB,WAAW,QAAQ,WAAW,IAAK,WAAW,QAAQ,CAAC,KAAK,OAAQ;AAAA,MAC7F,WAAW,CAAC,MAAM,kBAAkB,WAAW,QAAQ,WAAW,GAAG;AACnE,cAAM,iBAAiB,WAAW,QAAQ,CAAC,KAAK;AAAA,MAClD;AACA,YAAM,IAAI,WAAW,YAAY,KAAK;AAEtC,YAAM,WAAW,IAAI,YAAY,MAAM;AACvC,UAAI,YAAY,WAAW,QAAQ,SAAS,QAAQ,GAAG;AACrD,cAAM,mBAAmB,MAAM,IAAI,SAAS,cAAc,IAAI,aAAa,QAAQ;AACnF,cAAM,cAAc,MAAM,IAAI,WAAW,kBAAkB,UAAU,eAAe,OAAO,KAAK,SAAS;AACzG,oBAAY,eAAe,eAAe,OAAO,KAAK,YAAY;AAClE,oBAAY,OAAO,YAAY,YAAY,IAAI;AAAA,UAC7C,QAAQ;AAAA,UACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AACA,oBAAY,sBAAsB;AAAA,UAChC,SAAS,OAAO;AAAA,UAChB,MAAM,OAAO;AAAA,UACb,UAAU,OAAO;AAAA,UACjB,QAAO,oBAAI,KAAK,GAAE,YAAY;AAAA,QAChC;AACA,oBAAY,MAAM,eAAe,MAAM,qBAAqB,iBAAiB,SAAS;AACtF,oBAAY,MAAM,gBAAe,oBAAI,KAAK,GAAE,YAAY;AACxD,cAAM,IAAI,WAAW,YAAY,WAAW;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,OAAO;AAAA,IAChB,IAAI;AAAA,IACJ;AAAA,IACA,SAAS,OAAO,OAAO;AAAA,EACzB,CAAC;AACH;AAEA,eAAsB,mBAAmB,KAAwB,SAAiB,MAA+B;AAC/G,QAAM,SAAS,MAAM,IAAI,SAAS,IAAI,SAAS,gBAAgB,IAAI,GAAG,EAAE,KAAK,IAAI,aAAa,OAAO,IAAI,OAAO,SAAS,UAAU,CAAC;AACpI,MAAI,OAAO,aAAa,GAAG;AACzB,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS,YAAY,OAAO;AAAA,MAC5B,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAEA,SAAS,gBAAgB,MAA0B;AACjD,QAAM,SAAmB,CAAC;AAC1B,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,QAAQ,WAAW,QAAQ,YAAY;AACzC,eAAS;AACT;AAAA,IACF;AACA,QAAI,KAAK,WAAW,QAAQ,KAAK,KAAK,WAAW,WAAW,GAAG;AAC7D;AAAA,IACF;AACA,QAAI,QAAQ,WAAW,QAAQ,YAAY,QAAQ,eAAe,QAAQ,cAAc;AACtF;AAAA,IACF;AACA,QAAI,KAAK;AACP,aAAO,KAAK,GAAG;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,mBACb,KACA,SACA,MAC8C;AAC9C,UAAQ,SAAS;AAAA,IACf,KAAK;AAAA,IACL,KAAK;AACH,aAAO,EAAE,SAAS,OAAO,MAAM,KAAK,CAAC,MAAM,WAAW,OAAO,CAAC,UAAU,GAAG,IAAI,EAAE;AAAA,IACnF,KAAK;AACH,aAAO,EAAE,SAAS,gBAAgB,MAAM,CAAC,GAAG,iBAAiB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,YAAY,MAAM,gBAAgB,GAAG,CAAC,EAAE;AAAA,IAC5I,KAAK;AACH,aAAO,EAAE,SAAS,UAAU,MAAM,CAAC,YAAY,MAAM,gBAAgB,GAAG,CAAC,EAAE;AAAA,IAC7E,KAAK;AACH,aAAO,EAAE,SAAS,gBAAgB,MAAM,CAAC,SAAS,YAAY,MAAM,gBAAgB,GAAG,CAAC,EAAE;AAAA,IAC5F,KAAK;AACH,aAAO,EAAE,SAAS,YAAY,MAAM,CAAC,IAAI,YAAY,KAAK,CAAC,KAAM,MAAM,gBAAgB,GAAG,GAAI,UAAU,UAAU,UAAU,EAAE;AAAA,IAChI,KAAK;AACH,aAAO,EAAE,SAAS,WAAW,MAAM,CAAC,IAAI,YAAY,KAAK,CAAC,KAAM,MAAM,gBAAgB,GAAG,GAAI,GAAG,KAAK,MAAM,IAAI,WAAW,IAAI,CAAC,CAAC,EAAE;AAAA,IACpI,KAAK;AACH,YAAM,IAAI,SAAS;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB,CAAC;AAAA,IACH,KAAK;AACH,aAAO,EAAE,SAAS,gBAAgB,MAAM,CAAC,YAAY,YAAY,MAAM,gBAAgB,GAAG,CAAC,EAAE;AAAA,IAC/F,KAAK;AACH,aAAO,EAAE,SAAS,gBAAgB,MAAM,CAAC,EAAE;AAAA,IAC7C;AACE,aAAO,EAAE,SAAS,KAAK;AAAA,EAC3B;AACF;AAEA,eAAe,gBAAgB,KAAyC;AACtE,MAAI,IAAI,UAAU;AAChB,WAAO,IAAI;AAAA,EACb;AACA,QAAM,QAAQ,MAAM,IAAI,WAAW,kBAAkB;AACrD,MAAI,MAAM,gBAAgB;AACxB,WAAO,MAAM;AAAA,EACf;AACA,QAAM,aAAa,MAAM,IAAI,SAAS,eAAe,IAAI,WAAW;AACpE,MAAI,WAAW,QAAQ,WAAW,KAAK,WAAW,QAAQ,CAAC,GAAG;AAC5D,WAAO,WAAW,QAAQ,CAAC;AAAA,EAC7B;AACA,QAAM,IAAI,SAAS;AAAA,IACjB;AAAA,IACA,SAAS;AAAA,IACT,SAAS,EAAE,eAAe,WAAW,QAAQ;AAAA,IAC7C,kBAAkB;AAAA,EACpB,CAAC;AACH;AAEA,SAAS,iBAAiB,QAA4B;AACpD,SAAO,OAAO,OAAO,OAAO;AAC9B;AAEA,eAAe,eAAe,KAAuC;AACnE,QAAM,SAAS,MAAM,IAAI,WAAW,kBAAkB;AACtD,QAAM,WAAW,IAAI,YAAY,OAAO;AACxC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACA,QAAM,SAAS,MAAM,IAAI,WAAW,WAAW,QAAQ;AACvD,QAAM,aAAa,MAAM,IAAI,SAAS,eAAe,IAAI,WAAW;AACpE,MAAI,CAAC,WAAW,QAAQ,SAAS,QAAQ,GAAG;AAC1C,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,SAAS,EAAE,UAAU,eAAe,WAAW,QAAQ;AAAA,MACvD,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACA,MAAI,QAAQ,cAAc,WAAW,iBAAiB;AACpD,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,SAAS,EAAE,SAAS;AAAA,MACpB,kBAAkB,uBAAuB,QAAQ;AAAA,IACnD,CAAC;AAAA,EACH;AACF;;;ACxMA,SAAS,kBAAkB;AAC3B,SAAS,SAAAC,QAAO,YAAAC,WAAU,QAAAC,aAAY;AACtC,SAAS,QAAAC,aAAY;AAOrB,eAAsB,cAAc,KAAwB,SAA4D;AACtH,MAAI,QAAQ,MAAM;AAChB,UAAM,OAAO,MAAM,IAAI,QAAQ,KAAK,IAAI,aAAa,CAAC,CAAC;AACvD,UAAM,OAAO;AAAA,MACX,eAAe;AAAA,MACf,gBAAgB,KAAK,QAAQ;AAAA,MAC7B,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,KAAK;AAAA,UACL,UAAU,OAAO,QAAQ,KAAK,QAAQ,EACnC,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,aAAa,MAAM,EAAE,SAAS,IAAI,CAAC,EAC/D,IAAI,CAAC,CAAC,WAAW,OAAO,OAAO;AAAA,YAC9B;AAAA,YACA,SAAS,QAAQ;AAAA,YACjB,QAAQ,QAAQ;AAAA,YAChB,UAAU,QAAQ;AAAA,YAClB,iBAAiB,QAAQ,WAAW,SAAS;AAAA,UAC/C,EAAE;AAAA,QACN;AAAA,MACF;AAAA,MACA,SAAS,CAAC,QAAQ,aAAa,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,SAAS,IAAI,CAAC;AAAA,IAC9E;AACA,QAAI,IAAI,KAAK;AACX,YAAM,SAAS,MAAM,IAAI,WAAW,kBAAkB;AACtD,aAAO,sBAAsB;AAAA,QAC3B,eAAe;AAAA,QACf,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACnC,oBAAoB,YAAY,IAAI;AAAA,QACpC,gBAAgB,KAAK;AAAA,QACrB,MAAM,KAAK,WAAW;AAAA,UAAQ,CAAC,cAC7B,UAAU,SAAS,IAAI,CAAC,aAAa;AAAA,YACnC,KAAK,UAAU;AAAA,YACf,WAAW,QAAQ;AAAA,YACnB,SAAS,QAAQ;AAAA,YACjB,QAAQ,QAAQ;AAAA,YAChB,UAAU,QAAQ;AAAA,UACpB,EAAE;AAAA,QACJ;AAAA,MACF;AACA,YAAM,IAAI,WAAW,YAAY,MAAM;AAAA,IACzC;AAEA,QAAI,OAAO,OAAO;AAAA,MAChB,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,SAAS,IAAI,MAAM,8HAAyC;AAAA,MAC5D,UAAU,KAAK,QAAQ,IAAI,CAAC,SAAS,sBAAO,IAAI,+GAAqB;AAAA,MACrE,MAAM;AAAA,MACN,WAAW,IAAI,MAAM,CAAC,wGAA6B,IAAI,CAAC,wCAAU,4EAAoC,wGAA6B;AAAA,IACrI,CAAC;AACD;AAAA,EACF;AAEA,QAAM;AAAA,IACJ,IAAI;AAAA,IACJ,EAAE,SAAS,UAAU,KAAK,IAAI,KAAK,YAAY,IAAI,WAAW;AAAA,IAC9D,YAAY;AACV,YAAM,WAAW,MAAM,gBAAgB,GAAG;AAC1C,UAAI,QAAQ,MAAM;AAChB,cAAM,SAAS,KAAK,QAAQ;AAAA,MAC9B,OAAO;AACL,cAAM,kBAAkB,KAAK,QAAQ;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,kBAAkB,KAAwB,UAAiC;AACxF,QAAM,mBAAmB,KAAK,QAAQ;AACtC,QAAM,eAAc,oBAAI,KAAK,GAAE,YAAY;AAC3C,QAAM,MAAMC,MAAK,IAAI,aAAa,YAAY,WAAW,UAAU,MAAM;AACzE,QAAM,mBAAmBA,MAAK,KAAK,wBAAwB;AAC3D,QAAMC,OAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACpC,QAAM,YAAY,kBAAkB,yBAAyB,UAAU,WAAW,CAAC;AAEnF,QAAM,QAAQ,MAAM,IAAI,WAAW,kBAAkB,UAAU,QAAQ;AACvE,QAAM,eAAe;AACrB,QAAM,OAAO,SAAS,EAAE,QAAQ,eAAe,WAAW,YAAY;AACtE,QAAM,IAAI,WAAW,YAAY,KAAK;AAEtC,MAAI,OAAO,OAAO;AAAA,IAChB,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,iCAAuB,QAAQ,gCAAgC,6DAAoC,QAAQ,EAAE;AAAA,EAC3H,CAAC;AACH;AAEA,eAAe,SAAS,KAAwB,UAAiC;AAC/E,QAAM,mBAAmB,KAAK,QAAQ;AACtC,QAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC1C,QAAM,mBAAmBD,MAAK,IAAI,aAAa,YAAY,WAAW,UAAU,QAAQ,wBAAwB;AAChH,QAAM,eAAe,MAAM,iBAAiB,kBAAkB,QAAQ;AACtE,QAAM,0BAA0B,qBAAqB,cAAc,aAAa,KAAK;AACrF,QAAM,QAAQ,MAAM,IAAI,WAAW,kBAAkB,UAAU,QAAQ;AACvE,QAAM,eAAe;AACrB,QAAM,OAAO,SAAS,EAAE,QAAQ,QAAQ,WAAW,WAAW;AAC9D,QAAM,eAAe;AAAA,IACnB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR;AAAA,IACA,kBAAkB,oBAAoB,QAAQ;AAAA,IAC9C;AAAA,IACA,UAAU;AAAA,EACZ;AACA,QAAM,IAAI,WAAW,YAAY,KAAK;AAEtC,MAAI,OAAO,OAAO;AAAA,IAChB,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW,CAAC,qBAAqB,QAAQ,IAAI,wBAAwB,QAAQ,EAAE;AAAA,EACjF,CAAC;AACH;AAEA,eAAe,mBAAmB,KAAwB,UAAiC;AACzF,QAAM,aAAa,MAAM,IAAI,SAAS,cAAc,IAAI,aAAa,QAAQ;AAC7E,MAAI,CAAC,WAAW,QAAQ;AACtB,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,SAAS,EAAE,SAAS;AAAA,MACpB,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACF;AAEA,eAAe,iBAAiB,MAAc,UAAmC;AAC/E,MAAI;AACF,UAAME,MAAK,IAAI;AACf,UAAM,UAAU,MAAMC,UAAS,MAAM,MAAM;AAC3C,UAAM,eAAe,qBAAqB,SAAS,UAAU;AAC7D,QAAI,iBAAiB,UAAU;AAC7B,YAAM,IAAI,SAAS;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,SAAS,EAAE,UAAU,UAAU,QAAQ,aAAa;AAAA,QACpD,kBAAkB,uBAAuB,QAAQ;AAAA,MACnD,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,UAAU;AAC7B,YAAM;AAAA,IACR;AACA,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,SAAS,EAAE,KAAK;AAAA,MAChB,kBAAkB,uBAAuB,QAAQ;AAAA,IACnD,CAAC;AAAA,EACH;AACF;AAEA,SAAS,qBAAqB,SAAiB,KAA4B;AACzE,QAAM,QAAQ,QAAQ,MAAM,IAAI,OAAO,IAAI,GAAG,cAAc,GAAG,CAAC;AAChE,SAAO,QAAQ,CAAC,GAAG,KAAK,KAAK;AAC/B;AAEA,SAAS,YAAY,OAAwB;AAC3C,SAAO,UAAU,WAAW,QAAQ,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;AACnF;AAEA,eAAe,gBAAgB,KAAyC;AACtE,MAAI,IAAI,UAAU;AAChB,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,SAAS,MAAM,IAAI,WAAW,kBAAkB;AACtD,MAAI,OAAO,gBAAgB;AACzB,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,aAAa,MAAM,IAAI,SAAS,eAAe,IAAI,WAAW;AACpE,MAAI,WAAW,QAAQ,WAAW,KAAK,WAAW,QAAQ,CAAC,GAAG;AAC5D,WAAO,WAAW,QAAQ,CAAC;AAAA,EAC7B;AAEA,QAAM,IAAI,SAAS;AAAA,IACjB;AAAA,IACA,SAAS;AAAA,IACT,SAAS,EAAE,eAAe,WAAW,QAAQ;AAAA,IAC7C,kBAAkB;AAAA,EACpB,CAAC;AACH;;;AClMA,SAAS,eAAe;;;ACAxB,SAAS,SAAAC,QAAO,YAAAC,WAAU,QAAAC,aAAY;AACtC,SAAS,WAAAC,UAAS,QAAAC,cAAY;;;ACC9B,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,mBAA6D;AAC3E,SAAO,SAAS,IAAI,CAAC,aAAa;AAAA,IAChC,MAAM,sBAAsB,OAAO;AAAA,IACnC,SAAS,YAAY,OAAO;AAAA,EAC9B,EAAE;AACJ;AAEO,SAAS,iBAAoD;AAClE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA;AAAA,cAEC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBvB;AACF;AAEA,SAAS,YAAY,SAAyB;AAC5C,SAAO;AAAA;AAAA,cAEK,WAAW;AAAA;AAAA;AAAA,eAGV,OAAO;AAAA;AAAA;AAAA;AAAA,YAIV,OAAO;AAAA,wCACqB,OAAO;AAAA;AAAA;AAAA;AAAA,wHAIP,OAAO,kGAA4B,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAK5E,OAAO;AAAA;AAAA;AAAA;AAAA;AAKb;;;ADjEO,IAAM,gBAAN,MAA2C;AAAA,EACvC,OAAO;AAAA,EACP,iBAAiB;AAAA,EAE1B,MAAM,OAAO,aAAqB;AAChC,WAAO;AAAA,MACL,UAAU,MAAMC,QAAOC,OAAK,aAAa,SAAS,CAAC;AAAA,MACnD,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,cAAgD;AAChE,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,OAAO,CAAC,GAAG,iBAAiB,GAAG,eAAe,CAAC,EAAE,IAAI,CAAC,UAAU;AAAA,QAC9D,GAAG;AAAA,QACH,SAAS;AAAA,MACX,EAAE;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,aAAqB,MAAuB,QAAQ,OAAmC;AACnG,UAAM,UAAoB,CAAC;AAC3B,UAAM,UAAoB,CAAC;AAE3B,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,SAASA,OAAK,aAAa,KAAK,IAAI;AAC1C,YAAM,WAAW,MAAM,aAAa,MAAM;AAC1C,UAAI,YAAY,CAAC,SAAS,SAAS,aAAa,KAAK,CAAC,OAAO;AAC3D,cAAM,IAAI,SAAS;AAAA,UACjB;AAAA,UACA,SAAS;AAAA,UACT,SAAS,EAAE,MAAM,KAAK,KAAK;AAAA,UAC3B,kBAAkB;AAAA,QACpB,CAAC;AAAA,MACH;AACA,UAAI,YAAY,CAAC,SAAS,SAAS,aAAa,KAAK,OAAO;AAC1D,cAAM,aAAa,MAAM;AAAA,MAC3B;AACA,YAAMC,OAAMC,SAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,YAAM,YAAY,QAAQ,KAAK,OAAO;AACtC,cAAQ,KAAK,KAAK,IAAI;AAAA,IACxB;AAEA,WAAO,EAAE,MAAM,KAAK,MAAM,SAAS,QAAQ;AAAA,EAC7C;AAAA,EAEA,MAAM,OAAO,aAA6C;AACxD,UAAM,OAAO,MAAM,KAAK,YAAY,WAAW;AAC/C,UAAM,SAAwB,CAAC;AAC/B,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,SAASF,OAAK,aAAa,KAAK,IAAI;AAC1C,YAAM,UAAU,MAAM,aAAa,MAAM;AACzC,YAAM,UAAU,QAAQ,SAAS,SAAS,aAAa,CAAC;AACxD,YAAM,iBAAiB,QAAQ,SAAS,SAAS,mBAAmB,KAAK,cAAc,EAAE,CAAC;AAC1F,aAAO,KAAK;AAAA,QACV,IAAI,UAAU,KAAK,IAAI;AAAA,QACvB,QAAQ,CAAC,UAAU,SAAS,WAAW,iBAAiB,SAAS;AAAA,QACjE,SAAS,CAAC,UACN,GAAG,KAAK,IAAI,kBACZ,CAAC,UACC,GAAG,KAAK,IAAI,qDACZ,CAAC,iBACC,GAAG,KAAK,IAAI,uCACZ,GAAG,KAAK,IAAI;AAAA,QACpB,kBAAkB,CAAC,WAAW,CAAC,WAAW,CAAC,iBAAiB,aAAa;AAAA,MAC3E,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;AAEA,eAAe,aAAa,MAAsC;AAChE,MAAI;AACF,WAAO,MAAMG,UAAS,MAAM,MAAM;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAeJ,QAAO,MAAgC;AACpD,MAAI;AACF,UAAMK,MAAK,IAAI;AACf,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AEhGA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,aAAAC,kBAAiB;;;ACD1B,SAAS,SAAS,QAAAC,aAAY;AAC9B,SAAS,QAAAC,cAAY;AAGrB,eAAsB,uBAAuB,aAAyD;AACpG,QAAM,eAAeA,OAAK,aAAa,UAAU;AACjD,QAAM,cAAcA,OAAK,cAAc,SAAS;AAChD,QAAM,cAAcA,OAAK,cAAc,SAAS;AAEhD,SAAO;AAAA,IACL,QAAQ,MAAMC,QAAO,YAAY;AAAA,IACjC,SAAS,MAAM,gBAAgB,WAAW;AAAA,IAC1C,UAAU,MAAM,gBAAgB,WAAW;AAAA,EAC7C;AACF;AAEA,eAAsB,sBACpB,aACA,UACmC;AACnC,QAAM,aAAaD,OAAK,aAAa,YAAY,WAAW,QAAQ;AACpE,QAAM,YAAYA,OAAK,YAAY,UAAU;AAC7C,QAAM,YAAYA,OAAK,YAAY,OAAO;AAE1C,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MAAMC,QAAO,UAAU;AAAA,IAC/B,aAAa,MAAMA,QAAOD,OAAK,YAAY,aAAa,CAAC;AAAA,IACzD,UAAU,MAAMC,QAAO,SAAS;AAAA,IAChC,UAAU,MAAMA,QAAO,SAAS;AAAA,IAChC;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,gBAAgB,MAAiC;AAC9D,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAC3D,WAAO,QAAQ,OAAO,CAAC,UAAU,MAAM,YAAY,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,EACjF,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAeA,QAAO,MAAgC;AACpD,MAAI;AACF,UAAMF,MAAK,IAAI;AACf,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACnDA,SAAS,YAAAG,iBAAgB;AACzB,SAAS,aAAAC,kBAAiB;AAK1B,IAAMC,iBAAgBC,WAAUC,SAAQ;AAExC,eAAsB,4BAAuD;AAC3E,QAAM,iBAAiB,MAAM,eAAe;AAC5C,QAAM,UAAU,MAAM,YAAY,cAAc;AAChD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,EAClB;AACF;AAEA,eAAe,iBAAkC;AAC/C,QAAM,UAAU,QAAQ,aAAa,UAAU,cAAc;AAC7D,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,KAAK,SAAS,CAAC,UAAU,CAAC;AACnD,UAAM,QAAQ,OACX,MAAM,OAAO,EACb,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,KAAK,OAAO;AACf,QAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,KAAK,OAAO,CAAC,YAAY,WAAW,CAAC;AAC3C,WAAO;AAAA,EACT,QAAQ;AACN,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACF;AAEA,eAAe,YAAY,gBAAyC;AAClE,QAAM,UAAU,mBAAmB,iBAAiB,QAAQ;AAC5D,QAAM,OAAO,mBAAmB,iBAAiB,CAAC,YAAY,WAAW,IAAI,CAAC,WAAW;AACzF,MAAI;AACF,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,KAAK,SAAS,IAAI;AACnD,WAAO,OAAO,KAAK,KAAK,OAAO,KAAK,KAAK;AAAA,EAC3C,SAAS,OAAO;AACd,UAAM,IAAI,SAAS;AAAA,MACjB;AAAA,MACA,SAAS;AAAA,MACT,SAAS,EAAE,eAAe;AAAA,MAC1B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEA,SAAS,KAAK,SAAiB,MAAgB;AAC7C,SAAOF,eAAc,SAAS,MAAM,EAAE,OAAO,QAAQ,aAAa,QAAQ,CAAC;AAC7E;;;AC/DA,SAAS,aAAa;AAKtB,eAAsB,YACpB,gBACA,SACA,MACA,SAC4B;AAC5B,QAAM,eAAe,mBAAmB,iBAAiB,QAAQ;AACjE,QAAM,YAAY,mBAAmB,iBAAiB,CAAC,YAAY,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI;AAExG,SAAO,IAAI,QAAQ,CAACG,UAAS,WAAW;AACtC,UAAM,SAAmB,CAAC;AAC1B,UAAM,SAAmB,CAAC;AAC1B,UAAM,QAAQ,MAAM,cAAc,WAAW;AAAA,MAC3C,KAAK,QAAQ;AAAA,MACb,OAAO,QAAQ,SAAS;AAAA,MACxB,OAAO,QAAQ,aAAa;AAAA,IAC9B,CAAC;AAED,QAAI,MAAM,QAAQ;AAChB,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB,OAAO,KAAK,KAAK,CAAC;AAAA,IAC/D;AACA,QAAI,MAAM,QAAQ;AAChB,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB,OAAO,KAAK,KAAK,CAAC;AAAA,IAC/D;AAEA,UAAM,GAAG,SAAS,CAAC,UAAU;AAC3B;AAAA,QACE,IAAI,SAAS;AAAA,UACX;AAAA,UACA,SAAS;AAAA,UACT,SAAS,EAAE,SAAS,KAAK;AAAA,UACzB,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,UAAU,WAAW;AACtC,MAAAA,SAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA,UAAU,YAAY;AAAA,QACtB;AAAA,QACA,QAAQ,OAAO,SAAS,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,IAAI;AAAA,QACjE,QAAQ,OAAO,SAAS,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,IAAI;AAAA,MACnE,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;;;AHrCA,IAAMC,iBAAgBC,WAAUC,SAAQ;AAEjC,IAAM,yBAAN,MAAwD;AAAA,EACrD;AAAA,EAER,MAAM,oBAA+C;AACnD,SAAK,aAAa,MAAM,0BAA0B;AAClD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,kBAAiD;AACrD,UAAM,WAAW,MAAM,KAAK,kBAAkB;AAC9C,UAAM,aAAa,SAAS,mBAAmB,iBAAiB,QAAQ,SAAS;AACjF,UAAM,OAAO,SAAS,mBAAmB,iBAAiB,CAAC,YAAY,QAAQ,IAAI,CAAC,QAAQ;AAE5F,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAMF,eAAc,YAAY,MAAM,EAAE,OAAO,QAAQ,aAAa,QAAQ,CAAC;AAChG,aAAO;AAAA,QACL,SAAS,SAAS;AAAA,QAClB,UAAU,cAAc,MAAM;AAAA,QAC9B,WAAW;AAAA,MACb;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,SAAS,SAAS;AAAA,QAClB,UAAU,CAAC;AAAA,QACX,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,SAAiB,MAAgB,SAAyD;AAClG,UAAM,WAAW,MAAM,KAAK,kBAAkB;AAC9C,WAAO,YAAY,SAAS,gBAAgB,SAAS,MAAM,OAAO;AAAA,EACpE;AAAA,EAEA,eAAe,aAAyD;AACtE,WAAO,uBAAuB,WAAW;AAAA,EAC3C;AAAA,EAEA,cAAc,aAAqB,UAAqD;AACtF,WAAO,sBAAsB,aAAa,QAAQ;AAAA,EACpD;AACF;AAEA,SAAS,cAAc,MAAwB;AAC7C,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,MAAM,OAAO,CAAC,YAAY,KAAK,SAAS,OAAO,CAAC;AACzD;;;AI5EA,SAAS,YAAAG,YAAU,QAAAC,aAAY;AAC/B,SAAS,QAAAC,cAAY;AACrB,SAAS,SAAAC,cAAa;AAYtB,eAAsB,gBAAgB,aAAkD;AACtF,MAAI;AACF,WAAO,KAAK,MAAM,MAAMH,WAASE,OAAK,aAAa,cAAc,GAAG,MAAM,CAAC;AAAA,EAC7E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,qBAAqB,aAAqB,KAA2D;AACzH,QAAM,WAAqB,CAAC;AAC5B,MAAI,KAAK,gBAAgB;AACvB,UAAM,WAAW,IAAI,eAAe,MAAM,GAAG,EAAE,CAAC,KAAK;AACrD,UAAME,SAAQ,MAAM,mBAAmB,WAAW;AAClD,UAAM,cAAcA,OAAM,OAAO,CAAC,SAAS,SAAS,QAAQ;AAC5D,QAAI,YAAY,QAAQ;AACtB,eAAS,KAAK,qCAAsB,QAAQ,+DAAa,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,IACnF;AACA,WAAO,EAAE,SAAS,UAAU,YAAY,QAAQ,SAAS;AAAA,EAC3D;AAEA,QAAM,QAAQ,MAAM,mBAAmB,WAAW;AAClD,MAAI,MAAM,SAAS,GAAG;AACpB,aAAS,KAAK,2EAAe,MAAM,KAAK,IAAI,CAAC,kCAAS,MAAM,CAAC,CAAC,EAAE;AAChE,WAAO,EAAE,SAAS,MAAM,CAAC,KAAK,OAAO,YAAY,UAAU,SAAS;AAAA,EACtE;AACA,MAAI,MAAM,CAAC,GAAG;AACZ,WAAO,EAAE,SAAS,MAAM,CAAC,GAAG,YAAY,QAAQ,SAAS;AAAA,EAC3D;AACA,SAAO,EAAE,SAAS,OAAO,YAAY,OAAO,SAAS;AACvD;AAEO,SAAS,gBAAgB,KAAyB,gBAAwD;AAC/G,QAAM,UAAU,KAAK,WAAW,CAAC;AACjC,QAAM,SAAyC,CAAC;AAChD,QAAM,cAAc,CAAC,OAAO,SAAS,QAAQ,aAAa,SAAS,QAAQ,WAAW;AAEtF,aAAW,QAAQ,aAAa;AAC9B,QAAI,QAAQ,IAAI,GAAG;AACjB,YAAM,YAAY,SAAS,UAAU,cAAc,SAAS,cAAc,SAAS;AACnF,UAAI,OAAO,SAAS,GAAG;AACrB;AAAA,MACF;AACA,aAAO,SAAS,IAAI;AAAA,QAClB,SAAS,cAAc,gBAAgB,IAAI;AAAA,QAC3C,QAAQ,wBAAwB,IAAI;AAAA,QACpC,UAAU,SAAS;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,gBAAgB,KAAqG;AACnI,QAAM,OAAO,EAAE,GAAI,KAAK,gBAAgB,CAAC,GAAI,GAAI,KAAK,mBAAmB,CAAC,EAAG;AAC7E,QAAM,aAAwC;AAAA,IAC5C,CAAC,QAAQ,CAAC,MAAM,CAAC;AAAA,IACjB,CAAC,QAAQ,CAAC,MAAM,CAAC;AAAA,IACjB,CAAC,QAAQ,CAAC,MAAM,CAAC;AAAA,IACjB,CAAC,aAAa,CAAC,eAAe,CAAC;AAAA,IAC/B,CAAC,WAAW,CAAC,iBAAiB,cAAc,CAAC;AAAA,IAC7C,CAAC,SAAS,CAAC,OAAO,CAAC;AAAA,IACnB,CAAC,OAAO,CAAC,KAAK,CAAC;AAAA,IACf,CAAC,UAAU,CAAC,QAAQ,CAAC;AAAA,EACvB;AACA,aAAW,CAAC,WAAW,QAAQ,KAAK,YAAY;AAC9C,QAAI,SAAS,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,GAAG;AACvC,aAAO,EAAE,MAAM,WAAW,YAAY,QAAQ,SAAS,CAAC,cAAc,EAAE;AAAA,IAC1E;AAAA,EACF;AACA,SAAO,EAAE,MAAM,WAAW,YAAY,OAAO,SAAS,CAAC,EAAE;AAC3D;AAEA,eAAsB,eAAe,aAAqB,KAA0C;AAClG,QAAM,OAAO,EAAE,GAAI,KAAK,gBAAgB,CAAC,GAAI,GAAI,KAAK,mBAAmB,CAAC,EAAG;AAC7E,MAAI,KAAK,cAAe,MAAMC,QAAOH,OAAK,aAAa,eAAe,CAAC,GAAI;AACzE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,eAAsB,iBAAiB,aAAqB,KAAsD;AAChH,QAAM,oBAAoB,oBAAoB,KAAK,UAAU,EAAE,IAAI,CAAC,UAAU;AAAA,IAC5E,MAAM;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,EACV,EAAE;AACF,MAAI,kBAAkB,QAAQ;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,YAAYC,OAAM,MAAMH,WAASE,OAAK,aAAa,qBAAqB,GAAG,MAAM,CAAC;AACxF,YAAQ,WAAW,YAAY,CAAC,GAAG,IAAI,CAAC,UAAU;AAAA,MAChD,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,IACV,EAAE;AAAA,EACJ,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAe,mBAAmB,aAAwC;AACxE,QAAM,YAAqC;AAAA,IACzC,CAAC,kBAAkB,MAAM;AAAA,IACzB,CAAC,aAAa,MAAM;AAAA,IACpB,CAAC,aAAa,KAAK;AAAA,IACnB,CAAC,YAAY,KAAK;AAAA,IAClB,CAAC,qBAAqB,KAAK;AAAA,EAC7B;AACA,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,MAAM,OAAO,KAAK,WAAW;AACvC,QAAI,MAAMG,QAAOH,OAAK,aAAa,IAAI,CAAC,GAAG;AACzC,YAAM,KAAK,OAAO;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,YAAiD;AAC5E,MAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,YAAY,YAAY,CAAC;AAClC;AAEA,SAAS,cAAc,gBAAwB,MAAsB;AACnE,SAAO,mBAAmB,QAAQ,WAAW,IAAI,KAAK,GAAG,cAAc,IAAI,IAAI;AACjF;AAEA,eAAeG,QAAO,MAAgC;AACpD,MAAI;AACF,UAAMJ,MAAK,IAAI;AACf,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC9JA,SAAS,WAAAK,UAAS,QAAAC,aAAY;AAC9B,SAAS,QAAAC,QAAM,UAAU,WAAW;AAGpC,eAAsB,WAAW,aAA8C;AAC7E,QAAM,aAAa,CAAC,cAAc,aAAa,OAAO,OAAO;AAC7D,QAAM,SAAyB,CAAC;AAEhC,aAAW,aAAa,YAAY;AAClC,UAAM,OAAOA,OAAK,aAAa,SAAS;AACxC,QAAI,CAAE,MAAMC,QAAO,IAAI,GAAI;AACzB;AAAA,IACF;AACA,eAAW,QAAQ,MAAM,UAAU,IAAI,GAAG;AACxC,UAAI,CAAC,4BAA4B,KAAK,IAAI,GAAG;AAC3C;AAAA,MACF;AACA,aAAO,KAAK;AAAA,QACV,MAAM,eAAe,SAAS,MAAM,IAAI,CAAC;AAAA,QACzC,QAAQ,SAAS,aAAa,IAAI,EAAE,MAAM,GAAG,EAAE,KAAK,GAAG;AAAA,QACvD,UAAU;AAAA,QACV,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,OAAO,MAAM,GAAG,GAAG;AAC5B;AAEA,SAAS,eAAe,cAA8B;AACpD,QAAM,aAAa,aAAa,MAAM,GAAG,EAAE,KAAK,GAAG;AACnD,QAAM,aAAa,WAAW,QAAQ,6BAA6B,EAAE;AACrE,QAAM,eAAe,WAAW,QAAQ,YAAY,EAAE,EAAE,QAAQ,WAAW,EAAE;AAC7E,SAAO,IAAI,YAAY,GAAG,QAAQ,QAAQ,GAAG;AAC/C;AAEA,eAAe,UAAU,MAAiC;AACxD,QAAM,UAAU,MAAMH,SAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAC3D,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,UAAM,OAAOE,OAAK,MAAM,MAAM,IAAI;AAClC,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,KAAK,GAAI,MAAM,UAAU,IAAI,CAAE;AAAA,IACvC,OAAO;AACL,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAeC,QAAO,MAAgC;AACpD,MAAI;AACF,UAAMF,MAAK,IAAI;AACf,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACrDO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,MAAM,KAAK,aAAqB,WAAwB,CAAC,GAA+B;AACtF,UAAM,MAAM,MAAM,gBAAgB,WAAW;AAC7C,UAAM,iBAAiB,MAAM,qBAAqB,aAAa,GAAG;AAClE,UAAM,YAAY,gBAAgB,GAAG;AACrC,UAAM,aAAa,MAAM,iBAAiB,aAAa,GAAG;AAC1D,UAAM,WAAW,MAAM,eAAe,aAAa,GAAG;AACtD,UAAM,WAAW,CAAC,GAAG,eAAe,QAAQ;AAC5C,QAAI,UAAU,SAAS,WAAW;AAChC,eAAS,KAAK,sEAAyB;AAAA,IACzC;AAEA,WAAO;AAAA,MACL,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,gBAAgB;AAAA,MAChB,SAAS;AAAA,QACP,MAAM,KAAK,QAAQ;AAAA,QACnB,gBAAgB,eAAe;AAAA,QAC/B,0BAA0B,eAAe;AAAA,QACzC;AAAA,QACA;AAAA,QACA,UAAU,WAAW,SAAS;AAAA,QAC9B;AAAA,MACF;AAAA,MACA,UAAU,gBAAgB,KAAK,eAAe,OAAO;AAAA,MACrD,QAAQ,MAAM,WAAW,WAAW;AAAA,MACpC,aAAa,CAAC;AAAA,MACd,cAAc,CAAC;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;;;ACxBO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,MAAe;AAAf;AAAA,EAAgB;AAAA,EAAhB;AAAA,EAE7B,KAAK,SAAiB,SAAyB;AAC7C,QAAI,CAAC,KAAK,MAAM;AACd,cAAQ,OAAO,MAAM,GAAG,OAAO,GAAG,cAAc,OAAO,CAAC;AAAA,CAAI;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,KAAK,SAAiB,SAAyB;AAC7C,QAAI,CAAC,KAAK,MAAM;AACd,cAAQ,OAAO,MAAM,qBAAM,OAAO,GAAG,cAAc,OAAO,CAAC;AAAA,CAAI;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,OAAuB;AAC3B,QAAI,KAAK,MAAM;AACb,cAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,MAAM,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AACzF;AAAA,IACF;AAEA,YAAQ,OAAO,MAAM,qCAAY,MAAM,OAAO;AAAA,CAAI;AAClD,QAAI,MAAM,YAAY,QAAW;AAC/B,cAAQ,OAAO,MAAM;AAAA;AAAA,EAAU,YAAY,MAAM,OAAO,CAAC;AAAA,CAAI;AAAA,IAC/D;AACA,QAAI,MAAM,kBAAkB;AAC1B,cAAQ,OAAO,MAAM;AAAA;AAAA,IAAY,MAAM,gBAAgB;AAAA,CAAI;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,OAAO,QAA6B;AAClC,QAAI,KAAK,MAAM;AACb,cAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,CAAI;AAC3D;AAAA,IACF;AAEA,YAAQ,OAAO,MAAM,GAAG,OAAO,OAAO;AAAA,CAAI;AAC1C,eAAW,WAAW,OAAO,YAAY,CAAC,GAAG;AAC3C,cAAQ,OAAO,MAAM,qBAAM,OAAO;AAAA,CAAI;AAAA,IACxC;AACA,QAAI,OAAO,WAAW,QAAQ;AAC5B,cAAQ,OAAO,MAAM,8BAAU;AAC/B,iBAAW,QAAQ,OAAO,WAAW;AACnC,gBAAQ,OAAO,MAAM,KAAK,IAAI;AAAA,CAAI;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,SAA0B;AAC/C,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,SAAO,IAAI,KAAK,UAAU,OAAO,CAAC;AACpC;AAEA,SAAS,YAAY,SAA0B;AAC7C,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,KAAK,OAAO;AAAA,EACrB;AACA,SAAO,KAAK,UAAU,SAAS,MAAM,CAAC,EACnC,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,EACzB,KAAK,IAAI;AACd;;;AV3DA,eAAsB,qBAAqB,SAAiB,SAAwB;AAClF,QAAM,cAAc,QAAQ,QAAQ,OAAO,QAAQ,IAAI,CAAC;AACxD,QAAM,UAAU,MAAM,sBAAsB,WAAW;AACvD,QAAM,SAAS,IAAI,aAAa,QAAQ,QAAQ,IAAI,CAAC;AAErD,SAAO;AAAA,IACL;AAAA,IACA,KAAK;AAAA,IACL;AAAA,IACA,OAAO,QAAQ,QAAQ,OAAO,KAAK;AAAA,IACnC,MAAM,QAAQ,QAAQ,IAAI;AAAA,IAC1B,SAAS,QAAQ,QAAQ,OAAO;AAAA,IAChC,KAAK,QAAQ,QAAQ,GAAG;AAAA,IACxB,UAAU,QAAQ;AAAA,IAClB,YAAY;AAAA,IACZ;AAAA,IACA,YAAY,IAAI,WAAW,aAAa,aAAa,OAAO;AAAA,IAC5D,UAAU,IAAI,uBAAuB;AAAA,IACrC,SAAS,IAAI,eAAe;AAAA,IAC5B,cAAc,CAAC,IAAI,cAAc,CAAC;AAAA,EACpC;AACF;;;ArB1BA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,KAAK,EACV,YAAY,6DAA6D,EACzE,wBAAwB,EACxB,QAAQ,WAAW,EACnB,OAAO,gBAAgB,4CAAS,EAChC,OAAO,iBAAiB,8BAAoB,EAC5C,OAAO,SAAS,0EAAc,EAC9B,OAAO,UAAU,2CAAa,EAC9B,OAAO,aAAa,sCAAQ,EAC5B,OAAO,cAAc,sCAAQ;AAEhC,iBAAiB,QAAQ,QAAQ,MAAM,CAAC,EAAE,YAAY,mCAAoB,EAAE,OAAO,KAAK,QAAQ,WAAW,CAAC;AAC5G,iBAAiB,QAAQ,QAAQ,gBAAgB,CAAC,EAAE,YAAY,4CAAS,EAAE,OAAO,KAAK,kBAAkB,oBAAoB,CAAC;AAC9H,iBAAiB,QACd,QAAQ,QAAQ,EAChB,YAAY,oEAAa,EACzB,OAAO,cAAc,qCAAY,CAAC,EAClC;AAAA,EACC,KAAK,UAAU,CAAC,KAAK,YAAmC,cAAc,KAAK,EAAE,SAAS,QAAQ,QAAQ,OAAO,EAAE,CAAC,CAAC;AACnH;AAEF,iBAAiB,QACd,QAAQ,QAAQ,EAChB,YAAY,sCAAQ,EACpB,OAAO,UAAU,wDAAW,EAC5B,OAAO,UAAU,oEAAa,CAAC,EAC/B,OAAO,KAAK,UAAU,aAAa,CAAC;AAEvC,WAAW,WAAW,CAAC,WAAW,WAAW,OAAO,YAAY,MAAM,SAAS,QAAQ,WAAW,gBAAgB,SAAS,GAAG;AAC5H,mBAAiB,QACd,QAAQ,GAAG,OAAO,YAAY,EAC9B,YAAY,qCAAiB,OAAO,EAAE,EACtC,mBAAmB,IAAI,EACvB,mBAAmB,CAAC,EACpB,OAAO,KAAK,SAAS,CAAC,KAAK,OAAiB,CAAC,MAAM,aAAa,KAAK,SAAS,IAAI,CAAC,CAAC;AACzF;AAEA,iBAAiB,QACd,QAAQ,iCAAiC,EACzC,YAAY,kEAAqB,EACjC,mBAAmB,IAAI,EACvB,mBAAmB,CAAC,EACpB,OAAO,KAAK,eAAe,CAAC,KAAK,SAAiB,OAAiB,CAAC,MAAM,mBAAmB,KAAK,SAAS,IAAI,CAAC,CAAC;AAEpH,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,UAAU;AAChD,QAAM,OAAO,QAAQ,KAAK,SAAS,QAAQ;AAC3C,QAAM,SAAS,IAAI,aAAa,IAAI;AACpC,QAAM,WAAW,WAAW,KAAK;AACjC,SAAO,MAAM,QAAQ;AACrB,UAAQ,WAAW,SAAS;AAC9B,CAAC;AAED,SAAS,KACP,SACA,SACA;AACA,SAAO,UAAU,SAAY;AAC3B,UAAM,eAAe,KAAK,KAAK,SAAS,CAAC;AACzC,UAAM,OAAO,cAAc,YAAY,IAClC,EAAE,GAAI,aAAa,QAAQ,KAAK,GAAqB,GAAI,aAAa,KAAK,EAAoB,IAC/F,QAAQ,KAAK;AAClB,UAAM,MAAM,MAAM,qBAAqB,SAAS,EAAE,GAAG,MAAM,GAAG,qBAAqB,IAAI,EAAE,CAAC;AAC1F,QAAI;AACF,YAAM,QAAQ,KAAK,GAAG,IAAI;AAAA,IAC5B,SAAS,OAAO;AACd,YAAM,WAAW,WAAW,KAAK;AACjC,UAAI,OAAO,MAAM,QAAQ;AACzB,cAAQ,WAAW,SAAS;AAAA,IAC9B;AAAA,EACF;AACF;AAEA,SAAS,cAAc,OAAkC;AACvD,SAAO,iBAAiB;AAC1B;AAEA,SAAS,iBAAiB,SAA2B;AACnD,SAAO,QACJ,OAAO,gBAAgB,4CAAS,EAChC,OAAO,iBAAiB,8BAAoB,EAC5C,OAAO,SAAS,0EAAc,EAC9B,OAAO,UAAU,2CAAa,EAC9B,OAAO,aAAa,sCAAQ,EAC5B,OAAO,cAAc,sCAAQ;AAClC;AAEA,SAAS,qBAAqB,MAAgC;AAC5D,QAAM,SAAS,KAAK,QAAQ,CAAC,QAAS,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,CAAE;AACpE,QAAM,UAAyB,CAAC;AAChC,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,UAAM,QAAQ,OAAO,KAAK;AAC1B,QAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,IACF;AACA,QAAI,UAAU,WAAW,OAAO,OAAO,QAAQ,CAAC,MAAM,UAAU;AAC9D,cAAQ,MAAM,OAAO,QAAQ,CAAC;AAC9B,eAAS;AAAA,IACX,WAAW,MAAM,WAAW,QAAQ,GAAG;AACrC,cAAQ,MAAM,MAAM,MAAM,SAAS,MAAM;AAAA,IAC3C,WAAW,UAAU,cAAc,OAAO,OAAO,QAAQ,CAAC,MAAM,UAAU;AACxE,cAAQ,SAAS,OAAO,QAAQ,CAAC;AACjC,eAAS;AAAA,IACX,WAAW,MAAM,WAAW,WAAW,GAAG;AACxC,cAAQ,SAAS,MAAM,MAAM,YAAY,MAAM;AAAA,IACjD,WAAW,UAAU,SAAS;AAC5B,cAAQ,MAAM;AAAA,IAChB,WAAW,UAAU,UAAU;AAC7B,cAAQ,OAAO;AAAA,IACjB,WAAW,UAAU,aAAa;AAChC,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;","names":["readFile","stat","join","dirname","dirname","join","mkdir","open","join","mkdir","dirname","open","join","readFile","join","dirname","join","commands","readFile","join","readFile","join","readFile","join","readOptional","readFile","stat","stat","join","join","exists","stat","mkdir","readFile","join","readFile","mkdir","join","readFile","mkdir","readFile","stat","join","join","mkdir","stat","readFile","mkdir","readFile","stat","dirname","join","exists","join","mkdir","dirname","readFile","stat","execFile","promisify","stat","join","exists","execFile","promisify","execFileAsync","promisify","execFile","resolve","execFileAsync","promisify","execFile","readFile","stat","join","parse","locks","exists","readdir","stat","join","exists"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nick848/fet",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Frontend workflow orchestration tool built around OpenSpec.",
5
5
  "type": "module",
6
6
  "engines": {