docs: add claude code skills, settings, and update architecture guide (#378)

This commit is contained in:
Carlos Florêncio
2026-03-05 21:48:27 +00:00
committed by GitHub
parent 766e62d8c2
commit d56f13273a
8 changed files with 338 additions and 72 deletions
+42
View File
@@ -0,0 +1,42 @@
---
name: clean-branches
description: Delete local branches whose remote has been deleted ([gone]), including their worktrees. Use for branch cleanup after merging PRs.
---
# Clean Branches
Remove local branches that have been deleted on the remote (marked `[gone]`), including any associated git worktrees.
## Steps
1. **Fetch and prune remote refs:**
```bash
git fetch --prune
```
2. **List branches to identify [gone] status:**
```bash
git branch -v
```
Branches with a `+` prefix have associated worktrees that must be removed before deletion.
3. **List worktrees for reference:**
```bash
git worktree list
```
4. **Remove worktrees and delete [gone] branches:**
```bash
git branch -v | grep '\[gone\]' | sed 's/^[+* ]//' | awk '{print $1}' | while read branch; do
echo "Processing branch: $branch"
worktree=$(git worktree list | grep "\\[$branch\\]" | awk '{print $1}')
if [ ! -z "$worktree" ] && [ "$worktree" != "$(git rev-parse --show-toplevel)" ]; then
echo " Removing worktree: $worktree"
git worktree remove --force "$worktree"
fi
echo " Deleting branch: $branch"
git branch -D "$branch"
done
```
5. **Report** which branches and worktrees were removed. If none were `[gone]`, say no cleanup was needed.
+66
View File
@@ -0,0 +1,66 @@
---
name: code-review
description: Review changed code in the Kandev monorepo for quality, security, and architecture compliance. Use after implementing features or before opening PRs.
---
# Code Review
Review the current changes in the Kandev codebase (Go + Next.js monorepo).
## Steps
### 1. Run verification first
Invoke the `/verify` skill to ensure all formatters, linters, typechecks, and tests pass. Do NOT proceed with review until verify passes clean.
### 2. Identify changed files
Run `git diff --name-only` (and `git diff --cached --name-only` for staged changes) to get the list of modified files. Read each changed file.
### 3. Review for issues
Check every changed file for the following. Report issues with `file_path:line_number` references.
**Complexity limits** (these are enforced by CI — catch them early):
- Go: functions ≤80 lines, ≤50 statements, cyclomatic ≤15, cognitive ≤30, nesting ≤5
- TS: files ≤600 lines, functions ≤100 lines, cyclomatic ≤15, cognitive ≤20, nesting ≤4
- If a file is too large or a function too complex, split it into smaller cohesive files/functions grouped by responsibility
**Duplicated code:**
- Look for copy-pasted logic across changed files and their surrounding code
- Extract shared helpers, constants, or utility functions when duplication is found
**Dead code:**
- Unused functions, variables, imports, types, or unreachable branches introduced by the changes
- Remove them — don't leave commented-out code
**Security:**
- No secrets, tokens, or credentials in code
- Proper input validation at system boundaries (user input, API handlers, external data)
- No SQL injection, XSS, command injection, or path traversal risks
**Architecture violations:**
- Frontend: no direct data fetching in components (must go through store), shadcn imports from `@kandev/ui` not `@/components/ui/*`
- Backend: provider pattern for DI, context passed through call chains, event bus for cross-component communication
**Missing unit tests:**
- Backend (Go): new or changed functions/methods should have corresponding tests
- Frontend (JS/TS libs only): new utility functions, hooks, API clients, and store slices should have tests
- We do NOT test React components — skip those
- Flag untested logic but don't block on it; suggest what tests to add
**Improvements:**
- Suggest simplifications, better naming, or more idiomatic patterns — but only if the improvement is clear and worth the churn
- Don't nitpick formatting or style that linters already cover
### 4. Fix or report
- **Fix directly** any issues you can resolve confidently (dead code, unused imports, simple duplication, missing early returns)
- **Report with explanation** any issues that need the author's input (architectural decisions, ambiguous test coverage, design trade-offs)
### 5. Summary
Provide a brief summary:
- Number of issues found and fixed
- Any remaining items that need author attention
- Overall assessment: ready to merge, needs minor fixes, or needs rework
+1 -1
View File
@@ -1,6 +1,6 @@
---
name: commit
description: Create git commits following Conventional Commits format. Use when committing changes, creating commits, or when the user asks to commit. Ensures commit messages conform to the project's changelog generation conventions.
description: Stage and commit changes using Conventional Commits. Use when there are dirty/staged files to commit, the user says "commit", or before pushing a PR.
---
# Commit
+73
View File
@@ -0,0 +1,73 @@
---
name: pr-comments
description: Address PR review comments — fix valid ones, react with thumbs up, resolve threads, and push.
---
# PR Comments
Read and address review comments on a pull request, then push fixes.
## Context
- Current branch: !`git branch --show-current`
- Current PR (if any): !`gh pr view --json number,url,title --jq '"\(.url) - \(.title)"' 2>/dev/null || echo "no PR found"`
## Steps
### 1. Fetch comments
Get the PR number from context or the user. Fetch all review comments:
```bash
gh pr view <number> --json reviews,comments
gh api repos/{owner}/{repo}/pulls/<number>/comments
```
Also check for top-level PR comments and review threads.
### 2. Triage each comment
For each comment, decide:
- **Valid and actionable** — the comment points to a real issue (bug, missing edge case, naming, architecture concern, code quality). Proceed to fix it.
- **Already addressed** — the code already handles what the comment suggests. Skip it.
- **Nitpick or preference** — subjective style preference not covered by linters. Skip unless the reviewer is insistent.
- **Wrong or outdated** — the comment misunderstands the code or refers to old state. Skip it.
### 3. Fix valid comments
For each valid comment:
1. Read the file at the referenced line
2. Implement the fix
3. React with a thumbs up on the comment:
```bash
gh api repos/{owner}/{repo}/pulls/comments/<comment_id>/reactions -f content="+1"
```
4. Resolve the review thread:
```bash
gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: "<thread_node_id>"}) { thread { isResolved } } }'
```
Get the `thread_node_id` from the review threads query (use `node_id` field from the thread, not the comment ID).
### 4. Verify
Run `/verify` to ensure formatters, linters, typechecks, and tests all pass. Do NOT push until verify passes clean.
### 5. Commit and push
Run `/commit` to stage and commit the fixes. Use a message like:
```
fix: address PR review feedback
```
or be more specific if fixes are scoped (e.g., `fix: add nil check per review feedback`).
Then push:
```bash
git push
```
### 6. Summary
Report what was done:
- Which comments were addressed (with thumbs up)
- Which comments were skipped and why
- Link to the pushed commit
+57
View File
@@ -0,0 +1,57 @@
---
name: push-pr
description: Push the current branch and open a draft PR. Use when the user wants to open a pull request or push their work for review.
---
## Context
- Current git status: !`git status`
- Current branch: !`git branch --show-current`
- Commits on this branch vs main: !`git log --oneline main..HEAD`
- Recent commit messages for style reference: !`git log --oneline -5`
## Your task
Push the current branch and open a **draft** pull request.
### Rules
1. **Uncommitted changes:** If there are dirty or staged changes, run the `/commit` skill first to commit them before proceeding.
2. **Branch:** If on `main`, create a new branch from the commits (use a descriptive name like `feat/short-description` or `fix/short-description`) and switch to it before pushing. If already on a feature branch, use it as-is.
3. **Push:** Push the branch to origin with `-u` to set upstream tracking.
4. **PR title** must follow Conventional Commits format (CI validates this via `pr-title.yml`, and it becomes the squash-merge commit used for release notes):
- Format: `type(scope): lowercase description` or `type: lowercase description`
- Allowed types: `feat`, `fix`, `perf`, `refactor`, `docs`, `chore`, `ci`, `test`
- Subject starts with a lowercase letter
- Keep under 72 characters
- Add `!` after type for breaking changes: `feat!: remove legacy API`
- Examples: `feat(ui): add task filter dialog`, `fix: prevent duplicate session on reconnect`
5. **PR body** must follow the project's pull request template. Fill in each section using these rules:
- **Summary** (required): 1–2 sentences of prose, no heading. Lead with the problem/goal, end with the outcome. Say WHY, not what.
- **Important Changes** (optional): short bullet list of significant architectural changes. Remove section if not needed.
- **Validation** (required): list commands or checks run (e.g. `go test ./...`, `make lint`).
- **Diagram** (optional): Mermaid diagram only for non-obvious flows. Remove section if not needed.
- **Possible Improvements** (optional): one line on risk and what could go wrong. Remove section if not needed.
- **Checklist**: always include as-is, do not pre-fill.
- **Related issues**: use `Closes #N` if applicable, otherwise remove.
- Do NOT add tool attribution footers.
- Do NOT leave placeholder text or unfilled sections.
6. **Always create as draft:** Use `gh pr create --draft`.
7. **Execute in a single message.** Push and create the PR using parallel tool calls where possible. Do not read files or do anything else beyond what's listed here.
### Command
```
gh pr create --draft --title "type: description" --body "$(cat <<'EOF'
<filled PR template>
EOF
)"
```
8. **Return the PR URL** when done.
+35
View File
@@ -0,0 +1,35 @@
---
name: verify
description: Run format, typecheck, test, and lint across the monorepo. Use after implementing changes.
---
# Verify
Run the full verification pipeline for the Kandev monorepo, then fix any issues found.
## Steps
1. **Format first** (prevents formatter-induced lint failures):
- `make -C apps/backend fmt`
- `cd apps && pnpm format`
2. **Verify in parallel** where possible:
- `make -C apps/backend test lint`
- `cd apps && pnpm --filter @kandev/web typecheck && pnpm --filter @kandev/web lint`
3. **Fix issues** — do NOT just report them:
- Read each failing file at the reported line number
- Fix the root cause (don't suppress warnings or add ignores)
- Common fixes:
- **Type errors**: fix the type, add a missing import, or correct the function signature
- **Lint — function too long**: extract a helper function or sub-component
- **Lint — file too long**: split the file into smaller, cohesive files grouped by responsibility (e.g., separate types, helpers, constants, or sub-domains into their own files)
- **Lint — cyclomatic/cognitive complexity**: simplify conditionals, extract early returns, break into smaller functions
- **Lint — unused imports**: remove them
- **Lint — duplicate strings**: extract to a constant
- **Test failures**: read the test, understand the assertion, fix the code (not the test) unless the test is outdated
- After fixing, re-run only the failed command to confirm the fix
4. **Repeat** steps 2-3 until all commands pass. If a fix introduces new issues, address those too.
5. **Done** when all four pass cleanly: fmt, typecheck, test, lint.
+24
View File
@@ -0,0 +1,24 @@
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "f=\"$TOOL_INPUT_FILE_PATH\"; case \"$f\" in *.ts|*.tsx|*.js|*.jsx) root=$(cd \"$(dirname \"$f\")\" && git rev-parse --show-toplevel 2>/dev/null) && npx --prefix \"$root/apps\" prettier --write \"$f\" 2>/dev/null ;; *.go) gofmt -w \"$f\" 2>/dev/null ;; esac"
}
]
},
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "f=\"$TOOL_INPUT_FILE_PATH\"; case \"$f\" in *.ts|*.tsx|*.js|*.jsx) root=$(cd \"$(dirname \"$f\")\" && git rev-parse --show-toplevel 2>/dev/null) && npx --prefix \"$root/apps\" prettier --write \"$f\" 2>/dev/null ;; *.go) gofmt -w \"$f\" 2>/dev/null ;; esac"
}
]
}
]
}
}
+40 -71
View File
@@ -9,6 +9,7 @@ apps/
├── backend/ # Go backend (orchestrator, lifecycle, agentctl, WS gateway)
├── web/ # Next.js frontend (SSR + WS + Zustand)
├── cli/ # CLI tool (TypeScript)
├── landing/ # Landing page
└── packages/ # Shared packages/types
```
@@ -42,22 +43,26 @@ apps/backend/
│ │ ├── discovery/ # Agent discovery
│ │ ├── docker/ # Docker-specific agent logic
│ │ ├── dto/ # Agent data transfer objects
│ │ ├── executor/ # Executor types, checks, and service
│ │ ├── handlers/ # Agent event handlers
│ │ ├── registry/ # Agent type registry and defaults
│ │ ├── runtime/ # Runtime name constants
│ │ ├── settings/ # Agent settings
│ │ ├── mcpconfig/ # MCP server configuration
│ │ └── remoteauth/ # Remote auth catalog and method IDs for remote executors/UI
│ ├── agentctl/
│ │ ├── client/ # HTTP client for talking to agentctl
│ │ └── server/ # agentctl HTTP server
│ │ ├── acp/ # ACP protocol implementation
│ │ ├── adapter/ # Protocol adapters + transport/ (ACP, Codex, OpenCode, Copilot, Amp)
│ │ ├── api/ # HTTP endpoints
│ │ ├── adapter/ # Protocol adapters (ACP, Codex, Copilot, Amp)
│ │ ├── config/ # agentctl configuration
│ │ ├── instance/ # Multi-instance management
│ │ ├── mcp/ # MCP server integration
│ │ ├── process/ # Agent subprocess management
│ │ └── shell/ # Shell session management
│ │ ├── shell/ # Shell session management
│ │ └── utility/ # agentctl utilities
│ ├── orchestrator/ # Task execution coordination
│ │ ├── dto/ # Orchestrator data transfer objects
│ │ ├── executor/ # Launches agents via lifecycle manager
│ │ ├── handlers/ # Orchestrator event handlers
│ │ ├── messagequeue/ # Message queue for agent prompts
@@ -84,6 +89,7 @@ apps/backend/
│ ├── integration/ # External integrations
│ ├── lsp/ # LSP server
│ ├── mcp/ # MCP protocol support
│ ├── health/ # Health check endpoints
│ ├── notifications/ # Notification system
│ ├── persistence/ # Persistence layer
│ ├── prompts/ # Prompt management
@@ -96,6 +102,7 @@ apps/backend/
│ │ └── ...
│ ├── tools/ # Tool integrations
│ ├── user/ # User management
│ ├── utility/ # Shared utility functions
│ ├── workflow/ # Workflow engine
│ │ ├── engine/ # Typed state-machine engine (trigger evaluation, action callbacks, transition store)
│ │ ├── models/ # Workflow step, template, and history models
@@ -122,13 +129,11 @@ apps/backend/
- Idempotent by `OperationID`; session-scoped data bag via `MachineState.Data`
**Lifecycle Manager** (`internal/agent/lifecycle/`) manages agent instances:
- `Manager` (`manager.go`) - central coordinator for agent lifecycle
- `Runtime` interface (`runtime.go`) - abstracts execution environment (Docker, Standalone, Remote Docker)
- `Manager` (`manager.go`, `manager_*.go`) - central coordinator for agent lifecycle
- `ExecutorBackend` interface (`executor_backend.go`) - abstracts execution environment (Docker, Standalone, Sprites, Remote Docker)
- `ExecutionStore` (`execution_store.go`) - thread-safe in-memory execution tracking
- `session.go` - ACP session initialization and resume
- `streams.go` - WebSocket stream connections to agentctl
- `events.go` - publishes events to the event bus
- `container.go` - Docker container operations
- `process_runner.go` - agent process launch and management
- `profile_resolver.go` - resolves agent profiles/settings
@@ -141,43 +146,23 @@ apps/backend/
**Executor Types** (database model):
- `local_pc` - Standalone process on host ✅
- `local_docker` - Docker container on host ✅
- `sprites` - Sprites cloud environment ✅
- `remote_docker`, `remote_vps`, `k8s` - Planned
**Runtime Interface** implements execution:
```go
type Runtime interface {
Name() runtime.Name
HealthCheck(ctx context.Context) error
CreateInstance(ctx context.Context, req *RuntimeCreateRequest) (*RuntimeInstance, error)
StopInstance(ctx context.Context, instance *RuntimeInstance, force bool) error
RecoverInstances(ctx context.Context) ([]*RuntimeInstance, error)
}
```
### Execution Flow
```
Client (WS) Orchestrator Lifecycle Manager Runtime agentctl
| | | | |
| task.start | | | |
|--------------->| LaunchAgent() | | |
| |--------------------->| CreateInstance() | |
| | |----------------->| (container) |
| | | |--------------->|
| | StartAgentProcess() | | |
| |--------------------->| ConfigureAgent() | |
| | |-----------------------------> |
| | | Start() | |
| | |-----------------------------> |
| | | | agent proc |
| | |<---- stream updates (WS) ---------|
|<--- WS events -| | | |
Client (WS) → Orchestrator → Lifecycle Manager → ExecutorBackend (container/process) → agentctl
↓
Client (WS) ← Orchestrator ← Lifecycle Manager ←──── stream updates (WS) ──────── agent subprocess
```
**Session Resume:**
- `TaskSession.ACPSessionID` - stored ACP session ID for resume
- `ExecutorRunning` - tracks active executor state (container ID, port, worktree)
- On backend restart: `RecoverInstances()` finds running containers, reconnects streams
1. Orchestrator receives `task.start` via WS
2. Lifecycle Manager creates executor instance (container or process)
3. agentctl starts inside the instance, agent subprocess is configured and started
4. Agent events stream back via WS through the chain
**Session Resume:** `TaskSession.ACPSessionID` stored for resume; `ExecutorRunning` tracks active state; on restart `RecoverInstances()` reconnects.
**Provider Pattern:** Packages expose `Provide(cfg, log) (*impl, cleanup, error)` for DI. Returns implementation, cleanup function, and error. Cleanup called during graceful shutdown.
@@ -189,47 +174,30 @@ Client (WS) Orchestrator Lifecycle Manager Runtime age
## agentctl Server
### HTTP Endpoints
### API Groups
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/health` | GET | Health check |
| `/api/v1/status` | GET | Agent status |
| `/api/v1/configure` | POST | Configure agent before start |
| `/api/v1/start` | POST | Start agent subprocess |
| `/api/v1/stop` | POST | Stop agent |
| `/api/v1/acp/*` | Various | ACP protocol (initialize, session/*, prompt) |
| `/api/v1/shell/*` | Various | Shell operations |
| `/api/v1/workspace/*` | Various | Git status, file changes |
| `/ws/updates` | WS | Agent event stream |
| `/ws/workspace` | WS | Workspace event stream (git, files, shell) |
agentctl exposes these route groups (see `internal/agentctl/server/api/`):
- `/health`, `/info`, `/status` - Health and status
- `/instances/*` - Multi-instance management
- `/processes/*` - Agent subprocess management (start/stop)
- `/agent/configure`, `/agent/stream` - Agent configuration and event streaming
- `/git/*` - Git operations (status, commit, push, pull, rebase, stage, etc.)
- `/shell/*` - Shell session management
- `/workspace/*` - File operations, search, tree
- `/vscode/*` - VS Code integration proxy
### Adapter Model
Protocol adapters normalize different agent CLIs:
Protocol adapters in `adapter/transport/` normalize different agent CLIs:
- `AgentAdapter` interface defines `Start()`, `Stop()`, `Prompt()`, `Cancel()`
- `ACP` - ACP JSON-RPC over stdio (Claude Code)
- `Codex` - Codex-style JSON-RPC (OpenAI Codex)
- `CopilotAdapter` - GitHub Copilot SDK
- `AmpAdapter` - Sourcegraph Amp CLI
- Transports: `acp` (Claude Code), `codex` (OpenAI Codex), `opencode`, `shared`, `streamjson`
- Top-level adapters: `CopilotAdapter` (GitHub Copilot SDK), `AmpAdapter` (Sourcegraph Amp)
- `process.Manager` owns subprocess, wires stdio to adapter
- Factory pattern in `adapter/factory.go` selects adapter by agent type
---
### ACP Protocol
## ACP Protocol
JSON-RPC 2.0 over stdin/stdout between agentctl and agent process.
**Backend -> Agent (Requests)**
- `initialize` - handshake
- `session/new` - create new session
- `session/load` - resume existing session
- `session/prompt` - send user message
- `session/cancel` - cancel current operation
**Agent -> Backend (Notifications)**
- `session/update` with types: `message_chunk`, `tool_call`, `tool_update`, `complete`, `error`, `permission_request`, `context_window`
JSON-RPC 2.0 over stdin/stdout between agentctl and agent process. Requests: `initialize`, `session/new`, `session/load`, `session/prompt`, `session/cancel`. Notifications: `session/update` with types `message_chunk`, `tool_call`, `tool_update`, `complete`, `error`, `permission_request`, `context_window`.
---
@@ -271,11 +239,12 @@ lib/state/
│ └── ui/ # preview, connection, active state
├── hydration/ # SSR merge strategies
hooks/domains/{kanban,session,workspace,settings}/ # Domain-organized hooks
hooks/domains/{kanban,session,workspace,settings,comments,github}/ # Domain-organized hooks
lib/api/domains/ # API clients
├── kanban-api, session-api, workspace-api, settings-api, process-api
├── plan-api, queue-api, workflow-api, stats-api, github-api
├── user-shell-api, debug-api, secrets-api, sprites-api, vscode-api
├── health-api, utility-api
```
**Key State Paths:**
@@ -346,4 +315,4 @@ This file is read by AI coding agents (Claude Code via `CLAUDE.md` symlink, Code
---
**Last Updated**: 2026-02-26
**Last Updated**: 2026-03-05