@xynogen/pix-optimizer 1.1.29 → 1.2.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/README.md +12 -8
- package/package.json +2 -2
- package/src/caveman.ts +54 -32
- package/src/mode.ts +7 -1
- package/src/persist.ts +4 -8
- package/src/ponytail.ts +39 -27
- package/src/rtk.ts +7 -1
package/README.md
CHANGED
|
@@ -49,14 +49,18 @@ Icons follow the **global** `pix-pretty` mode. Set it via `/pix` or the
|
|
|
49
49
|
|
|
50
50
|
### Caveman Mode (`Cv`)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
|
59
|
-
|
|
52
|
+
Makes replies follow [ASD-STE100 Simplified Technical English](https://asd-ste100.org).
|
|
53
|
+
Two layers: Layer 1 sets the words and sentences, Layer 2 sets the reply shape
|
|
54
|
+
(next action first, numbered steps, no preamble or closer). Both govern prose
|
|
55
|
+
only, not code or command syntax. Keeps the article, unlike the old
|
|
56
|
+
article-dropping caveman prompt.
|
|
57
|
+
|
|
58
|
+
| Level | Description |
|
|
59
|
+
|-------|-----------------------------------|
|
|
60
|
+
| lite | STE-flavored words, light shape |
|
|
61
|
+
| full | STE words + full reply shape |
|
|
62
|
+
| ultra | Strict STE + full reply shape |
|
|
63
|
+
| micro | Experimental prompt-minimized |
|
|
60
64
|
|
|
61
65
|
The `/optimizer` overlay opens a settings dialog when needed. Default level
|
|
62
66
|
for new sessions is restored from `~/.pi/agent/optimizer.json`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-optimizer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Performance optimization suite for Pi Coding Agent - caveman mode + RTK tool rewriting + ponytail lazy-dev mode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@xynogen/pix-pretty": "^1.
|
|
46
|
+
"@xynogen/pix-pretty": "^1.24.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@earendil-works/pi-coding-agent": "*",
|
package/src/caveman.ts
CHANGED
|
@@ -40,45 +40,67 @@ export const STATUS_LABELS: Record<Exclude<Level, "off">, string> = {
|
|
|
40
40
|
// ── Prompt fragments ──────────────────────────────────────────────────────────
|
|
41
41
|
|
|
42
42
|
const BASE = `\
|
|
43
|
-
IMPORTANT: You
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
43
|
+
IMPORTANT: You write in ASD-STE100 Simplified Technical English. Two layers stay on. \
|
|
44
|
+
Both layers govern prose only. They do not touch code, identifiers, or command syntax.
|
|
45
|
+
|
|
46
|
+
LAYER 1 — words and sentences:
|
|
47
|
+
- Use one name for one thing. Do not rotate check / verify / validate for the same action.
|
|
48
|
+
- Use the short common word: start (not initiate), use (not utilize), help (not facilitate), \
|
|
49
|
+
make sure (not ensure), do (not perform), give (not provide), before (not prior to), \
|
|
50
|
+
about (not regarding), get (not obtain), show (not demonstrate), also (not moreover).
|
|
51
|
+
- No marketing adjectives: seamless, robust, powerful, cutting-edge, effortless.
|
|
52
|
+
- Use the active voice. Write "the parser reads the file", not "the file is read by the parser".
|
|
53
|
+
- Use simple tenses only. Write "we received the report", not "we have received the report".
|
|
54
|
+
- Use a verb for an action. Write "analyze the log", not "perform an analysis of the log".
|
|
55
|
+
- No phrasal verbs: spin up, dive into, kick off, roll out.
|
|
56
|
+
- One instruction per sentence. Max 20 words for an instruction, max 25 words for other text.
|
|
57
|
+
- Keep the article (a, an, the). Do not drop words to compress.
|
|
58
|
+
- No semicolons. Write two sentences.
|
|
59
|
+
|
|
60
|
+
LAYER 2 — reply shape:
|
|
61
|
+
- Lead with the next action. The first line is a command, a path, or a snippet the reader can do now.
|
|
62
|
+
- Number a multi-step task. One bounded action per step.
|
|
63
|
+
- No preamble, no recap, no closer. Start with the answer. Stop when the answer is done.
|
|
64
|
+
- Cap an action list at five items. Split into "do now" and "later" past five.
|
|
65
|
+
- Give an estimate in concrete units (minutes, hours, days). Do not write "some work".
|
|
66
|
+
- Restate the state of multi-turn work. Write "step 3 of 5 done".
|
|
67
|
+
- Stay matter-of-fact about an error. Give the cause and the fix.
|
|
68
|
+
|
|
69
|
+
Bad: "Sure! I'd be happy to help. The issue you are experiencing is likely caused by..."
|
|
70
|
+
Good: "Bug in the auth middleware. The token expiry check uses \`<\`, not \`<=\`. Fix:"`;
|
|
71
|
+
|
|
72
|
+
const MICRO_PROMPT = `# STE output
|
|
73
|
+
Write in Simplified Technical English. Use short common words, the active voice, and simple tenses.
|
|
74
|
+
- One instruction per sentence, max 20 words. Keep the article (a, an, the).
|
|
75
|
+
- No phrasal verbs, no semicolons, no marketing adjectives.
|
|
76
|
+
- Reply shape: lead with the next action (a command, a path, or a snippet). No preamble, no closer.
|
|
77
|
+
- Number a multi-step task. Give an estimate in concrete units.
|
|
78
|
+
- Preserve code, identifiers, and error strings exactly.`;
|
|
63
79
|
|
|
64
80
|
const INTENSITY: Record<Exclude<Level, "off" | "micro">, string> = {
|
|
65
81
|
lite: `\
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
STE-flavored words. Keep the sentence, tense, active-voice, and no-phrasal-verb discipline. \
|
|
83
|
+
Relax the strict dictionary. Apply Layer 2 lightly: lead with the answer, no preamble or closer.
|
|
84
|
+
Example: "The component re-renders because you create a new object reference each render. Wrap it in \`useMemo\`."`,
|
|
68
85
|
|
|
69
86
|
full: `\
|
|
70
|
-
|
|
71
|
-
|
|
87
|
+
STE-flavored words with the full Layer 2 shape. Number the steps. Cap the action list at five items. \
|
|
88
|
+
Restate the multi-turn state.
|
|
89
|
+
Example: "Wrap the prop in \`useMemo\`. Cause: a new object reference each render forces a re-render."`,
|
|
72
90
|
|
|
73
91
|
ultra: `\
|
|
74
|
-
|
|
75
|
-
|
|
92
|
+
Strict STE. Apply the strict word set (but not however, because not since, can not may, \
|
|
93
|
+
must not should) and both length caps. Keep the full Layer 2 shape.
|
|
94
|
+
Example: "Wrap the prop in \`useMemo\`. A new object reference each render forces a re-render."`,
|
|
76
95
|
};
|
|
77
96
|
|
|
78
97
|
const SAFETY = `\
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
98
|
+
When to break Layer 2: if the user asks you to explain, explain in full, but keep the \
|
|
99
|
+
no-preamble and no-closer rules. Before a destructive action, confirm first — safety beats brevity. \
|
|
100
|
+
In a debug spiral, name the wrong assumption and ask one question. On real ambiguity, ask one short question.
|
|
101
|
+
Guards: never drop a fact, a number, a condition, or a scope qualifier to satisfy a length cap. \
|
|
102
|
+
Preserve code, identifiers, units, and error strings exactly.
|
|
103
|
+
Boundaries: this governs prose, not code. "stop caveman" or "normal mode" reverts.`;
|
|
82
104
|
|
|
83
105
|
/**
|
|
84
106
|
* Build the system prompt injection for a given level.
|
|
@@ -109,9 +131,9 @@ export function buildHelp(current: Level): string {
|
|
|
109
131
|
`Caveman mode: ${statusLine}`,
|
|
110
132
|
"",
|
|
111
133
|
"Usage: /caveman <level>",
|
|
112
|
-
" 1 lite -
|
|
113
|
-
" 2 full -
|
|
114
|
-
" 3 ultra -
|
|
134
|
+
" 1 lite - STE-flavored words, light reply shape",
|
|
135
|
+
" 2 full - STE words + full ADHD reply shape",
|
|
136
|
+
" 3 ultra - strict STE + full reply shape",
|
|
115
137
|
" 0 off - disable (aliases: off, stop, quit)",
|
|
116
138
|
"",
|
|
117
139
|
"Other levels: micro",
|
package/src/mode.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
ExtensionCommandContext,
|
|
14
14
|
ExtensionContext,
|
|
15
15
|
} from "@earendil-works/pi-coding-agent";
|
|
16
|
+
import { showTransientError } from "@xynogen/pix-pretty/transient-error";
|
|
16
17
|
import { loadOptValue, saveOptValue } from "./persist.ts";
|
|
17
18
|
import type { OptimizerHandle, OptimizerStatus, OptimizerTool } from "./status.ts";
|
|
18
19
|
|
|
@@ -100,7 +101,12 @@ export function createMode<L extends string>(
|
|
|
100
101
|
level = resolved;
|
|
101
102
|
|
|
102
103
|
pi.appendEntry(customType, { level });
|
|
103
|
-
|
|
104
|
+
try {
|
|
105
|
+
saveOptValue(name, level);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
108
|
+
showTransientError(ctx.ui, `optimizer: failed to save ${name}: ${detail}`);
|
|
109
|
+
}
|
|
104
110
|
syncStatus(ctx);
|
|
105
111
|
|
|
106
112
|
ctx.ui.notify(config.notify(level), "info");
|
package/src/persist.ts
CHANGED
|
@@ -47,12 +47,8 @@ export function loadOptValue(tool: OptimizerTool): string | undefined {
|
|
|
47
47
|
|
|
48
48
|
/** Persist a single tool's value, merging into the shared config file. */
|
|
49
49
|
export function saveOptValue(tool: OptimizerTool, value: string): void {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
writeFileSync(sp, JSON.stringify(next, null, 2), "utf-8");
|
|
55
|
-
} catch (err) {
|
|
56
|
-
console.warn(`optimizer: persist ${tool} failed:`, err);
|
|
57
|
-
}
|
|
50
|
+
const sp = getStatePath();
|
|
51
|
+
mkdirSync(dirname(sp), { recursive: true });
|
|
52
|
+
const next = { ...readFile(), [tool]: value };
|
|
53
|
+
writeFileSync(sp, JSON.stringify(next, null, 2), "utf-8");
|
|
58
54
|
}
|
package/src/ponytail.ts
CHANGED
|
@@ -44,47 +44,59 @@ export const STATUS_LABELS: Record<Exclude<Level, "off">, string> = {
|
|
|
44
44
|
|
|
45
45
|
const BASE = `\
|
|
46
46
|
PONYTAIL MODE ACTIVE. You are a lazy senior developer. Lazy means efficient, \
|
|
47
|
-
not careless. The best code is the code never
|
|
47
|
+
not careless. The best code is the code you never write.
|
|
48
48
|
|
|
49
|
-
Before
|
|
50
|
-
1. Does this need to exist at all?
|
|
51
|
-
2.
|
|
52
|
-
3.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
Before you write any code, stop at the first rung that holds:
|
|
50
|
+
1. Does this need to exist at all? A speculative need means you skip it. Say so in one line. (YAGNI)
|
|
51
|
+
2. Does the standard library do it? Use it.
|
|
52
|
+
3. Does a native platform feature cover it? Use it (\`<input type="date">\` over a picker library, \
|
|
53
|
+
CSS over JavaScript, a database constraint over application code).
|
|
54
|
+
4. Does an installed dependency solve it? Use it. Never add a new one for what a few lines can do.
|
|
55
|
+
5. Can it be one line? Write one line.
|
|
56
|
+
6. Only then, write the minimum code that works.
|
|
56
57
|
|
|
57
|
-
The ladder is a reflex, not a research project.
|
|
58
|
+
The ladder is a reflex, not a research project. If two rungs work, take the higher one and move on.
|
|
58
59
|
|
|
59
60
|
Rules:
|
|
60
|
-
- No unrequested
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
|
|
64
|
-
-
|
|
61
|
+
- No unrequested abstraction. No interface with one use, no factory for one product, \
|
|
62
|
+
no config for a value that never changes.
|
|
63
|
+
- No boilerplate. No scaffolding for later. Prefer deletion to addition. Prefer boring code to clever code. \
|
|
64
|
+
Use the fewest files.
|
|
65
|
+
- For a complex request, ship the lazy version and question it in the same reply. \
|
|
66
|
+
Never stop for an answer you can default.
|
|
67
|
+
- For two stdlib options of the same size, take the one that is correct on the edge cases. \
|
|
68
|
+
Lazy means less code, not the weaker algorithm.
|
|
69
|
+
- Mark a deliberate simplification with a \`ponytail:\` comment. \
|
|
70
|
+
A shortcut with a known ceiling names the ceiling and the upgrade path.`;
|
|
65
71
|
|
|
66
72
|
const INTENSITY: Record<Exclude<Level, "off">, string> = {
|
|
67
73
|
lite: `\
|
|
68
|
-
Build what
|
|
69
|
-
Example: "Done
|
|
74
|
+
Build what the user asks, but name the lazier alternative in one line. The user picks.
|
|
75
|
+
Example: "Done. I added a cache. The \`functools.lru_cache\` decorator covers this in one line \
|
|
76
|
+
if you do not want to own a cache class."`,
|
|
70
77
|
|
|
71
78
|
full: `\
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
Enforce the ladder. Prefer the standard library and native features first. \
|
|
80
|
+
Write the shortest diff and the shortest explanation.
|
|
81
|
+
Example: "I put \`@lru_cache(maxsize=1000)\` on the fetch function. I skipped a custom cache class. \
|
|
82
|
+
Add one when lru_cache falls short in a measurement."`,
|
|
74
83
|
|
|
75
84
|
ultra: `\
|
|
76
|
-
YAGNI extremist.
|
|
77
|
-
|
|
85
|
+
YAGNI extremist. Prefer deletion to addition. Ship the one-liner and challenge the rest of the \
|
|
86
|
+
requirement in the same reply.
|
|
87
|
+
Example: "No cache until a profiler asks for one. When it does, use \`@lru_cache\`. \
|
|
88
|
+
A hand-rolled TTL cache class is a bug farm with a hit rate."`,
|
|
78
89
|
};
|
|
79
90
|
|
|
80
91
|
const SAFETY = `\
|
|
81
|
-
When
|
|
82
|
-
error handling that prevents data loss, security, accessibility, or anything \
|
|
83
|
-
|
|
84
|
-
Lazy code without its check is unfinished
|
|
85
|
-
(an assert-based self-check or one small test file
|
|
86
|
-
Output: code first, then at most three short lines — what
|
|
87
|
-
|
|
92
|
+
When not to be lazy: never simplify away input validation at a trust boundary, \
|
|
93
|
+
error handling that prevents data loss, security, accessibility, or anything the user asks for. \
|
|
94
|
+
The hardware is never the spec ideal. Leave the calibration knob.
|
|
95
|
+
Lazy code without its check is unfinished. Non-trivial logic leaves ONE runnable check behind \
|
|
96
|
+
(an assert-based self-check or one small test file, no frameworks). A trivial one-liner needs no test.
|
|
97
|
+
Output: write the code first, then at most three short lines — what you skipped, and when to add it. \
|
|
98
|
+
Write these lines in Simplified Technical English: short common words, the active voice, and simple tenses.
|
|
99
|
+
Boundaries: ponytail governs what you build, not how you talk. "stop ponytail" or "normal mode" reverts.`;
|
|
88
100
|
|
|
89
101
|
/**
|
|
90
102
|
* Build the system prompt injection for a given level.
|
package/src/rtk.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
ExtensionCommandContext,
|
|
12
12
|
ExtensionContext,
|
|
13
13
|
} from "@earendil-works/pi-coding-agent";
|
|
14
|
+
import { showTransientError } from "@xynogen/pix-pretty/transient-error";
|
|
14
15
|
import { canExecute } from "./capability.ts";
|
|
15
16
|
import { loadOptValue, saveOptValue } from "./persist.ts";
|
|
16
17
|
import type { OptimizerHandle, OptimizerStatus } from "./status.ts";
|
|
@@ -285,7 +286,12 @@ export function rtk(pi: ExtensionAPI, status: OptimizerStatus): OptimizerHandle
|
|
|
285
286
|
|
|
286
287
|
async function run(value: string, ctx: ExtensionCommandContext): Promise<void> {
|
|
287
288
|
enabled = value === "on";
|
|
288
|
-
|
|
289
|
+
try {
|
|
290
|
+
saveOptValue("rtk", enabled ? "on" : "off");
|
|
291
|
+
} catch (error) {
|
|
292
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
293
|
+
showTransientError(ctx.ui, `optimizer: failed to save rtk: ${detail}`);
|
|
294
|
+
}
|
|
289
295
|
|
|
290
296
|
await checkRtkAvailability();
|
|
291
297
|
syncStatus(ctx);
|