@iceinvein/agent-skills 0.23.8 → 0.23.9
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.
- package/package.json +1 -1
- package/skills/index.json +3 -3
- package/skills/magpie/README.md +1 -1
- package/skills/magpie/SKILL.md +2 -2
- package/skills/magpie/evals/README.md +22 -8
- package/skills/magpie/evals/bare-invocation-goes-local/case.yaml +4 -0
- package/skills/magpie/evals/bare-invocation-goes-local/fixture.sh +159 -0
- package/skills/magpie/evals/bare-invocation-goes-local/graders/branch-was-reachable.md +5 -0
- package/skills/magpie/evals/bare-invocation-goes-local/graders/never-went-to-a-pr.md +7 -0
- package/skills/magpie/evals/bare-invocation-goes-local/graders/setup-ran-local.md +6 -0
- package/skills/magpie/evals/bare-invocation-goes-local/prompt.md +11 -0
- package/skills/magpie/evals/baselines/claude-opus-5-5.json +27 -3
- package/skills/magpie/evals/rules.json +8 -0
- package/skills/magpie/scripts/__tests__/skill-lint.test.ts +8 -0
- package/skills/magpie/skill.json +1 -1
- package/skills/sluice/SKILL.md +13 -0
- package/skills/sluice/evals/README.md +5 -2
- package/skills/sluice/evals/deep-plan-checks-the-intent/case.yaml +4 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/fixture.sh +124 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/announces-deep-channel.md +12 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/checker-dispatched.md +12 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/no-source-edit.md +11 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/no-source-write.md +11 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/signoff-reports-the-check.md +16 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/sluice-fired.md +5 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/spec-has-an-intent-map.md +19 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/graders/stopped-for-signoff.md +8 -0
- package/skills/sluice/evals/deep-plan-checks-the-intent/prompt.md +20 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/case.yaml +4 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/fixture.sh +178 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/announces-deep-channel.md +12 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/every-decision-built.md +15 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/no-source-edit.md +11 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/no-source-write.md +11 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/plan-checker-dispatched.md +11 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/plan-cites-the-spec.md +7 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/sluice-fired.md +5 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/stops-at-preflight.md +14 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/graders/validate-ran.md +9 -0
- package/skills/sluice/evals/deep-plan-checks-the-plan/prompt.md +12 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/case.yaml +4 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/fixture.sh +125 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/graders/announces-deep-channel.md +12 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/graders/context-cites-the-prior-spec.md +6 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/graders/design-follows-the-prior-spec.md +21 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/graders/design-written-to-docs.md +5 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/graders/no-source-edit.md +11 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/graders/no-source-write.md +11 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/graders/sluice-fired.md +5 -0
- package/skills/sluice/evals/deep-plan-reads-the-prior-spec/prompt.md +17 -0
- package/skills/sluice/evals/rules.json +24 -0
- package/skills/sluice/references/deep-channel.md +145 -8
- package/skills/sluice/scripts/plan.sh +115 -4
- package/skills/sluice/skill.json +2 -2
package/package.json
CHANGED
package/skills/index.json
CHANGED
|
@@ -227,7 +227,7 @@
|
|
|
227
227
|
"name": "magpie",
|
|
228
228
|
"description": "Interactive PR review pipeline. Runs five parallel specialist subagents (security, bugs, performance, code-smells, architecture) plus a once-per-PR checks pass that finds tests and controls able to pass without proving their purpose, drops findings whose quoted evidence is not in the code, dedupes, runs critic subagents that re-check each finding against the worktree and set its risk label, peer-reviews via codex exec (falling back to a Claude second opinion when codex is unavailable), and serves an interactive HTML report for selecting or dismissing findings to post via gh, recording the outcome per finding as labels. Bundles a Bun CLI put on PATH by the skill's postinstall step under a bunx install, or by the plugin's bin/ under a Claude Code plugin install. Use when the user asks to review a GitHub pull request. Local mode (setup --local) runs the same pipeline on the current branch's diff from its merge base, uncommitted and untracked work included, against the caller's live tree, with no server or posting, and hands the ranked findings back in the terminal for an implementing or orchestrating agent to address. Splits oversized diffs into budgeted shards and rebuilds the diff from the local clone when gh pr diff refuses it.",
|
|
229
229
|
"type": "prompt",
|
|
230
|
-
"version": "0.
|
|
230
|
+
"version": "0.15.0"
|
|
231
231
|
},
|
|
232
232
|
{
|
|
233
233
|
"name": "migrate",
|
|
@@ -293,9 +293,9 @@
|
|
|
293
293
|
},
|
|
294
294
|
{
|
|
295
295
|
"name": "sluice",
|
|
296
|
-
"description": "Routes work by change shape into four channels (bypass, fast, main, deep) and applies only the rules each channel needs, so a one-line fix does not pay the cost of a multi-subsystem build. Carries nine rules as one-liners in the router and the full treatment in references read only on friction. Checks the finished plan with plan.sh validate rather than trusting it to memory, seeds the run state from it, keeps a deep run's task breakdown in .sluice/run.json so a statusline segment, one status command and a SessionStart hook can answer where the run is (the hook prints a live run at every session start, compaction included), lists every live deep run and routed fast or main session on the machine in one board.sh view (drawn once, watched, or as JSON), and closes each run with a ledger read out of the session transcript: elapsed, tools, tokens, and what each dispatched agent cost where the transcript recorded it. Two Stop hooks hold a handback: one refuses a tree that moved since its last recorded check, the other refuses a changed existing test not proven to fail on the session's starting code (or recorded with a reason). Claude Code only; stands down where the superpowers pipeline governs the repo.",
|
|
296
|
+
"description": "Routes work by change shape into four channels (bypass, fast, main, deep) and applies only the rules each channel needs, so a one-line fix does not pay the cost of a multi-subsystem build. Carries nine rules as one-liners in the router and the full treatment in references read only on friction. Deep runs read the repo before designing, map the spec's intent to its decisions, and check spec against intent and plan against spec with a fresh reader, with plan.sh validate enforcing that every decision is covered. Checks the finished plan with plan.sh validate rather than trusting it to memory, seeds the run state from it, keeps a deep run's task breakdown in .sluice/run.json so a statusline segment, one status command and a SessionStart hook can answer where the run is (the hook prints a live run at every session start, compaction included), lists every live deep run and routed fast or main session on the machine in one board.sh view (drawn once, watched, or as JSON), and closes each run with a ledger read out of the session transcript: elapsed, tools, tokens, and what each dispatched agent cost where the transcript recorded it. Two Stop hooks hold a handback: one refuses a tree that moved since its last recorded check, the other refuses a changed existing test not proven to fail on the session's starting code (or recorded with a reason). Claude Code only; stands down where the superpowers pipeline governs the repo.",
|
|
297
297
|
"type": "prompt",
|
|
298
|
-
"version": "0.
|
|
298
|
+
"version": "0.28.0"
|
|
299
299
|
},
|
|
300
300
|
{
|
|
301
301
|
"name": "temporal-coupling-detector",
|
package/skills/magpie/README.md
CHANGED
|
@@ -35,7 +35,7 @@ If you cloned this repo and want to run from source, you can also invoke `./inst
|
|
|
35
35
|
|
|
36
36
|
Inside Claude Code, ask: "Review PR 1234" (or paste a PR URL). The agent reads SKILL.md and walks the pipeline; the CLI runs as `magpie setup`, `magpie serve`, etc.
|
|
37
37
|
|
|
38
|
-
An implementing or orchestrating agent can also ask for a review of its own branch before a PR exists: local mode (`magpie setup <run-dir> --local [--base <ref>]`) reviews the merge base to working tree diff in place and hands the ranked findings back as terminal text via `magpie handoff`, with no server, report or posting.
|
|
38
|
+
An implementing or orchestrating agent can also ask for a review of its own branch before a PR exists: local mode (`magpie setup <run-dir> --local [--base <ref>]`) reviews the merge base to working tree diff in place and hands the ranked findings back as terminal text via `magpie handoff`, with no server, report or posting. `/magpie` with no arguments runs local mode; pass a PR number or URL to review a PR.
|
|
39
39
|
|
|
40
40
|
## Development
|
|
41
41
|
|
package/skills/magpie/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: magpie
|
|
3
3
|
description: Use when the user asks to review a GitHub pull request (a PR number, PR URL, or "review this PR"), or to self-review the current branch diff before a PR exists, typically requested by an implementing or orchestrating agent, with findings handed back in the terminal. Interactive PR review pipeline; five parallel specialist subagents, dedupe, critic, codex/Claude peer review, and an interactive HTML report for posting selected findings via gh. Follow the stage walkthrough in this skill; the description is not the procedure.
|
|
4
|
-
argument-hint: "[<pr#>|<pr-url>|local] [--base <ref>] [--intent-file <path>]"
|
|
4
|
+
argument-hint: "[<pr#>|<pr-url>|local (default)] [--base <ref>] [--intent-file <path>]"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Magpie
|
|
@@ -16,7 +16,7 @@ Stop reading and follow these steps in order. Do not skip stages. Use the exact
|
|
|
16
16
|
|
|
17
17
|
### 0. Identify the PR
|
|
18
18
|
|
|
19
|
-
A request with no PR that asks to review the current branch, the working tree, or work in progress, or arguments starting `local` (any `--base` or `--intent-file`
|
|
19
|
+
A bare invocation (no arguments and no PR named), a request with no PR that asks to review the current branch, the working tree, or work in progress, or arguments starting `local` or `--` (any `--base` or `--intent-file` go to setup), is local mode: follow "Local mode" below in place of this step and stages 1 and 2, then run stages 3 to 7 as written, taking `TARGET` from Local mode.
|
|
20
20
|
|
|
21
21
|
Parse the user's request for a PR number, URL, or "this PR" (current branch). If ambiguous, ask one clarifying terminal question. Capture the PR number into `$PR_NUMBER` and the repo path into `$REPO` (default: the current working directory).
|
|
22
22
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# magpie evals
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
decisions this skill owns are the ones between the CLI calls: `scripts/__tests__/`
|
|
3
|
+
Seven cases for `claude plugin eval`. Each starts at a decision rather than at
|
|
4
|
+
the top of a run, most of them mid-pipeline, because the decisions this skill owns are the ones between the CLI calls: `scripts/__tests__/`
|
|
5
5
|
already pins what `magpie setup`, `dedupe`, `shard`, `post` and `status` compute.
|
|
6
6
|
What no unit test can reach is whether the agent stops where the walkthrough says
|
|
7
7
|
stop, falls back where it says fall back, and keeps its hands off the things it
|
|
@@ -15,6 +15,7 @@ must not touch.
|
|
|
15
15
|
| `post-folds-selection-events` | The user typed `post` after re-ticking | Folds `state/events` last-event-wins, posts `bugs-1,perf-1` only |
|
|
16
16
|
| `resume-finds-active-run` | A fresh review ask on a PR with a live run | Checks `--list-runs` first, never calls `setup`, surfaces the interrupted run |
|
|
17
17
|
| `local-mode-hands-back` | A local run resumed after peer review | Runs `handoff` then `cleanup`, replies with both finding titles, never serves, renders, posts or calls `gh` |
|
|
18
|
+
| `bare-invocation-goes-local` | A bare `/magpie` on a branch with an open PR | Runs `setup --local`, never `--pr`, never calls `gh` |
|
|
18
19
|
|
|
19
20
|
## Running
|
|
20
21
|
|
|
@@ -59,8 +60,8 @@ bun run eval:fresh accept skills/magpie <result.json>
|
|
|
59
60
|
|
|
60
61
|
`rules.json` maps each rule the skill states to the cases that pin it, or says
|
|
61
62
|
why none does; `diff` reads it to name rules at risk or ready to expire. What
|
|
62
|
-
each verdict means is in `skills/sluice/evals/README.md`.
|
|
63
|
-
|
|
63
|
+
each verdict means is in `skills/sluice/evals/README.md`. The accepted baseline
|
|
64
|
+
is `baselines/claude-opus-5-5.json`.
|
|
64
65
|
|
|
65
66
|
## How the fixtures fake the pipeline
|
|
66
67
|
|
|
@@ -121,6 +122,16 @@ reported as pass/fail indicators, because they can never pass without the
|
|
|
121
122
|
plugin. They are there to tell you whether a score came from magpie or from the
|
|
122
123
|
model's own habits.
|
|
123
124
|
|
|
125
|
+
`bare-invocation-goes-local` has no such grader. Its prompt is `/magpie`, which
|
|
126
|
+
the child expands as a slash command, so the skill loads without a `Skill` call
|
|
127
|
+
and the trace does not record the load. `setup-ran-local` stands in for it: only
|
|
128
|
+
SKILL.md tells the agent to run `magpie setup --local`.
|
|
129
|
+
|
|
130
|
+
That case needs git in the child for the branch slug, and the xcrun shim at
|
|
131
|
+
`/usr/bin/git` fails in the sandbox, so its fixture puts a `git` wrapper on the
|
|
132
|
+
shims path that execs `/Library/Developer/CommandLineTools/usr/bin/git`. On a
|
|
133
|
+
machine without the Command Line Tools, point the wrapper at that machine's git.
|
|
134
|
+
|
|
124
135
|
**Every `llm` grader carries `focus: last_message`.** Without it the judge is
|
|
125
136
|
handed a window of the whole trace, and in a case that reads a 40,000-line diff
|
|
126
137
|
the handback falls outside that window: the shard-gate rubric voted FAIL nine
|
|
@@ -175,7 +186,10 @@ Its default effort is `medium` where Claude Opus 5's is `high`, so a rubric that
|
|
|
175
186
|
starts failing there is worth reading as a real behavioural difference before
|
|
176
187
|
it is loosened.
|
|
177
188
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
The current baseline (skill 0.15.0, CLI 2.1.306, 2026-10-21) ran every case
|
|
190
|
+
three times in both arms on Claude Opus 5.5, USD 10.31 and nine and a half
|
|
191
|
+
minutes at `-j 3`. Every case scored 1.00 with the plugin on all three runs
|
|
192
|
+
except `local-mode-hands-back`, which scored 0.80 once: the judge failed
|
|
193
|
+
`reply-lists-both-findings` 3/3 on that run, and its trace was not kept. Without
|
|
194
|
+
the plugin the cases score 0.40 to 0.78, so each one measures the skill rather
|
|
195
|
+
than the model's habits.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# A bare /magpie on a feature branch that already has an open PR. With no PR
|
|
3
|
+
# named, the walkthrough routes to local mode, so the open PR is a lure: the
|
|
4
|
+
# gh fake answers `gh pr view` with it, and the case passes only if gh is never
|
|
5
|
+
# asked.
|
|
6
|
+
#
|
|
7
|
+
# The branch is an orphan history (it was imported, not branched from main), so
|
|
8
|
+
# no base has a merge base with it and the real `setup --local` fails in
|
|
9
|
+
# localBranchDiff. The walkthrough stops on a failed setup, which keeps the case
|
|
10
|
+
# to the routing decision: nothing past setup is dispatched or graded.
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
BRANCH="feat/tenant-settings-cache"
|
|
14
|
+
CALLS="$PWD/.magpie-calls.log"
|
|
15
|
+
REPO="$PWD"
|
|
16
|
+
|
|
17
|
+
mkdir -p "$HOME/shims" "$HOME/tmp"
|
|
18
|
+
: > "$CALLS"
|
|
19
|
+
|
|
20
|
+
cat > "$HOME/shim-config" <<EOF
|
|
21
|
+
CALLS="$CALLS"
|
|
22
|
+
REPO="$REPO"
|
|
23
|
+
EOF
|
|
24
|
+
|
|
25
|
+
# The real magpie and gh are outside the eval sandbox and cannot be executed
|
|
26
|
+
# from inside it, so the child gets fakes rather than exit 126.
|
|
27
|
+
cat > "$HOME/.zshenv" <<'RC'
|
|
28
|
+
export PATH="$HOME/shims:/usr/bin:/bin:/usr/sbin:/sbin"
|
|
29
|
+
export TMPDIR="$HOME/tmp"
|
|
30
|
+
RC
|
|
31
|
+
|
|
32
|
+
# /usr/bin/git is the xcrun shim, which cannot write its cache in the sandbox,
|
|
33
|
+
# and local mode needs git for the branch slug. The Command Line Tools binary
|
|
34
|
+
# runs when called by full path (skills/sluice/evals/README.md has the details).
|
|
35
|
+
cat > "$HOME/shims/git" <<'SHIM'
|
|
36
|
+
#!/bin/sh
|
|
37
|
+
exec /Library/Developer/CommandLineTools/usr/bin/git "$@"
|
|
38
|
+
SHIM
|
|
39
|
+
chmod +x "$HOME/shims/git"
|
|
40
|
+
|
|
41
|
+
# setup --local makes the checks scripts/local-diff.ts makes, with the same
|
|
42
|
+
# messages, and writes what setup-cmd.ts writes for a local run when they pass.
|
|
43
|
+
# The PR path is not faked: reaching it fails the case.
|
|
44
|
+
cat > "$HOME/shims/magpie" <<'SHIM'
|
|
45
|
+
#!/usr/bin/env bash
|
|
46
|
+
. "$HOME/shim-config"
|
|
47
|
+
echo "magpie $*" >> "$CALLS"
|
|
48
|
+
case "${1:-}" in
|
|
49
|
+
--list-runs) ;;
|
|
50
|
+
setup)
|
|
51
|
+
shift
|
|
52
|
+
run_dir="$1"; shift
|
|
53
|
+
local_mode=0 base="origin/HEAD" repo="$PWD"
|
|
54
|
+
while [ $# -gt 0 ]; do
|
|
55
|
+
case "$1" in
|
|
56
|
+
--local) local_mode=1 ;;
|
|
57
|
+
--base) base="$2"; shift ;;
|
|
58
|
+
--repo) repo="$2"; shift ;;
|
|
59
|
+
--intent-file) shift ;;
|
|
60
|
+
esac
|
|
61
|
+
shift
|
|
62
|
+
done
|
|
63
|
+
if [ "$local_mode" = 0 ]; then
|
|
64
|
+
echo "fake magpie: PR setup is not faked" >&2
|
|
65
|
+
exit 64
|
|
66
|
+
fi
|
|
67
|
+
mkdir -p "$run_dir/findings"
|
|
68
|
+
if ! git -C "$repo" rev-parse --verify -q "$base^{commit}" > /dev/null; then
|
|
69
|
+
echo "{\"stage\":\"local-diff\",\"status\":\"error\",\"error\":\"cannot resolve base ref $base to a commit\"}" >> "$run_dir/log.jsonl"
|
|
70
|
+
echo "magpie: cannot resolve base ref $base to a commit" >&2
|
|
71
|
+
exit 4
|
|
72
|
+
fi
|
|
73
|
+
if ! merge_base=$(git -C "$repo" merge-base "$base" HEAD); then
|
|
74
|
+
echo "{\"stage\":\"local-diff\",\"status\":\"error\",\"error\":\"no merge base between $base and HEAD: \"}" >> "$run_dir/log.jsonl"
|
|
75
|
+
echo "magpie: no merge base between $base and HEAD: " >&2
|
|
76
|
+
exit 4
|
|
77
|
+
fi
|
|
78
|
+
head=$(git -C "$repo" rev-parse HEAD)
|
|
79
|
+
branch=$(git -C "$repo" symbolic-ref --short -q HEAD || true)
|
|
80
|
+
git -C "$repo" diff --no-color --no-ext-diff "$merge_base" > "$run_dir/diff.patch"
|
|
81
|
+
printf '{ "mode": "local", "root": "%s" }\n' "$repo" > "$run_dir/target.json"
|
|
82
|
+
git -C "$repo" log --format=%H%x1f%s%x1f%b%x1e "$merge_base..HEAD" |
|
|
83
|
+
python3 -c '
|
|
84
|
+
import json, sys
|
|
85
|
+
branch, base, merge_base, head = sys.argv[1:]
|
|
86
|
+
commits = []
|
|
87
|
+
for record in sys.stdin.read().split("\x1e"):
|
|
88
|
+
if record.strip():
|
|
89
|
+
oid, headline, body = record.strip("\n").split("\x1f")
|
|
90
|
+
commits.append({"oid": oid, "headline": headline, "body": body.strip()})
|
|
91
|
+
print(json.dumps({"branch": branch or None, "baseRef": base, "mergeBase": merge_base, "head": head,
|
|
92
|
+
"dirty": False, "author": "Asha Platform", "commits": commits, "intentFile": None}, indent=2))
|
|
93
|
+
' "$branch" "$base" "$merge_base" "$head" > "$run_dir/local.json"
|
|
94
|
+
echo '[]' > "$run_dir/findings/tests.json"
|
|
95
|
+
printf '%s\n' '{"stage":"preflight","status":"done","missingOptional":["codex"]}' '{"stage":"setup","status":"done"}' > "$run_dir/log.jsonl"
|
|
96
|
+
echo "magpie: codex not found; peer review will use a Claude subagent"
|
|
97
|
+
echo "setup done: $run_dir"
|
|
98
|
+
;;
|
|
99
|
+
target)
|
|
100
|
+
python3 -c 'import json, sys; print(json.load(open(sys.argv[1]))["root"])' "${2}/target.json"
|
|
101
|
+
;;
|
|
102
|
+
*) echo "fake magpie: unsupported subcommand: $*" >&2; exit 64 ;;
|
|
103
|
+
esac
|
|
104
|
+
SHIM
|
|
105
|
+
chmod +x "$HOME/shims/magpie"
|
|
106
|
+
|
|
107
|
+
cat > "$HOME/shims/gh" <<'SHIM'
|
|
108
|
+
#!/usr/bin/env bash
|
|
109
|
+
. "$HOME/shim-config"
|
|
110
|
+
echo "gh $*" >> "$CALLS"
|
|
111
|
+
if [ "${1:-} ${2:-}" = "pr view" ] || [ "${1:-} ${2:-}" = "pr list" ]; then
|
|
112
|
+
echo '{"number":1337,"title":"feat: cache tenant settings","headRefName":"feat/tenant-settings-cache","state":"OPEN"}'
|
|
113
|
+
exit 0
|
|
114
|
+
fi
|
|
115
|
+
echo "fake gh: no request was made" >&2
|
|
116
|
+
exit 1
|
|
117
|
+
SHIM
|
|
118
|
+
chmod +x "$HOME/shims/gh"
|
|
119
|
+
|
|
120
|
+
export GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null
|
|
121
|
+
git init -q -b main .
|
|
122
|
+
git config commit.gpgsign false
|
|
123
|
+
printf '.magpie-calls.log\n' >> .git/info/exclude
|
|
124
|
+
export GIT_AUTHOR_NAME="Asha Platform" GIT_AUTHOR_EMAIL="asha@example.com"
|
|
125
|
+
export GIT_COMMITTER_NAME="Asha Platform" GIT_COMMITTER_EMAIL="asha@example.com"
|
|
126
|
+
mkdir -p src/settings
|
|
127
|
+
|
|
128
|
+
cat > src/settings/cache.ts <<'TS'
|
|
129
|
+
const store = new Map<string, Settings>()
|
|
130
|
+
|
|
131
|
+
export function clear() {
|
|
132
|
+
store.clear()
|
|
133
|
+
}
|
|
134
|
+
TS
|
|
135
|
+
|
|
136
|
+
git add src
|
|
137
|
+
git commit -q -m "feat: tenant settings store"
|
|
138
|
+
git update-ref refs/remotes/origin/main HEAD
|
|
139
|
+
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
|
|
140
|
+
git checkout -q --orphan "$BRANCH"
|
|
141
|
+
|
|
142
|
+
cat > src/settings/cache.ts <<'TS'
|
|
143
|
+
const store = new Map<string, Settings>()
|
|
144
|
+
|
|
145
|
+
export function put(tenantId: string, settings: Settings) {
|
|
146
|
+
store.set(tenantId, settings)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function get(tenantId: string): Settings | undefined {
|
|
150
|
+
return store.get(tenantId)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function clear() {
|
|
154
|
+
store.clear()
|
|
155
|
+
}
|
|
156
|
+
TS
|
|
157
|
+
|
|
158
|
+
git add src
|
|
159
|
+
git commit -q -m "feat: cache tenant settings in the request path"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bare-invocation-goes-local
|
|
3
|
+
description: A bare /magpie on a branch that already has an open PR reviews the branch in local mode. It never looks the PR up or sets up a PR run.
|
|
4
|
+
tags: [magpie, local, routing, scaffold]
|
|
5
|
+
max_turns: 15
|
|
6
|
+
timeout_seconds: 600
|
|
7
|
+
allowed_tools: [Read, Glob, Grep, Skill, Write, Edit, Bash, Task]
|
|
8
|
+
expected_outcome: Runs magpie setup with --local against the workspace, never --pr, and never calls gh. The branch shares no history with any base, so setup fails and the run stops there, surfacing the error.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
/magpie
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"model": "claude-opus-5-5",
|
|
3
3
|
"judgeModel": "claude-opus-5-5",
|
|
4
|
-
"claudeVersion": "2.1.
|
|
5
|
-
"skillVersion": "0.
|
|
6
|
-
"date": "2026-10-
|
|
4
|
+
"claudeVersion": "2.1.306",
|
|
5
|
+
"skillVersion": "0.15.0",
|
|
6
|
+
"date": "2026-10-21T16:36:32.144Z",
|
|
7
7
|
"cases": {
|
|
8
|
+
"bare-invocation-goes-local": {
|
|
9
|
+
"with": [
|
|
10
|
+
1,
|
|
11
|
+
1,
|
|
12
|
+
1
|
|
13
|
+
],
|
|
14
|
+
"without": [
|
|
15
|
+
0.5,
|
|
16
|
+
0.5,
|
|
17
|
+
0.5
|
|
18
|
+
]
|
|
19
|
+
},
|
|
8
20
|
"codex-missing-falls-back": {
|
|
9
21
|
"with": [
|
|
10
22
|
1,
|
|
@@ -17,6 +29,18 @@
|
|
|
17
29
|
0.5
|
|
18
30
|
]
|
|
19
31
|
},
|
|
32
|
+
"local-mode-hands-back": {
|
|
33
|
+
"with": [
|
|
34
|
+
1,
|
|
35
|
+
1,
|
|
36
|
+
0.8
|
|
37
|
+
],
|
|
38
|
+
"without": [
|
|
39
|
+
0.4,
|
|
40
|
+
0.4,
|
|
41
|
+
0.4
|
|
42
|
+
]
|
|
43
|
+
},
|
|
20
44
|
"post-folds-selection-events": {
|
|
21
45
|
"with": [
|
|
22
46
|
1,
|
|
@@ -149,6 +149,14 @@
|
|
|
149
149
|
"cases": [],
|
|
150
150
|
"unpinned": "Only local-mode-hands-back runs cleanup, and local cleanup prints no view-later line by design; no PR case reaches stage 10, and the PR fakes have no cleanup subcommand."
|
|
151
151
|
},
|
|
152
|
+
{
|
|
153
|
+
"id": "bare-invocation-is-local-mode",
|
|
154
|
+
"states": "SKILL.md: 0. Identify the PR",
|
|
155
|
+
"origin": "commit:fdda718",
|
|
156
|
+
"cases": [
|
|
157
|
+
"bare-invocation-goes-local"
|
|
158
|
+
]
|
|
159
|
+
},
|
|
152
160
|
{
|
|
153
161
|
"id": "local-mode-hands-back-via-handoff",
|
|
154
162
|
"states": "SKILL.md: Local mode",
|
|
@@ -212,6 +212,14 @@ test('SKILL.md sends each stage to the reference file it needs', async () => {
|
|
|
212
212
|
expect(section('### 7. Peer review')).toContain('references/peer-review.md')
|
|
213
213
|
})
|
|
214
214
|
|
|
215
|
+
test('a bare /magpie is routed to local mode and the hint says so', async () => {
|
|
216
|
+
const text = await readFile(SKILL, 'utf8')
|
|
217
|
+
expect(text).toMatch(/^argument-hint: ".*local \(default\).*"$/m)
|
|
218
|
+
const start = text.indexOf('### 0. Identify the PR')
|
|
219
|
+
const routing = text.slice(start, text.indexOf('\n### ', start + 1))
|
|
220
|
+
expect(routing).toMatch(/bare invocation \(no arguments and no PR named\)[^.]*is local mode/)
|
|
221
|
+
})
|
|
222
|
+
|
|
215
223
|
test('SKILL.md no longer inlines the prompt bodies it moved out', async () => {
|
|
216
224
|
const text = await readFile(SKILL, 'utf8')
|
|
217
225
|
for (const tag of ['magpie-specialist-', 'magpie-critic', 'magpie-peer-review', 'magpie-scout']) {
|
package/skills/magpie/skill.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magpie",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Interactive PR review pipeline. Runs five parallel specialist subagents (security, bugs, performance, code-smells, architecture) plus a once-per-PR checks pass that finds tests and controls able to pass without proving their purpose, drops findings whose quoted evidence is not in the code, dedupes, runs critic subagents that re-check each finding against the worktree and set its risk label, peer-reviews via codex exec (falling back to a Claude second opinion when codex is unavailable), and serves an interactive HTML report for selecting or dismissing findings to post via gh, recording the outcome per finding as labels. Bundles a Bun CLI put on PATH by the skill's postinstall step under a bunx install, or by the plugin's bin/ under a Claude Code plugin install. Use when the user asks to review a GitHub pull request. Local mode (setup --local) runs the same pipeline on the current branch's diff from its merge base, uncommitted and untracked work included, against the caller's live tree, with no server or posting, and hands the ranked findings back in the terminal for an implementing or orchestrating agent to address. Splits oversized diffs into budgeted shards and rebuilds the diff from the local clone when gh pr diff refuses it.",
|
|
5
5
|
"author": "iceinvein",
|
|
6
6
|
"type": "prompt",
|
package/skills/sluice/SKILL.md
CHANGED
|
@@ -132,6 +132,12 @@ the design's shape turns on a fork only your partner can settle, ask that one
|
|
|
132
132
|
question through `AskUserQuestion`, with your recommendation, before the design
|
|
133
133
|
is written. `references/deep-channel.md` has the test for what counts.
|
|
134
134
|
|
|
135
|
+
Read the repo before the walk and before any fork question: prior designs, the
|
|
136
|
+
code beside the path and the stated constraints, each cited by path in the
|
|
137
|
+
spec's `## Context`. A prior spec
|
|
138
|
+
often settles the fork, and nothing can be settled from a repo nobody read.
|
|
139
|
+
`references/deep-channel.md` has it under `## The ground`.
|
|
140
|
+
|
|
135
141
|
The design carries a `## Trace` section before it goes up for sign-off: the
|
|
136
142
|
request's own example, quoted, walked through the data as it stands, with what
|
|
137
143
|
each reused function requires and writes read from the code. Per-task reviews
|
|
@@ -140,6 +146,11 @@ a design checked only against the shape of the code is wrong for a whole plan
|
|
|
140
146
|
before anything catches it.
|
|
141
147
|
`references/deep-channel.md` has what the section holds.
|
|
142
148
|
|
|
149
|
+
Each stop gets a fresh reader first: the intent check before sign-off, the plan
|
|
150
|
+
check after `plan.sh validate` and before pre-flight, because an author reads
|
|
151
|
+
past the gap between what was meant and what was written.
|
|
152
|
+
`references/deep-channel.md` has the briefs under `## The alignment checks`.
|
|
153
|
+
|
|
143
154
|
Take the design stop through the harness's plan mode where there is one. Its
|
|
144
155
|
gate is enforced rather than requested and it holds edits shut while it is open,
|
|
145
156
|
so nothing gets built against a design nobody signed. It carries the first stop
|
|
@@ -168,11 +179,13 @@ plan:
|
|
|
168
179
|
|
|
169
180
|
```
|
|
170
181
|
# Plan: <topic>
|
|
182
|
+
**Spec:** <path to the signed-off design>
|
|
171
183
|
## Ground Rules
|
|
172
184
|
- <exact value>
|
|
173
185
|
### Task N: <name>
|
|
174
186
|
**Contract:** Needs: <sig> | Offers: <sig>
|
|
175
187
|
**Touches:** <path> (new) | <path> (edit) | <path> (test)
|
|
188
|
+
**Builds:** <D<n>, ..., or none and why>
|
|
176
189
|
**Flips:** <what changes, from what, or omit>
|
|
177
190
|
**Review:** <reason, or omit>
|
|
178
191
|
**Effort:** <low, and why the work is mechanical, or omit>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# sluice evals
|
|
2
2
|
|
|
3
|
-
Twenty-
|
|
3
|
+
Twenty-five cases for `claude plugin eval`. Eighteen pin the routing decision: which
|
|
4
4
|
channel the run names, and whether the behaviour that channel owes actually
|
|
5
5
|
happened. Seven pin what a deep run does after pre-flight, where the question is
|
|
6
6
|
no longer which channel but whether the run keeps going.
|
|
@@ -13,6 +13,9 @@ no longer which channel but whether the run keeps going.
|
|
|
13
13
|
| `deep-plan-across-subsystems` | A plan asked for, three subsystems | Deep channel; design written to `docs/specs/`; stops before code |
|
|
14
14
|
| `deep-plan-asks-the-fork` | The same plan with nothing saying where the counters can live | One question with a recommendation before any design; no spec yet |
|
|
15
15
|
| `deep-plan-traces-the-example` | A ticket whose own example the obvious design fails: the lookup it says to reuse matches accepted slides, and the smoke deck has none | A `## Trace` section in the spec that walks the example through the smoke deck, a lookup designed around what it found, and no write under `src/` or `tests/` |
|
|
16
|
+
| `deep-plan-reads-the-prior-spec` | A ticket whose obvious design keeps a counter in memory, against an earlier spec the prompt never names that settled counters in a file | The new spec cites `2026-09-01-counters.md`, the design keeps the counter in that file or asks whether to supersede it, and no write under `src/` or `tests/` |
|
|
17
|
+
| `deep-plan-checks-the-intent` | A ticket with three numbered asks | An Intent section that quotes the ticket and maps each ask to a decision or to Out of scope, an Agent dispatch naming the draft and its Intent after the draft is first written, and a sign-off message that says what the check found |
|
|
18
|
+
| `deep-plan-checks-the-plan` | A signed-off spec with D1 to D3, and the plan asked for | A `**Spec:**` line and a Builds line on every task covering D1 to D3, `plan.sh validate` run, a dispatch naming both files after the first validate, and a stop at the pre-flight questions with no task started |
|
|
16
19
|
| `explicit-instruction-collapses-to-fast` | Main-shaped work plus "just do it" | Collapses to fast; no design, no proposal |
|
|
17
20
|
| `superpowers-conflict-stands-down` | Repo mandates the superpowers sequence | Stands down once, names no channel |
|
|
18
21
|
| `announcement-reaches-the-ledger` | A flag that a surface test turns into a new export | `status.sh route main` before any write under `src/` and before any fast or deep route |
|
|
@@ -37,7 +40,7 @@ Execution, where the run is already past both stops:
|
|
|
37
40
|
|
|
38
41
|
## Running
|
|
39
42
|
|
|
40
|
-
Twenty-
|
|
43
|
+
Twenty-four cases scaffold a small Node repo and then change it, so they need the
|
|
41
44
|
scaffold flag and a tool grant. Pin the model, because the eval child does not
|
|
42
45
|
inherit it, and pin the judge, because `--model` does not reach it and the
|
|
43
46
|
`llm` graders otherwise run on Haiku. From the repo root:
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# A relay whose CLI, webhook handler and worker all reach one upstream client,
|
|
3
|
+
# so a ticket touching retries is a three-subsystem change. The ticket carries
|
|
4
|
+
# three numbered asks, and each one fixes its own numbers, so the run has no
|
|
5
|
+
# fork to ask about and the case reaches the written design, where it pins the
|
|
6
|
+
# Intent map and the fresh-context check of the spec against it. The README
|
|
7
|
+
# fixes where the design goes, so the graders can read it.
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
mkdir -p src/cli src/webhook src/worker src/upstream tests docs/specs
|
|
11
|
+
|
|
12
|
+
cat > package.json <<'JSON'
|
|
13
|
+
{
|
|
14
|
+
"name": "relay",
|
|
15
|
+
"version": "0.6.0",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "node --test \"tests/*.test.js\""
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
JSON
|
|
22
|
+
|
|
23
|
+
cat > src/upstream/client.js <<'JS'
|
|
24
|
+
const BASE = "https://api.upstream.example";
|
|
25
|
+
|
|
26
|
+
export async function call(path, body, fetchImpl = fetch) {
|
|
27
|
+
const response = await fetchImpl(`${BASE}${path}`, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: { "content-type": "application/json" },
|
|
30
|
+
body: JSON.stringify(body),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
throw new Error(`upstream ${response.status} on ${path}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return response.json();
|
|
38
|
+
}
|
|
39
|
+
JS
|
|
40
|
+
|
|
41
|
+
cat > src/cli/push.js <<'JS'
|
|
42
|
+
import { call } from "../upstream/client.js";
|
|
43
|
+
|
|
44
|
+
export async function push(records, log = console.log) {
|
|
45
|
+
for (const record of records) {
|
|
46
|
+
await call("/v1/records", record);
|
|
47
|
+
log(`pushed ${record.id}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
JS
|
|
51
|
+
|
|
52
|
+
cat > src/cli/main.js <<'JS'
|
|
53
|
+
import { readFileSync } from "node:fs";
|
|
54
|
+
import { push } from "./push.js";
|
|
55
|
+
|
|
56
|
+
const [file] = process.argv.slice(2);
|
|
57
|
+
await push(JSON.parse(readFileSync(file, "utf8")));
|
|
58
|
+
JS
|
|
59
|
+
|
|
60
|
+
cat > src/webhook/handler.js <<'JS'
|
|
61
|
+
import { call } from "../upstream/client.js";
|
|
62
|
+
|
|
63
|
+
export async function handle(event) {
|
|
64
|
+
const result = await call("/v1/events", { type: event.type, payload: event.payload });
|
|
65
|
+
return { status: 202, id: result.id };
|
|
66
|
+
}
|
|
67
|
+
JS
|
|
68
|
+
|
|
69
|
+
cat > src/worker/backfill.js <<'JS'
|
|
70
|
+
import { call } from "../upstream/client.js";
|
|
71
|
+
|
|
72
|
+
export async function backfill(queue, log = console.log) {
|
|
73
|
+
let sent = 0;
|
|
74
|
+
|
|
75
|
+
while (queue.length > 0) {
|
|
76
|
+
await call("/v1/records", queue.shift());
|
|
77
|
+
sent += 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
log(`backfill sent ${sent}`);
|
|
81
|
+
return sent;
|
|
82
|
+
}
|
|
83
|
+
JS
|
|
84
|
+
|
|
85
|
+
cat > tests/upstream.test.js <<'JS'
|
|
86
|
+
import assert from "node:assert/strict";
|
|
87
|
+
import { test } from "node:test";
|
|
88
|
+
import { call } from "../src/upstream/client.js";
|
|
89
|
+
|
|
90
|
+
function fakeFetch(ok, body) {
|
|
91
|
+
return async () => ({ ok, status: ok ? 200 : 429, json: async () => body });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
test("a successful call returns the parsed body", async () => {
|
|
95
|
+
const result = await call("/v1/records", { id: "a" }, fakeFetch(true, { id: "a" }));
|
|
96
|
+
assert.deepEqual(result, { id: "a" });
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("a rejected call reports the status and the path", async () => {
|
|
100
|
+
await assert.rejects(
|
|
101
|
+
() => call("/v1/records", { id: "a" }, fakeFetch(false)),
|
|
102
|
+
/upstream 429 on \/v1\/records/,
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
JS
|
|
106
|
+
|
|
107
|
+
cat > README.md <<'MD'
|
|
108
|
+
# relay
|
|
109
|
+
|
|
110
|
+
Three callers, one upstream API: `src/cli/push.js`, `src/webhook/handler.js`
|
|
111
|
+
and `src/worker/backfill.js` all go through `src/upstream/client.js`. Each
|
|
112
|
+
caller logs through the `log` it is handed, which defaults to `console.log`.
|
|
113
|
+
`npm test` runs the suite.
|
|
114
|
+
|
|
115
|
+
## Designs
|
|
116
|
+
|
|
117
|
+
A ticket's design goes in `docs/specs/<ticket>.md`, for example
|
|
118
|
+
`docs/specs/OPS-12.md`, and its plan in `docs/plans/<ticket>.md`.
|
|
119
|
+
MD
|
|
120
|
+
touch docs/specs/.gitkeep
|
|
121
|
+
|
|
122
|
+
git init --quiet
|
|
123
|
+
git add -A
|
|
124
|
+
git -c user.email=fixture@example.com -c user.name=fixture commit --quiet -m "relay 0.6.0"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: regex
|
|
3
|
+
# The trace carries SKILL.md's own routing table, which names every channel, so
|
|
4
|
+
# `contains` passes whenever the skill loads. Anchor on the two ways the agent
|
|
5
|
+
# routes instead, the same ones run-stats.sh meters: a Bash call that invokes
|
|
6
|
+
# `status.sh route deep` (a quoted mention, as in a grep, does not count), or the
|
|
7
|
+
# words opening an assistant message or following a label such as "Sluice:".
|
|
8
|
+
pattern: '"command":"(?:(?:[^"\\]|\\.)*?(?:[\s/]|\\[nt]))?status\.sh(?:\\"|'')?(?:\s|\\[nt])+route(?:\s|\\[nt])+deep(?:\s|\\[nt]|[;&|]|")|"text":"(?:[^.!?\n"]{0,100}[:=]\s*)?[\s*_#>\\]*deep channel'
|
|
9
|
+
flags: i
|
|
10
|
+
target: trace
|
|
11
|
+
weight: 2
|
|
12
|
+
---
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: tool_order
|
|
3
|
+
# The check reads a drafted design in a fresh context, so it comes after the
|
|
4
|
+
# first Write of the draft: the spec file, or the harness's plan file under plan
|
|
5
|
+
# mode, which is where the reference says the draft lives until sign-off. Its
|
|
6
|
+
# brief names that draft and the Intent it checks against. The ground read goes
|
|
7
|
+
# out before any draft exists; were its brief also to name the spec's path and
|
|
8
|
+
# the word Intent, it would be the first after-match and fail the case.
|
|
9
|
+
before: { tool: Write, input_match: '"file_path"\s*:\s*"[^"]*(?:docs/specs/OPS-12\.md|/\.claude/plans/[^"]*\.md)"' }
|
|
10
|
+
after: { tool: Agent, input_match: '^(?=[\s\S]*(?:OPS-12\.md|/\.claude/plans/))(?=[\s\S]*Intent)' }
|
|
11
|
+
weight: 2
|
|
12
|
+
---
|