pi-native-output-styles 0.4.0 → 0.5.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/CHANGELOG.md +14 -0
- package/LICENSE +2 -0
- package/README.md +42 -14
- package/extensions/output-styles.ts +130 -15
- package/extensions/prompts/output-style-leader.md +71 -0
- package/extensions/styles/caveman.md +11 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
One command, plus a bundled style and an agent that maintains styles.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `/output-style <request>` hands the task to an agent that reviews, rewrites, or creates styles. The brief is short Markdown in `extensions/prompts/output-style-leader.md`, and the agent decides for itself whether to fan work out to other agents.
|
|
10
|
+
- Bundled `caveman` style, from [carlosduplar/caveman-output-style-claude-code](https://github.com/carlosduplar/caveman-output-style-claude-code) (MIT, © 2026 Carlos Mello).
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **`/style` is gone; `/output-style` is the only command.** A single word that names a style, `off`, or `none` is style management; anything else is a request for the agent. `/output-style` with no arguments lists what exists.
|
|
15
|
+
- Style names are matched case-insensitively and resolved to their declared name.
|
|
16
|
+
|
|
3
17
|
## 0.4.0
|
|
4
18
|
|
|
5
19
|
Repackaged as `pi-native-output-styles` — a Pi-only output-style switcher built on Pi's native `.pi/` directories.
|
package/LICENSE
CHANGED
|
@@ -2,6 +2,8 @@ MIT License
|
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 LoneExile
|
|
4
4
|
Copyright (c) 2026 code-koan contributors
|
|
5
|
+
The bundled `caveman` output style is Copyright (c) 2026 Carlos Mello
|
|
6
|
+
(https://github.com/carlosduplar/caveman-output-style-claude-code), MIT.
|
|
5
7
|
|
|
6
8
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
9
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/pi-native-output-styles)
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
|
|
7
|
-
Named, swappable system-prompt styles for [Pi](https://pi.dev)
|
|
7
|
+
Named, swappable system-prompt styles for [Pi](https://pi.dev), plus an agent that can review, rewrite, and create them for you. Unlike Claude Code's output styles (which need `/clear` to switch), styles here apply and switch **live, mid-session**.
|
|
8
8
|
|
|
9
9
|
Styles and saved defaults live in Pi's own directories: `~/.pi/agent/output-styles/` and `<repo>/.pi/output-styles/`.
|
|
10
10
|
|
|
@@ -19,17 +19,31 @@ pi install git:github.com/code-koan/pi-native-output-styles
|
|
|
19
19
|
|
|
20
20
|
Then start a **new** session. Extensions do not hot-reload.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## One command
|
|
23
23
|
|
|
24
|
-
-
|
|
25
|
-
- `/style <name>` — activate a style for this session.
|
|
26
|
-
- `/style <name> --save` — also save it as your personal (user) default.
|
|
27
|
-
- `/style <name> --project` — save it as the project default (committed with the repo).
|
|
28
|
-
- `/style off` — clear the active style for this session, overriding any saved default.
|
|
29
|
-
- `/style off --save` / `/style off --project` — also clear the saved default. `none` is an alias for `off`.
|
|
30
|
-
- While composing `/style`, a hint line below the input shows the available flags.
|
|
24
|
+
`/output-style` does both jobs. What you type decides which one you get.
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
**Switch styles** — the first word is a style name, `off`, or nothing:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
/output-style list styles and show the active one
|
|
30
|
+
/output-style caveman use caveman for this session
|
|
31
|
+
/output-style concise --save and make it your default
|
|
32
|
+
/output-style concise --project save it as this project's default
|
|
33
|
+
/output-style off clear it; --save / --project also clears the default
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Ask the agent to work on a style** — anything else:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
/output-style review the reviewer style
|
|
40
|
+
/output-style 重写这个 output style,让它更简洁、更适合编程
|
|
41
|
+
/output-style 创建一个适合代码 Review 的 output style
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The rule is one line: *a single word that names a style, `off`, or `none` is management; anything else is a request for the agent.* So `/output-style concise` activates, and `/output-style rewrite concise` asks. To review a style whose name you would otherwise activate, say more than its name.
|
|
45
|
+
|
|
46
|
+
While composing the command, a hint line under the editor shows both forms.
|
|
33
47
|
|
|
34
48
|
## How a style is applied
|
|
35
49
|
|
|
@@ -37,9 +51,23 @@ Pi's assembled system prompt is flat prose plus XML blocks — there is no perso
|
|
|
37
51
|
|
|
38
52
|
It is idempotent: a prompt that already carries the marker is left untouched, so switching styles mid-session never stacks a second block. Nothing else in the prompt is modified.
|
|
39
53
|
|
|
54
|
+
## The style agent
|
|
55
|
+
|
|
56
|
+
`/output-style <request>` hands the task to the agent with a short brief and the live picture: which style is active, both writable directories, and every style that exists with its tier and file path.
|
|
57
|
+
|
|
58
|
+
The agent owns the task end to end. It decides for itself whether the work needs other agents — a review is the usual case, where prompt quality, responsibility boundaries, and conflicts/redundancy are worth splitting across children. It uses whatever delegation tool the session has, and does the analysis itself when there is none. The final write and the summary stay with it.
|
|
59
|
+
|
|
60
|
+
Review findings are specific: conflicting instructions, duplicate or unenforceable rules, vague wording, over-constraining the model, content that belongs to a different concern, AI-slop voice, and rules that are hard to follow while actually working. Rewrites keep what works, delete what does not, and add only what is missing.
|
|
61
|
+
|
|
62
|
+
A review reports; it does not edit. The file is written only when the request asks for a change. In observed runs the agent delegated on its own when a task had several independent angles to check, and worked solo on a small single-file review.
|
|
63
|
+
|
|
64
|
+
The brief lives in [`extensions/prompts/output-style-leader.md`](extensions/prompts/output-style-leader.md) and is plain Markdown — edit it without touching code.
|
|
65
|
+
|
|
40
66
|
## Bundled styles
|
|
41
67
|
|
|
42
|
-
`concise` · `explanatory` · `teacher` · `reviewer` · `diagrams-first` · `ste` · `eli5`
|
|
68
|
+
`caveman` · `concise` · `explanatory` · `teacher` · `reviewer` · `diagrams-first` · `ste` · `eli5`
|
|
69
|
+
|
|
70
|
+
`caveman` is [Carlos Mello's Caveman output style](https://github.com/carlosduplar/caveman-output-style-claude-code) — terse replies, no filler, same technical signal. The same repo also ships a more aggressive `caveman-ultra`; it is not bundled, but you can drop it into your own `output-styles/` directory unchanged.
|
|
43
71
|
|
|
44
72
|
`ste` writes in [ASD-STE100](https://asd-ste100.org) Simplified Technical English, with the v2.0 action-first reply shape for person-addressed replies, tasks, issues, pull request descriptions, and commit messages. Adapted from [Ege Chelebi's ste-writing skill](https://github.com/woosal1337/blog/blob/9240b25eac013467554fd8217f319743aa0282b8/videos/ep01-the-cure-for-ai-slop/asd-ste100/SKILL.md).
|
|
45
73
|
|
|
@@ -60,12 +88,12 @@ description: Teach as you go
|
|
|
60
88
|
Act as a patient teacher. Explain the concept before applying it.
|
|
61
89
|
```
|
|
62
90
|
|
|
63
|
-
|
|
91
|
+
`name` is lowercase kebab-case, `description` is one line and shows up in `/output-style`.
|
|
64
92
|
|
|
65
93
|
Precedence:
|
|
66
94
|
|
|
67
95
|
- **Definitions** (low → high): bundled < user < project.
|
|
68
|
-
- **Which style is active**: session `/style` > user default > project default.
|
|
96
|
+
- **Which style is active**: session `/output-style` > user default > project default.
|
|
69
97
|
|
|
70
98
|
## Config
|
|
71
99
|
|
|
@@ -91,4 +119,4 @@ bun x tsc --noEmit
|
|
|
91
119
|
|
|
92
120
|
## Credits
|
|
93
121
|
|
|
94
|
-
Started as a fork of [LoneExile/pi-output-styles](https://github.com/LoneExile/pi-output-styles)
|
|
122
|
+
Started as a fork of [LoneExile/pi-output-styles](https://github.com/LoneExile/pi-output-styles). Bundles [caveman](https://github.com/carlosduplar/caveman-output-style-claude-code) by Carlos Mello. MIT licensed; original work © 2026 LoneExile, caveman style © 2026 Carlos Mello.
|
|
@@ -11,6 +11,21 @@ export interface Style {
|
|
|
11
11
|
name: string;
|
|
12
12
|
description: string;
|
|
13
13
|
body: string;
|
|
14
|
+
/** Absolute file path; set by discoverStyles. */
|
|
15
|
+
path?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Where a style definition was found. Only `project` and `user` are writable. */
|
|
19
|
+
export type StyleTier = "bundled" | "user" | "project";
|
|
20
|
+
|
|
21
|
+
export interface StyleSource {
|
|
22
|
+
dir: string;
|
|
23
|
+
tier: StyleTier;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface StyleEntry extends Style {
|
|
27
|
+
tier: StyleTier;
|
|
28
|
+
path: string;
|
|
14
29
|
}
|
|
15
30
|
|
|
16
31
|
type NotifyType = "info" | "warning" | "error";
|
|
@@ -25,6 +40,7 @@ interface ExtensionUI {
|
|
|
25
40
|
interface ExtensionContext {
|
|
26
41
|
cwd: string;
|
|
27
42
|
hasUI: boolean;
|
|
43
|
+
isIdle?(): boolean;
|
|
28
44
|
ui: ExtensionUI;
|
|
29
45
|
setInterval?(callback: () => void, ms?: number): unknown;
|
|
30
46
|
}
|
|
@@ -59,6 +75,7 @@ interface ExtensionAPI {
|
|
|
59
75
|
handler: (args: string, ctx: ExtensionContext) => void | Promise<void>;
|
|
60
76
|
},
|
|
61
77
|
): void;
|
|
78
|
+
sendUserMessage(content: string, options?: { deliverAs?: "steer" | "followUp" }): void;
|
|
62
79
|
}
|
|
63
80
|
|
|
64
81
|
export function parseStyle(text: string, fallbackName: string): Style {
|
|
@@ -99,7 +116,7 @@ export function discoverStyles(dirsLowToHigh: string[]): Map<string, Style> {
|
|
|
99
116
|
}
|
|
100
117
|
const style = parseStyle(text, entry.slice(0, -3));
|
|
101
118
|
if (style.body.length === 0) continue;
|
|
102
|
-
styles.set(style.name, style);
|
|
119
|
+
styles.set(style.name, { ...style, path: join(dir, entry) });
|
|
103
120
|
}
|
|
104
121
|
}
|
|
105
122
|
return styles;
|
|
@@ -207,20 +224,46 @@ export function parseStyleCommandArgs(args: string): StyleCommandArgs {
|
|
|
207
224
|
return { name, persist };
|
|
208
225
|
}
|
|
209
226
|
|
|
227
|
+
// One command serves both jobs, so the split has to be guessable from the
|
|
228
|
+
// words alone. Rule: the request is style management only when it is empty,
|
|
229
|
+
// or its single non-flag word is `off`/`none` or a style that exists. Anything
|
|
230
|
+
// else is a task for the agent. `/output-style concise` activates; `/output-style
|
|
231
|
+
// rewrite concise` asks the agent.
|
|
232
|
+
export type StyleCommandRoute = { kind: "manage" } | { kind: "task"; request: string };
|
|
233
|
+
|
|
234
|
+
export function routeStyleCommand(args: string, styleNames: Iterable<string>): StyleCommandRoute {
|
|
235
|
+
const request = args.trim();
|
|
236
|
+
if (request.length === 0) return { kind: "manage" };
|
|
237
|
+
const words = request.split(/\s+/).filter(t => t.length > 0 && !t.startsWith("--"));
|
|
238
|
+
if (words.length === 0) return { kind: "manage" }; // flags only
|
|
239
|
+
if (words.length > 1) return { kind: "task", request };
|
|
240
|
+
const word = words[0].toLowerCase();
|
|
241
|
+
if (OFF_WORDS[word]) return { kind: "manage" };
|
|
242
|
+
const known = new Set([...styleNames].map(n => n.toLowerCase()));
|
|
243
|
+
return known.has(word) ? { kind: "manage" } : { kind: "task", request };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Routing matches names case-insensitively, but the style map is keyed by the
|
|
247
|
+
// exact declared name, so the selected name has to be canonicalised before use.
|
|
248
|
+
export function resolveStyleName(name: string, styleNames: Iterable<string>): string | null {
|
|
249
|
+
const all = [...styleNames];
|
|
250
|
+
return all.find(n => n === name) ?? all.find(n => n.toLowerCase() === name.toLowerCase()) ?? null;
|
|
251
|
+
}
|
|
252
|
+
|
|
210
253
|
const STATUS_KEY = "output-styles";
|
|
211
254
|
const HINT_KEY = "output-styles-hint";
|
|
212
|
-
// Persistent ghost hint shown below the editor while
|
|
213
|
-
//
|
|
214
|
-
//
|
|
255
|
+
// Persistent ghost hint shown below the editor while `/output-style` is being
|
|
256
|
+
// composed. Pi only renders inline usage ghost text for builtin commands, so
|
|
257
|
+
// this widget carries the same message for extension commands.
|
|
215
258
|
const STYLE_HINT_LINES = [
|
|
216
|
-
"/style <name|off> [--save] [--project]",
|
|
217
|
-
"
|
|
259
|
+
"/output-style <name|off> [--save] [--project]",
|
|
260
|
+
"/output-style <ask the agent to review, rewrite, or create a style>",
|
|
218
261
|
];
|
|
219
262
|
|
|
220
|
-
// Pure matcher for the widget: show the hint while the input starts with
|
|
221
|
-
// `/style` command word (line start,
|
|
263
|
+
// Pure matcher for the widget: show the hint while the input starts with the
|
|
264
|
+
// `/output-style` command word (line start, optional leading whitespace).
|
|
222
265
|
export function styleHintFor(text: string): string[] | null {
|
|
223
|
-
return /^\s*\/style(?:\s|$)/.test(text) ? STYLE_HINT_LINES : null;
|
|
266
|
+
return /^\s*\/output-style(?:\s|$)/.test(text) ? STYLE_HINT_LINES : null;
|
|
224
267
|
}
|
|
225
268
|
|
|
226
269
|
// Poller state: one started flag guards re-registration across in-process
|
|
@@ -259,9 +302,29 @@ export function startHintPoller(ctx: ExtensionContext): void {
|
|
|
259
302
|
type SessionSelection = { type: "inherit" } | { type: "off" } | { type: "style"; name: string };
|
|
260
303
|
let session: SessionSelection = { type: "inherit" };
|
|
261
304
|
|
|
262
|
-
function
|
|
305
|
+
export function styleSources(cwd: string): StyleSource[] {
|
|
263
306
|
// low → high precedence: bundled < user < project
|
|
264
|
-
return [
|
|
307
|
+
return [
|
|
308
|
+
{ dir: bundledStylesDir(), tier: "bundled" },
|
|
309
|
+
{ dir: userStylesDir(), tier: "user" },
|
|
310
|
+
{ dir: projectStylesDir(cwd), tier: "project" },
|
|
311
|
+
];
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// One row per style name: the winning definition plus the file that actually
|
|
315
|
+
// produced it, so a rewrite knows whether it may edit in place.
|
|
316
|
+
export function styleCatalog(cwd: string): StyleEntry[] {
|
|
317
|
+
const byName = new Map<string, StyleEntry>();
|
|
318
|
+
for (const { dir, tier } of styleSources(cwd)) {
|
|
319
|
+
for (const style of discoverStyles([dir]).values()) {
|
|
320
|
+
if (style.path) byName.set(style.name, { ...style, tier, path: style.path });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function styleDirs(cwd: string): string[] {
|
|
327
|
+
return styleSources(cwd).map(s => s.dir);
|
|
265
328
|
}
|
|
266
329
|
|
|
267
330
|
// Argument completions for `/style <name>`: matches style names by prefix.
|
|
@@ -302,6 +365,37 @@ function refreshStatus(ctx: ExtensionContext, style: Style | null): void {
|
|
|
302
365
|
ctx.ui.setStatus(STATUS_KEY, style ? `style: ${style.name}` : undefined);
|
|
303
366
|
}
|
|
304
367
|
|
|
368
|
+
// The Leader brief is plain Markdown next to the extension, so its wording can
|
|
369
|
+
// be edited without touching code.
|
|
370
|
+
export function leaderBrief(): string {
|
|
371
|
+
return readFileSync(join(dirname(fileURLToPath(import.meta.url)), "prompts", "output-style-leader.md"), "utf8").trim();
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// The brief stays fixed and short. What changes per run is the live picture:
|
|
375
|
+
// which style is active, where styles may be written, and what already exists.
|
|
376
|
+
// The user's words are passed through untouched — this is a router, not a form.
|
|
377
|
+
export function buildStyleTask(brief: string, cwd: string, active: Style | null, request: string): string {
|
|
378
|
+
const catalog = styleCatalog(cwd);
|
|
379
|
+
return [
|
|
380
|
+
brief,
|
|
381
|
+
"",
|
|
382
|
+
"## Context",
|
|
383
|
+
"",
|
|
384
|
+
`Active style: ${active?.name ?? "(none)"}`,
|
|
385
|
+
`Project style dir: ${projectStylesDir(cwd)}`,
|
|
386
|
+
`User style dir: ${userStylesDir()}`,
|
|
387
|
+
"",
|
|
388
|
+
"Available styles:",
|
|
389
|
+
...(catalog.length
|
|
390
|
+
? catalog.map(s => `- ${s.name} [${s.tier}] ${s.path}${s.description ? ` — ${s.description}` : ""}`)
|
|
391
|
+
: ["(none)"]),
|
|
392
|
+
"",
|
|
393
|
+
"## Request",
|
|
394
|
+
"",
|
|
395
|
+
request,
|
|
396
|
+
].join("\n");
|
|
397
|
+
}
|
|
398
|
+
|
|
305
399
|
export default function outputStyles(pi: ExtensionAPI): void {
|
|
306
400
|
pi.on("session_start", (_event, ctx) => {
|
|
307
401
|
refreshStatus(ctx, resolveActiveStyle(ctx.cwd));
|
|
@@ -332,13 +426,30 @@ export default function outputStyles(pi: ExtensionAPI): void {
|
|
|
332
426
|
}
|
|
333
427
|
});
|
|
334
428
|
|
|
335
|
-
pi.registerCommand("style", {
|
|
429
|
+
pi.registerCommand("output-style", {
|
|
336
430
|
description:
|
|
337
|
-
"Select an output style
|
|
431
|
+
"Select an output style, or ask the agent to review, rewrite, or create one. Usage: /output-style <name|off|what you want> [--save] [--project]",
|
|
338
432
|
getArgumentCompletions: argumentPrefix => styleCompletions(argumentPrefix, process.cwd()),
|
|
339
433
|
handler: (args, ctx) => {
|
|
340
|
-
const { name, persist } = parseStyleCommandArgs(args);
|
|
341
434
|
const styles = discoverStyles(styleDirs(ctx.cwd));
|
|
435
|
+
const route = routeStyleCommand(args, styles.keys());
|
|
436
|
+
|
|
437
|
+
if (route.kind === "task") {
|
|
438
|
+
let task: string;
|
|
439
|
+
try {
|
|
440
|
+
task = buildStyleTask(leaderBrief(), ctx.cwd, resolveActiveStyle(ctx.cwd, styles), route.request);
|
|
441
|
+
} catch (err) {
|
|
442
|
+
ctx.ui.notify(`Could not build the output-style task: ${String(err)}`, "error");
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
// Mid-stream the delivery mode is required; otherwise the message goes
|
|
446
|
+
// out immediately and triggers the turn.
|
|
447
|
+
pi.sendUserMessage(task, ctx.isIdle?.() === false ? { deliverAs: "followUp" } : undefined);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const { name: requested, persist } = parseStyleCommandArgs(args);
|
|
452
|
+
const name = requested === null ? null : (resolveStyleName(requested, styles.keys()) ?? requested);
|
|
342
453
|
const available = [...styles.keys()].sort().join(", ") || "(none)";
|
|
343
454
|
|
|
344
455
|
const unknownFlags = args
|
|
@@ -355,7 +466,11 @@ export default function outputStyles(pi: ExtensionAPI): void {
|
|
|
355
466
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
356
467
|
.map(s => (s.description ? `${s.name} — ${s.description}` : s.name))
|
|
357
468
|
.join("\n");
|
|
358
|
-
ctx.ui.notify(
|
|
469
|
+
ctx.ui.notify(
|
|
470
|
+
`Active style: ${current?.name ?? "(none)"}\nAvailable:\n${listing || "(none)"}\n\n` +
|
|
471
|
+
"/output-style <name|off> [--save] [--project] to switch, or /output-style <request> to have the agent review, rewrite, or create a style.",
|
|
472
|
+
"info",
|
|
473
|
+
);
|
|
359
474
|
return;
|
|
360
475
|
}
|
|
361
476
|
if (OFF_WORDS[name.toLowerCase()]) {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Output style task
|
|
2
|
+
|
|
3
|
+
You own this end to end: read the request, decide what work it needs, do it,
|
|
4
|
+
then verify what you produced. Finish with a short report of what changed and
|
|
5
|
+
where.
|
|
6
|
+
|
|
7
|
+
## What an output style is
|
|
8
|
+
|
|
9
|
+
A style defines **how** you behave: voice, structure, level of detail,
|
|
10
|
+
interaction style. It is not a home for project architecture, coding rules,
|
|
11
|
+
domain knowledge, tooling conventions, or repo facts. Anything like that is a
|
|
12
|
+
responsibility-boundary bug: drop it, or say where it belongs instead.
|
|
13
|
+
|
|
14
|
+
## Delegation
|
|
15
|
+
|
|
16
|
+
Decide for yourself whether the task needs other agents. Delegate only when
|
|
17
|
+
independent angles genuinely improve the result. A review is the usual case:
|
|
18
|
+
prompt quality, responsibility boundaries, and conflicts/redundancy are worth
|
|
19
|
+
splitting. Use the `subagent` tool when it is available, and run the children
|
|
20
|
+
in one workflow call. If it is not available, do the analysis yourself.
|
|
21
|
+
Children report findings back to you and never write files. You do the final
|
|
22
|
+
write and the final summary — never hand the file off.
|
|
23
|
+
|
|
24
|
+
## Reviewing
|
|
25
|
+
|
|
26
|
+
Review means report, not edit. Do not change the file unless the request also
|
|
27
|
+
asks for the change; offer the fix instead.
|
|
28
|
+
|
|
29
|
+
Name each finding specifically: what is wrong, what it costs, and the fix.
|
|
30
|
+
Look for:
|
|
31
|
+
|
|
32
|
+
- instructions that conflict with each other
|
|
33
|
+
- duplicate, dead, or unenforceable rules
|
|
34
|
+
- vague wording that cannot be acted on
|
|
35
|
+
- over-constraining the model
|
|
36
|
+
- content that belongs to another concern
|
|
37
|
+
- AI-slop voice: inflated claims, filler, ceremony
|
|
38
|
+
- rules that are hard to follow while actually working
|
|
39
|
+
|
|
40
|
+
No praise padding, and do not restate the style back at the user.
|
|
41
|
+
|
|
42
|
+
## Rewriting
|
|
43
|
+
|
|
44
|
+
Keep what works, delete what does not, add only what is missing. Fewer sharp
|
|
45
|
+
rules beat more rules. Do not add text to look thorough, and do not quietly
|
|
46
|
+
widen the scope.
|
|
47
|
+
|
|
48
|
+
## Creating
|
|
49
|
+
|
|
50
|
+
Write the smallest style that achieves the goal. `name` is lowercase
|
|
51
|
+
kebab-case; `description` is one line and shows up in `/style`.
|
|
52
|
+
|
|
53
|
+
## File format
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
name: <kebab-case>
|
|
57
|
+
description: <one line>
|
|
58
|
+
---
|
|
59
|
+
<style body>
|
|
60
|
+
|
|
61
|
+
## Where to write
|
|
62
|
+
|
|
63
|
+
Default to the project directory. Write to the user directory only when asked
|
|
64
|
+
for personal or global. Never edit a style under a package install path — those
|
|
65
|
+
are read-only bundled styles; copy one out instead.
|
|
66
|
+
|
|
67
|
+
## Before you finish
|
|
68
|
+
|
|
69
|
+
- Re-read what you wrote: frontmatter plus body, nothing else.
|
|
70
|
+
- Confirm the file parses and the `name` matches what `/style <name>` expects.
|
|
71
|
+
- State the path you wrote and what changed.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: caveman
|
|
3
|
+
description: Ultra-compact replies. Less fluff. Same technical signal.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Smart caveman style: terse responses, keep technical substance, drop ALL fluff.
|
|
7
|
+
Lead with answer. Drop articles, filler, pleasantries, hedging, preamble, recap.
|
|
8
|
+
Fragments OK. Pattern: `[thing] [action] [reason]. [next step].`
|
|
9
|
+
Keep technical terms, code, commands, paths, JSON, errors unchanged.
|
|
10
|
+
Bullets/tables only when scan > prose.
|
|
11
|
+
Normal language for safety, irreversible actions, or confusion risk.
|