agenr 2.0.1 → 3.0.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/dist/cli.js CHANGED
@@ -4,6 +4,12 @@ import {
4
4
  computeProcedureRevisionHash,
5
5
  computeProcedureSourceHash
6
6
  } from "./chunk-ZYADFKX3.js";
7
+ import {
8
+ deriveOpenClawSessionIdFromFilePath,
9
+ openClawTranscriptParser,
10
+ parseTuiSessionKey,
11
+ readOpenClawSessionsStore
12
+ } from "./chunk-TBFAARM5.js";
7
13
  import {
8
14
  applyClaimExtractionResultToEntry,
9
15
  backfillEpisodeEmbeddings,
@@ -12,8 +18,7 @@ import {
12
18
  computeContentHash,
13
19
  computeNormContentHash,
14
20
  createEpisodeIngestPlan,
15
- createOpenClawRepository,
16
- deriveOpenClawSessionIdFromFilePath,
21
+ createMemoryRepository,
17
22
  describeSupersessionRuleFailure,
18
23
  detectClaimKeyEntityFamilyCandidates,
19
24
  detectClaimKeySingletonAliasCandidates,
@@ -21,17 +26,14 @@ import {
21
26
  evaluateClaimKeySupport,
22
27
  executeEpisodeIngestPlan,
23
28
  normalizeGroundingTags,
24
- openClawTranscriptParser,
25
- parseTuiSessionKey,
26
29
  prepareEpisodeIngest,
27
30
  previewClaimKeyExtraction,
28
- readOpenClawSessionsStore,
29
31
  runBatchClaimExtraction,
30
32
  storeEntriesDetailed,
31
33
  tokenizeGroundingText,
32
34
  validateEntriesWithIndexes,
33
35
  validateSupersessionRules
34
- } from "./chunk-XD3446YW.js";
36
+ } from "./chunk-LAXNNWHM.js";
35
37
  import {
36
38
  DEFAULT_CLAIM_EXTRACTION_CONCURRENCY,
37
39
  DEFAULT_SURGEON_CONTEXT_LIMIT,
@@ -45,6 +47,7 @@ import {
45
47
  ENTRY_TYPES,
46
48
  EXPIRY_LEVELS,
47
49
  applyClaimKeyLifecycle,
50
+ attachCrossEncoderPort,
48
51
  authMethodToProvider,
49
52
  buildActiveEntryClause,
50
53
  buildClaimKeyLifecycleAuditDetails,
@@ -60,17 +63,19 @@ import {
60
63
  configFileExists,
61
64
  createDatabase,
62
65
  createEmbeddingClient,
66
+ createLlmClient,
67
+ createOpenAICrossEncoder,
63
68
  createRecallAdapter,
64
69
  deserializeTags,
65
70
  getAuthMethodDefinition,
66
71
  getEntry,
67
72
  getLastBulkIngestAt,
68
73
  insertEntry,
69
- isAgenrAuthMethod,
70
74
  mapEntryRow,
71
75
  mergeExplicitClaimKeyMetadata,
72
76
  normalizeManualClaimKeyUpdate,
73
77
  parseAndNormalizeProcedureYaml,
78
+ probeLlmCredentials,
74
79
  projectClaimCentricRecallEntry,
75
80
  readBoolean,
76
81
  readConfig,
@@ -82,16 +87,20 @@ import {
82
87
  requireClaimSupportMode,
83
88
  resolveClaimExtractionConfig,
84
89
  resolveConfigPath,
90
+ resolveCrossEncoderApiKey,
85
91
  resolveDbPath,
86
92
  resolveEmbeddingApiKey,
87
93
  resolveEmbeddingModel,
94
+ resolveLlmApiKey,
95
+ resolveLlmCredentials,
96
+ resolveModel,
88
97
  retireEntry,
89
98
  supersedeEntry,
90
99
  toAgenrConfigInput,
91
100
  updateEntry,
92
101
  validateTemporalValidityRange,
93
102
  writeConfig
94
- } from "./chunk-Y2BC7RCE.js";
103
+ } from "./chunk-ELR2HSVC.js";
95
104
  import {
96
105
  compactClaimKey,
97
106
  describeClaimKeyNormalizationFailure,
@@ -102,7 +111,7 @@ import {
102
111
  normalizeClaimKeySegment,
103
112
  recall,
104
113
  resolveClaimSlotPolicy
105
- } from "./chunk-MEHOGUZE.js";
114
+ } from "./chunk-5LADPJ4C.js";
106
115
 
107
116
  // src/cli/main.ts
108
117
  import { Command } from "commander";
@@ -235,7 +244,7 @@ function formatUnknownError(error) {
235
244
  }
236
245
 
237
246
  // src/cli/commands/ingest.ts
238
- import path10 from "path";
247
+ import path9 from "path";
239
248
  import * as clack4 from "@clack/prompts";
240
249
 
241
250
  // src/core/ingestion/parser.ts
@@ -2236,378 +2245,9 @@ function matchesTranscriptFileName(fileName) {
2236
2245
  return GENERIC_TRANSCRIPT_FILE_PATTERN.test(fileName.trim());
2237
2246
  }
2238
2247
 
2239
- // src/adapters/llm.ts
2240
- import { createHash as createHash2 } from "crypto";
2241
- import fs3 from "fs";
2242
- import os from "os";
2243
- import path4 from "path";
2244
- import { createRequire as createRequire2 } from "module";
2245
- import { completeSimple, getEnvApiKey, getModel } from "@mariozechner/pi-ai";
2246
- var DEFAULT_REASONING = "medium";
2247
- var require3 = createRequire2(import.meta.url);
2248
- var getModelWithStrings = getModel;
2249
- function probeLlmCredentials(params) {
2250
- const candidate = resolveCredentialCandidate(params);
2251
- if (!candidate) {
2252
- return {
2253
- available: false,
2254
- guidance: credentialSetupGuidance(params.auth)
2255
- };
2256
- }
2257
- return {
2258
- available: true,
2259
- source: candidate.source,
2260
- guidance: "Credentials available.",
2261
- credentials: {
2262
- apiKey: candidate.token,
2263
- source: candidate.source,
2264
- auth: params.auth
2265
- }
2266
- };
2267
- }
2268
- function resolveAuthCredentials(params) {
2269
- const probe = probeLlmCredentials(params);
2270
- if (!probe.available || !probe.credentials) {
2271
- throw new Error(probe.guidance);
2272
- }
2273
- return probe.credentials;
2274
- }
2275
- function createLlmClient(provider, modelId, options = {}) {
2276
- const model = getModelWithStrings(provider, modelId);
2277
- const metadata = {
2278
- model,
2279
- contextWindowTokens: model.contextWindow,
2280
- maxOutputTokens: model.maxTokens,
2281
- supportsReasoning: model.reasoning,
2282
- usage: createEmptyUsageStats2()
2283
- };
2284
- const resolvedApiKey = normalizeOptionalString2(options.apiKey);
2285
- const requestCompletion = async (systemPrompt, userMessage) => {
2286
- const response = await completeSimple(
2287
- model,
2288
- {
2289
- systemPrompt,
2290
- messages: [
2291
- {
2292
- role: "user",
2293
- content: userMessage,
2294
- timestamp: Date.now()
2295
- }
2296
- ]
2297
- },
2298
- {
2299
- apiKey: resolvedApiKey,
2300
- reasoning: metadata.supportsReasoning ? options.reasoning ?? DEFAULT_REASONING : void 0
2301
- }
2302
- );
2303
- accumulateUsage(metadata.usage, response.usage);
2304
- if (response.stopReason === "error") {
2305
- throw new Error(response.errorMessage ?? `LLM completion failed for ${provider}/${modelId}.`);
2306
- }
2307
- return response;
2308
- };
2309
- const complete = async (systemPrompt, userMessage) => {
2310
- const response = await requestCompletion(systemPrompt, userMessage);
2311
- return extractText(response);
2312
- };
2313
- return {
2314
- metadata,
2315
- complete,
2316
- completeJson: async (systemPrompt, userMessage) => {
2317
- const response = await requestCompletion(systemPrompt, userMessage);
2318
- const text2 = extractText(response);
2319
- return JSON.parse(stripCodeFence3(text2));
2320
- }
2321
- };
2322
- }
2323
- function resolveModel(config, stage) {
2324
- const override = stage === "extraction" ? config?.extractionModel : stage === "dedup" ? config?.dedupModel : stage === "episode" ? config?.episodeModel : config?.claimExtraction?.model ?? config?.extractionModel;
2325
- return {
2326
- provider: normalizeOptionalString2(override?.provider) ?? normalizeOptionalString2(config?.provider) ?? "openai",
2327
- modelId: normalizeOptionalString2(override?.model) ?? normalizeOptionalString2(config?.model) ?? defaultModelForStage(stage)
2328
- };
2329
- }
2330
- function resolveLlmCredentials(config, provider, env = process.env) {
2331
- const normalizedProvider = normalizeOptionalString2(provider);
2332
- if (!normalizedProvider) {
2333
- throw new Error("Provider is required to resolve LLM credentials.");
2334
- }
2335
- const auth = normalizeAuthMethod(config?.auth);
2336
- if (auth && authMethodToProvider(auth) === normalizedProvider) {
2337
- return resolveAuthCredentials({
2338
- auth,
2339
- storedCredentials: config?.credentials,
2340
- env
2341
- });
2342
- }
2343
- const fallback = resolveProviderCredentialCandidate(config, normalizedProvider, env);
2344
- if (fallback) {
2345
- return {
2346
- apiKey: fallback.token,
2347
- source: fallback.source
2348
- };
2349
- }
2350
- if (normalizedProvider === "openai-codex") {
2351
- throw new Error("No OpenAI subscription credential found. Run `codex auth` or configure `auth` as `openai-api-key`.");
2352
- }
2353
- const exampleEnv = normalizedProvider === "anthropic" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
2354
- throw new Error(`No credential found for provider "${normalizedProvider}". Set the appropriate auth method in config or provide ${exampleEnv}.`);
2355
- }
2356
- function resolveLlmApiKey(config, provider, env = process.env) {
2357
- return resolveLlmCredentials(config, provider, env).apiKey;
2358
- }
2359
- function stripCodeFence3(text2) {
2360
- const trimmed = text2.trim();
2361
- const match = /^```(?:json)?\s*([\s\S]+?)\s*```$/i.exec(trimmed);
2362
- return match?.[1]?.trim() ?? trimmed;
2363
- }
2364
- function defaultModelForStage(stage) {
2365
- switch (stage) {
2366
- case "extraction":
2367
- case "episode":
2368
- case "claim":
2369
- return "gpt-5.4-mini";
2370
- case "dedup":
2371
- return "gpt-5.4-nano";
2372
- }
2373
- }
2374
- function normalizeOptionalString2(value) {
2375
- const trimmed = value?.trim();
2376
- return trimmed && trimmed.length > 0 ? trimmed : void 0;
2377
- }
2378
- function normalizeAuthMethod(value) {
2379
- const normalized = normalizeOptionalString2(value);
2380
- return normalized && isAgenrAuthMethod(normalized) ? normalized : void 0;
2381
- }
2382
- function safeReadJson(filePath) {
2383
- try {
2384
- const raw = fs3.readFileSync(filePath, "utf8");
2385
- return JSON.parse(raw);
2386
- } catch {
2387
- return null;
2388
- }
2389
- }
2390
- function resolveHomeDir(env) {
2391
- const home = normalizeOptionalString2(env.HOME);
2392
- return home ? resolveUserPath(home) : os.homedir();
2393
- }
2394
- function resolveCodexHome(env) {
2395
- const configured = normalizeOptionalString2(env.CODEX_HOME) ?? "~/.codex";
2396
- const resolved = resolveUserPath(configured);
2397
- try {
2398
- return fs3.realpathSync.native(resolved);
2399
- } catch {
2400
- return resolved;
2401
- }
2402
- }
2403
- function resolveUserPath(value) {
2404
- const trimmed = value.trim();
2405
- if (trimmed === "~") {
2406
- return os.homedir();
2407
- }
2408
- if (trimmed.startsWith("~/")) {
2409
- return path4.join(os.homedir(), trimmed.slice(2));
2410
- }
2411
- if (trimmed.startsWith("~\\")) {
2412
- return path4.join(os.homedir(), trimmed.slice(2));
2413
- }
2414
- return path4.resolve(trimmed);
2415
- }
2416
- function parseCodexFromFile(env) {
2417
- const authPath = path4.join(resolveCodexHome(env), "auth.json");
2418
- const parsed = safeReadJson(authPath);
2419
- if (!parsed || typeof parsed !== "object") {
2420
- return null;
2421
- }
2422
- const record = parsed;
2423
- const tokens = record.tokens;
2424
- const accessToken = tokens?.access_token;
2425
- if (typeof accessToken !== "string" || !accessToken.trim()) {
2426
- return null;
2427
- }
2428
- return {
2429
- token: accessToken.trim(),
2430
- source: `file:${authPath}`
2431
- };
2432
- }
2433
- function resolveCodexKeychainAccount(env) {
2434
- const hash = createHash2("sha256").update(resolveCodexHome(env)).digest("hex");
2435
- return `cli|${hash.slice(0, 16)}`;
2436
- }
2437
- function parseCodexFromKeychain(env) {
2438
- if (process.platform !== "darwin") {
2439
- return null;
2440
- }
2441
- try {
2442
- const account = resolveCodexKeychainAccount(env);
2443
- const { execSync } = require3("node:child_process");
2444
- const raw = execSync(`security find-generic-password -s "Codex Auth" -a "${account}" -w`, {
2445
- encoding: "utf8",
2446
- stdio: ["pipe", "pipe", "pipe"],
2447
- timeout: 5e3
2448
- }).trim();
2449
- const parsed = JSON.parse(raw);
2450
- const tokens = parsed.tokens;
2451
- const accessToken = tokens?.access_token;
2452
- if (typeof accessToken !== "string" || !accessToken.trim()) {
2453
- return null;
2454
- }
2455
- return {
2456
- token: accessToken.trim(),
2457
- source: "keychain:Codex Auth"
2458
- };
2459
- } catch {
2460
- return null;
2461
- }
2462
- }
2463
- function parseClaudeCredentialRecord(parsed, source) {
2464
- if (!parsed || typeof parsed !== "object") {
2465
- return null;
2466
- }
2467
- const record = parsed;
2468
- const claudeOauth = record.claudeAiOauth;
2469
- const accessToken = claudeOauth?.accessToken;
2470
- if (typeof accessToken !== "string" || !accessToken.trim()) {
2471
- return null;
2472
- }
2473
- return {
2474
- token: accessToken.trim(),
2475
- source
2476
- };
2477
- }
2478
- function parseClaudeFromFiles(env) {
2479
- const homeDir = resolveHomeDir(env);
2480
- const candidates = [path4.join(homeDir, ".claude", ".credentials.json"), path4.join(homeDir, ".claude", "credentials.json")];
2481
- for (const candidate of candidates) {
2482
- const parsed = safeReadJson(candidate);
2483
- const resolved = parseClaudeCredentialRecord(parsed, `file:${candidate}`);
2484
- if (resolved) {
2485
- return resolved;
2486
- }
2487
- }
2488
- return null;
2489
- }
2490
- function parseClaudeFromKeychain() {
2491
- if (process.platform !== "darwin") {
2492
- return null;
2493
- }
2494
- try {
2495
- const { execSync } = require3("node:child_process");
2496
- const raw = execSync('security find-generic-password -s "Claude Code-credentials" -w', {
2497
- encoding: "utf8",
2498
- stdio: ["pipe", "pipe", "pipe"],
2499
- timeout: 5e3
2500
- }).trim();
2501
- return parseClaudeCredentialRecord(JSON.parse(raw), "keychain:Claude Code-credentials");
2502
- } catch {
2503
- return null;
2504
- }
2505
- }
2506
- function candidateFromToken(token, source) {
2507
- const normalized = normalizeOptionalString2(token);
2508
- if (!normalized) {
2509
- return null;
2510
- }
2511
- return {
2512
- token: normalized,
2513
- source
2514
- };
2515
- }
2516
- function resolveOpenAIApiKeyCandidate(storedCredentials, env) {
2517
- return candidateFromToken(env.OPENAI_API_KEY, "env:OPENAI_API_KEY") ?? candidateFromToken(storedCredentials?.openaiApiKey, "config:credentials.openaiApiKey");
2518
- }
2519
- function resolveAnthropicApiKeyCandidate(storedCredentials, env) {
2520
- return candidateFromToken(env.ANTHROPIC_API_KEY, "env:ANTHROPIC_API_KEY") ?? candidateFromToken(storedCredentials?.anthropicApiKey, "config:credentials.anthropicApiKey");
2521
- }
2522
- function resolveAnthropicTokenCandidate(storedCredentials, env) {
2523
- return candidateFromToken(env.ANTHROPIC_OAUTH_TOKEN, "env:ANTHROPIC_OAUTH_TOKEN") ?? candidateFromToken(storedCredentials?.anthropicOauthToken, "config:credentials.anthropicOauthToken");
2524
- }
2525
- function resolveAnthropicOauthCandidate(env) {
2526
- return parseClaudeFromFiles(env) ?? parseClaudeFromKeychain();
2527
- }
2528
- function resolveOpenAiSubscriptionCandidate(env) {
2529
- return parseCodexFromFile(env) ?? parseCodexFromKeychain(env);
2530
- }
2531
- function credentialSetupGuidance(auth) {
2532
- switch (auth) {
2533
- case "anthropic-oauth":
2534
- return "Claude Code credentials not found. Install Claude Code CLI and sign in with `claude`.";
2535
- case "anthropic-token":
2536
- return "No Anthropic long-lived token found. Set ANTHROPIC_OAUTH_TOKEN or save credentials.anthropicOauthToken.";
2537
- case "anthropic-api-key":
2538
- return "No Anthropic API key found. Set ANTHROPIC_API_KEY or save credentials.anthropicApiKey.";
2539
- case "openai-subscription":
2540
- return "Codex CLI credentials not found or expired. Run `codex auth`.";
2541
- case "openai-api-key":
2542
- return "No OpenAI API key found. Set OPENAI_API_KEY or save credentials.openaiApiKey.";
2543
- }
2544
- }
2545
- function resolveCredentialCandidate(params) {
2546
- const env = params.env ?? process.env;
2547
- switch (params.auth) {
2548
- case "anthropic-oauth":
2549
- return resolveAnthropicOauthCandidate(env);
2550
- case "anthropic-token":
2551
- return resolveAnthropicTokenCandidate(params.storedCredentials, env);
2552
- case "anthropic-api-key":
2553
- return resolveAnthropicApiKeyCandidate(params.storedCredentials, env);
2554
- case "openai-subscription":
2555
- return resolveOpenAiSubscriptionCandidate(env);
2556
- case "openai-api-key":
2557
- return resolveOpenAIApiKeyCandidate(params.storedCredentials, env);
2558
- }
2559
- }
2560
- function resolveProviderCredentialCandidate(config, provider, env) {
2561
- if (provider === "openai") {
2562
- return resolveOpenAIApiKeyCandidate(config?.credentials, env);
2563
- }
2564
- if (provider === "anthropic") {
2565
- const auth = normalizeAuthMethod(config?.auth);
2566
- if (auth && authMethodToProvider(auth) === "anthropic") {
2567
- return resolveCredentialCandidate({
2568
- auth,
2569
- storedCredentials: config?.credentials,
2570
- env
2571
- });
2572
- }
2573
- return resolveAnthropicApiKeyCandidate(config?.credentials, env);
2574
- }
2575
- const envApiKey = getEnvApiKey(provider) ?? getEnvApiKey(provider);
2576
- return candidateFromToken(envApiKey, `env:${provider}`);
2577
- }
2578
- function createEmptyUsageStats2() {
2579
- return {
2580
- calls: 0,
2581
- inputTokens: 0,
2582
- outputTokens: 0,
2583
- cacheReadTokens: 0,
2584
- cacheWriteTokens: 0,
2585
- totalTokens: 0,
2586
- totalCost: 0
2587
- };
2588
- }
2589
- function accumulateUsage(target, usage) {
2590
- target.calls += 1;
2591
- target.inputTokens += usage.input;
2592
- target.outputTokens += usage.output;
2593
- target.cacheReadTokens += usage.cacheRead;
2594
- target.cacheWriteTokens += usage.cacheWrite;
2595
- target.totalTokens += usage.totalTokens;
2596
- target.totalCost += usage.cost.total;
2597
- }
2598
- function extractText(response) {
2599
- const blocks = [];
2600
- for (const contentBlock of response.content) {
2601
- if (contentBlock.type === "text") {
2602
- blocks.push(contentBlock.text);
2603
- }
2604
- }
2605
- return blocks.join("");
2606
- }
2607
-
2608
2248
  // src/cli/shared/parse.ts
2609
2249
  import { InvalidArgumentError } from "commander";
2610
- function normalizeOptionalString3(value) {
2250
+ function normalizeOptionalString2(value) {
2611
2251
  const trimmed = value?.trim();
2612
2252
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
2613
2253
  }
@@ -2615,7 +2255,7 @@ function normalizeStringList(values) {
2615
2255
  const normalizedValues = [];
2616
2256
  const seen = /* @__PURE__ */ new Set();
2617
2257
  for (const value of values ?? []) {
2618
- const normalized = normalizeOptionalString3(value);
2258
+ const normalized = normalizeOptionalString2(value);
2619
2259
  if (!normalized || seen.has(normalized)) {
2620
2260
  continue;
2621
2261
  }
@@ -2625,7 +2265,7 @@ function normalizeStringList(values) {
2625
2265
  return normalizedValues.length > 0 ? normalizedValues : void 0;
2626
2266
  }
2627
2267
  function collectStringValue(value, previous) {
2628
- const normalized = normalizeOptionalString3(value);
2268
+ const normalized = normalizeOptionalString2(value);
2629
2269
  if (!normalized) {
2630
2270
  throw new InvalidArgumentError("Value cannot be empty.");
2631
2271
  }
@@ -2677,7 +2317,7 @@ function parseUnitInterval(value) {
2677
2317
  return parsed;
2678
2318
  }
2679
2319
  function parseModelRef(value) {
2680
- const normalized = normalizeOptionalString3(value);
2320
+ const normalized = normalizeOptionalString2(value);
2681
2321
  if (!normalized) {
2682
2322
  throw new InvalidArgumentError("Model reference cannot be empty.");
2683
2323
  }
@@ -2687,8 +2327,8 @@ function parseModelRef(value) {
2687
2327
  modelId: normalized
2688
2328
  };
2689
2329
  }
2690
- const provider = normalizeOptionalString3(normalized.slice(0, separatorIndex));
2691
- const modelId = normalizeOptionalString3(normalized.slice(separatorIndex + 1));
2330
+ const provider = normalizeOptionalString2(normalized.slice(0, separatorIndex));
2331
+ const modelId = normalizeOptionalString2(normalized.slice(separatorIndex + 1));
2692
2332
  if (!provider || !modelId) {
2693
2333
  throw new InvalidArgumentError(`Model reference must look like "provider/model" or "model". Received: ${value}.`);
2694
2334
  }
@@ -2739,13 +2379,13 @@ function timestamp() {
2739
2379
  import { InvalidArgumentError as InvalidArgumentError3, Option as Option2 } from "commander";
2740
2380
 
2741
2381
  // src/cli/commands/ingest-episodes.ts
2742
- import fs5 from "fs/promises";
2743
- import path7 from "path";
2382
+ import fs4 from "fs/promises";
2383
+ import path6 from "path";
2744
2384
  import * as clack2 from "@clack/prompts";
2745
2385
  import { InvalidArgumentError as InvalidArgumentError2, Option } from "commander";
2746
2386
 
2747
2387
  // src/adapters/db/episode-ingest-support.ts
2748
- import path5 from "path";
2388
+ import path4 from "path";
2749
2389
  function createEpisodeIngestSupportPort(executor) {
2750
2390
  return {
2751
2391
  countEntries: async () => countRows(executor, "SELECT COUNT(*) AS count FROM entries"),
@@ -2761,7 +2401,7 @@ async function hasRelevantProvenanceMatch(executor, sampleFiles) {
2761
2401
  if (ingestLogMatches > 0) {
2762
2402
  return true;
2763
2403
  }
2764
- const basenames = Array.from(new Set(sampleFiles.map((filePath) => path5.basename(filePath))));
2404
+ const basenames = Array.from(new Set(sampleFiles.map((filePath) => path4.basename(filePath))));
2765
2405
  const basenameClauses = basenames.map(() => "(source_file = ? OR source_file LIKE ?)").join(" OR ");
2766
2406
  const basenameArgs = basenames.flatMap((basename) => [basename, `%/${basename}`]);
2767
2407
  const entryMatches = await countRows(executor, `SELECT COUNT(*) AS count FROM entries WHERE source_file IS NOT NULL AND (${basenameClauses})`, basenameArgs);
@@ -2850,17 +2490,17 @@ function normalizeNullableString(value) {
2850
2490
  }
2851
2491
 
2852
2492
  // src/adapters/openclaw/session/transcript-files.ts
2853
- import fs4 from "fs/promises";
2854
- import path6 from "path";
2493
+ import fs3 from "fs/promises";
2494
+ import path5 from "path";
2855
2495
  var OPENCLAW_TRANSCRIPT_FILE_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl(?:\.(?:reset|deleted)\..+)?$/i;
2856
2496
  async function discoverOpenClawTranscriptFiles(targetPath) {
2857
- const resolvedTargetPath = path6.resolve(targetPath);
2858
- const stat = await fs4.stat(resolvedTargetPath);
2497
+ const resolvedTargetPath = path5.resolve(targetPath);
2498
+ const stat = await fs3.stat(resolvedTargetPath);
2859
2499
  if (stat.isFile()) {
2860
- return matchesOpenClawTranscriptFile(path6.basename(resolvedTargetPath)) ? [resolvedTargetPath] : [];
2500
+ return matchesOpenClawTranscriptFile(path5.basename(resolvedTargetPath)) ? [resolvedTargetPath] : [];
2861
2501
  }
2862
- const entries = await fs4.readdir(resolvedTargetPath, { recursive: true, withFileTypes: true });
2863
- return entries.filter((entry) => entry.isFile() && matchesOpenClawTranscriptFile(entry.name)).map((entry) => path6.resolve(entry.parentPath ?? resolvedTargetPath, entry.name)).sort((left, right) => left.localeCompare(right));
2502
+ const entries = await fs3.readdir(resolvedTargetPath, { recursive: true, withFileTypes: true });
2503
+ return entries.filter((entry) => entry.isFile() && matchesOpenClawTranscriptFile(entry.name)).map((entry) => path5.resolve(entry.parentPath ?? resolvedTargetPath, entry.name)).sort((left, right) => left.localeCompare(right));
2864
2504
  }
2865
2505
  var openClawTranscriptFiles = {
2866
2506
  discoverFiles: discoverOpenClawTranscriptFiles
@@ -2907,7 +2547,7 @@ function registerIngestEpisodesCommand(parent) {
2907
2547
  }
2908
2548
  const { provider, modelId } = resolveEpisodeModel(config, commandInput.modelOverride);
2909
2549
  const modelInfo = createEpisodeIngestSummaryModelInfo(provider, modelId);
2910
- const resolvedTargetPath = path7.resolve(normalizedTargetPath);
2550
+ const resolvedTargetPath = path6.resolve(normalizedTargetPath);
2911
2551
  const sessionsDir = await resolveSessionsDirectory(resolvedTargetPath);
2912
2552
  const ports = await createEpisodeIngestPorts(database, sessionsDir);
2913
2553
  const embeddingSetup = resolveEpisodeEmbeddingSetup(config, commandInput);
@@ -3122,18 +2762,18 @@ function createEpisodeIngestSummaryLlm(provider, modelId, apiKey) {
3122
2762
  };
3123
2763
  }
3124
2764
  async function resolveSessionsDirectory(targetPath) {
3125
- const stat = await fs5.stat(targetPath);
3126
- return stat.isFile() ? path7.dirname(targetPath) : targetPath;
2765
+ const stat = await fs4.stat(targetPath);
2766
+ return stat.isFile() ? path6.dirname(targetPath) : targetPath;
3127
2767
  }
3128
2768
  function resolveEpisodeDbPath(config, overridePath) {
3129
- const normalizedOverride = normalizeOptionalString3(overridePath);
2769
+ const normalizedOverride = normalizeOptionalString2(overridePath);
3130
2770
  if (!normalizedOverride) {
3131
2771
  return config?.dbPath ?? resolveDbPath(config);
3132
2772
  }
3133
2773
  if (normalizedOverride === ":memory:" || normalizedOverride.startsWith("file:")) {
3134
2774
  return normalizedOverride;
3135
2775
  }
3136
- return path7.resolve(normalizedOverride);
2776
+ return path6.resolve(normalizedOverride);
3137
2777
  }
3138
2778
  function resolveEpisodeModel(config, overrideRef) {
3139
2779
  const resolved = resolveModel(config, "episode");
@@ -3247,7 +2887,7 @@ function reportEpisodeProgress(completed, total, session) {
3247
2887
  }
3248
2888
  function formatEpisodeProgressLine(completed, total, session) {
3249
2889
  const prefix = completed !== void 0 && total !== void 0 ? `${completed}/${total} ` : "";
3250
- const fileLabel = path7.basename(session.filePath);
2890
+ const fileLabel = path6.basename(session.filePath);
3251
2891
  const details = session.action === "failed" ? `failed (${session.error ?? "unknown error"})` : session.action;
3252
2892
  const usage = session.usage.totalCost > 0 ? ` ${formatCost(session.usage.totalCost)}` : "";
3253
2893
  return `${prefix}${fileLabel}: ${details}${usage}`;
@@ -3272,15 +2912,15 @@ function formatUnknownError2(error) {
3272
2912
  }
3273
2913
  function normalizeEpisodeIngestCommand(targetPath, options) {
3274
2914
  const commandInput = {
3275
- targetPath: normalizeOptionalString3(targetPath),
2915
+ targetPath: normalizeOptionalString2(targetPath),
3276
2916
  verbose: options.verbose === true,
3277
2917
  dryRun: options.dryRun === true,
3278
2918
  regenerate: options.regenerate === true,
3279
2919
  embedOnly: options.embedOnly === true,
3280
2920
  noEmbed: options.noEmbed === true,
3281
- recent: normalizeOptionalString3(options.recent),
2921
+ recent: normalizeOptionalString2(options.recent),
3282
2922
  concurrency: options.concurrency ?? DEFAULT_EPISODE_INGEST_CONCURRENCY,
3283
- dbOverride: normalizeOptionalString3(options.db),
2923
+ dbOverride: normalizeOptionalString2(options.db),
3284
2924
  modelOverride: options.model ? parseModelRef(options.model) : void 0
3285
2925
  };
3286
2926
  validateEpisodeIngestOptions(commandInput);
@@ -3291,26 +2931,26 @@ function parseEpisodeIngestConcurrency(value) {
3291
2931
  }
3292
2932
 
3293
2933
  // src/cli/commands/ingest-procedures.ts
3294
- import path9 from "path";
2934
+ import path8 from "path";
3295
2935
  import * as clack3 from "@clack/prompts";
3296
2936
  import "commander";
3297
2937
 
3298
2938
  // src/adapters/files/procedure-files.ts
3299
- import fs6 from "fs/promises";
3300
- import path8 from "path";
2939
+ import fs5 from "fs/promises";
2940
+ import path7 from "path";
3301
2941
  var PROCEDURE_FILE_PATTERN = /^.+\.ya?ml$/iu;
3302
2942
  async function discoverProcedureFiles(targetPath, options = {}) {
3303
- const resolvedTargetPath = path8.resolve(targetPath);
3304
- const stat = await fs6.stat(resolvedTargetPath);
2943
+ const resolvedTargetPath = path7.resolve(targetPath);
2944
+ const stat = await fs5.stat(resolvedTargetPath);
3305
2945
  if (stat.isFile()) {
3306
- return matchesProcedureFileName(path8.basename(resolvedTargetPath)) ? [resolvedTargetPath] : [];
2946
+ return matchesProcedureFileName(path7.basename(resolvedTargetPath)) ? [resolvedTargetPath] : [];
3307
2947
  }
3308
2948
  const recursive = options.recursive ?? true;
3309
- const entries = recursive ? await fs6.readdir(resolvedTargetPath, { recursive: true, withFileTypes: true }) : await fs6.readdir(resolvedTargetPath, { withFileTypes: true });
3310
- return entries.filter((entry) => entry.isFile() && matchesProcedureFileName(entry.name)).map((entry) => path8.resolve(entry.parentPath ?? resolvedTargetPath, entry.name)).sort((left, right) => left.localeCompare(right));
2949
+ const entries = recursive ? await fs5.readdir(resolvedTargetPath, { recursive: true, withFileTypes: true }) : await fs5.readdir(resolvedTargetPath, { withFileTypes: true });
2950
+ return entries.filter((entry) => entry.isFile() && matchesProcedureFileName(entry.name)).map((entry) => path7.resolve(entry.parentPath ?? resolvedTargetPath, entry.name)).sort((left, right) => left.localeCompare(right));
3311
2951
  }
3312
2952
  async function readProcedureFile(filePath) {
3313
- return fs6.readFile(filePath, "utf-8");
2953
+ return fs5.readFile(filePath, "utf-8");
3314
2954
  }
3315
2955
  var LocalProcedureFiles = class {
3316
2956
  /**
@@ -3645,7 +3285,7 @@ function registerIngestProceduresCommand(parent) {
3645
3285
  try {
3646
3286
  const config = readConfig();
3647
3287
  const dbPath = config.dbPath;
3648
- const resolvedTargetPath = path9.resolve(commandInput.targetPath);
3288
+ const resolvedTargetPath = path8.resolve(commandInput.targetPath);
3649
3289
  database = await createDatabase(dbPath);
3650
3290
  if (commandInput.verbose) {
3651
3291
  clack3.log.step(`Preparing procedure sync for ${resolvedTargetPath}...`);
@@ -3701,7 +3341,7 @@ function registerIngestProceduresCommand(parent) {
3701
3341
  }
3702
3342
  function normalizeIngestProceduresCommand(targetPath, options) {
3703
3343
  return {
3704
- targetPath: normalizeOptionalString3(targetPath) ?? DEFAULT_PROCEDURE_SYNC_PATH,
3344
+ targetPath: normalizeOptionalString2(targetPath) ?? DEFAULT_PROCEDURE_SYNC_PATH,
3705
3345
  verbose: options.verbose === true,
3706
3346
  dryRun: options.dryRun === true
3707
3347
  };
@@ -3822,11 +3462,11 @@ function registerIngestEntriesCommand(parent) {
3822
3462
  const claimApiKey = claimModel ? resolveLlmApiKey(config, claimModel.provider) : void 0;
3823
3463
  const sharedEmbedding = createEmbeddingClient(resolveEmbeddingApiKey(config), resolveEmbeddingModel(config));
3824
3464
  if (commandInput.verbose) {
3825
- clack4.log.step(`Discovering transcript files in ${path10.resolve(commandInput.targetPath)}...`);
3465
+ clack4.log.step(`Discovering transcript files in ${path9.resolve(commandInput.targetPath)}...`);
3826
3466
  }
3827
3467
  const files = await localTranscriptFiles.discoverFiles(commandInput.targetPath);
3828
3468
  if (files.length === 0) {
3829
- clack4.log.warn(`No transcript files found at ${path10.resolve(commandInput.targetPath)}.`);
3469
+ clack4.log.warn(`No transcript files found at ${path9.resolve(commandInput.targetPath)}.`);
3830
3470
  clack4.outro("Nothing to ingest.");
3831
3471
  return;
3832
3472
  }
@@ -3909,7 +3549,7 @@ function registerIngestEntriesCommand(parent) {
3909
3549
  failedFiles: 0,
3910
3550
  warnings: 0
3911
3551
  };
3912
- const usageTotals = extractionRuns.reduce((total, run) => addUsageStats(total, run.usage), createEmptyUsageStats3());
3552
+ const usageTotals = extractionRuns.reduce((total, run) => addUsageStats(total, run.usage), createEmptyUsageStats2());
3913
3553
  addUsageStats(usageTotals, dedupUsage);
3914
3554
  let runningCost = 0;
3915
3555
  for (const [index, extractionRun] of extractionRuns.entries()) {
@@ -3922,9 +3562,9 @@ function registerIngestEntriesCommand(parent) {
3922
3562
  totals.skippedFiles += 1;
3923
3563
  if (commandInput.verbose) {
3924
3564
  printVerboseFileDetails(result, commandInput, usage);
3925
- clack4.log.step(buildSkippedMessage(path10.basename(result.file)));
3565
+ clack4.log.step(buildSkippedMessage(path9.basename(result.file)));
3926
3566
  } else {
3927
- clack4.log.step(buildSkippedMessage(path10.basename(result.file)));
3567
+ clack4.log.step(buildSkippedMessage(path9.basename(result.file)));
3928
3568
  }
3929
3569
  continue;
3930
3570
  }
@@ -3933,7 +3573,7 @@ function registerIngestEntriesCommand(parent) {
3933
3573
  if (commandInput.verbose) {
3934
3574
  printVerboseFileDetails(result, commandInput, usage);
3935
3575
  }
3936
- clack4.log.error(buildFailureMessage(path10.basename(result.file), result, commandInput, usage, index === 0));
3576
+ clack4.log.error(buildFailureMessage(path9.basename(result.file), result, commandInput, usage, index === 0));
3937
3577
  continue;
3938
3578
  }
3939
3579
  const storeResult = result.storeResult ?? emptyStoreResult2();
@@ -3943,7 +3583,7 @@ function registerIngestEntriesCommand(parent) {
3943
3583
  if (commandInput.verbose) {
3944
3584
  printVerboseFileDetails(result, commandInput, usage);
3945
3585
  }
3946
- clack4.log.step(buildSuccessMessage(path10.basename(result.file), result, commandInput, usage, index === 0));
3586
+ clack4.log.step(buildSuccessMessage(path9.basename(result.file), result, commandInput, usage, index === 0));
3947
3587
  }
3948
3588
  const summaryParts = [`${totals.stored} ${pluralize3(totals.stored, "entry", "entries")} stored`, `${totals.deduped} deduped`];
3949
3589
  if (totals.rejected > 0) {
@@ -3982,7 +3622,7 @@ function registerIngestEntriesCommand(parent) {
3982
3622
  });
3983
3623
  }
3984
3624
  function normalizeIngestEntriesCommand(targetPath, options) {
3985
- const normalizedTargetPath = normalizeOptionalString3(targetPath);
3625
+ const normalizedTargetPath = normalizeOptionalString2(targetPath);
3986
3626
  if (!normalizedTargetPath) {
3987
3627
  throw new InvalidArgumentError3("Path cannot be empty.");
3988
3628
  }
@@ -4336,7 +3976,7 @@ function truncateText(text2, maxLength) {
4336
3976
  function isDefined3(value) {
4337
3977
  return value !== void 0;
4338
3978
  }
4339
- function createEmptyUsageStats3() {
3979
+ function createEmptyUsageStats2() {
4340
3980
  return {
4341
3981
  calls: 0,
4342
3982
  inputTokens: 0,
@@ -4369,11 +4009,11 @@ function parseConcurrency(value) {
4369
4009
  }
4370
4010
 
4371
4011
  // src/cli/commands/setup.ts
4372
- import { getModels } from "@mariozechner/pi-ai";
4012
+ import { getModels } from "@earendil-works/pi-ai";
4373
4013
 
4374
4014
  // src/cli/ui.ts
4375
- import os2 from "os";
4376
- import path11 from "path";
4015
+ import os from "os";
4016
+ import path10 from "path";
4377
4017
  import * as clack5 from "@clack/prompts";
4378
4018
  function createCliPrompts() {
4379
4019
  return {
@@ -4403,24 +4043,24 @@ function createCliPrompts() {
4403
4043
  };
4404
4044
  }
4405
4045
  var cliPrompts = createCliPrompts();
4406
- function resolveUserPath2(value) {
4046
+ function resolveUserPath(value) {
4407
4047
  const trimmed = value.trim();
4408
4048
  if (trimmed === ":memory:" || trimmed.startsWith("file:")) {
4409
4049
  return trimmed;
4410
4050
  }
4411
4051
  if (trimmed === "~") {
4412
- return os2.homedir();
4052
+ return os.homedir();
4413
4053
  }
4414
4054
  if (trimmed.startsWith("~/")) {
4415
- return path11.join(os2.homedir(), trimmed.slice(2));
4055
+ return path10.join(os.homedir(), trimmed.slice(2));
4416
4056
  }
4417
4057
  if (trimmed.startsWith("~\\")) {
4418
- return path11.join(os2.homedir(), trimmed.slice(2));
4058
+ return path10.join(os.homedir(), trimmed.slice(2));
4419
4059
  }
4420
- return path11.resolve(trimmed);
4060
+ return path10.resolve(trimmed);
4421
4061
  }
4422
4062
  function formatPathForDisplay(filePath) {
4423
- const home = os2.homedir();
4063
+ const home = os.homedir();
4424
4064
  const resolvedPath = filePath.trim();
4425
4065
  return resolvedPath.startsWith(home) ? `~${resolvedPath.slice(home.length)}` : resolvedPath;
4426
4066
  }
@@ -4448,50 +4088,50 @@ function validateSecret(value) {
4448
4088
  return value?.trim().length ? void 0 : "Value cannot be empty.";
4449
4089
  }
4450
4090
  function hasSecret(value) {
4451
- return normalizeOptionalString4(value) !== void 0;
4091
+ return normalizeOptionalString3(value) !== void 0;
4452
4092
  }
4453
4093
  function formatModelRef(config) {
4454
- const provider = normalizeOptionalString4(config?.provider) ?? "(provider not set)";
4455
- const model = normalizeOptionalString4(config?.model) ?? "(model not set)";
4094
+ const provider = normalizeOptionalString3(config?.provider) ?? "(provider not set)";
4095
+ const model = normalizeOptionalString3(config?.model) ?? "(model not set)";
4456
4096
  return `${provider}/${model}`;
4457
4097
  }
4458
4098
  function hasModelOverride(config) {
4459
- return normalizeOptionalString4(config?.provider) !== void 0 || normalizeOptionalString4(config?.model) !== void 0;
4099
+ return normalizeOptionalString3(config?.provider) !== void 0 || normalizeOptionalString3(config?.model) !== void 0;
4460
4100
  }
4461
4101
  function sameModelRef(left, right) {
4462
- return normalizeOptionalString4(left?.provider) === normalizeOptionalString4(right?.provider) && normalizeOptionalString4(left?.model) === normalizeOptionalString4(right?.model);
4102
+ return normalizeOptionalString3(left?.provider) === normalizeOptionalString3(right?.provider) && normalizeOptionalString3(left?.model) === normalizeOptionalString3(right?.model);
4463
4103
  }
4464
4104
  function resolveStoredCredentialForAuth(config, auth) {
4465
4105
  switch (auth) {
4466
4106
  case "openai-api-key":
4467
- return normalizeOptionalString4(config?.credentials?.openaiApiKey);
4107
+ return normalizeOptionalString3(config?.credentials?.openaiApiKey);
4468
4108
  case "anthropic-api-key":
4469
- return normalizeOptionalString4(config?.credentials?.anthropicApiKey);
4109
+ return normalizeOptionalString3(config?.credentials?.anthropicApiKey);
4470
4110
  case "anthropic-token":
4471
- return normalizeOptionalString4(config?.credentials?.anthropicOauthToken);
4111
+ return normalizeOptionalString3(config?.credentials?.anthropicOauthToken);
4472
4112
  case "anthropic-oauth":
4473
4113
  case "openai-subscription":
4474
4114
  return void 0;
4475
4115
  }
4476
4116
  }
4477
4117
  function resolveStoredEmbeddingCredential(config) {
4478
- return normalizeOptionalString4(config?.credentials?.openaiApiKey);
4118
+ return normalizeOptionalString3(config?.credentials?.openaiApiKey);
4479
4119
  }
4480
4120
  function normalizeProvider(value) {
4481
- const normalized = normalizeOptionalString4(value);
4121
+ const normalized = normalizeOptionalString3(value);
4482
4122
  if (normalized === "openai" || normalized === "openai-codex" || normalized === "anthropic") {
4483
4123
  return normalized;
4484
4124
  }
4485
4125
  return void 0;
4486
4126
  }
4487
- function normalizeAuthMethod2(value) {
4488
- const normalized = normalizeOptionalString4(value);
4127
+ function normalizeAuthMethod(value) {
4128
+ const normalized = normalizeOptionalString3(value);
4489
4129
  if (normalized === "openai-api-key" || normalized === "openai-subscription" || normalized === "anthropic-api-key" || normalized === "anthropic-oauth" || normalized === "anthropic-token") {
4490
4130
  return normalized;
4491
4131
  }
4492
4132
  return void 0;
4493
4133
  }
4494
- function normalizeOptionalString4(value) {
4134
+ function normalizeOptionalString3(value) {
4495
4135
  const trimmed = value?.trim();
4496
4136
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
4497
4137
  }
@@ -4733,7 +4373,7 @@ function hasPersistedSurgeonConfig(config) {
4733
4373
  return false;
4734
4374
  }
4735
4375
  const retirementConfig = config.passes?.retirement;
4736
- return hasModelOverride(config.model) || config.costCap !== void 0 || config.dailyCostCap !== void 0 || config.contextLimit !== void 0 || normalizeOptionalString4(config.customInstructions) !== void 0 || retirementConfig?.protectRecalledDays !== void 0 || retirementConfig?.protectMinImportance !== void 0 || retirementConfig?.skipRecentlyEvaluatedDays !== void 0;
4376
+ return hasModelOverride(config.model) || config.costCap !== void 0 || config.dailyCostCap !== void 0 || config.contextLimit !== void 0 || normalizeOptionalString3(config.customInstructions) !== void 0 || retirementConfig?.protectRecalledDays !== void 0 || retirementConfig?.protectMinImportance !== void 0 || retirementConfig?.skipRecentlyEvaluatedDays !== void 0;
4737
4377
  }
4738
4378
 
4739
4379
  // src/cli/commands/setup/config.ts
@@ -4770,8 +4410,8 @@ function isSetupConfigured(config, env = process.env) {
4770
4410
  return getSetupReadiness(config, env).ready;
4771
4411
  }
4772
4412
  function getSetupReadiness(config, env = process.env) {
4773
- const provider = normalizeOptionalString4(config?.provider);
4774
- const model = normalizeOptionalString4(config?.model);
4413
+ const provider = normalizeOptionalString3(config?.provider);
4414
+ const model = normalizeOptionalString3(config?.model);
4775
4415
  if (!provider || !model) {
4776
4416
  return {
4777
4417
  ready: false,
@@ -4812,7 +4452,7 @@ function formatSavedConfigSummary(config, configPath, dbPath, options) {
4812
4452
  return lines.join("\n");
4813
4453
  }
4814
4454
  function describePrimaryCredentialConfig(config) {
4815
- const auth = normalizeAuthMethod2(config.auth);
4455
+ const auth = normalizeAuthMethod(config.auth);
4816
4456
  if (!auth) {
4817
4457
  return "not set";
4818
4458
  }
@@ -4829,9 +4469,9 @@ function describePrimaryCredentialConfig(config) {
4829
4469
  }
4830
4470
  function describeEmbeddingConfig(config) {
4831
4471
  if (hasSecret(resolveStoredEmbeddingCredential(config))) {
4832
- return normalizeAuthMethod2(config.auth) === "openai-api-key" ? "uses the primary OpenAI key" : "separate OpenAI key configured";
4472
+ return normalizeAuthMethod(config.auth) === "openai-api-key" ? "uses the primary OpenAI key" : "separate OpenAI key configured";
4833
4473
  }
4834
- const auth = normalizeAuthMethod2(config.auth);
4474
+ const auth = normalizeAuthMethod(config.auth);
4835
4475
  if (auth && auth !== "openai-api-key") {
4836
4476
  return "missing separate OpenAI key";
4837
4477
  }
@@ -4841,7 +4481,7 @@ function mergeStoredCredentials(existingCredentials, values) {
4841
4481
  const next = {
4842
4482
  ...existingCredentials ?? {}
4843
4483
  };
4844
- const normalizedPrimaryCredential = normalizeOptionalString4(values.primaryCredential);
4484
+ const normalizedPrimaryCredential = normalizeOptionalString3(values.primaryCredential);
4845
4485
  if (normalizedPrimaryCredential) {
4846
4486
  if (values.auth === "openai-api-key") {
4847
4487
  next.openaiApiKey = normalizedPrimaryCredential;
@@ -4851,7 +4491,7 @@ function mergeStoredCredentials(existingCredentials, values) {
4851
4491
  next.anthropicOauthToken = normalizedPrimaryCredential;
4852
4492
  }
4853
4493
  }
4854
- const normalizedEmbeddingApiKey = normalizeOptionalString4(values.embeddingApiKey);
4494
+ const normalizedEmbeddingApiKey = normalizeOptionalString3(values.embeddingApiKey);
4855
4495
  if (normalizedEmbeddingApiKey) {
4856
4496
  next.openaiApiKey = normalizedEmbeddingApiKey;
4857
4497
  }
@@ -4877,7 +4517,7 @@ async function runSetupCore(options = {}) {
4877
4517
  }
4878
4518
  const existingConfig = options.existingConfig;
4879
4519
  const configPath = runtime.resolveConfigPath();
4880
- const auth = await selectAuthMethod(prompts, normalizeAuthMethod2(existingConfig?.auth));
4520
+ const auth = await selectAuthMethod(prompts, normalizeAuthMethod(existingConfig?.auth));
4881
4521
  if (auth === null) {
4882
4522
  return null;
4883
4523
  }
@@ -4922,7 +4562,7 @@ async function runSetupCore(options = {}) {
4922
4562
  if (stageOverrides === null) {
4923
4563
  return null;
4924
4564
  }
4925
- const defaultDbPath = normalizeOptionalString4(existingConfig?.dbPath) ?? runtime.resolveDbPath(existingConfig);
4565
+ const defaultDbPath = normalizeOptionalString3(existingConfig?.dbPath) ?? runtime.resolveDbPath(existingConfig);
4926
4566
  const dbPathInput = await prompts.text({
4927
4567
  message: "Database path:",
4928
4568
  initialValue: defaultDbPath,
@@ -4932,7 +4572,7 @@ async function runSetupCore(options = {}) {
4932
4572
  if (prompts.isCancel(dbPathInput)) {
4933
4573
  return null;
4934
4574
  }
4935
- const dbPath = resolveUserPath2(dbPathInput);
4575
+ const dbPath = resolveUserPath(dbPathInput);
4936
4576
  const nextConfig = buildNextConfig(existingConfig, {
4937
4577
  auth,
4938
4578
  provider,
@@ -5289,9 +4929,9 @@ async function promptTaskModelOverrides(prompts, runtime, options) {
5289
4929
  async function promptStageOverride(prompts, runtime, options) {
5290
4930
  const defaultRef = `${describeAuthMethod(options.defaultAuth)} / ${options.defaultModel}`;
5291
4931
  const currentProvider = normalizeProvider(options.current?.provider);
5292
- const currentModel = normalizeOptionalString4(options.current?.model) ?? options.defaultModel;
4932
+ const currentModel = normalizeOptionalString3(options.current?.model) ?? options.defaultModel;
5293
4933
  const currentAuth = resolveStageAuthChoice(currentProvider, options.defaultAuth);
5294
- const hasExplicitOverride = normalizeOptionalString4(options.current?.provider) !== void 0 || normalizeOptionalString4(options.current?.model) !== void 0;
4934
+ const hasExplicitOverride = normalizeOptionalString3(options.current?.provider) !== void 0 || normalizeOptionalString3(options.current?.model) !== void 0;
5295
4935
  const action = await prompts.select({
5296
4936
  message: `${options.stage.label} model override:`,
5297
4937
  options: [
@@ -5450,7 +5090,7 @@ async function runSetupCore2(options = {}) {
5450
5090
  }
5451
5091
 
5452
5092
  // src/cli/commands/init/cost-estimator.ts
5453
- import { getModels as getModels2 } from "@mariozechner/pi-ai";
5093
+ import { getModels as getModels2 } from "@earendil-works/pi-ai";
5454
5094
  var CHARS_PER_TOKEN2 = 4;
5455
5095
  var EFFECTIVE_CONTENT_RATIO = 0.1;
5456
5096
  var OUTPUT_TOKEN_RATIO = 0.1;
@@ -5490,8 +5130,8 @@ function formatTokenCount(tokens) {
5490
5130
 
5491
5131
  // src/cli/commands/init/external-commands.ts
5492
5132
  import { execFile, execFileSync } from "child_process";
5493
- import fs7 from "fs/promises";
5494
- import path12 from "path";
5133
+ import fs6 from "fs/promises";
5134
+ import path11 from "path";
5495
5135
  var OPENCLAW_PLUGIN_PACKAGE = "@agenr/agenr-plugin";
5496
5136
  function execAsync(command, args, options) {
5497
5137
  return new Promise((resolve, reject) => {
@@ -5588,10 +5228,10 @@ async function restartOpenClawGateway() {
5588
5228
  }
5589
5229
  }
5590
5230
  async function writeOpenClawPluginConfig(stateDir, config) {
5591
- const openclawConfigPath = path12.join(stateDir, "openclaw.json");
5231
+ const openclawConfigPath = path11.join(stateDir, "openclaw.json");
5592
5232
  let root = {};
5593
5233
  try {
5594
- const raw = await fs7.readFile(openclawConfigPath, "utf8");
5234
+ const raw = await fs6.readFile(openclawConfigPath, "utf8");
5595
5235
  const parsed = JSON.parse(raw);
5596
5236
  if (isRecord(parsed)) {
5597
5237
  root = parsed;
@@ -5617,13 +5257,13 @@ async function writeOpenClawPluginConfig(stateDir, config) {
5617
5257
  } else {
5618
5258
  delete entryConfig.configPath;
5619
5259
  }
5620
- await fs7.mkdir(stateDir, { recursive: true });
5621
- await fs7.writeFile(openclawConfigPath, `${JSON.stringify(root, null, 2)}
5260
+ await fs6.mkdir(stateDir, { recursive: true });
5261
+ await fs6.writeFile(openclawConfigPath, `${JSON.stringify(root, null, 2)}
5622
5262
  `, "utf8");
5623
5263
  return openclawConfigPath;
5624
5264
  }
5625
5265
  function shouldPersistPluginConfigPath(dbPath, configPath) {
5626
- return path12.dirname(dbPath) !== path12.dirname(configPath);
5266
+ return path11.dirname(dbPath) !== path11.dirname(configPath);
5627
5267
  }
5628
5268
  function isRecord(value) {
5629
5269
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -5650,32 +5290,32 @@ function ensureArrayOfStrings(target, key) {
5650
5290
  }
5651
5291
 
5652
5292
  // src/cli/commands/init/openclaw-detect.ts
5653
- import fs8 from "fs";
5654
- import os3 from "os";
5655
- import path13 from "path";
5293
+ import fs7 from "fs";
5294
+ import os2 from "os";
5295
+ import path12 from "path";
5656
5296
  function resolveDefaultOpenClawStateDir() {
5657
- return path13.join(os3.homedir(), ".openclaw");
5297
+ return path12.join(os2.homedir(), ".openclaw");
5658
5298
  }
5659
- function detectOpenClawInstallation(env = process.env, existsSyncFn = fs8.existsSync) {
5660
- const envStateDir = normalizeOptionalString5(env.OPENCLAW_STATE_DIR) ?? normalizeOptionalString5(env.OPENCLAW_HOME);
5299
+ function detectOpenClawInstallation(env = process.env, existsSyncFn = fs7.existsSync) {
5300
+ const envStateDir = normalizeOptionalString4(env.OPENCLAW_STATE_DIR) ?? normalizeOptionalString4(env.OPENCLAW_HOME);
5661
5301
  const source = envStateDir ? "environment" : "default";
5662
- const stateDir = envStateDir ? resolveUserPath2(envStateDir) : resolveDefaultOpenClawStateDir();
5302
+ const stateDir = envStateDir ? resolveUserPath(envStateDir) : resolveDefaultOpenClawStateDir();
5663
5303
  return {
5664
5304
  detected: envStateDir !== void 0 || existsSyncFn(stateDir),
5665
5305
  stateDir,
5666
- configPath: path13.join(stateDir, "openclaw.json"),
5667
- sessionsRoot: path13.join(stateDir, "agents"),
5306
+ configPath: path12.join(stateDir, "openclaw.json"),
5307
+ sessionsRoot: path12.join(stateDir, "agents"),
5668
5308
  source
5669
5309
  };
5670
5310
  }
5671
- function normalizeOptionalString5(value) {
5311
+ function normalizeOptionalString4(value) {
5672
5312
  const trimmed = value?.trim();
5673
5313
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
5674
5314
  }
5675
5315
 
5676
5316
  // src/cli/commands/init/session-scanner.ts
5677
- import fs9 from "fs/promises";
5678
- import path14 from "path";
5317
+ import fs8 from "fs/promises";
5318
+ import path13 from "path";
5679
5319
  async function scanSessionFiles(sessionsRoot, recentDays = 7) {
5680
5320
  const result = {
5681
5321
  totalFiles: 0,
@@ -5700,7 +5340,7 @@ async function scanSessionFiles(sessionsRoot, recentDays = 7) {
5700
5340
  }
5701
5341
  let stat;
5702
5342
  try {
5703
- stat = await fs9.stat(filePath);
5343
+ stat = await fs8.stat(filePath);
5704
5344
  } catch (error) {
5705
5345
  if (isMissingPathError(error)) {
5706
5346
  continue;
@@ -5718,7 +5358,7 @@ async function scanSessionFiles(sessionsRoot, recentDays = 7) {
5718
5358
  return result;
5719
5359
  }
5720
5360
  function isSessionTranscriptPath(filePath) {
5721
- return filePath.split(path14.sep).includes("sessions");
5361
+ return filePath.split(path13.sep).includes("sessions");
5722
5362
  }
5723
5363
  function isMissingPathError(error) {
5724
5364
  return typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
@@ -6089,7 +5729,7 @@ function registerInitCommand(program2) {
6089
5729
  import * as clack6 from "@clack/prompts";
6090
5730
  import { InvalidArgumentError as InvalidArgumentError4, Option as Option3 } from "commander";
6091
5731
  function registerRecallCommand(program2) {
6092
- program2.command("recall <query>").description("Search the knowledge database with the v1 hybrid recall pipeline").addOption(new Option3("--limit <n>", "Max results").argParser(parsePositiveInteger).default(10)).addOption(new Option3("--threshold <n>", "Minimum score cutoff").argParser(parseUnitInterval).default(0)).addOption(new Option3("--budget <n>", "Max token budget").argParser(parsePositiveInteger)).addOption(new Option3("--types <types>", "Comma-separated entry types").argParser(parseEntryTypes)).addOption(new Option3("--tags <tags>", "Comma-separated tags").argParser(parseCsvList)).option("--since <date>", "Only entries after this date (ISO or relative like 7d)").option("--until <date>", "Only entries before this date").option("--around <date>", "Bias results toward this date").option("--as-of <date>", "Resolve current vs prior state at this reference time").addOption(new Option3("--around-radius <n>", "Gaussian radius in days").argParser(parsePositiveNumber).default(14)).option("--verbose", "Show score breakdowns").action(async (query, options) => {
5732
+ program2.command("recall <query>").description("Search the knowledge database with the v1 hybrid recall pipeline").addOption(new Option3("--limit <n>", "Max results").argParser(parsePositiveInteger).default(10)).addOption(new Option3("--threshold <n>", "Minimum score cutoff").argParser(parseUnitInterval).default(0)).addOption(new Option3("--budget <n>", "Max token budget").argParser(parsePositiveInteger)).addOption(new Option3("--types <types>", "Comma-separated entry types").argParser(parseEntryTypes)).addOption(new Option3("--tags <tags>", "Comma-separated tags").argParser(parseCsvList)).option("--since <date>", "Only entries after this date (ISO or relative like 7d)").option("--until <date>", "Only entries before this date").option("--around <date>", "Bias results toward this date").option("--as-of <date>", "Resolve current vs prior state at this reference time").addOption(new Option3("--around-radius <n>", "Gaussian radius in days").argParser(parsePositiveNumber).default(14)).addOption(new Option3("--cross-encoder <state>", "Enable or disable the cross-encoder rerank stage").choices(["enabled", "disabled"])).addOption(new Option3("--cross-encoder-top-k <n>", "Top-K shortlist size for cross-encoder rerank").argParser(parsePositiveInteger)).addOption(new Option3("--cross-encoder-alpha <n>", "Blend weight for cross-encoder vs prior score (0-1)").argParser(parseUnitInterval)).option("--verbose", "Show score breakdowns").action(async (query, options) => {
6093
5733
  clack6.intro(banner());
6094
5734
  let db = null;
6095
5735
  try {
@@ -6098,23 +5738,37 @@ function registerRecallCommand(program2) {
6098
5738
  const dbPath = config.dbPath;
6099
5739
  const embeddingClient = createEmbeddingClient(resolveEmbeddingApiKey(config), resolveEmbeddingModel(config));
6100
5740
  db = await createDatabase(dbPath);
6101
- const adapter = createRecallAdapter(db, embeddingClient);
5741
+ const recallPorts = createRecallAdapter(db, embeddingClient);
5742
+ const crossEncoder = commandInput.rankingPolicy?.crossEncoder === "disabled" ? void 0 : tryCreateCrossEncoder(config);
5743
+ const adapter = attachCrossEncoderPort(recallPorts, crossEncoder);
6102
5744
  let lastTraceSummary;
6103
5745
  const spinner6 = clack6.spinner();
6104
5746
  spinner6.start("Searching knowledge...");
6105
- const results = await recall(commandInput.request, adapter, {
5747
+ const recallOptions = {
6106
5748
  trace: {
6107
5749
  reportSummary(summary) {
6108
5750
  lastTraceSummary = summary;
6109
5751
  }
6110
- }
6111
- });
5752
+ },
5753
+ ...commandInput.rankingPolicy ? { rankingPolicy: commandInput.rankingPolicy } : {}
5754
+ };
5755
+ const results = await recall(commandInput.request, adapter, recallOptions);
6112
5756
  spinner6.stop(`Found ${results.length} ${pluralize4(results.length, "result")}.`);
6113
5757
  if (lastTraceSummary?.degraded.active) {
6114
5758
  for (const notice of lastTraceSummary.degraded.notices) {
6115
5759
  clack6.log.warn(notice);
6116
5760
  }
6117
5761
  }
5762
+ if (commandInput.verbose && lastTraceSummary) {
5763
+ const crossEncoder2 = lastTraceSummary.crossEncoder;
5764
+ if (crossEncoder2.applied) {
5765
+ clack6.log.info(
5766
+ `Cross-encoder reranked top-${crossEncoder2.k} (alpha=${crossEncoder2.alpha.toFixed(2)}, latencyMs=${crossEncoder2.latencyMs}, rescored=${crossEncoder2.rescoredIds.length}).`
5767
+ );
5768
+ } else if (crossEncoder2.degradedReason) {
5769
+ clack6.log.info(`Cross-encoder skipped (${crossEncoder2.degradedReason}).`);
5770
+ }
5771
+ }
6118
5772
  if (results.length === 0) {
6119
5773
  clack6.outro("No matching entries found.");
6120
5774
  return;
@@ -6133,10 +5787,11 @@ function registerRecallCommand(program2) {
6133
5787
  });
6134
5788
  }
6135
5789
  function normalizeRecallCommand(query, options) {
6136
- const normalizedQuery = normalizeOptionalString3(query);
5790
+ const normalizedQuery = normalizeOptionalString2(query);
6137
5791
  if (!normalizedQuery) {
6138
5792
  throw new InvalidArgumentError4("Query cannot be empty.");
6139
5793
  }
5794
+ const rankingPolicy = buildRankingPolicy(options);
6140
5795
  return {
6141
5796
  request: {
6142
5797
  text: normalizedQuery,
@@ -6145,15 +5800,38 @@ function normalizeRecallCommand(query, options) {
6145
5800
  budget: options.budget,
6146
5801
  types: options.types,
6147
5802
  tags: normalizeStringList(options.tags),
6148
- since: normalizeOptionalString3(options.since),
6149
- until: normalizeOptionalString3(options.until),
6150
- around: normalizeOptionalString3(options.around),
5803
+ since: normalizeOptionalString2(options.since),
5804
+ until: normalizeOptionalString2(options.until),
5805
+ around: normalizeOptionalString2(options.around),
6151
5806
  aroundRadius: options.aroundRadius,
6152
- asOf: normalizeOptionalString3(options.asOf)
5807
+ asOf: normalizeOptionalString2(options.asOf)
6153
5808
  },
6154
- verbose: options.verbose === true
5809
+ verbose: options.verbose === true,
5810
+ ...rankingPolicy ? { rankingPolicy } : {}
6155
5811
  };
6156
5812
  }
5813
+ function buildRankingPolicy(options) {
5814
+ const policy = {};
5815
+ if (options.crossEncoder !== void 0) {
5816
+ policy.crossEncoder = options.crossEncoder;
5817
+ }
5818
+ if (typeof options.crossEncoderTopK === "number") {
5819
+ policy.crossEncoderTopK = options.crossEncoderTopK;
5820
+ }
5821
+ if (typeof options.crossEncoderAlpha === "number") {
5822
+ policy.crossEncoderAlpha = options.crossEncoderAlpha;
5823
+ }
5824
+ return Object.keys(policy).length > 0 ? policy : void 0;
5825
+ }
5826
+ function tryCreateCrossEncoder(config) {
5827
+ try {
5828
+ const apiKey = resolveCrossEncoderApiKey(config);
5829
+ const { modelId } = resolveModel(config, "cross_encoder");
5830
+ return createOpenAICrossEncoder({ apiKey, model: modelId });
5831
+ } catch {
5832
+ return void 0;
5833
+ }
5834
+ }
6157
5835
  function formatResult(result, verbose, asOf) {
6158
5836
  const projected = projectClaimCentricRecallEntry(result, {
6159
5837
  asOf
@@ -6171,8 +5849,9 @@ function formatResult(result, verbose, asOf) {
6171
5849
  }
6172
5850
  lines.push(` why=${projected.whySurfaced.summary}`);
6173
5851
  if (verbose) {
5852
+ const crossEncoderFragment = typeof result.scores.crossEncoder === "number" ? ` crossEncoder=${result.scores.crossEncoder.toFixed(2)}` : "";
6174
5853
  lines.push(
6175
- ` vector=${result.scores.vector.toFixed(2)} lexical=${result.scores.lexical.toFixed(2)} recency=${result.scores.recency.toFixed(2)} importance=${result.scores.importance.toFixed(2)} relevance=${result.scores.relevance.toFixed(2)} historicalLineage=${result.scores.historicalLineage.toFixed(2)} claimKeyTrustPenalty=${result.scores.claimKeyTrustPenalty.toFixed(2)} claimKeyRedundancyPenalty=${result.scores.claimKeyRedundancyPenalty.toFixed(2)}`
5854
+ ` vector=${result.scores.vector.toFixed(2)} lexical=${result.scores.lexical.toFixed(2)} recency=${result.scores.recency.toFixed(2)} importance=${result.scores.importance.toFixed(2)} relevance=${result.scores.relevance.toFixed(2)} historicalLineage=${result.scores.historicalLineage.toFixed(2)} claimKeyTrustPenalty=${result.scores.claimKeyTrustPenalty.toFixed(2)} claimKeyRedundancyPenalty=${result.scores.claimKeyRedundancyPenalty.toFixed(2)}${crossEncoderFragment}`
6176
5855
  );
6177
5856
  }
6178
5857
  return lines.join("\n");
@@ -6226,8 +5905,8 @@ import { InvalidArgumentError as InvalidArgumentError5, Option as Option4 } from
6226
5905
  // src/app/scenarios/claim-keys/runtime.ts
6227
5906
  import { randomUUID as randomUUID11 } from "crypto";
6228
5907
  import { mkdir as mkdir2, writeFile } from "fs/promises";
6229
- import path21 from "path";
6230
- import { getModel as getModel2 } from "@mariozechner/pi-ai";
5908
+ import path20 from "path";
5909
+ import { getModel } from "@earendil-works/pi-ai";
6231
5910
 
6232
5911
  // src/adapters/db/surgeon-run-log.ts
6233
5912
  import { randomUUID as randomUUID2 } from "crypto";
@@ -6288,9 +5967,9 @@ async function createSurgeonRun(executor, run) {
6288
5967
  args: [
6289
5968
  id,
6290
5969
  run.passType,
6291
- normalizeOptionalString6(run.project),
5970
+ normalizeOptionalString5(run.project),
6292
5971
  startedAt,
6293
- normalizeOptionalString6(run.model ?? void 0),
5972
+ normalizeOptionalString5(run.model ?? void 0),
6294
5973
  run.dryRun ? 1 : 0,
6295
5974
  JSON.stringify(run.config ?? null)
6296
5975
  ]
@@ -6323,7 +6002,7 @@ async function completeSurgeonRun(executor, runId, result) {
6323
6002
  normalizeInteger(result.actionsSkipped),
6324
6003
  normalizeInteger(result.entriesRetired),
6325
6004
  JSON.stringify(result.summaryJson ?? null),
6326
- normalizeOptionalString6(result.error ?? void 0),
6005
+ normalizeOptionalString5(result.error ?? void 0),
6327
6006
  runId.trim()
6328
6007
  ]
6329
6008
  });
@@ -6460,7 +6139,7 @@ async function logSurgeonProposal(executor, proposal) {
6460
6139
  proposal.eligibleForApply ? 1 : 0,
6461
6140
  reviewStatus,
6462
6141
  normalizeTimestamp(reviewedAt ?? void 0),
6463
- normalizeOptionalString6(reviewReason ?? void 0),
6142
+ normalizeOptionalString5(reviewReason ?? void 0),
6464
6143
  normalizeInteger(appliedActionCount ?? 0),
6465
6144
  normalizeTimestamp(proposal.createdAt) ?? (/* @__PURE__ */ new Date()).toISOString()
6466
6145
  ]
@@ -6824,7 +6503,7 @@ function normalizeEntryIds(entryIds) {
6824
6503
  function normalizeStringArray(values) {
6825
6504
  return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
6826
6505
  }
6827
- function normalizeOptionalString6(value) {
6506
+ function normalizeOptionalString5(value) {
6828
6507
  if (value === void 0) {
6829
6508
  return null;
6830
6509
  }
@@ -6832,7 +6511,7 @@ function normalizeOptionalString6(value) {
6832
6511
  return trimmed.length > 0 ? trimmed : null;
6833
6512
  }
6834
6513
  function normalizeTimestamp(value) {
6835
- return normalizeOptionalString6(value);
6514
+ return normalizeOptionalString5(value);
6836
6515
  }
6837
6516
  function normalizeInteger(value) {
6838
6517
  if (!Number.isFinite(value)) {
@@ -7125,7 +6804,7 @@ async function listRetirementCandidates(executor, query) {
7125
6804
  }
7126
6805
  async function listSupersessionCandidates(executor, query) {
7127
6806
  const scope = normalizeSupersessionScope(query.scope);
7128
- const type = normalizeOptionalString7(query.type);
6807
+ const type = normalizeOptionalString6(query.type);
7129
6808
  const scopes = scope === "all" ? ["claim_key", "subject"] : [scope];
7130
6809
  const clusters = (await Promise.all(
7131
6810
  scopes.map(async (currentScope) => {
@@ -7139,7 +6818,7 @@ async function listSupersessionCandidates(executor, query) {
7139
6818
  return limit === null ? filteredClusters.slice(offset) : filteredClusters.slice(offset, offset + limit);
7140
6819
  }
7141
6820
  async function countSupersessionCandidates(executor, query) {
7142
- const type = normalizeOptionalString7(query.type);
6821
+ const type = normalizeOptionalString6(query.type);
7143
6822
  const skippedEntryIds = typeof query.skipRecentlyEvaluatedDays === "number" && Number.isFinite(query.skipRecentlyEvaluatedDays) && query.skipRecentlyEvaluatedDays > 0 ? await loadRecentlySkippedSupersessionEntryIds(executor, {
7144
6823
  now: query.now ?? /* @__PURE__ */ new Date(),
7145
6824
  skipRecentlyEvaluatedDays: query.skipRecentlyEvaluatedDays
@@ -7352,17 +7031,17 @@ async function inspectSurgeonEntry(executor, entryId) {
7352
7031
  async function listClaimKeyQualityEntries(executor, query) {
7353
7032
  const whereClauses = [query.includeInactive === true ? "1 = 1" : buildActiveEntryClause("e")];
7354
7033
  const args = [];
7355
- const project = normalizeOptionalString7(query.project);
7034
+ const project = normalizeOptionalString6(query.project);
7356
7035
  if (project) {
7357
7036
  whereClauses.push(`(e.project = ? OR ${buildTagContainsClause("e")})`);
7358
7037
  args.push(project, project);
7359
7038
  }
7360
- const type = normalizeOptionalString7(query.type);
7039
+ const type = normalizeOptionalString6(query.type);
7361
7040
  if (type) {
7362
7041
  whereClauses.push("e.type = ?");
7363
7042
  args.push(type);
7364
7043
  }
7365
- const claimKeyPrefix = normalizeOptionalString7(query.claimKeyPrefix);
7044
+ const claimKeyPrefix = normalizeOptionalString6(query.claimKeyPrefix);
7366
7045
  if (claimKeyPrefix) {
7367
7046
  whereClauses.push("e.claim_key LIKE ?");
7368
7047
  args.push(`${claimKeyPrefix}/%`);
@@ -7394,7 +7073,7 @@ function buildCandidateFilter(query) {
7394
7073
  const protectMinImportance = normalizeNonNegativeInteger(query.protectMinImportance);
7395
7074
  const protectRecalledDays = normalizeNonNegativeInteger(query.protectRecalledDays);
7396
7075
  const protectRecalledCutoffIso = new Date(now.getTime() - protectRecalledDays * DAY_MS).toISOString();
7397
- const currentRunId = normalizeOptionalString7(query.runId);
7076
+ const currentRunId = normalizeOptionalString6(query.runId);
7398
7077
  const whereClauses = [buildActiveEntryClause("e"), "e.expiry <> 'core'", "e.importance < ?", "(e.last_recalled_at IS NULL OR e.last_recalled_at < ?)"];
7399
7078
  const args = [protectMinImportance, protectRecalledCutoffIso];
7400
7079
  if (currentRunId) {
@@ -7407,12 +7086,12 @@ function buildCandidateFilter(query) {
7407
7086
  )`);
7408
7087
  args.push(currentRunId, ...SURGEON_RETIREMENT_SAME_RUN_SUPPRESSION_ACTION_TYPES);
7409
7088
  }
7410
- const project = normalizeOptionalString7(query.project);
7089
+ const project = normalizeOptionalString6(query.project);
7411
7090
  if (project) {
7412
7091
  whereClauses.push(buildTagContainsClause("e"));
7413
7092
  args.push(project);
7414
7093
  }
7415
- const type = normalizeOptionalString7(query.type);
7094
+ const type = normalizeOptionalString6(query.type);
7416
7095
  if (type) {
7417
7096
  whereClauses.push("e.type = ?");
7418
7097
  args.push(type);
@@ -7623,7 +7302,7 @@ function normalizeNonNegativeInteger(value) {
7623
7302
  }
7624
7303
  return Math.max(0, Math.floor(value));
7625
7304
  }
7626
- function normalizeOptionalString7(value) {
7305
+ function normalizeOptionalString6(value) {
7627
7306
  if (value === void 0) {
7628
7307
  return null;
7629
7308
  }
@@ -7713,9 +7392,9 @@ function createSurgeonPort(executor) {
7713
7392
 
7714
7393
  // src/app/surgeon/service.ts
7715
7394
  import { randomUUID as randomUUID9 } from "crypto";
7716
- import fs11 from "fs";
7717
- import path16 from "path";
7718
- import { runAgentLoop } from "@mariozechner/pi-agent-core";
7395
+ import fs10 from "fs";
7396
+ import path15 from "path";
7397
+ import { runAgentLoop } from "@earendil-works/pi-agent-core";
7719
7398
 
7720
7399
  // src/core/surgeon/domain/run-presets.ts
7721
7400
  var AUTONOMOUS_SURGEON_SEQUENCE = ["claim_key_quality", "proposal_resolution", "supersession", "retirement"];
@@ -7994,9 +7673,9 @@ var SHADOW_BUCKET_ORDER = [
7994
7673
  async function runClaimKeyQualityPass(options, deps) {
7995
7674
  const selection = {
7996
7675
  includeInactive: options.includeInactive === true,
7997
- project: normalizeOptionalString8(options.project) ?? null,
7998
- type: normalizeOptionalString8(options.type) ?? null,
7999
- claimKeyPrefix: normalizeOptionalString8(options.claimKeyPrefix) ?? null,
7676
+ project: normalizeOptionalString7(options.project) ?? null,
7677
+ type: normalizeOptionalString7(options.type) ?? null,
7678
+ claimKeyPrefix: normalizeOptionalString7(options.claimKeyPrefix) ?? null,
8000
7679
  entryIds: normalizeStringArray3(options.entryIds ?? [])
8001
7680
  };
8002
7681
  const executionStyle = selection.includeInactive || selection.type !== null || selection.claimKeyPrefix !== null || selection.entryIds.length > 0 ? "targeted" : "autonomous";
@@ -9231,7 +8910,7 @@ function cloneEntry(entry) {
9231
8910
  embedding: entry.embedding ? [...entry.embedding] : void 0
9232
8911
  };
9233
8912
  }
9234
- function normalizeOptionalString8(value) {
8913
+ function normalizeOptionalString7(value) {
9235
8914
  const trimmed = value?.trim();
9236
8915
  return trimmed ? trimmed : null;
9237
8916
  }
@@ -10440,8 +10119,8 @@ async function applyProposalToEntries(input, deps) {
10440
10119
  }
10441
10120
 
10442
10121
  // src/app/surgeon/trace-logger.ts
10443
- import fs10 from "fs";
10444
- import path15 from "path";
10122
+ import fs9 from "fs";
10123
+ import path14 from "path";
10445
10124
  var TRACE_MAX_STRING_LENGTH = 320;
10446
10125
  var TRACE_MAX_ARRAY_ITEMS = 12;
10447
10126
  var TRACE_MAX_OBJECT_KEYS = 20;
@@ -10649,8 +10328,8 @@ function appendTrace(tracePath, payload, logger) {
10649
10328
  return;
10650
10329
  }
10651
10330
  try {
10652
- fs10.mkdirSync(path15.dirname(tracePath), { recursive: true });
10653
- fs10.appendFileSync(tracePath, `${JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...payload })}
10331
+ fs9.mkdirSync(path14.dirname(tracePath), { recursive: true });
10332
+ fs9.appendFileSync(tracePath, `${JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...payload })}
10654
10333
  `, "utf8");
10655
10334
  } catch (error) {
10656
10335
  logger.warn(`failed to write trace file ${tracePath}: ${formatError2(error)}`);
@@ -11547,10 +11226,10 @@ function createQueryCandidatesTool(deps) {
11547
11226
  const offset = normalizeOffset2(params.offset);
11548
11227
  const page = await deps.port.listRetirementCandidates({
11549
11228
  scope,
11550
- type: normalizeOptionalString9(params.type),
11229
+ type: normalizeOptionalString8(params.type),
11551
11230
  importanceMax: params.importance_max,
11552
11231
  minAgeDays: params.min_age_days,
11553
- project: normalizeOptionalString9(params.project) ?? deps.project,
11232
+ project: normalizeOptionalString8(params.project) ?? deps.project,
11554
11233
  limit,
11555
11234
  offset,
11556
11235
  protectRecalledDays: deps.protection.protectRecalledDays,
@@ -11613,7 +11292,7 @@ function normalizeOffset2(value) {
11613
11292
  function normalizeScope2(value) {
11614
11293
  return value === "all" ? "all" : "actionable";
11615
11294
  }
11616
- function normalizeOptionalString9(value) {
11295
+ function normalizeOptionalString8(value) {
11617
11296
  const normalized = value?.trim();
11618
11297
  return normalized ? normalized : void 0;
11619
11298
  }
@@ -11639,7 +11318,7 @@ function createSimulateRecallTool(deps) {
11639
11318
  if (!deps.recallPorts) {
11640
11319
  throw new Error("Recall simulation is unavailable because no embedding-enabled recall ports are configured.");
11641
11320
  }
11642
- const excludeEntryId = normalizeOptionalString10(params.exclude_entry_id);
11321
+ const excludeEntryId = normalizeOptionalString9(params.exclude_entry_id);
11643
11322
  const results = await recall(
11644
11323
  {
11645
11324
  text: params.query.trim(),
@@ -11673,17 +11352,17 @@ function createSimulationRecallPorts(inner, excludeEntryId) {
11673
11352
  }
11674
11353
  return results.filter((result) => result.entry.id !== excludeEntryId);
11675
11354
  },
11676
- async fetchPredecessors(params) {
11677
- if (!inner.fetchPredecessors) {
11355
+ async expandNeighborhood(request) {
11356
+ if (!inner.expandNeighborhood) {
11678
11357
  return [];
11679
11358
  }
11680
- const activeEntryIds = excludeEntryId ? params.activeEntryIds.filter((id) => id !== excludeEntryId) : params.activeEntryIds;
11681
- if (activeEntryIds.length === 0) {
11359
+ const seedIds = excludeEntryId ? request.seedIds.filter((id) => id !== excludeEntryId) : request.seedIds;
11360
+ if (seedIds.length === 0) {
11682
11361
  return [];
11683
11362
  }
11684
- const results = await inner.fetchPredecessors({
11685
- ...params,
11686
- activeEntryIds
11363
+ const results = await inner.expandNeighborhood({
11364
+ ...request,
11365
+ seedIds
11687
11366
  });
11688
11367
  if (!excludeEntryId) {
11689
11368
  return results;
@@ -11704,7 +11383,7 @@ function normalizeLimit3(value) {
11704
11383
  }
11705
11384
  return Math.floor(value);
11706
11385
  }
11707
- function normalizeOptionalString10(value) {
11386
+ function normalizeOptionalString9(value) {
11708
11387
  const normalized = value?.trim();
11709
11388
  return normalized ? normalized : void 0;
11710
11389
  }
@@ -11984,7 +11663,7 @@ function createQuerySupersessionCandidatesTool(deps) {
11984
11663
  const scope = normalizeScope3(params.scope);
11985
11664
  const limit = normalizeLimit4(params.limit);
11986
11665
  const offset = normalizeOffset3(params.offset);
11987
- const type = normalizeOptionalString11(params.type);
11666
+ const type = normalizeOptionalString10(params.type);
11988
11667
  const progress = deps.completionGuards?.supersession.snapshot();
11989
11668
  if ((scope === "subject" || scope === "all") && shouldBlockLowerConfidenceScope(progress)) {
11990
11669
  return toolResult({
@@ -12092,7 +11771,7 @@ function normalizeScope3(value) {
12092
11771
  }
12093
11772
  return "claim_key";
12094
11773
  }
12095
- function normalizeOptionalString11(value) {
11774
+ function normalizeOptionalString10(value) {
12096
11775
  const normalized = value?.trim();
12097
11776
  return normalized ? normalized : void 0;
12098
11777
  }
@@ -13199,8 +12878,8 @@ function resolveTracePath(tracePath, passType, runId) {
13199
12878
  return void 0;
13200
12879
  }
13201
12880
  try {
13202
- if (fs11.statSync(tracePath).isDirectory()) {
13203
- return path16.join(tracePath, `surgeon-${passType}-${runId}.jsonl`);
12881
+ if (fs10.statSync(tracePath).isDirectory()) {
12882
+ return path15.join(tracePath, `surgeon-${passType}-${runId}.jsonl`);
13204
12883
  }
13205
12884
  } catch {
13206
12885
  return tracePath;
@@ -14102,7 +13781,7 @@ function formatValue(value) {
14102
13781
  }
14103
13782
 
14104
13783
  // src/app/scenarios/claim-keys/deterministic-fixtures.ts
14105
- import { createHash as createHash3 } from "crypto";
13784
+ import { createHash as createHash2 } from "crypto";
14106
13785
  var DEFAULT_CONTEXT_WINDOW_TOKENS2 = 16e3;
14107
13786
  var DEFAULT_MAX_OUTPUT_TOKENS = 4e3;
14108
13787
  var EMBEDDING_DIMENSIONS = 1024;
@@ -14160,7 +13839,7 @@ function hashToVector(text2, dimensions) {
14160
13839
  const vector = [];
14161
13840
  let counter = 0;
14162
13841
  while (vector.length < dimensions) {
14163
- const block = createHash3("sha256").update(text2).update(String(counter)).digest();
13842
+ const block = createHash2("sha256").update(text2).update(String(counter)).digest();
14164
13843
  for (let offset = 0; offset + 4 <= block.length && vector.length < dimensions; offset += 4) {
14165
13844
  vector.push(block.readInt32LE(offset) / 2147483647);
14166
13845
  }
@@ -14202,7 +13881,7 @@ function isFixtureError(value) {
14202
13881
 
14203
13882
  // src/app/scenarios/claim-keys/fixture-loader.ts
14204
13883
  import { readFile } from "fs/promises";
14205
- import path18 from "path";
13884
+ import path17 from "path";
14206
13885
 
14207
13886
  // src/app/scenarios/claim-keys/validation/shared.ts
14208
13887
  var SUPPORTED_PROPOSAL_SCOPES = ["single_entry", "cluster"];
@@ -14532,12 +14211,12 @@ function readRequiredTrue(value, label, filePath) {
14532
14211
 
14533
14212
  // src/app/scenarios/claim-keys/validation/scenario-root.ts
14534
14213
  import { existsSync } from "fs";
14535
- import path17 from "path";
14214
+ import path16 from "path";
14536
14215
  import { fileURLToPath as fileURLToPath2 } from "url";
14537
14216
  var SCENARIO_ROOT_SEGMENTS = ["tests", "scenarios", "claim-keys"];
14538
14217
  function getDefaultClaimKeyScenarioRoot(options = {}) {
14539
- const moduleDirectory = path17.dirname(fileURLToPath2(options.moduleUrl ?? import.meta.url));
14540
- const startDirectories = Array.from(/* @__PURE__ */ new Set([path17.resolve(options.cwd ?? process.cwd()), moduleDirectory]));
14218
+ const moduleDirectory = path16.dirname(fileURLToPath2(options.moduleUrl ?? import.meta.url));
14219
+ const startDirectories = Array.from(/* @__PURE__ */ new Set([path16.resolve(options.cwd ?? process.cwd()), moduleDirectory]));
14541
14220
  for (const startDirectory of startDirectories) {
14542
14221
  const discovered = findScenarioRootFrom(startDirectory);
14543
14222
  if (discovered) {
@@ -14559,24 +14238,24 @@ function readOptionalRelativeFixturePath(value, label, filePath, rootDir) {
14559
14238
  return readRelativeFixturePath(value, label, filePath, rootDir);
14560
14239
  }
14561
14240
  function normalizeFixturePath(relativePath, rootDir, filePath, label) {
14562
- if (path17.isAbsolute(relativePath)) {
14241
+ if (path16.isAbsolute(relativePath)) {
14563
14242
  throw new Error(`Invalid scenario ${filePath}: ${label} must be relative to the scenario root.`);
14564
14243
  }
14565
- const resolved = path17.resolve(rootDir, relativePath);
14566
- const relative = path17.relative(rootDir, resolved);
14567
- if (relative.startsWith("..") || path17.isAbsolute(relative)) {
14244
+ const resolved = path16.resolve(rootDir, relativePath);
14245
+ const relative = path16.relative(rootDir, resolved);
14246
+ if (relative.startsWith("..") || path16.isAbsolute(relative)) {
14568
14247
  throw new Error(`Invalid scenario ${filePath}: ${label} must stay inside the scenario root.`);
14569
14248
  }
14570
- return relative.split(path17.sep).join("/");
14249
+ return relative.split(path16.sep).join("/");
14571
14250
  }
14572
14251
  function findScenarioRootFrom(startDirectory) {
14573
- let currentDirectory = path17.resolve(startDirectory);
14252
+ let currentDirectory = path16.resolve(startDirectory);
14574
14253
  while (true) {
14575
- const candidate = path17.join(currentDirectory, ...SCENARIO_ROOT_SEGMENTS);
14254
+ const candidate = path16.join(currentDirectory, ...SCENARIO_ROOT_SEGMENTS);
14576
14255
  if (existsSync(candidate)) {
14577
14256
  return candidate;
14578
14257
  }
14579
- const parentDirectory = path17.dirname(currentDirectory);
14258
+ const parentDirectory = path16.dirname(currentDirectory);
14580
14259
  if (parentDirectory === currentDirectory) {
14581
14260
  return void 0;
14582
14261
  }
@@ -14919,7 +14598,7 @@ async function loadSeedFixtureEntries(rootDir, relativePath) {
14919
14598
  if (!relativePath) {
14920
14599
  return null;
14921
14600
  }
14922
- const parsed = await readJsonFile(path18.join(rootDir, relativePath));
14601
+ const parsed = await readJsonFile(path17.join(rootDir, relativePath));
14923
14602
  const seedEntries = readSeedEntries(parsed, relativePath);
14924
14603
  if (!seedEntries) {
14925
14604
  throw new Error(`Seed fixture ${relativePath} must contain an array.`);
@@ -14982,7 +14661,7 @@ async function readArrayFixture(rootDir, relativePath) {
14982
14661
  if (!relativePath) {
14983
14662
  return null;
14984
14663
  }
14985
- const parsed = await readJsonFile(path18.join(rootDir, relativePath));
14664
+ const parsed = await readJsonFile(path17.join(rootDir, relativePath));
14986
14665
  if (!Array.isArray(parsed)) {
14987
14666
  throw new Error(`Fixture file ${relativePath} must contain a JSON array.`);
14988
14667
  }
@@ -15036,7 +14715,7 @@ function readExtractionImportance(value, label, filePath) {
15036
14715
 
15037
14716
  // src/app/scenarios/claim-keys/load-scenarios.ts
15038
14717
  import { readdir, readFile as readFile2 } from "fs/promises";
15039
- import path19 from "path";
14718
+ import path18 from "path";
15040
14719
 
15041
14720
  // src/app/scenarios/claim-keys/validation/expectations.ts
15042
14721
  var EXPECTATION_KEYS = /* @__PURE__ */ new Set(["warnings", "rows", "rowCount", "proposals", "storeResult", "surgeonSummary"]);
@@ -15298,13 +14977,13 @@ function validateClaimKeyScenario(input, filePath, rootDir = getDefaultClaimKeyS
15298
14977
  async function discoverScenarioFiles(rootDir) {
15299
14978
  const files = [];
15300
14979
  for (const kind of SUPPORTED_KINDS2) {
15301
- const directory = path19.join(rootDir, kind);
14980
+ const directory = path18.join(rootDir, kind);
15302
14981
  const entries = await readdir(directory, { withFileTypes: true });
15303
14982
  for (const entry of entries) {
15304
14983
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
15305
14984
  continue;
15306
14985
  }
15307
- files.push(path19.join(directory, entry.name));
14986
+ files.push(path18.join(directory, entry.name));
15308
14987
  }
15309
14988
  }
15310
14989
  return files.sort();
@@ -15322,11 +15001,11 @@ async function readScenarioJsonFile(filePath) {
15322
15001
 
15323
15002
  // src/app/scenarios/claim-keys/sandbox.ts
15324
15003
  import { mkdir, rm } from "fs/promises";
15325
- import path20 from "path";
15004
+ import path19 from "path";
15326
15005
  var SANDBOX_DB_FILENAME = "knowledge.db";
15327
15006
  async function createClaimKeyScenarioSandbox(root) {
15328
- const resolvedRoot = path20.resolve(root);
15329
- const dbPath = path20.join(resolvedRoot, SANDBOX_DB_FILENAME);
15007
+ const resolvedRoot = path19.resolve(root);
15008
+ const dbPath = path19.join(resolvedRoot, SANDBOX_DB_FILENAME);
15330
15009
  await mkdir(resolvedRoot, { recursive: true });
15331
15010
  await removeDatabaseFiles(dbPath);
15332
15011
  const database = await createDatabase(dbPath);
@@ -15351,7 +15030,7 @@ async function removeDatabaseFiles(dbPath) {
15351
15030
  import { randomUUID as randomUUID10 } from "crypto";
15352
15031
  var DEFAULT_SCENARIO_CREATED_AT = "2026-04-01T10:00:00.000Z";
15353
15032
  function buildClaimKeyScenarioSeedEntry(seedEntry) {
15354
- const seedClaimKey = normalizeOptionalString12(seedEntry.claim_key);
15033
+ const seedClaimKey = normalizeOptionalString11(seedEntry.claim_key);
15355
15034
  const preserveLegacyStoredClaimKey = shouldPreserveLegacyStoredClaimKey(seedClaimKey);
15356
15035
  const validatedInput = validateSeedStoreInput(seedEntry, preserveLegacyStoredClaimKey);
15357
15036
  const lifecycle = preserveLegacyStoredClaimKey ? resolveLegacySeedClaimKeyLifecycle(seedEntry) : resolveSeedClaimKeyLifecycle(seedEntry, validatedInput);
@@ -15373,11 +15052,11 @@ function buildClaimKeyScenarioSeedEntry(seedEntry) {
15373
15052
  quality_score: 0.5,
15374
15053
  recall_count: 0,
15375
15054
  last_recalled_at: void 0,
15376
- superseded_by: normalizeOptionalString12(seedEntry.superseded_by),
15055
+ superseded_by: normalizeOptionalString11(seedEntry.superseded_by),
15377
15056
  valid_from: validatedInput.valid_from,
15378
15057
  valid_to: validatedInput.valid_to,
15379
15058
  claim_key: preserveLegacyStoredClaimKey ? seedClaimKey : lifecycle?.claim_key,
15380
- claim_key_raw: preserveLegacyStoredClaimKey ? normalizeOptionalString12(seedEntry.claim_key_raw) : lifecycle?.claim_key_raw,
15059
+ claim_key_raw: preserveLegacyStoredClaimKey ? normalizeOptionalString11(seedEntry.claim_key_raw) : lifecycle?.claim_key_raw,
15381
15060
  claim_key_status: lifecycle?.claim_key_status,
15382
15061
  claim_key_source: lifecycle?.claim_key_source,
15383
15062
  claim_key_confidence: lifecycle?.claim_key_confidence,
@@ -15392,8 +15071,8 @@ function buildClaimKeyScenarioSeedEntry(seedEntry) {
15392
15071
  user_id: validatedInput.user_id,
15393
15072
  project: validatedInput.project,
15394
15073
  retired: seedEntry.retired ?? false,
15395
- retired_at: normalizeOptionalString12(seedEntry.retired_at),
15396
- retired_reason: normalizeOptionalString12(seedEntry.retired_reason),
15074
+ retired_at: normalizeOptionalString11(seedEntry.retired_at),
15075
+ retired_reason: normalizeOptionalString11(seedEntry.retired_reason),
15397
15076
  created_at: createdAt,
15398
15077
  updated_at: updatedAt
15399
15078
  };
@@ -15479,14 +15158,14 @@ function resolveLegacySeedClaimKeyLifecycle(seedEntry) {
15479
15158
  }
15480
15159
  return {
15481
15160
  claim_key: seedEntry.claim_key.trim(),
15482
- claim_key_raw: normalizeOptionalString12(seedEntry.claim_key_raw),
15161
+ claim_key_raw: normalizeOptionalString11(seedEntry.claim_key_raw),
15483
15162
  claim_key_status: seedEntry.claim_key_status,
15484
15163
  claim_key_source: seedEntry.claim_key_source,
15485
15164
  claim_key_confidence: seedEntry.claim_key_confidence,
15486
15165
  claim_key_rationale: seedEntry.claim_key_rationale.trim(),
15487
- claim_support_source_kind: normalizeOptionalString12(seedEntry.claim_support_source_kind),
15488
- claim_support_locator: normalizeOptionalString12(seedEntry.claim_support_locator),
15489
- claim_support_observed_at: normalizeOptionalString12(seedEntry.claim_support_observed_at),
15166
+ claim_support_source_kind: normalizeOptionalString11(seedEntry.claim_support_source_kind),
15167
+ claim_support_locator: normalizeOptionalString11(seedEntry.claim_support_locator),
15168
+ claim_support_observed_at: normalizeOptionalString11(seedEntry.claim_support_observed_at),
15490
15169
  claim_support_mode: seedEntry.claim_support_mode
15491
15170
  };
15492
15171
  }
@@ -15497,7 +15176,7 @@ function shouldPreserveLegacyStoredClaimKey(claimKey) {
15497
15176
  const normalized = normalizeClaimKey(claimKey);
15498
15177
  return !normalized.ok || normalized.value.claimKey !== claimKey;
15499
15178
  }
15500
- function normalizeOptionalString12(value) {
15179
+ function normalizeOptionalString11(value) {
15501
15180
  const normalized = value?.trim();
15502
15181
  return normalized && normalized.length > 0 ? normalized : void 0;
15503
15182
  }
@@ -15517,7 +15196,7 @@ async function listClaimKeyScenariosRuntime(options = {}) {
15517
15196
  }
15518
15197
  async function runClaimKeyScenariosRuntime(options = {}) {
15519
15198
  const runId = buildRunId();
15520
- const artifactRoot = path21.resolve(DEFAULT_ARTIFACT_ROOT, runId);
15199
+ const artifactRoot = path20.resolve(DEFAULT_ARTIFACT_ROOT, runId);
15521
15200
  await mkdir2(artifactRoot, { recursive: true });
15522
15201
  let scenarios;
15523
15202
  try {
@@ -15569,11 +15248,11 @@ function filterClaimKeyScenarios(scenarios, options) {
15569
15248
  }
15570
15249
  async function runOneClaimKeyScenario(scenario, options) {
15571
15250
  const startedAt = Date.now();
15572
- const scenarioArtifactRoot = path21.join(options.artifactRoot, scenario.id);
15573
- const sandboxRoot = path21.join(scenarioArtifactRoot, "sandbox");
15251
+ const scenarioArtifactRoot = path20.join(options.artifactRoot, scenario.id);
15252
+ const sandboxRoot = path20.join(scenarioArtifactRoot, "sandbox");
15574
15253
  const warnings = [];
15575
15254
  await mkdir2(scenarioArtifactRoot, { recursive: true });
15576
- await writeJson(path21.join(scenarioArtifactRoot, "scenario.json"), scenario);
15255
+ await writeJson(path20.join(scenarioArtifactRoot, "scenario.json"), scenario);
15577
15256
  let actual = {
15578
15257
  warnings: [],
15579
15258
  rows: [],
@@ -15686,7 +15365,7 @@ async function runIngestScenario(scenario, database, warnings, rootDir) {
15686
15365
  throw new Error(`Scenario ${scenario.id} is missing extraction fixture responses.`);
15687
15366
  }
15688
15367
  const result = await ingestPath(
15689
- path21.join(rootDir, scenario.input.transcriptFile),
15368
+ path20.join(rootDir, scenario.input.transcriptFile),
15690
15369
  {
15691
15370
  files: localTranscriptFiles,
15692
15371
  transcript: openClawTranscriptParser,
@@ -15758,7 +15437,7 @@ async function runSurgeonScenario(scenario, database, _warnings, rootDir) {
15758
15437
  {
15759
15438
  port: createSurgeonPort(database),
15760
15439
  config: null,
15761
- model: getModel2("openai", "gpt-5.4-mini"),
15440
+ model: getModel("openai", "gpt-5.4-mini"),
15762
15441
  now: () => SCENARIO_NOW,
15763
15442
  ...claimExtractionResponses ? {
15764
15443
  createClaimExtractionLlm: () => createFixtureLlm(claimExtractionResponses)
@@ -15828,20 +15507,20 @@ async function loadLatestSurgeonProposals(database, runId) {
15828
15507
  }));
15829
15508
  }
15830
15509
  async function writeScenarioArtifacts(scenarioArtifactRoot, actual, assertionResults, diffSummary) {
15831
- await writeJson(path21.join(scenarioArtifactRoot, "actual.json"), actual);
15832
- await writeJson(path21.join(scenarioArtifactRoot, "diff.json"), {
15510
+ await writeJson(path20.join(scenarioArtifactRoot, "actual.json"), actual);
15511
+ await writeJson(path20.join(scenarioArtifactRoot, "diff.json"), {
15833
15512
  assertions: assertionResults,
15834
15513
  diffSummary
15835
15514
  });
15836
- await writeJson(path21.join(scenarioArtifactRoot, "warnings.json"), actual.warnings);
15515
+ await writeJson(path20.join(scenarioArtifactRoot, "warnings.json"), actual.warnings);
15837
15516
  if (actual.storeResult) {
15838
- await writeJson(path21.join(scenarioArtifactRoot, "store-result.json"), actual.storeResult);
15517
+ await writeJson(path20.join(scenarioArtifactRoot, "store-result.json"), actual.storeResult);
15839
15518
  }
15840
15519
  if (actual.surgeonSummary) {
15841
- await writeJson(path21.join(scenarioArtifactRoot, "surgeon-summary.json"), actual.surgeonSummary);
15520
+ await writeJson(path20.join(scenarioArtifactRoot, "surgeon-summary.json"), actual.surgeonSummary);
15842
15521
  }
15843
15522
  if (actual.proposals.length > 0) {
15844
- await writeJson(path21.join(scenarioArtifactRoot, "proposals.json"), actual.proposals);
15523
+ await writeJson(path20.join(scenarioArtifactRoot, "proposals.json"), actual.proposals);
15845
15524
  }
15846
15525
  }
15847
15526
  async function writeJson(filePath, value) {
@@ -15973,12 +15652,12 @@ import { InvalidArgumentError as InvalidArgumentError6, Option as Option5 } from
15973
15652
 
15974
15653
  // src/app/surgeon/runtime.ts
15975
15654
  import { copyFile, mkdir as mkdir3 } from "fs/promises";
15976
- import path22 from "path";
15655
+ import path21 from "path";
15977
15656
  import { fileURLToPath as fileURLToPath3 } from "url";
15978
- import { getModel as getModel3 } from "@mariozechner/pi-ai";
15657
+ import { getModel as getModel2 } from "@earendil-works/pi-ai";
15979
15658
  var DEFAULT_SURGEON_PROVIDER = "openai";
15980
15659
  var DEFAULT_SURGEON_MODEL = "gpt-5.4-mini";
15981
- var getModelWithStrings2 = getModel3;
15660
+ var getModelWithStrings = getModel2;
15982
15661
  async function runSurgeonRuntime(input) {
15983
15662
  const runtime = loadRuntimeConfig(input);
15984
15663
  const database = await createDatabase(runtime.dbPath);
@@ -15988,7 +15667,7 @@ async function runSurgeonRuntime(input) {
15988
15667
  const modelSelection = resolveSurgeonModel(runtime.config, input);
15989
15668
  const claimExtractionConfig = selection.includesClaimKeyQuality ? resolveClaimExtractionConfig(runtime.config) : { enabled: false };
15990
15669
  const claimModelSelection = claimExtractionConfig.enabled ? resolveModel(runtime.config, "claim") : null;
15991
- const model = getModelWithStrings2(modelSelection.provider, modelSelection.modelId);
15670
+ const model = getModelWithStrings(modelSelection.provider, modelSelection.modelId);
15992
15671
  const credentials = resolveLlmCredentials(runtime.config, modelSelection.provider, input.env ?? process.env);
15993
15672
  const claimCredentials = claimModelSelection && claimModelSelection.provider === modelSelection.provider ? credentials : claimModelSelection ? resolveLlmCredentials(runtime.config, claimModelSelection.provider, input.env ?? process.env) : null;
15994
15673
  let recallPorts;
@@ -16114,7 +15793,7 @@ async function reviewSurgeonProposalRuntime(input) {
16114
15793
  if (proposal.reviewStatus !== "open") {
16115
15794
  throw new Error(`Proposal ${proposal.id} was already reviewed as ${proposal.reviewStatus}.`);
16116
15795
  }
16117
- const reviewReason = normalizeOptionalString13(input.reason);
15796
+ const reviewReason = normalizeOptionalString12(input.reason);
16118
15797
  if (!reviewReason) {
16119
15798
  throw new Error("Review reason is required.");
16120
15799
  }
@@ -16173,8 +15852,8 @@ async function reviewSurgeonProposalRuntime(input) {
16173
15852
  }
16174
15853
  }
16175
15854
  function loadRuntimeConfig(input) {
16176
- const dbPathOverride = normalizeOptionalString13(input.dbPath) ?? normalizeOptionalString13(input.env?.AGENR_DB_PATH);
16177
- const configPathOverride = normalizeOptionalString13(input.env?.AGENR_CONFIG_PATH);
15855
+ const dbPathOverride = normalizeOptionalString12(input.dbPath) ?? normalizeOptionalString12(input.env?.AGENR_DB_PATH);
15856
+ const configPathOverride = normalizeOptionalString12(input.env?.AGENR_CONFIG_PATH);
16178
15857
  const config = readConfig({
16179
15858
  configPath: configPathOverride,
16180
15859
  dbPath: dbPathOverride
@@ -16187,8 +15866,8 @@ function loadRuntimeConfig(input) {
16187
15866
  function resolveSurgeonModel(config, input) {
16188
15867
  const surgeonModel = config.surgeon?.model;
16189
15868
  return {
16190
- provider: normalizeOptionalString13(input.provider) ?? normalizeOptionalString13(surgeonModel?.provider) ?? normalizeOptionalString13(config.provider) ?? DEFAULT_SURGEON_PROVIDER,
16191
- modelId: normalizeOptionalString13(input.model) ?? normalizeOptionalString13(surgeonModel?.model) ?? normalizeOptionalString13(config.model) ?? DEFAULT_SURGEON_MODEL
15869
+ provider: normalizeOptionalString12(input.provider) ?? normalizeOptionalString12(surgeonModel?.provider) ?? normalizeOptionalString12(config.provider) ?? DEFAULT_SURGEON_PROVIDER,
15870
+ modelId: normalizeOptionalString12(input.model) ?? normalizeOptionalString12(surgeonModel?.model) ?? normalizeOptionalString12(config.model) ?? DEFAULT_SURGEON_MODEL
16192
15871
  };
16193
15872
  }
16194
15873
  function resolveRuntimeSelection(input) {
@@ -16218,7 +15897,7 @@ async function backupDatabaseFile(dbPath) {
16218
15897
  }
16219
15898
  const sourcePath = resolveFilesystemPath(dbPath);
16220
15899
  const backupPath = `${sourcePath}.surgeon-backup-${(/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-").replaceAll(".", "-")}`;
16221
- await mkdir3(path22.dirname(backupPath), { recursive: true });
15900
+ await mkdir3(path21.dirname(backupPath), { recursive: true });
16222
15901
  await copyFile(sourcePath, backupPath);
16223
15902
  await copySidecarIfPresent(`${sourcePath}-wal`, `${backupPath}-wal`);
16224
15903
  await copySidecarIfPresent(`${sourcePath}-shm`, `${backupPath}-shm`);
@@ -16236,18 +15915,18 @@ async function copySidecarIfPresent(sourcePath, targetPath) {
16236
15915
  }
16237
15916
  function resolveFilesystemPath(value) {
16238
15917
  if (!value.startsWith("file:")) {
16239
- return path22.resolve(value);
15918
+ return path21.resolve(value);
16240
15919
  }
16241
15920
  try {
16242
15921
  return fileURLToPath3(value);
16243
15922
  } catch {
16244
- return path22.resolve(value.slice("file:".length));
15923
+ return path21.resolve(value.slice("file:".length));
16245
15924
  }
16246
15925
  }
16247
15926
  function isMissingFileError2(error) {
16248
15927
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
16249
15928
  }
16250
- function normalizeOptionalString13(value) {
15929
+ function normalizeOptionalString12(value) {
16251
15930
  const normalized = value?.trim();
16252
15931
  return normalized && normalized.length > 0 ? normalized : void 0;
16253
15932
  }
@@ -16330,9 +16009,9 @@ function registerSurgeonCommand(program2) {
16330
16009
  try {
16331
16010
  const backlog = await loadSurgeonBacklogRuntime({
16332
16011
  state: options.state,
16333
- issueKind: normalizeOptionalString3(options.issueKind),
16012
+ issueKind: normalizeOptionalString2(options.issueKind),
16334
16013
  eligibleOnly: options.eligibleOnly === true,
16335
- entryId: normalizeOptionalString3(options.entryId),
16014
+ entryId: normalizeOptionalString2(options.entryId),
16336
16015
  limit: options.limit,
16337
16016
  offset: options.offset,
16338
16017
  env: process.env
@@ -16341,8 +16020,8 @@ function registerSurgeonCommand(program2) {
16341
16020
  renderBacklog(backlog, {
16342
16021
  state: options.state ?? "open",
16343
16022
  eligibleOnly: options.eligibleOnly === true,
16344
- issueKind: normalizeOptionalString3(options.issueKind),
16345
- entryId: normalizeOptionalString3(options.entryId),
16023
+ issueKind: normalizeOptionalString2(options.issueKind),
16024
+ entryId: normalizeOptionalString2(options.entryId),
16346
16025
  limit: options.limit ?? 20,
16347
16026
  offset: options.offset ?? 0
16348
16027
  })
@@ -16381,7 +16060,7 @@ function registerSurgeonCommand(program2) {
16381
16060
  });
16382
16061
  surgeonCommand.command("review <proposalId>").description("Apply or reject one open proposal").addOption(new Option5("--decision <decision>", "Review decision").choices(["apply", "reject"]).makeOptionMandatory(true)).option("--reason <text>", "Why this review decision was taken").action(async (proposalId, options) => {
16383
16062
  try {
16384
- const reason = normalizeOptionalString3(options.reason);
16063
+ const reason = normalizeOptionalString2(options.reason);
16385
16064
  if (!reason) {
16386
16065
  throw new InvalidArgumentError6("Review reason is required.");
16387
16066
  }
@@ -16416,10 +16095,10 @@ function normalizeSurgeonRunCommand(options) {
16416
16095
  contextLimit: options.contextLimit,
16417
16096
  skipEvaluatedDays: options.skipEvaluatedDays,
16418
16097
  apply: options.apply === true,
16419
- model: normalizeOptionalString3(options.model),
16420
- provider: normalizeOptionalString3(options.provider),
16098
+ model: normalizeOptionalString2(options.model),
16099
+ provider: normalizeOptionalString2(options.provider),
16421
16100
  verbose: options.verbose === true,
16422
- tracePath: normalizeOptionalString3(options.trace),
16101
+ tracePath: normalizeOptionalString2(options.trace),
16423
16102
  json: options.json === true
16424
16103
  };
16425
16104
  }
@@ -17137,17 +16816,17 @@ function formatPassContextSummary(event) {
17137
16816
  // src/cli/commands/trace.ts
17138
16817
  import { Option as Option6 } from "commander";
17139
16818
 
17140
- // src/app/openclaw/inspect.ts
17141
- async function loadOpenClawEntryTraceRuntime(input) {
16819
+ // src/app/memory/inspect.ts
16820
+ async function loadEntryTraceRuntime(input) {
17142
16821
  const selector = normalizeTraceSelector(input);
17143
- const configPathOverride = normalizeOptionalString14(input.env?.AGENR_CONFIG_PATH);
16822
+ const configPathOverride = normalizeOptionalString13(input.env?.AGENR_CONFIG_PATH);
17144
16823
  const config = readConfig({
17145
16824
  configPath: configPathOverride,
17146
- dbPath: normalizeOptionalString14(input.dbPath) ?? normalizeOptionalString14(input.env?.AGENR_DB_PATH)
16825
+ dbPath: normalizeOptionalString13(input.dbPath) ?? normalizeOptionalString13(input.env?.AGENR_DB_PATH)
17147
16826
  });
17148
- const dbPath = normalizeOptionalString14(input.dbPath) ?? normalizeOptionalString14(input.env?.AGENR_DB_PATH) ?? resolveDbPath(config);
16827
+ const dbPath = normalizeOptionalString13(input.dbPath) ?? normalizeOptionalString13(input.env?.AGENR_DB_PATH) ?? resolveDbPath(config);
17149
16828
  const database = await createDatabase(dbPath);
17150
- const repository = createOpenClawRepository(database);
16829
+ const repository = createMemoryRepository(database);
17151
16830
  try {
17152
16831
  const entryId = await resolveTraceEntryId(repository, selector);
17153
16832
  const trace = await repository.getEntryTrace(entryId);
@@ -17177,8 +16856,8 @@ async function resolveTraceEntryId(repository, selector) {
17177
16856
  return entry.id;
17178
16857
  }
17179
16858
  function normalizeTraceSelector(selector) {
17180
- const id = normalizeOptionalString14(selector.id);
17181
- const subject = normalizeOptionalString14(selector.subject);
16859
+ const id = normalizeOptionalString13(selector.id);
16860
+ const subject = normalizeOptionalString13(selector.subject);
17182
16861
  const last = selector.last === true;
17183
16862
  const count = (id ? 1 : 0) + (subject ? 1 : 0) + (last ? 1 : 0);
17184
16863
  if (count !== 1) {
@@ -17190,7 +16869,7 @@ function normalizeTraceSelector(selector) {
17190
16869
  last
17191
16870
  };
17192
16871
  }
17193
- function normalizeOptionalString14(value) {
16872
+ function normalizeOptionalString13(value) {
17194
16873
  const normalized = value?.trim();
17195
16874
  return normalized && normalized.length > 0 ? normalized : void 0;
17196
16875
  }
@@ -17199,7 +16878,7 @@ function normalizeOptionalString14(value) {
17199
16878
  function registerTraceCommand(program2) {
17200
16879
  program2.command("trace").description("Inspect one entry's provenance and claim-family lineage").addOption(new Option6("--id <id>", "Entry id to inspect")).addOption(new Option6("--subject <text>", "Subject text to resolve when the id is unknown")).option("--last", "Inspect the most recently created entry").option("--json", "Emit structured JSON output").action(async (options) => {
17201
16880
  try {
17202
- const trace = await loadOpenClawEntryTraceRuntime({
16881
+ const trace = await loadEntryTraceRuntime({
17203
16882
  id: options.id,
17204
16883
  subject: options.subject,
17205
16884
  last: options.last === true,