@nick848/fet 0.1.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.
Files changed (51) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +265 -44
  3. package/dist/chunk-FZOVNHE7.js +104 -0
  4. package/dist/chunk-FZOVNHE7.js.map +1 -0
  5. package/dist/cli/index.js +1816 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/index.js +12 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +43 -49
  10. package/dist/apply.d.ts +0 -1
  11. package/dist/apply.js +0 -172
  12. package/dist/approval.d.ts +0 -2
  13. package/dist/approval.js +0 -26
  14. package/dist/atomic-write.d.ts +0 -5
  15. package/dist/atomic-write.js +0 -41
  16. package/dist/cli.d.ts +0 -2
  17. package/dist/cli.js +0 -178
  18. package/dist/doctor.d.ts +0 -1
  19. package/dist/doctor.js +0 -93
  20. package/dist/fingerprint.d.ts +0 -6
  21. package/dist/fingerprint.js +0 -77
  22. package/dist/hooks.d.ts +0 -12
  23. package/dist/hooks.js +0 -47
  24. package/dist/init.d.ts +0 -4
  25. package/dist/init.js +0 -47
  26. package/dist/opencode-skills.d.ts +0 -3
  27. package/dist/opencode-skills.js +0 -236
  28. package/dist/openspec.d.ts +0 -16
  29. package/dist/openspec.js +0 -73
  30. package/dist/paths.d.ts +0 -9
  31. package/dist/paths.js +0 -20
  32. package/dist/prompt.d.ts +0 -4
  33. package/dist/prompt.js +0 -30
  34. package/dist/scanner.d.ts +0 -23
  35. package/dist/scanner.js +0 -352
  36. package/dist/skills.d.ts +0 -3
  37. package/dist/skills.js +0 -142
  38. package/dist/state.d.ts +0 -17
  39. package/dist/state.js +0 -126
  40. package/dist/tasks.d.ts +0 -13
  41. package/dist/tasks.js +0 -69
  42. package/dist/types.d.ts +0 -38
  43. package/dist/types.js +0 -1
  44. package/dist/validate.d.ts +0 -1
  45. package/dist/validate.js +0 -150
  46. package/dist/verify.d.ts +0 -6
  47. package/dist/verify.js +0 -193
  48. package/dist/watch-paths.d.ts +0 -2
  49. package/dist/watch-paths.js +0 -70
  50. package/dist/workflow-hints.d.ts +0 -2
  51. package/dist/workflow-hints.js +0 -9
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 nick848
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 nick848
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,44 +1,265 @@
1
- # FET
2
-
3
- 在项目中以 [OpenSpec](https://github.com/Fission-AI/OpenSpec) 为基座做**工作流编排**:`fet` 命令在前后挂钩子、管理 `openspec/fet-state.json`、生成上下文与工具技能(Cursor / OpenCode),并把 `openspec` CLI 透传执行。
4
-
5
- ## 要求
6
-
7
- - Node.js **≥ 18**
8
- - 已安装 OpenSpec CLI(PATH 中的 `openspec`,否则将尝试 `npx @fission-ai/openspec`)
9
-
10
- ## 安装
11
-
12
- ```bash
13
- npm install -g @nick848/fet
14
- ```
15
-
16
- ## 常用命令
17
-
18
- | 命令 | 说明 |
19
- |------|------|
20
- | `fet init` | 初始化 OpenSpec + FET 状态、扫描上下文、生成工具文件(`--tool cursor \| opencode \| both`) |
21
- | `fet apply` / `fet validate` | 实施循环与任务校验 |
22
- | `fet verify` | 终验(`--auto` / `--done` 等) |
23
- | `fet doctor` | 诊断配置与 openspec 解析路径 |
24
- | `fet update-context` | 刷新 `AGENTS.md` 与 `openspec/config.yaml` 中的 FET 区块 |
25
-
26
- 其余子命令多为对 `openspec` 的透传,详见 `fet --help`。
27
-
28
- ## 文档
29
-
30
- 仓库内 [DESIGN.md](./DESIGN.md) 为完整设计说明(威胁模型、状态机、与 OpenSpec 关系等)。
31
-
32
- ## 维护者:发布到 npm
33
-
34
- 1. 登录:`npm login`(首次)
35
- 2. 确认版本号:编辑 `package.json` 的 `version`(语义化版本)
36
- 3. 本地校验:`npm run build && npm test`
37
- 4. 干跑包内容:`npm pack --dry-run`
38
- 5. 发布(作用域包已设 `publishConfig.access: public`):`npm publish`
39
-
40
- `prepublishOnly` 会在发布前自动执行 `npm run build && npm test`。
41
-
42
- ## 开源协议
43
-
44
- MIT,见 [LICENSE](./LICENSE)。
1
+ # FET
2
+
3
+ FET 是一个围绕 OpenSpec 构建的前端开发工作流编排 CLI。它不会直接生成业务代码,而是代理 OpenSpec 命令、维护本地工作流状态、生成可审计的项目上下文,并帮助 Cursor AI 编程工具读取正确的项目资料。
4
+
5
+ ### 作用
6
+
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 状态,降低未验证变更被归档的风险。
12
+
13
+ ### 基本原理
14
+
15
+ FET 是 OpenSpec 的透明代理和本地编排层。用户运行 `fet apply`、`fet archive` 等命令时,FET 会先读取项目状态和 change 状态,执行必要的 pre-hook,再调用真实的 `openspec` CLI,最后根据 OpenSpec 的结果更新 FET 状态。
16
+
17
+ 对于 OpenSpec 1.2.x,FET 会把部分高层命令映射到真实 OpenSpec 命令。例如 `fet apply` 会调用 `openspec instructions apply --change <id>` 输出实施指令,`fet sync` 会调用 `openspec validate <change> --type change --strict` 做归档前校验。
18
+
19
+ ### 环境要求
20
+
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
153
+
154
+ - Node.js 18 or newer
155
+ - OpenSpec CLI available on `PATH`
156
+
157
+ Install OpenSpec:
158
+
159
+ ```sh
160
+ npm install -g @fission-ai/openspec
161
+ ```
162
+
163
+ ### Installation
164
+
165
+ ```sh
166
+ npm install -g @nick848/fet
167
+ ```
168
+
169
+ Check the installation:
170
+
171
+ ```sh
172
+ fet --version
173
+ fet --help
174
+ ```
175
+
176
+ ### Quick Start
177
+
178
+ Run this in a project root:
179
+
180
+ ```sh
181
+ fet init
182
+ fet doctor
183
+ ```
184
+
185
+ Typical workflow:
186
+
187
+ ```sh
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
194
+ ```
195
+
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
230
+
231
+ FET may create or update:
232
+
233
+ - `AGENTS.md`
234
+ - the `fet:` namespace in `openspec/config.yaml`
235
+ - `openspec/fet-state.json`
236
+ - `openspec/changes/<change-id>/fet-state.json`
237
+ - `openspec/changes/<change-id>/.fet/verify-instructions.md`
238
+ - `.cursor/skills/fet-*/SKILL.md`
239
+ - `.cursor/rules/fet-context.mdc`
240
+
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.
242
+
243
+ ### Safety Model
244
+
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.
246
+
247
+ ### Development
248
+
249
+ ```sh
250
+ npm install
251
+ npm run typecheck
252
+ npm run test
253
+ npm run build
254
+ npm run release:check
255
+ ```
256
+
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
264
+
265
+ MIT
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/errors/codes.ts
4
+ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
5
+ ErrorCode2["Unknown"] = "UNKNOWN";
6
+ ErrorCode2["InvalidArguments"] = "INVALID_ARGUMENTS";
7
+ ErrorCode2["OpenSpecNotFound"] = "OPENSPEC_NOT_FOUND";
8
+ ErrorCode2["OpenSpecUnsupportedVersion"] = "OPENSPEC_UNSUPPORTED_VERSION";
9
+ ErrorCode2["OpenSpecCommandFailed"] = "OPENSPEC_COMMAND_FAILED";
10
+ ErrorCode2["OpenSpecStructureUnknown"] = "OPENSPEC_STRUCTURE_UNKNOWN";
11
+ ErrorCode2["StateSchemaUnsupported"] = "STATE_SCHEMA_UNSUPPORTED";
12
+ ErrorCode2["StateCorrupted"] = "STATE_CORRUPTED";
13
+ ErrorCode2["LockHeld"] = "LOCK_HELD";
14
+ ErrorCode2["UserCancelled"] = "USER_CANCELLED";
15
+ ErrorCode2["UnsafeScriptApprovalRequired"] = "UNSAFE_SCRIPT_APPROVAL_REQUIRED";
16
+ ErrorCode2["ToolAdapterConflict"] = "TOOL_ADAPTER_CONFLICT";
17
+ ErrorCode2["ConfigInvalid"] = "CONFIG_INVALID";
18
+ ErrorCode2["FileSystemError"] = "FILE_SYSTEM_ERROR";
19
+ return ErrorCode2;
20
+ })(ErrorCode || {});
21
+ function exitCodeForError(code) {
22
+ switch (code) {
23
+ case "INVALID_ARGUMENTS" /* InvalidArguments */:
24
+ case "CONFIG_INVALID" /* ConfigInvalid */:
25
+ return 2;
26
+ case "OPENSPEC_NOT_FOUND" /* OpenSpecNotFound */:
27
+ case "OPENSPEC_UNSUPPORTED_VERSION" /* OpenSpecUnsupportedVersion */:
28
+ return 3;
29
+ case "OPENSPEC_COMMAND_FAILED" /* OpenSpecCommandFailed */:
30
+ return 4;
31
+ case "OPENSPEC_STRUCTURE_UNKNOWN" /* OpenSpecStructureUnknown */:
32
+ case "STATE_SCHEMA_UNSUPPORTED" /* StateSchemaUnsupported */:
33
+ case "STATE_CORRUPTED" /* StateCorrupted */:
34
+ case "TOOL_ADAPTER_CONFLICT" /* ToolAdapterConflict */:
35
+ case "FILE_SYSTEM_ERROR" /* FileSystemError */:
36
+ return 5;
37
+ case "LOCK_HELD" /* LockHeld */:
38
+ return 6;
39
+ case "USER_CANCELLED" /* UserCancelled */:
40
+ return 7;
41
+ case "UNSAFE_SCRIPT_APPROVAL_REQUIRED" /* UnsafeScriptApprovalRequired */:
42
+ return 8;
43
+ case "UNKNOWN" /* Unknown */:
44
+ default:
45
+ return 1;
46
+ }
47
+ }
48
+
49
+ // src/errors/fet-error.ts
50
+ var FetError = class extends Error {
51
+ code;
52
+ exitCode;
53
+ details;
54
+ recoverable;
55
+ suggestedCommand;
56
+ cause;
57
+ constructor(options) {
58
+ super(options.message);
59
+ this.name = "FetError";
60
+ this.code = options.code;
61
+ this.exitCode = exitCodeForError(options.code);
62
+ this.details = options.details;
63
+ this.recoverable = options.recoverable ?? true;
64
+ this.suggestedCommand = options.suggestedCommand;
65
+ this.cause = options.cause;
66
+ }
67
+ toJSON() {
68
+ return {
69
+ code: this.code,
70
+ exitCode: this.exitCode,
71
+ message: this.message,
72
+ details: this.details,
73
+ recoverable: this.recoverable,
74
+ suggestedCommand: this.suggestedCommand
75
+ };
76
+ }
77
+ };
78
+ function toFetError(error) {
79
+ if (error instanceof FetError) {
80
+ return error;
81
+ }
82
+ if (error instanceof Error) {
83
+ return new FetError({
84
+ code: "UNKNOWN" /* Unknown */,
85
+ message: error.message,
86
+ recoverable: false,
87
+ cause: error
88
+ });
89
+ }
90
+ return new FetError({
91
+ code: "UNKNOWN" /* Unknown */,
92
+ message: "Unknown error",
93
+ details: error,
94
+ recoverable: false
95
+ });
96
+ }
97
+
98
+ export {
99
+ ErrorCode,
100
+ exitCodeForError,
101
+ FetError,
102
+ toFetError
103
+ };
104
+ //# sourceMappingURL=chunk-FZOVNHE7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/codes.ts","../src/errors/fet-error.ts"],"sourcesContent":["export enum ErrorCode {\n Unknown = \"UNKNOWN\",\n InvalidArguments = \"INVALID_ARGUMENTS\",\n OpenSpecNotFound = \"OPENSPEC_NOT_FOUND\",\n OpenSpecUnsupportedVersion = \"OPENSPEC_UNSUPPORTED_VERSION\",\n OpenSpecCommandFailed = \"OPENSPEC_COMMAND_FAILED\",\n OpenSpecStructureUnknown = \"OPENSPEC_STRUCTURE_UNKNOWN\",\n StateSchemaUnsupported = \"STATE_SCHEMA_UNSUPPORTED\",\n StateCorrupted = \"STATE_CORRUPTED\",\n LockHeld = \"LOCK_HELD\",\n UserCancelled = \"USER_CANCELLED\",\n UnsafeScriptApprovalRequired = \"UNSAFE_SCRIPT_APPROVAL_REQUIRED\",\n ToolAdapterConflict = \"TOOL_ADAPTER_CONFLICT\",\n ConfigInvalid = \"CONFIG_INVALID\",\n FileSystemError = \"FILE_SYSTEM_ERROR\"\n}\n\nexport function exitCodeForError(code: ErrorCode): number {\n switch (code) {\n case ErrorCode.InvalidArguments:\n case ErrorCode.ConfigInvalid:\n return 2;\n case ErrorCode.OpenSpecNotFound:\n case ErrorCode.OpenSpecUnsupportedVersion:\n return 3;\n case ErrorCode.OpenSpecCommandFailed:\n return 4;\n case ErrorCode.OpenSpecStructureUnknown:\n case ErrorCode.StateSchemaUnsupported:\n case ErrorCode.StateCorrupted:\n case ErrorCode.ToolAdapterConflict:\n case ErrorCode.FileSystemError:\n return 5;\n case ErrorCode.LockHeld:\n return 6;\n case ErrorCode.UserCancelled:\n return 7;\n case ErrorCode.UnsafeScriptApprovalRequired:\n return 8;\n case ErrorCode.Unknown:\n default:\n return 1;\n }\n}\n","import { ErrorCode, exitCodeForError } from \"./codes.js\";\n\nexport interface FetErrorOptions {\n code: ErrorCode;\n message: string;\n details?: unknown;\n recoverable?: boolean;\n suggestedCommand?: string;\n cause?: unknown;\n}\n\nexport class FetError extends Error {\n readonly code: ErrorCode;\n readonly exitCode: number;\n readonly details?: unknown;\n readonly recoverable: boolean;\n readonly suggestedCommand?: string;\n override readonly cause?: unknown;\n\n constructor(options: FetErrorOptions) {\n super(options.message);\n this.name = \"FetError\";\n this.code = options.code;\n this.exitCode = exitCodeForError(options.code);\n this.details = options.details;\n this.recoverable = options.recoverable ?? true;\n this.suggestedCommand = options.suggestedCommand;\n this.cause = options.cause;\n }\n\n toJSON() {\n return {\n code: this.code,\n exitCode: this.exitCode,\n message: this.message,\n details: this.details,\n recoverable: this.recoverable,\n suggestedCommand: this.suggestedCommand\n };\n }\n}\n\nexport function toFetError(error: unknown): FetError {\n if (error instanceof FetError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new FetError({\n code: ErrorCode.Unknown,\n message: error.message,\n recoverable: false,\n cause: error\n });\n }\n\n return new FetError({\n code: ErrorCode.Unknown,\n message: \"Unknown error\",\n details: error,\n recoverable: false\n });\n}\n"],"mappings":";;;AAAO,IAAK,YAAL,kBAAKA,eAAL;AACL,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,gCAA6B;AAC7B,EAAAA,WAAA,2BAAwB;AACxB,EAAAA,WAAA,8BAA2B;AAC3B,EAAAA,WAAA,4BAAyB;AACzB,EAAAA,WAAA,oBAAiB;AACjB,EAAAA,WAAA,cAAW;AACX,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,kCAA+B;AAC/B,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,qBAAkB;AAdR,SAAAA;AAAA,GAAA;AAiBL,SAAS,iBAAiB,MAAyB;AACxD,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;;;AChCO,IAAM,WAAN,cAAuB,MAAM;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACS;AAAA,EAElB,YAAY,SAA0B;AACpC,UAAM,QAAQ,OAAO;AACrB,SAAK,OAAO;AACZ,SAAK,OAAO,QAAQ;AACpB,SAAK,WAAW,iBAAiB,QAAQ,IAAI;AAC7C,SAAK,UAAU,QAAQ;AACvB,SAAK,cAAc,QAAQ,eAAe;AAC1C,SAAK,mBAAmB,QAAQ;AAChC,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,kBAAkB,KAAK;AAAA,IACzB;AAAA,EACF;AACF;AAEO,SAAS,WAAW,OAA0B;AACnD,MAAI,iBAAiB,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,OAAO;AAC1B,WAAO,IAAI,SAAS;AAAA,MAClB;AAAA,MACA,SAAS,MAAM;AAAA,MACf,aAAa;AAAA,MACb,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,SAAS;AAAA,IAClB;AAAA,IACA,SAAS;AAAA,IACT,SAAS;AAAA,IACT,aAAa;AAAA,EACf,CAAC;AACH;","names":["ErrorCode"]}