@wwjd/pi-graphify 0.1.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 ADDED
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: pi-graphify
3
+ description: Agent context for working on pi-graphify
4
+ ---
5
+
6
+ # pi-graphify
7
+
8
+ A Pi extension that integrates [Graphify](https://github.com/Graphify-Labs/graphify) into Pi sessions.
9
+
10
+ ## Key references
11
+
12
+ - Project standards: [docs/STANDARDS.md](docs/STANDARDS.md)
13
+ - Design: [docs/DESIGN.md](docs/DESIGN.md)
14
+ - Architecture: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
15
+ - Ecosystem: [docs/ECOSYSTEM.md](docs/ECOSYSTEM.md)
16
+ - Versioning: [docs/VERSIONING.md](docs/VERSIONING.md)
17
+ - Release: [RELEASE.md](RELEASE.md)
18
+
19
+ ## Quick verification
20
+
21
+ ```bash
22
+ npm run typecheck && npm run lint
23
+ ```
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## 0.1.0 (2026-07-11)
11
+
12
+ ### Added
13
+
14
+ - Initial project setup from the official pi package template.
15
+ - Scaffolded extension, skill, prompt template, and theme for graphify.
16
+ - add graphify_status tool and /graphify-status command
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # pi-graphify
2
+
3
+ A production-quality [pi](https://pi.dev) extension for [Graphify](https://github.com/Graphify-Labs/graphify).
4
+
5
+ This extension brings Graphify knowledge graph capabilities into your Pi sessions, making it easy to query, explore, and update codebase graphs without leaving the agent.
6
+
7
+ > ⚠️ **Work in progress** — this package is in early development. The public API, tools, and commands will evolve as the extension matures toward a stable 1.0 release.
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ # Install from a local path (during development)
13
+ pi install .
14
+
15
+ # Or run ephemerally without installing
16
+ pi -e .
17
+
18
+ # Type check
19
+ npm run typecheck
20
+
21
+ # Lint
22
+ npm run lint
23
+ ```
24
+
25
+ ## What's Included
26
+
27
+ ```
28
+ pi-graphify/
29
+ ├── extensions/
30
+ │ └── index.ts # Extension entry point (tools, commands, events)
31
+ ├── src/ # Core implementation
32
+ ├── package.json # Pi manifest + npm config
33
+ ├── tsconfig.json # TypeScript config (type checking only)
34
+ ├── biome.json # Linter/formatter config
35
+ ├── .gitignore
36
+ ├── LICENSE
37
+ ├── CHANGELOG.md
38
+ ├── RELEASE.md # Versioning and release standards
39
+ ├── AGENTS.md # Agent context / development conventions
40
+ └── README.md
41
+ ```
42
+
43
+ ## Package Structure
44
+
45
+ ### Extensions (`extensions/`)
46
+
47
+ TypeScript modules that extend pi's behavior with custom tools, slash commands, and event handlers.
48
+
49
+ ### Source (`src/`)
50
+
51
+ Pi-agnostic implementation logic. The `extensions/` layer imports from here and registers everything with Pi.
52
+
53
+ ## Development
54
+
55
+ ### Requirements
56
+
57
+ - Node.js 22+
58
+ - npm 10+
59
+ - pi CLI
60
+
61
+ ### Scripts
62
+
63
+ | Command | Description |
64
+ |---------|-------------|
65
+ | `npm run typecheck` | TypeScript type checking (`tsc --noEmit`) |
66
+ | `npm run lint` | Check lint + formatting (`biome check`) |
67
+ | `npm run lint:fix` | Auto-fix lint + formatting issues |
68
+ | `npm run format` | Format code only |
69
+
70
+ ### Testing the package
71
+
72
+ ```bash
73
+ # Run ephemerally with no other extensions loaded
74
+ pi -ne -e . --no-session
75
+
76
+ # Test a specific tool in print mode
77
+ pi -ne -e . --no-session -p "List the available tools."
78
+ ```
79
+
80
+ ## Publishing
81
+
82
+ This package is intended for publication to npm so it can be listed on [pi.dev/packages](https://pi.dev/packages). CI/CD workflows for release automation are included under `.github/workflows/`.
83
+
84
+ See `RELEASE.md` for versioning and release standards.
85
+
86
+ Before publishing, update:
87
+
88
+ - `package.json` author and repository fields
89
+ - `README.md` with final usage instructions
90
+ - `CHANGELOG.md` with release notes
91
+
92
+ ## License
93
+
94
+ MIT
package/RELEASE.md ADDED
@@ -0,0 +1,149 @@
1
+ # Release Standards
2
+
3
+ This document defines how `pi-graphify` is versioned and released.
4
+
5
+ ---
6
+
7
+ ## Versioning
8
+
9
+ `pi-graphify` follows [Semantic Versioning 2.0.0](https://semver.org/):
10
+
11
+ | Position | Name | Bumped when |
12
+ |---|---|---|
13
+ | `MAJOR` | Breaking release | A public tool, command, config option, or behavior changes in a way that could break existing users. |
14
+ | `MINOR` | Feature release | New tools, commands, or backward-compatible features are added. |
15
+ | `PATCH` | Fix release | Bugs are fixed, docs are corrected, or internal behavior improves without affecting the public API. |
16
+
17
+ Pre-1.0 policy: while the package is at `0.x`, the API is considered unstable. Minor releases may introduce substantial changes. Patch releases are safe to apply.
18
+
19
+ ---
20
+
21
+ ## What triggers each version bump
22
+
23
+ ### MAJOR (`x.0.0`)
24
+
25
+ - Removing a registered tool or command.
26
+ - Renaming a tool, command, or parameter.
27
+ - Changing the default behavior of a tool or command in a way that breaks existing workflows.
28
+ - Changing the required config schema or environment variables.
29
+
30
+ ### MINOR (`0.x.0`)
31
+
32
+ - Adding a new tool (e.g., `graphify_query`).
33
+ - Adding a new slash command (e.g., `/graphify-watch`).
34
+ - Adding new optional parameters to existing tools/commands.
35
+ - Adding new config options with safe defaults.
36
+ - Adding support for new Graphify CLI features.
37
+
38
+ ### PATCH (`0.0.x`)
39
+
40
+ - Fixing a bug in a tool or command.
41
+ - Improving error messages or output formatting.
42
+ - Updating documentation.
43
+ - Updating dependencies that do not change public behavior.
44
+ - Internal refactoring with no user-visible change.
45
+
46
+ ---
47
+
48
+ ## Commit conventions
49
+
50
+ All commits must use [Conventional Commits](https://www.conventionalcommits.org/).
51
+
52
+ Allowed prefixes:
53
+
54
+ | Prefix | Use for |
55
+ |---|---|
56
+ | `feat:` | New user-facing feature or tool |
57
+ | `fix:` | Bug fix |
58
+ | `docs:` | Documentation-only changes |
59
+ | `refactor:` | Code change that neither fixes a bug nor adds a feature |
60
+ | `test:` | Adding or correcting tests |
61
+ | `chore:` | Maintenance, dependency updates, cleanup |
62
+ | `ci:` | Changes to CI/CD configuration |
63
+
64
+ For breaking changes, add `BREAKING CHANGE:` in the commit body or use `!` after the prefix:
65
+
66
+ ```
67
+ feat!: remove graphify_status tool in favor of graphify_info
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Release workflow
73
+
74
+ Releases are automated with [release-please](https://github.com/googleapis/release-please) via `.github/workflows/release.yml`.
75
+
76
+ ### How it works
77
+
78
+ 1. **You commit to `main`** using conventional commits.
79
+ 2. **release-please scans the commit history** and opens a Release PR titled something like `chore(main): release 0.2.0`.
80
+ 3. **The Release PR contains:**
81
+ - An updated `CHANGELOG.md`.
82
+ - A version bump in `package.json` and `package-lock.json`.
83
+ 4. **You review and merge the Release PR.**
84
+ 5. **release-please creates:**
85
+ - A Git tag (e.g., `v0.2.0`).
86
+ - A GitHub Release with auto-generated notes.
87
+ 6. **The `publish` job runs** and publishes the package to npm with provenance.
88
+
89
+ ### Manual steps required
90
+
91
+ - Ensure `NPM_TOKEN` is configured as a repository secret in GitHub.
92
+ - Ensure GitHub Actions has permission to create pull requests.
93
+ - Review the Release PR before merging.
94
+
95
+ ### No manual version bumps
96
+
97
+ Do not manually edit `version` in `package.json`. release-please handles this. The only exception is the very first `0.1.0`, which is already set.
98
+
99
+ ---
100
+
101
+ ## Branching strategy
102
+
103
+ Because this is a solo project, keep the branching model minimal:
104
+
105
+ - **`main`** is the only long-lived branch.
106
+ - Commit directly to `main` for small changes.
107
+ - Optional: use short-lived feature branches (e.g., `feat/query-tool`) if you want cleaner history, but they are not required.
108
+ - No release branches, no sub-branches, no cherry-pick branches.
109
+ - Hotfixes are committed to `main` and release-please cuts a new patch release.
110
+
111
+ ---
112
+
113
+ ## Git tags
114
+
115
+ Git tags are created automatically by release-please in the format `v0.2.0`. Do not create tags manually.
116
+
117
+ ---
118
+
119
+ ## npm provenance
120
+
121
+ The publish workflow uses `npm publish --provenance`, which attaches a signed attestation to the package on npm. This requires:
122
+
123
+ - The `publish` job runs in GitHub Actions.
124
+ - The workflow has `id-token: write` permission.
125
+ - The package is published with `--access public`.
126
+
127
+ ---
128
+
129
+ ## Pre-release checklist
130
+
131
+ Before merging a Release PR, verify:
132
+
133
+ - [ ] `CHANGELOG.md` accurately describes the release.
134
+ - [ ] The version bump is correct (patch/minor/major).
135
+ - [ ] `npm run typecheck` passes on `main`.
136
+ - [ ] `npm run lint` passes on `main`.
137
+ - [ ] `NPM_TOKEN` is available.
138
+
139
+ ---
140
+
141
+ ## Emergency fixes
142
+
143
+ If a release is broken and needs an immediate fix:
144
+
145
+ 1. Commit the fix to `main` with `fix: <description>`.
146
+ 2. release-please will open a new Release PR with a patch bump.
147
+ 3. Merge it to publish the fix.
148
+
149
+ Do not unpublish npm versions. Prefer publishing a patch release over unpublishing.
@@ -0,0 +1,388 @@
1
+ # Architecture Document: pi-graphify
2
+
3
+ This document describes the internal architecture of `pi-graphify`. It is intended for developers who want to understand or contribute to the extension.
4
+
5
+ ---
6
+
7
+ ## Component overview
8
+
9
+ ```
10
+ ┌─────────────────────────────────────────────────────────────┐
11
+ │ Pi Agent │
12
+ └─────────────────────────────────────────────────────────────┘
13
+
14
+
15
+ ┌─────────────────────────────────────────────────────────────┐
16
+ │ Extension Entry Point │
17
+ │ (extensions/index.ts) │
18
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
19
+ │ │ Tool │ │ Command │ │ Event handlers │ │
20
+ │ │ registration │ │ registration │ │ (session, model) │ │
21
+ │ └──────────────┘ └──────────────┘ └──────────────────┘ │
22
+ └─────────────────────────────────────────────────────────────┘
23
+
24
+
25
+ ┌─────────────────────────────────────────────────────────────┐
26
+ │ Coordinator │
27
+ │ (src/coordinator.ts) │
28
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
29
+ │ │ Backend │ │ Version │ │ State manager │ │
30
+ │ │ selector │ │ manager │ │ │ │
31
+ │ └──────────────┘ └──────────────┘ └──────────────────┘ │
32
+ └─────────────────────────────────────────────────────────────┘
33
+
34
+ ┌───────────────┴───────────────┐
35
+ ▼ ▼
36
+ ┌────────────────────────────┐ ┌────────────────────────────┐
37
+ │ CliBackend │ │ McpBackend │
38
+ │ (src/backends/cli.ts) │ │ (src/backends/mcp.ts) │
39
+ │ Shells out to `graphify` │ │ Spawns `graphify --mcp` │
40
+ │ via execFile │ │ and speaks JSON-RPC │
41
+ └────────────────────────────┘ └────────────────────────────┘
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Backend abstraction
47
+
48
+ All Graphify operations are abstracted behind a `GraphifyBackend` interface. This allows the rest of the extension to be backend-agnostic.
49
+
50
+ ```typescript
51
+ export interface GraphifyBackend {
52
+ readonly type: 'cli' | 'mcp';
53
+ readonly version: string | null;
54
+ readonly capabilities: GraphifyCapabilities;
55
+
56
+ status(cwd: string): Promise<GraphStatusResult>;
57
+ build(options: BuildOptions): Promise<GraphifyResult>;
58
+ query(options: QueryOptions): Promise<GraphifyResult>;
59
+ path(options: PathOptions): Promise<GraphifyResult>;
60
+ explain(options: ExplainOptions): Promise<GraphifyResult>;
61
+ affected(options: AffectedOptions): Promise<GraphifyResult>;
62
+ add(options: AddOptions): Promise<GraphifyResult>;
63
+ watch(options: WatchOptions): Promise<GraphifyResult>;
64
+ reflect(options: ReflectOptions): Promise<GraphifyResult>;
65
+
66
+ close?(): Promise<void>;
67
+ }
68
+ ```
69
+
70
+ ### Capabilities
71
+
72
+ ```typescript
73
+ export interface GraphifyCapabilities {
74
+ query: boolean;
75
+ path: boolean;
76
+ explain: boolean;
77
+ affected: boolean;
78
+ add: boolean;
79
+ watch: boolean;
80
+ reflect: boolean;
81
+ mcp: boolean;
82
+ directedGraph: boolean;
83
+ incrementalUpdate: boolean;
84
+ semanticExtraction: boolean;
85
+ }
86
+ ```
87
+
88
+ Capabilities are determined by:
89
+ 1. Detected Graphify version.
90
+ 2. Whether the backend is CLI or MCP.
91
+ 3. A feature map that maps version ranges to supported features.
92
+
93
+ ### Backend selector
94
+
95
+ The coordinator chooses the backend in this order:
96
+
97
+ 1. **MCP if explicitly enabled** (`backend: 'mcp'` in config) and available.
98
+ 2. **MCP if auto-detected** (`backend: 'auto'`) and the MCP server starts successfully.
99
+ 3. **CLI** as the universal fallback.
100
+
101
+ The CLI backend is always safe to attempt because Graphify is required to be installed. The MCP backend is preferred when it works because it provides typed, structured responses and avoids spawning a process per call.
102
+
103
+ ---
104
+
105
+ ## Backend implementations
106
+
107
+ ### CliBackend
108
+
109
+ Responsibilities:
110
+ - Resolve the Graphify executable path.
111
+ - Execute `graphify <command>` with argument arrays via `execFile`.
112
+ - Parse stdout/stderr into a normalized `GraphifyResult`.
113
+ - Enforce timeouts.
114
+ - Handle version detection via `graphify --version`.
115
+
116
+ Security:
117
+ - Never construct shell strings.
118
+ - Validate all paths before passing them.
119
+ - Respect `timeout` to prevent hung processes.
120
+
121
+ ### McpBackend
122
+
123
+ Responsibilities:
124
+ - Spawn `graphify --mcp` as a long-lived stdio process per session.
125
+ - Maintain a JSON-RPC client over stdin/stdout.
126
+ - Map Pi tool calls to MCP tool invocations.
127
+ - Cache the graph context so the MCP server does not reload the graph on every call.
128
+ - Close the process on `session_shutdown`.
129
+
130
+ Fallback:
131
+ - If the MCP process fails to start or crashes, the coordinator falls back to `CliBackend` and logs the reason.
132
+
133
+ ---
134
+
135
+ ## Coordinator
136
+
137
+ The coordinator is the single entry point for all Graphify operations. It:
138
+
139
+ 1. Loads configuration.
140
+ 2. Detects or selects the backend.
141
+ 3. Checks the installed Graphify version against the supported range.
142
+ 4. Builds a capability map.
143
+ 5. Routes tool/command requests to the backend.
144
+ 6. Normalizes backend results into a common format.
145
+ 7. Handles errors and converts them into user-friendly messages.
146
+
147
+ ```typescript
148
+ export class GraphifyCoordinator {
149
+ constructor(config: GraphifyConfig, backend: GraphifyBackend);
150
+
151
+ initialize(): Promise<void>;
152
+ getStatus(): Promise<SystemStatus>;
153
+ runOperation(name: string, options: unknown): Promise<GraphifyResult>;
154
+ supports(feature: keyof GraphifyCapabilities): boolean;
155
+ close(): Promise<void>;
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Version manager
162
+
163
+ The version manager is responsible for detecting the installed Graphify version and determining what features are available.
164
+
165
+ ```typescript
166
+ export interface GraphifyVersionInfo {
167
+ version: string | null;
168
+ installationMethod: 'uv' | 'pipx' | 'pip' | 'system' | 'unknown';
169
+ isSupported: boolean;
170
+ isRecommended: boolean;
171
+ minSupported: string;
172
+ recommended: string;
173
+ warnings: string[];
174
+ }
175
+ ```
176
+
177
+ It is used by:
178
+ - The coordinator to disable unsupported features.
179
+ - The `graphify_version` tool to report compatibility.
180
+ - The `session_start` handler to notify the user of issues.
181
+
182
+ ---
183
+
184
+ ## State manager
185
+
186
+ The state manager holds per-session runtime state. It does not persist across sessions; it is rebuilt on `session_start`.
187
+
188
+ ```typescript
189
+ export interface GraphifyState {
190
+ cwd: string;
191
+ graphPath: string | null;
192
+ graphExists: boolean;
193
+ graphMtime: number | null;
194
+ backendType: 'cli' | 'mcp';
195
+ graphifyVersion: string | null;
196
+ capabilities: GraphifyCapabilities;
197
+ watcherActive: boolean;
198
+ lastError: string | null;
199
+ }
200
+ ```
201
+
202
+ This state is used by:
203
+ - Event handlers to decide whether to inject hints.
204
+ - Tools to check prerequisites quickly.
205
+ - Commands to report status.
206
+
207
+ ---
208
+
209
+ ## Watcher manager
210
+
211
+ The watcher manager watches source files and triggers incremental rebuilds.
212
+
213
+ Responsibilities:
214
+ - Use `chokidar` to watch the project root.
215
+ - Ignore `node_modules/`, `.git/`, `graphify-out/`, and other non-source directories.
216
+ - Debounce change events.
217
+ - Run `graphify --update` with `codeOnly: true` by default.
218
+ - Never run full semantic rebuilds automatically.
219
+ - Stop cleanly on `session_shutdown`.
220
+
221
+ ```typescript
222
+ export interface WatcherOptions {
223
+ root: string;
224
+ debounceMs: number;
225
+ ignored: string[];
226
+ codeOnly: boolean;
227
+ }
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Tool/command mapping
233
+
234
+ Each tool has a corresponding command, but the implementation is shared.
235
+
236
+ ```typescript
237
+ // src/tools/query.ts
238
+ export function registerQueryTool(pi: ExtensionAPI, coordinator: GraphifyCoordinator) {
239
+ pi.registerTool({
240
+ name: 'graphify_query',
241
+ // ...
242
+ execute: async (_id, params, _signal, _onUpdate, ctx) => {
243
+ return coordinator.runOperation('query', { ...params, cwd: ctx.cwd });
244
+ },
245
+ });
246
+ }
247
+
248
+ // src/commands/query.ts
249
+ export function registerQueryCommand(pi: ExtensionAPI, coordinator: GraphifyCoordinator) {
250
+ pi.registerCommand('graphify-query', {
251
+ handler: async (args, ctx) => {
252
+ const result = await coordinator.runOperation('query', { question: args, cwd: ctx.cwd });
253
+ ctx.ui.notify(result.stdout.slice(0, 200), 'info');
254
+ },
255
+ });
256
+ }
257
+ ```
258
+
259
+ This ensures tools and commands behave identically and reduces duplication.
260
+
261
+ ---
262
+
263
+ ## Error normalization
264
+
265
+ All backends return a `GraphifyResult`:
266
+
267
+ ```typescript
268
+ export interface GraphifyResult {
269
+ stdout: string;
270
+ stderr: string;
271
+ exitCode: number;
272
+ durationMs: number;
273
+ backend: 'cli' | 'mcp';
274
+ feature: string;
275
+ }
276
+ ```
277
+
278
+ The coordinator converts backend errors into extension-level errors:
279
+
280
+ ```typescript
281
+ export class GraphifyError extends Error {
282
+ readonly code: 'MISSING' | 'VERSION' | 'BUILD' | 'QUERY' | 'TIMEOUT' | 'MCP' | 'UNKNOWN';
283
+ readonly details: Record<string, unknown>;
284
+ readonly userMessage: string;
285
+ }
286
+ ```
287
+
288
+ This allows tools and UI to present consistent messages without knowing backend specifics.
289
+
290
+ ---
291
+
292
+ ## Configuration loading
293
+
294
+ Configuration is loaded in this order (later overrides earlier):
295
+
296
+ 1. Default config (`src/config.ts`).
297
+ 2. Global config (`~/.pi/agent/pi-graphify/config.json`).
298
+ 3. Project-local config (`.pi/pi-graphify.json`) if project is trusted.
299
+
300
+ ```typescript
301
+ export interface GraphifyConfig {
302
+ backend: 'auto' | 'cli' | 'mcp';
303
+ autoHint: boolean;
304
+ autoWatch: boolean;
305
+ watchDebounceMs: number;
306
+ buildTimeoutMs: number;
307
+ queryTimeoutMs: number;
308
+ shortTimeoutMs: number;
309
+ staleThresholdHours: number;
310
+ codeOnlyUpdates: boolean;
311
+ interceptReads: boolean;
312
+ graphifyPath?: string;
313
+ mcpTimeoutMs: number;
314
+ }
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Integration hooks
320
+
321
+ `pi-graphify` is designed so that third-party integrations are optional, easy to add, and easy to build. The core extension works without any integrations. When another extension is available, `pi-graphify` can detect it and wire itself in through well-defined hooks.
322
+
323
+ ### Hook interface
324
+
325
+ ```typescript
326
+ export interface GraphifyIntegration {
327
+ readonly name: string;
328
+ readonly priority: number;
329
+ isAvailable(pi: ExtensionAPI): boolean | Promise<boolean>;
330
+ onGraphBuilt?(result: GraphifyResult): void | Promise<void>;
331
+ onQueryResult?(result: GraphifyResult, question: string): void | Promise<void>;
332
+ onLesson?(lesson: GraphifyLesson): void | Promise<void>;
333
+ }
334
+
335
+ export interface GraphifyLesson {
336
+ kind: 'insight' | 'correction' | 'dead_end' | 'preference';
337
+ summary: string;
338
+ sourceNodes: string[];
339
+ query?: string;
340
+ }
341
+ ```
342
+
343
+ ### How integrations are registered
344
+
345
+ Third-party Pi extensions register themselves by importing a small registration helper from `pi-graphify`:
346
+
347
+ ```typescript
348
+ import { registerGraphifyIntegration } from 'pi-graphify/integrations';
349
+
350
+ registerGraphifyIntegration({
351
+ name: 'pi-hermes-memory',
352
+ priority: 100,
353
+ isAvailable: (pi) => pi.getAllTools().some((t) => t.name === 'memory'),
354
+ onLesson: async (lesson) => {
355
+ // Save a durable memory entry
356
+ },
357
+ });
358
+ ```
359
+
360
+ If no integrations are registered, the extension functions normally. This keeps the core lean and avoids hard dependencies.
361
+
362
+ ### Built-in integration stubs
363
+
364
+ The extension ships with no built-in third-party integrations. It may include example adapters in a separate `examples/integrations/` directory to show how to build them.
365
+
366
+ ### Future integration candidates
367
+
368
+ - `pi-hermes-memory`: save graph-derived lessons as memory entries.
369
+ - `pi-fallow`: cross-reference dead-code findings with graph communities.
370
+ - Custom provider extensions: route semantic extraction through the user’s configured provider.
371
+
372
+ These are explicitly out of scope for the initial implementation but are supported by the hook design.
373
+
374
+ ---
375
+
376
+ ## Module boundaries
377
+
378
+ - `extensions/` — Only Pi registration code. No business logic.
379
+ - `src/coordinator.ts` — The only place backend selection happens.
380
+ - `src/backends/` — Backend-specific code. No Pi imports.
381
+ - `src/tools/` — Tool definitions. Each tool calls the coordinator.
382
+ - `src/commands/` — Command definitions. Each command calls the coordinator.
383
+ - `src/config.ts` — Pure config loading. No Pi imports.
384
+ - `src/state.ts` — Session state.
385
+ - `src/watcher.ts` — File watcher.
386
+ - `src/version.ts` — Version detection and compatibility.
387
+
388
+ This separation makes the core logic testable without loading Pi.