pi-doc-injector 0.2.0 → 0.2.1

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.
Files changed (3) hide show
  1. package/README.md +8 -1
  2. package/index.ts +18 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -101,11 +101,18 @@ Injection is also skipped if the current context usage exceeds 80% of the token
101
101
 
102
102
  The extension uses a per-session injection model:
103
103
 
104
- - On `session_start`, the registry is rebuilt from scratch, resetting all `injected` flags.
104
+ - On `session_start`, the registry scans `docs/` and indexes all valid documents.
105
105
  - Within a session, once a document is injected, it won't be re-injected automatically.
106
106
  - Use `/doc-inject reset` to manually reset all flags and allow docs to be injected again.
107
107
  - Use `/doc-inject list` to see which docs have been injected (✅) and which are pending (⬜).
108
108
 
109
+ ### Injection Timing
110
+
111
+ - **User messages**: matched via the `input` event, injected before the assistant
112
+ responds — **same turn**, no delay.
113
+ - **Assistant streaming**: if the assistant mentions a NEW keyword mid-response,
114
+ generation is aborted and restarted with the doc injected immediately.
115
+
109
116
  ### System Prompt Lifecycle
110
117
 
111
118
  Pi **reconstructs the system prompt from source files each turn** (verified against pi v0.70.6).
package/index.ts CHANGED
@@ -66,6 +66,7 @@ export default async function docInjectorExtension(pi: ExtensionAPI) {
66
66
  // ---- State ----
67
67
  let config = loadConfig(process.cwd());
68
68
  let registry: DocRegistry | null = null;
69
+ let initRegistryPromise: Promise<void> | null = null;
69
70
  let enabled = true;
70
71
  let textBuffer = "";
71
72
  let pendingMatches = new Map<string, string[]>(); // filePath → matchedKeywords
@@ -98,17 +99,24 @@ export default async function docInjectorExtension(pi: ExtensionAPI) {
98
99
  );
99
100
  };
100
101
 
101
- let lastInitTime = 0;
102
-
103
102
  // ---- Event: session_start ----
104
- // Pi fires session_start twice on startup (both with reason "startup").
105
- // Use a 2-second dedup window to skip the duplicate. Real session changes
106
- // (/new, /resume, /fork) happen well outside this window.
107
- pi.on("session_start", async (_event, ctx) => {
108
- const now = Date.now();
109
- if (now - lastInitTime < 100) return;
110
- lastInitTime = now;
111
- await initRegistry(ctx.cwd);
103
+ // Pi emits session_start for startup, reload, and real session transitions.
104
+ // Skip the reload variant because resources_discover will rebuild docs right
105
+ // after it, and deduplicate any overlapping non-reload inits.
106
+ pi.on("session_start", async (event, ctx) => {
107
+ if (event.reason === "reload") return;
108
+
109
+ if (initRegistryPromise) {
110
+ await initRegistryPromise;
111
+ return;
112
+ }
113
+
114
+ initRegistryPromise = initRegistry(ctx.cwd);
115
+ try {
116
+ await initRegistryPromise;
117
+ } finally {
118
+ initRegistryPromise = null;
119
+ }
112
120
  });
113
121
 
114
122
  const reloadRegistry = async (): Promise<number> => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-doc-injector",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Auto-inject relevant project documentation into Pi's LLM context based on keyword matching",
5
5
  "type": "module",
6
6
  "main": "./index.ts",