SLOPSHOPPER

prefilter-rank

After a Grep/Glob with 5+ results, ranks them by relevance to the task using the local Laya prefilter (system1-prefilter addon) and adds a read-order reminder…

newguardnetwork
★ 8v0.1.0MITupdated 2026-10-21AftabIbrahimKazi/ai-dev-kit/mods/prefilter-rank
A shopper browsing a rack in a slop shop
README

AI Dev Kit

Agent skills, optional MCP tools, and layered coding standards for AI-assisted development — Claude Code, OpenCode, Codex, and any coding agent that reads markdown.

Portable SKILL.md agent skills, framework-agnostic coding standards, and opt-in free/local MCP servers (UI prototyping, image reading, image generation, file pre-filtering) for teams building with AI pair programmers. One clone. Drop two folders into any project. Every session works your way — and gets better at it with use.

License: MIT GitHub stars GitHub forks Last commit


Listed under AI Hub → Skills on Three.js Resources — a curated directory for Three.js AI tools.

Featured on Three.js Resources


Quick start

git clone https://github.com/AftabIbrahimKazi/ai-dev-kit.git
cp -r ai-dev-kit/skills ai-dev-kit/coding-standards your-project/

On Windows PowerShell: Copy-Item -Recurse ai-dev-kit/skills, ai-dev-kit/coding-standards your-project/

Then open Claude Code, OpenCode, Codex or any agent that reads markdown in your-project and say:

read skills/README.md and install

The installer copies markdown files only: no packages, no build step. Full details: Install into a project.

Why use it

  • Consistent sessions. The standards chain loads for each file you edit (the optional standards-chain mod makes that mechanical), and skills load when the agent recognises their trigger, so session ten behaves like session one. Skill loading is model-judged, not guaranteed; the mods are what enforce the critical gates.
  • Fewer wasted tokens. Skills load only when relevant, reads are targeted, cheap models take the cheap work, and a script finds violations so the agent does not have to.
  • Standards that are enforced, not just written down. Rules are testable, the agent self-checks before a commit, and gaps are flagged instead of improvised.
  • Cleanup of old or shared code. code-audit counts violations across a whole project and lists the exact lines, so the agent reads only what is flagged.

What's in the kit

The kit is two independent systems that share one install path. skills/ teaches an AI coding agent how to work — session discipline, model-specific behavior, memory, coordination. coding-standards/ teaches it what correct code looks like for this project — language rules, file-role conventions, framework overrides. Either can be adopted alone; together, the coding-standards skill is what loads and enforces the standards chain during a session, so a project that wants enforcement needs both folders.

Every skill is a single portable markdown file with name + description frontmatter — the description is situation-first ("use whenever … load this BEFORE …") so it loads only when relevant — and reads a project-local, gitignored learnings.md sidecar at start and appends a lesson at end, so this repo stays the clean upstream while each install compounds its own experience. Every standard is testable and declarative, with wrong/right examples wherever a rule could be misread, and flags a gap (RULE AI-12) rather than inventing a rule where the standards are silent. They interlock at one seam: the install-kit skill installs both in one pass, and the coding-standards skill is what actually loads and walks the standards chain during a session — without it, coding-standards/ is just reference documentation.

skills/ — the self-improving skills library

Full catalog: skills/README.md

CategoryCoversRepresentative skills
models/claude/Protocols tuned to each Claude model's actual behaviorfable-5-1, opus-5-5, sonnet-5-5, haiku-5-5 (current) plus fable-5, opus-5, opus-4-8, sonnet-5, haiku-4-5 (previous gen), claude-all-models (fleet routing), opus-as-fable, hooks-enforcement (opt-in Claude Code hooks)
models/opencode/Open-weight fleet driven through OpenCodeopencode-all-models (routing), GLM, DeepSeek, Kimi, Qwen3-Coder, MiniMax, Devstral, MiMo, gpt-oss, local-small-models (≤32B self-hosted)
workflow/Session/process discipline, model-independentintent-capture → plan-first → interpretation-checkpoint → pre-merge-gate / pre-commit pipeline; plus handover, debug-protocol, session-budget, perf-audit, role-session (parallel sessions), e2e-scaffold
standards/Loads and enforces the coding-standards chain; audits a whole project against the script-checkable rules; sets comment volumecoding-standards, code-audit, comment-style (none / terse / descriptive — token-saving, asked at install)
memory/Persistent knowledge across sessionsmemory-bank (repo-committed context/decisions), memory-gardener (prunes/merges learnings)
stack/Technology-specific disciplinethreejs-scene (shaders, disposal, render hygiene), astro-page (convention-driven scaffolding)
libraries/The author's own librariesstrata-css, triforge
meta/Maintains the library itselfskill-writer (quality bar), install-kit (installer), skill-scope (pinned/archivable/addon classification), mod-writer and mod-setup (Claude Code mods), misfire-log (opt-in: logs when a skill/mod/addon should have fired but didn't, for the next kit update)
addons/Optional, user-opted capabilities — never installed by defaultsystem1-prefilter (typed-decision prefiltering; hosted endpoint or the free local Laya model, exposed as the prefilter MCP tool)
mcp/Optional MCP servers behind one meta skill — never installed by defaultmcp-manager (setup interview, global-first per-tool config, MCP-first-then-fallback) + one companion per server: stitch, local-vision, image-gen

coding-standards/ — the layered standards system

Full map: coding-standards/index.md

LayerWhat it isLocation
1 — Universal global rulesOne rule file per discipline, applies to every file of that typecss-standards.md, html-standards.md, and one script standard (js-, ts-, or js-and-ts-standards.md — never more than one per project)
2 — Universal file-role rulesPartials for each file role within a discipline (e.g. a CSS token file vs. an overlay file; a script's entry vs. orchestrator vs. controller file)matching {discipline}-standards/ subfolder
3 — Framework rulesExtends or explicitly overrides a universal rule (OVERRIDES [file] RULE [n])frameworks/ — currently Astro, Bootstrap, Strata CSS
Cross-cuttingCovers
git-standards.md, versioning-standards.mdCommit/branch/PR conventions, package versioning
seo-standards.md, accessibility-standards.md, performance-standards.mdSEO structure/schema; WCAG 2.1 AA; load/runtime performance budgets
qa/ (umbrella folder, not one file)Definition of done, branch gates, logic/error checks, security, E2E testing, bug reporting
ai-standards.mdThe AI behavioral contract — hallucination detection, [CX] context-integrity signal, read-efficiency rules — for every session regardless of tool
tooling/Lint configs that mechanically enforce whichever rules above are machine-checkable

Optional AI tools: free and local MCP servers for any coding agent

One setup interview (mcp-manager) wires any of these into Claude Code, OpenCode, or another MCP client. Models, runtimes, usage ledgers and keys live once in ~/.ai-dev-kit/ — never per project — and each tool falls back to your normal flow when it is missing, rate-limited, or out of quota.

ToolWhat the agent getsRunsCostVerified
stitchUI prototyping with Google Stitch (screens, variants, design systems) before any code is writtenhostedfree for now, limitedlive: generated a mobile screen and a Three.js 3D widget
local-visiondescribe_image — reads screenshots, diagrams and photos for models that cannot see (Qwen3-VL-2B via llama.cpp)local CPU/GPUfreereal OpenCode; ~7–12 s per image on an 8-core CPU
image-gengenerate_image for websites and apps: Gemini "Nano Banana" → Cloudflare Workers AI FLUX.1 schnell → labelled placeholderhostedCloudflare free tier ≈ 173 images/day; Gemini image models need billingreal OpenCode; live Cloudflare and Gemini quota paths
prefilterprefilter — the local Laya decision model ranks candidate files/tests before the agent reads them in fulllocalfreereal OpenCode; 1–3 s per call after a ~15–20 s first start

Built so a free tool can never become a trap. image-gen warns at 80% of a daily cap, switches provider at 90% (before anything fails or bills), pauses all generation until 00:00 UTC when every provider is exhausted, then serves clearly marked placeholders — and every switch, pause and placeholder is reported to you as a notice, in the tool output and in ~/.ai-dev-kit/image-gen/notices.log. Installers run a hardware preflight (CPU, RAM, disk, GPU) first, refuse installs the machine cannot hold, and pick CUDA/Vulkan/Metal builds only when the hardware warrants it, with automatic CPU fallback.

Honest status. Developed and tested on Windows 11 with an 8-core CPU and no discrete GPU. The CUDA, Metal, discrete-GPU Vulkan and Linux/macOS paths are implemented but untested. Model and API facts carry a verified: date and are re-checked live at setup. Credits and licences for every model and service (Qwen, llama.cpp, Laya, FLUX.1, Gemini, Stitch, placehold.co) are in CREDITS.md and each server file; nothing third-party is bundled in this repo.

Get started: install the kit, then tell your agent "set up MCP servers" — mcp-manager asks which tools, which AI clients, and where to keep keys, then writes the configs (merging, never overwriting) and health-checks each one.

Install into a project

  1. Copy skills/ — and coding-standards/ if the project should carry the standards — into the project root.
  2. Open Claude Code (or your AI coding tool) in that project and say:

read skills/README.md and install

  1. Choose everything, pick, auto-detect (scans the project and cites the signal before pinning anything), or a stack preset (name the stack directly — Astro, Next.js, Laravel — no scan needed). The installer detects which coding tool you're in, copies the chosen skills to that tool's skill root (.claude/skills/ for Claude Code, .opencode/skills/ for OpenCode), wires the standards into that tool's session file (CLAUDE.md or AGENTS.md respectively), mechanically re-verifies the result (install-kit.verify.js), and reports what was installed — or exactly what still needs fixing before it's reported done.

Details, including per-skill manual installs: skills/README.md → Installing into a new project.

Slash commands

Slash commands are shortcuts you type; the agent never runs them on its own. Anything typed after the name is passed to the command (/audit src/components). Most of the kit needs no command: the mods and git hooks fire by themselves, and skills load when the agent recognises their trigger. Reach for a command at the moments below. Type /kit in a session for this table.

Most useful commands

CommandUse it whenHow to use it
/commit-checkYou are about to commit/commit-check or /commit-check --message "feat: add nav". Reports secrets, secret files, stray files and message format; a BLOCK means do not commit.
/auditYou want a health check of the whole project/audit, /audit src/ or /audit --standard css,html. Prints counts per rule and the worst files.
/debug-protocolSomething fails and the cause is unknown/debug-protocol the build fails with a weird error. Forces reproduce first, one hypothesis, one change at a time.
/plan-firstThe task is big or touches many files/plan-first add dark mode and a language switcher. Gives a short file list and plan before any edit.
/quietA test or build run prints a wall of output/quiet npm test. Shortens the output, keeps every failure line, shows the exit code.
/handoverStarting or ending a session/handover. Resume from, or write, handover.md.
/token-reportThe session feels expensive/token-report or /token-report --last 3. Shows where the tokens went. Needs the ledger from the budget-ledger mod.
/etaA task is taking a while, or is backgrounded, and you want its time estimate without asking in prose/eta. Restates the current task's (and checkpoint's) time estimate — a judgment call, not a measurement; plan-first states it unprompted past 5 min or for background/parallel work.
/kitYou forget which command to use/kit prints this table; /kit my build keeps failing names the best command.

All commands

Kit commands (templates in skills/commands/; installed on request by install-kit into .claude/commands/ or .opencode/commands/; each runs a kit script and hands the output to the agent, so no skill has to be matched first):

CommandWhat it doesArgumentsNeeds
/auditStandards audit of the projectscript options: a path, --standard, --rule, --top Ncode-audit
/commit-checkMechanical pre-commit check of the staged change--message "…", --allpre-commit
/token-reportToken and cost report from the ledger--last N, --sid IDsession-budget
/quietRuns a command with shortened outputthe command, e.g. npm run buildsession-budget
/staleLists memory and handover bullets that name deleted files (report only)nonememory-gardener
/hooksShows git hook status and offers to install themnonepre-commit
/kitThis cheat sheetoptional: describe your situationnone
/etaRestates the active task's time estimate and checkpoint, no scriptnoneplan-first

Mod command (Claude Code, from the budget-ledger mod): /budget shows the same ledger report.

Skills by name (Claude Code turns every installed skill into /<skill-name> <free text>, which loads it on purpose instead of waiting for the agent to match it):

GroupCommandsUse when
Workflow/debug-protocol, /plan-first, /intent-capture, /interpretation-checkpoint, /handover, /pre-commit, /pre-merge-gate, /session-budget, /agent-usage, /mode-kernel, /perf-audit, /e2e-scaffold, /role-sessionthe situation in each skill's description
Standards/coding-standards, /code-audit, /comment-styleediting code, auditing, or changing comment level
Memory/memory-bank, /memory-gardener, /skill-ablationrecording decisions, pruning notes, testing which skills are still needed
Setup and authoring/install-kit, /mod-setup, /mod-writer, /skill-scope, /skill-writerinstalling the kit or mods, writing a skill or mod
Stack and tools/astro-page, /threejs-scene, /shopify-toolkit-install, /mcp-manager, /system1-prefilter, /strata-css, /triforgeworking in that stack or setting up that tool
Claude models/claude-all-models, /fable-5-1, /fable-5, /opus-5-5, /opus-5, /opus-4-8, /opus-as-fable, /sonnet-5-5, /sonnet-5, /haiku-5-5, /haiku-4-5, /hooks-enforcementchoosing or prompting a Claude model
OpenCode models/opencode-all-models, /big-pickle, /deepseek-v4, /devstral-2, /glm-5-2, /gpt-oss, /kimi-k2-6, /local-small-models, /mimo-v2-5, /minimax-m3, /qwen3-coderchoosing or prompting an open-weight model

Claude Code built-ins (not part of the kit): /help, /clear, /compact, /context, /model, /mcp, /plugin, /resume, /config, and bundled skills such as /code-review, /simplify, /security-review, /init, /loop and /schedule. /help lists what your version has.

Good to know

  • Tested: all seven script-backed kit commands ran in Claude Code (/audit was last re-checked at script level after its --no-fail change); /audit also runs in OpenCode. /eta is untested (new, no script to run headless) — it's a plain instruction template, same shape as /kit. Skills by name were checked for /debug-protocol in Claude Code only; whether OpenCode exposes skills the same way is not confirmed.
  • Free text vs options: kit commands pass what you type to a script, so give them options, not sentences (/audit focus on a11y prints "unknown option"). Skills by name take plain sentences.
  • /quiet vs the output-compact mod: same compaction engine. The mod does it automatically for every Bash and PowerShell call in Claude Code; /quiet is the manual version for OpenCode, Codex, or a project without the mod.
  • prefilter-rank mod: automates system1-prefilter's local-Laya narrowing after Grep/Glob (5-40 results) — adds a ranked read-order reminder, never removes a result. Loopback-only (127.0.0.1, checked in code, never the hosted-provider path), fails open if Laya isn't configured or reachable within a short timeout. Needs the addon's local-Laya path already set up; mod-setup won't offer it before that.
  • /budget vs /token-report: the same report; the mod owns /budget, so the kit's command has a different name to avoid a clash.
  • Always-on checks do not need a command: secrets, bad commit messages, destructive commands and standards violations are caught by the mods (Claude Code) and, if installed through /hooks, by git hooks (every tool).

Key ideas

  • Self-improving skills. Every skill reads a learnings.md sidecar at start and appends one distilled lesson at end. Learnings are per-project (never committed here, never copied by the installer) — each project's copies adapt to that project.
  • Adaptive to change. Skills that describe living things (Claude models, libraries, frameworks) carry staleness guards: verify against the live source, follow it over the skill text, log the correction.
  • Standards as law, gaps flagged. The standards system is declarative and testable; where it is silent, the AI flags the gap instead of inventing a rule (RULE AI-12).
  • Sequential by default, parallel when you say so. The role-session skill coordinates multiple parallel AI sessions — Claude Code, OpenCode, or both (role charters, atomic mkdir file claims, a git commit token, session ids) and switches itself off in projects without the parallel structure.
  • Token-lean by design. Skill descriptions are hard-capped, bodies stay under ~120 lines, read-efficiency rules are part of the standards, and the memory-gardener skill prunes accumulated knowledge.
  • Intent before implementation, a self-check before handoff. intent-capture pins down goal/constraints/done-when on ambiguous asks before any plan is made; pre-merge-gate re-checks a diff against the loaded standards before a commit or review handoff — both are prose protocols, not tool-specific.
  • Measured, not promised. Where a claim has a number, the number and its sample size are stated: Haiku 5.5 running a written plan cost $0.049 against $0.581 for Sonnet 5.5 on six test plans (both passed all six); the audit script found the same lines as a model-led audit in 0.2 s with no tokens, where the model cost $0.026 and missed one file (one project, three rules); the output compactor shrank a verbose passing test log by 59% and failure output by about 0%. These are small samples from the author's own projects: indicative, not guarantees.
  • Claude Code enhancements stay optional and isolated. Where a Claude Code-only mechanism (like hook-based enforcement in hooks-enforcement) can mechanically assist a rule, it lives under skills/models/claude/ as an opt-in add-on — the underlying contract in coding-standards/ai-standards.md works the same with or without it, on any tool.

Recent additions

  • Time estimates & checkpointing. plan-first now states a time estimate (as a range, not false precision) before any task estimated past 5 minutes, or anything backgrounded or part of a sequential/parallel chain, and designs that work into self-contained checkpoints (target ≤10 min, worst case ≤15, longer only when a step is genuinely unsplittable). The new /eta command restates the current estimate/checkpoint on demand without re-deriving it from scratch. The eta-nudge mod makes the reminder half deterministic instead of memory-dependent (nudges on a backgrounded call, and every 10 minutes past the first 5). The estimate itself stays the model's judgment call — nothing can mechanize that — but session-budget.report.js now surfaces each turn's real wall-clock duration (budget-ledger already logged it, just never read it back), so an estimate can finally be checked against what actually happened instead of staying pure vibes.
  • prefilter-rank mod. Automates system1-prefilter's local-Laya narrowing: ranks a Grep/Glob result (5-40 files) by relevance to the task and adds a read-order reminder, instead of requiring the agent to call the prefilter MCP tool itself every time. Task text comes from the session transcript's last user message ($.session.messages() — free, no model call). Loopback-only by a host check in code (never trusts SYSTEM1_BASE_URL alone), never the hosted-provider path (no-ops if SYSTEM1_API_KEY is set instead), fails open if Laya isn't reachable within a short timeout. mod-writer.md's "no network" rule now carries this one narrow, disclosed exception.
  • Install protocol, enforced. install-kit's Step 4 now runs install-kit.verify.js, a mechanical re-check of the actual files on disk (flat skill layout, the CommonJS package.json shield, the session-protocol file with its Context-code placeholder actually filled in, comment-style's level actually answered, coding-standards/index.md present) instead of trusting the agent's own narration — the install isn't reported done while it fails. A new Stack preset mode lets the user name a stack directly (Astro, Next.js, Laravel) instead of waiting on Auto-detect's scan; Next.js and Laravel presets install what the kit actually has and say plainly, in the report, which framework-specific layer doesn't exist yet rather than papering over the gap.
  • output-compact mod. Runs session-budget's compactor on every Bash/PowerShell result automatically, instead of depending on the agent remembering to pipe a command through it by hand. No-ops below the compactor's own savings floor, fails open, no network.
  • misfire-log. Opt-in
Source 1 files
hooks/register.ts 112 lines
1import type { Register } from 'claude-code'
2
3// Automatic half of system1-prefilter's local-Laya path: ranks a Grep/Glob result by relevance to the
4// task so the model can skip low-relevance files instead of reading all of them. Loopback-only, by a
5// host check in code (never trust SYSTEM1_BASE_URL alone) -- never the hosted provider path, never
6// starts Laya, never removes a result, only adds a reminder. Fails open on anything unexpected: a slow
7// or absent Laya costs nothing beyond its own short timeout, never blocks the Grep/Glob call itself.
8const MIN_CANDIDATES = 5
9const MAX_CANDIDATES = 40 // Laya's own batch cap (system1-prefilter.prefilter-mcp.js)
10const HEALTH_TIMEOUT_MS = 800
11const RANK_TIMEOUT_MS = 2000
12const CONFIDENCE_FLOOR = 0.7
13
14function timeout(ms: number): Promise<never> {
15  return new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), ms))
16}
17
18async function loopbackBase($: any): Promise<string | null> {
19  const key = await $.env.get('SYSTEM1_API_KEY')
20  if (key) return null // a hosted provider is configured instead -- never touch it from here
21  const base = await $.env.get('SYSTEM1_BASE_URL')
22  if (!base) return null
23  let url: URL
24  try { url = new URL(base) } catch { return null }
25  if (url.hostname !== '127.0.0.1' && url.hostname !== 'localhost') return null // host checked in code, not trusted from the env var
26  return base.replace(/\/+$/, '')
27}
28
29async function isUp($: any, base: string): Promise<boolean> {
30  try {
31    const r: any = await Promise.race([$.http.fetch(`${base}/health`), timeout(HEALTH_TIMEOUT_MS)])
32    return !!r.ok
33  } catch { return false }
34}
35
36// Mirrors ladder.js's fromLaya()+resolveBoolean() inline -- the hooks module has no Node, so ladder.js
37// cannot be required; this is the same handful of comparisons, not new logic.
38function rank(ids: string[], results: { answers: { q: { noul: number } } }[]) {
39  const toRead: string[] = []
40  const toReVerify: string[] = []
41  ids.forEach((id, i) => {
42    const noul = results[i]?.answers?.q?.noul
43    if (typeof noul !== 'number') return
44    const confidence = Math.max(noul, 1 - noul)
45    if (noul >= 0.5) toRead.push(id)
46    if (confidence < CONFIDENCE_FLOOR) toReVerify.push(id)
47  })
48  return { toRead, toReVerify }
49}
50
51async function lastUserTask($: any): Promise<string | null> {
52  try {
53    const messages = await $.session.messages()
54    if (!Array.isArray(messages)) return null
55    const last = [...messages].reverse().find((m: any) => m.role === 'user' && typeof m.text === 'string' && m.text.trim())
56    return last ? String(last.text).slice(0, 4000) : null
57  } catch { return null }
58}
59
60async function rankCandidates($: any, base: string, task: string, ids: string[]) {
61  const states = ids.map((id) => `Task: ${task}. Candidate file: ${id}`)
62  const questions = { q: { type: 'noul', instructions: 'Does the candidate file need to be read or changed to complete the task?' } }
63  const r: any = await Promise.race([
64    $.http.fetch(`${base}/v1/systemone/batch`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ states, questions }) }),
65    timeout(RANK_TIMEOUT_MS),
66  ])
67  if (!r.ok) return null
68  const parsed = JSON.parse(r.text)
69  if (!Array.isArray(parsed?.results)) return null
70  return parsed.results
71}
72
73function reminder(toRead: string[], toReVerify: string[], skipped: string[]) {
74  const lines = [`prefilter (local Laya): read first (${toRead.length}): ${toRead.join(', ') || 'none'}.`]
75  if (skipped.length) lines.push(`Lower relevance, skip unless they turn out needed (${skipped.length}): ${skipped.join(', ')}.`)
76  if (toReVerify.length) lines.push(`Low confidence either way -- don't trust this ranking for these, read/check directly: ${toReVerify.join(', ')}.`)
77  lines.push('Ranking only, not a security/correctness judgment -- never skip a file this would normally flag as relevant to a security/auth/payment check.')
78  return lines.join('\n')
79}
80
81export const register: Register = (on) => {
82  on('tool.call', { tool: ['Grep', 'Glob'] }, async ($, e, next) => {
83    const ran = await next(e)
84    try {
85      if ('deny' in ran && ran.deny) return ran
86      if ('isError' in ran && ran.isError) return ran
87      const result = 'result' in ran ? (ran.result as any) : null
88      const ids: string[] | undefined = result?.filenames
89      if (!Array.isArray(ids) || ids.length < MIN_CANDIDATES || ids.length > MAX_CANDIDATES) return ran
90
91      const base = await loopbackBase($)
92      if (!base) return ran
93      if (!(await isUp($, base))) return ran
94
95      const task = await lastUserTask($)
96      if (!task) return ran
97
98      const results = await rankCandidates($, base, task, ids)
99      if (!results || results.length !== ids.length) return ran
100
101      const { toRead, toReVerify } = rank(ids, results)
102      if (toRead.length === 0 || toRead.length === ids.length) return ran // nothing to narrow either way
103      const skipped = ids.filter((id) => !toRead.includes(id))
104
105      const prior = 'context' in ran && ran.context ? ran.context : []
106      return { ...ran, context: [...prior, reminder(toRead, toReVerify, skipped)] } as typeof ran
107    } catch {
108      return ran // a prefilter problem must never turn a good Grep/Glob result into an error, or block it
109    }
110  }).catch(($, e, next) => next(e))
111}
112