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 +26 -2
- package/package.json +5 -1
- package/packs/registry.json +41 -6
- package/skills/agent-economy-setup/SKILL.md +32 -0
- package/src/cli.js +56 -2
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
|
-
##
|
|
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
|
-
|
|
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.
|
|
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
|
},
|
package/packs/registry.json
CHANGED
|
@@ -16,24 +16,59 @@
|
|
|
16
16
|
"source": "mattpocock/skills",
|
|
17
17
|
"ref": "main",
|
|
18
18
|
"kind": "skills",
|
|
19
|
-
"status": "
|
|
20
|
-
"
|
|
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": "
|
|
28
|
-
"
|
|
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": "
|
|
36
|
-
"
|
|
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
|
|
102
|
-
for (const p of reg.packs
|
|
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
|
}
|