Compare commits

...

3 Commits

Author SHA1 Message Date
张宗平 2ff4de8c2e docs: add MIT LICENSE, AGENTS.md for development conventions, update README license section 2026-06-10 21:43:16 +08:00
张宗平 2bba75808a docs: add README with installation and usage instructions 2026-06-10 21:39:42 +08:00
张宗平 979e652f46 add missing skills 2026-06-10 21:35:52 +08:00
5 changed files with 424 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
# AGENTS.md
Project conventions for agent-assisted development.
## Project Overview
This repository provides Pi coding agent skills and extensions. The primary component is **goal-driven-loop** — a skill + extension pair that keeps a session focused on a user-defined goal with explicit acceptance criteria.
## Repository Structure
```
extensions/goal-driven-loop/ # TypeScript extension (Pi Extension API)
.agents/skills/goal-driven-loop/ # Skill instructions (Markdown)
.pi/skills/ → symlink # Pi skill discovery
.pi/extensions/ → symlink # Pi extension discovery
docs/superpowers/ # Design specs and implementation plans
openspec/ # OpenSpec change archive
```
Agent directories (`.claude/`, `.agents/`, `.pi/`) are **gitignored**. Only the symlinks and source files at top-level directories are committed.
## Tech Stack
- **Skills**: Markdown (Agent Skills standard), no build step
- **Extensions**: TypeScript, loaded via jiti (no compilation needed), depends on `@earendil-works/pi-coding-agent` Extension API
- **Testing**: Manual behavioral tests via `pi -p` / `pi -e`; unit tests run with `npx jiti` against individual modules
- **Workflow**: OpenSpec → comet lifecycle for change tracking
## Development Commands
```bash
# Verify skill loads
pi -p "/skill:goal-driven-loop"
# Verify extension loads
pi -e extensions/goal-driven-loop/index.ts -p "test"
# Run unit tests for trigger-detector
npx jiti /tmp/test-trigger-detector.mjs
# Run unit tests for state-injector
npx jiti /tmp/test-state-injector.mjs
# End-to-end test (create a temp project first)
mkdir -p /tmp/test && cd /tmp/test && git init
pi -e /path/to/pi-setup/extensions/goal-driven-loop/index.ts \
-p "当前目标是实现 reverseString(s) 函数"
```
## Key Design Decisions
1. **Skill + Extension dual layer**: Skill = instructions (agent reads). Extension = mechanics (event handlers). Do not mix concerns.
2. **File-based state** (`.agents/goal/GOAL.md`): Survives context compaction. Deleted on goal completion.
3. **Extension never blocks user**: All confirms use timed auto-defaults (10s timeout). Fallbacks are safe (continue existing goal).
4. **Anti-triggers are mechanical**: Code blocks, quote blocks, reported speech, trivial keywords — all checked programmatically, not by agent judgment.
5. **Per-iteration retry**: Exponential backoff counter resets each iteration. 10 retries / ~37min coverage.
6. **Comet delegation**: Coarse-grained goals auto-delegate to `comet-open`. Fallback to multi-stage mode if comet unavailable.
## When Modifying This Project
### Adding a new skill
1. Create directory at `.agents/skills/<name>/SKILL.md`
2. Follow the Agent Skills standard: YAML frontmatter with `name` and `description` (start with "Use when...")
3. Keep SKILL.md ≤ 500 words; move detailed reference to `references/` subdirectory
4. Create symlink: `ln -s ../../.agents/skills/<name> .pi/skills/<name>`
5. Test with `pi -p "/skill:<name>"`
### Adding a new extension
1. Create directory at `extensions/<name>/`
2. Write `index.ts` that exports a default function receiving `ExtensionAPI`
3. Add `package.json` with `{ "pi": { "extensions": ["./index.ts"] } }`
4. Create symlink: `ln -s ../../extensions/<name> .pi/extensions/<name>`
5. Test with `pi -e extensions/<name>/index.ts -p "test"`
### Modifying goal-driven-loop
- **Skill layer** (`.agents/skills/goal-driven-loop/`): Changes to instructions, acceptance criteria rules, error handling reference
- **Extension layer** (`extensions/goal-driven-loop/`):
- `trigger-detector.ts` — trigger phrase patterns and anti-trigger logic
- `state-injector.ts` — GOAL.md parsing and injection text generation
- `ui-prompts.ts` — timed confirms and notification helpers
- `index.ts` — event wiring (input, before_agent_start)
After any change, re-run unit tests and E2E verification.
## Commit Conventions
- `feat(skill):` / `feat(ext):` — new features
- `fix(skill):` / `fix(ext):` — bug fixes
- `docs:` — documentation changes
- `chore:` — maintenance (gitignore, archive, etc.)
## Known Limitations (v1)
1. Mid-loop granularity upgrade needs skill-side signal (`status: needs-upgrade` in GOAL.md) — extension cannot auto-detect goal complexity increase
2. Agent "estimates < 5 min" anti-trigger is instruction-level only, not mechanical
3. Stagnation dual-signal precise detection needs skill-side passing count history in GOAL.md — extension relies on skill's own stagnation detection
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Charles
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+170
View File
@@ -0,0 +1,170 @@
# pi-setup
Pi coding agent (https://github.com/badlogic/pi-mono) — skills, extensions, and configuration for goal-driven development workflows.
## What This Repository Provides
| Component | Path | Purpose |
|-----------|------|---------|
| **Skill: `goal-driven-loop`** | `.agents/skills/goal-driven-loop/` | Keeps a session focused on a user-defined goal with explicit acceptance criteria. Iterates until all criteria pass or stagnation is detected. |
| **Extension: `goal-driven-loop`** | `extensions/goal-driven-loop/` | TypeScript extension that automates trigger detection, state injection on every agent turn, context tension detection, and timed auto-default confirms. |
| **Symlinks for Pi discovery** | `.pi/skills/`, `.pi/extensions/` | Pi-specific discovery points — point to the real source files in `.agents/skills/` and `extensions/`. |
| **Spec & plan** | `docs/superpowers/` | Design spec and implementation plan that produced the skill + extension. |
| **Comet archive** | `openspec/changes/archive/` | Formal change record from the OpenSpec lifecycle. |
The skill and extension work as a pair. The skill is the instruction layer (what the agent reads). The extension is the automation layer (mechanical trigger detection, state injection, timed confirms).
## Repository Layout
```
pi-setup/
├── .gitignore # ignores .claude/, .agents/, .pi/
├── extensions/
│ └── goal-driven-loop/ # Extension source (git-tracked)
│ ├── index.ts # Event wiring
│ ├── trigger-detector.ts # Phrase matching + anti-triggers
│ ├── state-injector.ts # GOAL.md parsing + injection
│ ├── ui-prompts.ts # Timed auto-defaults
│ └── package.json
├── docs/
│ └── superpowers/
│ ├── specs/2026-06-10-goal-driven-loop-design.md
│ └── plans/2026-06-10-goal-driven-loop.md
├── openspec/
│ └── changes/archive/2026-06-10-goal-driven-loop/
├── .agents/skills/ # (gitignored) Skill source
│ └── goal-driven-loop/
│ ├── SKILL.md
│ └── references/error-handling.md
├── .pi/ # (gitignored) Pi discovery symlinks
│ ├── skills/goal-driven-loop → ../../.agents/skills/goal-driven-loop
│ └── extensions/goal-driven-loop → ../../extensions/goal-driven-loop
└── .claude/ # (gitignored) Claude Code state
```
## Installation
The skill and extension source are committed at the top level. The agent-specific directories (`.agents/`, `.pi/`, `.claude/`) are gitignored and only hold symlinks/discovery points on the local machine.
### Option 1: Clone and use locally
```bash
git clone <repo-url> pi-setup
cd pi-setup
# Create symlinks so Pi can discover the skill and extension
mkdir -p .agents/skills
ln -s ../extensions/../.agents/skills/goal-driven-loop .agents/skills/goal-driven-loop
mkdir -p .pi/skills .pi/extensions
ln -s ../../.agents/skills/goal-driven-loop .pi/skills/goal-driven-loop
ln -s ../../extensions/goal-driven-loop .pi/extensions/goal-driven-loop
```
Or use the project's `.pi` settings to point at the source directly (see Option 3).
### Option 2: Install into another project (as a Git submodule)
```bash
cd your-project
git submodule add <repo-url> vendor/pi-setup
```
Then add to your project's `.pi/settings.json`:
```json
{
"skills": ["vendor/pi-setup/.agents/skills"],
"extensions": ["vendor/pi-setup/extensions/goal-driven-loop"]
}
```
### Option 3: Configure Pi to discover via settings (no copy)
In `.pi/settings.json` (project) or `~/.pi/agent/settings.json` (user):
```json
{
"skills": ["/path/to/pi-setup/.agents/skills"],
"extensions": ["/path/to/pi-setup/extensions/goal-driven-loop"]
}
```
Pi loads skills from any directory in this list, so the source files at the top level are used directly — no symlinks required.
## Verifying Installation
```bash
# 1. Skill loads
pi -p "/skill:goal-driven-loop"
# → "Goal-Driven Loop is active. Awaiting your goal statement."
# 2. Extension loads
pi -e extensions/goal-driven-loop/index.ts -p "test"
# → no errors, normal output
# 3. End-to-end trigger
mkdir -p /tmp/test && cd /tmp/test && git init
pi -e /path/to/pi-setup/extensions/goal-driven-loop/index.ts \
-p "当前目标是实现 reverseString(s) 函数"
# → Goal-driven loop activates, implements, tests, completes
```
## Usage
Set a goal with a trigger phrase (Chinese, English, or other language with similar meaning):
```
设定当前目标为给 auth 模块加 rate limiting
当前目标是实现 camelCase 函数
my goal is to add caching, acceptance: hit rate > 80%
```
The skill auto-generates verifiable acceptance criteria if you don't provide them, persists state to `.agents/goal/GOAL.md`, and iterates until all criteria pass.
To abandon a goal:
```
放弃
不要了
cancel
```
To override auto-defaults within the timed window, just type your choice. After 10 seconds, the system defaults to "continue" on stale state prompts.
## Trigger Reference
| Language | Patterns |
|----------|----------|
| Chinese | 设定当前目标为 / 当前目标是 / 把当前目标设为 / 我的目标是 |
| English | set current goal to / current goal is / my goal is / the goal is |
| Other | semantically equivalent phrasings |
The skill does **not** activate when the phrase is inside a quote block, code block, or reported speech; when the message contains trivial-task keywords (hotfix, tweak, quick fix, 修个bug, 小改); or when the goal is ≤ 10 characters without architectural keywords.
## Architecture
```
User: "设定当前目标为 X"
[Extension: input event] detectTrigger(X) → validates against anti-triggers
[Extension: before_agent_start] reads .agents/goal/GOAL.md, injects state
[Skill: SKILL.md] instructs agent on iteration steps
[Agent] implements, verifies, updates GOAL.md
[Extension: before_agent_start] on next turn re-injects updated state
[Skill: completion] deslop pass + cleanup + output summary
```
State is file-based — `.agents/goal/GOAL.md` — so it survives context compaction. The extension re-injects the goal state on every agent turn.
## Error Handling
The skill handles transient failures with exponential backoff (10 retries, ~37min total coverage). Stagnation uses dual-signal detection (criteria count + progress keywords) with auto-recovery injection before user notification. See `docs/superpowers/specs/2026-06-10-goal-driven-loop-design.md` for the full design.
## License
MIT — see [LICENSE](LICENSE).
+59
View File
@@ -0,0 +1,59 @@
---
name: goal-driven-loop
description: Use when the user sets a current goal with phrases like "设定当前目标为", "当前目标是", "current goal is", or "my goal is", and the task is not a trivial fix, hotfix, tweak, or quoted text
---
# Goal-Driven Loop
Keep the current session focused on a user-defined goal with explicit acceptance criteria. Iterate until all criteria pass, or genuine stagnation is detected.
## When to Activate
**Trigger phrases (any language, semantic variants):**
- Chinese: 设定当前目标为 / 当前目标是 / 把当前目标设为 / 我的目标是
- English: set current goal to / current goal is / my goal is / the goal is
- Other: semantically equivalent phrasings + concrete deliverable
**Do NOT activate when:**
- Trigger phrase inside markdown quote (`>`) or code block, or same sentence as reported speech (he said / 他说)
- Message contains trivial-task keywords: hotfix, tweak, quick fix, 修个bug, 小改
- Goal description ≤ 10 chars without architectural keywords, or agent estimates < 5 min without architectural keywords
- `.agents/goal/GOAL.md` exists → extension prompts: continue / replace / abandon (10s timeout → continue)
**Granularity:** Coarse (file count > 5, multi-module, architectural) → extension invokes `comet-open`. Fine (single concern, ≤ 5 files) → this skill. Fallback: if comet unavailable, auto-split into phases.
## Core Loop
1. **Initialize** — If `GOAL.md` exists, extension prompts with timed default. If no criteria provided, auto-generate (verifiability red line). Write `GOAL.md`.
2. **Execute** — Read `GOAL.md`, pick next unpassed criterion (least dependent), implement, verify, record in Progress Log.
3. **Verify** — Check each criterion against fresh evidence. Update checkboxes, iteration counter, timestamp.
4. **Loop** — All ✅ → exit. Stagnation → extension auto-injects strategy change (2x before user notification). Otherwise → step 2.
5. **Exit** — Deslop pass on modified files (failure doesn't block). Delete `GOAL.md`. Output summary.
## Acceptance Criteria Verifiability
Auto-generated criteria must be verifiable. Examples:
- ❌ "Implement rate limiting" → not verifiable
- ✅ "Rate limiter middleware mounts on auth routes, excess requests return 429" → verifiable
- ❌ "Code quality is good" → not verifiable
- ✅ "Related files lint clean, typecheck passes" → verifiable
Agent cannot unilaterally delete or skip criteria. Material modifications require logged reason; safe adjustments (typos, splitting compounds) may be auto-applied.
## Goal State File
Path: `.agents/goal/GOAL.md` — frontmatter with `goal`, `created`, `updated`, `iteration`, `status` (in-progress | blocked | complete). Body has Acceptance Criteria (checkboxes), Progress Log (per-iteration), Blocked section.
## Error Handling
See `references/error-handling.md` for retry strategy, exception classification, stagnation rules, and red flags.
**Context tension:** Extension detects via `ctx.getContextUsage() > 0.8`. Auto-injects "save progress now" directive into next turn.
**Mid-loop granularity upgrade:** If execution reveals the goal is more complex than estimated, extension auto-invokes `comet-open` with `GOAL.md` state. User is informed via UI notification, not asked for confirmation.
**Explicit abandon:** User says "abandon / cancel / 不要了" → extension deletes `GOAL.md`, outputs brief summary, terminates.
@@ -0,0 +1,75 @@
# Error Handling Reference
Detailed retry strategy, exception classification, and recovery rules for the `goal-driven-loop` skill.
## Retry Strategy (Automatic, No Human Intervention)
All recoverable exceptions use exponential backoff. Counter is **per-iteration** — resets at the start of each new iteration.
| Parameter | Value |
|-----------|-------|
| Max retries | 10 per iteration |
| Initial delay | 30s |
| Backoff factor | ×2 |
| Max delay | 300s (5min) |
**Backoff sequence:**
| Retry | Delay | Cumulative |
|-------|-------|------------|
| 1 | 30s | 0.5min |
| 2 | 60s | 1.5min |
| 3 | 120s | 3.5min |
| 4 | 240s | 7.5min |
| 5 | 300s | 12.5min |
| 6 | 300s | 17.5min |
| 7 | 300s | 22.5min |
| 8 | 300s | 27.5min |
| 9 | 300s | 32.5min |
| 10 | 300s | 37.5min |
**Formula:** `delay = min(30 * 2^(retry-1), 300)` seconds.
**Execution:** Before retry, run `bash -c "sleep <delay> && echo done"` with `timeout` parameter set to `delay + 30`. If sleep is interrupted, treat as tool failure, enter retry.
**After 10 retries exhausted:** `status = blocked`, write Blocked section to `GOAL.md`, extension auto-attempts alternative approach. If still blocked after auto-attempt, then notify user.
## Exception Classification
| Exception | Detection signal | Recoverable? | Response |
|-----------|------------------|--------------|----------|
| Tool execution failure | bash returns non-zero exit | Yes | Exponential backoff retry |
| LLM API exception | subagent timeout/error | Yes | Exponential backoff retry |
| Context tension | Extension detects `getContextUsage() > 0.8` | No | Extension auto-saves state, injects continuation directive |
| User interruption | User sends new message mid-loop | No | Extension auto-pauses, responds, resumes on next trigger |
| Stale state | `GOAL.md` exists with `status = in-progress` | No | Extension prompts: continue / replace / abandon (10s timeout → continue) |
## Stagnation Detection
Both signals must be present:
1. Acceptance criteria passing count unchanged for 3 consecutive iterations, AND
2. Progress Log last 3 iterations contain no progress keywords (found / fixed / implemented / added / refactored / verified)
Only both conditions together trigger stagnation. Extension auto-injects strategy-change prompt. After 2 consecutive auto-recoveries with no progress, extension notifies user.
## Continuation Prompt Format (Fixed)
When context is tight, output exactly this format:
```
🔄 目标状态已保存至 .agents/goal/GOAL.md
当前进度:X/Y criteria 通过,第 N 轮迭代。
```
The extension injects the full state summary on every `before_agent_start`, so the next prompt automatically re-loads the goal.
## Red Flags — These Do NOT Count as Completion
- "LLM call failed, goal should be considered complete" → retry or blocked
- "Tests don't run but code looks fine" → must have test evidence
- "Context full, let me summarize" → save state, extension auto-injects continuation, do not declare done
- "Too many retries, skip this criterion" → exhausted retries → blocked, do not skip
- "This criterion is too hard to verify, skip it" → agent may auto-rewrite, logged as material change
- "All criteria basically met, close enough" → each criterion must have explicit pass evidence
- "Deslop pass would take too long, skip" → deslop failure does not block, but agent should still attempt it