@nick848/fet 1.0.4 → 1.0.6

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
@@ -131,6 +131,32 @@ $env:FET_REAL_OPENSPEC='1'; npm run test:real-openspec
131
131
 
132
132
  MIT
133
133
 
134
+ ### 可选 GitNexus 图谱支持
135
+
136
+ FET 会在 `fet init` 时检测可选的 `gitnexus` 可执行文件,并把结果记录到 `openspec/fet-state.json`。如果没有安装 GitNexus,初始化只会给出一次推荐提示,主流程会继续执行;`fet doctor` 也会把缺失 GitNexus 作为提示性 warning,而不是阻断问题。
137
+
138
+ 二阶段图谱命令统一放在 `fet graph` 下:
139
+
140
+ - `fet graph status`:检查 GitNexus、图谱路径和当前状态,并更新 FET 状态。
141
+ - `fet graph setup`:生成 `.fet/graph-setup.md`,用于安装和 IDE 辅助配置引导;FET 不会自动安装 GitNexus。
142
+ - `fet graph init`:执行 `gitnexus analyze`,用于首次构建图谱。
143
+ - `fet graph refresh`:再次执行 `gitnexus analyze`,用于刷新图谱。
144
+ - `fet graph doctor`:检查图谱集成健康状态,缺失只提示,不阻断 FET/OpenSpec 命令。
145
+ - `fet graph handoff`:生成 `.fet/graph-handoff.md`,供 Cursor、Codex、OpenCode 等 IDE AI 在大范围扫描前优先参考图谱上下文。
146
+
147
+ 默认情况下,FET 会从 `PATH` 查找 `gitnexus`,并认为图谱目录是 `.gitnexus`。高级用户可以通过 `FET_GITNEXUS_EXECUTABLE`、`FET_GITNEXUS_COMMAND`、`FET_GITNEXUS_GRAPH_PATH` 覆盖默认行为。
148
+
149
+ ### Andrej Karpathy Skills
150
+
151
+ `fet init` 和 `fet update-context` 会为当前工程加入一份 FET 管理的 Andrej Karpathy 风格编码指南。FET 不假设 Codex 或 OpenCode 会主动读取 `CLAUDE.md`,因此会把指南同步到 FET 自己的上下文文件中:
152
+
153
+ - `CLAUDE.md`:追加或刷新 `FET:BEGIN ANDREJ-KARPATHY-SKILLS` 管理块,供 Claude Code、Codex、OpenCode 等能读取项目根文档的 AI 工具使用。
154
+ - `.cursor/rules/karpathy-guidelines.mdc`:为 Cursor 生成项目规则。若该文件已存在且不是 FET 管理文件,FET 会保留原文件并给出 warning。
155
+ - `.fet/karpathy-guidelines.md`:通用 IDE handoff,供 OpenCode 或其他不读取 `CLAUDE.md` 的工具显式读取。
156
+ - `.codex/fet/karpathy-guidelines.md`:Codex 专用上下文;FET 生成的 Codex context、command guide 和 slash prompt 会明确要求读取该文件。
157
+
158
+ 这份指南不会复制第三方仓库全文,而是基于 `andrej-karpathy-skills` 的使用目标生成项目级精简规则:先思考、保持简单、精准修改、按目标验证。来源项目:<https://github.com/forrestchang/andrej-karpathy-skills>。
159
+
134
160
  ## English
135
161
 
136
162
  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 and Codex load the right files.
@@ -199,6 +225,28 @@ FET can detect an optional `gitnexus` executable during `fet init` and records t
199
225
 
200
226
  Generated Cursor and Codex instructions tell the IDE AI to prefer GitNexus graph context before broad repository scans when that context is available. FET does not install GitNexus, generate graphs, or require graph support for any command.
201
227
 
228
+ ### Andrej Karpathy Skills
229
+
230
+ `fet init` and `fet update-context` add FET-managed Andrej Karpathy inspired coding guidelines. FET does not assume Codex, OpenCode, or other IDE agents will read `CLAUDE.md` automatically, so the guidelines are also written into FET-owned context files:
231
+
232
+ - `CLAUDE.md` receives a managed `FET:BEGIN ANDREJ-KARPATHY-SKILLS` block for tools that do read root-level Claude guidance.
233
+ - `.fet/karpathy-guidelines.md` is the generic handoff for OpenCode or other IDEs.
234
+ - `.codex/fet/karpathy-guidelines.md` is the Codex-specific copy; generated Codex context, command guides, and slash prompts explicitly ask Codex to read it.
235
+ - `.cursor/rules/karpathy-guidelines.mdc` is the Cursor project rule.
236
+
237
+ The generated guidance is a concise project-level adaptation of `andrej-karpathy-skills`: think before coding, keep changes simple, edit precisely, and verify against concrete goals.
238
+
239
+ Phase-two graph commands are available under `fet graph`:
240
+
241
+ - `fet graph status` checks GitNexus, the configured graph path, and records the result.
242
+ - `fet graph setup` writes `.fet/graph-setup.md` with installation and IDE-assisted setup guidance.
243
+ - `fet graph init` runs `gitnexus analyze` to build the first graph.
244
+ - `fet graph refresh` runs `gitnexus analyze` again to refresh graph data.
245
+ - `fet graph doctor` reports graph integration warnings without blocking normal FET commands.
246
+ - `fet graph handoff` writes `.fet/graph-handoff.md` for Cursor, Codex, OpenCode, or other IDE AI tools.
247
+
248
+ By default FET looks for `gitnexus` on `PATH` and expects the graph directory at `.gitnexus`. Advanced users can override these with `FET_GITNEXUS_EXECUTABLE`, `FET_GITNEXUS_COMMAND`, and `FET_GITNEXUS_GRAPH_PATH`.
249
+
202
250
  ### Global Options
203
251
 
204
252
  | Option | Description | Example |
@@ -217,6 +265,12 @@ Generated Cursor and Codex instructions tell the IDE AI to prefer GitNexus graph
217
265
  | `fet init` | `fet init [--yes]` | Initialize FET and OpenSpec; generate context, state, Cursor rules and Skills, plus Codex workflow guides. |
218
266
  | `fet update-context` | `fet update-context [--yes]` | Rescan the project and update FET-managed regions in `AGENTS.md` and `openspec/config.yaml`. |
219
267
  | `fet fill-context` | `fet fill-context [--yes]` | Refresh IDE handoff commands that ask Cursor/Codex/OpenCode-style AI to replace `AGENTS.md` placeholders. |
268
+ | `fet graph status` | `fet graph status` | Check optional GitNexus installation and graph status. |
269
+ | `fet graph setup` | `fet graph setup` | Generate GitNexus installation and setup handoff instructions without installing anything. |
270
+ | `fet graph init` | `fet graph init [...args]` | Run `gitnexus analyze` to build the first graph. |
271
+ | `fet graph refresh` | `fet graph refresh [...args]` | Run `gitnexus analyze` again and update recorded graph state. |
272
+ | `fet graph doctor` | `fet graph doctor` | Diagnose optional graph integration health. |
273
+ | `fet graph handoff` | `fet graph handoff` | Generate IDE AI instructions for using graph context before broad scans. |
220
274
  | `fet doctor` | `fet doctor [--fix-lock]` | Diagnose OpenSpec, FET state, context files, Cursor and Codex integration, and lock files. |
221
275
  | `fet explore` | `fet explore [...args] [--change <id>]` | Run native OpenSpec explore through FET so clarification prompts stay interactive. |
222
276
  | `fet propose` | `fet propose <change-id>` | Create a new OpenSpec change through FET's proposal entry point. |
@@ -243,9 +297,15 @@ FET may create or update:
243
297
  - `openspec/changes/<change-id>/fet-state.json`
244
298
  - `openspec/changes/<change-id>/.fet/verify-instructions.md`
245
299
  - `CHANGELOG.md`
300
+ - `.fet/graph-setup.md`
301
+ - `.fet/graph-handoff.md`
302
+ - `.fet/karpathy-guidelines.md`
303
+ - `CLAUDE.md`
246
304
  - `.cursor/skills/fet-*/SKILL.md`
247
305
  - `.cursor/rules/fet-context.mdc`
306
+ - `.cursor/rules/karpathy-guidelines.mdc`
248
307
  - `.codex/fet/context.md`
308
+ - `.codex/fet/karpathy-guidelines.md`
249
309
  - `.codex/fet/commands/*.md`
250
310
  - `$CODEX_HOME/prompts/fet-*.md` for Codex native slash commands. If `CODEX_HOME` is not set, FET uses `~/.codex`.
251
311
  - `.fet/fill-context.md` as a generic IDE handoff for tools without native command support.
@@ -8,6 +8,8 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
8
8
  ErrorCode2["OpenSpecUnsupportedVersion"] = "OPENSPEC_UNSUPPORTED_VERSION";
9
9
  ErrorCode2["OpenSpecCommandFailed"] = "OPENSPEC_COMMAND_FAILED";
10
10
  ErrorCode2["OpenSpecStructureUnknown"] = "OPENSPEC_STRUCTURE_UNKNOWN";
11
+ ErrorCode2["GraphProviderNotFound"] = "GRAPH_PROVIDER_NOT_FOUND";
12
+ ErrorCode2["GraphCommandFailed"] = "GRAPH_COMMAND_FAILED";
11
13
  ErrorCode2["StateSchemaUnsupported"] = "STATE_SCHEMA_UNSUPPORTED";
12
14
  ErrorCode2["StateCorrupted"] = "STATE_CORRUPTED";
13
15
  ErrorCode2["LockHeld"] = "LOCK_HELD";
@@ -25,8 +27,10 @@ function exitCodeForError(code) {
25
27
  return 2;
26
28
  case "OPENSPEC_NOT_FOUND" /* OpenSpecNotFound */:
27
29
  case "OPENSPEC_UNSUPPORTED_VERSION" /* OpenSpecUnsupportedVersion */:
30
+ case "GRAPH_PROVIDER_NOT_FOUND" /* GraphProviderNotFound */:
28
31
  return 3;
29
32
  case "OPENSPEC_COMMAND_FAILED" /* OpenSpecCommandFailed */:
33
+ case "GRAPH_COMMAND_FAILED" /* GraphCommandFailed */:
30
34
  return 4;
31
35
  case "OPENSPEC_STRUCTURE_UNKNOWN" /* OpenSpecStructureUnknown */:
32
36
  case "STATE_SCHEMA_UNSUPPORTED" /* StateSchemaUnsupported */:
@@ -101,4 +105,4 @@ export {
101
105
  FetError,
102
106
  toFetError
103
107
  };
104
- //# sourceMappingURL=chunk-FZOVNHE7.js.map
108
+ //# sourceMappingURL=chunk-V4ZRBF5L.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 GraphProviderNotFound = \"GRAPH_PROVIDER_NOT_FOUND\",\n GraphCommandFailed = \"GRAPH_COMMAND_FAILED\",\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 case ErrorCode.GraphProviderNotFound:\n return 3;\n case ErrorCode.OpenSpecCommandFailed:\n case ErrorCode.GraphCommandFailed:\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,2BAAwB;AACxB,EAAAA,WAAA,wBAAqB;AACrB,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;AAhBR,SAAAA;AAAA,GAAA;AAmBL,SAAS,iBAAiB,MAAyB;AACxD,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,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;;;ACpCO,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"]}