openlore 2.0.11 → 2.0.13
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/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +3 -2
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +34 -16
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +116 -28
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +15 -7
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/core/analyzer/artifact-generator.d.ts +1 -13
- package/dist/core/analyzer/artifact-generator.d.ts.map +1 -1
- package/dist/core/analyzer/artifact-generator.js +5 -23
- package/dist/core/analyzer/artifact-generator.js.map +1 -1
- package/dist/core/analyzer/call-graph.d.ts.map +1 -1
- package/dist/core/analyzer/call-graph.js +21 -11
- package/dist/core/analyzer/call-graph.js.map +1 -1
- package/dist/core/analyzer/file-walker.d.ts.map +1 -1
- package/dist/core/analyzer/file-walker.js +9 -1
- package/dist/core/analyzer/file-walker.js.map +1 -1
- package/dist/core/analyzer/test-file.d.ts +19 -0
- package/dist/core/analyzer/test-file.d.ts.map +1 -0
- package/dist/core/analyzer/test-file.js +29 -0
- package/dist/core/analyzer/test-file.js.map +1 -0
- package/dist/core/decisions/consolidator.d.ts.map +1 -1
- package/dist/core/decisions/consolidator.js +7 -1
- package/dist/core/decisions/consolidator.js.map +1 -1
- package/dist/core/decisions/syncer.js +8 -0
- package/dist/core/decisions/syncer.js.map +1 -1
- package/dist/core/services/edge-store.d.ts.map +1 -1
- package/dist/core/services/edge-store.js +3 -0
- package/dist/core/services/edge-store.js.map +1 -1
- package/dist/core/services/mcp-handlers/analysis.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/analysis.js +2 -1
- package/dist/core/services/mcp-handlers/analysis.js.map +1 -1
- package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/semantic.js +7 -3
- package/dist/core/services/mcp-handlers/semantic.js.map +1 -1
- package/dist/core/services/mcp-handlers/utils.d.ts +13 -0
- package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/utils.js +49 -0
- package/dist/core/services/mcp-handlers/utils.js.map +1 -1
- package/dist/core/services/mcp-watcher.d.ts.map +1 -1
- package/dist/core/services/mcp-watcher.js +5 -5
- package/dist/core/services/mcp-watcher.js.map +1 -1
- package/dist/core/services/tool-dispatch.d.ts +7 -0
- package/dist/core/services/tool-dispatch.d.ts.map +1 -1
- package/dist/core/services/tool-dispatch.js +7 -0
- package/dist/core/services/tool-dispatch.js.map +1 -1
- package/dist/pi/extension.d.ts +62 -0
- package/dist/pi/extension.d.ts.map +1 -0
- package/dist/pi/extension.js +508 -0
- package/dist/pi/extension.js.map +1 -0
- package/examples/pi/README.md +37 -9
- package/package.json +18 -4
- package/skills/openlore-orient/README.md +73 -0
- package/skills/openlore-orient/SKILL.md +73 -0
- package/skills/openlore-orient/examples/example-orient-output.json +103 -0
- package/skills/openlore-orient/examples/example-task-prompt.md +26 -0
- package/skills/openlore-orient/scripts/orient-via-mcp.mjs +124 -0
- package/skills/openlore-orient/scripts/orient.ps1 +36 -0
- package/skills/openlore-orient/scripts/orient.sh +28 -0
- package/examples/pi/openlore.ts +0 -358
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openlore Pi extension — src/pi/extension.ts
|
|
3
|
+
*
|
|
4
|
+
* Compiled to dist/pi/extension.js and declared in package.json "pi" field so
|
|
5
|
+
* `pi install npm:openlore` drops it into the Pi extension registry automatically.
|
|
6
|
+
*
|
|
7
|
+
* Two halves:
|
|
8
|
+
* C — context injection (before_agent_start): model starts grounded with the
|
|
9
|
+
* architecture digest + spec index + task-grounded orient call, so weak
|
|
10
|
+
* tool-callers benefit even without calling a tool.
|
|
11
|
+
* B — native tools (registerTool): navigation surface for on-demand structural
|
|
12
|
+
* queries, each round-tripping to the warm daemon via fetch.
|
|
13
|
+
*
|
|
14
|
+
* Uses ctx.mode (0.78.1+): full injection in tui/rpc (interactive), none in
|
|
15
|
+
* json/print (one-shot). rpc = headless interactive over stdin/stdout (IDE,
|
|
16
|
+
* custom UI) — same injection needs as tui.
|
|
17
|
+
*
|
|
18
|
+
* Config onboarding: runs on first session when .openlore/config.json is absent;
|
|
19
|
+
* also available anytime via the openlore_configure tool.
|
|
20
|
+
*/
|
|
21
|
+
import { StringEnum } from '@earendil-works/pi-ai';
|
|
22
|
+
import { Type } from 'typebox';
|
|
23
|
+
import { spawn } from 'node:child_process';
|
|
24
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
import { homedir } from 'node:os';
|
|
27
|
+
const OPENLORE_DIR = '.openlore';
|
|
28
|
+
/** Treat a config as absent unless it has the minimum viable fields. */
|
|
29
|
+
export function isUsableConfig(raw) {
|
|
30
|
+
return !!raw && typeof raw === 'object' && typeof raw.generation?.provider === 'string';
|
|
31
|
+
}
|
|
32
|
+
export async function readConfig(cwd) {
|
|
33
|
+
try {
|
|
34
|
+
const raw = JSON.parse(await readFile(join(cwd, OPENLORE_DIR, 'config.json'), 'utf-8'));
|
|
35
|
+
return isUsableConfig(raw) ? raw : null;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function writeConfig(cwd, config) {
|
|
42
|
+
await mkdir(join(cwd, OPENLORE_DIR), { recursive: true });
|
|
43
|
+
await writeFile(join(cwd, OPENLORE_DIR, 'config.json'), JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
44
|
+
}
|
|
45
|
+
const PROVIDERS = [
|
|
46
|
+
'anthropic', 'openai', 'openai-compat', 'gemini',
|
|
47
|
+
'copilot', 'claude-code', 'gemini-cli', 'mistral-vibe', 'cursor-agent',
|
|
48
|
+
];
|
|
49
|
+
const PROVIDER_MODEL_DEFAULTS = {
|
|
50
|
+
anthropic: 'claude-sonnet-4-6',
|
|
51
|
+
openai: 'gpt-4o',
|
|
52
|
+
'openai-compat': '',
|
|
53
|
+
gemini: 'gemini-2.0-flash',
|
|
54
|
+
copilot: 'gpt-4o',
|
|
55
|
+
'claude-code': 'claude-sonnet-4-6',
|
|
56
|
+
'gemini-cli': 'gemini-2.0-flash',
|
|
57
|
+
'mistral-vibe': 'codestral-latest',
|
|
58
|
+
'cursor-agent': '',
|
|
59
|
+
};
|
|
60
|
+
const SYSTEM_AUTH_PROVIDERS = new Set(['copilot', 'claude-code', 'gemini-cli', 'mistral-vibe', 'cursor-agent']);
|
|
61
|
+
const PROVIDER_ENV_VARS = {
|
|
62
|
+
anthropic: 'ANTHROPIC_API_KEY',
|
|
63
|
+
openai: 'OPENAI_API_KEY',
|
|
64
|
+
'openai-compat': 'OPENAI_COMPAT_API_KEY',
|
|
65
|
+
copilot: 'COPILOT_API_KEY',
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Build the `/v1/models` URL for a provider base URL, tolerating a trailing
|
|
69
|
+
* slash and an already-present `/v1` segment (e.g. https://api.mistral.ai/v1/).
|
|
70
|
+
*/
|
|
71
|
+
export function modelsUrl(baseUrl) {
|
|
72
|
+
const base = baseUrl.replace(/\/+$/, '').replace(/\/v1$/, '');
|
|
73
|
+
return `${base}/v1/models`;
|
|
74
|
+
}
|
|
75
|
+
/** Strip the trailing " *" current-value marker added to select-list entries. */
|
|
76
|
+
export function stripMarker(label) {
|
|
77
|
+
return label.replace(/ \*$/, '');
|
|
78
|
+
}
|
|
79
|
+
async function fetchModels(baseUrl, apiKey) {
|
|
80
|
+
try {
|
|
81
|
+
const res = await fetch(modelsUrl(baseUrl), {
|
|
82
|
+
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
|
|
83
|
+
signal: AbortSignal.timeout(1500),
|
|
84
|
+
});
|
|
85
|
+
if (!res.ok)
|
|
86
|
+
return null;
|
|
87
|
+
const data = await res.json();
|
|
88
|
+
return data.data?.map((m) => m.id).sort() ?? null;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ── Config wizard ─────────────────────────────────────────────────────────────
|
|
95
|
+
async function configureGeneration(ui, existing) {
|
|
96
|
+
const existingProvider = existing?.provider;
|
|
97
|
+
const providerList = existingProvider
|
|
98
|
+
? [`${existingProvider} *`, ...PROVIDERS.filter((p) => p !== existingProvider)]
|
|
99
|
+
: PROVIDERS;
|
|
100
|
+
const selectedProvider = await ui.select('LLM provider', providerList) ?? providerList[0];
|
|
101
|
+
const provider = stripMarker(selectedProvider);
|
|
102
|
+
let baseUrl = existing?.openaiCompatBaseUrl;
|
|
103
|
+
let skipSslVerify = existing?.skipSslVerify ?? false;
|
|
104
|
+
let apiKey;
|
|
105
|
+
if (provider === 'openai-compat') {
|
|
106
|
+
const urlTitle = baseUrl ? `Base URL (current: ${baseUrl})` : 'Base URL';
|
|
107
|
+
const rawUrl = await ui.input(urlTitle, 'http://localhost:11434');
|
|
108
|
+
baseUrl = rawUrl || baseUrl || '';
|
|
109
|
+
skipSslVerify = await ui.confirm('Skip SSL verification?', 'Only enable for local servers with self-signed certificates (e.g. Ollama on localhost). Do NOT enable for remote/cloud endpoints.');
|
|
110
|
+
}
|
|
111
|
+
if (!SYSTEM_AUTH_PROVIDERS.has(provider) && PROVIDER_ENV_VARS[provider]) {
|
|
112
|
+
apiKey = process.env[PROVIDER_ENV_VARS[provider]];
|
|
113
|
+
if (!apiKey) {
|
|
114
|
+
ui.notify(`API key: set ${PROVIDER_ENV_VARS[provider]} in your shell environment`, 'warning');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
let model;
|
|
118
|
+
const apiBase = provider === 'openai' ? 'https://api.openai.com' : (baseUrl ?? '');
|
|
119
|
+
const models = apiBase ? await fetchModels(apiBase, apiKey) : null;
|
|
120
|
+
if (models && models.length > 0) {
|
|
121
|
+
const currentModel = existing?.model;
|
|
122
|
+
const modelList = currentModel && models.includes(currentModel)
|
|
123
|
+
? [`${currentModel} *`, ...models.filter((m) => m !== currentModel)]
|
|
124
|
+
: models;
|
|
125
|
+
const selectedModel = await ui.select('Model', modelList) ?? modelList[0];
|
|
126
|
+
model = stripMarker(selectedModel);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const existingModel = existing?.model ?? PROVIDER_MODEL_DEFAULTS[provider] ?? '';
|
|
130
|
+
const modelTitle = existing?.model ? `Model (current: ${existing.model})` : 'Model';
|
|
131
|
+
model = (await ui.input(modelTitle, PROVIDER_MODEL_DEFAULTS[provider] ?? '')) || existingModel;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
provider,
|
|
135
|
+
model,
|
|
136
|
+
...(baseUrl ? { openaiCompatBaseUrl: baseUrl } : {}),
|
|
137
|
+
...(skipSslVerify ? { skipSslVerify: true } : {}),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
async function configureEmbedding(ui, existing) {
|
|
141
|
+
const embedUrl = (await ui.input(existing?.baseUrl ? `Embedding base URL (current: ${existing.baseUrl})` : 'Embedding base URL', existing?.baseUrl ?? 'http://localhost:11434')) || existing?.baseUrl || '';
|
|
142
|
+
if (!embedUrl)
|
|
143
|
+
return undefined;
|
|
144
|
+
const embedSsl = await ui.confirm('Skip SSL verification for embedding?', 'Only enable for local servers with self-signed certificates (e.g. Ollama on localhost). Do NOT enable for remote/cloud endpoints.');
|
|
145
|
+
const embedModels = await fetchModels(embedUrl);
|
|
146
|
+
let embedModel;
|
|
147
|
+
if (embedModels && embedModels.length > 0) {
|
|
148
|
+
const currentEmbedModel = existing?.model;
|
|
149
|
+
const embedModelList = currentEmbedModel && embedModels.includes(currentEmbedModel)
|
|
150
|
+
? [`${currentEmbedModel} *`, ...embedModels.filter((m) => m !== currentEmbedModel)]
|
|
151
|
+
: embedModels;
|
|
152
|
+
const selectedEmbedModel = await ui.select('Embedding model', embedModelList) ?? embedModelList[0];
|
|
153
|
+
embedModel = stripMarker(selectedEmbedModel);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const existingModel = existing?.model ?? '';
|
|
157
|
+
embedModel = (await ui.input(existing?.model ? `Embedding model (current: ${existing.model})` : 'Embedding model', '')) || existingModel;
|
|
158
|
+
}
|
|
159
|
+
const embedApiKey = process.env['OPENLORE_EMBEDDING_API_KEY'];
|
|
160
|
+
if (!embedApiKey) {
|
|
161
|
+
ui.notify('Embedding API key: set OPENLORE_EMBEDDING_API_KEY in your shell environment (leave unset for Ollama/local endpoints)', 'info');
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
baseUrl: embedUrl,
|
|
165
|
+
model: embedModel,
|
|
166
|
+
...(embedSsl ? { skipSslVerify: true } : {}),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async function runConfigWizard(ctx, existing) {
|
|
170
|
+
const { ui } = ctx;
|
|
171
|
+
// Mutable working copy — sections update independently until "Save".
|
|
172
|
+
let generation = existing?.generation ?? {};
|
|
173
|
+
let embedding = existing?.embedding;
|
|
174
|
+
let maxFiles = existing?.analysis?.maxFiles ?? 500;
|
|
175
|
+
// Pi never persists API keys (they belong in env vars). If an older config
|
|
176
|
+
// written by the CLI carried an embedding apiKey, drop it on save and tell the
|
|
177
|
+
// user — keeps behaviour consistent whether or not they edit the embedding.
|
|
178
|
+
if (embedding?.apiKey) {
|
|
179
|
+
embedding = { baseUrl: embedding.baseUrl, model: embedding.model, ...(embedding.skipSslVerify ? { skipSslVerify: true } : {}) };
|
|
180
|
+
ui.notify('Removed stored embedding API key from config — set OPENLORE_EMBEDDING_API_KEY in your shell instead.', 'warning');
|
|
181
|
+
}
|
|
182
|
+
// Menu loop — user picks which section to edit, repeats until Done.
|
|
183
|
+
while (true) {
|
|
184
|
+
const genLabel = generation.provider
|
|
185
|
+
? `Generation ${generation.provider} · ${generation.model ?? '—'}${generation.openaiCompatBaseUrl ? ' · ' + generation.openaiCompatBaseUrl : ''}`
|
|
186
|
+
: 'Generation (not configured)';
|
|
187
|
+
const embedLabel = embedding
|
|
188
|
+
? `Embedding ${embedding.baseUrl} · ${embedding.model || '—'}`
|
|
189
|
+
: 'Embedding (not configured)';
|
|
190
|
+
const analysisLabel = `Analysis maxFiles=${maxFiles}`;
|
|
191
|
+
const choice = await ui.select('openlore config — what to change?', [
|
|
192
|
+
genLabel,
|
|
193
|
+
embedLabel,
|
|
194
|
+
analysisLabel,
|
|
195
|
+
'Save & close',
|
|
196
|
+
]);
|
|
197
|
+
if (!choice)
|
|
198
|
+
return; // escaped — discard all changes
|
|
199
|
+
if (choice === 'Save & close')
|
|
200
|
+
break;
|
|
201
|
+
if (choice === genLabel) {
|
|
202
|
+
generation = await configureGeneration(ui, generation);
|
|
203
|
+
}
|
|
204
|
+
else if (choice === embedLabel) {
|
|
205
|
+
embedding = await configureEmbedding(ui, embedding);
|
|
206
|
+
}
|
|
207
|
+
else if (choice === analysisLabel) {
|
|
208
|
+
const raw = await ui.input(`Max files to analyze (current: ${maxFiles})`, '500');
|
|
209
|
+
maxFiles = parseInt(raw ?? '', 10) || maxFiles;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const config = {
|
|
213
|
+
version: existing?.version ?? '1.0.0',
|
|
214
|
+
projectType: existing?.projectType ?? 'unknown',
|
|
215
|
+
openspecPath: existing?.openspecPath ?? 'openspec',
|
|
216
|
+
analysis: {
|
|
217
|
+
maxFiles,
|
|
218
|
+
includePatterns: existing?.analysis?.includePatterns ?? [],
|
|
219
|
+
excludePatterns: existing?.analysis?.excludePatterns ?? [],
|
|
220
|
+
},
|
|
221
|
+
generation,
|
|
222
|
+
...(embedding ? { embedding } : {}),
|
|
223
|
+
createdAt: existing?.createdAt ?? new Date().toISOString(),
|
|
224
|
+
lastRun: existing?.lastRun ?? null,
|
|
225
|
+
};
|
|
226
|
+
await writeConfig(ctx.cwd, config);
|
|
227
|
+
ui.notify('Configuration saved.', 'info');
|
|
228
|
+
const runNow = await ui.confirm('Run openlore analyze now?', 'Builds the structural index required for navigation tools (~30s–2min depending on codebase size)');
|
|
229
|
+
if (runNow) {
|
|
230
|
+
ui.notify('Running openlore analyze…', 'info');
|
|
231
|
+
const [exitCode, errText] = await new Promise((resolve) => {
|
|
232
|
+
// Try `openlore` in PATH; fall back to `npx openlore` if not found.
|
|
233
|
+
const trySpawn = (cmd, args) => new Promise((res) => {
|
|
234
|
+
const chunks = [];
|
|
235
|
+
const proc = spawn(cmd, args, { cwd: ctx.cwd, stdio: ['ignore', 'ignore', 'pipe'] });
|
|
236
|
+
proc.stderr?.on('data', (d) => chunks.push(d));
|
|
237
|
+
proc.on('close', (code) => res([code ?? 1, Buffer.concat(chunks).toString().trim()]));
|
|
238
|
+
proc.on('error', () => res(null));
|
|
239
|
+
});
|
|
240
|
+
trySpawn('openlore', ['analyze']).then((r) => {
|
|
241
|
+
if (r !== null)
|
|
242
|
+
return resolve(r);
|
|
243
|
+
return trySpawn('npx', ['openlore', 'analyze']).then((r2) => resolve(r2 ?? [1, 'openlore not found in PATH']));
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
if (exitCode === 0) {
|
|
247
|
+
ui.notify('Analysis complete — openlore tools are ready.', 'info');
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
ui.notify(`openlore analyze failed — run it manually. ${errText ? '(' + errText.slice(0, 120) + ')' : ''}`.trim(), 'error');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const HEALTH_TIMEOUT_MS = 8000;
|
|
255
|
+
const HEALTH_POLL_MS = 150;
|
|
256
|
+
const RESULT_MAX = 50_000;
|
|
257
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
258
|
+
async function readDescriptor(cwd) {
|
|
259
|
+
try {
|
|
260
|
+
return JSON.parse(await readFile(join(cwd, OPENLORE_DIR, 'serve.json'), 'utf-8'));
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async function healthy(desc) {
|
|
267
|
+
try {
|
|
268
|
+
const res = await fetch(`http://${desc.host}:${desc.port}/health`, { signal: AbortSignal.timeout(1000) });
|
|
269
|
+
if (!res.ok)
|
|
270
|
+
return false;
|
|
271
|
+
return (await res.json().catch(() => null))?.ok === true;
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async function ensureDaemon(cwd) {
|
|
278
|
+
const existing = await readDescriptor(cwd);
|
|
279
|
+
if (existing && (await healthy(existing)))
|
|
280
|
+
return { baseUrl: `http://${existing.host}:${existing.port}`, token: existing.token };
|
|
281
|
+
try {
|
|
282
|
+
spawn('openlore', ['serve', '--directory', cwd], { detached: true, stdio: 'ignore' }).unref();
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
const deadline = Date.now() + HEALTH_TIMEOUT_MS;
|
|
288
|
+
while (Date.now() < deadline) {
|
|
289
|
+
await sleep(HEALTH_POLL_MS);
|
|
290
|
+
const desc = await readDescriptor(cwd);
|
|
291
|
+
if (desc && (await healthy(desc)))
|
|
292
|
+
return { baseUrl: `http://${desc.host}:${desc.port}`, token: desc.token };
|
|
293
|
+
}
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
async function callTool(daemon, name, args, cwd, signal) {
|
|
297
|
+
const headers = { 'content-type': 'application/json' };
|
|
298
|
+
if (daemon.token)
|
|
299
|
+
headers['x-openlore-token'] = daemon.token;
|
|
300
|
+
try {
|
|
301
|
+
const res = await fetch(`${daemon.baseUrl}/tool/${encodeURIComponent(name)}`, {
|
|
302
|
+
method: 'POST', headers, body: JSON.stringify({ directory: cwd, args }), signal,
|
|
303
|
+
});
|
|
304
|
+
const body = await res.json().catch(() => ({ error: `non-JSON (${res.status})` }));
|
|
305
|
+
if (!res.ok)
|
|
306
|
+
return { error: body.error ?? `HTTP ${res.status}` };
|
|
307
|
+
return body;
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// ── Context injection helpers ─────────────────────────────────────────────────
|
|
314
|
+
function truncate(s, max) {
|
|
315
|
+
return s.length <= max ? s : s.slice(0, max) + `\n… (truncated, ${s.length - max} more chars)`;
|
|
316
|
+
}
|
|
317
|
+
async function readDigest(cwd) {
|
|
318
|
+
try {
|
|
319
|
+
return await readFile(join(cwd, OPENLORE_DIR, 'analysis', 'CODEBASE.md'), 'utf-8');
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
return '';
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
async function readSpecIndex(cwd) {
|
|
326
|
+
try {
|
|
327
|
+
const { readdir } = await import('node:fs/promises');
|
|
328
|
+
const dirs = (await readdir(join(cwd, 'openspec', 'specs'), { withFileTypes: true }))
|
|
329
|
+
.filter((d) => d.isDirectory()).map((d) => d.name);
|
|
330
|
+
if (dirs.length === 0)
|
|
331
|
+
return '';
|
|
332
|
+
return ['## openlore spec domains', ...dirs.map((d) => `- ${d}`)].join('\n');
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return '';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const NAV_TOOLS = [
|
|
339
|
+
{
|
|
340
|
+
name: 'orient',
|
|
341
|
+
label: 'openlore orient',
|
|
342
|
+
description: 'START HERE on any new task. Returns relevant functions, files, spec domains, call neighbours, and insertion points in one call.',
|
|
343
|
+
guideline: 'Use openlore_orient FIRST on any new task before reading files.',
|
|
344
|
+
parameters: Type.Object({ task: Type.String({ description: 'Natural-language task description' }), limit: Type.Optional(Type.Number()) }),
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: 'search_code',
|
|
348
|
+
label: 'openlore search_code',
|
|
349
|
+
description: 'Semantic + keyword search for functions by meaning or name.',
|
|
350
|
+
guideline: 'Use openlore_search_code to find where a concept lives instead of grepping.',
|
|
351
|
+
parameters: Type.Object({ query: Type.String(), limit: Type.Optional(Type.Number()), language: Type.Optional(Type.String()) }),
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: 'get_subgraph',
|
|
355
|
+
label: 'openlore get_subgraph',
|
|
356
|
+
description: 'Call topology around a function (callers/callees) to a given depth.',
|
|
357
|
+
guideline: 'Use openlore_get_subgraph to see blast radius before changing a function.',
|
|
358
|
+
parameters: Type.Object({ functionName: Type.String(), direction: Type.Optional(StringEnum(['downstream', 'upstream', 'both'])), maxDepth: Type.Optional(Type.Number()) }),
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
name: 'trace_execution_path',
|
|
362
|
+
label: 'openlore trace_execution_path',
|
|
363
|
+
description: 'Find call paths from an entry function to a target function.',
|
|
364
|
+
guideline: 'Use openlore_trace_execution_path to answer "how does X reach Y".',
|
|
365
|
+
parameters: Type.Object({ entryFunction: Type.String(), targetFunction: Type.String(), maxDepth: Type.Optional(Type.Number()) }),
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'analyze_impact',
|
|
369
|
+
label: 'openlore analyze_impact',
|
|
370
|
+
description: 'Blast radius of changing a symbol (transitive dependents).',
|
|
371
|
+
guideline: 'Use openlore_analyze_impact before editing a shared/hub symbol.',
|
|
372
|
+
parameters: Type.Object({ symbol: Type.String(), depth: Type.Optional(Type.Number()) }),
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: 'suggest_insertion_points',
|
|
376
|
+
label: 'openlore suggest_insertion_points',
|
|
377
|
+
description: 'Where to add a feature — ranked file/function insertion candidates.',
|
|
378
|
+
guideline: 'Use openlore_suggest_insertion_points when planning where new code goes.',
|
|
379
|
+
parameters: Type.Object({ description: Type.String(), limit: Type.Optional(Type.Number()) }),
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: 'get_function_skeleton',
|
|
383
|
+
label: 'openlore get_function_skeleton',
|
|
384
|
+
description: 'Compact skeleton of a file: signatures + control flow, noise stripped.',
|
|
385
|
+
guideline: 'Use openlore_get_function_skeleton to read a file cheaply before opening it.',
|
|
386
|
+
parameters: Type.Object({ filePath: Type.String() }),
|
|
387
|
+
},
|
|
388
|
+
];
|
|
389
|
+
function toolResult(text, details = null) {
|
|
390
|
+
return { content: [{ type: 'text', text }], details };
|
|
391
|
+
}
|
|
392
|
+
// ── Extension entry point ─────────────────────────────────────────────────────
|
|
393
|
+
export default function openlore(pi) {
|
|
394
|
+
const daemons = new Map();
|
|
395
|
+
// Negative cache: when a daemon can't be reached, remember the failure for a
|
|
396
|
+
// short window so we don't pay the full 8s spawn-and-poll on every call in a
|
|
397
|
+
// repo that simply isn't analyzed yet. Transient failures recover after TTL.
|
|
398
|
+
const failedUntil = new Map();
|
|
399
|
+
const DAEMON_RETRY_COOLDOWN_MS = 30_000;
|
|
400
|
+
const primed = new Set();
|
|
401
|
+
let sessionCwd = process.cwd();
|
|
402
|
+
let sessionMode = 'tui';
|
|
403
|
+
async function getDaemon(cwd) {
|
|
404
|
+
const cached = daemons.get(cwd);
|
|
405
|
+
if (cached)
|
|
406
|
+
return cached;
|
|
407
|
+
if ((failedUntil.get(cwd) ?? 0) > Date.now())
|
|
408
|
+
return null;
|
|
409
|
+
const d = await ensureDaemon(cwd);
|
|
410
|
+
if (d) {
|
|
411
|
+
daemons.set(cwd, d);
|
|
412
|
+
failedUntil.delete(cwd);
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
failedUntil.set(cwd, Date.now() + DAEMON_RETRY_COOLDOWN_MS);
|
|
416
|
+
}
|
|
417
|
+
return d;
|
|
418
|
+
}
|
|
419
|
+
// ── B: navigation tools ──
|
|
420
|
+
for (const tool of NAV_TOOLS) {
|
|
421
|
+
pi.registerTool({
|
|
422
|
+
name: `openlore_${tool.name}`,
|
|
423
|
+
label: tool.label,
|
|
424
|
+
description: tool.description,
|
|
425
|
+
promptSnippet: tool.description,
|
|
426
|
+
promptGuidelines: [tool.guideline],
|
|
427
|
+
parameters: tool.parameters,
|
|
428
|
+
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
429
|
+
const daemon = await getDaemon(ctx.cwd);
|
|
430
|
+
if (!daemon)
|
|
431
|
+
return toolResult('openlore daemon unavailable — run `openlore analyze` then retry.');
|
|
432
|
+
const result = await callTool(daemon, tool.name, params, ctx.cwd, signal ?? undefined);
|
|
433
|
+
const text = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
|
|
434
|
+
return toolResult(truncate(text, RESULT_MAX), result);
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
// ── Config tool ──
|
|
439
|
+
pi.registerTool({
|
|
440
|
+
name: 'openlore_configure',
|
|
441
|
+
label: 'openlore configure',
|
|
442
|
+
description: 'Open the openlore configuration wizard to set provider, model, embedding, and analysis settings.',
|
|
443
|
+
promptSnippet: 'Configure openlore settings (provider, model, API key, embedding).',
|
|
444
|
+
promptGuidelines: ['Use openlore_configure to change the LLM provider, model, or embedding settings.'],
|
|
445
|
+
parameters: Type.Object({}),
|
|
446
|
+
async execute(_id, _params, _signal, _onUpdate, ctx) {
|
|
447
|
+
if (!ctx.hasUI)
|
|
448
|
+
return toolResult('Config wizard requires an interactive session (tui or rpc mode).');
|
|
449
|
+
const existing = await readConfig(ctx.cwd);
|
|
450
|
+
await runConfigWizard(ctx, existing);
|
|
451
|
+
return toolResult('Configuration saved to .openlore/config.json.');
|
|
452
|
+
},
|
|
453
|
+
});
|
|
454
|
+
// ── /configure slash command ──
|
|
455
|
+
pi.registerCommand('openlore', {
|
|
456
|
+
description: 'Open the openlore configuration wizard',
|
|
457
|
+
async handler(_args, ctx) {
|
|
458
|
+
if (!ctx.hasUI) {
|
|
459
|
+
ctx.ui.notify('Config wizard requires an interactive session.', 'error');
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const existing = await readConfig(ctx.cwd);
|
|
463
|
+
await runConfigWizard(ctx, existing);
|
|
464
|
+
},
|
|
465
|
+
});
|
|
466
|
+
// ── session_start: onboarding + daemon warmup ──
|
|
467
|
+
pi.on('session_start', async (_event, ctx) => {
|
|
468
|
+
sessionCwd = ctx.cwd;
|
|
469
|
+
sessionMode = ctx.mode;
|
|
470
|
+
if (ctx.hasUI && !(await readConfig(ctx.cwd))) {
|
|
471
|
+
await runConfigWizard(ctx, null);
|
|
472
|
+
}
|
|
473
|
+
if (ctx.mode !== 'json' && ctx.mode !== 'print') {
|
|
474
|
+
await getDaemon(ctx.cwd);
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
// ── C: context injection on the first turn ──
|
|
478
|
+
pi.on('before_agent_start', async (event, _ctx) => {
|
|
479
|
+
if (sessionMode === 'json' || sessionMode === 'print')
|
|
480
|
+
return;
|
|
481
|
+
if (primed.has(sessionCwd))
|
|
482
|
+
return;
|
|
483
|
+
primed.add(sessionCwd);
|
|
484
|
+
const blocks = [];
|
|
485
|
+
const digest = await readDigest(sessionCwd);
|
|
486
|
+
if (digest)
|
|
487
|
+
blocks.push('# Codebase architecture (openlore)\n\n' + truncate(digest, 8000));
|
|
488
|
+
const specIndex = await readSpecIndex(sessionCwd);
|
|
489
|
+
if (specIndex)
|
|
490
|
+
blocks.push(specIndex);
|
|
491
|
+
const daemon = await getDaemon(sessionCwd);
|
|
492
|
+
if (daemon && event.prompt) {
|
|
493
|
+
const oriented = await callTool(daemon, 'orient', { task: event.prompt }, sessionCwd);
|
|
494
|
+
if (oriented && typeof oriented === 'object' && !('error' in oriented)) {
|
|
495
|
+
blocks.push('# openlore orientation for this task\n\n' + truncate(JSON.stringify(oriented, null, 2), 6000));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
const suffix = blocks.length > 0
|
|
499
|
+
? blocks.join('\n\n')
|
|
500
|
+
: '[openlore: no analysis found — run `openlore analyze` to enable structural context.]';
|
|
501
|
+
return { systemPrompt: event.systemPrompt + '\n\n' + suffix };
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
export const installPaths = {
|
|
505
|
+
project: (cwd) => join(cwd, '.pi', 'extensions', 'openlore.js'),
|
|
506
|
+
global: () => join(homedir(), '.pi', 'agent', 'extensions', 'openlore.js'),
|
|
507
|
+
};
|
|
508
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../src/pi/extension.ts"],"names":[],"mappings":"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"}
|
package/examples/pi/README.md
CHANGED
|
@@ -17,6 +17,8 @@ fresh while you edit.
|
|
|
17
17
|
`openlore_orient`, `openlore_search_code`, `openlore_get_subgraph`,
|
|
18
18
|
`openlore_trace_execution_path`, `openlore_analyze_impact`,
|
|
19
19
|
`openlore_suggest_insertion_points`, `openlore_get_function_skeleton`.
|
|
20
|
+
- **Config wizard**: interactive setup on first run, or anytime via `/openlore`
|
|
21
|
+
slash command or `openlore_configure` tool.
|
|
20
22
|
|
|
21
23
|
## Prerequisites
|
|
22
24
|
|
|
@@ -28,23 +30,49 @@ openlore analyze # build the structural index at least once
|
|
|
28
30
|
|
|
29
31
|
## Install
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
### Recommended — Pi gallery
|
|
32
34
|
|
|
33
35
|
```bash
|
|
34
|
-
|
|
35
|
-
openlore setup --tools pi --global # → ~/.pi/agent/extensions/openlore.ts (all projects)
|
|
36
|
+
pi install npm:openlore
|
|
36
37
|
```
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
Pi discovers the extension automatically via the `"pi"` field in openlore's
|
|
40
|
+
`package.json`. On first session it launches the config wizard.
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
### Alternative — openlore setup
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
openlore setup --tools pi # → .pi/extensions/openlore.js (this project)
|
|
46
|
+
openlore setup --tools pi --global # → ~/.pi/agent/extensions/openlore.js (all projects)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> Requires Pi ≥ 0.78.1. The extension uses `ctx.mode` (0.78.1+) for injection
|
|
50
|
+
> depth: full in `tui`/`rpc` (interactive), none in `json`/`print` (one-shot).
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
On first session (no `.openlore/config.json`) the wizard runs automatically.
|
|
55
|
+
Re-open anytime:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
/openlore # slash command in any Pi session
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
or ask Pi to call `openlore_configure`.
|
|
62
|
+
|
|
63
|
+
API keys are never stored in config — set them as environment variables:
|
|
64
|
+
|
|
65
|
+
| Provider | Env var |
|
|
66
|
+
|----------|---------|
|
|
67
|
+
| `anthropic` | `ANTHROPIC_API_KEY` |
|
|
68
|
+
| `openai` | `OPENAI_API_KEY` |
|
|
69
|
+
| `openai-compat` | `OPENAI_COMPAT_API_KEY` |
|
|
70
|
+
| Embedding | `OPENLORE_EMBEDDING_API_KEY` |
|
|
43
71
|
|
|
44
72
|
## How it works
|
|
45
73
|
|
|
46
|
-
On
|
|
47
|
-
is announced it spawns `openlore serve` detached and waits for `/health`.
|
|
74
|
+
On `session_start` the extension looks for `.openlore/serve.json`; if no healthy
|
|
75
|
+
daemon is announced it spawns `openlore serve` detached and waits for `/health`.
|
|
48
76
|
The daemon:
|
|
49
77
|
|
|
50
78
|
- serves the `navigation` tool preset over `127.0.0.1`,
|