vault-go 0.11.0 → 0.12.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/README.md +31 -0
- package/assets/vault-logo-glass.png +0 -0
- package/dist/activity.js +28 -13
- package/dist/auth.d.ts +2 -0
- package/dist/auth.js +7 -2
- package/dist/callback-page.d.ts +2 -2
- package/dist/callback-page.js +29 -4
- package/dist/cloud.d.ts +9 -0
- package/dist/cloud.js +36 -2
- package/dist/context-engines.d.ts +52 -0
- package/dist/context-engines.js +350 -0
- package/dist/local-dashboard.js +305 -22
- package/dist/local-device.d.ts +22 -0
- package/dist/local-device.js +185 -0
- package/dist/local-install.d.ts +8 -1
- package/dist/local-install.js +172 -59
- package/dist/local-service.d.ts +13 -3
- package/dist/local-service.js +495 -84
- package/dist/locale.d.ts +1 -1
- package/dist/locale.js +102 -5
- package/dist/private-store.d.ts +8 -0
- package/dist/private-store.js +130 -0
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -241,6 +241,8 @@ local, atividade MCP recente, projetos e memórias consultados na nuvem.
|
|
|
241
241
|
Atualiza a interface a cada 5 segundos enquanto visível e consulta a nuvem
|
|
242
242
|
a cada 15 segundos. Sem conexão, conserva o último cache da mesma conta.
|
|
243
243
|
|
|
244
|
+
Abra http://localhost:38850 e clique em **Conectar ao Vault** para entrar pelo navegador. A senha permanece no portal; o painel libera a sessão somente após confirmar o retorno OAuth com PKCE. A tela oferece próximos passos para configurar clientes e registrar a primeira memória. A logo e as cores são as mesmas do portal.
|
|
245
|
+
|
|
244
246
|
O serviço escuta exclusivamente em 127.0.0.1:38850. `local open` verifica
|
|
245
247
|
uma prova criptográfica do serviço e abre uma sessão privada no navegador;
|
|
246
248
|
o segredo local é removido do fragmento imediatamente e trocado por cookie
|
|
@@ -259,3 +261,32 @@ pelo MCP Vault, sem argumentos, consultas ou credenciais. Não captura toda a
|
|
|
259
261
|
atividade da máquina nem importa automaticamente o banco do claude-mem em
|
|
260
262
|
37701. A sincronização deste painel é de leitura da nuvem; as ferramentas
|
|
261
263
|
MCP continuam responsáveis pelas gravações na API.
|
|
264
|
+
|
|
265
|
+
### Sessões, dispositivos e proteção local
|
|
266
|
+
|
|
267
|
+
**Sair** encerra a sessão desta página e cancela suas prévias de contexto.
|
|
268
|
+
**Desconectar dispositivo** pede confirmação, revoga as credenciais do agente
|
|
269
|
+
na nuvem e remove a autenticação e o cache local após sucesso. Os arquivos
|
|
270
|
+
pessoais permanecem intactos. Para reconectar, entre novamente pelo navegador.
|
|
271
|
+
O portal mostra último contato, permissões e permite revogar cada agente.
|
|
272
|
+
|
|
273
|
+
O cache e a credencial de monitoramento usam AES-256-GCM. No macOS, a chave
|
|
274
|
+
fica no Keychain; nos demais sistemas, em arquivo privado `0600`. Os tokens
|
|
275
|
+
MCP existentes continuam em arquivo privado. O painel informa essas diferenças:
|
|
276
|
+
cache cifrado não significa que todas as memórias sejam criptografadas ponta a
|
|
277
|
+
ponta. O cofre de arquivos e o canal do terminal têm seus próprios protocolos.
|
|
278
|
+
|
|
279
|
+
### Motor de contexto
|
|
280
|
+
|
|
281
|
+
Escolha **Vault AI Resume**, **Claude Subscription** ou **OpenAI Subscription**
|
|
282
|
+
no painel local. A disponibilidade é verificada antes da geração. Claude usa
|
|
283
|
+
`claude auth login`; OpenAI usa `codex login` com uma conta ChatGPT. O agente
|
|
284
|
+
não pede nem copia credenciais desses provedores. O modelo gerenciado depende
|
|
285
|
+
de configuração e quota no servidor Vault.
|
|
286
|
+
|
|
287
|
+
A geração exige texto e consentimento explícito, usa diretório temporário,
|
|
288
|
+
limites de entrada/saída e timeout, e permite cancelamento. CLIs recebem apenas
|
|
289
|
+
o texto informado, com ferramentas/configurações locais desativadas conforme
|
|
290
|
+
os recursos suportados. O resultado é uma prévia privada da sessão, disponível
|
|
291
|
+
para copiar; não é salvo automaticamente como memória. Os planos e limites do
|
|
292
|
+
provedor escolhido se aplicam. Cancelar não garante estorno de uso já iniciado.
|
|
Binary file
|
package/dist/activity.js
CHANGED
|
@@ -1,29 +1,44 @@
|
|
|
1
|
-
import { appendFileSync, chmodSync, mkdirSync, readFileSync, statSync, writeFileSync } from
|
|
2
|
-
import { join } from
|
|
3
|
-
import { randomUUID } from
|
|
1
|
+
import { appendFileSync, chmodSync, mkdirSync, readFileSync, statSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
4
|
export function recordActivity(home, operation, ok, durationMs) {
|
|
5
5
|
try {
|
|
6
6
|
mkdirSync(home, { recursive: true, mode: 0o700 });
|
|
7
|
-
const file = join(home,
|
|
7
|
+
const file = join(home, "local-activity.jsonl");
|
|
8
8
|
// Bounded journal contains metadata only: never arguments, content or credentials.
|
|
9
9
|
try {
|
|
10
10
|
if (statSync(file).size > 2 * 1024 * 1024)
|
|
11
|
-
writeFileSync(file,
|
|
11
|
+
writeFileSync(file, "", { mode: 0o600 });
|
|
12
12
|
}
|
|
13
13
|
catch { }
|
|
14
|
-
appendFileSync(file, JSON.stringify({
|
|
14
|
+
appendFileSync(file, JSON.stringify({
|
|
15
|
+
id: randomUUID(),
|
|
16
|
+
time: new Date().toISOString(),
|
|
17
|
+
operation: operation.slice(0, 180),
|
|
18
|
+
ok,
|
|
19
|
+
durationMs: Math.round(durationMs),
|
|
20
|
+
}) + "\n", { mode: 0o600 });
|
|
15
21
|
chmodSync(file, 0o600);
|
|
16
22
|
}
|
|
17
|
-
catch {
|
|
23
|
+
catch {
|
|
24
|
+
/* Observability must never prevent an MCP operation. */
|
|
25
|
+
}
|
|
18
26
|
}
|
|
19
27
|
export function readActivity(home) {
|
|
20
28
|
try {
|
|
21
|
-
return readFileSync(join(home,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
return readFileSync(join(home, "local-activity.jsonl"), "utf8")
|
|
30
|
+
.split("\n")
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.slice(-100)
|
|
33
|
+
.flatMap((line) => {
|
|
34
|
+
try {
|
|
35
|
+
return [JSON.parse(line)];
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
.reverse();
|
|
27
42
|
}
|
|
28
43
|
catch {
|
|
29
44
|
return [];
|
package/dist/auth.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export declare function validateExistingAuthentication(home: string, fetcher?: F
|
|
|
10
10
|
export declare function openVaultBrowser(url: string): Promise<void>;
|
|
11
11
|
export declare function authenticateWithBrowser(home: string, options?: {
|
|
12
12
|
locale?: Locale;
|
|
13
|
+
callbackHtml?: string;
|
|
14
|
+
signal?: AbortSignal;
|
|
13
15
|
fetcher?: Fetcher;
|
|
14
16
|
openBrowser?: (url: string) => Promise<void>;
|
|
15
17
|
timeoutMs?: number;
|
package/dist/auth.js
CHANGED
|
@@ -128,7 +128,7 @@ export async function authenticateWithBrowser(home, options = {}) {
|
|
|
128
128
|
const server = createServer((req, res) => {
|
|
129
129
|
res.setHeader('Cache-Control', 'no-store');
|
|
130
130
|
res.setHeader('Referrer-Policy', 'no-referrer');
|
|
131
|
-
res.setHeader('Content-Security-Policy', "default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'");
|
|
131
|
+
res.setHeader('Content-Security-Policy', "default-src 'none'; img-src data:; style-src 'unsafe-inline'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'");
|
|
132
132
|
let url;
|
|
133
133
|
try {
|
|
134
134
|
url = new URL(req.url ?? '/', `http://127.0.0.1:${port}`);
|
|
@@ -160,11 +160,15 @@ export async function authenticateWithBrowser(home, options = {}) {
|
|
|
160
160
|
}
|
|
161
161
|
accepted = true;
|
|
162
162
|
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
163
|
-
res.end(callbackPage(locale));
|
|
163
|
+
res.end(options.callbackHtml ?? callbackPage(locale));
|
|
164
164
|
claim?.(code);
|
|
165
165
|
});
|
|
166
166
|
let timer;
|
|
167
|
+
const abort = () => rejectClaim?.(new Error(t.denied));
|
|
168
|
+
options.signal?.addEventListener('abort', abort, { once: true });
|
|
167
169
|
try {
|
|
170
|
+
if (options.signal?.aborted)
|
|
171
|
+
throw new Error(t.denied);
|
|
168
172
|
await new Promise((resolve, reject) => { server.once('error', reject); server.listen(0, '127.0.0.1', resolve); });
|
|
169
173
|
const address = server.address();
|
|
170
174
|
if (!address || typeof address === 'string')
|
|
@@ -197,6 +201,7 @@ export async function authenticateWithBrowser(home, options = {}) {
|
|
|
197
201
|
return { email: account.email, method: 'browser' };
|
|
198
202
|
}
|
|
199
203
|
finally {
|
|
204
|
+
options.signal?.removeEventListener('abort', abort);
|
|
200
205
|
if (timer)
|
|
201
206
|
clearTimeout(timer);
|
|
202
207
|
server.closeAllConnections();
|
package/dist/callback-page.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { type Locale } from
|
|
1
|
+
import { type Locale } from "./locale.js";
|
|
2
2
|
/** All interpolated content is from the static locale catalog, never the callback URL. */
|
|
3
|
-
export declare function callbackPage(locale: Locale): string;
|
|
3
|
+
export declare function callbackPage(locale: Locale, dashboardUrl?: string): string;
|
package/dist/callback-page.js
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { copy } from "./locale.js";
|
|
2
3
|
/** All interpolated content is from the static locale catalog, never the callback URL. */
|
|
3
|
-
export function callbackPage(locale) {
|
|
4
|
-
const
|
|
4
|
+
export function callbackPage(locale, dashboardUrl) {
|
|
5
|
+
const base = copy[locale];
|
|
6
|
+
const local = {
|
|
7
|
+
pt: {
|
|
8
|
+
body: "Sua conexão está sendo concluída. Volte ao painel local para acompanhar suas memórias.",
|
|
9
|
+
step2: "Retorno seguro recebido nesta máquina",
|
|
10
|
+
step3: "Abra o painel para acompanhar a conexão",
|
|
11
|
+
back: "Voltar ao painel local",
|
|
12
|
+
},
|
|
13
|
+
en: {
|
|
14
|
+
body: "Your connection is being completed. Return to the local dashboard to follow your memories.",
|
|
15
|
+
step2: "Secure callback received on this machine",
|
|
16
|
+
step3: "Open the dashboard to follow the connection",
|
|
17
|
+
back: "Return to local dashboard",
|
|
18
|
+
},
|
|
19
|
+
es: {
|
|
20
|
+
body: "Tu conexión se está completando. Vuelve al panel local para consultar tus memorias.",
|
|
21
|
+
step2: "Retorno seguro recibido en esta máquina",
|
|
22
|
+
step3: "Abre el panel para consultar la conexión",
|
|
23
|
+
back: "Volver al panel local",
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const t = dashboardUrl ? { ...base, ...local[locale] } : base;
|
|
27
|
+
if (dashboardUrl && !/^http:\/\/localhost:\d+\/$/.test(dashboardUrl))
|
|
28
|
+
throw new Error("Invalid dashboard callback");
|
|
29
|
+
const logo = readFileSync(new URL("../assets/vault-logo-glass.png", import.meta.url)).toString("base64");
|
|
5
30
|
return `<!doctype html><html lang="${locale}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="color-scheme" content="dark"><title>AI Vault Memory · ${t.received}</title><style>
|
|
6
31
|
*{box-sizing:border-box}body{margin:0;min-height:100svh;display:grid;place-items:center;padding:24px;color:#f1f3fc;background:radial-gradient(ellipse at 20% 10%,#38305a60,transparent 50%),radial-gradient(ellipse at 90% 90%,#20394c40,transparent 55%),#080b12;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}.panel{width:min(100%,520px);padding:44px;border:1px solid #cdd8ff26;border-radius:32px;background:linear-gradient(135deg,#272c3edb,#131724ed);box-shadow:0 32px 100px #0008,inset 0 1px #ffffff10;animation:arrive .6s cubic-bezier(.2,.8,.2,1) both}.mark{display:block;margin:0 auto 28px;width:92px;height:92px;filter:drop-shadow(0 8px 25px #9990ff40)}.ribbon{stroke-dasharray:180;animation:draw 1.1s ease both}.ribbon:nth-child(2){animation-delay:.12s}.ribbon:nth-child(3){animation-delay:.24s}.brand{text-align:center;color:#b9b6ff;font-size:10px;letter-spacing:.22em;font-weight:650}h1{text-align:center;font-size:34px;letter-spacing:-.045em;line-height:1.1;margin:16px 0}.intro{text-align:center;color:#acb4cb;font-size:15px;line-height:1.7;margin:0 0 30px}.steps{list-style:none;padding:0;margin:0;border-top:1px solid #cdd8ff20}.steps li{display:flex;align-items:center;gap:14px;padding:15px 0;border-bottom:1px solid #cdd8ff15;font-size:13px;animation:arrive .5s both}.steps li:nth-child(2){animation-delay:.15s}.steps li:nth-child(3){animation-delay:.3s}.step{display:grid;place-items:center;flex-shrink:0;width:28px;height:28px;border:1px solid #b9b6ff40;background:#b9b6ff12;border-radius:9px;color:#c8c5ff;font-size:11px}.return{margin:26px 0 0;padding:16px 18px;background:#b9b6ff14;border:1px solid #b9b6ff30;border-radius:16px;color:#d4d1ff;font-size:14px;line-height:1.6}.privacy{margin:22px 0 0;color:#929db6;font-size:11px;line-height:1.7;text-align:center}@keyframes arrive{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes draw{from{stroke-dashoffset:180;opacity:0}to{stroke-dashoffset:0;opacity:1}}@media(max-width:480px){.panel{padding:30px 24px}h1{font-size:30px}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important}}@media(forced-colors:active){.panel,.step,.return{border:1px solid CanvasText}svg{stroke:CanvasText}}
|
|
7
|
-
</style></head><body><main class="panel"><
|
|
32
|
+
</style></head><body><main class="panel"><img class="mark" src="data:image/png;base64,${logo}" alt="AI Vault Memory"><p class="brand">AI VAULT MEMORY</p><h1>${t.received}</h1><p class="intro">${t.body}</p><ol class="steps"><li><span class="step">01</span>${t.step1}</li><li><span class="step">02</span>${t.step2}</li><li><span class="step">03</span>${t.step3}</li></ol><div class="return">${dashboardUrl ? `<a style="color:inherit" href="${dashboardUrl}">↗ ${t.back}</a>` : `↗ ${t.back}`}</div><p class="privacy">${t.privacy}</p></main></body></html>`;
|
|
8
33
|
}
|
package/dist/cloud.d.ts
CHANGED
|
@@ -35,6 +35,11 @@ export declare class VaultCloudClient implements VaultMemoryApi {
|
|
|
35
35
|
private readonly journal;
|
|
36
36
|
constructor(home?: string, cloudFetch?: typeof fetch, journal?: boolean);
|
|
37
37
|
health(): Promise<unknown>;
|
|
38
|
+
observerStatus(): Promise<unknown>;
|
|
39
|
+
observerGenerate(text: string, signal?: AbortSignal): Promise<unknown>;
|
|
40
|
+
registerDevice(input: Record<string, unknown>): Promise<unknown>;
|
|
41
|
+
rotateDevice(id: string): Promise<unknown>;
|
|
42
|
+
deviceAction(id: string, token: string, action: 'heartbeat' | 'disconnect', body?: Record<string, unknown>): Promise<unknown>;
|
|
38
43
|
projects(): Promise<unknown>;
|
|
39
44
|
createProject(input: Record<string, unknown>): Promise<unknown>;
|
|
40
45
|
startSession(input: Record<string, unknown>): Promise<unknown>;
|
|
@@ -68,3 +73,7 @@ export declare class VaultCloudClient implements VaultMemoryApi {
|
|
|
68
73
|
private request;
|
|
69
74
|
private performRequest;
|
|
70
75
|
}
|
|
76
|
+
export declare class VaultCloudError extends Error {
|
|
77
|
+
readonly status: number;
|
|
78
|
+
constructor(status: number, message: string);
|
|
79
|
+
}
|
package/dist/cloud.js
CHANGED
|
@@ -12,6 +12,26 @@ export class VaultCloudClient {
|
|
|
12
12
|
async health() {
|
|
13
13
|
return this.request('/health', { authenticated: false });
|
|
14
14
|
}
|
|
15
|
+
async observerStatus() { return this.request('/memory/observer/status'); }
|
|
16
|
+
async observerGenerate(text, signal) {
|
|
17
|
+
return this.request('/memory/observer/generate', { method: 'POST', body: { text }, timeoutMs: 60_000, ...(signal ? { signal } : {}) });
|
|
18
|
+
}
|
|
19
|
+
async registerDevice(input) {
|
|
20
|
+
return this.request('/devices/register', { method: 'POST', body: input });
|
|
21
|
+
}
|
|
22
|
+
async rotateDevice(id) {
|
|
23
|
+
if (!/^[a-f0-9-]{36}$/.test(id))
|
|
24
|
+
throw new Error('Invalid device identifier.');
|
|
25
|
+
return this.request(`/devices/${id}/rotate`, { method: 'POST', body: {} });
|
|
26
|
+
}
|
|
27
|
+
async deviceAction(id, token, action, body = {}) {
|
|
28
|
+
if (!/^[a-f0-9-]{36}$/.test(id) || !/^vg_device_[a-f0-9]{64}$/.test(token))
|
|
29
|
+
throw new Error('Invalid device credential.');
|
|
30
|
+
const response = await this.cloudFetch(this.endpoint(`/devices/${id}/${action}`), { method: 'POST', redirect: 'error', headers: { authorization: `Bearer ${token}`, 'content-type': 'application/json' }, body: JSON.stringify(body), signal: AbortSignal.timeout(10_000) });
|
|
31
|
+
if (!response.ok)
|
|
32
|
+
throw new VaultCloudError(response.status, 'device_request_failed');
|
|
33
|
+
return response.status === 204 ? null : response.json();
|
|
34
|
+
}
|
|
15
35
|
async projects() {
|
|
16
36
|
return this.request('/memory/projects');
|
|
17
37
|
}
|
|
@@ -146,6 +166,12 @@ export class VaultCloudClient {
|
|
|
146
166
|
throw new Error('Sessão expirada. Execute `bunx --bun vault-go@latest login --force`.');
|
|
147
167
|
}
|
|
148
168
|
const refreshed = (await response.json());
|
|
169
|
+
// A refresh already in flight must not overwrite a newer login or logout.
|
|
170
|
+
const latest = loadTokens(this.home);
|
|
171
|
+
if (!latest)
|
|
172
|
+
throw new Error('Vault session was disconnected.');
|
|
173
|
+
if (latest.accessToken !== tokens.accessToken || latest.refreshToken !== tokens.refreshToken)
|
|
174
|
+
return latest.accessToken;
|
|
149
175
|
const stored = {
|
|
150
176
|
...refreshed,
|
|
151
177
|
expiresAt: Date.now() + (refreshed.expiresIn ?? 900) * 1000,
|
|
@@ -177,7 +203,7 @@ export class VaultCloudClient {
|
|
|
177
203
|
method: options.method ?? 'GET',
|
|
178
204
|
redirect: 'error',
|
|
179
205
|
headers,
|
|
180
|
-
signal: AbortSignal.timeout(15_000),
|
|
206
|
+
signal: options.signal ? AbortSignal.any([options.signal, AbortSignal.timeout(options.timeoutMs ?? 15_000)]) : AbortSignal.timeout(options.timeoutMs ?? 15_000),
|
|
181
207
|
};
|
|
182
208
|
if (options.body)
|
|
183
209
|
request.body = JSON.stringify(options.body);
|
|
@@ -197,11 +223,19 @@ export class VaultCloudClient {
|
|
|
197
223
|
const message = payload && typeof payload === 'object' && 'error' in payload
|
|
198
224
|
? String(payload.error)
|
|
199
225
|
: `Vault respondeu HTTP ${response.status}`;
|
|
200
|
-
throw new
|
|
226
|
+
throw new VaultCloudError(response.status, message);
|
|
201
227
|
}
|
|
202
228
|
return payload;
|
|
203
229
|
}
|
|
204
230
|
}
|
|
231
|
+
export class VaultCloudError extends Error {
|
|
232
|
+
status;
|
|
233
|
+
constructor(status, message) {
|
|
234
|
+
super(message);
|
|
235
|
+
this.status = status;
|
|
236
|
+
this.name = 'VaultCloudError';
|
|
237
|
+
}
|
|
238
|
+
}
|
|
205
239
|
function safeJson(text) {
|
|
206
240
|
try {
|
|
207
241
|
return JSON.parse(text);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare const CONTEXT_ENGINE_IDS: readonly ["vault-ai-resume", "claude-subscription", "openai-subscription"];
|
|
2
|
+
export type ContextEngineId = (typeof CONTEXT_ENGINE_IDS)[number];
|
|
3
|
+
export interface ContextResult {
|
|
4
|
+
title: string;
|
|
5
|
+
content: string;
|
|
6
|
+
facts: string[];
|
|
7
|
+
concepts: string[];
|
|
8
|
+
engine: ContextEngineId;
|
|
9
|
+
}
|
|
10
|
+
export interface EngineAvailability {
|
|
11
|
+
available: boolean;
|
|
12
|
+
reason?: string;
|
|
13
|
+
billing?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ContextEngine extends EngineAvailability {
|
|
16
|
+
id: ContextEngineId;
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CommandRequest {
|
|
20
|
+
command: "claude" | "codex";
|
|
21
|
+
args: string[];
|
|
22
|
+
cwd: string;
|
|
23
|
+
env: NodeJS.ProcessEnv;
|
|
24
|
+
input?: string;
|
|
25
|
+
timeoutMs: number;
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
}
|
|
28
|
+
export type CommandRunner = (request: CommandRequest) => Promise<{
|
|
29
|
+
stdout: string;
|
|
30
|
+
stderr: string;
|
|
31
|
+
}>;
|
|
32
|
+
export declare function isContextEngine(value: unknown): value is ContextEngineId;
|
|
33
|
+
export declare function selectedContextEngine(home: string): ContextEngineId;
|
|
34
|
+
export declare function selectContextEngine(home: string, engine: unknown): ContextEngineId;
|
|
35
|
+
export declare function contextEnvironment(source?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
36
|
+
/** Never includes process stderr or model input in an error message. */
|
|
37
|
+
export declare const runContextCommand: CommandRunner;
|
|
38
|
+
export declare function listContextEngines(home: string, managedStatus?: EngineAvailability, options?: {
|
|
39
|
+
runner?: CommandRunner;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
selected: ContextEngineId;
|
|
42
|
+
engines: ContextEngine[];
|
|
43
|
+
}>;
|
|
44
|
+
export declare function validateContextResult(value: unknown, engine: ContextEngineId): ContextResult;
|
|
45
|
+
export interface GenerateContextOptions {
|
|
46
|
+
signal?: AbortSignal;
|
|
47
|
+
runner?: CommandRunner;
|
|
48
|
+
managedGenerate?: (text: string, options: {
|
|
49
|
+
signal?: AbortSignal;
|
|
50
|
+
}) => Promise<unknown>;
|
|
51
|
+
}
|
|
52
|
+
export declare function generateContext(_home: string, engine: unknown, text: unknown, options?: GenerateContextOptions): Promise<ContextResult>;
|