CLI tools for setting up and integrating Confidence with user projects.
pnpm workspace with six packages under packages/:
| Package | Published | Purpose |
|---|---|---|
packages/shared-kernel/ |
No (private) | Cross-domain types (AuthState, IdeId, OnboardingGoal, etc.) and lightweight helpers (noop, isDefined, isWindows). Breaks circular dependencies between core and testing. |
packages/eslint-config/ |
No (private) | Shared ESLint configuration. Exports base preset and /react preset with React Hooks rules. |
packages/core/ |
No (private) | Shared infrastructure — api, auth, config, session, telemetry, exec, system, sdk, mcp, utils, constants, frameworks, integrations, providers. Depends on shared-kernel. |
packages/testing/ |
No (private) | Test infrastructure — auth scaffolds, project scaffolds, env helpers, terminal helpers, MSW handlers. Sub-path exports: /auth, /scaffold, /env, /terminal, /msw, /e2e. Depends on shared-kernel. |
packages/quickstart/ |
Yes (@spotify-confidence/quickstart) |
Interactive TUI wizard. Depends on core and shared-kernel. |
packages/cli/ |
Yes (@spotify-confidence/cli) |
CLI for managing Confidence (flags, events, recordings, config). Depends on quickstart. |
shared-kernel (shared leaf)
▲
├── core (infrastructure)
├── testing (test scaffolds)
├── quickstart (TUI wizard) ──► core
└── cli (CLI) ──► quickstart ──► core
api/— HTTP client, types, and base request helpers for Confidence APIsauth/— OAuth PKCE flow + token persistenceconfig/— Persistent CLI configuration (read/write/reset)session/— WizardSession state, ScreenId enum, createSessiontelemetry/— Analytics + session trackingexec/— Running external commands (spawn, execFile, resolveBin)system/— Environment vars, filesystem helpers, system checkssdk/— SDK metadata + optionsmcp/— MCP client and server type definitionsutils/— Generic utilities (prompt-utils, semver)constants.ts— Confidence URLs + env-derived valuesframeworks/— Framework detection (react, nextjs, node, go, java, kotlin, python, swift)integrations/— IDE integration strategies (claude, cursor, codex) + MCP, skills, chatproviders/— Provider detection (Statsig, Eppo, PostHog, Optimizely) + dependency scanners
bin/cli.ts— Entry point (yargs, launches TUI)src/commands/— CLI command definitions (default, help)src/features/— Vertical feature slices (onboarding/prompt builder)src/ui/— Ink/React TUI (screens, components, hooks, theme, store, router)
bin/cli.ts— Entry point (yargs,confidencebinary)src/commands/— Command definitions (login, logout, whoami, config, flags, events, recordings, docs, mcp, plugin, sdk, migrate, update, quickstart, warehouse)src/features/— Feature implementations (config, docs, events, flags, ide, mcp, migrate, plugin, quickstart, recordings, sdk, update, warehouse)src/input/— Input parsing (file reading, aliases, resolve)src/output/— Output formatters (json, table, format detection)src/network/— API clients (flags, events, recordings, docs, config, registry, warehouse)src/utils/— Shared utilities (auth, safely, telemetry, validation)
- Reactive state:
WizardStoreuses nanostores atoms. Screens subscribe viauseSyncExternalStore. - Screen navigation:
WizardRouteruses a state-machine transition map (screen-transitions.ts) with a history stack for back navigation. Screens navigate via the type-safeuseNavigation(ScreenId.X)hook, callingnav.to('event')ornav.back(). Adding a branch is one new edge in the transition map. - Screen slices: Every screen is a subdirectory under
src/ui/screens/containing the component, a barrelindex.ts, and collocatedlog-messages.ts+telemetry-events.ts+actions.ts. Slices with side-effect hooks also contain their hooks. Shared log/telemetry factories stay inui/lib/. Slices that compute initial state at mount time have a collocateduseInitial*hook. To add a screen: create subdir inscreens/, add component + barrel + slice files, addScreenIdenum value, register inscreen-registry.tsx, add transitions inscreen-transitions.ts. - IDE strategy pattern: Each IDE (Claude Code, Cursor, Codex) is a self-contained
IdeIntegrationobject underpackages/core/src/integrations/. Adding a new IDE means creating one subdir and adding it to the registry. - No product knowledge in TUI: The TUI is a generic wizard shell. Confidence-specific domain logic belongs in the Claude Code Skill and MCP tools, not in the UI layer.
pnpm install # Install all workspace deps
pnpm --filter @spotify-confidence/quickstart try # Run the wizard locally via tsx
pnpm --filter @spotify-confidence/cli try # Run the CLI locally via tsx
pnpm test # Run all tests (core + quickstart + cli)
pnpm test:e2e # Build + run quickstart e2e tests
pnpm lint # ESLint + Prettier check across all packages
pnpm typecheck # TypeScript type checking across all packages
pnpm qa # Run all checks: typecheck + lint + test
pnpm build # Build all packagesPer-package commands:
pnpm --filter @spotify-confidence/core test # Core unit tests only
pnpm --filter @spotify-confidence/quickstart test # Quickstart unit tests only
pnpm --filter @spotify-confidence/cli test # CLI unit tests only
pnpm --filter @spotify-confidence/quickstart build # Build quickstart for distribution
pnpm --filter @spotify-confidence/cli build # Build CLI for distribution- TypeScript (strict mode, NodeNext modules)
- Ink 7 + React 19 (TUI rendering)
- @inkjs/ui (Select, TextInput, Spinner, etc.)
- nanostores (reactive state)
- yargs (CLI parsing)
- vitest (testing)
- tsdown (bundling)
- pnpm workspaces (monorepo)
The CLI works alongside Confidence MCP servers:
confidence-flags— Feature flag management (create, list, resolve, target, archive)confidence-docs— Documentation search and SDK integration guides
These are accessed via the Claude Code Skill, not directly from the TUI.
E2E tests use node-pty to drive the TUI in a real terminal. This native module requires platform-specific build tools. If pnpm install fails on node-pty, install the prerequisites listed at https://github.com/microsoft/node-pty#dependencies.
The stable node-pty release (v1.1.0) doesn't ship prebuilt binaries for Node.js v26+. The project uses node-pty@1.2.0-beta.14 which includes updated Node-API bindings for newer Node versions. If you hit this error on a newer Node version, ensure the beta is installed. On CI with Node 24, the stable release works fine.
- Cross-package imports use npm package names:
import { authenticate } from '@spotify-confidence/core',import type { IdeId } from '@spotify-confidence/shared-kernel'. - Within quickstart, use path aliases (
@commands/*,@features/*,@ui/*) for cross-domain imports. Keep relative imports within the same domain. - Within cli, use path aliases (
@commands/*,@features/*,@input/*,@output/*,@network/*,@utils/*,@meta,@composition) for cross-domain imports. Keep relative imports within the same domain. - Within core source (
packages/core/src/), use relative imports. Core's__tests__/may use tsconfig path aliases (@auth/*,@integrations/*, etc.). - Test imports from
@spotify-confidence/testinguse sub-path exports:@spotify-confidence/testing/auth,@spotify-confidence/testing/scaffold,@spotify-confidence/testing/env,@spotify-confidence/testing/terminal,@spotify-confidence/testing/e2e. - Use
@inkjs/uicomponents over standaloneink-*packages. - Screens go in
packages/quickstart/src/ui/screens/(as slices), reusable components incomponents/. - Shared modules (
hooks/,lib/,components/) must never import from screen slices. If a type is needed by both, put it inui/lib/. - Framework integrations each get their own subdir under
packages/core/src/frameworks/. - All state mutations go through
WizardStoresetters so reactivity works. - Enums for screen IDs, not string literals.
- Prefer
AbortControllerfor removing event listeners instead of manualremoveEventListener. - All commits must follow Conventional Commits. The
commit-msghook enforces this via commitlint. - Run
pnpm qabefore pushing to ensure CI will pass. - When writing or modifying code, always use the
architectureandcoding-conventionsskills first. - When writing, modifying, or adding any test file (unit, integration, or e2e), always use the
testingskill first. For e2e tests, also loadtesting-e2e. - When working on the
packages/cli/package, load thecliskill. - When making commits or working with the CI/release pipeline, use the
development-harnessskill for guidelines.
Before making any changes, agents MUST load the relevant skill(s) from .claude/skills/. These skills contain the authoritative guidelines for this project — architecture constraints, coding conventions, testing philosophy, and development harness rules. Skipping them leads to guideline violations.
| Skill | When to load | Key rules |
|---|---|---|
architecture |
Any code change | Monorepo structure, dependency graph, domain separation, package boundaries, cross-package imports |
coding-conventions |
Any code change | TypeScript style (type over interface, satisfies never, object params for 4+ args), import ordering, module exports, linting, React hooks |
auth |
Authentication changes | OAuth PKCE flow, token persistence, Auth0 config, JWT handling, regional endpoints |
cli |
packages/cli/ changes |
Command architecture, output formatting, config feature, quickstart integration, path aliases |
ink-tui |
Any TUI/screen change | Ink rendering model, @inkjs/ui over standalone packages, Colors/Icons/HAlign/VAlign from styles.ts, named functions in useEffect |
integrations |
IDE integration changes | Strategy pattern, self-contained IDE subdirs, adding new IDEs, MCP/chat/plugin flows |
testing |
Any test change or addition | Observable behavior only, AAA pattern, sut naming, using for disposables, waitFor over delay, MSW for HTTP mocks |
testing-e2e |
E2E test changes | node-pty framework, createSession(), press('Enter'), waitForText, checkpoint, navigation helpers |
development-harness |
Commits, CI, releases | Conventional Commits, pnpm qa before push, pre-commit hooks, release-please |
workflows |
Workflow changes | Hash-pinned actions with version comments, minimal permissions, per-secret references |