openlore 2.0.9 → 2.0.11

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 (32) hide show
  1. package/README.md +12 -0
  2. package/dist/cli/commands/mcp.d.ts.map +1 -1
  3. package/dist/cli/commands/mcp.js +77 -233
  4. package/dist/cli/commands/mcp.js.map +1 -1
  5. package/dist/cli/commands/orient.d.ts.map +1 -1
  6. package/dist/cli/commands/orient.js +17 -0
  7. package/dist/cli/commands/orient.js.map +1 -1
  8. package/dist/cli/commands/serve.d.ts +49 -0
  9. package/dist/cli/commands/serve.d.ts.map +1 -0
  10. package/dist/cli/commands/serve.js +362 -0
  11. package/dist/cli/commands/serve.js.map +1 -0
  12. package/dist/cli/commands/setup.d.ts.map +1 -1
  13. package/dist/cli/commands/setup.js +23 -7
  14. package/dist/cli/commands/setup.js.map +1 -1
  15. package/dist/cli/index.js +2 -0
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/install/templates/agent-instructions.md +1 -3
  18. package/dist/core/services/mcp-watcher.d.ts +9 -0
  19. package/dist/core/services/mcp-watcher.d.ts.map +1 -1
  20. package/dist/core/services/mcp-watcher.js +10 -0
  21. package/dist/core/services/mcp-watcher.js.map +1 -1
  22. package/dist/core/services/serve-client.d.ts +40 -0
  23. package/dist/core/services/serve-client.d.ts.map +1 -0
  24. package/dist/core/services/serve-client.js +115 -0
  25. package/dist/core/services/serve-client.js.map +1 -0
  26. package/dist/core/services/tool-dispatch.d.ts +28 -0
  27. package/dist/core/services/tool-dispatch.d.ts.map +1 -0
  28. package/dist/core/services/tool-dispatch.js +246 -0
  29. package/dist/core/services/tool-dispatch.js.map +1 -0
  30. package/examples/pi/README.md +70 -0
  31. package/examples/pi/openlore.ts +358 -0
  32. package/package.json +1 -1
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Shared tool dispatch — single source of truth mapping a tool name + args to its
3
+ * handler. Consumed by BOTH transports:
4
+ * - the stdio MCP server (`src/cli/commands/mcp.ts`)
5
+ * - the local HTTP daemon (`src/cli/commands/serve.ts`)
6
+ *
7
+ * Keeping one dispatch table here prevents the two transports from drifting as
8
+ * handlers are added or their signatures change. This function is intentionally
9
+ * pure: it resolves args → handler → result and nothing else. Transport concerns
10
+ * (input validation, telemetry, epistemic/panic tracking, output truncation) stay
11
+ * in the caller.
12
+ *
13
+ * `directory` is passed explicitly (already resolved from `args.directory` by the
14
+ * caller) but most branches re-read it from `args` to preserve the exact behaviour
15
+ * the MCP server had before this extraction.
16
+ */
17
+ import { DEFAULT_DRIFT_MAX_FILES } from '../../constants.js';
18
+ import { handleOrient } from './mcp-handlers/orient.js';
19
+ import { handleSelectTests } from './mcp-handlers/test-impact.js';
20
+ import { handleFindDeadCode } from './mcp-handlers/reachability.js';
21
+ import { handleStructuralDiff } from './mcp-handlers/structural-diff.js';
22
+ import { handleGetChangeCoupling } from './mcp-handlers/change-coupling.js';
23
+ import { handleCheckArchitecture } from './mcp-handlers/architecture.js';
24
+ import { handleGenerateChangeProposal, handleAnnotateStory } from './mcp-handlers/change.js';
25
+ import { handleGetCallGraph, handleGetSubgraph, handleAnalyzeImpact, handleGetLowRiskRefactorCandidates, handleGetLeafFunctions, handleGetCriticalHubs, handleGetGodFunctions, handleGetFileDependencies, handleTraceExecutionPath, } from './mcp-handlers/graph.js';
26
+ import { handleSearchCode, handleSuggestInsertionPoints, handleSearchSpecs, handleListSpecDomains, handleGetSpec, handleUnifiedSearch, } from './mcp-handlers/semantic.js';
27
+ import { handleRecordDecision, handleListDecisions, handleApproveDecision, handleRejectDecision, handleSyncDecisions, } from './mcp-handlers/decisions.js';
28
+ import { handleAnalyzeCodebase, handleGetArchitectureOverview, handleGetRefactorReport, handleGetDuplicateReport, handleGetSignatures, handleGetMapping, handleCheckSpecDrift, handleGetFunctionSkeleton, handleGetFunctionBody, handleGetDecisions, handleGetRouteInventory, handleGetMiddlewareInventory, handleGetSchemaInventory, handleGetUIComponents, handleGetEnvVars, handleGetExternalPackages, handleAuditSpecCoverage, handleGenerateTests, handleGetTestCoverage, handleGetMinimalContext, handleGetCluster, handleDetectChanges, } from './mcp-handlers/analysis.js';
29
+ /** Thrown when a tool name has no registered handler. Callers map this to their
30
+ * transport's "unknown tool" response (isError result / HTTP 404). */
31
+ export class UnknownToolError extends Error {
32
+ toolName;
33
+ constructor(toolName) {
34
+ super(`Unknown tool: ${toolName}`);
35
+ this.toolName = toolName;
36
+ this.name = 'UnknownToolError';
37
+ }
38
+ }
39
+ /**
40
+ * Resolve a tool call to its result. Throws {@link UnknownToolError} for an
41
+ * unregistered name; propagates any handler error unchanged.
42
+ */
43
+ export async function dispatchTool(name, args, directory) {
44
+ if (name === 'orient') {
45
+ const { task, limit = 5, tokenBudget, lean } = args;
46
+ return handleOrient(directory, task, limit, tokenBudget, lean);
47
+ }
48
+ else if (name === 'analyze_codebase') {
49
+ const { directory, force = false } = args;
50
+ return handleAnalyzeCodebase(directory, force);
51
+ }
52
+ else if (name === 'get_architecture_overview') {
53
+ const { directory } = args;
54
+ return handleGetArchitectureOverview(directory);
55
+ }
56
+ else if (name === 'get_refactor_report') {
57
+ const { directory } = args;
58
+ return handleGetRefactorReport(directory);
59
+ }
60
+ else if (name === 'get_call_graph') {
61
+ const { directory } = args;
62
+ return handleGetCallGraph(directory);
63
+ }
64
+ else if (name === 'get_signatures') {
65
+ const { directory, filePattern } = args;
66
+ return handleGetSignatures(directory, filePattern);
67
+ }
68
+ else if (name === 'get_subgraph') {
69
+ const { directory, functionName, direction = 'downstream', maxDepth = 3, format = 'json' } = args;
70
+ return handleGetSubgraph(directory, functionName, direction, maxDepth, format);
71
+ }
72
+ else if (name === 'trace_execution_path') {
73
+ const { directory, entryFunction, targetFunction, maxDepth = 6, maxPaths = 10 } = args;
74
+ return handleTraceExecutionPath(directory, entryFunction, targetFunction, maxDepth, maxPaths);
75
+ }
76
+ else if (name === 'get_mapping') {
77
+ const { directory, domain, orphansOnly } = args;
78
+ return handleGetMapping(directory, domain, orphansOnly);
79
+ }
80
+ else if (name === 'analyze_impact') {
81
+ const { directory, symbol, depth = 2 } = args;
82
+ return handleAnalyzeImpact(directory, symbol, depth);
83
+ }
84
+ else if (name === 'select_tests') {
85
+ const { directory, changedSymbols, diffRef, maxDepth } = args;
86
+ return handleSelectTests({ directory, changedSymbols, diffRef, maxDepth });
87
+ }
88
+ else if (name === 'find_dead_code') {
89
+ const { directory, ifDeleted, maxResults, filePattern } = args;
90
+ return handleFindDeadCode({ directory, ifDeleted, maxResults, filePattern });
91
+ }
92
+ else if (name === 'structural_diff') {
93
+ const { directory, baseRef, headRef, maxResults } = args;
94
+ return handleStructuralDiff({ directory, baseRef, headRef, maxResults });
95
+ }
96
+ else if (name === 'get_change_coupling') {
97
+ const { directory, file, limit } = args;
98
+ return handleGetChangeCoupling({ directory, file, limit });
99
+ }
100
+ else if (name === 'check_architecture') {
101
+ const { directory, from, to } = args;
102
+ return handleCheckArchitecture({ directory, from, to });
103
+ }
104
+ else if (name === 'get_low_risk_refactor_candidates') {
105
+ const { directory, limit = 5, filePattern } = args;
106
+ return handleGetLowRiskRefactorCandidates(directory, limit, filePattern);
107
+ }
108
+ else if (name === 'get_leaf_functions') {
109
+ const { directory, limit = 20, filePattern, sortBy = 'fanIn' } = args;
110
+ return handleGetLeafFunctions(directory, limit, filePattern, sortBy);
111
+ }
112
+ else if (name === 'get_critical_hubs') {
113
+ const { directory, limit = 10, minFanIn = 3 } = args;
114
+ return handleGetCriticalHubs(directory, limit, minFanIn);
115
+ }
116
+ else if (name === 'get_duplicate_report') {
117
+ const { directory } = args;
118
+ return handleGetDuplicateReport(directory);
119
+ }
120
+ else if (name === 'get_function_skeleton') {
121
+ const { directory, filePath } = args;
122
+ return handleGetFunctionSkeleton(directory, filePath);
123
+ }
124
+ else if (name === 'get_god_functions') {
125
+ const { directory, filePath, fanOutThreshold = 8 } = args;
126
+ return handleGetGodFunctions(directory, filePath, fanOutThreshold);
127
+ }
128
+ else if (name === 'check_spec_drift') {
129
+ const { directory, base = 'auto', files = [], domains = [], failOn = 'warning', maxFiles = DEFAULT_DRIFT_MAX_FILES } = args;
130
+ return handleCheckSpecDrift(directory, base, files, domains, failOn, maxFiles);
131
+ }
132
+ else if (name === 'search_code') {
133
+ const { directory, query, limit = 10, language, minFanIn, tokenBudget } = args;
134
+ return handleSearchCode(directory, query, limit, language, minFanIn, tokenBudget);
135
+ }
136
+ else if (name === 'suggest_insertion_points') {
137
+ const { directory, description, limit = 5, language } = args;
138
+ return handleSuggestInsertionPoints(directory, description, limit, language);
139
+ }
140
+ else if (name === 'search_specs') {
141
+ const { directory, query, limit = 10, domain, section } = args;
142
+ return handleSearchSpecs(directory, query, limit, domain, section);
143
+ }
144
+ else if (name === 'search_unified') {
145
+ const { directory, query, limit = 10, language, domain, section } = args;
146
+ return handleUnifiedSearch(directory, query, limit, language, domain, section);
147
+ }
148
+ else if (name === 'list_spec_domains') {
149
+ const { directory } = args;
150
+ return handleListSpecDomains(directory);
151
+ }
152
+ else if (name === 'get_spec') {
153
+ const { directory, domain } = args;
154
+ return handleGetSpec(directory, domain);
155
+ }
156
+ else if (name === 'get_function_body') {
157
+ const { directory, filePath, functionName } = args;
158
+ return handleGetFunctionBody(directory, filePath, functionName);
159
+ }
160
+ else if (name === 'get_file_dependencies') {
161
+ const { directory, filePath, direction = 'both' } = args;
162
+ return handleGetFileDependencies(directory, filePath, direction);
163
+ }
164
+ else if (name === 'generate_change_proposal') {
165
+ const { directory, description, slug, storyContent } = args;
166
+ return handleGenerateChangeProposal(directory, description, slug, storyContent);
167
+ }
168
+ else if (name === 'annotate_story') {
169
+ const { directory, storyFilePath, description } = args;
170
+ return handleAnnotateStory(directory, storyFilePath, description);
171
+ }
172
+ else if (name === 'get_decisions') {
173
+ const { directory, query } = args;
174
+ return handleGetDecisions(directory, query);
175
+ }
176
+ else if (name === 'get_route_inventory') {
177
+ const { directory } = args;
178
+ return handleGetRouteInventory(directory);
179
+ }
180
+ else if (name === 'get_middleware_inventory') {
181
+ const { directory } = args;
182
+ return handleGetMiddlewareInventory(directory);
183
+ }
184
+ else if (name === 'get_schema_inventory') {
185
+ const { directory } = args;
186
+ return handleGetSchemaInventory(directory);
187
+ }
188
+ else if (name === 'get_ui_components') {
189
+ const { directory } = args;
190
+ return handleGetUIComponents(directory);
191
+ }
192
+ else if (name === 'get_env_vars') {
193
+ const { directory } = args;
194
+ return handleGetEnvVars(directory);
195
+ }
196
+ else if (name === 'get_external_packages') {
197
+ const { directory } = args;
198
+ return handleGetExternalPackages(directory);
199
+ }
200
+ else if (name === 'audit_spec_coverage') {
201
+ const { directory, maxUncovered = 50, hubThreshold = 5 } = args;
202
+ return handleAuditSpecCoverage(directory, maxUncovered, hubThreshold);
203
+ }
204
+ else if (name === 'generate_tests') {
205
+ const { directory, domains, framework, useLlm, dryRun } = args;
206
+ return handleGenerateTests({ directory, domains, framework, useLlm, dryRun });
207
+ }
208
+ else if (name === 'get_test_coverage') {
209
+ const { directory, domains, minCoverage } = args;
210
+ return handleGetTestCoverage({ directory, domains, minCoverage });
211
+ }
212
+ else if (name === 'get_minimal_context') {
213
+ const { directory, functionName, filePath } = args;
214
+ return handleGetMinimalContext(directory, functionName, filePath);
215
+ }
216
+ else if (name === 'get_cluster') {
217
+ const { directory, functionName } = args;
218
+ return handleGetCluster(directory, functionName);
219
+ }
220
+ else if (name === 'detect_changes') {
221
+ const { directory, base } = args;
222
+ return handleDetectChanges(directory, base);
223
+ }
224
+ else if (name === 'record_decision') {
225
+ const { directory, title, rationale, consequences, affectedFiles, supersedes, scope } = args;
226
+ return handleRecordDecision(directory, title, rationale, consequences, affectedFiles, supersedes, scope);
227
+ }
228
+ else if (name === 'list_decisions') {
229
+ const { directory, status } = args;
230
+ return handleListDecisions(directory, status);
231
+ }
232
+ else if (name === 'approve_decision') {
233
+ const { directory, id, note } = args;
234
+ return handleApproveDecision(directory, id, note);
235
+ }
236
+ else if (name === 'reject_decision') {
237
+ const { directory, id, note } = args;
238
+ return handleRejectDecision(directory, id, note);
239
+ }
240
+ else if (name === 'sync_decisions') {
241
+ const { directory, dryRun = false, id } = args;
242
+ return handleSyncDecisions(directory, dryRun, id);
243
+ }
244
+ throw new UnknownToolError(name);
245
+ }
246
+ //# sourceMappingURL=tool-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-dispatch.js","sourceRoot":"","sources":["../../../src/core/services/tool-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kCAAkC,EAClC,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,EACvB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC;sEACsE;AACtE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACb;IAA5B,YAA4B,QAAgB;QAC1C,KAAK,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;QADT,aAAQ,GAAR,QAAQ,CAAQ;QAE1C,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,IAA6B,EAC7B,SAAiB;IAEjB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,IAA8E,CAAC;QAC9H,OAAO,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC;SAAM,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACvC,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,IAA8C,CAAC;QACpF,OAAO,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,IAAI,KAAK,2BAA2B,EAAE,CAAC;QAChD,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,6BAA6B,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;SAAM,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;QAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,IAAmD,CAAC;QACvF,OAAO,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACnC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,GAAG,YAAY,EAAE,QAAQ,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GACxF,IAAmJ,CAAC;QACtJ,OAAO,iBAAiB,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;SAAM,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;QAC3C,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE,GAC7E,IAAkH,CAAC;QACrH,OAAO,wBAAwB,CAAC,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAChG,CAAC;SAAM,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAClC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAqE,CAAC;QACjH,OAAO,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,GACpC,IAA6D,CAAC;QAChE,OAAO,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACvD,CAAC;SAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACnC,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,GACpD,IAA6F,CAAC;QAChG,OAAO,iBAAiB,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7E,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,GACrD,IAA4F,CAAC;QAC/F,OAAO,kBAAkB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;IAC/E,CAAC;SAAM,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACtC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAC/C,IAAsF,CAAC;QACzF,OAAO,oBAAoB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3E,CAAC;SAAM,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;QAC1C,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAA4D,CAAC;QAChG,OAAO,uBAAuB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;SAAM,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACzC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,IAAyD,CAAC;QAC1F,OAAO,uBAAuB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,IAAI,KAAK,kCAAkC,EAAE,CAAC;QACvD,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,WAAW,EAAE,GACzC,IAAmE,CAAC;QACtE,OAAO,kCAAkC,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAC3E,CAAC;SAAM,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACzC,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,EAAE,GAC5D,IAAuG,CAAC;QAC1G,OAAO,sBAAsB,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC;SAAM,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACxC,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,QAAQ,GAAG,CAAC,EAAE,GAC3C,IAAgE,CAAC;QACnE,OAAO,qBAAqB,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;SAAM,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;QAC3C,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,wBAAwB,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;SAAM,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;QAC5C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAA+C,CAAC;QAChF,OAAO,yBAAyB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;SAAM,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACxC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,GAAG,CAAC,EAAE,GAChD,IAA0E,CAAC;QAC7E,OAAO,qBAAqB,CAAC,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrE,CAAC;SAAM,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACvC,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,GAAG,uBAAuB,EAAE,GAClH,IAA4I,CAAC;QAC/I,OAAO,oBAAoB,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjF,CAAC;SAAM,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAClC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,GACrE,IAAwH,CAAC;QAC3H,OAAO,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACpF,CAAC;SAAM,IAAI,IAAI,KAAK,0BAA0B,EAAE,CAAC;QAC/C,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,QAAQ,EAAE,GACnD,IAAqF,CAAC;QACxF,OAAO,4BAA4B,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/E,CAAC;SAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACnC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GACrD,IAA+F,CAAC;QAClG,OAAO,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAC/D,IAAkH,CAAC;QACrH,OAAO,mBAAmB,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACjF,CAAC;SAAM,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACxC,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAA6C,CAAC;QAC5E,OAAO,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACxC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,GACzC,IAAqE,CAAC;QACxE,OAAO,qBAAqB,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAClE,CAAC;SAAM,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;QAC5C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,MAAM,EAAE,GAC/C,IAA8F,CAAC;QACjG,OAAO,yBAAyB,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC;SAAM,IAAI,IAAI,KAAK,0BAA0B,EAAE,CAAC;QAC/C,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,GAClD,IAAuF,CAAC;QAC1F,OAAO,4BAA4B,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAClF,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,GAC7C,IAAyE,CAAC;QAC5E,OAAO,mBAAmB,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;QACpC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAA6C,CAAC;QAC3E,OAAO,kBAAkB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;QAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;SAAM,IAAI,IAAI,KAAK,0BAA0B,EAAE,CAAC;QAC/C,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,4BAA4B,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;QAC3C,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,wBAAwB,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;SAAM,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACxC,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACnC,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;SAAM,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;QAC5C,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,OAAO,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;QAC1C,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,EAAE,EAAE,YAAY,GAAG,CAAC,EAAE,GACtD,IAA2E,CAAC;QAC9E,OAAO,uBAAuB,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IACxE,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GACrD,IAMC,CAAC;QACJ,OAAO,mBAAmB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChF,CAAC;SAAM,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACxC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,GACvC,IAAuE,CAAC;QAC1E,OAAO,qBAAqB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;QAC1C,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,GACzC,IAAsE,CAAC;QACzE,OAAO,uBAAuB,CAAC,SAAS,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAClC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,IAAmD,CAAC;QACxF,OAAO,gBAAgB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAA4C,CAAC;QACzE,OAAO,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACtC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,GACnF,IAA4J,CAAC;QAC/J,OAAO,oBAAoB,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAC3G,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAA8C,CAAC;QAC7E,OAAO,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACvC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAwD,CAAC;QACzF,OAAO,qBAAqB,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;SAAM,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACtC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAwD,CAAC;QACzF,OAAO,oBAAoB,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,EAAE,EAAE,EAAE,GAAG,IAA4D,CAAC;QACvG,OAAO,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,70 @@
1
+ # openlore × Pi
2
+
3
+ A [Pi](https://pi.dev) extension that brings openlore's deterministic structural
4
+ context into Pi — built for local models (Qwen, Gemma, …) that are strong at
5
+ using injected context but weaker at tool-calling.
6
+
7
+ It does **not** use MCP. It talks to a warm `openlore serve` HTTP daemon over
8
+ loopback, so tool calls hit warm caches and the analysis stays continuously
9
+ fresh while you edit.
10
+
11
+ ## What you get
12
+
13
+ - **Context injection** (no tool call needed): each session starts grounded with
14
+ the architecture digest (`CODEBASE.md`), the spec-domain index, and a
15
+ task-specific `orient` on your first message.
16
+ - **Native tools**: the navigation surface as Pi tools —
17
+ `openlore_orient`, `openlore_search_code`, `openlore_get_subgraph`,
18
+ `openlore_trace_execution_path`, `openlore_analyze_impact`,
19
+ `openlore_suggest_insertion_points`, `openlore_get_function_skeleton`.
20
+
21
+ ## Prerequisites
22
+
23
+ ```bash
24
+ npm i -g openlore # `openlore` must be on PATH
25
+ cd your-project
26
+ openlore analyze # build the structural index at least once
27
+ ```
28
+
29
+ ## Install
30
+
31
+ Automatic:
32
+
33
+ ```bash
34
+ openlore setup --tools pi # → .pi/extensions/openlore.ts (this project)
35
+ openlore setup --tools pi --global # → ~/.pi/agent/extensions/openlore.ts (all projects)
36
+ ```
37
+
38
+ Manual: copy `openlore.ts` into either location.
39
+
40
+ > Imports are verified against pi 0.78 (`Type` from `typebox`, `StringEnum` from
41
+ > `@earendil-works/pi-ai`, extension types from `@earendil-works/pi-coding-agent`).
42
+ > If a future Pi version moves these, adjust the imports at the top of `openlore.ts`.
43
+
44
+ ## How it works
45
+
46
+ On first use the extension looks for `.openlore/serve.json`; if no healthy daemon
47
+ is announced it spawns `openlore serve` detached and waits for `/health`.
48
+ The daemon:
49
+
50
+ - serves the `navigation` tool preset over `127.0.0.1`,
51
+ - keeps signatures/vector fresh live, and
52
+ - re-analyzes the call graph (debounced) after each edit burst — so what the
53
+ model sees never silently diverges from the code.
54
+
55
+ The extension never kills a daemon it didn't start; it may be serving other
56
+ clients (another Pi session, an editor).
57
+
58
+ ## Verify
59
+
60
+ ```bash
61
+ # daemon is reachable
62
+ curl 127.0.0.1:$(jq .port .openlore/serve.json)/health
63
+
64
+ # a tool round-trips
65
+ curl -XPOST 127.0.0.1:$(jq .port .openlore/serve.json)/tool/orient \
66
+ -d '{"args":{"task":"add rate limiting"}}'
67
+ ```
68
+
69
+ Then run Pi in the project and confirm the session opens with openlore context
70
+ and that `openlore_orient` is callable.