Skip to main content
ClaudeWave
Skill2.2k repo starsupdated 2d ago

skillshare-devcontainer

This skill executes CLI commands and Go tests inside a Linux devcontainer, essential because the project's binary is Linux-only while the host is macOS. Use it for running `ss`/`skillshare` commands, `go test`, reproducing bugs, testing features, or starting the web UI. The skill provides zero-rebuild workflow since source code is bind-mounted and the `ss` wrapper auto-builds on each invocation, allowing immediate testing of host-side edits without manual compilation steps.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/runkids/skillshare /tmp/skillshare-devcontainer && cp -r /tmp/skillshare-devcontainer/.skillshare/skills/skillshare-devcontainer ~/.claude/skills/skillshare-devcontainer
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

Execute CLI commands and tests inside the devcontainer. The host machine is macOS but the project binary is Linux — running CLI commands on the host will silently produce wrong results or fail. This skill prevents that mistake.

## When to Use This

- Running `ss` / `skillshare` commands for verification
- Running `go test`, `make test`, `make check`
- Reproducing a bug report
- Testing a feature you just implemented
- Starting the web UI dashboard
- Any command that needs the skillshare binary or Go toolchain

## When NOT to Use This

- Editing source code (do that on host via Read/Edit tools)
- Running `git` commands (git works on host)
- Running `make fmt`, `make lint` (host-safe Go toolchain commands; no container needed)
- E2E test runbooks → use `cli-e2e-test` skill instead (it handles ssenv isolation)

## Architecture: Two Layers of Isolation

```
Host (macOS)
  └─ Devcontainer (Linux, Debian-based)
       ├─ Default HOME: /home/developer (persistent volume)
       ├─ Source: /workspace (bind-mount of repo root)
       └─ ssenv environments: ~/.ss-envs/<name>/ (isolated HOME dirs)
```

**Devcontainer** = Linux environment with Go, git, pnpm, air (hot-reload). Source code is at `/workspace` (bind-mount of the host repo). The `ss` / `skillshare` wrapper auto-builds from source on every invocation — **no manual `make build` needed**. Edit code on the host, then immediately `docker exec` to run it; the change is picked up automatically.

**ssenv** = Isolated HOME directories within the devcontainer. Each env gets its own `~/.config/skillshare/`, `~/.claude/`, etc. Use ssenv when you need a clean state (testing init, install, sync) without polluting the container's default HOME.

## Zero-Rebuild Workflow

Source code is bind-mounted into the container at `/workspace`. The `ss` wrapper runs `go build` transparently on every invocation:

1. Edit files on host (Read/Edit tools)
2. `docker exec $CONTAINER ss <command>` — picks up your changes instantly
3. No `make build`, no restart, no rebuild step

This also applies to `go test` — tests always compile against the latest source. The Web UI backend uses `air` for hot-reload (same zero-rebuild experience).

## Entering the Devcontainer

The quickest way — one command builds, initialises, and enters the shell:

```bash
make devc           # build + init + interactive shell (one step)
make devc-up        # start only (no shell)
make devc-down      # stop
make devc-restart   # restart + re-run start-dev.sh
make devc-reset     # full reset (remove volumes), then `make devc` to re-init
make devc-status    # show container status
```

Works with **or without** VS Code — `make devc` handles the full lifecycle autonomously.

### Programmatic access (for `docker exec` workflows)

```bash
CONTAINER=$(docker compose -f .devcontainer/docker-compose.yml ps -q skillshare-devcontainer 2>/dev/null)
```

If `$CONTAINER` is empty, tell the user:
> Devcontainer is not running. Start it with `make devc-up`.

Then verify the binary:
```bash
docker exec $CONTAINER bash -c \
  '/workspace/.devcontainer/ensure-skillshare-linux-binary.sh && ss version'
```

## Running Commands

### Simple command (uses container's default HOME)

```bash
docker exec $CONTAINER ss <command> [flags]
```

Good for: `ss version`, `ss status`, `ss list`, `ss check`, `ss audit`.

### Command with isolated HOME (clean state)

```bash
ENV_NAME="test-$(date +%s)"
docker exec $CONTAINER ssenv create "$ENV_NAME" --init
docker exec $CONTAINER ssenv enter "$ENV_NAME" -- ss status
# Cleanup when done:
docker exec $CONTAINER ssenv delete "$ENV_NAME" --force
```

Good for: testing `init`, `install`, `sync`, `uninstall` — anything that modifies config/state.

### Multi-command sequence

```bash
docker exec $CONTAINER ssenv enter "$ENV_NAME" -- bash -c '
  ss install runkids/demo-skills --track --force
  ss list
  ss sync
'
```

Always use `bash -c '...'` for multi-command sequences inside `ssenv enter`.

### Go tests

```bash
# All tests (unit + integration)
docker exec $CONTAINER bash -c 'cd /workspace && make test'

# Unit tests only
docker exec $CONTAINER bash -c 'cd /workspace && make test-unit'

# Integration tests only
docker exec $CONTAINER bash -c 'cd /workspace && make test-int'

# Specific test
docker exec $CONTAINER bash -c 'cd /workspace && go test ./tests/integration -run TestInit_Fresh -count=1'

# Specific package
docker exec $CONTAINER bash -c 'cd /workspace && go test ./internal/install/... -count=1'
```

Always `cd /workspace` before Go commands — ssenv changes HOME which can break module resolution.

### Go tests with auth disabled

Some tests (e.g., `TestResolveToken`, `TestAuthEnv`) need auth credentials removed:

```bash
docker exec $CONTAINER bash -c '
  eval "$(credential-helper --eval off)"
  cd /workspace
  go test ./internal/github -run TestResolveToken -count=1
  eval "$(credential-helper --eval on)"
'
```

## Web UI Dashboard

```bash
# Start (global mode)
docker exec $CONTAINER ui

# Start (project mode — uses ~/demo-project)
docker exec $CONTAINER ui -p

# Stop
docker exec $CONTAINER ui stop
```

Dashboard accessible at `http://localhost:5173` (Vite dev server with HMR).
API backend at `http://localhost:19420`.
Logs: `/tmp/api-dev.log`, `/tmp/vite-dev.log`.

## ssenv Quick Reference

| Shortcut | Full form | Purpose |
|----------|-----------|---------|
| `ssnew <name>` | `ssenv create <name>` + enter | Create and enter isolated shell |
| `ssuse <name>` | `ssenv enter <name>` | Enter existing isolated shell |
| `ssrm <name>` | `ssenv delete <name> --force` | Delete environment |
| `ssls` | `ssenv list` | List all environments |
| `ssback` | `ssenv reset` | Leave isolated context |
| `sshelp` | `help` | Show all devcontainer commands |

For automation (non-interactive), prefer `ssenv enter <name> -- <command>` over `ssnew`/`ssuse` (which launch subshells).

## Ports

| Port | Service | Notes |
|------|---------|-------|
| 5173 | Vite dev server | React dashboard with HM