# FET

[中文](https://unpkg.com/@nick848/fet/README.md) | [English](https://unpkg.com/@nick848/fet/README_en.md)

> The npm package page only renders `README.md`; relative links such as `./README_en.md` return 404. Use the **unpkg** links above to open the other file from the same npm package. Source repo: [Gitee](https://gitee.com/agent-team/fet).

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 project material.

## What It Does

- Provides one entry point: wraps OpenSpec workflows with `fet <command>` so users and AI tools do not bypass FET state tracking.
- Generates context: scans the project and writes `AGENTS.md` plus the `fet:` namespace in `openspec/config.yaml`.
- Manages state: records the active change, synced tasks, manual verification declarations, tool adapter state, and language preference.
- Integrates AI tools: generates Cursor rules and Skills, plus Codex context files, command guides, and native slash prompts.
- Unifies language: Chinese is the default for interaction messages and generated artifacts; use `--lang <language>` to switch.
- Guards critical stages: checks FET verification state before `sync` / `archive`.
- Supports optional code graphs: integrates with GitNexus so AI tools can prefer structured code context before broad repository scans.
- Figma guard: when a change references Figma, FET writes `figma-apply-instructions.md` (read design before UI work on apply) and `figma-stop.md` (stop and ask the user when Figma cannot be read—no guessed styles).
- Layered bilingual specs: English Requirements/Scenario stay canonical; each Requirement gets a `<!-- 中文：... -->` note. LLM edits must refresh Chinese notes in the same edit (`fet.specLanguage`, `.cursor/rules/fet-spec-language.mdc`).
- UI display contract: when a change references Figma and/or API docs, FET writes `ui-display-contract.yaml` (draft) and `ui-field-apply-instructions.md`; planning specs must include a Requirement that only `displayFields` may render—OpenAPI must not drive full UI field lists.

## How It Works

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 required pre-hooks, calls the real `openspec` CLI, and then updates FET state based on the result.

FET proxy commands keep the native OpenSpec command name intact. For example, `fet apply --change <id>` calls `openspec apply --change <id>`, and `fet sync --change <id>` calls `openspec sync --change <id>` after FET's verification gate passes.

## Requirements

- Node.js 18 or newer
- OpenSpec CLI available on `PATH`

Install OpenSpec:

```sh
npm install -g @fission-ai/openspec
```

## Installation

```sh
npm install -g @nick848/fet
```

Check the installation:

```sh
fet --version
fet --help
fet update
```

## First-Time Setup (Recommended Order)

This section is for **bringing FET into a business project for the first time**. Run commands in the **project root** you want OpenSpec to manage (where your app source lives), not inside the FET tool repository itself.

### Step 1: Install required tools

1. Install the [OpenSpec CLI](https://github.com/Fission-AI/OpenSpec) globally:

   ```sh
   npm install -g @fission-ai/openspec
   openspec --version
   ```

2. Install FET globally:

   ```sh
   npm install -g @nick848/fet
   fet --version
   ```

### Step 2: Initialize the project

From your project root:

```sh
fet init --yes
```

`fet init` will:

- Detect OpenSpec and run `openspec init` when `openspec/` is missing
- Scan the repository and generate `AGENTS.md` plus the `fet:` namespace in `openspec/config.yaml`
- Write workflow state such as `openspec/fet-state.json`
- Install **Cursor** and **Codex** integration files (see “Use in your IDE” below)
- Optionally detect GitNexus (a one-time recommendation if missing; non-blocking)

For English interaction messages and generated artifacts:

```sh
fet init --yes --lang en
```

### Step 3: Verify the environment

```sh
fet doctor
```

Confirm there are no `fail` results for OpenSpec, context files, or tool integration. Use `fet doctor --fix-lock` if a stale `openspec/.fet.lock` is reported.

### Step 4: Fill project context (with your IDE)

The scanner marks unknown facts in `AGENTS.md` as `[NEEDS LLM INPUT]`. Run:

```sh
fet fill-context
```

Then, in **Cursor** or **Codex**, follow the generated handoff (for example `.fet/fill-context.md` or `.cursor/skills/fet-fill-context/SKILL.md`) so the AI can help replace placeholders. Run `fet doctor` again afterward; placeholder checks should pass.

### Step 5: (Optional) Set up a code graph

To let AI prefer structured graph context before broad repository scans, install GitNexus, then:

```sh
fet graph setup    # installation guide only; FET does not install GitNexus for you
fet graph init     # first graph build
fet graph handoff  # IDE handoff document
```

### Step 6: Use in your IDE

After initialization, make sure your AI tool can read:

| Tool | Main entry points |
|------|-------------------|
| Cursor | `.cursor/rules/fet-context.mdc`; `.cursor/skills/fet-*/SKILL.md` |
| Codex | `.codex/fet/context.md`; `$CODEX_HOME/prompts/fet-*.md` |

Run workflow commands in the **terminal** as `fet <command>` (for example `fet apply`). Calling `openspec` directly bypasses FET state and the verify gate.

### Step 7: Complete your first change

When setup looks healthy, drive your first OpenSpec change. Simple path example:

```sh
fet propose my-first-change
# or use fet continue step by step from your IDE handoff
fet tdd --change my-first-change
fet apply --change my-first-change
fet test --change my-first-change
fet visual --change my-first-change
fet verify --change my-first-change
fet verify --done --change my-first-change
fet sync --change my-first-change
fet archive --change my-first-change
```

For the expanded workflow, start with `fet new <id>` and repeat `fet continue` or run `fet ff`. See “Day-to-day change workflow” below.

---

## Day-to-day change workflow

After first-time setup, a typical loop is:

```sh
fet new my-change          # or fet propose my-change
fet continue               # repeat as needed for the next planning artifact
fet tdd --change my-change
fet apply --change my-change
fet test --change my-change
fet visual --change my-change
fet verify --change my-change
fet verify --done --change my-change
fet sync --change my-change
fet archive --change my-change
```

Notes:

- When `continue`, `apply`, `ff`, or `sync` is called without `--change`, FET uses the recorded **active change**, or the only open change when there is exactly one.
- `sync` and `archive` through FET require `fet verify --done` first.
- Run `fet update-context` after major project structure changes; run `fet fill-context` when you only need to refresh IDE placeholder handoff.

## Language

FET defaults to Chinese for interaction messages and generated artifacts.

```sh
fet init --lang zh-CN
fet init --lang en
```

`fet init --lang <language>` saves the language in `openspec/fet-state.json`. Later commands reuse the saved language when `--lang` is not provided. Supported values:

| Value | Meaning |
|-------|---------|
| `zh-CN`, `zh`, `cn`, `chinese` | Chinese |
| `en`, `en-US`, `english` | English |

## Global Options

| Option | Description | Example |
|--------|-------------|---------|
| `--cwd <path>` | Set the project root. Defaults to the current directory. | `fet doctor --cwd ./app` |
| `--change <id>` | Select an OpenSpec change. | `fet apply --change add-login` |
| `--lang <language>` | Set the language for interaction messages and generated artifacts. | `fet init --lang en` |
| `--yes` | Accept low-risk confirmations. | `fet init --yes` |
| `--json` | Print machine-readable JSON. | `fet doctor --json` |
| `--verbose` | Print more diagnostics. | `fet doctor --verbose` |
| `--no-color` | Disable terminal colors. | `fet --no-color doctor` |

### Version update check

Before most commands (except `fet update`), FET checks npm for a newer release (cached for 6 hours by default). When an update is available, it prints the current and latest versions. In an interactive terminal you can upgrade now, skip and continue the current task, or cancel the command.

| Variable | Description |
|----------|-------------|
| `FET_UPDATE_CHECK` | `off` disables checks; `warn` prints a warning and continues; `confirm` prompts in a TTY (default). |
| `FET_SKIP_UPDATE_CHECK` | Set to `1` to disable checks (same as `FET_UPDATE_CHECK=off`). |
| `FET_UPDATE_CHECK_TTL_MS` | Cache TTL in milliseconds; default `21600000` (6 hours). |

`--yes` and `--json` skip the interactive upgrade prompt. If you skip a specific latest version, FET will not prompt again for that version until a newer release appears.

## Commands

| Command | Usage | Description |
|---------|-------|-------------|
| `fet init` | `fet init [--yes] [--lang <language>]` | Initialize FET and OpenSpec; generate context, state, Cursor integration, and Codex workflow guides. |
| `fet update` | `fet update` | Check whether FET is the latest published version and automatically upgrade when a newer version is available. |
| `fet update-context` | `fet update-context [--yes]` | Rescan the project and update FET-managed regions in `AGENTS.md` and `openspec/config.yaml`. |
| `fet fill-context` | `fet fill-context [--yes]` | Refresh IDE handoff commands that ask AI to replace `AGENTS.md` placeholders. |
| `fet doctor` | `fet doctor [--fix-lock]` | Diagnose OpenSpec, FET state, context files, tool integration, and lock files. |
| `fet explore` | `fet explore [...args] [--change <id>]` | Run native OpenSpec explore through FET so clarification prompts remain interactive. |
| `fet propose` | `fet propose <change-id-or-description>` | Create an OpenSpec change and the first ready planning artifact; use `continue` for each subsequent artifact after review. |
| `fet new` | `fet new <change-id>` | Create a new OpenSpec change. |
| `fet continue` | `fet continue [...args] [--change <id>]` | Run native OpenSpec continue through FET. |
| `fet ff` | `fet ff [...args] [--change <id>]` | Run native OpenSpec ff through FET. |
| `fet tdd` | `fet tdd [--change <id>]` | Generate per-change TDD manifest under `openspec/changes/<id>/.fet/`. |
| `fet apply` | `fet apply [...args] [--change <id>]` | Prepare implementation instructions; requires TDD manifest by default. |
| `fet test` | `fet test [--change <id>] [--plan]` | Run project tests scoped to the TDD manifest; record pass/fail. |
| `fet visual` | `fet visual [--change <id>] [--base-url <url>] [--plan]` | Layout-only visual verification (default: manifest + capture + layout check). |
| `fet verify` | `fet verify --change <id>` | Generate verify instructions; requires `fet test` (and `fet visual` when Figma is referenced). |
| `fet verify --done` | `fet verify --done --change <id>` | Declare manual verification complete and allow later `sync` / `archive`. |
| `fet verify --auto` | `fet verify --auto [--yes]` | Generate an automatic verification plan. This version does not run project scripts; `--yes` records the plan fingerprint. |
| `fet sync` | `fet sync [...args] [--change <id>]` | Run native OpenSpec sync after the FET verify gate passes. |
| `fet archive` | `fet archive --change <id>` | Archive the change after the FET verify gate passes and append to `CHANGELOG.md`. |
| `fet bulk-archive` | `fet bulk-archive [...args] [--change <id>]` | Run native OpenSpec bulk-archive through FET. |
| `fet onboard` | `fet onboard [...args] [--change <id>]` | Run native OpenSpec onboard through FET. |
| `fet passthrough` | `fet passthrough <command> [...args]` | Pass through unmanaged OpenSpec commands without updating FET lifecycle state. |

## GitNexus Graph Support

GitNexus support is optional. FET detects a `gitnexus` executable during `fet init` and records the result in `openspec/fet-state.json`. If GitNexus is not installed, init shows a one-time recommendation and continues normally. `fet doctor` reports missing GitNexus as a warning only.

Graph commands are grouped under `fet graph`:

| Command | Description |
|---------|-------------|
| `fet graph status` | Check GitNexus, the graph path, and current status; update FET state. |
| `fet graph setup` | Generate `.fet/graph-setup.md` for installation and IDE-assisted setup guidance; FET does not install GitNexus automatically. |
| `fet graph init` | Run `gitnexus analyze` to build the first graph. |
| `fet graph refresh` | Run `gitnexus analyze` again to refresh the graph. |
| `fet graph doctor` | Diagnose graph integration health; missing graph support warns but does not block FET/OpenSpec commands. |
| `fet graph handoff` | Generate `.fet/graph-handoff.md` so Cursor, Codex, OpenCode, and other IDE AI tools can prefer graph context before broad scans. |

By default, FET looks for `gitnexus` on `PATH` and expects the graph directory at `.gitnexus`. Advanced users can override this with `FET_GITNEXUS_EXECUTABLE`, `FET_GITNEXUS_COMMAND`, and `FET_GITNEXUS_GRAPH_PATH`.

## Andrej Karpathy Inspired Guidelines

`fet init` and `fet update-context` add FET-managed Andrej Karpathy inspired coding guidelines to the current project. FET does not assume Codex or OpenCode will read `CLAUDE.md` automatically, so it syncs the guidance into multiple context files:

- `CLAUDE.md`: appends or refreshes a managed `FET:BEGIN ANDREJ-KARPATHY-SKILLS` block.
- `.fet/karpathy-guidelines.md`: generic IDE handoff.
- `.codex/fet/karpathy-guidelines.md`: Codex-specific context.
- `.cursor/rules/karpathy-guidelines.mdc`: Cursor project rule.

The generated guidance is not a full copy of the upstream repository. It is a concise project-level adaptation of `andrej-karpathy-skills`: think before coding, keep changes simple, edit precisely, and verify against concrete goals. Source project: <https://github.com/forrestchang/andrej-karpathy-skills>.

## Generated Files

FET may create or update:

- `AGENTS.md`
- the `fet:` namespace in `openspec/config.yaml`
- `openspec/fet-state.json`
- `openspec/changes/<change-id>/fet-state.json`
- `openspec/changes/<change-id>/.fet/verify-instructions.md`
- `CHANGELOG.md`
- `.fet/fill-context.md`
- `.fet/graph-setup.md`
- `.fet/graph-handoff.md`
- `.fet/karpathy-guidelines.md`
- `CLAUDE.md`
- `.cursor/skills/fet-*/SKILL.md`
- `.cursor/rules/fet-context.mdc`
- `.cursor/rules/fet-figma-stop.mdc`
- `.cursor/rules/fet-spec-language.mdc`
- `.cursor/rules/karpathy-guidelines.mdc`
- `.codex/fet/context.md`
- `.codex/fet/figma-stop.md`
- `.codex/fet/spec-language.md`
- `.codex/fet/karpathy-guidelines.md`
- `openspec/changes/<change-id>/.fet/figma-apply-instructions.md` (written on apply when the change references Figma)
- `openspec/changes/<change-id>/.fet/figma-stop.md` (written when the change references Figma)
- `.codex/fet/commands/*.md`
- `$CODEX_HOME/prompts/fet-*.md`

FET only owns explicitly marked managed regions. User content outside those regions should be preserved.

**Git and teams**: Whether to commit `openspec/fet-state.json`, lock files, and related paths is a team policy. `fet init` no longer edits `.gitignore` automatically. Common options: (1) commit shared state and coordinate who owns each change to avoid `activeChangeId` conflicts; (2) use per-machine `.git/info/exclude` for locks and journals while keeping a shared `.gitignore`; (3) keep all FET state local when collaboration on state is not needed. See `src/templates/gitignore.ts` for a reference ignore block you can merge manually.

## Safety Model

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.

## Development

```sh
npm install
npm run typecheck
npm run test
npm run build
npm run release:check
```

Run the real OpenSpec smoke test:

```powershell
$env:FET_REAL_OPENSPEC='1'; npm run test:real-openspec
```

## License

MIT
