npm package: @hatchworksai/gendd-studio-cli
Description: GenDD Studio CLI: install Cursor or Claude Code hooks and git hooks for Stella dashboard (projectId + upload URL). Use --agent cursor or --agent claude.
Author: Hatchworks
Latest version: 1.1.2

# @hatchworksai/gendd-studio-cli

Install Cursor IDE or Claude Code hooks and git hooks for [Stella](https://github.com/your-org/stella) so developer activity is sent to your Stella dashboard.

## Usage

From your project root (a git repo):

```bash
# Cursor (default)
npx @hatchworksai/gendd-studio-cli --project-code <code> --token <token> --url <url>

# Claude Code
npx @hatchworksai/gendd-studio-cli --project-code <code> --token <token> --url <url> --agent claude
```

**Parameters:**
- `--project-code`: Your repository's project code (e.g. `GN`, `GVH`) from the Stella dashboard
- `--token`: A one-time installation token generated from the Stella dashboard (repository setup guide)
- `--url`: The full cursor-history endpoint URL (e.g. `https://stella-dev-nextjs-gue66h5uyq-uc.a.run.app/api/cursor-history`)
- `--agent`: Which AI coding tool to install hooks for: `cursor` (default) or `claude`

You can obtain the project code, token, and URL from the **repository setup guide** in the Stella dashboard when you first access a repository.

## Code standards (`install-standards`)

Install synced coding standards as **Cursor rules** (`.cursor/rules/<id>.mdc`) or **Claude Code project skills** (`.claude/skills/<name>/SKILL.md`). See [Claude Code skills](https://code.claude.com/docs/en/skills).

**Local / dashboard (same token as Setup Stella CLI):** use the installation token from the repository setup guide or generate one from the **Code Standards** page. You can pass the same `--url` value as the setup command (including `.../api/cursor-history`); it is normalized to the app origin automatically.

```bash
npx @hatchworksai/gendd-studio-cli install-standards --token <token> --url <stella-base-url>
```

- **`--url`**: Optional. If omitted, the CLI uses `STELLA_BASE_URL`, then `STELLA_STANDARDS_CLI_BASE_URL`, then the Hatchworks production Stella URL. Use the Stella **origin** only (no `/api/cursor-history` required).
- **Interactive flow** (terminal only): confirms the detected IDE (Cursor vs Claude Code), then asks you to pick **tech stacks** (domains). Use **space** to toggle stacks and **enter** to confirm; all standards in the chosen stacks are installed. The first option installs **all** stacks.
- **Local changes:** If a rule file already exists and its contents differ from what Stella would write, you are asked to **keep global standard** (replace the file with Stella’s version) or **keep my local** (skip that standard). In non-interactive environments (no TTY), existing differing files are **replaced** without prompting (same as before).
- **`--ide`**: Optional. Use `cursor` or `claude` to skip IDE detection and confirmation. `claude-code` and legacy `cloudcode` are accepted as aliases for Claude Code.
- **`--token`**: Same one-time token as `--token` for the main installer, or set `CURSOR_HISTORY_INSTALLATION_TOKEN` / `STELLA_CLI_INSTALLATION_TOKEN`.

**GitHub Actions:** use an OIDC JWT from the **hatchworks/coding-standards** workflow (no long-lived Stella API key).

```bash
npx @hatchworksai/gendd-studio-cli install-standards --url <stella-base-url> --oidc-token <jwt>
```

- **`--url`**: Stella app origin (e.g. `https://your-stella.example.com`), or the full cursor-history URL from the setup guide.
- **`--oidc-token`**: OIDC JWT, or set `GITHUB_ACTIONS_ID_TOKEN` / `STELLA_CODE_STANDARDS_OIDC_TOKEN`.
- **`--ide`**: `cursor` or `claude` (optional; skips IDE confirmation when set). Legacy `cloudcode` maps to Claude Code.
- **`--ids`**: Comma-separated standard `id` values to skip IDE confirmation and tech-stack selection (required for non-interactive runs when stdin is not a TTY, e.g. CI).

Example **GitHub Actions** job (run from `hatchworks/coding-standards`; replace audience with your `CODE_STANDARDS_ACTIONS_OIDC_AUDIENCE` value):

```yaml
permissions:
  id-token: write
  contents: read
jobs:
  install-standards:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Request OIDC token
        id: oidc
        run: |
          TOKEN=$(curl -sS -H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
            "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=stella-code-standards-api" | jq -r .value)
          echo "::add-mask::${TOKEN}"
          echo "token=${TOKEN}" >> "${GITHUB_OUTPUT}"
      - run: npx @hatchworksai/gendd-studio-cli install-standards --url "${{ secrets.STELLA_BASE_URL }}" --oidc-token "${{ steps.oidc.outputs.token }}" --ids "my-standard-id"
```

**Mirror scripts:** The installer copies these files from `gendd-studio-cli/hooks/`. When you change any script, update the same file under `gendd-studio-cli/hooks/` so the published installer stays in sync.

### Cursor scripts (`--agent cursor`, default)

| Script | Purpose |
|--------|---------|
| `clear-events-after-push.js` | Clears event CSVs after pre-push upload |
| `log-after-agent-response.js` | Logs agent response timestamps to `after-agent-response.csv` |
| `log-before-submit-prompt.js` | Logs prompt submit timestamps to `before-submit-prompt.csv` |
| `log-edits.js` | Logs file edits for Cursor edit events |
| `log-session.js` | Session logging (sessionStart/sessionEnd); writes `.cursor/events/sessions.csv` with session type (agent \| ask \| edit) |
| `post-commit.js` | Writes commit history and upload payload |
| `upload-history.js` | On pre-push, reads payload files and POSTs each to Stella |

### Claude Code scripts (`--agent claude`)

| Script | Purpose |
|--------|---------|
| `clear-events-after-push-claude.js` | Clears `.claude/events/` CSVs after pre-push upload |
| `log-edits-claude.js` | Logs PreToolUse (Read) and PostToolUse (Edit/Write) to `.claude/events/edits.csv` |
| `log-prompt-claude.js` | Logs UserPromptSubmit events to `.claude/events/before-submit-prompt.csv` |
| `log-stop-claude.js` | Logs Stop events to `.claude/events/after-agent-response.csv` |
| `log-session-claude.js` | Session logging (SessionStart/SessionEnd); writes `.claude/events/sessions.csv` |
| `post-commit-claude.js` | Writes commit history to `.claude/history/` and builds upload payload |
| `upload-history-claude.js` | On pre-push, reads `.claude/history/*-payload.json` and POSTs each to Stella |

### What the installer does

**For Cursor (`--agent cursor`):**
- Validate the installation token with the Stella API
- Create `.cursor/hooks/` with the Cursor scripts
- Create `.cursor/hooks.json` so Cursor runs the hooks
- Create `.cursor/hooks/upload-config.json` with the provided API URL, project code, and `agent: "cursor"`
- Install git hooks: **post-commit** and **pre-push**
- Add Cursor-related entries to `.gitignore`

**For Claude Code (`--agent claude`):**
- Validate the installation token with the Stella API
- Create `.claude/hooks/` with the Claude Code scripts
- Create `.claude/settings.local.json` so Claude Code runs the hooks (SessionStart, SessionEnd, PreToolUse, PostToolUse, UserPromptSubmit, Stop)
- Create `.claude/hooks/upload-config.json` with the provided API URL, project code, and `agent: "claude"`
- Install git hooks: **post-commit** and **pre-push**
- Add Claude-related entries to `.gitignore`

After each commit, `.cursor/history/<sha>-payload.json` contains the exact request body that will be sent on the next push, so you can inspect sessions and duration before pushing.

## Requirements

- Node.js 18+
- Git (for git hooks)
- A repository already added in Stella dashboard
- An installation token generated from the repository setup guide in the Stella dashboard

## Verifying that CSV events are written

The prompt/response hooks write to `.cursor/events/before-submit-prompt.csv` and `after-agent-response.csv`. If those files stay empty (headers only):

1. **Confirm Cursor is using project hooks**  
   Cursor reads `.cursor/hooks.json` from the **workspace root**. If you opened a parent folder or a different root, that folder’s `hooks.json` is used (or none). Open the repo that contains `.cursor/hooks.json` as the workspace root.

2. **Run the hook by hand** (from the repo root):
   ```bash
   echo "{\"conversation_id\":\"test\",\"generation_id\":\"test\"}" | node .cursor/hooks/log-before-submit-prompt.js
   ```
   Then check `.cursor/events/before-submit-prompt.csv` for a new row. If you see it, the script and path are fine; Cursor may not be invoking the hook (e.g. hook support or config location).

3. **Check Cursor’s output**  
   If the hook runs but gets bad input (e.g. encoding on Windows), you may see `[log-before-submit-prompt] Invalid JSON:` in the terminal or Cursor’s developer tools.

## Configuration

You can also provide parameters via environment variables instead of command-line arguments:

- `CURSOR_HISTORY_PROJECT_CODE` – project code
- `CURSOR_HISTORY_INSTALLATION_TOKEN` – installation token
- `CURSOR_HISTORY_UPLOAD_URL` – full cursor-history endpoint URL
- `STELLA_AGENT` – agent type (`cursor` or `claude`); defaults to `cursor`

**Note:** The installation token is validated during installation and must be valid and not expired. Tokens expire 24 hours after generation.

## Publishing

Publishing is done by the GitHub workflow [Publish GenDD Studio CLI](../.github/workflows/publish-gendd-studio-cli.yml) (push to `production`, tag `gendd-studio-cli-v*`, or manual dispatch). It requires the `NPM_TOKEN` secret.

If publish fails with **404 Not Found** for `@hatchworksai/gendd-studio-cli`:

1. Create the npm organization **hatchworksai** at [npmjs.com/org/create](https://www.npmjs.com/org/create) if it does not exist.
2. Add the npm user whose token is in `NPM_TOKEN` to that org with a role that can publish (e.g. Developer).
3. Use a token that can publish (e.g. Automation token or Classic token with "Publish packages").

## License

MIT