pi-caveman 1.0.6 → 1.0.8

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 CHANGED
@@ -84,6 +84,16 @@ When active, a status bar displays caveman level and an animated campfire flicke
84
84
 
85
85
  The extension hooks `before_agent_start` to append caveman communication rules to the system prompt at the selected intensity. Within a session, the active level is stored as a custom session entry and restored on resume. Across sessions, persistent config (`~/.pi/agent/caveman.json`) provides the default level and status bar preference. Auto-clarity rules tell the model to drop caveman mode for security warnings or irreversible actions.
86
86
 
87
+ ## Warning
88
+
89
+ Caveman mode only affects _output tokens_, not chain-of-thought tokens, input tokens, file read/write tool calls, etc. If your agent is in a huge codebase and you've given it a complex task, don't expect much token reduction.
90
+
91
+ <p align="center">
92
+ <img src="https://raw.githubusercontent.com/jonjonrankin/pi-caveman/main/shoutout.jpg" alt="pi-caveman glowing review" width="600">
93
+ </p>
94
+
95
+ But for the cost-conscious, every token counts ;)
96
+
87
97
  ## Credits
88
98
 
89
99
  Based on [caveman](https://github.com/JuliusBrussee/caveman) by [Julius Brussee](https://github.com/JuliusBrussee).
@@ -13,7 +13,11 @@
13
13
  import { readFile, writeFile, mkdir } from "node:fs/promises";
14
14
  import { homedir } from "node:os";
15
15
  import { join } from "node:path";
16
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
16
+ import type {
17
+ BeforeAgentStartEventResult,
18
+ ExtensionAPI,
19
+ ExtensionContext,
20
+ } from "@earendil-works/pi-coding-agent";
17
21
  import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
18
22
  import { Container, type SettingItem, SettingsList, Text } from "@earendil-works/pi-tui";
19
23
 
@@ -43,6 +47,18 @@ const CAVEMAN_COMMAND_OPTIONS = [
43
47
  // Persistent config (survives across sessions)
44
48
  // ---------------------------------------------------------------------------
45
49
 
50
+ /**
51
+ * Resolve the pi agent config directory, mirroring pi itself and pi-web-access:
52
+ * 1. PI_CODING_AGENT_DIR env override (already points at the agent dir)
53
+ * 2. $XDG_CONFIG_HOME/pi/agent
54
+ * 3. ~/.pi/agent
55
+ */
56
+ function getConfigDir(): string {
57
+ if (process.env.PI_CODING_AGENT_DIR) return process.env.PI_CODING_AGENT_DIR;
58
+ if (process.env.XDG_CONFIG_HOME) return join(process.env.XDG_CONFIG_HOME, "pi", "agent");
59
+ return join(homedir(), ".pi", "agent");
60
+ }
61
+
46
62
  interface CavemanConfig {
47
63
  /** Level to apply on new sessions. "off" means don't auto-enable. */
48
64
  defaultLevel: Level;
@@ -50,7 +66,7 @@ interface CavemanConfig {
50
66
  showStatus: boolean;
51
67
  }
52
68
 
53
- const CONFIG_PATH = join(homedir(), ".pi", "agent", "caveman.json");
69
+ const CONFIG_PATH = join(getConfigDir(), "caveman.json");
54
70
  const DEFAULT_CONFIG: CavemanConfig = { defaultLevel: "full", showStatus: true };
55
71
  let saveConfigQueue: Promise<void> = Promise.resolve();
56
72
 
@@ -70,7 +86,7 @@ async function loadConfig(): Promise<CavemanConfig> {
70
86
  async function saveConfig(config: CavemanConfig): Promise<void> {
71
87
  const snapshot = JSON.stringify(config, null, 2) + "\n";
72
88
  saveConfigQueue = saveConfigQueue.then(async () => {
73
- await mkdir(join(homedir(), ".pi", "agent"), { recursive: true });
89
+ await mkdir(getConfigDir(), { recursive: true });
74
90
  await writeFile(CONFIG_PATH, snapshot, "utf8");
75
91
  });
76
92
  return saveConfigQueue;
@@ -172,6 +188,18 @@ Auto-clarity: drop caveman for security warnings, irreversible action confirmati
172
188
  or when user is confused. Resume after.
173
189
  Boundaries: write normal code. Only compress explanations. "stop caveman" or "normal mode" reverts.`;
174
190
 
191
+ /** OMP passes ordered string[] blocks; upstream Pi passes one string. */
192
+ function appendSystemPrompt(
193
+ systemPrompt: string | string[] | null | undefined,
194
+ addition: string,
195
+ ): string | string[] {
196
+ if (Array.isArray(systemPrompt)) {
197
+ return [...systemPrompt, addition];
198
+ }
199
+ const basePrompt = typeof systemPrompt === "string" ? systemPrompt : String(systemPrompt ?? "");
200
+ return basePrompt ? `${basePrompt}\n\n${addition}` : addition;
201
+ }
202
+
175
203
  // ---------------------------------------------------------------------------
176
204
  // Extension
177
205
  // ---------------------------------------------------------------------------
@@ -336,7 +364,7 @@ export default function caveman(pi: ExtensionAPI) {
336
364
 
337
365
  const container = new Container();
338
366
  container.addChild(new Text(theme.fg("accent", theme.bold(" Caveman Config")), 0, 0));
339
- container.addChild(new Text(theme.fg("dim", " Saved to ~/.pi/agent/caveman.json"), 0, 0));
367
+ container.addChild(new Text(theme.fg("dim", ` Saved to ${CONFIG_PATH}`), 0, 0));
340
368
  container.addChild(new Text(theme.fg("dim", " Default level applies to future sessions."), 0, 0));
341
369
  container.addChild(new Text("", 0, 0));
342
370
 
@@ -406,13 +434,13 @@ export default function caveman(pi: ExtensionAPI) {
406
434
  pi.on("before_agent_start", async (event) => {
407
435
  await ensureConfigLoaded();
408
436
  if (level === "off") return;
409
- if (level === "micro") {
410
- return {
411
- systemPrompt: `${event.systemPrompt}\n\n${MICRO_PROMPT}`,
412
- };
413
- }
437
+ const addition =
438
+ level === "micro" ? MICRO_PROMPT : `${BASE}\n\n${INTENSITY[level]}\n\n${SAFETY}`;
414
439
  return {
415
- systemPrompt: `${event.systemPrompt}\n\n${BASE}\n\n${INTENSITY[level]}\n\n${SAFETY}`,
416
- };
440
+ systemPrompt: appendSystemPrompt(
441
+ event.systemPrompt as string | string[] | null | undefined,
442
+ addition,
443
+ ),
444
+ } as unknown as BeforeAgentStartEventResult;
417
445
  });
418
446
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-caveman",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Why use many token when few do trick. Caveman mode for pi — cuts ~75% output tokens while keeping full technical accuracy.",
5
5
  "keywords": [
6
6
  "pi-package",