@geohar/pi-cribsheet 0.10.0 → 0.11.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAER,YAAY,EAIf,MAAM,SAAS,CAAA;AA0GhB,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAyIxD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAER,YAAY,EAIf,MAAM,SAAS,CAAA;AA8GhB,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2JxD"}
package/dist/index.js CHANGED
@@ -24,9 +24,11 @@
24
24
  // — see mcp.json.example and the README; static, and unnecessary when combiner-served.
25
25
  // The sharedserver resolution is ported faithfully from plugins/opencode/src/index.ts.
26
26
  import { spawnSync } from "node:child_process";
27
- import { existsSync, readFileSync } from "node:fs";
27
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
28
+ import { homedir } from "node:os";
28
29
  import { dirname, join } from "node:path";
29
30
  import { fileURLToPath } from "node:url";
31
+ import { installCribPlanSource } from "./plan-source.js";
30
32
  import { resolveSharedserver } from "./sharedserver-resolve.js";
31
33
  const DEFAULT_PORT = 7732;
32
34
  const DEFAULT_HOST = "127.0.0.1";
@@ -113,7 +115,10 @@ function detach() {
113
115
  return;
114
116
  const { binary, name } = attachment;
115
117
  attachment = null;
116
- spawnSync(binary, ["unuse", name, "--pid", String(process.pid)], { stdio: "ignore", env: process.env });
118
+ spawnSync(binary, ["unuse", name, "--pid", String(process.pid)], {
119
+ stdio: "ignore",
120
+ env: process.env,
121
+ });
117
122
  }
118
123
  // ── the extension ──────────────────────────────────────────────────
119
124
  export default function cribsheet(pi) {
@@ -134,7 +139,7 @@ export default function cribsheet(pi) {
134
139
  // ── /crib command: recall memory + code index, then steer the model ──
135
140
  if (wantCommand) {
136
141
  pi.registerCommand("crib", {
137
- description: "Consult crib (recall memory + code index); verb: system-prompt shows the directive",
142
+ description: "Consult crib (recall memory + code index); verbs: system-prompt (show the directive), install-config [path] (write mcp.json)",
138
143
  getArgumentCompletions: (prefix) => completeVerbs(prefix),
139
144
  handler: async (args, ctx) => {
140
145
  const arg = args.trim();
@@ -142,6 +147,10 @@ export default function cribsheet(pi) {
142
147
  showDirective(ctx, "cribsheet", CRIB_DIRECTIVE, wantInstructions);
143
148
  return;
144
149
  }
150
+ if (arg === "install-config" || arg.startsWith("install-config ")) {
151
+ installConfig(ctx, arg.slice("install-config".length).trim() || undefined);
152
+ return;
153
+ }
145
154
  const topic = arg;
146
155
  if (!topic) {
147
156
  ctx.ui?.notify?.("crib: give me a topic (e.g. /crib auth flow), or /crib system-prompt", "warn");
@@ -171,10 +180,19 @@ export default function cribsheet(pi) {
171
180
  "back, say so plainly rather than guessing.\n\n" +
172
181
  `Memory — semantic recall (crib note apropos):\n${memory}\n\n` +
173
182
  `Code index — symbols by concept or name (crib code lookup):\n${code}`;
174
- pi.sendMessage({ customType: "crib-recall", content, display: true, details: { topic } }, { triggerTurn: true, deliverAs: "steer" });
183
+ pi.sendMessage({
184
+ customType: "crib-recall",
185
+ content,
186
+ display: true,
187
+ details: { topic },
188
+ }, { triggerTurn: true, deliverAs: "steer" });
175
189
  },
176
190
  });
177
191
  }
192
+ // The crib PLAN SOURCE emits `plan:snapshot` events for a plan sidebar. Independent of
193
+ // server management (it reads via the crib CLI over the in-process bus), so it runs
194
+ // whether or not this plugin launches the backend — register it before the early return.
195
+ installCribPlanSource(pi, { resolveCrib });
178
196
  // Combiner-served or manage=false: nothing to launch (crib runs elsewhere). The
179
197
  // directive + command above still apply.
180
198
  if (served || !manage)
@@ -219,7 +237,10 @@ export default function cribsheet(pi) {
219
237
  useArgs.push("--log-file", logFile);
220
238
  useArgs.push("--", crib.cmd, ...crib.args, ...serve);
221
239
  installProcessCleanup();
222
- const result = spawnSync(binary, useArgs, { stdio: "pipe", env: process.env });
240
+ const result = spawnSync(binary, useArgs, {
241
+ stdio: "pipe",
242
+ env: process.env,
243
+ });
223
244
  if (result.error) {
224
245
  log("error", `${name}: failed to spawn sharedserver (${result.error.message})`);
225
246
  return;
@@ -241,12 +262,91 @@ export default function cribsheet(pi) {
241
262
  // Slash-command verbs. `system-prompt` shows the directive this extension injects — the
242
263
  // show-command pattern from pi-custom-system-prompt, since `before_agent_start`
243
264
  // injections are per-turn and never appear in Pi's own `/system-prompt` (base only).
244
- const COMMAND_VERBS = ["system-prompt"];
265
+ const COMMAND_VERBS = ["system-prompt", "install-config"];
245
266
  function completeVerbs(prefix) {
246
267
  const p = prefix.trim();
247
268
  const matches = COMMAND_VERBS.filter((v) => v.startsWith(p));
248
269
  return matches.length ? matches.map((v) => ({ value: v, label: v })) : null;
249
270
  }
271
+ // ── /crib install-config: write the pi-mcp-adapter mcp.json entry ──
272
+ // A USER-INVOKED write — merge the cribsheet entry into pi-mcp-adapter's mcp.json,
273
+ // wired for crib's optional inbound bearer auth:
274
+ //
275
+ // { "url": "…/mcp", "auth": "bearer", "bearerTokenEnv": "CRIBSHEET_AUTH_TOKEN" }
276
+ //
277
+ // - auth:"bearer" → the adapter attaches `Authorization: Bearer <token>` (it gates the
278
+ // header on `auth === "bearer"`, NOT on bearerTokenEnv alone), AND makes
279
+ // supportsOAuth() false so a wrong/missing token surfaces as an honest 401 rather
280
+ // than a Dynamic-Client-Registration 404.
281
+ // - bearerTokenEnv → names the env var the token is read from at connect (nothing
282
+ // written to disk). The backend enforces only when CRIBSHEET_AUTH_TOKEN is set on ITS
283
+ // side; unset ⇒ open, the env var is unset here too so no header is sent. The one
284
+ // shape is correct whether or not auth is enabled. Ported from mcp-companion's
285
+ // /mcp-combiner install-config.
286
+ function expandHome(p) {
287
+ if (p === "~")
288
+ return homedir();
289
+ if (p.startsWith("~/"))
290
+ return join(homedir(), p.slice(2));
291
+ return p;
292
+ }
293
+ /** The URL the adapter should reach cribsheet at — 127.0.0.1:<port>/mcp with the same
294
+ * port defaults the backend serves on ($PI_CRIBSHEET_PORT, else 7732). */
295
+ function defaultCribUrl() {
296
+ let port = DEFAULT_PORT;
297
+ const raw = env("PI_CRIBSHEET_PORT");
298
+ if (raw !== undefined) {
299
+ const n = Number(raw);
300
+ if (Number.isInteger(n) && n > 0)
301
+ port = n;
302
+ }
303
+ return `http://127.0.0.1:${port}/mcp`;
304
+ }
305
+ function installConfig(ctx, pathArg) {
306
+ const target = pathArg ? expandHome(pathArg) : join(homedir(), ".config", "mcp", "mcp.json");
307
+ const key = DEFAULT_NAME;
308
+ // Read + parse existing (tolerate absence; refuse to clobber non-JSON).
309
+ let doc = {};
310
+ if (existsSync(target)) {
311
+ try {
312
+ const parsed = JSON.parse(readFileSync(target, "utf8"));
313
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
314
+ ctx.ui?.notify?.(`cribsheet: ${target} is not a JSON object; not overwriting`, "error");
315
+ return;
316
+ }
317
+ doc = parsed;
318
+ }
319
+ catch (e) {
320
+ ctx.ui?.notify?.(`cribsheet: ${target} is not valid JSON; not overwriting (${e})`, "error");
321
+ return;
322
+ }
323
+ }
324
+ const servers = (doc.mcpServers ??= {});
325
+ const prev = (servers[key] ?? {});
326
+ const before = JSON.stringify(prev);
327
+ // Preserve any existing url and other fields; only ensure the auth-wiring keys.
328
+ servers[key] = {
329
+ ...prev,
330
+ url: typeof prev.url === "string" && prev.url ? prev.url : defaultCribUrl(),
331
+ auth: "bearer",
332
+ bearerTokenEnv: "CRIBSHEET_AUTH_TOKEN",
333
+ };
334
+ const existed = before !== "{}" && Object.keys(prev).length > 0;
335
+ const changed = before !== JSON.stringify(servers[key]);
336
+ try {
337
+ mkdirSync(dirname(target), { recursive: true });
338
+ writeFileSync(target, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
339
+ }
340
+ catch (e) {
341
+ ctx.ui?.notify?.(`cribsheet: failed to write ${target} (${e})`, "error");
342
+ return;
343
+ }
344
+ const what = existed ? changed ? "updated" : "already configured" : "added";
345
+ ctx.ui?.notify?.(`cribsheet: ${what} "${key}" in ${target}\n` +
346
+ `Sends "Authorization: Bearer $CRIBSHEET_AUTH_TOKEN" when that env var is set ` +
347
+ `(auth:"bearer" both sends the token and suppresses OAuth probing). ` +
348
+ `Run /reload so pi-mcp-adapter re-reads mcp.json.`, "info");
349
+ }
250
350
  const SHOW_LIMIT = 1600;
251
351
  function showDirective(ctx, label, directive, enabled) {
252
352
  if (!directive) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/pi.d.ts CHANGED
@@ -14,6 +14,15 @@ export type BeforeAgentStartEvent = {
14
14
  export type BeforeAgentStartResult = {
15
15
  systemPrompt?: string;
16
16
  } | void;
17
+ /** Fired after a tool finishes. We read only `toolName` (to spot crib plan mutations). */
18
+ export type ToolExecutionEndEvent = {
19
+ toolName: string;
20
+ args?: unknown;
21
+ result?: unknown;
22
+ isError?: boolean;
23
+ };
24
+ /** Fired at the end of an agent turn — our natural coalescing point for re-snapshots. */
25
+ export type TurnEndEvent = Record<string, never>;
17
26
  export type ExtensionContext = {
18
27
  cwd: string;
19
28
  mode: "tui" | "rpc" | "json" | "print";
@@ -63,8 +72,19 @@ export interface ExtensionAPI {
63
72
  on(event: "session_start", handler: (event: SessionStartEvent, ctx: ExtensionContext) => void | Promise<void>): void;
64
73
  on(event: "session_shutdown", handler: (event: SessionShutdownEvent, ctx: ExtensionContext) => void | Promise<void>): void;
65
74
  on(event: "before_agent_start", handler: (event: BeforeAgentStartEvent, ctx: ExtensionContext) => BeforeAgentStartResult | Promise<BeforeAgentStartResult>): void;
75
+ on(event: "tool_execution_end", handler: (event: ToolExecutionEndEvent, ctx: ExtensionContext) => void | Promise<void>): void;
76
+ on(event: "turn_end", handler: (event: TurnEndEvent, ctx: ExtensionContext) => void | Promise<void>): void;
66
77
  registerCommand(name: string, spec: CommandSpec): void;
67
78
  exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
68
79
  sendMessage(message: SendMessage, options?: SendMessageOptions): void;
80
+ /** Persist a custom session entry; emits `entry_appended` (forwarded over RPC, but NOT
81
+ * delivered to in-process extension `on` handlers). For RPC consumers (pi-acp). */
82
+ appendEntry(customType: string, data?: unknown): string;
83
+ /** Shared in-process pub/sub bus across all extensions (how `subagents:*` crosses
84
+ * extensions). The channel for in-process consumers like pi-plan's TUI. Not RPC-forwarded. */
85
+ events: {
86
+ on(channel: string, handler: (data: unknown) => void): () => void;
87
+ emit(channel: string, data?: unknown): void;
88
+ };
69
89
  }
70
90
  //# sourceMappingURL=pi.d.ts.map
package/dist/pi.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pi.d.ts","sourceRoot":"","sources":["../src/pi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pi.d.ts","sourceRoot":"","sources":["../src/pi.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;AACjF,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEjF,MAAM,MAAM,iBAAiB,GAAG;IAC5B,MAAM,EAAE,kBAAkB,CAAA;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC/B,CAAA;AACD,MAAM,MAAM,oBAAoB,GAAG;IAC/B,MAAM,EAAE,qBAAqB,CAAA;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAA;AACD,MAAM,MAAM,qBAAqB,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAA;AAC5D,MAAM,MAAM,sBAAsB,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAA;AAErE,0FAA0F;AAC1F,MAAM,MAAM,qBAAqB,GAAG;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AACD,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;AAEhD,MAAM,MAAM,gBAAgB,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;IACtC,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,EAAE,CAAC,EAAE;QACD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,KAAK,IAAI,CAAA;KACxE,CAAA;CACJ,CAAA;AAED;6CAC6C;AAC7C,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,CAAA;AAEtD,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhE,MAAM,MAAM,UAAU,GAAG;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;CAClB,CAAA;AACD,MAAM,MAAM,WAAW,GAAG;IACtB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAC1B,CAAA;AAED;mFACmF;AACnF,MAAM,MAAM,WAAW,GAAG;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC,CAAA;AACD,MAAM,MAAM,kBAAkB,GAAG;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7E,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,gBAAgB,EAAE,GAAG,IAAI,CAAA;CACzE,CAAA;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACpH,EAAE,CACE,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACtF,IAAI,CAAA;IACP,EAAE,CACE,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,CACL,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,gBAAgB,KACpB,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAC9D,IAAI,CAAA;IACP,EAAE,CACE,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACvF,IAAI,CAAA;IACP,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC1G,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACtD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACjF,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;IACrE;wFACoF;IACpF,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IACvD;mGAC+F;IAC/F,MAAM,EAAE;QACJ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;QACjE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;KAC9C,CAAA;CACJ"}
@@ -0,0 +1,67 @@
1
+ import type { ExtensionAPI } from "./pi.js";
2
+ /** One item in the shared plan wire format. Rich fields (`kind`, `tainted`, `deps`) are
3
+ * populated by cribsheet; a simpler source may omit them. */
4
+ export interface PlanItem {
5
+ /** crib's namespaced id, `<kind>:<slug>` (already the wire id scheme). */
6
+ id: string;
7
+ /** display text (the wire field is `title`). */
8
+ title: string;
9
+ /** kind passed through verbatim from crib (plan|design|note). */
10
+ kind: string;
11
+ status: string | null;
12
+ /** must-precede refs (this item depends on these), by node id. */
13
+ deps: string[];
14
+ tainted?: boolean;
15
+ ulid?: string;
16
+ updated?: string;
17
+ }
18
+ /** A full-replace snapshot on the `plan:snapshot` channel. `ns` attributes the source;
19
+ * `seq` lets a consumer drop out-of-order arrivals. */
20
+ export interface PlanSnapshot {
21
+ ns: "cribsheet";
22
+ seq: number;
23
+ project?: string;
24
+ items: PlanItem[];
25
+ }
26
+ interface CribNode {
27
+ id: string;
28
+ ulid?: string;
29
+ name?: string;
30
+ kind?: string;
31
+ status?: string | null;
32
+ updated?: string;
33
+ tainted?: boolean;
34
+ }
35
+ interface CribEdge {
36
+ from: string;
37
+ to: string;
38
+ kind: string;
39
+ }
40
+ interface CribGraph {
41
+ project?: string;
42
+ nodes?: CribNode[];
43
+ edges?: CribEdge[];
44
+ }
45
+ /** Map a crib `plan graph` payload into a `source=plan` snapshot. Edge `from -> to`
46
+ * (kind `dep`) means `from` depends on `to`, so `to` lands in `from`'s `deps`. */
47
+ export declare function graphToSnapshot(graph: CribGraph, seq: number): PlanSnapshot;
48
+ export declare function isCribPlanMutation(toolName: string): boolean;
49
+ /** How to invoke crib — mirrors index.ts's resolveCrib() shape. */
50
+ export type CribCommand = {
51
+ cmd: string;
52
+ args: string[];
53
+ };
54
+ export interface PlanSourceOptions {
55
+ /** Resolve the crib CLI (env command → `crib` on PATH → `uv run … crib`). */
56
+ resolveCrib: () => CribCommand | undefined;
57
+ /** Pull timeout in ms (default 15000). */
58
+ timeoutMs?: number;
59
+ }
60
+ /**
61
+ * Wire the crib plan source into the extension: prime on `session_start`, mark dirty when
62
+ * a crib plan-mutation tool completes, and re-snapshot at `turn_end` if dirty. Emits via
63
+ * `pi.events.emit("plan:snapshot", snapshot)` on the shared in-process bus (for pi-plan's TUI).
64
+ */
65
+ export declare function installCribPlanSource(pi: ExtensionAPI, opts: PlanSourceOptions): void;
66
+ export {};
67
+ //# sourceMappingURL=plan-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-source.d.ts","sourceRoot":"","sources":["../src/plan-source.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C;8DAC8D;AAC9D,MAAM,WAAW,QAAQ;IACrB,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAA;IACV,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,kEAAkE;IAClE,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;wDACwD;AACxD,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,WAAW,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,QAAQ,EAAE,CAAA;CACpB;AAGD,UAAU,QAAQ;IACd,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;CACpB;AACD,UAAU,QAAQ;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACf;AACD,UAAU,SAAS;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;CACrB;AAED;mFACmF;AACnF,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAqB3E;AAiBD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAS5D;AAED,mEAAmE;AACnE,MAAM,MAAM,WAAW,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAEzD,MAAM,WAAW,iBAAiB;IAC9B,6EAA6E;IAC7E,WAAW,EAAE,MAAM,WAAW,GAAG,SAAS,CAAA;IAC1C,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAqDrF"}
@@ -0,0 +1,132 @@
1
+ // The crib PLAN SOURCE: surfaces cribsheet's plan graph onto pi's in-process bus as
2
+ // `plan:snapshot` events, so a plan sidebar (pi-plan TUI, or the pi-acp ACP adapter over
3
+ // RPC) can render it. cribsheet is one PLAN source among many; it publishes the shared
4
+ // wire format with `ns:"cribsheet"` — only this plugin knows crib's CLI/schema.
5
+ //
6
+ // Snapshot-based (not delta): each emit carries the WHOLE current cribsheet plan; consumers
7
+ // replace their `cribsheet` slice. Prime on session_start; re-snapshot after a crib plan
8
+ // MUTATION tool completes (coalesced to turn_end). A missed trigger self-heals on the next
9
+ // snapshot — the trigger is a cache-invalidation ping, not the data.
10
+ //
11
+ // CHANNEL: emits on the shared in-process `pi.events` bus (`plan:snapshot`), which is how an
12
+ // in-process consumer (pi-plan's TUI) receives it. `appendEntry` is NOT used here: pi-acp
13
+ // runs its own bundled extension that re-emits this bus event as an `acp:plan` custom entry
14
+ // to cross RPC (entry_appended is forwarded over RPC, but is NOT delivered to in-process
15
+ // extension `on` handlers).
16
+ /** Map a crib `plan graph` payload into a `source=plan` snapshot. Edge `from -> to`
17
+ * (kind `dep`) means `from` depends on `to`, so `to` lands in `from`'s `deps`. */
18
+ export function graphToSnapshot(graph, seq) {
19
+ const depsByNode = new Map();
20
+ for (const e of graph.edges ?? []) {
21
+ if (!e || e.kind !== "dep" || typeof e.from !== "string" || typeof e.to !== "string")
22
+ continue;
23
+ const arr = depsByNode.get(e.from);
24
+ if (arr)
25
+ arr.push(e.to);
26
+ else
27
+ depsByNode.set(e.from, [e.to]);
28
+ }
29
+ const items = (graph.nodes ?? [])
30
+ .filter((n) => !!n && typeof n.id === "string")
31
+ .map((n) => ({
32
+ id: n.id,
33
+ title: typeof n.name === "string" ? n.name : n.id,
34
+ kind: typeof n.kind === "string" ? n.kind : "plan",
35
+ status: n.status ?? null,
36
+ deps: depsByNode.get(n.id) ?? [],
37
+ tainted: n.tainted,
38
+ ulid: n.ulid,
39
+ updated: n.updated,
40
+ }));
41
+ return { ns: "cribsheet", seq, project: graph.project, items };
42
+ }
43
+ // ── crib plan MUTATION tools (reads are ignored) ───────────────────
44
+ // Tools arrive combiner/client-PREFIXED (e.g. cribsheet_plan_add, or the longer
45
+ // mcp__…-combiner__cribsheet_plan_add), so match on the TAIL, with a separator
46
+ // boundary so `plan_add` can't spuriously match e.g. `explain_add`.
47
+ const CRIB_PLAN_MUTATION_VERBS = [
48
+ "plan_dep_remove",
49
+ "plan_dep_add",
50
+ "plan_reaffirm",
51
+ "plan_import",
52
+ "plan_status",
53
+ "plan_forget",
54
+ "plan_move",
55
+ "plan_add",
56
+ ];
57
+ export function isCribPlanMutation(toolName) {
58
+ for (const verb of CRIB_PLAN_MUTATION_VERBS) {
59
+ if (toolName === verb)
60
+ return true;
61
+ if (toolName.endsWith(verb)) {
62
+ const boundary = toolName[toolName.length - verb.length - 1];
63
+ if (boundary === "_" || boundary === ":" || boundary === "/")
64
+ return true;
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+ /**
70
+ * Wire the crib plan source into the extension: prime on `session_start`, mark dirty when
71
+ * a crib plan-mutation tool completes, and re-snapshot at `turn_end` if dirty. Emits via
72
+ * `pi.events.emit("plan:snapshot", snapshot)` on the shared in-process bus (for pi-plan's TUI).
73
+ */
74
+ export function installCribPlanSource(pi, opts) {
75
+ const timeout = opts.timeoutMs ?? 15_000;
76
+ let seq = 0;
77
+ let dirty = false;
78
+ let lastCwd;
79
+ // Guard against overlapping pulls (a burst of turn_end + a slow crib).
80
+ let pulling = false;
81
+ const pull = async (cwd, signal) => {
82
+ if (pulling)
83
+ return;
84
+ const crib = opts.resolveCrib();
85
+ if (!crib)
86
+ return;
87
+ pulling = true;
88
+ try {
89
+ // Global `--json` goes BEFORE the subcommand. Run crib IN the session cwd
90
+ // and select the project with `-P .` — the CLI resolves it to the absolute
91
+ // client path, so the daemon anchors on the right project (not `default`).
92
+ const res = await pi.exec(crib.cmd, [...crib.args, "--json", "plan", "graph", "-P", "."], {
93
+ signal,
94
+ timeout,
95
+ cwd,
96
+ });
97
+ if (res.code !== 0)
98
+ return;
99
+ let graph;
100
+ try {
101
+ graph = JSON.parse(res.stdout);
102
+ }
103
+ catch {
104
+ return;
105
+ }
106
+ pi.events.emit("plan:snapshot", graphToSnapshot(graph, seq++));
107
+ }
108
+ catch {
109
+ // best effort; a dropped snapshot self-heals on the next trigger
110
+ }
111
+ finally {
112
+ pulling = false;
113
+ }
114
+ };
115
+ pi.on("session_start", (_event, ctx) => {
116
+ lastCwd = ctx.cwd;
117
+ // Prime: surface whatever plan already exists (incl. edits from before this session).
118
+ void pull(ctx.cwd, ctx.signal);
119
+ });
120
+ pi.on("tool_execution_end", (event) => {
121
+ if (isCribPlanMutation(event.toolName))
122
+ dirty = true;
123
+ });
124
+ // Coalesce a turn's worth of mutations into one re-snapshot after they've all landed.
125
+ pi.on("turn_end", (_event, ctx) => {
126
+ if (!dirty)
127
+ return;
128
+ dirty = false;
129
+ void pull(ctx.cwd ?? lastCwd ?? process.cwd(), ctx.signal);
130
+ });
131
+ }
132
+ //# sourceMappingURL=plan-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-source.js","sourceRoot":"","sources":["../src/plan-source.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geohar/pi-cribsheet",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Pi extension: run the crib (cribsheet) memory + code-index MCP server via sharedserver, inject the reach-for-crib directive, and ship the /crib recall command. Pairs with pi-mcp-adapter.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/index.ts CHANGED
@@ -25,7 +25,8 @@
25
25
  // The sharedserver resolution is ported faithfully from plugins/opencode/src/index.ts.
26
26
 
27
27
  import { spawnSync } from "node:child_process"
28
- import { existsSync, readFileSync } from "node:fs"
28
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"
29
+ import { homedir } from "node:os"
29
30
  import { dirname, join } from "node:path"
30
31
  import { fileURLToPath } from "node:url"
31
32
  import type {
@@ -35,6 +36,7 @@ import type {
35
36
  ExtensionContext,
36
37
  SessionShutdownEvent,
37
38
  } from "./pi.js"
39
+ import { installCribPlanSource } from "./plan-source.js"
38
40
  import { resolveSharedserver } from "./sharedserver-resolve.js"
39
41
 
40
42
  const DEFAULT_PORT = 7732
@@ -135,7 +137,10 @@ function detach() {
135
137
  if (!attachment) return
136
138
  const { binary, name } = attachment
137
139
  attachment = null
138
- spawnSync(binary, ["unuse", name, "--pid", String(process.pid)], { stdio: "ignore", env: process.env })
140
+ spawnSync(binary, ["unuse", name, "--pid", String(process.pid)], {
141
+ stdio: "ignore",
142
+ env: process.env,
143
+ })
139
144
  }
140
145
 
141
146
  // ── the extension ──────────────────────────────────────────────────
@@ -158,7 +163,8 @@ export default function cribsheet(pi: ExtensionAPI): void {
158
163
  // ── /crib command: recall memory + code index, then steer the model ──
159
164
  if (wantCommand) {
160
165
  pi.registerCommand("crib", {
161
- description: "Consult crib (recall memory + code index); verb: system-prompt shows the directive",
166
+ description:
167
+ "Consult crib (recall memory + code index); verbs: system-prompt (show the directive), install-config [path] (write mcp.json)",
162
168
  getArgumentCompletions: (prefix) => completeVerbs(prefix),
163
169
  handler: async (args, ctx) => {
164
170
  const arg = args.trim()
@@ -166,6 +172,10 @@ export default function cribsheet(pi: ExtensionAPI): void {
166
172
  showDirective(ctx, "cribsheet", CRIB_DIRECTIVE, wantInstructions)
167
173
  return
168
174
  }
175
+ if (arg === "install-config" || arg.startsWith("install-config ")) {
176
+ installConfig(ctx, arg.slice("install-config".length).trim() || undefined)
177
+ return
178
+ }
169
179
  const topic = arg
170
180
  if (!topic) {
171
181
  ctx.ui?.notify?.("crib: give me a topic (e.g. /crib auth flow), or /crib system-prompt", "warn")
@@ -196,13 +206,23 @@ export default function cribsheet(pi: ExtensionAPI): void {
196
206
  `Memory — semantic recall (crib note apropos):\n${memory}\n\n` +
197
207
  `Code index — symbols by concept or name (crib code lookup):\n${code}`
198
208
  pi.sendMessage(
199
- { customType: "crib-recall", content, display: true, details: { topic } },
209
+ {
210
+ customType: "crib-recall",
211
+ content,
212
+ display: true,
213
+ details: { topic },
214
+ },
200
215
  { triggerTurn: true, deliverAs: "steer" },
201
216
  )
202
217
  },
203
218
  })
204
219
  }
205
220
 
221
+ // The crib PLAN SOURCE emits `plan:snapshot` events for a plan sidebar. Independent of
222
+ // server management (it reads via the crib CLI over the in-process bus), so it runs
223
+ // whether or not this plugin launches the backend — register it before the early return.
224
+ installCribPlanSource(pi, { resolveCrib })
225
+
206
226
  // Combiner-served or manage=false: nothing to launch (crib runs elsewhere). The
207
227
  // directive + command above still apply.
208
228
  if (served || !manage) return
@@ -259,7 +279,10 @@ export default function cribsheet(pi: ExtensionAPI): void {
259
279
  useArgs.push("--", crib.cmd, ...crib.args, ...serve)
260
280
 
261
281
  installProcessCleanup()
262
- const result = spawnSync(binary, useArgs, { stdio: "pipe", env: process.env })
282
+ const result = spawnSync(binary, useArgs, {
283
+ stdio: "pipe",
284
+ env: process.env,
285
+ })
263
286
  if (result.error) {
264
287
  log("error", `${name}: failed to spawn sharedserver (${result.error.message})`)
265
288
  return
@@ -284,13 +307,98 @@ export default function cribsheet(pi: ExtensionAPI): void {
284
307
  // Slash-command verbs. `system-prompt` shows the directive this extension injects — the
285
308
  // show-command pattern from pi-custom-system-prompt, since `before_agent_start`
286
309
  // injections are per-turn and never appear in Pi's own `/system-prompt` (base only).
287
- const COMMAND_VERBS = ["system-prompt"]
310
+ const COMMAND_VERBS = ["system-prompt", "install-config"]
288
311
  function completeVerbs(prefix: string): AutocompleteItem[] | null {
289
312
  const p = prefix.trim()
290
313
  const matches = COMMAND_VERBS.filter((v) => v.startsWith(p))
291
314
  return matches.length ? matches.map((v) => ({ value: v, label: v })) : null
292
315
  }
293
316
 
317
+ // ── /crib install-config: write the pi-mcp-adapter mcp.json entry ──
318
+ // A USER-INVOKED write — merge the cribsheet entry into pi-mcp-adapter's mcp.json,
319
+ // wired for crib's optional inbound bearer auth:
320
+ //
321
+ // { "url": "…/mcp", "auth": "bearer", "bearerTokenEnv": "CRIBSHEET_AUTH_TOKEN" }
322
+ //
323
+ // - auth:"bearer" → the adapter attaches `Authorization: Bearer <token>` (it gates the
324
+ // header on `auth === "bearer"`, NOT on bearerTokenEnv alone), AND makes
325
+ // supportsOAuth() false so a wrong/missing token surfaces as an honest 401 rather
326
+ // than a Dynamic-Client-Registration 404.
327
+ // - bearerTokenEnv → names the env var the token is read from at connect (nothing
328
+ // written to disk). The backend enforces only when CRIBSHEET_AUTH_TOKEN is set on ITS
329
+ // side; unset ⇒ open, the env var is unset here too so no header is sent. The one
330
+ // shape is correct whether or not auth is enabled. Ported from mcp-companion's
331
+ // /mcp-combiner install-config.
332
+
333
+ function expandHome(p: string): string {
334
+ if (p === "~") return homedir()
335
+ if (p.startsWith("~/")) return join(homedir(), p.slice(2))
336
+ return p
337
+ }
338
+
339
+ /** The URL the adapter should reach cribsheet at — 127.0.0.1:<port>/mcp with the same
340
+ * port defaults the backend serves on ($PI_CRIBSHEET_PORT, else 7732). */
341
+ function defaultCribUrl(): string {
342
+ let port = DEFAULT_PORT
343
+ const raw = env("PI_CRIBSHEET_PORT")
344
+ if (raw !== undefined) {
345
+ const n = Number(raw)
346
+ if (Number.isInteger(n) && n > 0) port = n
347
+ }
348
+ return `http://127.0.0.1:${port}/mcp`
349
+ }
350
+
351
+ function installConfig(ctx: ExtensionCommandContext, pathArg?: string): void {
352
+ const target = pathArg ? expandHome(pathArg) : join(homedir(), ".config", "mcp", "mcp.json")
353
+ const key = DEFAULT_NAME
354
+
355
+ // Read + parse existing (tolerate absence; refuse to clobber non-JSON).
356
+ let doc: Record<string, unknown> = {}
357
+ if (existsSync(target)) {
358
+ try {
359
+ const parsed = JSON.parse(readFileSync(target, "utf8"))
360
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
361
+ ctx.ui?.notify?.(`cribsheet: ${target} is not a JSON object; not overwriting`, "error")
362
+ return
363
+ }
364
+ doc = parsed as Record<string, unknown>
365
+ } catch (e) {
366
+ ctx.ui?.notify?.(`cribsheet: ${target} is not valid JSON; not overwriting (${e})`, "error")
367
+ return
368
+ }
369
+ }
370
+
371
+ const servers = (doc.mcpServers ??= {}) as Record<string, Record<string, unknown>>
372
+ const prev = (servers[key] ?? {}) as Record<string, unknown>
373
+ const before = JSON.stringify(prev)
374
+ // Preserve any existing url and other fields; only ensure the auth-wiring keys.
375
+ servers[key] = {
376
+ ...prev,
377
+ url: typeof prev.url === "string" && prev.url ? prev.url : defaultCribUrl(),
378
+ auth: "bearer",
379
+ bearerTokenEnv: "CRIBSHEET_AUTH_TOKEN",
380
+ }
381
+ const existed = before !== "{}" && Object.keys(prev).length > 0
382
+ const changed = before !== JSON.stringify(servers[key])
383
+
384
+ try {
385
+ mkdirSync(dirname(target), { recursive: true })
386
+ writeFileSync(target, `${JSON.stringify(doc, null, 2)}\n`, "utf8")
387
+ } catch (e) {
388
+ ctx.ui?.notify?.(`cribsheet: failed to write ${target} (${e})`, "error")
389
+ return
390
+ }
391
+
392
+ const what = existed ? changed ? "updated" : "already configured" : "added"
393
+ ctx.ui?.notify?.(
394
+ `cribsheet: ${what} "${key}" in ${target}\n` +
395
+ `Sends "Authorization: Bearer $CRIBSHEET_AUTH_TOKEN" when that env var is set ` +
396
+ `(auth:"bearer" both sends the token and suppresses OAuth probing). ` +
397
+ `Run /reload so pi-mcp-adapter re-reads mcp.json.`,
398
+ "info",
399
+ )
400
+ }
401
+
294
402
  const SHOW_LIMIT = 1600
295
403
  function showDirective(ctx: ExtensionCommandContext, label: string, directive: string, enabled: boolean): void {
296
404
  if (!directive) {
package/src/pi.ts CHANGED
@@ -10,17 +10,35 @@
10
10
  export type SessionStartReason = "startup" | "reload" | "new" | "resume" | "fork"
11
11
  export type SessionShutdownReason = "quit" | "reload" | "new" | "resume" | "fork"
12
12
 
13
- export type SessionStartEvent = { reason: SessionStartReason; previousSessionFile?: string }
14
- export type SessionShutdownEvent = { reason: SessionShutdownReason; targetSessionFile?: string }
13
+ export type SessionStartEvent = {
14
+ reason: SessionStartReason
15
+ previousSessionFile?: string
16
+ }
17
+ export type SessionShutdownEvent = {
18
+ reason: SessionShutdownReason
19
+ targetSessionFile?: string
20
+ }
15
21
  export type BeforeAgentStartEvent = { systemPrompt: string }
16
22
  export type BeforeAgentStartResult = { systemPrompt?: string } | void
17
23
 
24
+ /** Fired after a tool finishes. We read only `toolName` (to spot crib plan mutations). */
25
+ export type ToolExecutionEndEvent = {
26
+ toolName: string
27
+ args?: unknown
28
+ result?: unknown
29
+ isError?: boolean
30
+ }
31
+ /** Fired at the end of an agent turn — our natural coalescing point for re-snapshots. */
32
+ export type TurnEndEvent = Record<string, never>
33
+
18
34
  export type ExtensionContext = {
19
35
  cwd: string
20
36
  mode: "tui" | "rpc" | "json" | "print"
21
37
  hasUI: boolean
22
38
  signal?: AbortSignal
23
- ui?: { notify?: (message: string, level?: "info" | "warn" | "error") => void }
39
+ ui?: {
40
+ notify?: (message: string, level?: "info" | "warn" | "error") => void
41
+ }
24
42
  }
25
43
 
26
44
  /** Context handed to a command handler. Superset of ExtensionContext in practice; we
@@ -29,8 +47,18 @@ export type ExtensionCommandContext = ExtensionContext
29
47
 
30
48
  export type AutocompleteItem = { value: string; label?: string }
31
49
 
32
- export type ExecResult = { stdout: string; stderr: string; code: number; killed: boolean }
33
- export type ExecOptions = { signal?: AbortSignal; timeout?: number; cwd?: string; env?: NodeJS.ProcessEnv }
50
+ export type ExecResult = {
51
+ stdout: string
52
+ stderr: string
53
+ code: number
54
+ killed: boolean
55
+ }
56
+ export type ExecOptions = {
57
+ signal?: AbortSignal
58
+ timeout?: number
59
+ cwd?: string
60
+ env?: NodeJS.ProcessEnv
61
+ }
34
62
 
35
63
  /** An LLM-visible message injected from a command. `display:true` shows it in the TUI;
36
64
  * `{triggerTurn:true, deliverAs:"steer"}` makes the model act on it this turn. */
@@ -40,7 +68,10 @@ export type SendMessage = {
40
68
  display?: boolean
41
69
  details?: Record<string, unknown>
42
70
  }
43
- export type SendMessageOptions = { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" }
71
+ export type SendMessageOptions = {
72
+ triggerTurn?: boolean
73
+ deliverAs?: "steer" | "followUp"
74
+ }
44
75
 
45
76
  export type CommandSpec = {
46
77
  description: string
@@ -49,10 +80,7 @@ export type CommandSpec = {
49
80
  }
50
81
 
51
82
  export interface ExtensionAPI {
52
- on(
53
- event: "session_start",
54
- handler: (event: SessionStartEvent, ctx: ExtensionContext) => void | Promise<void>,
55
- ): void
83
+ on(event: "session_start", handler: (event: SessionStartEvent, ctx: ExtensionContext) => void | Promise<void>): void
56
84
  on(
57
85
  event: "session_shutdown",
58
86
  handler: (event: SessionShutdownEvent, ctx: ExtensionContext) => void | Promise<void>,
@@ -64,7 +92,21 @@ export interface ExtensionAPI {
64
92
  ctx: ExtensionContext,
65
93
  ) => BeforeAgentStartResult | Promise<BeforeAgentStartResult>,
66
94
  ): void
95
+ on(
96
+ event: "tool_execution_end",
97
+ handler: (event: ToolExecutionEndEvent, ctx: ExtensionContext) => void | Promise<void>,
98
+ ): void
99
+ on(event: "turn_end", handler: (event: TurnEndEvent, ctx: ExtensionContext) => void | Promise<void>): void
67
100
  registerCommand(name: string, spec: CommandSpec): void
68
101
  exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>
69
102
  sendMessage(message: SendMessage, options?: SendMessageOptions): void
103
+ /** Persist a custom session entry; emits `entry_appended` (forwarded over RPC, but NOT
104
+ * delivered to in-process extension `on` handlers). For RPC consumers (pi-acp). */
105
+ appendEntry(customType: string, data?: unknown): string
106
+ /** Shared in-process pub/sub bus across all extensions (how `subagents:*` crosses
107
+ * extensions). The channel for in-process consumers like pi-plan's TUI. Not RPC-forwarded. */
108
+ events: {
109
+ on(channel: string, handler: (data: unknown) => void): () => void
110
+ emit(channel: string, data?: unknown): void
111
+ }
70
112
  }
@@ -0,0 +1,185 @@
1
+ // The crib PLAN SOURCE: surfaces cribsheet's plan graph onto pi's in-process bus as
2
+ // `plan:snapshot` events, so a plan sidebar (pi-plan TUI, or the pi-acp ACP adapter over
3
+ // RPC) can render it. cribsheet is one PLAN source among many; it publishes the shared
4
+ // wire format with `ns:"cribsheet"` — only this plugin knows crib's CLI/schema.
5
+ //
6
+ // Snapshot-based (not delta): each emit carries the WHOLE current cribsheet plan; consumers
7
+ // replace their `cribsheet` slice. Prime on session_start; re-snapshot after a crib plan
8
+ // MUTATION tool completes (coalesced to turn_end). A missed trigger self-heals on the next
9
+ // snapshot — the trigger is a cache-invalidation ping, not the data.
10
+ //
11
+ // CHANNEL: emits on the shared in-process `pi.events` bus (`plan:snapshot`), which is how an
12
+ // in-process consumer (pi-plan's TUI) receives it. `appendEntry` is NOT used here: pi-acp
13
+ // runs its own bundled extension that re-emits this bus event as an `acp:plan` custom entry
14
+ // to cross RPC (entry_appended is forwarded over RPC, but is NOT delivered to in-process
15
+ // extension `on` handlers).
16
+
17
+ import type { ExtensionAPI } from "./pi.js"
18
+
19
+ /** One item in the shared plan wire format. Rich fields (`kind`, `tainted`, `deps`) are
20
+ * populated by cribsheet; a simpler source may omit them. */
21
+ export interface PlanItem {
22
+ /** crib's namespaced id, `<kind>:<slug>` (already the wire id scheme). */
23
+ id: string
24
+ /** display text (the wire field is `title`). */
25
+ title: string
26
+ /** kind passed through verbatim from crib (plan|design|note). */
27
+ kind: string
28
+ status: string | null
29
+ /** must-precede refs (this item depends on these), by node id. */
30
+ deps: string[]
31
+ tainted?: boolean
32
+ ulid?: string
33
+ updated?: string
34
+ }
35
+
36
+ /** A full-replace snapshot on the `plan:snapshot` channel. `ns` attributes the source;
37
+ * `seq` lets a consumer drop out-of-order arrivals. */
38
+ export interface PlanSnapshot {
39
+ ns: "cribsheet"
40
+ seq: number
41
+ project?: string
42
+ items: PlanItem[]
43
+ }
44
+
45
+ // ── crib `plan graph --json` shapes ────────────────────────────────
46
+ interface CribNode {
47
+ id: string
48
+ ulid?: string
49
+ name?: string
50
+ kind?: string
51
+ status?: string | null
52
+ updated?: string
53
+ tainted?: boolean
54
+ }
55
+ interface CribEdge {
56
+ from: string
57
+ to: string
58
+ kind: string
59
+ }
60
+ interface CribGraph {
61
+ project?: string
62
+ nodes?: CribNode[]
63
+ edges?: CribEdge[]
64
+ }
65
+
66
+ /** Map a crib `plan graph` payload into a `source=plan` snapshot. Edge `from -> to`
67
+ * (kind `dep`) means `from` depends on `to`, so `to` lands in `from`'s `deps`. */
68
+ export function graphToSnapshot(graph: CribGraph, seq: number): PlanSnapshot {
69
+ const depsByNode = new Map<string, string[]>()
70
+ for (const e of graph.edges ?? []) {
71
+ if (!e || e.kind !== "dep" || typeof e.from !== "string" || typeof e.to !== "string") continue
72
+ const arr = depsByNode.get(e.from)
73
+ if (arr) arr.push(e.to)
74
+ else depsByNode.set(e.from, [e.to])
75
+ }
76
+ const items: PlanItem[] = (graph.nodes ?? [])
77
+ .filter((n): n is CribNode => !!n && typeof n.id === "string")
78
+ .map((n) => ({
79
+ id: n.id,
80
+ title: typeof n.name === "string" ? n.name : n.id,
81
+ kind: typeof n.kind === "string" ? n.kind : "plan",
82
+ status: n.status ?? null,
83
+ deps: depsByNode.get(n.id) ?? [],
84
+ tainted: n.tainted,
85
+ ulid: n.ulid,
86
+ updated: n.updated,
87
+ }))
88
+ return { ns: "cribsheet", seq, project: graph.project, items }
89
+ }
90
+
91
+ // ── crib plan MUTATION tools (reads are ignored) ───────────────────
92
+ // Tools arrive combiner/client-PREFIXED (e.g. cribsheet_plan_add, or the longer
93
+ // mcp__…-combiner__cribsheet_plan_add), so match on the TAIL, with a separator
94
+ // boundary so `plan_add` can't spuriously match e.g. `explain_add`.
95
+ const CRIB_PLAN_MUTATION_VERBS = [
96
+ "plan_dep_remove",
97
+ "plan_dep_add",
98
+ "plan_reaffirm",
99
+ "plan_import",
100
+ "plan_status",
101
+ "plan_forget",
102
+ "plan_move",
103
+ "plan_add",
104
+ ] as const
105
+
106
+ export function isCribPlanMutation(toolName: string): boolean {
107
+ for (const verb of CRIB_PLAN_MUTATION_VERBS) {
108
+ if (toolName === verb) return true
109
+ if (toolName.endsWith(verb)) {
110
+ const boundary = toolName[toolName.length - verb.length - 1]
111
+ if (boundary === "_" || boundary === ":" || boundary === "/") return true
112
+ }
113
+ }
114
+ return false
115
+ }
116
+
117
+ /** How to invoke crib — mirrors index.ts's resolveCrib() shape. */
118
+ export type CribCommand = { cmd: string; args: string[] }
119
+
120
+ export interface PlanSourceOptions {
121
+ /** Resolve the crib CLI (env command → `crib` on PATH → `uv run … crib`). */
122
+ resolveCrib: () => CribCommand | undefined
123
+ /** Pull timeout in ms (default 15000). */
124
+ timeoutMs?: number
125
+ }
126
+
127
+ /**
128
+ * Wire the crib plan source into the extension: prime on `session_start`, mark dirty when
129
+ * a crib plan-mutation tool completes, and re-snapshot at `turn_end` if dirty. Emits via
130
+ * `pi.events.emit("plan:snapshot", snapshot)` on the shared in-process bus (for pi-plan's TUI).
131
+ */
132
+ export function installCribPlanSource(pi: ExtensionAPI, opts: PlanSourceOptions): void {
133
+ const timeout = opts.timeoutMs ?? 15_000
134
+ let seq = 0
135
+ let dirty = false
136
+ let lastCwd: string | undefined
137
+ // Guard against overlapping pulls (a burst of turn_end + a slow crib).
138
+ let pulling = false
139
+
140
+ const pull = async (cwd: string, signal?: AbortSignal): Promise<void> => {
141
+ if (pulling) return
142
+ const crib = opts.resolveCrib()
143
+ if (!crib) return
144
+ pulling = true
145
+ try {
146
+ // Global `--json` goes BEFORE the subcommand. Run crib IN the session cwd
147
+ // and select the project with `-P .` — the CLI resolves it to the absolute
148
+ // client path, so the daemon anchors on the right project (not `default`).
149
+ const res = await pi.exec(crib.cmd, [...crib.args, "--json", "plan", "graph", "-P", "."], {
150
+ signal,
151
+ timeout,
152
+ cwd,
153
+ })
154
+ if (res.code !== 0) return
155
+ let graph: CribGraph
156
+ try {
157
+ graph = JSON.parse(res.stdout) as CribGraph
158
+ } catch {
159
+ return
160
+ }
161
+ pi.events.emit("plan:snapshot", graphToSnapshot(graph, seq++))
162
+ } catch {
163
+ // best effort; a dropped snapshot self-heals on the next trigger
164
+ } finally {
165
+ pulling = false
166
+ }
167
+ }
168
+
169
+ pi.on("session_start", (_event, ctx) => {
170
+ lastCwd = ctx.cwd
171
+ // Prime: surface whatever plan already exists (incl. edits from before this session).
172
+ void pull(ctx.cwd, ctx.signal)
173
+ })
174
+
175
+ pi.on("tool_execution_end", (event) => {
176
+ if (isCribPlanMutation(event.toolName)) dirty = true
177
+ })
178
+
179
+ // Coalesce a turn's worth of mutations into one re-snapshot after they've all landed.
180
+ pi.on("turn_end", (_event, ctx) => {
181
+ if (!dirty) return
182
+ dirty = false
183
+ void pull(ctx.cwd ?? lastCwd ?? process.cwd(), ctx.signal)
184
+ })
185
+ }