agent-economy 0.2.0 → 0.2.2

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/README.md CHANGED
@@ -12,6 +12,14 @@ ae doctor # detect rtk / billion-context / goal plugin
12
12
  ae packs # curated third-party rule/skill packs
13
13
  ```
14
14
 
15
+ ### Install with your agent (no terminal needed)
16
+
17
+ Paste this into opencode / Claude Code / Codex / Cursor — the agent does the rest:
18
+
19
+ > Install agent-economy: run `npx -y agent-economy@latest init --level standard --yes`, then `npx -y agent-economy@latest skill`, then `npx -y agent-economy@latest doctor`, and report the results. Don't ask clarifying questions; project scope.
20
+
21
+ After that, every future session discovers the `agent-economy-setup` skill and knows how to verify, re-configure, or extend the setup on its own.
22
+
15
23
  ## Why requests, not tokens
16
24
 
17
25
  Token-compression tools (billion-context, RTK, headroom) are plentiful. **Request-economy tooling does not exist** — yet per-request metering is what actually caps free-tier sessions (measured baseline: ~7 model requests per user message in a real opencode session). Batching 3 independent calls into 1 round saves 2 requests *and* 2 round-trips of latency, every time. No plugin can force batching — call count is decided at generation time — so the prompt is the only injection point. This project owns that injection point.
@@ -40,9 +48,19 @@ You can't police teammates' machines — you can police the repo:
40
48
  - run: npx agent-economy verify --min-level strict
41
49
  ```
42
50
 
43
- ## Packs (v0.2 roadmap)
51
+ ## Development
52
+
53
+ ```bash
54
+ npm test # hermetic node:test suite
55
+ git config core.hooksPath .githooks # pre-commit verify (one-time per clone)
56
+ node src/cli.js packs --check # curated specs vs upstream HEAD (weekly in CI)
57
+ ```
44
58
 
45
- Curated, attributed, pinned fetch-on-demand integrations — never vendored:
59
+ Releases: push a tag (`git tag vX.Y.Z && git push --tags`) — the `release` workflow runs the tests, then publishes to npm via **OIDC trusted publishing** (no token secret). One-time setup on npmjs.com: package → Settings → Trusted Publisher → `markymakes-dev/agent-economy` · workflow `release.yml`.
60
+
61
+ ## Packs
62
+
63
+ Curated, attributed, pinned fetch-on-demand integrations - never vendored:
46
64
 
47
65
  | Pack | Source | Kind |
48
66
  |---|---|---|
@@ -51,6 +69,12 @@ Curated, attributed, pinned fetch-on-demand integrations — never vendored:
51
69
  | `ecc-harness` | affaan-m/ECC | harness performance patterns |
52
70
  | `anthropic-skills` | anthropics/skills | official skills |
53
71
 
72
+ ```bash
73
+ ae packs --install ecc-harness # → ~/.claude/skills (override with --dir)
74
+ ```
75
+
76
+ RTK and billion-context are **runtime tools**, not packs — `ae packs` prints their setup commands, `ae inventory` shows whether they're alive. `ae` never installs them for you.
77
+
54
78
  ## Positioning
55
79
 
56
80
  Token compressors optimize **bytes**; this optimizes **round-trips**. Different unit, different layer, complementary stack. The dedicated AGENTS.md-template niche is empty (existing repos: 6–41★) while the adjacent skills ecosystem measures in six figures — the lane is open.
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "agent-economy",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "files": [
5
5
  "src",
6
6
  "packs",
7
+ "skills",
7
8
  "AGENTS.md",
8
9
  "README.md",
9
10
  "LICENSE"
@@ -14,6 +15,9 @@
14
15
  "ae": "src/cli.js",
15
16
  "economy": "src/cli.js"
16
17
  },
18
+ "scripts": {
19
+ "test": "node --test"
20
+ },
17
21
  "engines": {
18
22
  "node": ">=18"
19
23
  },
@@ -16,24 +16,59 @@
16
16
  "source": "mattpocock/skills",
17
17
  "ref": "main",
18
18
  "kind": "skills",
19
- "status": "planned",
20
- "note": "Matt Pocock's .agents directory — engineering skills for real codebases (install spec TBD)"
19
+ "status": "curated",
20
+ "install": [
21
+ { "from": "skills/engineering/tdd", "to": "tdd" },
22
+ { "from": "skills/engineering/code-review", "to": "code-review" },
23
+ { "from": "skills/engineering/diagnosing-bugs", "to": "diagnosing-bugs" },
24
+ { "from": "skills/engineering/codebase-design", "to": "codebase-design" },
25
+ { "from": "skills/engineering/pr", "to": "pr" },
26
+ { "from": "skills/productivity/writing-for-agents", "to": "writing-for-agents" }
27
+ ],
28
+ "note": "Curated subset of Matt Pocock's engineering skills (the full 66-skill collection is worth browsing; these are the evergreen ones)"
21
29
  },
22
30
  {
23
31
  "id": "ecc-harness",
24
32
  "source": "affaan-m/ECC",
25
33
  "ref": "main",
26
34
  "kind": "harness",
27
- "status": "planned",
28
- "note": "Agent-harness performance patterns: skills, instincts, memory, security (install spec TBD)"
35
+ "status": "curated",
36
+ "install": [
37
+ { "from": ".agents/skills/verification-loop", "to": "verification-loop" },
38
+ { "from": ".agents/skills/change-impact", "to": "change-impact" },
39
+ { "from": ".agents/skills/coding-standards", "to": "coding-standards" },
40
+ { "from": ".agents/skills/security-review", "to": "security-review" }
41
+ ],
42
+ "note": "Request-economy-relevant subset of ECC's harness skills. strategic-compact excluded: it pushes manual /compact at token thresholds, which conflicts with proxy-based compaction (billion-context) that owns the compaction lane. ECC-specific skills like ecc-conventions deliberately excluded"
29
43
  },
30
44
  {
31
45
  "id": "anthropic-skills",
32
46
  "source": "anthropics/skills",
33
47
  "ref": "main",
34
48
  "kind": "skills",
35
- "status": "planned",
36
- "note": "Official Anthropic agent skills (install spec TBD)"
49
+ "status": "curated",
50
+ "install": [
51
+ { "from": "skills/skill-creator", "to": "skill-creator" },
52
+ { "from": "skills/mcp-builder", "to": "mcp-builder" },
53
+ { "from": "skills/webapp-testing", "to": "webapp-testing" }
54
+ ],
55
+ "note": "Official Anthropic skills, agent-tooling subset (document skills docx/pdf/pptx/xlsx live in the same repo if you want them manually)"
56
+ },
57
+ {
58
+ "id": "rtk",
59
+ "source": "rtk-ai/rtk",
60
+ "kind": "tool",
61
+ "status": "stack",
62
+ "setup": "winget install rtk-ai.rtk · then: rtk init -g --opencode --hook-only --no-patch",
63
+ "note": "Command rewriter — cuts agent tool output at the source (100+ per-command filters, fail-open)"
64
+ },
65
+ {
66
+ "id": "billion-context",
67
+ "source": "ranxianglei/billion-context",
68
+ "kind": "tool",
69
+ "status": "stack",
70
+ "setup": "npm i -g billion-context · then: bili plugin install opencode",
71
+ "note": "Context-compression proxy for agent sessions — folds stale context out of every request"
37
72
  }
38
73
  ]
39
74
  }
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: agent-economy-setup
3
+ description: Install, verify, or configure agent-economy request-economy rules. Use when the user asks to install/set up agent-economy, wants the agent to save requests/quota/credits, mentions ae commands, or a CI check on agent-economy fails.
4
+ license: MIT
5
+ ---
6
+
7
+ # agent-economy setup
8
+
9
+ Free and metered agent tiers bill **per request** — every model round-trip costs one. agent-economy manages a battle-tested rule set as an idempotent, marker-bounded block in `AGENTS.md`, so agents batch, dedupe, and finish in fewer round-trips.
10
+
11
+ ## Commands
12
+
13
+ - `ae init [--level off|standard|strict] [--scope project|global|both] [--yes]` — install/update the rules block (interactive unless `--yes`)
14
+ - `ae verify [file] [--min-level standard|strict]` — check the block; exit 0 ok, 1 missing, 2 below level (this is the CI gate)
15
+ - `ae doctor` — detect companion tooling (rtk, billion-context, goal plugin)
16
+ - `ae inventory` — list the token-economy stack (with live health) + all loaded plugins/skills/MCP
17
+ - `ae packs` / `ae packs --install <id>` — curated third-party rule/skill packs (fetch-on-demand, attributed)
18
+ - `ae skill` — (re)install this skill
19
+
20
+ ## Installing for a user
21
+
22
+ 1. Run `npx -y agent-economy@latest init --level standard --yes` (project scope). Use `--level strict` when the user wants maximum savings; `--scope global` writes `~/.config/opencode/AGENTS.md`.
23
+ 2. Run `npx -y agent-economy@latest skill` so future sessions can manage the setup themselves.
24
+ 3. Run `npx -y agent-economy@latest doctor` and report the results.
25
+ 4. Optional: `npx -y agent-economy@latest packs --install karpathy-rules` (behavior rules). NEVER install stack tools (`rtk`, `billion-context`) without asking — they change runtime behavior, not content.
26
+
27
+ ## Guardrails
28
+
29
+ - The block between `<!-- agent-economy:start level=… -->` and `<!-- agent-economy:end -->` is MANAGED — never hand-edit it; change the level with `ae init --level <lvl>`.
30
+ - `ae init` is idempotent and backs up to `AGENTS.md.bak-<timestamp>` first.
31
+ - If a repo contains the block, run `ae verify --min-level strict` before committing.
32
+ - Levels: `standard` = batch + dedupe + filter output at source; `strict` = + assume-and-proceed, same-turn completion, no subagents for small lookups.
package/src/cli.js CHANGED
@@ -38,6 +38,16 @@ const startMarker = (lvl) => `<!-- agent-economy:start level=${lvl} -->`;
38
38
  const blockFor = (lvl) => [startMarker(lvl), "", HEADER, "", ...RULES[lvl], "", MARKER_END].join("\n");
39
39
  const globalFile = () => path.join(os.homedir(), ".config", "opencode", "AGENTS.md");
40
40
 
41
+ function skill(dir) {
42
+ const src = path.join(ROOT, "skills", "agent-economy-setup");
43
+ const target = path.resolve(dir || path.join(os.homedir(), ".claude", "skills", "agent-economy-setup"));
44
+ fs.rmSync(target, { recursive: true, force: true });
45
+ fs.mkdirSync(path.dirname(target), { recursive: true });
46
+ fs.cpSync(src, target, { recursive: true });
47
+ console.log(` ✔ agent-economy-setup skill → ${target}`);
48
+ console.log(" = agents discover it automatically (opencode picks it up without restart)");
49
+ }
50
+
41
51
  function upsert(file, level) {
42
52
  const exists = fs.existsSync(file);
43
53
  const prev = exists ? fs.readFileSync(file, "utf8") : "";
@@ -98,14 +108,25 @@ function doctor() {
98
108
 
99
109
  function packs() {
100
110
  const reg = JSON.parse(fs.readFileSync(path.join(ROOT, "packs", "registry.json"), "utf8"));
101
- console.log(" Curated packs (fetch-on-demand in v0.2; attribution + pinned refs):\n");
102
- for (const p of reg.packs) console.log(` ${p.id.padEnd(18)} ${p.source.padEnd(38)} [${p.status}] ${p.note}`);
111
+ console.log(" Curated packs (fetch-on-demand; attribution + pinned refs):\n");
112
+ for (const p of reg.packs.filter((p) => p.status !== "stack"))
113
+ console.log(` ${p.id.padEnd(18)} ${p.source.padEnd(38)} [${p.status}] ${p.note}`);
114
+ const tools = reg.packs.filter((p) => p.status === "stack");
115
+ if (tools.length) {
116
+ console.log("\n Stack tools (runtime — detected by `ae inventory`; ae never installs these):\n");
117
+ for (const p of tools) console.log(` ${p.id.padEnd(18)} ${p.source.padEnd(38)} setup: ${p.setup}`);
118
+ }
103
119
  }
104
120
 
105
121
  async function installPack(id, dir) {
106
122
  const reg = JSON.parse(fs.readFileSync(path.join(ROOT, "packs", "registry.json"), "utf8"));
107
123
  const p = reg.packs.find((x) => x.id === id);
108
124
  if (!p) { console.error(` ✘ unknown pack "${id}"`); process.exit(2); }
125
+ if (p.status === "stack") {
126
+ console.error(` ✘ "${id}" is a runtime tool, not a fetchable pack — ae never installs those.`);
127
+ console.error(` set it up directly: ${p.setup}`);
128
+ process.exit(2);
129
+ }
109
130
  if (!Array.isArray(p.install) || !p.install.length) {
110
131
  console.error(` ✘ pack "${id}" has no curated install spec yet (status: ${p.status})`);
111
132
  process.exit(2);
@@ -141,6 +162,34 @@ async function installPack(id, dir) {
141
162
  }
142
163
  }
143
164
 
165
+ async function checkPack(id) {
166
+ const reg = JSON.parse(fs.readFileSync(path.join(ROOT, "packs", "registry.json"), "utf8"));
167
+ const list = id ? reg.packs.filter((p) => p.id === id) : reg.packs.filter((p) => Array.isArray(p.install) && p.install.length);
168
+ if (!list.length) { console.error(id ? ` ✘ unknown pack "${id}"` : " = no installable packs"); process.exit(id ? 2 : 0); }
169
+ const work = fs.mkdtempSync(path.join(os.tmpdir(), "ae-check-"));
170
+ let bad = 0;
171
+ try {
172
+ for (const p of list) {
173
+ const url = `https://codeload.github.com/${p.source}/tar.gz/refs/heads/${p.ref || "main"}`;
174
+ console.log(` … ${p.id} (${p.source}@${p.ref || "main"})`);
175
+ const res = await fetch(url);
176
+ if (!res.ok) { console.log(` ✘ download failed: HTTP ${res.status}`); bad++; continue; }
177
+ const tgz = path.join(work, `${p.id}.tgz`);
178
+ fs.writeFileSync(tgz, Buffer.from(await res.arrayBuffer()));
179
+ const r = spawnSync("tar", ["-tzf", tgz], { encoding: "utf8", maxBuffer: 128 * 1024 * 1024 });
180
+ if (r.status !== 0) { console.log(" ✘ tar listing failed"); bad++; continue; }
181
+ const files = new Set(r.stdout.split(/\r?\n/).map((f) => f.replace(/^[^/]+\//, "")));
182
+ const missing = p.install.filter((s) => !files.has(`${s.from}/SKILL.md`));
183
+ if (missing.length) { for (const s of missing) console.log(` ✘ drift: ${s.from}/SKILL.md gone from upstream`); bad++; }
184
+ else console.log(` ✔ ${p.install.length}/${p.install.length} specs present`);
185
+ }
186
+ } finally {
187
+ fs.rmSync(work, { recursive: true, force: true });
188
+ }
189
+ console.log(bad ? ` ✘ ${bad} pack(s) drifted — update packs/registry.json` : " = all curated install specs match upstream HEAD");
190
+ process.exit(bad ? 1 : 0);
191
+ }
192
+
144
193
  function listDir(p, filter) {
145
194
  try { return fs.readdirSync(p, { withFileTypes: true }).filter((d) => filter(d, p)).map((d) => d.name); }
146
195
  catch { return []; }
@@ -234,6 +283,8 @@ const HELP = `
234
283
  packs List curated third-party rule/skill packs
235
284
  --install <id> [--dir <target>] fetch + install a curated pack
236
285
  (default target: ~/.claude/skills)
286
+ --check [id] validate install specs against upstream HEAD
287
+ skill Install the agent-economy-setup skill (teaches any agent to run ae)
237
288
  help This text
238
289
 
239
290
  Every model round-trip bills one request. Batch the independent ones.
@@ -281,8 +332,11 @@ async function main() {
281
332
  }
282
333
 
283
334
  if (cmd === "doctor") return doctor();
335
+ if (cmd === "skill") return skill(get("--dir"));
284
336
  if (cmd === "inventory") return inventory();
285
337
  if (cmd === "packs") {
338
+ const cid = get("--check");
339
+ if (hasFlag("--check")) return checkPack(cid && !cid.startsWith("--") ? cid : undefined);
286
340
  if (get("--install")) return installPack(get("--install"), get("--dir"));
287
341
  return packs();
288
342
  }