Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions docs/superpowers/plans/2026-04-30-plan-10-e2e-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# FrinkLoop Plan 10 — End-to-End Smoke Test (Hackathon Vite+shadcn Run)

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development.

**Goal:** A single `bats` file that walks the full FrinkLoop pipeline from intake output through loop completion without running Claude. It stubs the builder/qa subagent work (file writes + commits) and exercises every helper that would fire in a real Vite+shadcn hackathon run. This is the integration gate that proves Plans 1-9 compose correctly end-to-end.

**Scope:** The test creates a temp project, initialises `.frinkloop/` state, sources all libs, runs one full loop iteration (pick → stub-build → verify → mark-done → learning event → post-iteration hook), checks that all output artifacts are correct, and confirms the stop hook exits 2 while work remains and 0 when done.

**Tech Stack:** Bash + bats-core + git (already available).

---

## File Structure

- Create: `tests/plan-10/test_e2e_smoke.bats` — the integration gate
- Create: `tests/plan-10/fixtures/vite-shadcn-tasks.json` — realistic task fixture

---

## Test coverage

The smoke tests verify end-to-end composition of all plans:

| Plan | Covered by |
|------|-----------|
| 1 — state helpers | `state_init`, `state_get`, `state_set` calls |
| 2 — loop core | `pick_next_task`, `verify_task`, `mark_task_done`, `queue_fix_task`, stop hook |
| 3 — templates | registry.yaml presence check |
| 4 — parallel | `pick_parallel_batch` presence check |
| 5 — design systems | `ds_list` presence check |
| 6 — learning | `emit_event`, `profile_init`, `profile_increment` |
| 7 — quota | `quota_hit`, `resume_time_from_reset`, `schedule_quota_resume` |
| 8 — deliverables | doc-writer and screenshot-capturer agent file presence |
| 9 — caveman | `caveman_prefix` levels |

---

*End of Plan 10.*
36 changes: 36 additions & 0 deletions docs/superpowers/plans/2026-04-30-plan-9-caveman-and-polish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# FrinkLoop Plan 9 — Caveman Integration + Plugin Polish + Acknowledgements

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development.

**Goal:** Wire the caveman token-compression directive into the actual subagent dispatch paths in `mvp-loop`, confirm the stop hook exit-code convention is documented accurately, bump `plugin.json` to v0.9.0, add acknowledgements to the plugin README, and tighten up any loose ends discovered during Plans 1-8.

**Architecture:** "Caveman" is a prompt-prefix directive that strips subagent prompts to a compact, telegraphic style. FrinkLoop already references compression in config.yaml and mentions it in SKILL.md — Plan 9 adds a concrete `caveman_prefix` helper and documents the dispatch pattern. Plugin polish: version bump, stop hook exit-code clarification, README acknowledgements.

**Tech Stack:** Bash only. No new dependencies.

---

## File Structure

- Create: `plugin/lib/caveman.sh` — `caveman_prefix` helper
- Modify: `plugin/plugin.json` — version → `0.9.0`
- Modify: `plugin/README.md` — acknowledgements section
- Modify: `plugin/skills/mvp-loop/SKILL.md` — caveman dispatch example
- Create: `tests/plan-9/test_polish.bats`

---

## Task 1: `caveman.sh` + SKILL.md update

**Files:** `plugin/lib/caveman.sh`, updated `mvp-loop` SKILL.md, `tests/plan-9/test_polish.bats`

- [ ] **Step 1: Write failing tests**
- [ ] **Step 2: Implement caveman.sh**
- [ ] **Step 3: Update SKILL.md with concrete dispatch example**
- [ ] **Step 4: Bump plugin.json + README acknowledgements**
- [ ] **Step 5: Run tests, expect PASS**
- [ ] **Step 6: Commit**

---

*End of Plan 9.*
53 changes: 53 additions & 0 deletions plugin/lib/caveman.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
# FrinkLoop caveman compression helper.
# Provides caveman_prefix() — prepends a telegraphic compression directive to
# subagent prompts when config.yaml has compression: lite | full | ultra.
# Caller sources this file and calls caveman_prefix "$compression_level" "$prompt".

set -euo pipefail

# caveman_prefix <level> <prompt>
# Prints the prompt with a compression preamble prepended.
# level: lite | full | ultra | none | ""
# Returns the prompt unchanged if level is "none" or empty.
caveman_prefix() {
local level="${1:-none}"
local prompt="$2"

case "$level" in
none|"")
printf '%s' "$prompt"
;;
lite)
printf '%s\n\n%s' \
"COMPRESS: respond in terse prose. No filler. Short sentences." \
"$prompt"
;;
full)
printf '%s\n\n%s' \
"CAVEMAN MODE: speak like caveman. short words. no fluff. grunt-level terse. get job done." \
"$prompt"
;;
ultra)
printf '%s\n\n%s' \
"ULTRA CAVEMAN: 1-3 word answers only. abbreviate everything. no punctuation beyond period. act not explain." \
"$prompt"
;;
*)
printf '%s' "$prompt"
;;
esac
}

# read_compression_level [config_yaml_path]
# Reads the compression level from config.yaml. Returns "none" if unset.
read_compression_level() {
local config_path="${1:-${FRINKLOOP_DIR:-}/config.yaml}"
if [ ! -f "$config_path" ]; then
echo "none"
return 0
fi
local level
level=$(yq -r '.compression // "none"' "$config_path" 2>/dev/null || echo "none")
echo "${level:-none}"
}
2 changes: 1 addition & 1 deletion plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frinkloop",
"version": "0.1.0",
"version": "0.9.0",
"description": "Autonomous MVP development for Claude Code: intake → scaffold → build → verify → deliver. Token-friendly, parallel, learns locally.",
"author": "Fernando Leyra",
"license": "MIT",
Expand Down
14 changes: 13 additions & 1 deletion plugin/skills/mvp-loop/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,22 @@ Read `config.yaml` at start. If `tdd: true` (commercial mode default), every `ki

If `config.yaml` has `hitl: milestones`, after each milestone is marked done, set `status=paused` and emit a one-line summary. The Stop hook will exit. The user runs `/frinkloop resume <project>` to continue.

## Compression
## Compression (Plan 9)

Read `config.yaml`. If `compression ∈ {lite, full, ultra}`, prepend a caveman directive to subagent prompts when dispatching. Loop narration itself stays uncompressed.

```bash
source plugin/lib/caveman.sh
compression=$(read_compression_level)
builder_prompt=$(caveman_prefix "$compression" "$raw_builder_prompt")
# Then dispatch the builder subagent with builder_prompt
```

The three levels:
- `lite` — terse prose, no filler
- `full` — caveman-style telegraphic
- `ultra` — 1-3 word answers, abbreviate everything

## Parallel fan-out (Plan 4)

When `pick_parallel_batch 10` returns ≥2 task ids, the loop dispatches multiple builder subagents simultaneously via the Task tool, capped at 10 per Claude Code limit.
Expand Down
34 changes: 34 additions & 0 deletions tests/plan-10/fixtures/vite-shadcn-tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"schema_version": 1,
"milestones": [
{
"id": "m1",
"title": "Scaffold",
"status": "in-progress",
"tasks": [
{"id": "T01", "title": "Bootstrap Vite+shadcn project", "status": "done", "kind": "scaffold"},
{"id": "T02", "title": "Apply tailwind recipe", "status": "pending", "kind": "scaffold"},
{"id": "T03", "title": "Write project README", "status": "pending", "kind": "doc", "depends_on": ["T02"]}
]
},
{
"id": "m2",
"title": "Core flow",
"status": "pending",
"tasks": [
{"id": "T04", "title": "Add todo list component", "status": "pending", "kind": "feature"},
{"id": "T05", "title": "Add todo add/remove tests", "status": "pending", "kind": "test", "depends_on": ["T04"]},
{"id": "T06", "title": "Write component JSDoc", "status": "pending", "kind": "doc", "depends_on": ["T05"]}
]
},
{
"id": "m3",
"title": "Deliver",
"status": "pending",
"tasks": [
{"id": "T07", "title": "Deploy to Vercel", "status": "pending", "kind": "deploy"},
{"id": "T08", "title": "Capture screenshots", "status": "pending", "kind": "screenshot", "depends_on": ["T07"]}
]
}
]
}
Loading