@xynogen/pix-optimizer 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 xynogen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # pix-optimizer
2
+
3
+ Token-optimization suite for Pi Coding Agent. Three tools wired into one
4
+ extension via `src/index.ts`, fronted by a single `/opt` command and one
5
+ shared status-bar cell:
6
+
7
+ - **Caveman** (`⛏`) — terse-output system prompt
8
+ - **RTK** (`⚔`) — prefixes shell commands with `rtk` + injects RTK prompt
9
+ - **TOON** (`✂`) — jq + TOON guidance for dense JSON (+ bundled skill)
10
+
11
+ ## Command
12
+
13
+ One command routes to every tool:
14
+
15
+ ```text
16
+ /opt → status + help
17
+ /opt caveman <level> → set caveman level (1/2/3/lite/full/ultra/micro/off/config)
18
+ /opt rtk [on|off] → toggle RTK rewriting
19
+ /opt toon [on|off] → toggle jq+TOON guidance
20
+ ```
21
+
22
+ ## Status bar
23
+
24
+ A single cell always shows all three icons in a fixed order (`⛏ ⚔ ✂`), color-
25
+ coded by state: **accent** when the tool is enabled, **dim** when disabled.
26
+
27
+ ## Features
28
+
29
+ ### Caveman Mode (`⛏`)
30
+
31
+ Cuts ~75% of output tokens while keeping full technical accuracy.
32
+
33
+ | # | Name | Description |
34
+ |---|-------|------------------------------|
35
+ | 1 | lite | Professional, no fluff |
36
+ | 2 | full | Classic caveman |
37
+ | 3 | ultra | Maximum compression |
38
+ | – | micro | Experimental prompt-minimized |
39
+
40
+ `/opt caveman config` opens a settings dialog. Default level for new sessions
41
+ and status-bar visibility are saved to `~/.pi/agent/caveman.json`.
42
+
43
+ ### RTK Tool Rewriting (`⚔`)
44
+
45
+ Two layers, both active automatically:
46
+
47
+ 1. **Prompt layer** — injects the RTK system prompt (tells the model to
48
+ prefix commands with `rtk`).
49
+ 2. **Execute layer** — rewrites `bash` tool calls, prefixing known commands
50
+ (`git`, `gh`, `cargo`, `npm`, `pnpm`, `docker`, `kubectl`, `ls`, `grep`, …)
51
+ with `rtk` when the model forgets. **Command chains are split on `&&`,
52
+ `||`, `;` and `|`, and every known segment is prefixed** — e.g.
53
+ `git add . && git push` becomes `rtk git add . && rtk git push`.
54
+ Operators inside quotes are ignored, and unparseable commands are left
55
+ untouched. Falls back gracefully when the `rtk` binary is missing
56
+ (warns once).
57
+
58
+ **Requirement:** the `rtk` binary must be on `PATH`.
59
+
60
+ ```bash
61
+ cargo install rtk-ai
62
+ ```
63
+
64
+ ### TOON / JSON Compression (`✂`)
65
+
66
+ Guidance + a bundled `toon-json` skill for handling information-dense JSON via
67
+ `jq` (query/reshape) and `toon` (compress). The system-prompt nudge is injected
68
+ **only when the user prompt mentions JSON** (`json`/`jsonl`/`jq`/`toon`/
69
+ `openapi`/…). TOON shines on uniform/tabular arrays; deeply nested or
70
+ array-of-arrays data and API contracts stay as JSON.
71
+
72
+ **Requirement:** `jq` and `toon` on `PATH`.
73
+
74
+ ```bash
75
+ npm i -g @toon-format/cli
76
+ ```
77
+
78
+ ## Installation
79
+
80
+ ```bash
81
+ pi install git:github.com/xynogen/pix-optimizer
82
+ ```
83
+
84
+ ## Architecture
85
+
86
+ | File | Role |
87
+ |-------------------|-----------------------------------------------------------|
88
+ | `src/index.ts` | Wires the three tools + shared status, registers `/opt` |
89
+ | `src/opt.ts` | The `/opt` router: parse, complete, dispatch |
90
+ | `src/status.ts` | Shared status-bar cell + `OptimizerHandle` contract |
91
+ | `src/caveman.ts` | Caveman logic, levels, prompt, settings dialog |
92
+ | `src/rtk.ts` | RTK prompt + bash command rewriting |
93
+ | `src/json.ts` | jq+TOON guidance, heuristics, bundled skill registration |
94
+
95
+ Each tool registers its own lifecycle hooks and exposes an `OptimizerHandle`
96
+ that `/opt` dispatches to. All three share one `OptimizerStatus`.
97
+
98
+ ## Development
99
+
100
+ ```bash
101
+ bun test
102
+ ```
103
+
104
+ ## License
105
+
106
+ MIT
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@xynogen/pix-optimizer",
3
+ "version": "1.0.0",
4
+ "description": "Performance optimization suite for Pi Coding Agent - caveman mode + RTK tool rewriting + jq/TOON JSON compression",
5
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "scripts": {
8
+ "test": "bun test"
9
+ },
10
+ "files": [
11
+ "src",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "pi": {
16
+ "extensions": ["./src/index.ts"]
17
+ },
18
+ "keywords": [
19
+ "pi",
20
+ "pi-package",
21
+ "pi-extension",
22
+ "optimizer",
23
+ "caveman",
24
+ "rtk",
25
+ "toon",
26
+ "jq",
27
+ "json",
28
+ "performance"
29
+ ],
30
+ "author": "xynogen",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/xynogen/pix-mono.git",
35
+ "directory": "packages/pix-optimizer"
36
+ },
37
+ "homepage": "https://github.com/xynogen/pix-mono/tree/main/packages/pix-optimizer#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/xynogen/pix-mono/issues"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "peerDependencies": {
45
+ "@earendil-works/pi-coding-agent": "*",
46
+ "@earendil-works/pi-tui": "*"
47
+ }
48
+ }
@@ -0,0 +1,239 @@
1
+ import { describe, it, expect } from "bun:test";
2
+ import {
3
+ LEVELS,
4
+ LEVEL_NUMBERS,
5
+ STOP_ALIASES,
6
+ STATUS_LABELS,
7
+ buildPrompt,
8
+ buildHelp,
9
+ resolveLevel,
10
+ toggleLevel,
11
+ parseConfig,
12
+ DEFAULT_CONFIG,
13
+ type Level,
14
+ } from "./caveman.ts";
15
+
16
+ // ── LEVELS ────────────────────────────────────────────────────────────────────
17
+
18
+ describe("LEVELS", () => {
19
+ it("contains off as first entry", () => {
20
+ expect(LEVELS[0]).toBe("off");
21
+ });
22
+
23
+ it("contains all expected levels", () => {
24
+ const expected = ["off", "lite", "full", "ultra", "micro"];
25
+ for (const l of expected) expect(LEVELS).toContain(l);
26
+ });
27
+ });
28
+
29
+ // ── STOP_ALIASES ──────────────────────────────────────────────────────────────
30
+
31
+ describe("STOP_ALIASES", () => {
32
+ it("includes off, stop, quit", () => {
33
+ expect(STOP_ALIASES.has("off")).toBe(true);
34
+ expect(STOP_ALIASES.has("stop")).toBe(true);
35
+ expect(STOP_ALIASES.has("quit")).toBe(true);
36
+ });
37
+
38
+ it("does not include active levels", () => {
39
+ expect(STOP_ALIASES.has("full")).toBe(false);
40
+ expect(STOP_ALIASES.has("ultra")).toBe(false);
41
+ });
42
+ });
43
+
44
+ // ── STATUS_LABELS ─────────────────────────────────────────────────────────────
45
+
46
+ describe("STATUS_LABELS", () => {
47
+ it("has a label for every non-off level", () => {
48
+ const nonOff = LEVELS.filter((l) => l !== "off") as Exclude<Level, "off">[];
49
+ for (const l of nonOff) {
50
+ expect(STATUS_LABELS[l]).toBeTruthy();
51
+ }
52
+ });
53
+
54
+ it("latin levels are uppercase", () => {
55
+ expect(STATUS_LABELS["lite"]).toBe("LITE");
56
+ expect(STATUS_LABELS["full"]).toBe("FULL");
57
+ expect(STATUS_LABELS["ultra"]).toBe("ULTRA");
58
+ expect(STATUS_LABELS["micro"]).toBe("MICRO");
59
+ });
60
+ });
61
+
62
+ // ── resolveLevel ──────────────────────────────────────────────────────────────
63
+
64
+ describe("resolveLevel", () => {
65
+ it("resolves valid levels", () => {
66
+ expect(resolveLevel("lite")).toBe("lite");
67
+ expect(resolveLevel("full")).toBe("full");
68
+ expect(resolveLevel("ultra")).toBe("ultra");
69
+ expect(resolveLevel("micro")).toBe("micro");
70
+ expect(resolveLevel("off")).toBe("off");
71
+ });
72
+
73
+ it("maps stop aliases to off", () => {
74
+ expect(resolveLevel("stop")).toBe("off");
75
+ expect(resolveLevel("quit")).toBe("off");
76
+ });
77
+
78
+ it("is case-insensitive", () => {
79
+ expect(resolveLevel("FULL")).toBe("full");
80
+ expect(resolveLevel("Ultra")).toBe("ultra");
81
+ expect(resolveLevel("STOP")).toBe("off");
82
+ });
83
+
84
+ it("trims whitespace", () => {
85
+ expect(resolveLevel(" full ")).toBe("full");
86
+ });
87
+
88
+ it("returns null for unknown input", () => {
89
+ expect(resolveLevel("unknown")).toBeNull();
90
+ expect(resolveLevel("")).toBeNull();
91
+ expect(resolveLevel("config")).toBeNull(); // config handled separately
92
+ });
93
+ });
94
+
95
+ // ── numeric levels ────────────────────────────────────────────────────────────
96
+
97
+ describe("numeric levels", () => {
98
+ it("maps 1/2/3 to lite/full/ultra", () => {
99
+ expect(resolveLevel("1")).toBe("lite");
100
+ expect(resolveLevel("2")).toBe("full");
101
+ expect(resolveLevel("3")).toBe("ultra");
102
+ });
103
+
104
+ it("maps 0 to off", () => {
105
+ expect(resolveLevel("0")).toBe("off");
106
+ });
107
+
108
+ it("LEVEL_NUMBERS only covers 1-3", () => {
109
+ expect(Object.keys(LEVEL_NUMBERS).sort()).toEqual(["1", "2", "3"]);
110
+ });
111
+
112
+ it("rejects out-of-range numbers", () => {
113
+ expect(resolveLevel("4")).toBeNull();
114
+ expect(resolveLevel("9")).toBeNull();
115
+ });
116
+
117
+ it("trims whitespace around numbers", () => {
118
+ expect(resolveLevel(" 2 ")).toBe("full");
119
+ });
120
+ });
121
+
122
+ // ── buildHelp ─────────────────────────────────────────────────────────────────
123
+
124
+ describe("buildHelp", () => {
125
+ it("lists numeric shortcuts", () => {
126
+ const help = buildHelp("off");
127
+ expect(help).toContain("1");
128
+ expect(help).toContain("lite");
129
+ expect(help).toContain("2");
130
+ expect(help).toContain("full");
131
+ expect(help).toContain("3");
132
+ expect(help).toContain("ultra");
133
+ });
134
+
135
+ it("shows current level when active", () => {
136
+ expect(buildHelp("ultra")).toContain("ULTRA");
137
+ });
138
+
139
+ it("shows off when disabled", () => {
140
+ expect(buildHelp("off")).toContain("off");
141
+ });
142
+
143
+ it("mentions config", () => {
144
+ expect(buildHelp("off")).toContain("config");
145
+ });
146
+
147
+ it("does not mention wenyan", () => {
148
+ expect(buildHelp("off").toLowerCase()).not.toContain("wenyan");
149
+ });
150
+ });
151
+
152
+ // ── toggleLevel ───────────────────────────────────────────────────────────────
153
+
154
+ describe("toggleLevel", () => {
155
+ it("off → full", () => {
156
+ expect(toggleLevel("off")).toBe("full");
157
+ });
158
+
159
+ it("full → off", () => {
160
+ expect(toggleLevel("full")).toBe("off");
161
+ });
162
+
163
+ it("any non-off level → off", () => {
164
+ const nonOff = LEVELS.filter((l) => l !== "off") as Level[];
165
+ for (const l of nonOff) {
166
+ expect(toggleLevel(l)).toBe("off");
167
+ }
168
+ });
169
+ });
170
+
171
+ // ── buildPrompt ───────────────────────────────────────────────────────────────
172
+
173
+ describe("buildPrompt", () => {
174
+ it("returns empty string for off", () => {
175
+ expect(buildPrompt("off")).toBe("");
176
+ });
177
+
178
+ it("returns MICRO_PROMPT for micro (no BASE)", () => {
179
+ const p = buildPrompt("micro");
180
+ expect(p).toContain("Token efficiency");
181
+ expect(p).not.toContain("CAVEMAN MODE");
182
+ });
183
+
184
+ it("includes BASE for all standard levels", () => {
185
+ const standard = ["lite", "full", "ultra"] as Level[];
186
+ for (const l of standard) {
187
+ expect(buildPrompt(l)).toContain("CAVEMAN MODE");
188
+ }
189
+ });
190
+
191
+ it("includes SAFETY clause for all standard levels", () => {
192
+ const standard = ["lite", "full", "ultra"] as Level[];
193
+ for (const l of standard) {
194
+ expect(buildPrompt(l)).toContain("Auto-clarity");
195
+ }
196
+ });
197
+
198
+ it("each level has distinct intensity instructions", () => {
199
+ const lite = buildPrompt("lite");
200
+ const ultra = buildPrompt("ultra");
201
+ expect(lite).toContain("Keep articles");
202
+ expect(ultra).toContain("Abbreviate");
203
+ expect(lite).not.toContain("Abbreviate");
204
+ });
205
+
206
+ });
207
+
208
+ // ── parseConfig ───────────────────────────────────────────────────────────────
209
+
210
+ describe("parseConfig", () => {
211
+ it("parses valid config", () => {
212
+ const cfg = parseConfig({ defaultLevel: "ultra", showStatus: false });
213
+ expect(cfg.defaultLevel).toBe("ultra");
214
+ expect(cfg.showStatus).toBe(false);
215
+ });
216
+
217
+ it("falls back to defaults for invalid defaultLevel", () => {
218
+ const cfg = parseConfig({ defaultLevel: "invalid", showStatus: true });
219
+ expect(cfg.defaultLevel).toBe(DEFAULT_CONFIG.defaultLevel);
220
+ });
221
+
222
+ it("falls back to defaults for missing fields", () => {
223
+ const cfg = parseConfig({});
224
+ expect(cfg.defaultLevel).toBe(DEFAULT_CONFIG.defaultLevel);
225
+ expect(cfg.showStatus).toBe(DEFAULT_CONFIG.showStatus);
226
+ });
227
+
228
+ it("falls back to defaults for null/undefined", () => {
229
+ const cfg = parseConfig(null);
230
+ expect(cfg.defaultLevel).toBe(DEFAULT_CONFIG.defaultLevel);
231
+ expect(cfg.showStatus).toBe(DEFAULT_CONFIG.showStatus);
232
+ });
233
+
234
+ it("accepts all valid levels as defaultLevel", () => {
235
+ for (const l of LEVELS) {
236
+ expect(parseConfig({ defaultLevel: l, showStatus: true }).defaultLevel).toBe(l);
237
+ }
238
+ });
239
+ });