@xynogen/pix-optimizer 1.1.18 → 1.1.20

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.
@@ -1,203 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import {
3
- buildHelp,
4
- buildPrompt,
5
- LEVEL_NUMBERS,
6
- LEVELS,
7
- type Level,
8
- resolveLevel,
9
- STATUS_LABELS,
10
- STOP_ALIASES,
11
- toggleLevel,
12
- } from "./caveman.ts";
13
-
14
- // ── LEVELS ────────────────────────────────────────────────────────────────────
15
-
16
- describe("LEVELS", () => {
17
- it("contains off as first entry", () => {
18
- expect(LEVELS[0]).toBe("off");
19
- });
20
-
21
- it("contains all expected levels", () => {
22
- const expected: Level[] = ["off", "lite", "full", "ultra", "micro"];
23
- for (const l of expected) expect(LEVELS).toContain(l);
24
- });
25
- });
26
-
27
- // ── STOP_ALIASES ──────────────────────────────────────────────────────────────
28
-
29
- describe("STOP_ALIASES", () => {
30
- it("includes off, stop, quit", () => {
31
- expect(STOP_ALIASES.has("off")).toBe(true);
32
- expect(STOP_ALIASES.has("stop")).toBe(true);
33
- expect(STOP_ALIASES.has("quit")).toBe(true);
34
- });
35
-
36
- it("does not include active levels", () => {
37
- expect(STOP_ALIASES.has("full")).toBe(false);
38
- expect(STOP_ALIASES.has("ultra")).toBe(false);
39
- });
40
- });
41
-
42
- // ── STATUS_LABELS ─────────────────────────────────────────────────────────────
43
-
44
- describe("STATUS_LABELS", () => {
45
- it("has a label for every non-off level", () => {
46
- const nonOff = LEVELS.filter((l) => l !== "off") as Exclude<Level, "off">[];
47
- for (const l of nonOff) {
48
- expect(STATUS_LABELS[l]).toBeTruthy();
49
- }
50
- });
51
-
52
- it("latin levels are uppercase", () => {
53
- expect(STATUS_LABELS.lite).toBe("LITE");
54
- expect(STATUS_LABELS.full).toBe("FULL");
55
- expect(STATUS_LABELS.ultra).toBe("ULTRA");
56
- expect(STATUS_LABELS.micro).toBe("MICRO");
57
- });
58
- });
59
-
60
- // ── resolveLevel ──────────────────────────────────────────────────────────────
61
-
62
- describe("resolveLevel", () => {
63
- it("resolves valid levels", () => {
64
- expect(resolveLevel("lite")).toBe("lite");
65
- expect(resolveLevel("full")).toBe("full");
66
- expect(resolveLevel("ultra")).toBe("ultra");
67
- expect(resolveLevel("micro")).toBe("micro");
68
- expect(resolveLevel("off")).toBe("off");
69
- });
70
-
71
- it("maps stop aliases to off", () => {
72
- expect(resolveLevel("stop")).toBe("off");
73
- expect(resolveLevel("quit")).toBe("off");
74
- });
75
-
76
- it("is case-insensitive", () => {
77
- expect(resolveLevel("FULL")).toBe("full");
78
- expect(resolveLevel("Ultra")).toBe("ultra");
79
- expect(resolveLevel("STOP")).toBe("off");
80
- });
81
-
82
- it("trims whitespace", () => {
83
- expect(resolveLevel(" full ")).toBe("full");
84
- });
85
-
86
- it("returns null for unknown input", () => {
87
- expect(resolveLevel("unknown")).toBeNull();
88
- expect(resolveLevel("")).toBeNull();
89
- expect(resolveLevel("config")).toBeNull(); // config handled separately
90
- });
91
- });
92
-
93
- // ── numeric levels ────────────────────────────────────────────────────────────
94
-
95
- describe("numeric levels", () => {
96
- it("maps 1/2/3 to lite/full/ultra", () => {
97
- expect(resolveLevel("1")).toBe("lite");
98
- expect(resolveLevel("2")).toBe("full");
99
- expect(resolveLevel("3")).toBe("ultra");
100
- });
101
-
102
- it("maps 0 to off", () => {
103
- expect(resolveLevel("0")).toBe("off");
104
- });
105
-
106
- it("LEVEL_NUMBERS only covers 1-3", () => {
107
- expect(Object.keys(LEVEL_NUMBERS).sort()).toEqual(["1", "2", "3"]);
108
- });
109
-
110
- it("rejects out-of-range numbers", () => {
111
- expect(resolveLevel("4")).toBeNull();
112
- expect(resolveLevel("9")).toBeNull();
113
- });
114
-
115
- it("trims whitespace around numbers", () => {
116
- expect(resolveLevel(" 2 ")).toBe("full");
117
- });
118
- });
119
-
120
- // ── buildHelp ─────────────────────────────────────────────────────────────────
121
-
122
- describe("buildHelp", () => {
123
- it("lists numeric shortcuts", () => {
124
- const help = buildHelp("off");
125
- expect(help).toContain("1");
126
- expect(help).toContain("lite");
127
- expect(help).toContain("2");
128
- expect(help).toContain("full");
129
- expect(help).toContain("3");
130
- expect(help).toContain("ultra");
131
- });
132
-
133
- it("shows current level when active", () => {
134
- expect(buildHelp("ultra")).toContain("ULTRA");
135
- });
136
-
137
- it("shows off when disabled", () => {
138
- expect(buildHelp("off")).toContain("off");
139
- });
140
-
141
- it("mentions config", () => {
142
- expect(buildHelp("off")).toContain("config");
143
- });
144
-
145
- it("does not mention wenyan", () => {
146
- expect(buildHelp("off").toLowerCase()).not.toContain("wenyan");
147
- });
148
- });
149
-
150
- // ── toggleLevel ───────────────────────────────────────────────────────────────
151
-
152
- describe("toggleLevel", () => {
153
- it("off → full", () => {
154
- expect(toggleLevel("off")).toBe("full");
155
- });
156
-
157
- it("full → off", () => {
158
- expect(toggleLevel("full")).toBe("off");
159
- });
160
-
161
- it("any non-off level → off", () => {
162
- const nonOff = LEVELS.filter((l) => l !== "off") as Level[];
163
- for (const l of nonOff) {
164
- expect(toggleLevel(l)).toBe("off");
165
- }
166
- });
167
- });
168
-
169
- // ── buildPrompt ───────────────────────────────────────────────────────────────
170
-
171
- describe("buildPrompt", () => {
172
- it("returns empty string for off", () => {
173
- expect(buildPrompt("off")).toBe("");
174
- });
175
-
176
- it("returns MICRO_PROMPT for micro (no BASE)", () => {
177
- const p = buildPrompt("micro");
178
- expect(p).toContain("Token efficiency");
179
- expect(p).not.toContain("CAVEMAN MODE");
180
- });
181
-
182
- it("includes BASE for all standard levels", () => {
183
- const standard = ["lite", "full", "ultra"] as Level[];
184
- for (const l of standard) {
185
- expect(buildPrompt(l)).toContain("CAVEMAN MODE");
186
- }
187
- });
188
-
189
- it("includes SAFETY clause for all standard levels", () => {
190
- const standard = ["lite", "full", "ultra"] as Level[];
191
- for (const l of standard) {
192
- expect(buildPrompt(l)).toContain("Auto-clarity");
193
- }
194
- });
195
-
196
- it("each level has distinct intensity instructions", () => {
197
- const lite = buildPrompt("lite");
198
- const ultra = buildPrompt("ultra");
199
- expect(lite).toContain("Keep articles");
200
- expect(ultra).toContain("Abbreviate");
201
- expect(lite).not.toContain("Abbreviate");
202
- });
203
- });
package/src/json.test.ts DELETED
@@ -1,167 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import {
3
- adviseToon,
4
- isUniformObjectArray,
5
- JSON_SYSTEM_PROMPT,
6
- mentionsJson,
7
- objectDepth,
8
- } from "./json.ts";
9
-
10
- describe("JSON_SYSTEM_PROMPT", () => {
11
- it("mentions the jq + toon pipeline", () => {
12
- expect(JSON_SYSTEM_PROMPT).toContain("jq");
13
- expect(JSON_SYSTEM_PROMPT).toContain("toon");
14
- });
15
-
16
- it("teaches both encode and decode directions", () => {
17
- expect(JSON_SYSTEM_PROMPT).toContain("toon -d");
18
- });
19
-
20
- it("warns to keep JSON for API contracts", () => {
21
- expect(JSON_SYSTEM_PROMPT.toLowerCase()).toContain("contract");
22
- });
23
-
24
- it("references the toon-json skill", () => {
25
- expect(JSON_SYSTEM_PROMPT).toContain("toon-json");
26
- });
27
- });
28
-
29
- describe("mentionsJson (injection gate)", () => {
30
- it("matches json in any case", () => {
31
- expect(mentionsJson("parse this JSON")).toBe(true);
32
- expect(mentionsJson("a Json file")).toBe(true);
33
- expect(mentionsJson("json blob")).toBe(true);
34
- });
35
-
36
- it("matches related tokens", () => {
37
- expect(mentionsJson("pipe through jq")).toBe(true);
38
- expect(mentionsJson("convert to toon")).toBe(true);
39
- expect(mentionsJson("a .jsonl dataset")).toBe(true);
40
- expect(mentionsJson("the openapi spec")).toBe(true);
41
- expect(mentionsJson("swagger doc")).toBe(true);
42
- expect(mentionsJson("some js object")).toBe(true);
43
- });
44
-
45
- it("does not match unrelated prompts", () => {
46
- expect(mentionsJson("refactor the auth module")).toBe(false);
47
- expect(mentionsJson("fix the bug")).toBe(false);
48
- });
49
-
50
- it("is word-bounded (no false positives inside words)", () => {
51
- expect(mentionsJson("adjust the layout")).toBe(false); // contains 'js'
52
- expect(mentionsJson("a jsx component")).toBe(false); // jsx != js
53
- expect(mentionsJson("jsonify is a typo")).toBe(false); // jsonify != json
54
- });
55
-
56
- it("handles empty / nullish input", () => {
57
- expect(mentionsJson("")).toBe(false);
58
- expect(mentionsJson(undefined)).toBe(false);
59
- expect(mentionsJson(null)).toBe(false);
60
- });
61
- });
62
-
63
- describe("isUniformObjectArray", () => {
64
- it("true for same-keyed flat objects", () => {
65
- expect(
66
- isUniformObjectArray([
67
- { id: 1, name: "a" },
68
- { id: 2, name: "b" },
69
- ]),
70
- ).toBe(true);
71
- });
72
-
73
- it("false for differing keys", () => {
74
- expect(isUniformObjectArray([{ id: 1 }, { id: 2, extra: true }])).toBe(false);
75
- });
76
-
77
- it("false when a value is itself an object", () => {
78
- expect(
79
- isUniformObjectArray([
80
- { id: 1, meta: { x: 1 } },
81
- { id: 2, meta: { x: 2 } },
82
- ]),
83
- ).toBe(false);
84
- });
85
-
86
- it("false for empty array", () => {
87
- expect(isUniformObjectArray([])).toBe(false);
88
- });
89
-
90
- it("false for array of primitives", () => {
91
- expect(isUniformObjectArray([1, 2, 3])).toBe(false);
92
- });
93
- });
94
-
95
- describe("objectDepth", () => {
96
- it("primitive is depth 0", () => {
97
- expect(objectDepth(42)).toBe(0);
98
- expect(objectDepth("x")).toBe(0);
99
- });
100
-
101
- it("flat object is depth 1", () => {
102
- expect(objectDepth({ a: 1, b: 2 })).toBe(1);
103
- });
104
-
105
- it("nested object counts each level", () => {
106
- expect(objectDepth({ a: { b: { c: 1 } } })).toBe(3);
107
- });
108
-
109
- it("array nesting counts too", () => {
110
- expect(objectDepth([{ a: [1, 2] }])).toBe(3);
111
- });
112
- });
113
-
114
- describe("adviseToon", () => {
115
- it("recommends TOON for uniform object arrays (sweet spot)", () => {
116
- const advice = adviseToon([
117
- { id: 1, role: "admin" },
118
- { id: 2, role: "user" },
119
- ]);
120
- expect(advice.useToon).toBe(true);
121
- expect(advice.reason).toContain("tabular");
122
- });
123
-
124
- it("recommends TOON for primitive arrays", () => {
125
- expect(adviseToon([1, 2, 3]).useToon).toBe(true);
126
- });
127
-
128
- it("recommends TOON for shallow objects", () => {
129
- expect(adviseToon({ a: 1, b: 2 }).useToon).toBe(true);
130
- });
131
-
132
- it("rejects array of arrays (TOON's worse case)", () => {
133
- const advice = adviseToon([
134
- [1, 2],
135
- [3, 4],
136
- ]);
137
- expect(advice.useToon).toBe(false);
138
- expect(advice.reason).toContain("array of arrays");
139
- });
140
-
141
- it("rejects empty array", () => {
142
- expect(adviseToon([]).useToon).toBe(false);
143
- });
144
-
145
- it("rejects deeply nested objects beyond maxDepth", () => {
146
- const deep = { a: { b: { c: { d: { e: 1 } } } } }; // depth 5
147
- const advice = adviseToon(deep, 4);
148
- expect(advice.useToon).toBe(false);
149
- expect(advice.reason).toContain("depth");
150
- });
151
-
152
- it("rejects non-uniform object arrays", () => {
153
- const advice = adviseToon([{ id: 1 }, { id: 2, extra: true }]);
154
- expect(advice.useToon).toBe(false);
155
- });
156
-
157
- it("rejects primitive scalars", () => {
158
- expect(adviseToon(42).useToon).toBe(false);
159
- expect(adviseToon("hi").useToon).toBe(false);
160
- });
161
-
162
- it("honours a custom maxDepth", () => {
163
- const d2 = { a: { b: 1 } }; // depth 2
164
- expect(adviseToon(d2, 1).useToon).toBe(false);
165
- expect(adviseToon(d2, 2).useToon).toBe(true);
166
- });
167
- });
package/src/opt.test.ts DELETED
@@ -1,56 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { buildOptHelp, levelBar } from "./opt.ts";
3
- import type { OptimizerHandle, OptimizerTool } from "./status.ts";
4
-
5
- /** Build a handle set with fixed current values + value lists. */
6
- function fakeHandles(): Record<OptimizerTool, OptimizerHandle> {
7
- const mk = (name: OptimizerTool, current: string, values: string[]): OptimizerHandle => ({
8
- name,
9
- help: `${name} — ${name} help`,
10
- values,
11
- current: () => current,
12
- run: () => {},
13
- });
14
- return {
15
- caveman: mk("caveman", "full", ["off", "lite", "full", "ultra", "micro"]),
16
- rtk: mk("rtk", "on", ["off", "on"]),
17
- toon: mk("toon", "off", ["off", "on"]),
18
- ponytail: mk("ponytail", "off", ["off", "lite", "full", "ultra"]),
19
- };
20
- }
21
-
22
- describe("levelBar", () => {
23
- const PONYTAIL = ["off", "lite", "full", "ultra"];
24
- const BINARY = ["off", "on"];
25
-
26
- it("fills segments by value position in a multi-step ladder", () => {
27
- expect(levelBar("off", PONYTAIL)).toBe("▱▱▱");
28
- expect(levelBar("lite", PONYTAIL)).toBe("▰▱▱");
29
- expect(levelBar("full", PONYTAIL)).toBe("▰▰▱");
30
- expect(levelBar("ultra", PONYTAIL)).toBe("▰▰▰");
31
- });
32
-
33
- it("renders a single segment for binary tools", () => {
34
- expect(levelBar("off", BINARY)).toBe("▱");
35
- expect(levelBar("on", BINARY)).toBe("▰");
36
- });
37
-
38
- it("treats an unknown value as off (no fill)", () => {
39
- expect(levelBar("???", PONYTAIL)).toBe("▱▱▱");
40
- });
41
-
42
- it("returns empty string when there are no non-off steps", () => {
43
- expect(levelBar("off", ["off"])).toBe("");
44
- });
45
- });
46
-
47
- describe("buildOptHelp", () => {
48
- it("lists every tool with its current value", () => {
49
- const help = buildOptHelp(fakeHandles());
50
- expect(help).toContain("caveman: full");
51
- expect(help).toContain("rtk: on");
52
- expect(help).toContain("toon: off");
53
- expect(help).toContain("ponytail: off");
54
- expect(help).toContain("caveman help");
55
- });
56
- });
@@ -1,56 +0,0 @@
1
- /**
2
- * Regression test for the cross-session reset bug: optimizer tool states
3
- * (caveman/ponytail/rtk/toon) were lost on a full quit/restart because they
4
- * only persisted to the session log. persist.ts adds disk persistence so a
5
- * value written in one session is readable in the next.
6
- */
7
-
8
- import { afterAll, beforeAll, describe, expect, test } from "bun:test";
9
- import { mkdtempSync, rmSync } from "node:fs";
10
- import { tmpdir } from "node:os";
11
- import { join } from "node:path";
12
- import { loadOptValue, saveOptValue } from "./persist.ts";
13
-
14
- let tmpAgentDir: string;
15
-
16
- beforeAll(() => {
17
- tmpAgentDir = mkdtempSync(join(tmpdir(), "optimizer-persist-test-"));
18
- process.env.PI_CODING_AGENT_DIR = tmpAgentDir;
19
- });
20
-
21
- afterAll(() => {
22
- delete process.env.PI_CODING_AGENT_DIR;
23
- try {
24
- rmSync(tmpAgentDir, { recursive: true });
25
- } catch {
26
- // temp dir may already be gone — safe to ignore
27
- }
28
- });
29
-
30
- describe("optimizer persistence", () => {
31
- test("returns undefined before anything is saved", () => {
32
- expect(loadOptValue("caveman")).toBeUndefined();
33
- });
34
-
35
- test("round-trips a single tool value across save/load (new-session sim)", () => {
36
- saveOptValue("caveman", "lite");
37
- // A fresh load (as a new session would do) sees the persisted value.
38
- expect(loadOptValue("caveman")).toBe("lite");
39
- });
40
-
41
- test("persists each tool independently in one shared file", () => {
42
- saveOptValue("ponytail", "full");
43
- saveOptValue("rtk", "off");
44
- saveOptValue("toon", "on");
45
- expect(loadOptValue("caveman")).toBe("lite");
46
- expect(loadOptValue("ponytail")).toBe("full");
47
- expect(loadOptValue("rtk")).toBe("off");
48
- expect(loadOptValue("toon")).toBe("on");
49
- });
50
-
51
- test("overwriting one tool leaves the others intact", () => {
52
- saveOptValue("caveman", "ultra");
53
- expect(loadOptValue("caveman")).toBe("ultra");
54
- expect(loadOptValue("ponytail")).toBe("full");
55
- });
56
- });
@@ -1,195 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import {
3
- buildHelp,
4
- buildPrompt,
5
- LEVEL_NUMBERS,
6
- LEVELS,
7
- type Level,
8
- resolveLevel,
9
- STATUS_LABELS,
10
- STOP_ALIASES,
11
- toggleLevel,
12
- } from "./ponytail.ts";
13
-
14
- // ── LEVELS ────────────────────────────────────────────────────────────────────
15
-
16
- describe("LEVELS", () => {
17
- it("contains off as first entry", () => {
18
- expect(LEVELS[0]).toBe("off");
19
- });
20
-
21
- it("contains all expected levels", () => {
22
- const expected: Level[] = ["off", "lite", "full", "ultra"];
23
- for (const l of expected) expect(LEVELS).toContain(l);
24
- });
25
-
26
- it("has no micro level (caveman-only)", () => {
27
- expect(LEVELS).not.toContain("micro" as Level);
28
- });
29
- });
30
-
31
- // ── STOP_ALIASES ──────────────────────────────────────────────────────────────
32
-
33
- describe("STOP_ALIASES", () => {
34
- it("includes off, stop, quit", () => {
35
- expect(STOP_ALIASES.has("off")).toBe(true);
36
- expect(STOP_ALIASES.has("stop")).toBe(true);
37
- expect(STOP_ALIASES.has("quit")).toBe(true);
38
- });
39
-
40
- it("does not include active levels", () => {
41
- expect(STOP_ALIASES.has("full")).toBe(false);
42
- expect(STOP_ALIASES.has("ultra")).toBe(false);
43
- });
44
- });
45
-
46
- // ── STATUS_LABELS ─────────────────────────────────────────────────────────────
47
-
48
- describe("STATUS_LABELS", () => {
49
- it("has a label for every non-off level", () => {
50
- const nonOff = LEVELS.filter((l) => l !== "off") as Exclude<Level, "off">[];
51
- for (const l of nonOff) {
52
- expect(STATUS_LABELS[l]).toBeTruthy();
53
- }
54
- });
55
-
56
- it("levels are uppercase", () => {
57
- expect(STATUS_LABELS.lite).toBe("LITE");
58
- expect(STATUS_LABELS.full).toBe("FULL");
59
- expect(STATUS_LABELS.ultra).toBe("ULTRA");
60
- });
61
- });
62
-
63
- // ── resolveLevel ──────────────────────────────────────────────────────────────
64
-
65
- describe("resolveLevel", () => {
66
- it("resolves valid levels", () => {
67
- expect(resolveLevel("lite")).toBe("lite");
68
- expect(resolveLevel("full")).toBe("full");
69
- expect(resolveLevel("ultra")).toBe("ultra");
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
- expect(resolveLevel("micro")).toBeNull(); // no micro level
93
- });
94
- });
95
-
96
- // ── numeric levels ────────────────────────────────────────────────────────────
97
-
98
- describe("numeric levels", () => {
99
- it("maps 1/2/3 to lite/full/ultra", () => {
100
- expect(resolveLevel("1")).toBe("lite");
101
- expect(resolveLevel("2")).toBe("full");
102
- expect(resolveLevel("3")).toBe("ultra");
103
- });
104
-
105
- it("maps 0 to off", () => {
106
- expect(resolveLevel("0")).toBe("off");
107
- });
108
-
109
- it("LEVEL_NUMBERS only covers 1-3", () => {
110
- expect(Object.keys(LEVEL_NUMBERS).sort()).toEqual(["1", "2", "3"]);
111
- });
112
-
113
- it("rejects out-of-range numbers", () => {
114
- expect(resolveLevel("4")).toBeNull();
115
- expect(resolveLevel("9")).toBeNull();
116
- });
117
-
118
- it("trims whitespace around numbers", () => {
119
- expect(resolveLevel(" 2 ")).toBe("full");
120
- });
121
- });
122
-
123
- // ── buildHelp ─────────────────────────────────────────────────────────────────
124
-
125
- describe("buildHelp", () => {
126
- it("lists numeric shortcuts", () => {
127
- const help = buildHelp("off");
128
- expect(help).toContain("1");
129
- expect(help).toContain("lite");
130
- expect(help).toContain("2");
131
- expect(help).toContain("full");
132
- expect(help).toContain("3");
133
- expect(help).toContain("ultra");
134
- });
135
-
136
- it("shows current level when active", () => {
137
- expect(buildHelp("ultra")).toContain("ULTRA");
138
- });
139
-
140
- it("shows off when disabled", () => {
141
- expect(buildHelp("off")).toContain("off");
142
- });
143
-
144
- it("mentions config", () => {
145
- expect(buildHelp("off")).toContain("config");
146
- });
147
- });
148
-
149
- // ── toggleLevel ───────────────────────────────────────────────────────────────
150
-
151
- describe("toggleLevel", () => {
152
- it("off → full", () => {
153
- expect(toggleLevel("off")).toBe("full");
154
- });
155
-
156
- it("full → off", () => {
157
- expect(toggleLevel("full")).toBe("off");
158
- });
159
-
160
- it("any non-off level → off", () => {
161
- const nonOff = LEVELS.filter((l) => l !== "off") as Level[];
162
- for (const l of nonOff) {
163
- expect(toggleLevel(l)).toBe("off");
164
- }
165
- });
166
- });
167
-
168
- // ── buildPrompt ───────────────────────────────────────────────────────────────
169
-
170
- describe("buildPrompt", () => {
171
- it("returns empty string for off", () => {
172
- expect(buildPrompt("off")).toBe("");
173
- });
174
-
175
- it("includes BASE ladder for all active levels", () => {
176
- for (const l of ["lite", "full", "ultra"] as Level[]) {
177
- expect(buildPrompt(l)).toContain("PONYTAIL MODE ACTIVE");
178
- expect(buildPrompt(l)).toContain("first rung that holds");
179
- }
180
- });
181
-
182
- it("includes SAFETY clause for all active levels", () => {
183
- for (const l of ["lite", "full", "ultra"] as Level[]) {
184
- expect(buildPrompt(l)).toContain("When NOT to be lazy");
185
- }
186
- });
187
-
188
- it("each level has distinct intensity instructions", () => {
189
- const lite = buildPrompt("lite");
190
- const ultra = buildPrompt("ultra");
191
- expect(lite).toContain("name the lazier alternative");
192
- expect(ultra).toContain("YAGNI extremist");
193
- expect(lite).not.toContain("YAGNI extremist");
194
- });
195
- });