Implement a feature from a spec file or description using TDD workflow. Use this skill whenever the user asks to: add a new CLI command, implement a feature from a spec, build new functionality, add a flag, create a new internal package, or write Go code for skillshare. This skill enforces test-first development, proper handler split conventions, oplog instrumentation, and dual-mode (global/project) patterns. If the request involves writing Go code and tests, use this skill — even if the user doesn't explicitly say "implement".
Implement a feature following TDD workflow. $ARGUMENTS is a spec file path (e.g., specs/my-feature.md) or a plain-text feature description.
Scope: This skill writes Go code and tests. It does NOT update website docs (use update-docs after) or CHANGELOG (use changelog after).
Before acting, run python3 scripts/ai-context.py cli-development testing. Those topics are the source of truth for repository patterns, execution boundaries and verification; this skill retains the TDD orchestration.
If $ARGUMENTS is a file path:
If $ARGUMENTS is a description:
List all files that will be created or modified:
# Typical pattern for a new command
cmd/skillshare/<command>.go # Command handler
cmd/skillshare/<command>_project.go # Project-mode handler (if dual-mode)
internal/<package>/<feature>.go # Core logic
tests/integration/<command>_test.go # Integration testDisplay the file list and continue.
Write integration tests using testutil.Sandbox:
func TestFeature_BasicCase(t *testing.T) {
sb := testutil.NewSandbox(t)
defer sb.Cleanup()
// Setup
sb.CreateSkill("test-skill", map[string]string{
"SKILL.md": "---\nname: test-skill\n---\n# Content",
})
// Act
result := sb.RunCLI("command", "args...")
// Assert
result.AssertSuccess(t)
result.AssertOutputContains(t, "expected output")
}Verify tests fail (inside the devcontainer, see the skillshare-devcontainer skill):
docker exec "$CONTAINER" bash -c 'cd /workspace && go test ./tests/integration -run TestFeature_BasicCase -count=1'Write minimal code to make tests pass:
cmd/skillshare/ and internal/internal/ui for terminal output (colors, spinners, boxes)start := time.Now()
// ... do work ...
e := oplog.NewEntry("command-name", statusFromErr(err), time.Since(start))
oplog.Write(configPath, oplog.OpsFile, e)main.go commands map if new commandVerify tests pass:
docker exec "$CONTAINER" bash -c 'cd /workspace && make test-int'docker exec "$CONTAINER" bash -c 'cd /workspace && make check' # fmt-check + lint + testThese patterns appear throughout the codebase. Follow them when implementing new features.
Large commands are split by concern rather than kept in a single file. When a command handler grows beyond ~300 lines, split it:
| Suffix | Purpose | Example |
|---|---|---|
<cmd>.go | Flag parsing + mode routing (dispatch) | install.go |
_handlers.go | Core handler logic | install_handlers.go |
_render.go / _audit_render.go | Output rendering | audit_render.go |
_prompt.go / _prompt_tui.go | Decision/prompt logic | install_prompt.go |
_tui.go | Full-screen TUI (bubbletea) | list_tui.go |
_batch.go | Batch operation orchestration | update_batch.go |
_resolve.go | Target/skill resolution | update_resolve.go |
_context.go | Mode-specific context struct | install_context.go |
_format.go | Output formatting helpers | log_format.go |
Principle: dispatch file does ONLY flag parsing + mode routing. Logic goes in sub-files.
Most commands support both global (-g) and project (-p) mode:
func handleMyCommand(args []string) error {
mode, rest, err := parseModeArgs(args)
if err != nil { return err }
switch mode {
case modeProject:
return handleMyCommandProject(rest)
default:
return handleMyCommandGlobal(rest)
}
}Create <cmd>_project.go for project-mode handler. Use parseModeArgs() from mode.go.
All interactive prompts use bubbletea (not survey). Key components:
checklist_tui.go — shared checklist/radio pickerlist_tui.go — filterable list with detail panelsearch_tui.go — multi-select checkbox listColor palette: cyan Color("6"), gray Color("8"), yellow #D4D93C.
Dispatch order: JSON output → TUI (if TTY + items + no --no-tui flag) → empty check → plain text.
If the feature needs a Web UI endpoint, add internal/server/handler_<name>.go:
func (s *Server) handle<Name>(w http.ResponseWriter, r *http.Request) {
// ...
writeJSON(w, result) // 200 OK with JSON
// writeError(w, 400, msg) // for errors
}Register in server.go route setup. Branch on s.IsProjectMode() for mode-specific behavior.
All mutating commands log to operations.log (JSONL):
start := time.Now()
// ... do work ...
e := oplog.NewEntry("command-name", statusFromErr(err), time.Since(start))
e.Args = map[string]any{"key": value}
oplog.Write(configPath, oplog.OpsFile, e)Security scans write to oplog.AuditFile instead.
If the feature meets any of these criteria, generate an E2E runbook:
Generate ai_docs/tests/<slug>_runbook.md following the existing convention:
# CLI E2E Runbook: <Title>
<One-line summary of what this validates.>
**Origin**: <version> — <why this runbook exists>
## Scope
- <bullet list of behaviors being validated>
## Environment
Run inside devcontainer with `ssenv` isolation.
## Steps
### 1. Setup: <description>
\```bash
<commands>
\```
**Expected**: <what should happen>
### 2. <Action>: <description>
...
## Pass Criteria
- All steps marked PASS
- <additional criteria>Key conventions:
bash block + Expected blockss = skillshare, ~ = ssenv-isolated HOMEcli-e2e-test skillIf the feature does not meet the criteria above, skip this step.
update-docs if the feature affects CLI flags or user-visible behaviorApply cli-development and testing. Load documentation as well when the authorized task includes user-facing documentation.
7043ca3
Also appears in
last in sync Sep 8, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.