Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .claude/skills/architecture/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
name: architecture
description: Monorepo structure, dependency graph, domain boundaries, and package-level constraints for the Confidence CLI project
version: '0.4'
---

# Architecture Guidelines

Structural rules, domain boundaries, and constraints for the Confidence CLI monorepo.

## Monorepo Structure

| Package | Published | Purpose |
| ------------------------- | --------- | -------------------------------------------------------------------------------------------------------- |
| `packages/shared-kernel/` | No | Cross-domain types and `noop` helper |
| `packages/eslint-config/` | No | Shared ESLint config (base + react presets) |
| `packages/core/` | No | Shared infrastructure (auth, session, telemetry, exec, system, sdk, frameworks, integrations, providers) |
| `packages/testing/` | No | Test infrastructure (sub-paths: `/auth`, `/scaffold`, `/env`, `/terminal`, `/msw`, `/e2e`) |
| `packages/quickstart/` | Yes | TUI wizard — `@spotify-confidence/quickstart` |
| `packages/cli/` | Yes | CLI — `@spotify-confidence/cli` |

### Dependency Graph

```
shared-kernel ◄── core ◄── quickstart ◄── cli
▲
└── testing
```

## Import Rules

**Cross-package** — always use npm package name:

```ts
import { authenticate } from '@spotify-confidence/core';
import type { IdeId } from '@spotify-confidence/shared-kernel';
import { buildTestJwt } from '@spotify-confidence/testing/auth';
```

**Intra-package** — use path aliases for cross-domain, relative for within-domain:

| Package | Aliases |
| ---------- | ----------------------------------------------------------------- |
| quickstart | `@commands/*`, `@features/*`, `@ui/*` |
| cli | `@commands/*`, `@features/*`, `@output/*`, `@api/*` |
| core | Relative imports in `src/`; tsconfig aliases in `__tests__/` only |

## Domain Boundaries

- **shared-kernel** — Types used by 3+ packages. Depends on nothing.
- **core** — Shared infrastructure. Must not import from quickstart, cli, or testing.
- **testing** — Test scaffolds. Depends on shared-kernel only.
- **quickstart** — TUI wizard. See `ink-tui` skill for UI details.
- **cli** — CLI binary. See `cli` skill for command architecture.

## Hard Constraints

### Dependency direction

```
cli → quickstart, core, shared-kernel
quickstart → core, shared-kernel
core → shared-kernel
shared-kernel → nothing
```

No circular dependencies. No upward imports.

Within quickstart UI: `screen slices → hooks/, lib/, components/ → lib/ → nothing in ui/`

### No product knowledge in the TUI

The TUI is a generic wizard shell. Confidence-specific domain logic belongs in the Claude Code Skill and is delivered via MCP tools.

### Screen identification

Always use `ScreenId` enum values from `@spotify-confidence/core`. Never use raw strings.

### State mutations

All session state changes go through `WizardStore` setters. Never mutate the session object directly.

### UI component sourcing

Use `@inkjs/ui` components over standalone `ink-*` packages.
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
---
name: auth
description: OAuth2 PKCE authentication flow with Confidence via Auth0
version: '0.2'
---

# Authentication Skill

Handles OAuth2 PKCE authentication with Confidence via Auth0.

## Flow

1. **Check existing credentials** — Look for persisted token at `$TMPDIR/confidence_token`. Validate JWT expiry.
1. **Check existing credentials** — Look for persisted token at `$CONFIDENCE_CONFIG_DIR/credentials.json` (or `$TMPDIR/confidence_token` legacy path). Validate JWT expiry.
2. **Prompt user** — If valid token exists, offer to reuse or re-authenticate. If no token, ask whether to create a new account or sign in.
3. **Browser-based OAuth2 PKCE** — Start local HTTP server on port 8084, open browser to Auth0 authorize endpoint, wait for callback with authorization code.
4. **Token exchange** — Exchange authorization code + PKCE verifier for access token and refresh token.
5. **Persist tokens** — Write access token to `$TMPDIR/confidence_token`, refresh token to `$TMPDIR/confidence_refresh_token`, and the Auth0 organization (`org_id` claim, falling back to `https://confidence.dev/org_login_id`) to `$TMPDIR/confidence_organization`.
5. **Persist tokens** — Write credentials to the config directory.
6. **Extract region** — Decode JWT payload, read `https://confidence.dev/region` claim (EU or US) to determine regional API endpoints.

## Auth0 Configuration
Expand Down Expand Up @@ -42,13 +48,15 @@ The auth flow is implemented in `packages/core/src/auth/authenticate.ts` using N
- `fetch` for token exchange with Auth0
- JWT payload decoded manually (base64url) — no external JWT library needed

## Token Files
## Token Persistence

Tokens are stored in the Confidence config directory (`$CONFIDENCE_CONFIG_DIR` or `~/.config/confidence/`):

| File | Content |
| ------------------ | --------------------------------------------- |
| `credentials.json` | JWT access token, refresh token, organization |

| File | Content |
| ---------------------------------- | ------------------------------------------------------------- |
| `$TMPDIR/confidence_token` | JWT access token |
| `$TMPDIR/confidence_refresh_token` | Refresh token for silent re-auth |
| `$TMPDIR/confidence_organization` | Auth0 organization for skipping the workspace prompt on login |
The `CONFIDENCE_TOKEN` env var overrides persisted tokens when present.

## Remembered Workspace

Expand Down
52 changes: 52 additions & 0 deletions .claude/skills/cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: cli
description: Structure, commands, output formatting, and conventions for the packages/cli/ package
version: '0.2'
---

# CLI Package

The `packages/cli/` package — the `confidence` binary for managing Confidence feature flags, events, session recordings, and configuration. Published as `@spotify-confidence/cli`.

## Build

tsdown bundles `core` and `shared-kernel` into the binary. `quickstart` stays external (dynamically imported at runtime). Target: Node 24+ ESM.

## Command Architecture

Each command exports a yargs command object:

```ts
export const exampleCommand = {
command: 'example',
describe: 'One-line description',
builder(yargs: Argv) { ... }, // optional — for subcommands or extra options
async handler(argv: Record<string, unknown>) { ... },
};
```

### Command Types

- **Standalone** — `login`, `logout`, `whoami`, `config` — directly perform their action
- **Setup** — `flags setup`, `events setup`, `recordings setup` — delegate to quickstart TUI with pre-selected features
- **TUI launcher** — `quickstart` — launches the full interactive wizard

## Output Formatting

All structured output goes through `src/output/`:

- **`resolveFormat()`** — priority: `--json` flag → `--output` flag → TTY detection (TTY → table, pipe → JSON)
- **`formatJson()`** — wraps data in `{ data, meta? }` envelope
- **`formatTable()`** — dynamically-sized columns with Unicode separators

Commands never call `JSON.stringify` directly.

## Quickstart Integration

`launchQuickstart()` in `src/features/quickstart/launch.ts` maps feature names to goal IDs (`flags` → `feature-flags`, etc.), dynamically imports `startTui` from `@spotify-confidence/quickstart`, and passes through CLI options.

## Hard Constraints

- Commands must not contain UI rendering logic — delegate to quickstart for TUI flows.
- Auth logic lives in `@spotify-confidence/core`, not in command handlers.
- The CLI must not import from quickstart's internal modules — only from its public `startTui` export.
41 changes: 41 additions & 0 deletions .claude/skills/coding-conventions/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: coding-conventions
description: TypeScript style, import ordering, module exports, and linting rules for the Confidence CLI monorepo
version: '0.2'
---

# Coding Conventions

TypeScript style and linting rules that apply across all packages.

## TypeScript Style

- **Import order** (blank-line separated): node built-ins → React → external deps → `@spotify-confidence/*` → path aliases → relative
- **`type` over `interface`** for all type definitions
- **Object params** when a function has 4+ arguments
- **`satisfies never`** in switch defaults for exhaustiveness checking
- **Modern syntax**: `satisfies`, `using` for disposables, etc.

## React / Hooks

- **Named functions in `useEffect`**, not arrow functions:
```ts
useEffect(function autoAdvance() { ... }, [deps]);
```
- **`AbortController`** for event listener cleanup instead of manual `removeEventListener`
- **`eslint-plugin-react-hooks`** with `recommended-latest`, all set to `error`

## Module Exports

- Barrel files re-export only the public API — no internal helpers.
- Use named types in `actions.ts` for union extensions.

## Quickstart-Specific

- **`useInitial*` hooks** for slices that compute initial state at mount: (1) pure `resolve*` function, (2) `useEffect` to sync store, (3) return values for parent hook.
- **Dry run separation** — keep dry-run logic in a separate function, never interleaved with conditionals.
- **Enums** — `ScreenId` for screens, `HAlign`/`VAlign` for alignment, `Colors`/`Icons` from `styles.ts` for theming. Never raw strings or values.

## Linting

Strict — all rules are errors. Config from `@spotify-confidence/eslint-config` (base) or `/react` (for React packages). Never suppress warnings or diagnostics; fix the root cause.
39 changes: 39 additions & 0 deletions .claude/skills/development-harness/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
name: development-harness
description: Quality gates, commit conventions, pre-commit hooks, and CI/CD processes for the Confidence CLI monorepo
version: '0.3'
---

# Development Harness

Quality gates, commit conventions, and CI/CD for the monorepo.

## Quality Harness

Run `pnpm qa` before committing and pushing — it runs typecheck + lint + test. Use `pnpm lint:fix` to auto-fix formatting.

Pre-commit hooks (Husky + lint-staged) auto-format staged files on every commit.

## Commit Conventions

All commits follow [Conventional Commits](https://www.conventionalcommits.org/), enforced by a `commit-msg` hook via commitlint.

```
<type>(<optional scope>): <description>
```

Types: `feat` (minor bump), `fix` (patch bump), `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`. Append `!` for breaking changes (major bump).

```
feat(cli): add whoami command
fix(frameworks): correct Next.js detection for app router
refactor(core): extract shared types to lib module
```

## CI/CD

**PR checks** (`.github/workflows/ci.yml`): typecheck + lint + test + commit message validation. Both must pass before merging.

**Release** (`.github/workflows/release.yml`): release-please opens a PR on `main` with changelog + version bumps. Merging the Release PR triggers GitHub Release + npm publish. No manual version bumping — versions are derived from commit messages.

Required secrets: `GITHUB_TOKEN` (automatic), `NPM_TOKEN` (repository secret).
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
name: ink-tui
description: Develop and modify the Ink-based terminal UI for the Confidence Wizard
version: '0.1'
description: Develop and modify the Ink-based terminal UI in the packages/quickstart/ package
version: '0.2'
---

# Ink TUI Wizard Skill
# Ink TUI Skill

This skill covers building and modifying the interactive terminal user interface for the Confidence Wizard CLI. The TUI is built with Ink (React for CLIs), @inkjs/ui, and nanostores for state management.
This skill covers building and modifying the interactive terminal user interface in `packages/quickstart/`. The TUI is built with Ink (React for CLIs), @inkjs/ui, and nanostores for state management.

## Core Architecture

Expand Down
38 changes: 38 additions & 0 deletions .claude/skills/integrations/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: integrations
description: IDE integration strategy pattern and guidelines for the packages/core/src/integrations/ module
version: '0.4'
---

# IDE Integrations Guidelines

Structure, constraints, and conventions for IDE integrations in `packages/core/src/integrations/`.

## Strategy Pattern

Each supported IDE (Claude Code, Cursor, Codex) is a self-contained `IdeIntegration` object in its own subdirectory. This eliminates per-IDE `switch` statements and makes adding a new IDE a single-directory change.

Every IDE implements the `IdeIntegration` interface: `id`, `name`, `launchChat()`, `runOnboarding()`, `detectPlugins()`, `installPlugins()`, `detectMcpStatuses()`, `connectMcpServer()`. See the type definition in `types.ts` for the full contract.

Thin orchestrators (`chat.ts`, `plugins.ts`) resolve the strategy via `getIntegration(ide)` and delegate.

## Hard Constraints

- **IDE subdirs are self-contained** — no imports from other IDE subdirs. Each is split into `paths.ts`, `plugins.ts`, `mcp.ts`, and `index.ts`. May import from `../types.js`, `../mcp/servers.js`, `../shared.js` — never from `../registry.js` or each other.
- **No switch-on-IDE outside strategies** — code outside `integrations/` must not branch on `IdeId`. Use `getIntegration(ide)` and call strategy methods.
- **Dependency direction** — integrations imports from `shared-kernel` and other core modules, never from `quickstart/` or `cli/`.
- **Clean-dev script** — when changing MCP-related code, verify `scripts/clean-dev-env.sh` still cleans up correctly. Update it when adding a new IDE.

## Adding a New IDE

1. Create `packages/core/src/integrations/<ide-name>/index.ts` with `paths.ts`, `plugins.ts`, `mcp.ts`
2. Export a `const <name>Integration: IdeIntegration`
3. Add to the `INTEGRATIONS` array in `registry.ts`
4. Update `scripts/clean-dev-env.sh`

No other source files need changes.

## Codex Runtime Constraints

- **Shell environment policy** — always pass `-c 'shell_environment_policy.inherit="core"'` in Codex `exec` spawn args, otherwise `npm install` times out on corporate networks.
- **Event batching** — Codex `exec --json` only emits `item.completed` events (no incremental deltas). Status lines only appear after a full message turn. Claude Code and Cursor stream incrementally.
Loading
Loading