Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5543531
feat: integrate tmux session spawning with seamless fallback
ahundt Nov 7, 2025
e191339
WIP daemon/tmux: integrate profile system with TypeScript-enhanced tm…
ahundt Nov 7, 2025
dd4d4a0
chore: update @anthropic-ai/claude-code dependency to 2.0.24
ahundt Nov 7, 2025
4e37c31
fix: critical profile schema inconsistency between GUI and CLI
ahundt Nov 7, 2025
8b0efe3
feat: add profile validation and schema migration with backwards comp…
ahundt Nov 15, 2025
6829836
docs(CLI): reorganize documentation with clear user/developer separation
ahundt Nov 16, 2025
edc2db2
fix(daemon): enable GUI profile selection by reading options.environm…
ahundt Nov 16, 2025
3f4c0dd
feat(CLI): add happy-dev global binary for development variant
ahundt Nov 16, 2025
30201e7
feat: add defaultPermissionMode and defaultModelMode to AIBackendProf…
ahundt Nov 17, 2025
ad06ed4
feat: add defaultSessionType to profile schema (CLI)
ahundt Nov 17, 2025
f425f6b
feat(CLI): expand ${VAR} references in profile environment variables …
ahundt Nov 17, 2025
f903de5
feat(CLI): log warnings for undefined ${VAR} references in profile en…
ahundt Nov 17, 2025
1be091a
fix: escape template literal in log message
ahundt Nov 17, 2025
182c051
feat(CLI): add dev/stable variant management with automatic environme…
ahundt Nov 16, 2025
2f8a313
feat(CLI): tmux defaults to first existing session when name empty or…
ahundt Nov 17, 2025
f515987
fix: critical bugs and add comprehensive test coverage for profile sync
ahundt Nov 17, 2025
495714f
fix(CLI): critical GUI-CLI compatibility bug in tmux sessionName hand…
ahundt Nov 17, 2025
753fe78
chore: remove one-off compatibility report markdown file
ahundt Nov 17, 2025
9724949
fix(CLI): enable environment variables in tmux sessions for alternati…
ahundt Nov 21, 2025
9f54333
fix(daemon): pass environmentVariables from GUI to spawnSession function
ahundt Nov 21, 2025
c9c5c24
expandEnvVars.ts: support bash parameter expansion ${VAR:-default} sy…
ahundt Nov 22, 2025
9828fdd
fix(claudeRemote.ts,persistence.ts,types.ts): enable bypassPermission…
ahundt Nov 22, 2025
5ec36cf
fix(api/types.ts): define complete PermissionMode type for both Claud…
ahundt Nov 22, 2025
21cb3ff
fix(tmux.ts): enable working directory and fix window creation bugs
ahundt Nov 22, 2025
5bbe2bd
fix(tmux): use native tmux -P flag to get process PID
ahundt Nov 22, 2025
9a0a0e4
fix(tmux): ensure complete environment inheritance for tmux sessions
ahundt Nov 22, 2025
a6c6189
fix(api.ts): gracefully handle 404 when POST /v1/machines endpoint un…
ahundt Nov 23, 2025
30a3d58
fix(runClaude.ts,runCodex.ts): add cross-agent permission mode fallba…
ahundt Nov 23, 2025
aa9586c
Update @anthropic-ai/claude-code to 2.0.53 and @anthropic-ai/sdk to 0…
jkomoros Nov 25, 2025
64163a5
Merge remote-tracking branch 'origin/main' into claude/yolo-mode-pers…
ahundt Nov 29, 2025
4a6495d
fix(auth,runClaude): add DEBUG guards and fail-fast on invalid daemon…
ahundt Nov 29, 2025
4f85832
logger.ts: fix circular dependency with persistence module
ahundt Nov 29, 2025
7edbc9b
chore: add .worktrees to gitignore
ahundt Dec 7, 2025
3c22580
package.json,README.md,scripts: make happy-dev a development-only com…
ahundt Dec 7, 2025
ba267fb
README.md,CONTRIBUTING.md: move development docs to CONTRIBUTING.md
ahundt Dec 7, 2025
c860715
fix(types,sdk): merge main + simplify PermissionMode to single type
ahundt Dec 10, 2025
0d5bfa6
feat(cli): add comprehensive Bun support for Claude Code CLI detection
ahundt Dec 15, 2025
320a229
runtime(support): add transparent runtime compatibility layer for Bun…
ahundt Dec 15, 2025
c59c448
Merge branch 'feature/bun-support-claude-cli-detection' into feature/…
ahundt Dec 15, 2025
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
17 changes: 17 additions & 0 deletions .envrc.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Happy CLI Development Environment
#
# This file is for direnv users who want automatic environment switching
# when entering this directory.
#
# Setup:
# 1. Install direnv: https://direnv.net/
# 2. Copy this file: cp .envrc.example .envrc
# 3. Run: direnv allow
#
# The .envrc file is gitignored, so each developer can customize it.

export HAPPY_HOME_DIR="$HOME/.happy-dev"
export HAPPY_VARIANT="dev"
export HAPPY_SERVER_URL="${HAPPY_SERVER_URL:-https://api.cluster-fluster.com}"

echo "🔧 DEV environment activated (data: $HAPPY_HOME_DIR)"
9 changes: 7 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ pnpm-lock.yaml
# Environment variables
.env
.env*.local
.envrc

# Claude code session level settings
.claude/settings.local.json

# Local installation
# Local installation and data directories
.happy/
.happy-dev/

**/*.log
.release-notes-temp.md
.release-notes-temp.md

# Git worktrees for isolated branch work
.worktrees/
333 changes: 333 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
# Contributing to Happy CLI

## Prerequisites

- Node.js >= 20.0.0
- Yarn (`npm install -g yarn`)
- Git
- Claude CLI installed and logged in (`claude` command available in PATH)

## Getting Started

```bash
git clone https://github.com/slopus/happy-cli.git
cd happy-cli
yarn install
yarn build
```

## Development Commands

### Global `happy-dev` Command

Create a global `happy-dev` command that runs your local development build:

```bash
yarn link:dev # Create happy-dev symlink
yarn unlink:dev # Remove happy-dev symlink
```

This creates a `happy-dev` command in your PATH pointing to your local build, while leaving any npm-installed `happy` command untouched.

| Command | Runs |
|---------|------|
| `happy` | Stable npm version (from `npm install -g happy-coder`) |
| `happy-dev` | Local development version (from this repo) |

**Note:** Run `yarn build` before `yarn link:dev` to ensure the binary exists.

### Build Commands

```bash
yarn build # Build the project
yarn typecheck # TypeScript type checking
yarn test # Run tests
yarn dev # Run without building (uses tsx)
```

## Stable vs Dev Data Isolation

The CLI supports running stable and development versions side-by-side with completely isolated data.

### Initial Setup (Once)

```bash
npm run setup:dev
```

This creates:
- `~/.happy/` - Stable version data (production-ready)
- `~/.happy-dev/` - Development version data (for testing changes)

### Daily Usage

**Stable (production-ready):**
```bash
npm run stable:daemon:start
```

**Development (testing changes):**
```bash
npm run dev:daemon:start
```

## Visual Indicators

You'll always see which version you're using:
- `✅ STABLE MODE - Data: ~/.happy`
- `🔧 DEV MODE - Data: ~/.happy-dev`

## Common Tasks

### Authentication

```bash
# Authenticate stable version
npm run stable auth login

# Authenticate dev version (can use same or different account)
npm run dev auth login

# Logout
npm run stable auth logout
npm run dev auth logout
```

### Daemon Management

```bash
# Check status of both
npm run stable:daemon:status
npm run dev:daemon:status

# Stop both
npm run stable:daemon:stop
npm run dev:daemon:stop

# Start both simultaneously
npm run stable:daemon:start && npm run dev:daemon:start
```

### Running Any Command

```bash
# Stable version
npm run stable <command> [args...]
npm run stable notify "Test message"
npm run stable doctor

# Dev version
npm run dev:variant <command> [args...]
npm run dev:variant notify "Test message"
npm run dev:variant doctor
```

## Data Isolation

Both versions maintain complete separation:

| Aspect | Stable | Development |
|--------|--------|-------------|
| Data Directory | `~/.happy/` | `~/.happy-dev/` |
| Settings | `~/.happy/settings.json` | `~/.happy-dev/settings.json` |
| Auth Keys | `~/.happy/access.key` | `~/.happy-dev/access.key` |
| Daemon State | `~/.happy/daemon.state.json` | `~/.happy-dev/daemon.state.json` |
| Logs | `~/.happy/logs/` | `~/.happy-dev/logs/` |

**No conflicts!** Both can run simultaneously with separate:
- Authentication sessions
- Server connections
- Daemon processes
- Session histories
- Configuration settings

## Advanced: direnv Auto-Switching

For automatic environment switching when entering directories:

1. Install [direnv](https://direnv.net/):
```bash
# macOS
brew install direnv

# Add to your shell (bash/zsh)
eval "$(direnv hook bash)" # or zsh
```

2. Setup direnv for this project:
```bash
cp .envrc.example .envrc
direnv allow
```

3. Now `cd` into the directory automatically sets `HAPPY_VARIANT=dev`!

## Troubleshooting

### Commands not working?
```bash
npm install
```

### Permission denied on scripts?
```bash
chmod +x scripts/*.cjs
```

### Data directories not created?
```bash
npm run setup:dev
```

### Both daemons won't start?
Check port conflicts - each daemon needs its own port. The dev daemon will automatically use a different port from stable.

### How do I check which version is running?
Look for the visual indicator:
- `✅ STABLE MODE` = stable version
- `🔧 DEV MODE` = development version

Or check the daemon status:
```bash
npm run stable:daemon:status # Shows ~/.happy/ data location
npm run dev:daemon:status # Shows ~/.happy-dev/ data location
```

### `yarn link:dev` fails with permission denied?
```bash
sudo yarn link:dev
```

### `happy-dev` command not found after linking?
- Ensure your global npm bin is in PATH: `npm bin -g`
- Try opening a new terminal window
- Check the symlink was created: `ls -la $(npm bin -g)/happy-dev`

## Tips

1. **Use stable for production work** - Your tested, reliable version
2. **Use dev for testing changes** - Test new features without breaking your workflow
3. **Run both simultaneously** - Compare behavior side-by-side
4. **Different accounts** - Use different Happy accounts for dev/stable if needed
5. **Check logs** - Logs are separated: `~/.happy/logs/` vs `~/.happy-dev/logs/`

## Example Workflow

```bash
# Initial setup (once)
yarn install
yarn build
yarn link:dev
npm run setup:dev

# Authenticate both
npm run stable auth login
npm run dev:variant auth login

# Start both daemons
npm run stable:daemon:start
npm run dev:daemon:start

# Do your development work...
# Edit code, build, test with dev version

# When ready, update stable version
npm run stable:daemon:stop
git pull # or your deployment process
npm run stable:daemon:start

# Dev continues running unaffected!
```

## How It Works

The system uses the built-in `HAPPY_HOME_DIR` environment variable to separate data:

- **Stable scripts** set: `HAPPY_HOME_DIR=~/.happy`
- **Dev scripts** set: `HAPPY_HOME_DIR=~/.happy-dev`

Everything else (auth, sessions, logs, daemon) automatically follows the `HAPPY_HOME_DIR` setting.

Cross-platform via Node.js - works identically on Windows, macOS, and Linux!

## Testing Profile Sync Between GUI and CLI

Profile synchronization ensures AI backend configurations created in the Happy mobile/web GUI work seamlessly with the CLI daemon.

### Profile Schema Validation

The profile schema is defined in both repositories:
- **GUI:** `sources/sync/settings.ts` (AIBackendProfileSchema)
- **CLI:** `src/persistence.ts` (AIBackendProfileSchema)

**Critical:** These schemas MUST stay in sync to prevent sync failures.

### Testing Profile Sync

1. **Create profile in GUI:**
```
- Open Happy mobile/web app
- Settings → AI Backend Profiles
- Create new profile with custom environment variables
- Note the profile ID
```

2. **Verify CLI receives profile:**
```bash
# Start daemon with dev variant
npm run dev:daemon:start

# Check daemon logs
tail -f ~/.happy-dev/logs/*.log | grep -i profile
```

3. **Test profile-based session spawning:**
```bash
# From GUI: Start new session with custom profile
# Check CLI daemon logs for:
# - "Loaded X environment variables from profile"
# - "Using GUI-provided profile environment variables"
```

4. **Verify environment variable expansion:**
```bash
# If profile uses ${VAR} references:
# - Set reference var in daemon environment: export Z_AI_AUTH_TOKEN="sk-..."
# - Start session from GUI
# - Verify daemon logs show expansion: "${Z_AI_AUTH_TOKEN}" → "sk-..."
```

### Testing Schema Compatibility

When modifying profile schemas:

1. **Update both repositories** - Never update one without the other
2. **Test migration** - Existing profiles should migrate gracefully
3. **Version bump** - Update `CURRENT_PROFILE_VERSION` if schema changes
4. **Test validation** - Invalid profiles should be caught with clear errors

### Common Issues

**"Invalid profile" warnings in logs:**
- Check profile has valid UUID (not timestamp)
- Verify environment variable names match regex: `^[A-Z_][A-Z0-9_]*$`
- Ensure compatibility.claude or compatibility.codex is true

**Environment variables not expanding:**
- Reference variable must be set in daemon's process.env
- Check daemon logs for expansion warnings
- Verify no typos in ${VAR} references

## Publishing to npm

Maintainers can publish new versions:

```bash
yarn release # Interactive version bump, changelog, publish
```

This runs tests, builds, and publishes to npm. The published package includes:
- `happy` - Main CLI command
- `happy-mcp` - MCP bridge command

**Note:** `happy-dev` is intentionally excluded from the npm package - it's for local development only.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ This will:
- `HAPPY_DISABLE_CAFFEINATE` - Disable macOS sleep prevention (set to `true`, `1`, or `yes`)
- `HAPPY_EXPERIMENTAL` - Enable experimental features (set to `true`, `1`, or `yes`)

## Contributing

Interested in contributing? See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.

## Requirements

- Node.js >= 20.0.0
Expand Down
Loading