# SANDCODE.md

This file provides guidance to SANDCODE when working with code in this repository.

## What is SANDCODE

A fully independent, privately branded fork of Claude Code. Uses **z.ai GLM-5.1** as the default AI model via the Anthropic-compatible endpoint at `api.z.ai/api/anthropic`. Zero dependency on Anthropic's npm packages — the SDK is vendored at `src/vendor/sandcode-sdk/`.

## Install & Run

### Quick install from GitHub (any machine)

```bash
# Requires Node.js >= 22 and either tsx or Bun
npm install -g tsx          # if you don't have Bun
npm install -g https://github.com/Djsand/SANDCODE
sandcode
```

The postinstall script automatically downloads the correct ripgrep binary for your platform (Windows/macOS/Linux, x64/arm64). On first run, SANDCODE will prompt for your z.ai API key.

### Run from source (development)

```bash
git clone https://github.com/Djsand/SANDCODE.git
cd SANDCODE

# Install dependencies (also runs postinstall: vendor copy + ripgrep download)
npm install

# Run directly
node bin/sandcode.js

# Or link globally
npm link
sandcode
```

### Production build (Bun required)

```bash
bun run build.ts
```

## Key Architecture

### Entry Flow
`bin/sandcode.js` → spawns `tsx` (or `bun`) → `src/entrypoints/cli.tsx` → `src/main.tsx`

The bin script detects Bun or tsx, sets up MACRO globals and `bun:bundle` shims, then spawns the entry point. `cli.tsx` has fast-paths for `--version`, `--help`, etc. Everything else loads `main.tsx` which sets up Commander, config, and the Ink React UI.

### Runtime Shims (`shims/`)
- `loader.js` — registers the `bun-bundle-hook.js` module resolution hook for tsx
- `bun-bundle-hook.js` — redirects `bun:bundle` imports to `shims/bun_bundle.js`, handles `.md` file imports, `.node`/`.napi` stubs
- `bun-preload.ts` — defines `globalThis.MACRO` for Bun dev mode
- `bun_bundle.js` — `feature()` always returns `false` in dev mode

### React Compiler Output
Most `.tsx` files in `src/components/` are **React Compiler output** with `_c()` memoization caches. When editing:
- Only change string literals and prop values
- NEVER change `$[N]` cache indices or `_c(N)` cache sizes
- `Symbol.for("react.memo_cache_sentinel")` checks are one-time init — don't duplicate

### Vendor Packages (`src/vendor/`)
Vendored copies of `@anthropic-ai/sdk` (as `@sandcode/sdk`), `color-diff-napi` (stub), `sandbox-runtime` (stub). The `postinstall` script (`scripts/copy-vendor.js`) copies these to `node_modules/@sandcode/` and `node_modules/color-diff-napi/`.

After `npm install`, always verify vendors are in place — `npm install` wipes `node_modules` before the postinstall hook restores them.

### z.ai API Integration
- Config: `src/utils/zaiSetupPrompt.ts` — plain readline prompt before Ink renders (avoids keybinding conflicts)
- Client: `src/services/api/client.ts` — z.ai branch creates standard `Anthropic` SDK client pointed at `api.z.ai/api/anthropic`
- Provider detection: `src/utils/model/providers.ts` — `isZaiProvider()` checks env and config
- Model configs: `src/utils/model/configs.ts` — GLM model entries in `ALL_MODEL_CONFIGS`
- Context window: `src/utils/context.ts` — GLM models get 200k

### Plugin Compatibility
Plugins from Claude Code's ecosystem use `.claude-plugin/` directories. SANDCODE has fallback logic in `src/utils/plugins/marketplaceManager.ts` that checks `.claude-plugin/` when `.sandcode-plugin/` is not found. The hook system also expands both `${SANDCODE_PLUGIN_ROOT}` and `${CLAUDE_PLUGIN_ROOT}` for backward compat.

### Branding Constants
- Theme colors: `src/utils/theme.ts` — amber/gold palette (`claude` key = `rgb(245,166,35)`)
- Figures: `src/constants/figures.ts` — `TEARDROP_ASTERISK = '◈'` (diamond, not Claude's `✻`)
- Turn verbs: `src/constants/turnCompletionVerbs.ts` — building theme (Forged, Crafted, etc.)
- Product URL: `src/constants/product.ts` — `https://sandcode.sh`
- Logo: `src/components/LogoV2/Clawd.tsx` — "SAND" box-drawing wordmark
- Distro defaults: `src/distro/defaults.ts` — `defaultProvider: 'zai'`, `defaultModel: 'GLM-5.1'`

### Config Hierarchy
`src/distro/defaults.ts` < `~/.sandcode/config.json` (user) < `.sandcode/settings.json` (project)

### Directory Layout
```
bin/            CLI entry point
shims/          bun:bundle and MACRO shims for tsx
scripts/        postinstall vendor copy
src/
  entrypoints/  cli.tsx (fast paths + main import)
  main.tsx      Commander setup, startup, Ink root
  screens/      REPL.tsx (main conversation loop)
  components/   React/Ink UI components
  services/     API client, analytics, compact, MCP, OAuth
  tools/        Tool implementations (Bash, Edit, Read, etc.)
  commands/     Slash commands (/init, /model, /compact, etc.)
  utils/        Config, auth, model, theme, hooks, plugins
  constants/    Prompts, figures, betas, tool limits
  recipes/      Recipe system (bundled workflows)
  distro/       SANDCODE identity defaults + welcome
  vendor/       Vendored @sandcode/sdk, stubs
```

## Telemetry

All Anthropic telemetry endpoints are disabled (metrics, feedback, transcript sharing return no-ops). Set `SANDCODE_METRICS_ENDPOINT` to enable your own telemetry server.
