paircode 0.13.2__tar.gz → 0.14.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {paircode-0.13.2 → paircode-0.14.0}/PKG-INFO +1 -1
- {paircode-0.13.2 → paircode-0.14.0}/pyproject.toml +1 -1
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/__init__.py +1 -1
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/detect.py +5 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/installer.py +28 -0
- paircode-0.14.0/src/paircode/templates/pi/prompts/paircode.md +95 -0
- {paircode-0.13.2 → paircode-0.14.0}/.gitignore +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/LICENSE +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/README.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/diary/001-step-a-architecture.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/diary/002-v0.10-release-pipeline.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/diary/003-arch-b-pivot-grappling.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/diary/004-gemini-silent-flash-downgrade.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/__main__.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/cli.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/converge.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/handshake.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/peerlab.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/runner.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/state.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/templates/FOCUS.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/templates/JOURNEY.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/templates/claude/commands/paircode.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/templates/claude/commands/peerlab.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/templates/codex/commands/paircode.md +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/templates/gemini/commands/paircode.toml +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/templates/peers.yaml +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/src/paircode/util.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/tests/__init__.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/tests/test_cli_smoke.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/tests/test_converge.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/tests/test_handshake.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/tests/test_peerlab.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/tests/test_smoke.py +0 -0
- {paircode-0.13.2 → paircode-0.14.0}/tests/test_state.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: paircode
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14.0
|
|
4
4
|
Summary: Adversarial journey framework — orchestrate multiple LLM peers through research, plan, and execute stages with file-trace peer review.
|
|
5
5
|
Project-URL: Homepage, https://github.com/starshipagentic/paircode
|
|
6
6
|
Project-URL: Repository, https://github.com/starshipagentic/paircode
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "paircode"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.14.0"
|
|
8
8
|
description = "Adversarial journey framework — orchestrate multiple LLM peers through research, plan, and execute stages with file-trace peer review."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -33,6 +33,11 @@ KNOWN_CLIS: dict[str, tuple[str, Path, str]] = {
|
|
|
33
33
|
Path.home() / ".gemini",
|
|
34
34
|
"Install Gemini CLI: `npm i -g @google/gemini-cli`",
|
|
35
35
|
),
|
|
36
|
+
"pi": (
|
|
37
|
+
"pi",
|
|
38
|
+
Path.home() / ".pi",
|
|
39
|
+
"Install Pi coding agent: `npm i -g @earendil-works/pi-coding-agent`",
|
|
40
|
+
),
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Strategy per CLI:
|
|
4
4
|
- Claude Code: file-drop ~/.claude/commands/paircode.md
|
|
5
|
+
- Pi: file-drop ~/.pi/agent/prompts/paircode.md ($@ args, bash-parallel peers)
|
|
5
6
|
Claude's native plugin-install requires publishing a marketplace;
|
|
6
7
|
overkill for one command. File-drop is first-class + documented.
|
|
7
8
|
- Codex CLI: native register via `codex marketplace add starshipagentic/paircode-codex`
|
|
@@ -80,6 +81,31 @@ def install_claude(info: CliInfo) -> InstallResult:
|
|
|
80
81
|
)
|
|
81
82
|
|
|
82
83
|
|
|
84
|
+
def install_pi(info: CliInfo) -> InstallResult:
|
|
85
|
+
"""Write ~/.pi/agent/prompts/paircode.md — file-drop (native for Pi coding agent).
|
|
86
|
+
|
|
87
|
+
Pi discovers prompt templates in ~/.pi/agent/prompts/ as /name slash commands.
|
|
88
|
+
The pi variant of the template uses `$@` for arguments (Pi's convention) and
|
|
89
|
+
fires peers as parallel background bash jobs (Pi has no stock Agent tool).
|
|
90
|
+
"""
|
|
91
|
+
if not info.installed:
|
|
92
|
+
return InstallResult(
|
|
93
|
+
cli_name="pi", action="skipped", path=None,
|
|
94
|
+
message=f"pi CLI not on PATH. {info.install_hint}",
|
|
95
|
+
)
|
|
96
|
+
prompts_dir = info.config_dir / "agent" / "prompts"
|
|
97
|
+
prompts_dir.mkdir(parents=True, exist_ok=True)
|
|
98
|
+
target = prompts_dir / "paircode.md"
|
|
99
|
+
target.write_text(
|
|
100
|
+
_read_template("pi/prompts/paircode.md"),
|
|
101
|
+
encoding="utf-8",
|
|
102
|
+
)
|
|
103
|
+
return InstallResult(
|
|
104
|
+
cli_name="pi", action="installed", path=target,
|
|
105
|
+
message=f"Wrote /paircode prompt template to {prompts_dir}.",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
83
109
|
def _codex_already_installed() -> bool:
|
|
84
110
|
"""Idempotency check: is the paircode marketplace already registered?"""
|
|
85
111
|
config = Path.home() / ".codex" / "config.toml"
|
|
@@ -181,6 +207,7 @@ def install_all() -> list[InstallResult]:
|
|
|
181
207
|
"claude": install_claude,
|
|
182
208
|
"codex": install_codex,
|
|
183
209
|
"gemini": install_gemini,
|
|
210
|
+
"pi": install_pi,
|
|
184
211
|
}
|
|
185
212
|
results: list[InstallResult] = []
|
|
186
213
|
for name, info in detected.items():
|
|
@@ -227,6 +254,7 @@ def uninstall_all() -> list[InstallResult]:
|
|
|
227
254
|
claude_paths = [
|
|
228
255
|
claude_home / "commands" / "paircode.md",
|
|
229
256
|
claude_home / "commands" / "peerlab.md",
|
|
257
|
+
Path.home() / ".pi" / "agent" / "prompts" / "paircode.md",
|
|
230
258
|
claude_home / "agents" / "paircode-peer.md",
|
|
231
259
|
]
|
|
232
260
|
removed = []
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "paircode — adversarial multi-LLM peer review. Fire peers in parallel, synthesize, write consensus to .paircode/. Usage: /paircode \"<prompt>\" [--peer id | --peers id,id]"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are the **team lead** for a paircode peer-review cycle, running inside a pi session
|
|
6
|
+
(alpha = you, whatever model this pi session runs). Your job: get the user a genuinely
|
|
7
|
+
adversarial second opinion by firing every peer LLM in parallel, reading what they wrote,
|
|
8
|
+
and synthesizing an honest consensus. All thoughts land on disk as Markdown under `.paircode/`.
|
|
9
|
+
|
|
10
|
+
**$@** is the full user input after `/paircode`: a quoted prompt, optionally `--peer <id>`
|
|
11
|
+
or `--peers <id,id>` filter flags.
|
|
12
|
+
|
|
13
|
+
## File naming (inside every $FOCUS/{stage}/)
|
|
14
|
+
- `alpha-vN.md` — your successive takes · `{peer-id}-vN.md` — each peer's takes
|
|
15
|
+
- `reviews/round-N-{peer-id}-critiques-alpha.md` — peer critiques of alpha
|
|
16
|
+
- `*-FINAL.md` (via `paircode converge {stage}`) · `consensus.md` — your synthesis (last write)
|
|
17
|
+
|
|
18
|
+
**Reports vs code:** files in `$FOCUS/{stage}/` are always markdown reports. Code lives in
|
|
19
|
+
sandboxes: peers in `.paircode/sandbox/{peer-id}/`, alpha (you) directly in the project root.
|
|
20
|
+
Sandboxes are always available, never required — code only when it materially sharpens an answer.
|
|
21
|
+
|
|
22
|
+
## Step 1 — Bootstrap (silent, via bash)
|
|
23
|
+
```bash
|
|
24
|
+
paircode ensure-scaffold
|
|
25
|
+
FOCUS=$(paircode focus new "<slug-from-prompt>" --prompt "<the quoted prompt verbatim>")
|
|
26
|
+
PEERS=$(paircode roster --alpha pi <user's --peer/--peers flags if any>)
|
|
27
|
+
```
|
|
28
|
+
Trust the roster. $FOCUS has research/ plan/ execute/ ask/ subdirs ready (each with reviews/).
|
|
29
|
+
**Bootstrap discipline:** run `paircode focus new` EXACTLY ONCE and capture its stdout into $FOCUS. If you lose the value, do NOT re-run it — recover with `FOCUS=$(ls -td .paircode/focus-* | head -1)`. Strip `--peer`/`--peers` flags OUT of the text before passing the quoted prompt to `--prompt` (flags go to `paircode roster`, never into FOCUS.md).
|
|
30
|
+
|
|
31
|
+
## Step 2 — Pick the flow (commit to the WHOLE flow)
|
|
32
|
+
| Flow | Trigger |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `ask` | "what do you think", "review/critique X", "second opinion" |
|
|
35
|
+
| `research` | "figure out", "explore", "how should we" |
|
|
36
|
+
| `research → plan` | "plan/design/lay out X" |
|
|
37
|
+
| `research → plan → execute` | "build/fix/implement/ship/do" — most imperatives. **Default when ambiguous.** |
|
|
38
|
+
| `execute` | "execute the plan at focus-NN" |
|
|
39
|
+
|
|
40
|
+
Append `flow: <flow>` to `$FOCUS/FOCUS.md`. {stage} = first stage of {flow}.
|
|
41
|
+
|
|
42
|
+
## Step 3 — Fire peers in PARALLEL (background bash, one job per peer)
|
|
43
|
+
Construct a stage-appropriate peer prompt (see shapes below), then launch ALL peers at once:
|
|
44
|
+
```bash
|
|
45
|
+
for P in $PEERS; do
|
|
46
|
+
nohup paircode invoke "$P" "<stage-appropriate prompt>" --out "$FOCUS/{stage}/$P-v1.md" \
|
|
47
|
+
> "$FOCUS/{stage}/$P-invoke.log" 2>&1 &
|
|
48
|
+
done
|
|
49
|
+
wait # blocks until every peer returns
|
|
50
|
+
```
|
|
51
|
+
Stage prompt shapes:
|
|
52
|
+
- **research**: honest, skeptical, specific cold take on the prompt; sandbox scripts welcome to ground claims in real data; clean markdown, no preamble.
|
|
53
|
+
- **plan**: concrete numbered plan (goal, scope, steps, risks, success criteria), KISS; read `../research/*-FINAL.md` if present.
|
|
54
|
+
- **execute**: carry out `$FOCUS/plan/*-FINAL.md`; code/tests in your sandbox `.paircode/sandbox/{peer-id}/` only; report = what you built/ran, files, verification, open items.
|
|
55
|
+
- **ask**: severity-ranked critique with file:line citations of the artifact FOCUS.md points to.
|
|
56
|
+
|
|
57
|
+
## Step 4 — Alpha's own take (while peers run, before `wait` if you can)
|
|
58
|
+
Write `$FOCUS/{stage}/alpha-v1.md` yourself — same stage rules. Your edge: this session's full
|
|
59
|
+
context. Execute-stage asymmetry: peers code in sandboxes; you code directly in the project root
|
|
60
|
+
(alpha-vN.md is the report; code lives in the repo).
|
|
61
|
+
|
|
62
|
+
## Step 5 — Read everything
|
|
63
|
+
After `wait`: read every `{peer-id}-v1.md` + your alpha file. Where did peers agree, clash,
|
|
64
|
+
surface what you missed? Spot-check 1-2 cited claims against the actual repo.
|
|
65
|
+
|
|
66
|
+
## Step 6 — Round convergence
|
|
67
|
+
Quick one-shot prompt answered well in round 1 → converge. **Otherwise default to another
|
|
68
|
+
round**: peers critique alpha (`reviews/round-N-{peer-id}-critiques-alpha.md` via the same
|
|
69
|
+
parallel-invoke pattern), you write `alpha-v(N+1).md`, loop to Step 5. Stop when a round adds
|
|
70
|
+
no new friction. No hard cap; use judgment.
|
|
71
|
+
|
|
72
|
+
## Step 7 — Converge stage + consensus
|
|
73
|
+
```bash
|
|
74
|
+
paircode converge {stage}
|
|
75
|
+
```
|
|
76
|
+
Read every `*-FINAL.md`, then WRITE `$FOCUS/{stage}/consensus.md`:
|
|
77
|
+
`# Consensus — {focus} — {stage}` with sections: **Where peers agreed / Where peers clashed /
|
|
78
|
+
Team-lead verdict (2-3 honest paragraphs) / Next action (one concrete thing)**.
|
|
79
|
+
Adversarial-but-honest. No pile-on, no rubber-stamping.
|
|
80
|
+
|
|
81
|
+
## Step 8 — Advance the flow (mechanical — do NOT ask permission)
|
|
82
|
+
{stage} = next stage in {flow}; jump to Step 3 (skip Steps 1-2). Previous stage's `*-FINAL.md`
|
|
83
|
+
feed the next stage's prompts. The user's prompt was implicit go-ahead for the WHOLE flow;
|
|
84
|
+
stop early only on a hard blocker, and say so in the final report. Last stage done → Step 9.
|
|
85
|
+
|
|
86
|
+
## Step 9 — Final report (under 200 words)
|
|
87
|
+
Focus path · stages+rounds run (e.g. `research (2) → plan (1) → execute (1)`) · peers that
|
|
88
|
+
participated/failed · one-sentence headline from the last consensus.md.
|
|
89
|
+
|
|
90
|
+
## Guardrails
|
|
91
|
+
- Never skip Step 1; never invent peer commands — always `paircode invoke <id> "..." --out <path>`.
|
|
92
|
+
- Fire EVERY rostered peer unless the user passed `--peer`/`--peers`.
|
|
93
|
+
- Peers never touch files outside their sandbox; you never touch theirs.
|
|
94
|
+
- If a peer invoke hard-fails, note it and continue with the rest — one dead peer never blocks the cycle.
|
|
95
|
+
- No AI attribution in any artifact you write.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|