privateer-agent 0.12.29 → 0.12.30

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.
@@ -23,24 +23,38 @@ import {
23
23
  } from "../src/context.ts";
24
24
 
25
25
  // Honor Pi's own "disable context files" switch, so --no-context-files / -nc silences
26
- // PRIVATEER.md too (not just AGENTS.md/CLAUDE.md) — otherwise the flag would half-work.
26
+ // everything this extension injects, not just PRIVATEER.md — otherwise the flag would
27
+ // half-work. A user who asks for a bare prompt gets a bare prompt.
27
28
  const CONTEXT_FILES_DISABLED =
28
29
  process.argv.includes("--no-context-files") || process.argv.includes("-nc");
29
30
 
30
31
  export default function privateerContext(pi: any): void {
31
- // Inject PRIVATEER.md into every turn's system prompt. The prompt is rebuilt per turn
32
- // and chained across before_agent_start handlers, so appending here is idempotent for
33
- // the turn; the marker guard makes it a no-op if an earlier handler already added it.
32
+ // Inject the runtime guidelines + PRIVATEER.md into every turn's system prompt. The
33
+ // prompt is rebuilt per turn and chained across before_agent_start handlers, so
34
+ // appending here is idempotent for the turn; each marker guard makes its own block a
35
+ // no-op if an earlier handler already added it.
36
+ //
37
+ // ONLY EVER APPEND, AND ONLY RETURN WHEN WE ADDED SOMETHING. Pi chains these handlers
38
+ // and a returned `systemPrompt` REPLACES what the chain has built so far, so both
39
+ // halves matter:
40
+ //
41
+ // • A host that doesn't populate `event.systemPrompt` must not be handed a prompt
42
+ // synthesised from "" — that gives back our two blocks as the ENTIRE system prompt
43
+ // and silently drops the real one. `typeof base !== "string"` is what separates
44
+ // "here is a prompt to chain onto" (possibly empty, legitimate) from "no field".
45
+ // • When both markers are already present (a re-entrant chain) we have nothing to
46
+ // contribute, and undefined leaves what is there alone.
34
47
  pi.on("before_agent_start", (event: any) => {
35
- let prompt: string = event?.systemPrompt ?? "";
36
- if (!prompt.includes(RUNTIME_GUIDELINES_MARKER)) {
37
- prompt += runtimeGuidelinesBlock();
38
- }
39
- if (!CONTEXT_FILES_DISABLED && !prompt.includes(CONTEXT_BLOCK_MARKER)) {
48
+ if (CONTEXT_FILES_DISABLED) return;
49
+ const base = event?.systemPrompt;
50
+ if (typeof base !== "string") return;
51
+ let prompt = base;
52
+ if (!prompt.includes(RUNTIME_GUIDELINES_MARKER)) prompt += runtimeGuidelinesBlock();
53
+ if (!prompt.includes(CONTEXT_BLOCK_MARKER)) {
40
54
  const cwd = event?.systemPromptOptions?.cwd ?? process.cwd();
41
- const block = contextBlock(cwd);
42
- if (block) prompt += block;
55
+ prompt += contextBlock(cwd); // "" when there is no PRIVATEER.md anywhere
43
56
  }
57
+ if (prompt === base) return; // nothing to add — leave the chain alone
44
58
  return { systemPrompt: prompt };
45
59
  });
46
60
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "privateer-agent",
3
- "version": "0.12.29",
3
+ "version": "0.12.30",
4
4
  "description": "Privacy-first terminal coding agent — bring your own model across 20 providers (Anthropic, OpenAI, OpenRouter, Google, local Ollama…). Safe-by-default permissions, MCP, sub-agents, workflows, and verifiable TEE inference. Built on the Pi toolkit.",
5
5
  "type": "module",
6
6
  "license": "MIT",