@kulapard/pi-caveman 0.4.2 → 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/AGENTS.md +9 -4
- package/CHANGELOG.md +12 -1
- package/README.md +9 -8
- package/extensions/caveman-state.ts +49 -0
- package/extensions/caveman.ts +33 -10
- package/package.json +1 -1
- package/skills/caveman-compress/README.md +3 -2
- package/skills/caveman-compress/SKILL.md +7 -4
- package/skills/caveman-help/README.md +7 -1
- package/skills/caveman-help/SKILL.md +9 -5
package/AGENTS.md
CHANGED
|
@@ -5,20 +5,25 @@ Project memory. Non-obvious only.
|
|
|
5
5
|
## Architecture (do not rebuild)
|
|
6
6
|
|
|
7
7
|
- `extensions/caveman.ts` = Pi extension. `extensions/caveman-core.ts` = pure SDK-free logic (`normalizeMode`, `modeInstructions`, `VALID_MODES`, regexes). Unit-testable without fake SDK.
|
|
8
|
-
- Mode state **session-scoped**: `pi.appendEntry("caveman-mode", …)
|
|
8
|
+
- Mode state **session + project-scoped**: `pi.appendEntry("caveman-mode", …)`
|
|
9
|
+
restores from `ctx.sessionManager.getBranch()` on `session_start`; since
|
|
10
|
+
v0.4.3 `extensions/caveman-state.ts` also reads/writes `.pi/caveman-mode.json`
|
|
11
|
+
in the project directory. A session entry overrides the project default; a
|
|
12
|
+
project without a state file falls back to `off`. No global/env default.
|
|
9
13
|
- Activation = `before_agent_start` appends `modeInstructions(mode)`. Statusline = `ctx.ui.setStatus("caveman", …)` guarded by `hasUI`.
|
|
10
|
-
- Extension `modeInstructions` = **canonical** activator. `skills/caveman/SKILL.md` = fallback for hosts loading skills but not extension.
|
|
14
|
+
- Extension `modeInstructions` = **canonical** activator. `skills/caveman/SKILL.md` = fallback for hosts loading skills but not extension. Both active → model sees both rule sets; intentional redundancy, no de-dupe.
|
|
11
15
|
- Pi 0.80.2 has **no `agents/` subagent mechanism**. `agents/cavecrew-*.md` = reference personas only; cavecrew optional/out-of-scope.
|
|
12
16
|
|
|
13
17
|
## Invariants
|
|
14
18
|
|
|
15
19
|
- **SDK import `import type` only** in `extensions/*.ts`. JS tests run via `--experimental-strip-types`, erases type-only imports. Value import from `@earendil-works/pi-coding-agent` breaks tests — `tests/extension.test.mjs` asserts this.
|
|
16
|
-
- **Verbatim preservation**: caveman-compress never changes code blocks, inline code, URLs, paths, commands, exact error strings.
|
|
20
|
+
- **Verbatim preservation**: caveman-compress never changes code blocks, inline code, URLs, paths, commands, exact error strings. Self-validate against original. Mismatch unfixable → restore from `.original` backup created in same invocation (stale backups rejected before compression).
|
|
17
21
|
- `caveman-compress` is **prompt-only**: Pi agent compresses with own model + file tools, driven by `SKILL.md`. No Python, no external model CLI. Coverage = `tests/compress-docs.test.mjs`.
|
|
22
|
+
- `/caveman-compress` supports `--force`: overwrites existing `.original.<ext>` backup instead of aborting.
|
|
18
23
|
|
|
19
24
|
## Changelog
|
|
20
25
|
|
|
21
|
-
Every notable change
|
|
26
|
+
Every notable change update `CHANGELOG.md` under `[Unreleased]`. Before finishing, run `npm run changelog:check`. CI runs same check on every PR.
|
|
22
27
|
|
|
23
28
|
- `npm test` runs `pretest` (`npm run typecheck` → `tsc --noEmit`), then `node --test tests/**/*.test.mjs`. Typecheck failures fail test run.
|
|
24
29
|
- Node `--test` glob expanded by runner, not shell. Directory-recursion `--test tests/` does **not** work on current Node — keep glob.
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.0] - 2026-06-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `/caveman-compress` now accepts an optional `--force` flag. With `--force`, an existing `.original.<ext>` backup is overwritten instead of aborting.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Updated README, AGENTS.md, caveman-help, and caveman-compress docs to reflect the project-scoped persistence added in v0.4.3 and the new `--force` flag.
|
|
19
|
+
|
|
10
20
|
## [0.4.2] - 2026-06-29
|
|
11
21
|
|
|
12
22
|
### Changed
|
|
@@ -112,7 +122,8 @@ port of [caveman](https://github.com/JuliusBrussee/caveman).
|
|
|
112
122
|
token, automatic provenance, a tag-equals-version guard, and a concurrency
|
|
113
123
|
group).
|
|
114
124
|
|
|
115
|
-
[Unreleased]: https://github.com/kulapard/pi-caveman/compare/v0.
|
|
125
|
+
[Unreleased]: https://github.com/kulapard/pi-caveman/compare/v0.5.0...HEAD
|
|
126
|
+
[0.5.0]: https://github.com/kulapard/pi-caveman/compare/v0.4.2...v0.5.0
|
|
116
127
|
[0.4.2]: https://github.com/kulapard/pi-caveman/compare/v0.4.1...v0.4.2
|
|
117
128
|
[0.4.1]: https://github.com/kulapard/pi-caveman/compare/v0.4.0...v0.4.1
|
|
118
129
|
[0.4.0]: https://github.com/kulapard/pi-caveman/compare/v0.3.0...v0.4.0
|
package/README.md
CHANGED
|
@@ -92,7 +92,7 @@ session ends.
|
|
|
92
92
|
| `/caveman-help` | Show the quick-reference card. |
|
|
93
93
|
| `/caveman-commit [notes]` | Generate a terse Conventional Commit message. Does **not** commit. |
|
|
94
94
|
| `/caveman-review [scope]` | One-line-per-finding code review comments. |
|
|
95
|
-
| `/caveman-compress <file
|
|
95
|
+
| `/caveman-compress <file> [--force]` | Compress a prose file via the caveman-compress skill. `--force` overwrites an existing `.original` backup. |
|
|
96
96
|
| `/caveman-stats` | Load the stats skill (an on-demand, model-driven estimate). |
|
|
97
97
|
|
|
98
98
|
## Natural-language activation
|
|
@@ -105,18 +105,19 @@ switches mode on phrases like:
|
|
|
105
105
|
- **Deactivate:** "stop caveman", "normal mode", "disable caveman" → turns it
|
|
106
106
|
off.
|
|
107
107
|
|
|
108
|
-
## Session-scoped behavior
|
|
108
|
+
## Session and project-scoped behavior
|
|
109
109
|
|
|
110
|
-
Mode state is
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
Mode state is stored as a session entry, so it survives a `/reload` within the
|
|
111
|
+
same session. Since v0.4.3 it is also persisted per project in
|
|
112
|
+
`.pi/caveman-mode.json`, so a **new session in the same project directory**
|
|
113
|
+
restores the last used mode. A session entry always overrides the project
|
|
114
|
+
default, and a project without a state file falls back to `off`.
|
|
114
115
|
|
|
115
116
|
## Statusline indicator
|
|
116
117
|
|
|
117
118
|
When a UI is attached, the statusline shows the active mode as
|
|
118
|
-
`caveman:<mode>` (for example `caveman:ultra`)
|
|
119
|
-
is cleared.
|
|
119
|
+
`caveman:<mode>` (for example `caveman:ultra`), and appends live context usage
|
|
120
|
+
as `ctx:XX%` when Pi provides it. When caveman is off the indicator is cleared.
|
|
120
121
|
|
|
121
122
|
## Compression vs. upstream MCP shrink
|
|
122
123
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Project-scoped persistence for caveman mode.
|
|
2
|
+
// This is a workaround until Pi exposes SettingsManager to extensions
|
|
3
|
+
// (tracked upstream as pi-coding-agent issue #4981).
|
|
4
|
+
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { normalizeMode, type StoredMode } from "./caveman-core.ts";
|
|
8
|
+
|
|
9
|
+
const STATE_DIR = ".pi";
|
|
10
|
+
const STATE_FILE = "caveman-mode.json";
|
|
11
|
+
|
|
12
|
+
function statePath(cwd: string): string {
|
|
13
|
+
return join(cwd, STATE_DIR, STATE_FILE);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Load the project-scoped caveman mode default. Returns `undefined` when no
|
|
18
|
+
* state file exists or it cannot be read, so the caller can fall back to the
|
|
19
|
+
* session-scoped default (`off`).
|
|
20
|
+
*/
|
|
21
|
+
export function loadProjectMode(cwd: string): StoredMode | undefined {
|
|
22
|
+
const path = statePath(cwd);
|
|
23
|
+
if (!existsSync(path)) return undefined;
|
|
24
|
+
try {
|
|
25
|
+
const raw = JSON.parse(readFileSync(path, "utf8"));
|
|
26
|
+
return normalizeMode(raw.mode);
|
|
27
|
+
} catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Persist the caveman mode for this project directory. Returns `true` on
|
|
34
|
+
* success; failures are silent so that session operation is never blocked by
|
|
35
|
+
* disk issues.
|
|
36
|
+
*/
|
|
37
|
+
export function saveProjectMode(cwd: string, mode: StoredMode): boolean {
|
|
38
|
+
try {
|
|
39
|
+
const dir = join(cwd, STATE_DIR);
|
|
40
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
41
|
+
writeFileSync(
|
|
42
|
+
statePath(cwd),
|
|
43
|
+
JSON.stringify({ mode, updatedAt: Date.now() }, null, 2),
|
|
44
|
+
);
|
|
45
|
+
return true;
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
package/extensions/caveman.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
normalizeMode,
|
|
11
11
|
type StoredMode,
|
|
12
12
|
} from "./caveman-core.ts";
|
|
13
|
+
import { loadProjectMode, saveProjectMode } from "./caveman-state.ts";
|
|
13
14
|
|
|
14
15
|
const HELP_TEXT = `# Caveman for Pi
|
|
15
16
|
|
|
@@ -19,18 +20,25 @@ Commands:
|
|
|
19
20
|
- /caveman-help — show this card.
|
|
20
21
|
- /caveman-commit [notes] — generate Conventional Commit message. Does not commit.
|
|
21
22
|
- /caveman-review [scope] — terse review comments.
|
|
22
|
-
- /caveman-compress <file> — compress prose file via caveman-compress skill.
|
|
23
|
+
- /caveman-compress <file> [--force] — compress prose file via caveman-compress skill. --force overwrites an existing .original backup.
|
|
23
24
|
- /caveman-stats — load stats skill/help.
|
|
24
25
|
|
|
25
|
-
Mode persists
|
|
26
|
-
Code, commands, API names, file paths, and
|
|
26
|
+
Mode persists across sessions in the same project via \`.pi/caveman-mode.json\`, and
|
|
27
|
+
survives /reload via session state. Code, commands, API names, file paths, and
|
|
28
|
+
exact errors stay verbatim.`;
|
|
27
29
|
|
|
28
30
|
export default function cavemanExtension(pi: ExtensionAPI) {
|
|
29
31
|
let mode: StoredMode = "off";
|
|
30
32
|
|
|
31
33
|
function setStatus(ctx?: ExtensionContext) {
|
|
32
34
|
if (!ctx?.hasUI) return;
|
|
33
|
-
ctx.
|
|
35
|
+
const usage = ctx.getContextUsage?.();
|
|
36
|
+
const suffix =
|
|
37
|
+
usage?.percent != null ? ` ctx:${Math.round(usage.percent)}%` : "";
|
|
38
|
+
ctx.ui.setStatus(
|
|
39
|
+
"caveman",
|
|
40
|
+
mode === "off" ? undefined : `caveman:${mode}${suffix}`,
|
|
41
|
+
);
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
function persistMode(nextMode: StoredMode, ctx?: ExtensionContext) {
|
|
@@ -40,7 +48,7 @@ export default function cavemanExtension(pi: ExtensionAPI) {
|
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
pi.on("session_start", (_event, ctx) => {
|
|
43
|
-
mode = "off";
|
|
51
|
+
mode = loadProjectMode(ctx.cwd) ?? "off";
|
|
44
52
|
for (const entry of ctx.sessionManager.getBranch() as Array<{
|
|
45
53
|
type?: string;
|
|
46
54
|
customType?: string;
|
|
@@ -73,6 +81,7 @@ export default function cavemanExtension(pi: ExtensionAPI) {
|
|
|
73
81
|
return;
|
|
74
82
|
}
|
|
75
83
|
persistMode(nextMode, ctx);
|
|
84
|
+
saveProjectMode(ctx.cwd, nextMode);
|
|
76
85
|
ctx.ui.notify(
|
|
77
86
|
nextMode === "off" ? "Caveman disabled" : `Caveman ${nextMode} enabled`,
|
|
78
87
|
"info",
|
|
@@ -112,14 +121,20 @@ export default function cavemanExtension(pi: ExtensionAPI) {
|
|
|
112
121
|
});
|
|
113
122
|
|
|
114
123
|
pi.registerCommand("caveman-compress", {
|
|
115
|
-
description:
|
|
124
|
+
description:
|
|
125
|
+
"Compress prose/memory file into caveman style (optional --force)",
|
|
116
126
|
handler: async (args, ctx) => {
|
|
117
|
-
const
|
|
127
|
+
const raw = args?.trim() ?? "";
|
|
128
|
+
const tokens = raw.split(/\s+/).filter(Boolean);
|
|
129
|
+
const force = tokens.includes("--force");
|
|
130
|
+
const target = tokens.filter((t) => t !== "--force").join(" ");
|
|
118
131
|
if (!target) {
|
|
119
|
-
ctx.ui.notify("Usage: /caveman-compress <file>", "error");
|
|
132
|
+
ctx.ui.notify("Usage: /caveman-compress <file> [--force]", "error");
|
|
120
133
|
return;
|
|
121
134
|
}
|
|
122
|
-
pi.sendUserMessage(
|
|
135
|
+
pi.sendUserMessage(
|
|
136
|
+
`/skill:caveman-compress ${target}${force ? " --force" : ""}`,
|
|
137
|
+
);
|
|
123
138
|
},
|
|
124
139
|
});
|
|
125
140
|
|
|
@@ -137,14 +152,22 @@ export default function cavemanExtension(pi: ExtensionAPI) {
|
|
|
137
152
|
if (event.source !== "extension") {
|
|
138
153
|
const text = (event.text ?? "").trim();
|
|
139
154
|
if (DEACTIVATION_RE.test(text)) {
|
|
140
|
-
if (mode !== "off")
|
|
155
|
+
if (mode !== "off") {
|
|
156
|
+
persistMode("off", ctx);
|
|
157
|
+
saveProjectMode(ctx.cwd, "off");
|
|
158
|
+
}
|
|
141
159
|
} else if (mode === "off" && ACTIVATION_RE.test(text)) {
|
|
142
160
|
persistMode("full", ctx);
|
|
161
|
+
saveProjectMode(ctx.cwd, "full");
|
|
143
162
|
}
|
|
144
163
|
}
|
|
145
164
|
return { action: "continue" as const };
|
|
146
165
|
});
|
|
147
166
|
|
|
167
|
+
pi.on("turn_end", (_event, ctx) => {
|
|
168
|
+
setStatus(ctx);
|
|
169
|
+
});
|
|
170
|
+
|
|
148
171
|
pi.on("before_agent_start", (event) => {
|
|
149
172
|
if (mode === "off") return undefined;
|
|
150
173
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kulapard/pi-caveman",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Caveman for Pi: ultra-compressed agent output that preserves technical substance. Six intensity modes, slash commands, natural-language activation, and a session statusline.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,7 +25,7 @@ AGENTS.md ← compressed (the agent reads this — fewer tokens every s
|
|
|
25
25
|
AGENTS.original.md ← human-readable backup (snapshot taken at first compression)
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Original never lost — first compression writes a verbatim backup. To edit and re-compress, **edit `AGENTS.md` itself**, then delete or rename the existing `AGENTS.original.md` so the next `/caveman-compress` can create a fresh backup.
|
|
28
|
+
Original never lost — first compression writes a verbatim backup. To edit and re-compress, **edit `AGENTS.md` itself**, then delete or rename the existing `AGENTS.original.md` so the next `/caveman-compress` can create a fresh backup. Or use `/caveman-compress AGENTS.md --force` to overwrite the existing backup in one step.
|
|
29
29
|
|
|
30
30
|
## Benchmarks
|
|
31
31
|
|
|
@@ -77,7 +77,7 @@ its own model and file tools — there is no separate tool or language to instal
|
|
|
77
77
|
## Usage
|
|
78
78
|
|
|
79
79
|
```
|
|
80
|
-
/caveman-compress <filepath>
|
|
80
|
+
/caveman-compress <filepath> [--force]
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
Examples:
|
|
@@ -87,6 +87,7 @@ Examples:
|
|
|
87
87
|
/caveman-compress CLAUDE.md
|
|
88
88
|
/caveman-compress docs/preferences.md
|
|
89
89
|
/caveman-compress todos.md
|
|
90
|
+
/caveman-compress AGENTS.md --force
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
### What files work
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Compress natural language memory files (AGENTS.md, CLAUDE.md, todos, preferences) into caveman
|
|
5
5
|
format to save input tokens. Preserves all technical substance, code, URLs, and structure.
|
|
6
6
|
Compressed version overwrites the original file. Human-readable backup saved as FILE.original.<ext> (same extension as the source).
|
|
7
|
-
Trigger: /caveman-compress FILEPATH
|
|
7
|
+
Trigger: /caveman-compress FILEPATH [--force]
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Caveman Compress
|
|
@@ -15,16 +15,19 @@ Compress natural language files (`AGENTS.md`, `CLAUDE.md`, todos, preferences) i
|
|
|
15
15
|
|
|
16
16
|
## Trigger
|
|
17
17
|
|
|
18
|
-
`/caveman-compress <filepath>` or when user asks to compress a memory file.
|
|
18
|
+
`/caveman-compress <filepath>` or when user asks to compress a memory file. Append `--force` to overwrite an existing `.original.<ext>` backup instead of aborting.
|
|
19
19
|
|
|
20
20
|
## Process
|
|
21
21
|
|
|
22
|
-
You (the Pi agent) perform the compression directly — there is no separate tool to run. Given `/caveman-compress <filepath
|
|
22
|
+
You (the Pi agent) perform the compression directly — there is no separate tool to run. Given `/caveman-compress <filepath>` (optionally with `--force`):
|
|
23
23
|
|
|
24
24
|
1. **Skip backups.** If the path ends in `.original.<ext>` or, for extensionless files, in `.original` (e.g. `AGENTS.original.md`, `NOTES.original`), stop — never compress a backup file.
|
|
25
25
|
2. **Check it is compressible** per **Boundaries** below: prose files (`.md`, `.txt`, `.rst`, `.typ`, `.typst`, `.tex`, or extensionless natural language). If it is code/config (`.py`, `.js`, `.ts`, `.json`, `.yaml`, …) or larger than ~500 KB, report it is out of scope and stop.
|
|
26
26
|
3. **Read** the file's full contents.
|
|
27
|
-
4. **Back up the original.** If a `.original`/`.original.<ext>` backup already exists
|
|
27
|
+
4. **Back up the original.** If a `.original`/`.original.<ext>` backup already exists:
|
|
28
|
+
- Without `--force`, **abort** and tell the user to remove or rename the stale backup before re-compressing.
|
|
29
|
+
- With `--force`, overwrite the existing backup with a verbatim copy of the current source before any rewrite.
|
|
30
|
+
If no backup exists, write a verbatim copy to `<filename>.original.<ext>` (or `<filename>.original` for extensionless files) before any rewrite.
|
|
28
31
|
5. **Rewrite** the file in place, applying the **Compression Rules** below. Treat code blocks, inline code, URLs, paths, commands, headings, and table structure as read-only regions.
|
|
29
32
|
6. **Self-validate** against the contents you read in step 3: every protected token — fenced and inline code, URLs, file paths, heading text, table structure, dates/version numbers — must be byte-for-byte identical. If any changed, fix just that region; if you cannot make it identical, restore the file from the backup you wrote in step 4 and report the failure rather than leave a corrupted file.
|
|
30
33
|
7. **Report** the result: bytes before/after and the approximate reduction.
|
|
@@ -4,7 +4,13 @@ Quick-reference card. One shot, no mode change.
|
|
|
4
4
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
|
-
Prints a cheat sheet of all caveman modes, sibling skills, deactivation
|
|
7
|
+
Prints a cheat sheet of all caveman modes, sibling skills, deactivation
|
|
8
|
+
triggers, and how mode persists: it is stored as a session entry (survives
|
|
9
|
+
`/reload`), and since v0.4.3 it is also saved per project in
|
|
10
|
+
`.pi/caveman-mode.json` (a new session in the same project directory restores
|
|
11
|
+
the last mode). No config file? Falls back to `off`. One-shot display — does not
|
|
12
|
+
flip the active mode, write flag files, or persist anything. Use when you forget
|
|
13
|
+
the slash commands.
|
|
8
14
|
|
|
9
15
|
## How to invoke
|
|
10
16
|
|
|
@@ -29,7 +29,7 @@ Mode stick until changed or session end.
|
|
|
29
29
|
|-------|---------|-----------|
|
|
30
30
|
| **caveman-commit** | `/caveman-commit` | Terse commit messages. Conventional Commits. ≤50 char subject. |
|
|
31
31
|
| **caveman-review** | `/caveman-review` | One-line PR comments: `L42: bug: user null. Add guard.` |
|
|
32
|
-
| **caveman-compress** | `/caveman-compress <file
|
|
32
|
+
| **caveman-compress** | `/caveman-compress <file> [--force]` | Compress .md files to caveman prose. Saves ~46% input tokens. `--force` overwrites stale backup. |
|
|
33
33
|
| **caveman-stats** | `/caveman-stats` | On-demand, model-driven estimate of tokens saved this session. |
|
|
34
34
|
| **caveman-help** | `/caveman-help` | This card. |
|
|
35
35
|
|
|
@@ -41,12 +41,16 @@ Say "stop caveman" or "normal mode". Resume anytime with `/caveman`.
|
|
|
41
41
|
|
|
42
42
|
Keep user's language by default. User write Portuguese → reply Portuguese caveman. Compress the style, not the language. Technical terms, code, commands, commit types, and exact error strings stay verbatim unless user ask for translation.
|
|
43
43
|
|
|
44
|
-
## Mode
|
|
44
|
+
## Mode persistence
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
Mode set per session entry, so it survives `/reload`. Since v0.4.3 it is also
|
|
47
|
+
saved per project in `.pi/caveman-mode.json`; a new session in the same project
|
|
48
|
+
directory restores the last mode. Session entry overrides project default. No
|
|
49
|
+
config file? Falls back to `off`.
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
`/caveman` (no argument) = `full`. Pick another with `/caveman ultra`,
|
|
52
|
+
`/caveman lite`, etc. Say "stop caveman" or "normal mode" to turn off.
|
|
49
53
|
|
|
50
54
|
## More
|
|
51
55
|
|
|
52
|
-
Full docs: https://github.com/kulapard/pi-caveman
|
|
56
|
+
Full docs: <https://github.com/kulapard/pi-caveman>
|