memorix 1.4.1 → 1.4.2

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/index.js CHANGED
@@ -685,10 +685,10 @@ function createColors(useColor = isColorSupported) {
685
685
  function getColor(color, fallback = "reset") {
686
686
  return colors[color] || colors[fallback];
687
687
  }
688
- function stripAnsi(text) {
689
- return text.replace(new RegExp(ansiRegex, "g"), "");
688
+ function stripAnsi(text2) {
689
+ return text2.replace(new RegExp(ansiRegex, "g"), "");
690
690
  }
691
- function box(text, _opts = {}) {
691
+ function box(text2, _opts = {}) {
692
692
  const opts = {
693
693
  ..._opts,
694
694
  style: {
@@ -696,7 +696,7 @@ function box(text, _opts = {}) {
696
696
  ..._opts.style
697
697
  }
698
698
  };
699
- const textLines = text.split("\n");
699
+ const textLines = text2.split("\n");
700
700
  const boxLines = [];
701
701
  const _color = getColor(opts.style.borderColor);
702
702
  const borderStyle = {
@@ -3221,7 +3221,7 @@ ${import_picocolors.default.gray(m3)} ${s3}
3221
3221
 
3222
3222
  // src/cli/version.ts
3223
3223
  function getCliVersion() {
3224
- return true ? "1.4.1" : pkg.version;
3224
+ return true ? "1.4.2" : pkg.version;
3225
3225
  }
3226
3226
  var init_version = __esm({
3227
3227
  "src/cli/version.ts"() {
@@ -6944,14 +6944,14 @@ function normalizeToken(prop, token, withCache = true) {
6944
6944
  }
6945
6945
  return token;
6946
6946
  }
6947
- function trim(text) {
6948
- while (text[text.length - 1] === "") {
6949
- text.pop();
6947
+ function trim(text2) {
6948
+ while (text2[text2.length - 1] === "") {
6949
+ text2.pop();
6950
6950
  }
6951
- while (text[0] === "") {
6952
- text.shift();
6951
+ while (text2[0] === "") {
6952
+ text2.shift();
6953
6953
  }
6954
- return text;
6954
+ return text2;
6955
6955
  }
6956
6956
  function tokenize(input, language, prop, withCache = true) {
6957
6957
  if (language && language !== this.language) {
@@ -9363,7 +9363,7 @@ function closeAllDatabases() {
9363
9363
  _dbCache.delete(key);
9364
9364
  }
9365
9365
  }
9366
- var BetterSqlite3, CREATE_OBSERVATIONS_TABLE, CREATE_MINI_SKILLS_TABLE, CREATE_SESSIONS_TABLE, CREATE_META_TABLE, CREATE_TEAM_AGENTS_TABLE, CREATE_TEAM_MESSAGES_TABLE, CREATE_TEAM_TASKS_TABLE, CREATE_TEAM_TASK_DEPS_TABLE, CREATE_TEAM_LOCKS_TABLE, CREATE_TEAM_ROLES_TABLE, CREATE_CHAT_TRANSCRIPT_TABLE, CREATE_GRAPH_ENTITIES_TABLE, CREATE_GRAPH_RELATIONS_TABLE, CREATE_CODE_FILES_TABLE, CREATE_CODE_SYMBOLS_TABLE, CREATE_CODE_EDGES_TABLE, CREATE_OBSERVATION_CODE_REFS_TABLE, CREATE_SCHEMA_MIGRATIONS_TABLE, CREATE_CODE_STATE_SNAPSHOTS_TABLE, CREATE_KNOWLEDGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_CLAIM_EVIDENCE_TABLE, CREATE_KNOWLEDGE_CLAIM_EVENTS_TABLE, CREATE_KNOWLEDGE_WORKSPACES_TABLE, CREATE_KNOWLEDGE_PAGES_TABLE, CREATE_KNOWLEDGE_PAGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_PAGE_LINKS_TABLE, CREATE_KNOWLEDGE_PROPOSALS_TABLE, CREATE_KNOWLEDGE_WORKFLOWS_TABLE, CREATE_KNOWLEDGE_WORKFLOW_RUNS_TABLE, CREATE_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
9366
+ var BetterSqlite3, CREATE_OBSERVATIONS_TABLE, CREATE_MINI_SKILLS_TABLE, CREATE_SESSIONS_TABLE, CREATE_META_TABLE, CREATE_TEAM_AGENTS_TABLE, CREATE_TEAM_MESSAGES_TABLE, CREATE_TEAM_TASKS_TABLE, CREATE_TEAM_TASK_DEPS_TABLE, CREATE_TEAM_LOCKS_TABLE, CREATE_TEAM_ROLES_TABLE, CREATE_CHAT_TRANSCRIPT_TABLE, CREATE_GRAPH_ENTITIES_TABLE, CREATE_GRAPH_RELATIONS_TABLE, CREATE_CODE_FILES_TABLE, CREATE_CODE_SYMBOLS_TABLE, CREATE_CODE_EDGES_TABLE, CREATE_OBSERVATION_CODE_REFS_TABLE, CREATE_SCHEMA_MIGRATIONS_TABLE, CREATE_CODE_STATE_SNAPSHOTS_TABLE, CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE, CREATE_KNOWLEDGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_CLAIM_EVIDENCE_TABLE, CREATE_KNOWLEDGE_CLAIM_EVENTS_TABLE, CREATE_KNOWLEDGE_WORKSPACES_TABLE, CREATE_KNOWLEDGE_PAGES_TABLE, CREATE_KNOWLEDGE_PAGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_PAGE_LINKS_TABLE, CREATE_KNOWLEDGE_PROPOSALS_TABLE, CREATE_KNOWLEDGE_WORKFLOWS_TABLE, CREATE_KNOWLEDGE_WORKFLOW_RUNS_TABLE, CREATE_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MEMORY_OUTCOME_SIGNALS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
9367
9367
  var init_sqlite_db = __esm({
9368
9368
  "src/store/sqlite-db.ts"() {
9369
9369
  "use strict";
@@ -9629,6 +9629,17 @@ CREATE TABLE IF NOT EXISTS observation_code_refs (
9629
9629
  " UNIQUE(projectId, sourceEpoch)",
9630
9630
  ");"
9631
9631
  ].join("\n");
9632
+ CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE = [
9633
+ "CREATE TABLE IF NOT EXISTS code_state_snapshot_files (",
9634
+ " snapshotId TEXT NOT NULL,",
9635
+ " projectId TEXT NOT NULL,",
9636
+ " fileId TEXT NOT NULL,",
9637
+ " path TEXT NOT NULL,",
9638
+ " contentHash TEXT NOT NULL,",
9639
+ " PRIMARY KEY (snapshotId, path),",
9640
+ " FOREIGN KEY (snapshotId) REFERENCES code_state_snapshots(id) ON DELETE CASCADE",
9641
+ ");"
9642
+ ].join("\n");
9632
9643
  CREATE_KNOWLEDGE_CLAIMS_TABLE = `
9633
9644
  CREATE TABLE IF NOT EXISTS knowledge_claims (
9634
9645
  id TEXT PRIMARY KEY,
@@ -9839,6 +9850,19 @@ CREATE TABLE IF NOT EXISTS long_term_memory_events (
9839
9850
  createdAt TEXT NOT NULL,
9840
9851
  FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
9841
9852
  );
9853
+ `;
9854
+ CREATE_MEMORY_OUTCOME_SIGNALS_TABLE = `
9855
+ CREATE TABLE IF NOT EXISTS memory_outcome_signals (
9856
+ id TEXT PRIMARY KEY,
9857
+ projectId TEXT NOT NULL,
9858
+ candidateKind TEXT NOT NULL,
9859
+ candidateId TEXT NOT NULL,
9860
+ kind TEXT NOT NULL,
9861
+ sourceRef TEXT NOT NULL,
9862
+ snapshotId TEXT,
9863
+ detail TEXT,
9864
+ observedAt TEXT NOT NULL
9865
+ );
9842
9866
  `;
9843
9867
  CREATE_MEDIA_ASSETS_TABLE = `
9844
9868
  CREATE TABLE IF NOT EXISTS media_assets (
@@ -10081,6 +10105,20 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
10081
10105
  db2.exec("CREATE INDEX IF NOT EXISTS idx_code_edges_snapshot ON code_edges(projectId, snapshotId)");
10082
10106
  }
10083
10107
  },
10108
+ {
10109
+ id: "1.4-codegraph-snapshot-manifest",
10110
+ apply: (db2) => {
10111
+ db2.exec(CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE);
10112
+ db2.exec("CREATE INDEX IF NOT EXISTS idx_code_snapshot_files_project_path ON code_state_snapshot_files(projectId, path)");
10113
+ }
10114
+ },
10115
+ {
10116
+ id: "1.4-memory-outcome-signals",
10117
+ apply: (db2) => {
10118
+ db2.exec(CREATE_MEMORY_OUTCOME_SIGNALS_TABLE);
10119
+ db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_outcomes_candidate ON memory_outcome_signals(projectId, candidateKind, candidateId, observedAt DESC)");
10120
+ }
10121
+ },
10084
10122
  {
10085
10123
  id: "1.2-knowledge-claim-ledger",
10086
10124
  apply: (db2) => {
@@ -11112,14 +11150,14 @@ var init_BytePairEncodingCore = __esm({
11112
11150
  clearMergeCache() {
11113
11151
  this.mergeCache?.clear();
11114
11152
  }
11115
- *encodeNativeGenerator(text, allowedSpecial) {
11153
+ *encodeNativeGenerator(text2, allowedSpecial) {
11116
11154
  let startIndex = 0;
11117
11155
  let lastTokenLength = 0;
11118
11156
  while (true) {
11119
- const nextSpecialMatch = this.findNextSpecialToken(text, allowedSpecial, startIndex);
11157
+ const nextSpecialMatch = this.findNextSpecialToken(text2, allowedSpecial, startIndex);
11120
11158
  const nextSpecialStartIndex = nextSpecialMatch?.[0];
11121
- const endIndex = nextSpecialStartIndex ?? text.length;
11122
- const textBeforeSpecial = startIndex === 0 && endIndex === text.length ? text : text.slice(startIndex, endIndex);
11159
+ const endIndex = nextSpecialStartIndex ?? text2.length;
11160
+ const textBeforeSpecial = startIndex === 0 && endIndex === text2.length ? text2 : text2.slice(startIndex, endIndex);
11123
11161
  for (const [match2] of textBeforeSpecial.matchAll(this.tokenSplitRegex)) {
11124
11162
  const token = this.getBpeRankFromString(match2);
11125
11163
  if (token !== void 0) {
@@ -11146,14 +11184,14 @@ var init_BytePairEncodingCore = __esm({
11146
11184
  }
11147
11185
  return lastTokenLength;
11148
11186
  }
11149
- encodeNative(text, allowedSpecial) {
11187
+ encodeNative(text2, allowedSpecial) {
11150
11188
  let startIndex = 0;
11151
11189
  const tokensArray = [];
11152
11190
  while (true) {
11153
- const nextSpecialMatch = this.findNextSpecialToken(text, allowedSpecial, startIndex);
11191
+ const nextSpecialMatch = this.findNextSpecialToken(text2, allowedSpecial, startIndex);
11154
11192
  const nextSpecialStartIndex = nextSpecialMatch?.[0];
11155
- const endIndex = nextSpecialStartIndex ?? text.length;
11156
- const textBeforeSpecial = startIndex === 0 && endIndex === text.length ? text : text.slice(startIndex, endIndex);
11193
+ const endIndex = nextSpecialStartIndex ?? text2.length;
11194
+ const textBeforeSpecial = startIndex === 0 && endIndex === text2.length ? text2 : text2.slice(startIndex, endIndex);
11157
11195
  for (const [match2] of textBeforeSpecial.matchAll(this.tokenSplitRegex)) {
11158
11196
  const token = this.getBpeRankFromString(match2);
11159
11197
  if (token !== void 0) {
@@ -11177,14 +11215,14 @@ var init_BytePairEncodingCore = __esm({
11177
11215
  }
11178
11216
  return tokensArray;
11179
11217
  }
11180
- countNative(text, allowedSpecial) {
11218
+ countNative(text2, allowedSpecial) {
11181
11219
  let startIndex = 0;
11182
11220
  let tokensCount = 0;
11183
11221
  while (true) {
11184
- const nextSpecialMatch = this.findNextSpecialToken(text, allowedSpecial, startIndex);
11222
+ const nextSpecialMatch = this.findNextSpecialToken(text2, allowedSpecial, startIndex);
11185
11223
  const nextSpecialStartIndex = nextSpecialMatch?.[0];
11186
- const endIndex = nextSpecialStartIndex ?? text.length;
11187
- const textBeforeSpecial = startIndex === 0 && endIndex === text.length ? text : text.slice(startIndex, endIndex);
11224
+ const endIndex = nextSpecialStartIndex ?? text2.length;
11225
+ const textBeforeSpecial = startIndex === 0 && endIndex === text2.length ? text2 : text2.slice(startIndex, endIndex);
11188
11226
  for (const [match2] of textBeforeSpecial.matchAll(this.tokenSplitRegex)) {
11189
11227
  const token = this.getBpeRankFromString(match2);
11190
11228
  if (token !== void 0) {
@@ -11306,11 +11344,11 @@ var init_BytePairEncodingCore = __esm({
11306
11344
  }
11307
11345
  return -1;
11308
11346
  }
11309
- findNextSpecialToken(text, allowedSpecial, startIndex) {
11347
+ findNextSpecialToken(text2, allowedSpecial, startIndex) {
11310
11348
  let searchIndex = startIndex;
11311
11349
  while (true) {
11312
11350
  this.specialTokenPatternRegex.lastIndex = searchIndex;
11313
- const nextSpecialMatch = this.specialTokenPatternRegex.exec(text);
11351
+ const nextSpecialMatch = this.specialTokenPatternRegex.exec(text2);
11314
11352
  if (!nextSpecialMatch) {
11315
11353
  return void 0;
11316
11354
  }
@@ -12761,17 +12799,17 @@ var init_main = __esm({
12761
12799
  });
12762
12800
 
12763
12801
  // src/compact/token-budget.ts
12764
- function countTextTokens(text) {
12765
- return countTokens(text);
12802
+ function countTextTokens(text2) {
12803
+ return countTokens(text2);
12766
12804
  }
12767
- function fitsInBudget(text, limit2) {
12768
- return isWithinTokenLimit(text, limit2);
12805
+ function fitsInBudget(text2, limit2) {
12806
+ return isWithinTokenLimit(text2, limit2);
12769
12807
  }
12770
- function truncateToTokenBudget(text, budget) {
12771
- if (fitsInBudget(text, budget) !== false) {
12772
- return text;
12808
+ function truncateToTokenBudget(text2, budget) {
12809
+ if (fitsInBudget(text2, budget) !== false) {
12810
+ return text2;
12773
12811
  }
12774
- const sentences = text.split(/(?<=[.!?])\s+/);
12812
+ const sentences = text2.split(/(?<=[.!?])\s+/);
12775
12813
  let result = "";
12776
12814
  for (const sentence of sentences) {
12777
12815
  const candidate2 = result ? `${result} ${sentence}` : sentence;
@@ -12782,12 +12820,12 @@ function truncateToTokenBudget(text, budget) {
12782
12820
  }
12783
12821
  if (!result) {
12784
12822
  const estimatedChars = budget * 2;
12785
- result = text.slice(0, estimatedChars);
12823
+ result = text2.slice(0, estimatedChars);
12786
12824
  while (fitsInBudget(result, budget) === false && result.length > 0) {
12787
12825
  result = result.slice(0, Math.floor(result.length * 0.9));
12788
12826
  }
12789
- if (result.length < text.length) {
12790
- const nextCharacter = text.charAt(result.length);
12827
+ if (result.length < text2.length) {
12828
+ const nextCharacter = text2.charAt(result.length);
12791
12829
  if (nextCharacter && !/[\s.,;:!?)}\]]/.test(nextCharacter)) {
12792
12830
  const boundary = result.search(/\s+\S*$/);
12793
12831
  result = boundary > 0 ? result.slice(0, boundary).trimEnd() : "";
@@ -13665,8 +13703,8 @@ var require_main = __commonJS({
13665
13703
  function supportsAnsi() {
13666
13704
  return process.stdout.isTTY;
13667
13705
  }
13668
- function dim(text) {
13669
- return supportsAnsi() ? `\x1B[2m${text}\x1B[0m` : text;
13706
+ function dim(text2) {
13707
+ return supportsAnsi() ? `\x1B[2m${text2}\x1B[0m` : text2;
13670
13708
  }
13671
13709
  var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
13672
13710
  function parse5(src2) {
@@ -14375,8 +14413,8 @@ import { createHash } from "crypto";
14375
14413
  import { readFile, writeFile, mkdir } from "fs/promises";
14376
14414
  import { join as join3 } from "path";
14377
14415
  import { homedir as homedir6 } from "os";
14378
- function textHash(text) {
14379
- return createHash("sha256").update(text).digest("hex").slice(0, 16);
14416
+ function textHash(text2) {
14417
+ return createHash("sha256").update(text2).digest("hex").slice(0, 16);
14380
14418
  }
14381
14419
  async function loadDiskCache() {
14382
14420
  try {
@@ -14439,11 +14477,11 @@ var init_fastembed_provider = __esm({
14439
14477
  async embedInputs(inputs, options2 = {}) {
14440
14478
  return Promise.all(inputs.map((input) => this.embedInput(input, options2)));
14441
14479
  }
14442
- async embed(text) {
14443
- const hash4 = textHash(text);
14480
+ async embed(text2) {
14481
+ const hash4 = textHash(text2);
14444
14482
  const cached2 = cache.get(hash4);
14445
14483
  if (cached2) return cached2;
14446
- const raw = await this.model.queryEmbed(text);
14484
+ const raw = await this.model.queryEmbed(text2);
14447
14485
  const result = Array.from(raw);
14448
14486
  if (result.length !== this.dimensions) {
14449
14487
  throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
@@ -14539,10 +14577,10 @@ var init_transformers_provider = __esm({
14539
14577
  async embedInputs(inputs, options2 = {}) {
14540
14578
  return Promise.all(inputs.map((input) => this.embedInput(input, options2)));
14541
14579
  }
14542
- async embed(text) {
14543
- const cached2 = cache2.get(text);
14580
+ async embed(text2) {
14581
+ const cached2 = cache2.get(text2);
14544
14582
  if (cached2) return cached2;
14545
- const output = await this.extractor(text, {
14583
+ const output = await this.extractor(text2, {
14546
14584
  pooling: "mean",
14547
14585
  normalize: true
14548
14586
  });
@@ -14550,7 +14588,7 @@ var init_transformers_provider = __esm({
14550
14588
  if (result.length !== this.dimensions) {
14551
14589
  throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
14552
14590
  }
14553
- this.cacheSet(text, result);
14591
+ this.cacheSet(text2, result);
14554
14592
  return result;
14555
14593
  }
14556
14594
  async embedBatch(texts) {
@@ -14613,8 +14651,8 @@ function dimsCacheFile() {
14613
14651
  function cacheMetaFile() {
14614
14652
  return join4(cacheDir(), ".embedding-api-cache-meta.json");
14615
14653
  }
14616
- function normalizeText(text) {
14617
- return text.replace(/\s+/g, " ").trim().slice(0, MAX_INPUT_CHARS);
14654
+ function normalizeText(text2) {
14655
+ return text2.replace(/\s+/g, " ").trim().slice(0, MAX_INPUT_CHARS);
14618
14656
  }
14619
14657
  function cacheNamespace(config2) {
14620
14658
  return [
@@ -14624,8 +14662,8 @@ function cacheNamespace(config2) {
14624
14662
  config2.requestedDimensions ?? "native"
14625
14663
  ].join("|");
14626
14664
  }
14627
- function textHash2(text, namespace) {
14628
- return createHash2("sha256").update(`${namespace}\0${text}`).digest("hex").slice(0, 16);
14665
+ function textHash2(text2, namespace) {
14666
+ return createHash2("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
14629
14667
  }
14630
14668
  function inputIdentity(input, options2 = {}) {
14631
14669
  return JSON.stringify({
@@ -15037,8 +15075,8 @@ var init_api_provider = __esm({
15037
15075
  if (!embedding) throw new Error("API probe returned no embeddings; check model name and API key");
15038
15076
  return embedding.length;
15039
15077
  }
15040
- async embed(text, options2) {
15041
- const normalized = normalizeText(text);
15078
+ async embed(text2, options2) {
15079
+ const normalized = normalizeText(text2);
15042
15080
  if (isNativeGeminiEndpoint(this.config.baseUrl)) {
15043
15081
  return this.embedInput({ modality: "text", text: normalized }, { intent: "document", ...options2 });
15044
15082
  }
@@ -15095,7 +15133,7 @@ var init_api_provider = __esm({
15095
15133
  }
15096
15134
  async embedBatch(texts, options2) {
15097
15135
  if (isNativeGeminiEndpoint(this.config.baseUrl)) {
15098
- return Promise.all(texts.map((text) => this.embedInput({ modality: "text", text }, { intent: "document", ...options2 })));
15136
+ return Promise.all(texts.map((text2) => this.embedInput({ modality: "text", text: text2 }, { intent: "document", ...options2 })));
15099
15137
  }
15100
15138
  await ensureDiskCacheLoaded();
15101
15139
  const normalizedTexts = texts.map(normalizeText);
@@ -15174,8 +15212,8 @@ var init_api_provider = __esm({
15174
15212
  }
15175
15213
  async getCachedEmbeddings(texts) {
15176
15214
  await ensureDiskCacheLoaded();
15177
- return texts.map((text) => {
15178
- const hash4 = textHash2(normalizeText(text), this.cacheKeyNamespace);
15215
+ return texts.map((text2) => {
15216
+ const hash4 = textHash2(normalizeText(text2), this.cacheKeyNamespace);
15179
15217
  return cache3.get(hash4) ?? null;
15180
15218
  });
15181
15219
  }
@@ -15405,9 +15443,9 @@ function wrapProvider(candidate2) {
15405
15443
  return {
15406
15444
  name: candidate2.name,
15407
15445
  dimensions: candidate2.dimensions,
15408
- async embed(text, options2) {
15446
+ async embed(text2, options2) {
15409
15447
  try {
15410
- return await candidate2.embed(text, options2);
15448
+ return await candidate2.embed(text2, options2);
15411
15449
  } catch (error40) {
15412
15450
  if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error40)) {
15413
15451
  warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
@@ -15415,7 +15453,7 @@ function wrapProvider(candidate2) {
15415
15453
  if (fallback) {
15416
15454
  provider = wrapProvider(fallback);
15417
15455
  warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
15418
- return provider.embed(text, options2);
15456
+ return provider.embed(text2, options2);
15419
15457
  }
15420
15458
  }
15421
15459
  if (isTemporaryEmbeddingFailure(error40)) {
@@ -15974,8 +16012,8 @@ async function readResponseText(response, signal, maxBytes = MAX_LLM_RESPONSE_BY
15974
16012
  }
15975
16013
  }
15976
16014
  async function readResponseJson(response, signal, maxBytes = MAX_LLM_RESPONSE_BYTES) {
15977
- const text = await readResponseText(response, signal, maxBytes);
15978
- return JSON.parse(text);
16015
+ const text2 = await readResponseText(response, signal, maxBytes);
16016
+ return JSON.parse(text2);
15979
16017
  }
15980
16018
  async function* callLLMWithToolsStream(messages, tools) {
15981
16019
  if (!currentConfig) {
@@ -16528,8 +16566,8 @@ function isCjkHeavy(query) {
16528
16566
  const cjkCount = (query.match(CJK_PATTERN) || []).length;
16529
16567
  return query.length > 0 && cjkCount / query.length > 0.3;
16530
16568
  }
16531
- function normalizeExpansion(text) {
16532
- return text.trim().replace(/^[-*]\s*/, "").replace(/^["'`]+|["'`]+$/g, "").split(/\r?\n/)[0].trim();
16569
+ function normalizeExpansion(text2) {
16570
+ return text2.trim().replace(/^[-*]\s*/, "").replace(/^["'`]+|["'`]+$/g, "").split(/\r?\n/)[0].trim();
16533
16571
  }
16534
16572
  async function maybeExpandSearchQuery(query) {
16535
16573
  if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
@@ -16892,9 +16930,9 @@ function shouldSkipCompression(narrative, type) {
16892
16930
  if (specialChars / narrative.length > 0.35) return true;
16893
16931
  return false;
16894
16932
  }
16895
- function estimateTokens(text) {
16896
- const cjkChars = (text.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length;
16897
- const otherChars = text.length - cjkChars;
16933
+ function estimateTokens(text2) {
16934
+ const cjkChars = (text2.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length;
16935
+ const otherChars = text2.length - cjkChars;
16898
16936
  return Math.ceil(cjkChars / 1.5 + otherChars / 4);
16899
16937
  }
16900
16938
  var COMPRESS_PROMPT, COMPRESS_PROMPT_GENTLE, RERANK_PROMPT, SKIP_PATTERNS, LOW_COMPRESSION_TYPES;
@@ -17555,9 +17593,9 @@ var init_entity_extractor = __esm({
17555
17593
  });
17556
17594
 
17557
17595
  // src/memory/secret-filter.ts
17558
- function applyRedaction(text) {
17559
- if (!text) return text;
17560
- let out = text;
17596
+ function applyRedaction(text2) {
17597
+ if (!text2) return text2;
17598
+ let out = text2;
17561
17599
  out = out.replace(
17562
17600
  /((?:password|passwd|pwd|secret|token|api[_-]?key|auth[_-]?key|access[_-]?key|private[_-]?key|client[_-]?secret)\s*[:=]\s*["']?)([^\s"',;\n]{6,})/gi,
17563
17601
  "$1[REDACTED]"
@@ -17571,11 +17609,11 @@ function applyRedaction(text) {
17571
17609
  out = out.replace(/\beyJ[A-Za-z0-9._-]{40,}\b/g, "[REDACTED]");
17572
17610
  return out;
17573
17611
  }
17574
- function sanitizeCredentials(text) {
17575
- return applyRedaction(text);
17612
+ function sanitizeCredentials(text2) {
17613
+ return applyRedaction(text2);
17576
17614
  }
17577
- function redactCredentials(text) {
17578
- return applyRedaction(text);
17615
+ function redactCredentials(text2) {
17616
+ return applyRedaction(text2);
17579
17617
  }
17580
17618
  var init_secret_filter = __esm({
17581
17619
  "src/memory/secret-filter.ts"() {
@@ -17626,8 +17664,8 @@ function clampPositiveInteger(value, fallback) {
17626
17664
  return Math.max(1, Math.floor(value));
17627
17665
  }
17628
17666
  function errorText(error40) {
17629
- const text = error40 instanceof Error ? error40.message : String(error40);
17630
- return sanitizeCredentials(text).slice(0, MAX_ERROR_LENGTH);
17667
+ const text2 = error40 instanceof Error ? error40.message : String(error40);
17668
+ return sanitizeCredentials(text2).slice(0, MAX_ERROR_LENGTH);
17631
17669
  }
17632
17670
  function normalizedKinds(kinds) {
17633
17671
  if (!kinds) return void 0;
@@ -18721,9 +18759,9 @@ __export(consolidation_exports, {
18721
18759
  executeConsolidation: () => executeConsolidation,
18722
18760
  findConsolidationCandidates: () => findConsolidationCandidates
18723
18761
  });
18724
- function tokenize2(text) {
18762
+ function tokenize2(text2) {
18725
18763
  return new Set(
18726
- text.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t3) => t3.length > 1)
18764
+ text2.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t3) => t3.length > 1)
18727
18765
  );
18728
18766
  }
18729
18767
  function jaccardSimilarity(a3, b3) {
@@ -27875,8 +27913,8 @@ var init_headers = __esm({
27875
27913
  });
27876
27914
 
27877
27915
  // packages/ai/dist/utils/sanitize-unicode.js
27878
- function sanitizeSurrogates(text) {
27879
- return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
27916
+ function sanitizeSurrogates(text2) {
27917
+ return text2.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
27880
27918
  }
27881
27919
  var init_sanitize_unicode = __esm({
27882
27920
  "packages/ai/dist/utils/sanitize-unicode.js"() {
@@ -28358,9 +28396,9 @@ var init_values = __esm({
28358
28396
  }
28359
28397
  return n2;
28360
28398
  };
28361
- safeJSON = (text) => {
28399
+ safeJSON = (text2) => {
28362
28400
  try {
28363
- return JSON.parse(text);
28401
+ return JSON.parse(text2);
28364
28402
  } catch (err) {
28365
28403
  return void 0;
28366
28404
  }
@@ -29523,8 +29561,8 @@ async function defaultParseResponse(client, props) {
29523
29561
  const json4 = await response.json();
29524
29562
  return addRequestID(json4, response);
29525
29563
  }
29526
- const text = await response.text();
29527
- return text;
29564
+ const text2 = await response.text();
29565
+ return text2;
29528
29566
  })();
29529
29567
  loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
29530
29568
  retryOfRequestLogID,
@@ -55142,9 +55180,9 @@ var init_values2 = __esm({
55142
55180
  }
55143
55181
  return n2;
55144
55182
  };
55145
- safeJSON2 = (text) => {
55183
+ safeJSON2 = (text2) => {
55146
55184
  try {
55147
- return JSON.parse(text);
55185
+ return JSON.parse(text2);
55148
55186
  } catch (err) {
55149
55187
  return void 0;
55150
55188
  }
@@ -55918,8 +55956,8 @@ async function defaultParseResponse2(client, props) {
55918
55956
  const json4 = await response.json();
55919
55957
  return addRequestID2(json4, response);
55920
55958
  }
55921
- const text = await response.text();
55922
- return text;
55959
+ const text2 = await response.text();
55960
+ return text2;
55923
55961
  })();
55924
55962
  loggerFor2(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails2({
55925
55963
  retryOfRequestLogID,
@@ -62512,9 +62550,9 @@ function decodeSseLine(line, state) {
62512
62550
  }
62513
62551
  return null;
62514
62552
  }
62515
- function nextLineBreakIndex(text) {
62516
- const carriageReturnIndex = text.indexOf("\r");
62517
- const newlineIndex = text.indexOf("\n");
62553
+ function nextLineBreakIndex(text2) {
62554
+ const carriageReturnIndex = text2.indexOf("\r");
62555
+ const newlineIndex = text2.indexOf("\n");
62518
62556
  if (carriageReturnIndex === -1) {
62519
62557
  return newlineIndex;
62520
62558
  }
@@ -62523,18 +62561,18 @@ function nextLineBreakIndex(text) {
62523
62561
  }
62524
62562
  return Math.min(carriageReturnIndex, newlineIndex);
62525
62563
  }
62526
- function consumeLine(text) {
62527
- const lineBreakIndex = nextLineBreakIndex(text);
62564
+ function consumeLine(text2) {
62565
+ const lineBreakIndex = nextLineBreakIndex(text2);
62528
62566
  if (lineBreakIndex === -1) {
62529
62567
  return null;
62530
62568
  }
62531
62569
  let nextIndex = lineBreakIndex + 1;
62532
- if (text[lineBreakIndex] === "\r" && text[nextIndex] === "\n") {
62570
+ if (text2[lineBreakIndex] === "\r" && text2[nextIndex] === "\n") {
62533
62571
  nextIndex += 1;
62534
62572
  }
62535
62573
  return {
62536
- line: text.slice(0, lineBreakIndex),
62537
- rest: text.slice(nextIndex)
62574
+ line: text2.slice(0, lineBreakIndex),
62575
+ rest: text2.slice(nextIndex)
62538
62576
  };
62539
62577
  }
62540
62578
  async function* iterateSseMessages(body, signal) {
@@ -64701,8 +64739,8 @@ var require_common = __commonJS({
64701
64739
  }
64702
64740
  function redactString(obj, key) {
64703
64741
  if (typeof obj === "object" && obj !== null && typeof obj[key] === "string") {
64704
- const text = obj[key];
64705
- if (/grant_type=/i.test(text) || /assertion=/i.test(text) || /secret/i.test(text)) {
64742
+ const text2 = obj[key];
64743
+ if (/grant_type=/i.test(text2) || /assertion=/i.test(text2) || /secret/i.test(text2)) {
64706
64744
  obj[key] = REDACT;
64707
64745
  }
64708
64746
  }
@@ -71530,8 +71568,8 @@ var init_body = __esm({
71530
71568
  * @return Promise
71531
71569
  */
71532
71570
  async json() {
71533
- const text = await this.text();
71534
- return JSON.parse(text);
71571
+ const text2 = await this.text();
71572
+ return JSON.parse(text2);
71535
71573
  }
71536
71574
  /**
71537
71575
  * Decode response as text
@@ -72683,7 +72721,7 @@ var require_gaxios = __commonJS({
72683
72721
  var retry_js_1 = require_retry3();
72684
72722
  var stream_1 = __require("stream");
72685
72723
  var interceptor_js_1 = require_interceptor();
72686
- var randomUUID16 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
72724
+ var randomUUID17 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
72687
72725
  var HTTP_STATUS_NO_CONTENT = 204;
72688
72726
  var Gaxios = class {
72689
72727
  agentCache = /* @__PURE__ */ new Map();
@@ -72956,7 +72994,7 @@ var require_gaxios = __commonJS({
72956
72994
  */
72957
72995
  ["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
72958
72996
  if (opts.multipart?.length) {
72959
- const boundary = await randomUUID16();
72997
+ const boundary = await randomUUID17();
72960
72998
  preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
72961
72999
  opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
72962
73000
  } else if (shouldDirectlyPassData) {
@@ -74707,18 +74745,18 @@ var require_parse = __commonJS({
74707
74745
  n: "\n",
74708
74746
  r: "\r",
74709
74747
  t: " "
74710
- }, text, error40 = function(m5) {
74748
+ }, text2, error40 = function(m5) {
74711
74749
  throw {
74712
74750
  name: "SyntaxError",
74713
74751
  message: m5,
74714
74752
  at,
74715
- text
74753
+ text: text2
74716
74754
  };
74717
74755
  }, next = function(c5) {
74718
74756
  if (c5 && c5 !== ch) {
74719
74757
  error40("Expected '" + c5 + "' instead of '" + ch + "'");
74720
74758
  }
74721
- ch = text.charAt(at);
74759
+ ch = text2.charAt(at);
74722
74760
  at += 1;
74723
74761
  return ch;
74724
74762
  }, number4 = function() {
@@ -74765,12 +74803,12 @@ var require_parse = __commonJS({
74765
74803
  var startAt = at;
74766
74804
  while (next()) {
74767
74805
  if (ch === '"') {
74768
- if (at - 1 > startAt) string5 += text.substring(startAt, at - 1);
74806
+ if (at - 1 > startAt) string5 += text2.substring(startAt, at - 1);
74769
74807
  next();
74770
74808
  return string5;
74771
74809
  }
74772
74810
  if (ch === "\\") {
74773
- if (at - 1 > startAt) string5 += text.substring(startAt, at - 1);
74811
+ if (at - 1 > startAt) string5 += text2.substring(startAt, at - 1);
74774
74812
  next();
74775
74813
  if (ch === "u") {
74776
74814
  uffff = 0;
@@ -74903,7 +74941,7 @@ var require_parse = __commonJS({
74903
74941
  };
74904
74942
  return function(source, reviver) {
74905
74943
  var result;
74906
- text = source + "";
74944
+ text2 = source + "";
74907
74945
  at = 0;
74908
74946
  ch = " ";
74909
74947
  result = value();
@@ -75815,8 +75853,8 @@ var require_crypto = __commonJS({
75815
75853
  const result = new TextDecoder().decode(uint8array);
75816
75854
  return result;
75817
75855
  }
75818
- encodeBase64StringUtf8(text) {
75819
- const uint8array = new TextEncoder().encode(text);
75856
+ encodeBase64StringUtf8(text2) {
75857
+ const uint8array = new TextEncoder().encode(text2);
75820
75858
  const result = base64js.fromByteArray(uint8array);
75821
75859
  return result;
75822
75860
  }
@@ -75885,8 +75923,8 @@ var require_crypto2 = __commonJS({
75885
75923
  decodeBase64StringUtf8(base643) {
75886
75924
  return Buffer.from(base643, "base64").toString("utf-8");
75887
75925
  }
75888
- encodeBase64StringUtf8(text) {
75889
- return Buffer.from(text, "utf-8").toString("base64");
75926
+ encodeBase64StringUtf8(text2) {
75927
+ return Buffer.from(text2, "utf-8").toString("base64");
75890
75928
  }
75891
75929
  /**
75892
75930
  * Computes the SHA-256 hash of the provided string.
@@ -96331,8 +96369,8 @@ async function defaultParseResponse3(client, props) {
96331
96369
  const json4 = await response.json();
96332
96370
  return json4;
96333
96371
  }
96334
- const text = await response.text();
96335
- return text;
96372
+ const text2 = await response.text();
96373
+ return text2;
96336
96374
  })();
96337
96375
  loggerFor3(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails3({
96338
96376
  retryOfRequestLogID,
@@ -97909,7 +97947,7 @@ var init_node = __esm({
97909
97947
  if (this.candidates && this.candidates.length > 1) {
97910
97948
  console.warn("there are multiple candidates in the response, returning text from the first one.");
97911
97949
  }
97912
- let text = "";
97950
+ let text2 = "";
97913
97951
  let anyTextPartText = false;
97914
97952
  const nonTextParts = [];
97915
97953
  for (const part of (_h = (_g = (_f = (_e = this.candidates) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.content) === null || _g === void 0 ? void 0 : _g.parts) !== null && _h !== void 0 ? _h : []) {
@@ -97923,13 +97961,13 @@ var init_node = __esm({
97923
97961
  continue;
97924
97962
  }
97925
97963
  anyTextPartText = true;
97926
- text += part.text;
97964
+ text2 += part.text;
97927
97965
  }
97928
97966
  }
97929
97967
  if (nonTextParts.length > 0) {
97930
97968
  console.warn(`there are non-text parts ${nonTextParts} in the response, returning concatenation of all text parts. Please refer to the non text parts for a full response from model.`);
97931
97969
  }
97932
- return anyTextPartText ? text : void 0;
97970
+ return anyTextPartText ? text2 : void 0;
97933
97971
  }
97934
97972
  /**
97935
97973
  * Returns the concatenation of all inline data parts from the first candidate
@@ -98182,7 +98220,7 @@ var init_node = __esm({
98182
98220
  */
98183
98221
  get text() {
98184
98222
  var _a5, _b, _c;
98185
- let text = "";
98223
+ let text2 = "";
98186
98224
  let anyTextPartFound = false;
98187
98225
  const nonTextParts = [];
98188
98226
  for (const part of (_c = (_b = (_a5 = this.serverContent) === null || _a5 === void 0 ? void 0 : _a5.modelTurn) === null || _b === void 0 ? void 0 : _b.parts) !== null && _c !== void 0 ? _c : []) {
@@ -98196,13 +98234,13 @@ var init_node = __esm({
98196
98234
  continue;
98197
98235
  }
98198
98236
  anyTextPartFound = true;
98199
- text += part.text;
98237
+ text2 += part.text;
98200
98238
  }
98201
98239
  }
98202
98240
  if (nonTextParts.length > 0) {
98203
98241
  console.warn(`there are non-text parts ${nonTextParts} in the response, returning concatenation of all text parts. Please refer to the non text parts for a full response from model.`);
98204
98242
  }
98205
- return anyTextPartFound ? text : void 0;
98243
+ return anyTextPartFound ? text2 : void 0;
98206
98244
  }
98207
98245
  /**
98208
98246
  * Returns the concatenation of all inline data parts from the server content if present.
@@ -102874,9 +102912,9 @@ var init_node = __esm({
102874
102912
  }
102875
102913
  return n2;
102876
102914
  };
102877
- safeJSON3 = (text) => {
102915
+ safeJSON3 = (text2) => {
102878
102916
  try {
102879
- return JSON.parse(text);
102917
+ return JSON.parse(text2);
102880
102918
  } catch (err) {
102881
102919
  return void 0;
102882
102920
  }
@@ -132477,8 +132515,8 @@ function findBoundary(buf) {
132477
132515
  return null;
132478
132516
  }
132479
132517
  function parseMessage2(chunk, parse5, state, dataRequired) {
132480
- const text = new TextDecoder().decode(chunk);
132481
- const lines = text.split(/\r\n|\r|\n/);
132518
+ const text2 = new TextDecoder().decode(chunk);
132519
+ const lines = text2.split(/\r\n|\r|\n/);
132482
132520
  const dataLines = [];
132483
132521
  const ret = {};
132484
132522
  let ignore = true;
@@ -159477,10 +159515,10 @@ function formatMistralError(error40) {
159477
159515
  }
159478
159516
  return safeJsonStringify(error40);
159479
159517
  }
159480
- function truncateErrorText(text, maxChars) {
159481
- if (text.length <= maxChars)
159482
- return text;
159483
- return `${text.slice(0, maxChars)}... [truncated ${text.length - maxChars} chars]`;
159518
+ function truncateErrorText(text2, maxChars) {
159519
+ if (text2.length <= maxChars)
159520
+ return text2;
159521
+ return `${text2.slice(0, maxChars)}... [truncated ${text2.length - maxChars} chars]`;
159484
159522
  }
159485
159523
  function safeJsonStringify(value) {
159486
159524
  try {
@@ -159600,7 +159638,7 @@ async function consumeChatStream(model, output, stream2, mistralStream) {
159600
159638
  continue;
159601
159639
  }
159602
159640
  if (item.type === "thinking") {
159603
- const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text) => text.length > 0).join("");
159641
+ const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text2) => text2.length > 0).join("");
159604
159642
  const thinkingDelta = sanitizeSurrogates(deltaText);
159605
159643
  if (!thinkingDelta)
159606
159644
  continue;
@@ -159797,8 +159835,8 @@ function toChatMessages(messages, supportsImages) {
159797
159835
  }
159798
159836
  return result;
159799
159837
  }
159800
- function buildToolResultText(text, hasImages, supportsImages, isError) {
159801
- const trimmed = text.trim();
159838
+ function buildToolResultText(text2, hasImages, supportsImages, isError) {
159839
+ const trimmed = text2.trim();
159802
159840
  const errorPrefix = isError ? "[tool error] " : "";
159803
159841
  if (trimmed.length > 0) {
159804
159842
  const imageSuffix = hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : "";
@@ -160599,14 +160637,14 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
160599
160637
  };
160600
160638
  const onMessage = (event) => {
160601
160639
  void (async () => {
160602
- let text = null;
160640
+ let text2 = null;
160603
160641
  try {
160604
160642
  if (!event || typeof event !== "object" || !("data" in event))
160605
160643
  return;
160606
- text = await decodeWebSocketData(event.data);
160607
- if (!text)
160644
+ text2 = await decodeWebSocketData(event.data);
160645
+ if (!text2)
160608
160646
  return;
160609
- const parsed = JSON.parse(text);
160647
+ const parsed = JSON.parse(text2);
160610
160648
  const type = typeof parsed.type === "string" ? parsed.type : "";
160611
160649
  if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
160612
160650
  sawCompletion = true;
@@ -160617,7 +160655,7 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
160617
160655
  } catch (cause) {
160618
160656
  failed = new CodexProtocolError(`Invalid Codex WebSocket JSON: ${formatThrownValue(cause)}`, {
160619
160657
  cause,
160620
- payload: text
160658
+ payload: text2
160621
160659
  });
160622
160660
  done = true;
160623
160661
  wake();
@@ -168810,11 +168848,11 @@ function videoRequestConfig(input) {
168810
168848
  };
168811
168849
  }
168812
168850
  async function readMiniMaxJson(response) {
168813
- const text = await response.text();
168851
+ const text2 = await response.text();
168814
168852
  let body = {};
168815
- if (text) {
168853
+ if (text2) {
168816
168854
  try {
168817
- const parsed = JSON.parse(text);
168855
+ const parsed = JSON.parse(text2);
168818
168856
  if (isRecord2(parsed)) body = parsed;
168819
168857
  } catch {
168820
168858
  throw new Error("MiniMax video API returned invalid JSON");
@@ -169717,6 +169755,7 @@ __export(store_exports, {
169717
169755
  CodeGraphStore: () => CodeGraphStore
169718
169756
  });
169719
169757
  import { randomUUID as randomUUID6 } from "crypto";
169758
+ import { posix as pathPosix } from "path";
169720
169759
  function rowToFile(row) {
169721
169760
  return {
169722
169761
  id: row.id,
@@ -169767,6 +169806,26 @@ function rowToEdge(row) {
169767
169806
  ...row.sourceEpoch != null ? { sourceEpoch: Number(row.sourceEpoch) } : {}
169768
169807
  };
169769
169808
  }
169809
+ function resolveRelativeImportTarget(sourcePath, evidence, fileByPath) {
169810
+ const target = evidence?.trim().replace(/\\/g, "/");
169811
+ if (!target?.startsWith(".")) return void 0;
169812
+ const base = normalizeCodePath(pathPosix.normalize(pathPosix.join(pathPosix.dirname(sourcePath), target)));
169813
+ if (!base || base === ".." || base.startsWith("../")) return void 0;
169814
+ const candidates = [base];
169815
+ const extensionMatch = base.match(/(\.[A-Za-z0-9]+)$/);
169816
+ const hasExtension = Boolean(extensionMatch);
169817
+ if (!hasExtension) {
169818
+ const extensions = [...new Set([...fileByPath.keys()].map((path46) => path46.match(/(\.[A-Za-z0-9]+)$/)?.[1]).filter((extension3) => Boolean(extension3)))];
169819
+ for (const extension3 of extensions) {
169820
+ candidates.push(`${base}${extension3}`, `${base}/index${extension3}`);
169821
+ }
169822
+ } else {
169823
+ const sourceStem = base.slice(0, -extensionMatch[1].length);
169824
+ const sourceExtensions = extensionMatch[1] === ".js" ? [".ts", ".tsx", ".js", ".jsx"] : extensionMatch[1] === ".mjs" ? [".mts", ".mjs"] : extensionMatch[1] === ".cjs" ? [".cts", ".cjs"] : [];
169825
+ for (const extension3 of sourceExtensions) candidates.push(`${sourceStem}${extension3}`);
169826
+ }
169827
+ return candidates.map((candidate2) => fileByPath.get(candidate2)).find((file2) => Boolean(file2));
169828
+ }
169770
169829
  function rowToRef(row) {
169771
169830
  return {
169772
169831
  id: row.id,
@@ -169827,6 +169886,18 @@ function rowToSnapshot(row) {
169827
169886
  ...row.previousSnapshotId ? { previousSnapshotId: row.previousSnapshotId } : {}
169828
169887
  };
169829
169888
  }
169889
+ function rowToSnapshotFile(row) {
169890
+ return {
169891
+ snapshotId: row.snapshotId,
169892
+ projectId: row.projectId,
169893
+ fileId: row.fileId,
169894
+ path: row.path,
169895
+ contentHash: row.contentHash
169896
+ };
169897
+ }
169898
+ function snapshotIsIncomplete(snapshot) {
169899
+ return snapshot.completeness.skippedOversizedFiles > 0 || (snapshot.completeness.unreadableFiles ?? 0) > 0 || snapshot.completeness.removalScanDeferred;
169900
+ }
169830
169901
  var CodeGraphStore;
169831
169902
  var init_store = __esm({
169832
169903
  "src/codegraph/store.ts"() {
@@ -169998,6 +170069,7 @@ var init_store = __esm({
169998
170069
  }
169999
170070
  });
170000
170071
  tx();
170072
+ this.reconcileLocalImportTargets(projectId);
170001
170073
  }
170002
170074
  /**
170003
170075
  * Reconcile only files whose source changed plus files that disappeared.
@@ -170007,7 +170079,10 @@ var init_store = __esm({
170007
170079
  const changed = input.changed.filter((delta) => delta.file.projectId === projectId);
170008
170080
  const metadataOnly = (input.metadataOnly ?? []).filter((file2) => file2.projectId === projectId);
170009
170081
  const removedFileIds = input.removedFileIds ?? [];
170010
- if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) return;
170082
+ if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) {
170083
+ this.reconcileLocalImportTargets(projectId);
170084
+ return;
170085
+ }
170011
170086
  const staleRefsForFile = this.db.prepare(`
170012
170087
  UPDATE observation_code_refs
170013
170088
  SET status = 'stale', updatedAt = ?
@@ -170017,9 +170092,18 @@ var init_store = __esm({
170017
170092
  )
170018
170093
  )
170019
170094
  `);
170020
- const deleteEdgesForFile = this.db.prepare(`
170095
+ const deleteEdgesFromFile = this.db.prepare(`
170096
+ DELETE FROM code_edges
170097
+ WHERE projectId = ? AND fromFileId = ?
170098
+ `);
170099
+ const clearImportTargetsForFile = this.db.prepare(`
170100
+ UPDATE code_edges
170101
+ SET toFileId = NULL
170102
+ WHERE projectId = ? AND toFileId = ? AND type = 'imports'
170103
+ `);
170104
+ const deleteOtherIncomingEdgesForFile = this.db.prepare(`
170021
170105
  DELETE FROM code_edges
170022
- WHERE projectId = ? AND (fromFileId = ? OR toFileId = ?)
170106
+ WHERE projectId = ? AND toFileId = ? AND type != 'imports'
170023
170107
  `);
170024
170108
  const deleteSymbolsForFile = this.db.prepare(`DELETE FROM code_symbols WHERE projectId = ? AND fileId = ?`);
170025
170109
  const deleteFile = this.db.prepare(`DELETE FROM code_files WHERE projectId = ? AND id = ?`);
@@ -170056,14 +170140,18 @@ var init_store = __esm({
170056
170140
  const staleAt = (/* @__PURE__ */ new Date()).toISOString();
170057
170141
  for (const fileId of removedFileIds) {
170058
170142
  staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
170059
- deleteEdgesForFile.run(projectId, fileId, fileId);
170143
+ deleteEdgesFromFile.run(projectId, fileId);
170144
+ clearImportTargetsForFile.run(projectId, fileId);
170145
+ deleteOtherIncomingEdgesForFile.run(projectId, fileId);
170060
170146
  deleteSymbolsForFile.run(projectId, fileId);
170061
170147
  deleteFile.run(projectId, fileId);
170062
170148
  }
170063
170149
  for (const delta of changed) {
170064
170150
  const fileId = delta.file.id;
170065
170151
  staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
170066
- deleteEdgesForFile.run(projectId, fileId, fileId);
170152
+ deleteEdgesFromFile.run(projectId, fileId);
170153
+ clearImportTargetsForFile.run(projectId, fileId);
170154
+ deleteOtherIncomingEdgesForFile.run(projectId, fileId);
170067
170155
  deleteSymbolsForFile.run(projectId, fileId);
170068
170156
  writeFile10(delta.file);
170069
170157
  for (const symbol2 of delta.symbols) {
@@ -170101,6 +170189,7 @@ var init_store = __esm({
170101
170189
  for (const file2 of metadataOnly) writeFile10(file2);
170102
170190
  });
170103
170191
  tx();
170192
+ this.reconcileLocalImportTargets(projectId);
170104
170193
  }
170105
170194
  upsertObservationRefs(refs) {
170106
170195
  if (refs.length === 0) return;
@@ -170162,6 +170251,25 @@ var init_store = __esm({
170162
170251
  });
170163
170252
  tx();
170164
170253
  }
170254
+ /**
170255
+ * Lite import extraction records the original import text first. Resolve only
170256
+ * local relative imports against the current index after each refresh, so an
170257
+ * added or removed target cannot leave a fabricated file-to-file relation.
170258
+ */
170259
+ reconcileLocalImportTargets(projectId) {
170260
+ const fileById = new Map(this.listFiles(projectId).map((file2) => [file2.id, file2]));
170261
+ const fileByPath = new Map([...fileById.values()].map((file2) => [file2.path, file2]));
170262
+ const update2 = this.db.prepare("UPDATE code_edges SET toFileId = ? WHERE id = ?");
170263
+ const tx = this.db.transaction(() => {
170264
+ for (const edge of this.listEdges(projectId)) {
170265
+ if (edge.type !== "imports" || !edge.fromFileId) continue;
170266
+ const source = fileById.get(edge.fromFileId);
170267
+ const target = source ? resolveRelativeImportTarget(source.path, edge.evidence, fileByPath) : void 0;
170268
+ update2.run(target?.id ?? null, edge.id);
170269
+ }
170270
+ });
170271
+ tx();
170272
+ }
170165
170273
  getFile(projectId, path46) {
170166
170274
  const row = this.db.prepare(`SELECT * FROM code_files WHERE projectId = ? AND path = ?`).get(projectId, normalizeCodePath(path46));
170167
170275
  return row ? rowToFile(row) : null;
@@ -170236,6 +170344,18 @@ var init_store = __esm({
170236
170344
  ORDER BY observationId, status, id
170237
170345
  `).all(projectId).map(rowToRef);
170238
170346
  }
170347
+ /** Count distinct observations whose binding to these exact files is stale. */
170348
+ countStaleObservationRefsForFiles(projectId, fileIds) {
170349
+ const ids = [...new Set(fileIds.filter(Boolean))];
170350
+ if (ids.length === 0) return 0;
170351
+ const placeholders = ids.map(() => "?").join(", ");
170352
+ const row = this.db.prepare(`
170353
+ SELECT COUNT(DISTINCT observationId) AS count
170354
+ FROM observation_code_refs
170355
+ WHERE projectId = ? AND status = 'stale' AND fileId IN (${placeholders})
170356
+ `).get(projectId, ...ids);
170357
+ return Number(row?.count ?? 0);
170358
+ }
170239
170359
  listReferencedSymbols(projectId) {
170240
170360
  return this.db.prepare(`
170241
170361
  SELECT DISTINCT symbols.*
@@ -170257,6 +170377,94 @@ var init_store = __esm({
170257
170377
  "SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
170258
170378
  ).all(projectId, safeLimit2).map(rowToSnapshot);
170259
170379
  }
170380
+ listSnapshotFiles(snapshotId) {
170381
+ return this.db.prepare(`
170382
+ SELECT snapshotId, projectId, fileId, path, contentHash
170383
+ FROM code_state_snapshot_files
170384
+ WHERE snapshotId = ?
170385
+ ORDER BY path
170386
+ `).all(snapshotId).map(rowToSnapshotFile);
170387
+ }
170388
+ diffSnapshots(projectId, fromSnapshotId, toSnapshotId) {
170389
+ const snapshots = this.db.prepare(`
170390
+ SELECT * FROM code_state_snapshots WHERE id IN (?, ?)
170391
+ `).all(fromSnapshotId, toSnapshotId).map(rowToSnapshot);
170392
+ if (snapshots.length !== 2) {
170393
+ return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "missing-snapshot", changes: [] };
170394
+ }
170395
+ if (snapshots.some((snapshot) => snapshot.projectId !== projectId)) {
170396
+ return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "project-mismatch", changes: [] };
170397
+ }
170398
+ if (snapshots.some(snapshotIsIncomplete)) {
170399
+ return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "incomplete-snapshot", changes: [] };
170400
+ }
170401
+ const before = this.listSnapshotFiles(fromSnapshotId);
170402
+ const after = this.listSnapshotFiles(toSnapshotId);
170403
+ if (before.length === 0 || after.length === 0) {
170404
+ return {
170405
+ projectId,
170406
+ fromSnapshotId,
170407
+ toSnapshotId,
170408
+ available: false,
170409
+ reason: "legacy-snapshot-without-manifest",
170410
+ changes: []
170411
+ };
170412
+ }
170413
+ const beforeByPath = new Map(before.map((file2) => [file2.path, file2]));
170414
+ const afterByPath = new Map(after.map((file2) => [file2.path, file2]));
170415
+ const paths = [.../* @__PURE__ */ new Set([...beforeByPath.keys(), ...afterByPath.keys()])].sort();
170416
+ const changes = [];
170417
+ for (const path46 of paths) {
170418
+ const oldFile = beforeByPath.get(path46);
170419
+ const newFile = afterByPath.get(path46);
170420
+ if (!oldFile && newFile) {
170421
+ changes.push({ path: path46, kind: "added", afterHash: newFile.contentHash });
170422
+ } else if (oldFile && !newFile) {
170423
+ changes.push({ path: path46, kind: "removed", beforeHash: oldFile.contentHash });
170424
+ } else if (oldFile && newFile && oldFile.contentHash !== newFile.contentHash) {
170425
+ changes.push({ path: path46, kind: "modified", beforeHash: oldFile.contentHash, afterHash: newFile.contentHash });
170426
+ }
170427
+ }
170428
+ return { projectId, fromSnapshotId, toSnapshotId, available: true, changes };
170429
+ }
170430
+ impactSlice(projectId, changedPaths, maxRelations = 24) {
170431
+ const safeLimit2 = Number.isFinite(maxRelations) ? Math.max(1, Math.min(100, Math.floor(maxRelations))) : 24;
170432
+ const normalizedPaths = [...new Set(changedPaths.map(normalizeCodePath).filter(Boolean))].sort();
170433
+ const files = this.listFiles(projectId);
170434
+ const fileById = new Map(files.map((file2) => [file2.id, file2.path]));
170435
+ const fileIdBySymbolId = new Map(this.listSymbols(projectId).map((symbol2) => [symbol2.id, symbol2.fileId]));
170436
+ const changedIds = new Set(files.filter((file2) => normalizedPaths.includes(file2.path)).map((file2) => file2.id));
170437
+ const direct = /* @__PURE__ */ new Set();
170438
+ let relationCount = 0;
170439
+ let truncated = false;
170440
+ for (const edge of this.listEdges(projectId)) {
170441
+ const endpoints = [
170442
+ edge.fromFileId,
170443
+ edge.toFileId,
170444
+ edge.fromSymbolId ? fileIdBySymbolId.get(edge.fromSymbolId) : void 0,
170445
+ edge.toSymbolId ? fileIdBySymbolId.get(edge.toSymbolId) : void 0
170446
+ ].filter((id) => Boolean(id));
170447
+ if (!endpoints.some((id) => changedIds.has(id))) continue;
170448
+ const relatedPaths = endpoints.filter((id) => !changedIds.has(id)).map((id) => fileById.get(id)).filter((path46) => Boolean(path46));
170449
+ if (relatedPaths.length === 0) continue;
170450
+ if (relationCount >= safeLimit2) {
170451
+ truncated = true;
170452
+ break;
170453
+ }
170454
+ relationCount += 1;
170455
+ for (const path46 of relatedPaths) direct.add(path46);
170456
+ }
170457
+ const snapshot = this.latestSnapshot(projectId);
170458
+ return {
170459
+ projectId,
170460
+ ...snapshot ? { snapshotId: snapshot.id } : {},
170461
+ changedPaths: normalizedPaths,
170462
+ directlyConnectedPaths: [...direct].sort(),
170463
+ relationCount,
170464
+ truncated,
170465
+ provider: snapshot?.provider ?? "lite"
170466
+ };
170467
+ }
170260
170468
  /**
170261
170469
  * Record a completed scan and mark all current structural facts with its
170262
170470
  * epoch. The snapshot is written only after refresh reconciliation succeeds,
@@ -170298,6 +170506,16 @@ var init_store = __esm({
170298
170506
  this.db.prepare(
170299
170507
  "UPDATE observation_code_refs SET snapshotId = ? WHERE projectId = ? AND status = 'current'"
170300
170508
  ).run(id, input.projectId);
170509
+ const snapshotFileRows = this.db.prepare(`
170510
+ SELECT id, projectId, path, contentHash FROM code_files WHERE projectId = ? ORDER BY path
170511
+ `).all(input.projectId);
170512
+ const insertSnapshotFile = this.db.prepare(`
170513
+ INSERT INTO code_state_snapshot_files (snapshotId, projectId, fileId, path, contentHash)
170514
+ VALUES (?, ?, ?, ?, ?)
170515
+ `);
170516
+ for (const file2 of snapshotFileRows) {
170517
+ insertSnapshotFile.run(id, file2.projectId, file2.id, file2.path, file2.contentHash);
170518
+ }
170301
170519
  snapshot = {
170302
170520
  ...input,
170303
170521
  id,
@@ -170463,8 +170681,8 @@ __export(lite_provider_exports, {
170463
170681
  import { createHash as createHash7 } from "crypto";
170464
170682
  import { readdirSync as readdirSync2, readFileSync as readFileSync7, statSync as statSync4 } from "fs";
170465
170683
  import { join as join5, relative } from "path";
170466
- function hashText(text) {
170467
- return createHash7("sha256").update(text).digest("hex");
170684
+ function hashText(text2) {
170685
+ return createHash7("sha256").update(text2).digest("hex");
170468
170686
  }
170469
170687
  function extension2(path46) {
170470
170688
  const index = path46.lastIndexOf(".");
@@ -170508,19 +170726,19 @@ function walk(root, exclude, maxFiles) {
170508
170726
  visit(root);
170509
170727
  return out;
170510
170728
  }
170511
- function lineOf(text, index) {
170512
- return text.slice(0, index).split(/\r?\n/).length;
170729
+ function lineOf(text2, index) {
170730
+ return text2.slice(0, index).split(/\r?\n/).length;
170513
170731
  }
170514
- function extractSymbols(projectId, file2, text, indexedAt) {
170732
+ function extractSymbols(projectId, file2, text2, indexedAt) {
170515
170733
  const symbols = [];
170516
170734
  const profile = file2.language ? languageProfiles[file2.language] : void 0;
170517
170735
  const patterns = profile?.symbols ?? [];
170518
170736
  for (const { kind, re: re2 } of patterns) {
170519
170737
  re2.lastIndex = 0;
170520
- for (const match2 of text.matchAll(re2)) {
170738
+ for (const match2 of text2.matchAll(re2)) {
170521
170739
  const name = match2[1];
170522
170740
  if (!name || name.includes("\n")) continue;
170523
- const startLine = lineOf(text, match2.index ?? 0);
170741
+ const startLine = lineOf(text2, match2.index ?? 0);
170524
170742
  const id = makeCodeSymbolId({ projectId, path: file2.path, qualifiedName: name, kind });
170525
170743
  symbols.push({
170526
170744
  id,
@@ -170540,13 +170758,13 @@ function extractSymbols(projectId, file2, text, indexedAt) {
170540
170758
  }
170541
170759
  return symbols;
170542
170760
  }
170543
- function extractImportEdges(projectId, file2, text, indexedAt) {
170761
+ function extractImportEdges(projectId, file2, text2, indexedAt) {
170544
170762
  const edges = [];
170545
170763
  const profile = file2.language ? languageProfiles[file2.language] : void 0;
170546
170764
  const imports = profile?.imports ?? [];
170547
170765
  for (const re2 of imports) {
170548
170766
  re2.lastIndex = 0;
170549
- for (const match2 of text.matchAll(re2)) {
170767
+ for (const match2 of text2.matchAll(re2)) {
170550
170768
  const target = (match2[1] ?? "").trim();
170551
170769
  if (!target) continue;
170552
170770
  if (target.includes("\n")) {
@@ -170581,14 +170799,14 @@ function extractImportEdges(projectId, file2, text, indexedAt) {
170581
170799
  function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
170582
170800
  const rel = normalizeCodePath(relative(projectRoot, abs));
170583
170801
  try {
170584
- const text = readFileSync7(abs, "utf-8");
170802
+ const text2 = readFileSync7(abs, "utf-8");
170585
170803
  const stat4 = fileStat ?? statSync4(abs);
170586
170804
  const file2 = {
170587
170805
  id: makeCodeFileId(projectId, rel),
170588
170806
  projectId,
170589
170807
  path: rel,
170590
170808
  language: languageForPath(rel),
170591
- contentHash: hashText(text),
170809
+ contentHash: hashText(text2),
170592
170810
  // Preserve filesystem precision. Rounding here made same-size edits in
170593
170811
  // a short Windows timestamp window indistinguishable to refresh.
170594
170812
  mtimeMs: Number(stat4.mtimeMs),
@@ -170598,8 +170816,8 @@ function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
170598
170816
  return {
170599
170817
  delta: {
170600
170818
  file: file2,
170601
- symbols: extractSymbols(projectId, file2, text, indexedAt),
170602
- edges: extractImportEdges(projectId, file2, text, indexedAt)
170819
+ symbols: extractSymbols(projectId, file2, text2, indexedAt),
170820
+ edges: extractImportEdges(projectId, file2, text2, indexedAt)
170603
170821
  },
170604
170822
  unreadable: false
170605
170823
  };
@@ -170878,18 +171096,18 @@ __export(binder_exports, {
170878
171096
  function observationText(obs) {
170879
171097
  return [obs.title, obs.narrative, ...obs.facts ?? []].join("\n");
170880
171098
  }
170881
- function mentionsSymbol(text, symbol2) {
171099
+ function mentionsSymbol(text2, symbol2) {
170882
171100
  const name = symbol2.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
170883
- return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text);
171101
+ return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text2);
170884
171102
  }
170885
- function identifierCandidates(text) {
170886
- return [...new Set(text.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
171103
+ function identifierCandidates(text2) {
171104
+ return [...new Set(text2.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
170887
171105
  }
170888
- function codeIdentifierCandidates(text) {
171106
+ function codeIdentifierCandidates(text2) {
170889
171107
  const explicit = /* @__PURE__ */ new Set();
170890
- for (const match2 of text.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
170891
- for (const match2 of text.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
170892
- return identifierCandidates(text).filter((candidate2) => explicit.has(candidate2) || candidate2.includes("::") || /[!?=]$/.test(candidate2) || /^[A-Z]/.test(candidate2) || /[_$]/.test(candidate2) || /[a-z0-9][A-Z]/.test(candidate2) || /[A-Z]{2}/.test(candidate2));
171108
+ for (const match2 of text2.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
171109
+ for (const match2 of text2.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
171110
+ return identifierCandidates(text2).filter((candidate2) => explicit.has(candidate2) || candidate2.includes("::") || /[!?=]$/.test(candidate2) || /^[A-Z]/.test(candidate2) || /[_$]/.test(candidate2) || /[a-z0-9][A-Z]/.test(candidate2) || /[A-Z]{2}/.test(candidate2));
170893
171111
  }
170894
171112
  function fileRef(projectId, obs, file2) {
170895
171113
  return {
@@ -170919,7 +171137,7 @@ function symbolRef(projectId, obs, file2, symbol2) {
170919
171137
  }
170920
171138
  function resolveObservationCodeRefs(obs, lookup2) {
170921
171139
  const refs = /* @__PURE__ */ new Map();
170922
- const text = observationText(obs);
171140
+ const text2 = observationText(obs);
170923
171141
  const candidateFiles = /* @__PURE__ */ new Map();
170924
171142
  for (const rawPath of obs.filesModified ?? []) {
170925
171143
  const file2 = lookup2.findFile(normalizeCodePath(rawPath));
@@ -170929,7 +171147,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
170929
171147
  refs.set(ref.id, ref);
170930
171148
  }
170931
171149
  const hintedFileIds = new Set(candidateFiles.keys());
170932
- const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text) : codeIdentifierCandidates(text);
171150
+ const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text2) : codeIdentifierCandidates(text2);
170933
171151
  const symbols = lookup2.findSymbols(symbolNames, [...hintedFileIds]);
170934
171152
  const symbolsByName = /* @__PURE__ */ new Map();
170935
171153
  for (const symbol2 of symbols) {
@@ -170940,7 +171158,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
170940
171158
  for (const group of symbolsByName.values()) {
170941
171159
  const candidates = group.length === 1 ? group : [];
170942
171160
  for (const symbol2 of candidates) {
170943
- if (!mentionsSymbol(text, symbol2)) continue;
171161
+ if (!mentionsSymbol(text2, symbol2)) continue;
170944
171162
  const file2 = candidateFiles.get(symbol2.fileId) ?? lookup2.findFile(symbol2.path);
170945
171163
  if (!file2) continue;
170946
171164
  candidateFiles.set(file2.id, file2);
@@ -171668,8 +171886,8 @@ function taskTokens(task) {
171668
171886
  return normalizedTokens(task);
171669
171887
  }
171670
171888
  function scoreClaim(claim, tokens) {
171671
- const text = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
171672
- const words = normalizedTokens(text);
171889
+ const text2 = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
171890
+ const words = normalizedTokens(text2);
171673
171891
  let matches = 0;
171674
171892
  for (const token of tokens) {
171675
171893
  if (words.has(token)) matches += 1;
@@ -176102,6 +176320,128 @@ var init_workflow_store = __esm({
176102
176320
  }
176103
176321
  });
176104
176322
 
176323
+ // src/knowledge/outcome-types.ts
176324
+ function qualityFromOutcome(signal) {
176325
+ if (!signal) return void 0;
176326
+ if (signal.kind === "verification-failed" || signal.kind === "user-correction" || signal.kind === "source-changed" || signal.kind === "conflict-confirmed") {
176327
+ return "degraded";
176328
+ }
176329
+ if (signal.kind === "verification-passed" || signal.kind === "verified-reuse" || signal.kind === "user-pin") {
176330
+ return "verified";
176331
+ }
176332
+ return void 0;
176333
+ }
176334
+ var MEMORY_OUTCOME_CANDIDATE_KINDS, MEMORY_OUTCOME_SIGNAL_KINDS;
176335
+ var init_outcome_types = __esm({
176336
+ "src/knowledge/outcome-types.ts"() {
176337
+ "use strict";
176338
+ init_esm_shims();
176339
+ MEMORY_OUTCOME_CANDIDATE_KINDS = ["claim", "durable-memory", "workflow"];
176340
+ MEMORY_OUTCOME_SIGNAL_KINDS = [
176341
+ "verification-passed",
176342
+ "verification-failed",
176343
+ "verified-reuse",
176344
+ "user-pin",
176345
+ "user-correction",
176346
+ "source-changed",
176347
+ "conflict-confirmed",
176348
+ "manual-review"
176349
+ ];
176350
+ }
176351
+ });
176352
+
176353
+ // src/knowledge/outcome-store.ts
176354
+ import { randomUUID as randomUUID10 } from "crypto";
176355
+ function optionalText4(value) {
176356
+ return typeof value === "string" && value.trim() ? value : void 0;
176357
+ }
176358
+ function text(value, field, max = 1e3) {
176359
+ const safe = sanitizeCredentials(value).replace(/\s+/g, " ").trim();
176360
+ if (!safe) throw new Error("Outcome signal " + field + " is required.");
176361
+ if (safe.length > max) throw new Error("Outcome signal " + field + " is too long.");
176362
+ return safe;
176363
+ }
176364
+ function oneOf(value, values, field) {
176365
+ if (typeof value !== "string" || !values.includes(value)) {
176366
+ throw new Error("Outcome signal " + field + " is invalid.");
176367
+ }
176368
+ return value;
176369
+ }
176370
+ function rowToSignal(row) {
176371
+ return {
176372
+ id: row.id,
176373
+ projectId: row.projectId,
176374
+ candidateKind: row.candidateKind,
176375
+ candidateId: row.candidateId,
176376
+ kind: row.kind,
176377
+ sourceRef: row.sourceRef,
176378
+ ...optionalText4(row.snapshotId) ? { snapshotId: row.snapshotId } : {},
176379
+ ...optionalText4(row.detail) ? { detail: row.detail } : {},
176380
+ observedAt: row.observedAt
176381
+ };
176382
+ }
176383
+ var OutcomeStore;
176384
+ var init_outcome_store = __esm({
176385
+ "src/knowledge/outcome-store.ts"() {
176386
+ "use strict";
176387
+ init_esm_shims();
176388
+ init_secret_filter();
176389
+ init_sqlite_db();
176390
+ init_outcome_types();
176391
+ OutcomeStore = class {
176392
+ db = null;
176393
+ async init(dataDir) {
176394
+ this.db = getDatabase(dataDir);
176395
+ }
176396
+ record(input) {
176397
+ const signal = {
176398
+ id: randomUUID10(),
176399
+ projectId: text(input.projectId, "project id"),
176400
+ candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
176401
+ candidateId: text(input.candidateId, "candidate id"),
176402
+ kind: oneOf(input.kind, MEMORY_OUTCOME_SIGNAL_KINDS, "kind"),
176403
+ sourceRef: text(input.sourceRef, "source reference"),
176404
+ ...input.snapshotId ? { snapshotId: text(input.snapshotId, "snapshot id") } : {},
176405
+ ...input.detail ? { detail: text(input.detail, "detail") } : {},
176406
+ observedAt: input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString()
176407
+ };
176408
+ this.db.prepare(`
176409
+ INSERT INTO memory_outcome_signals (
176410
+ id, projectId, candidateKind, candidateId, kind, sourceRef, snapshotId, detail, observedAt
176411
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
176412
+ `).run(
176413
+ signal.id,
176414
+ signal.projectId,
176415
+ signal.candidateKind,
176416
+ signal.candidateId,
176417
+ signal.kind,
176418
+ signal.sourceRef,
176419
+ signal.snapshotId ?? null,
176420
+ signal.detail ?? null,
176421
+ signal.observedAt
176422
+ );
176423
+ return signal;
176424
+ }
176425
+ latestForCandidates(projectId, candidateKind, candidateIds) {
176426
+ const ids = [...new Set(candidateIds.filter(Boolean))];
176427
+ if (ids.length === 0) return /* @__PURE__ */ new Map();
176428
+ const placeholders = ids.map(() => "?").join(", ");
176429
+ const rows = this.db.prepare(`
176430
+ SELECT * FROM memory_outcome_signals
176431
+ WHERE projectId = ? AND candidateKind = ? AND candidateId IN (${placeholders})
176432
+ ORDER BY observedAt DESC, id DESC
176433
+ `).all(projectId, candidateKind, ...ids);
176434
+ const latest = /* @__PURE__ */ new Map();
176435
+ for (const row of rows) {
176436
+ const signal = rowToSignal(row);
176437
+ if (!latest.has(signal.candidateId)) latest.set(signal.candidateId, signal);
176438
+ }
176439
+ return latest;
176440
+ }
176441
+ };
176442
+ }
176443
+ });
176444
+
176105
176445
  // src/codegraph/task-lens.ts
176106
176446
  var task_lens_exports = {};
176107
176447
  __export(task_lens_exports, {
@@ -176118,31 +176458,31 @@ __export(task_lens_exports, {
176118
176458
  function normalizePath2(path46) {
176119
176459
  return path46.replace(/\\/g, "/");
176120
176460
  }
176121
- function tokenize4(text) {
176122
- return (text.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1 && !STOP_WORDS.has(token));
176461
+ function tokenize4(text2) {
176462
+ return (text2.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1 && !STOP_WORDS.has(token));
176123
176463
  }
176124
- function containsTaskKeyword(text, keyword) {
176464
+ function containsTaskKeyword(text2, keyword) {
176125
176465
  const matcher = /^[a-z0-9_-]+$/i.test(keyword) ? new RegExp(`(^|[^a-z0-9_-])${keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?=[^a-z0-9_-]|$)`, "gi") : new RegExp(keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
176126
176466
  let match2;
176127
- while ((match2 = matcher.exec(text)) !== null) {
176467
+ while ((match2 = matcher.exec(text2)) !== null) {
176128
176468
  const keywordIndex = match2.index + (match2[1]?.length ?? 0);
176129
- if (!isNegatedTaskKeyword(text, keywordIndex)) return true;
176469
+ if (!isNegatedTaskKeyword(text2, keywordIndex)) return true;
176130
176470
  }
176131
176471
  return false;
176132
176472
  }
176133
- function isNegatedTaskKeyword(text, keywordIndex) {
176473
+ function isNegatedTaskKeyword(text2, keywordIndex) {
176134
176474
  const boundary = Math.max(
176135
- text.lastIndexOf(".", keywordIndex - 1),
176136
- text.lastIndexOf("!", keywordIndex - 1),
176137
- text.lastIndexOf("?", keywordIndex - 1),
176138
- text.lastIndexOf(";", keywordIndex - 1),
176139
- text.lastIndexOf("\n", keywordIndex - 1),
176140
- text.lastIndexOf("\u3002", keywordIndex - 1),
176141
- text.lastIndexOf("\uFF01", keywordIndex - 1),
176142
- text.lastIndexOf("\uFF1F", keywordIndex - 1),
176143
- text.lastIndexOf("\uFF1B", keywordIndex - 1)
176475
+ text2.lastIndexOf(".", keywordIndex - 1),
176476
+ text2.lastIndexOf("!", keywordIndex - 1),
176477
+ text2.lastIndexOf("?", keywordIndex - 1),
176478
+ text2.lastIndexOf(";", keywordIndex - 1),
176479
+ text2.lastIndexOf("\n", keywordIndex - 1),
176480
+ text2.lastIndexOf("\u3002", keywordIndex - 1),
176481
+ text2.lastIndexOf("\uFF01", keywordIndex - 1),
176482
+ text2.lastIndexOf("\uFF1F", keywordIndex - 1),
176483
+ text2.lastIndexOf("\uFF1B", keywordIndex - 1)
176144
176484
  );
176145
- let prefix = text.slice(boundary + 1, keywordIndex).toLowerCase();
176485
+ let prefix = text2.slice(boundary + 1, keywordIndex).toLowerCase();
176146
176486
  const contrast = /(?:,|\uff0c)\s*(?:but|however|instead|yet|\u4f46\u662f|\u4f46|\u800c\u662f)\s*/gi;
176147
176487
  let contrastMatch;
176148
176488
  let contrastEnd = -1;
@@ -176165,9 +176505,9 @@ function resolveTaskLens(task) {
176165
176505
  };
176166
176506
  for (const id of LENS_PRIORITY) {
176167
176507
  const score = KEYWORDS[id].reduce((sum, keyword) => sum + (containsTaskKeyword(normalized, keyword) ? 1 : 0), 0);
176168
- const priority = LENS_PRIORITY.indexOf(id);
176169
- if (score > best.score || score === best.score && score > 0 && priority < best.priority) {
176170
- best = { id, score, priority };
176508
+ const priority2 = LENS_PRIORITY.indexOf(id);
176509
+ if (score > best.score || score === best.score && score > 0 && priority2 < best.priority) {
176510
+ best = { id, score, priority: priority2 };
176171
176511
  }
176172
176512
  }
176173
176513
  return best.score > 0 ? LENSES[best.id] : LENSES.general;
@@ -176209,20 +176549,20 @@ function pathKindScore(path46, lens) {
176209
176549
  return 0;
176210
176550
  }
176211
176551
  }
176212
- function tokenScore(text, tokens) {
176552
+ function tokenScore(text2, tokens) {
176213
176553
  if (tokens.length === 0) return 0;
176214
- const normalized = text.toLowerCase();
176554
+ const normalized = text2.toLowerCase();
176215
176555
  return tokens.reduce((sum, token) => sum + (normalized.includes(token) ? 12 : 0), 0);
176216
176556
  }
176217
176557
  function sourceTaskMatchScore(source, task) {
176218
176558
  const tokens = tokenize4(task ?? "");
176219
176559
  if (tokens.length === 0) return 0;
176220
- const text = [
176560
+ const text2 = [
176221
176561
  source.title,
176222
176562
  source.path ?? "",
176223
176563
  source.symbol ?? ""
176224
176564
  ].join("\n").toLowerCase();
176225
- const matches = tokens.filter((token) => text.includes(token)).length;
176565
+ const matches = tokens.filter((token) => text2.includes(token)).length;
176226
176566
  if (matches >= 2) return 40;
176227
176567
  if (matches === 1) return 24;
176228
176568
  return 0;
@@ -176261,8 +176601,8 @@ function lensPathCandidates(lens) {
176261
176601
  }
176262
176602
  function scoreLensSource(source, lens, task) {
176263
176603
  const tokens = tokenize4(task ?? "");
176264
- const text = [source.title, source.type, source.path ?? "", source.symbol ?? ""].join("\n");
176265
- return pathKindScore(source.path ?? "", lens) + tokenScore(text, tokens) + sourceTaskMatchScore(source, task);
176604
+ const text2 = [source.title, source.type, source.path ?? "", source.symbol ?? ""].join("\n");
176605
+ return pathKindScore(source.path ?? "", lens) + tokenScore(text2, tokens) + sourceTaskMatchScore(source, task);
176266
176606
  }
176267
176607
  function rankLensSources(sources, lens, task) {
176268
176608
  return [...sources].map((source, index) => ({
@@ -176504,7 +176844,7 @@ function requiredText(data, key) {
176504
176844
  }
176505
176845
  return value.trim();
176506
176846
  }
176507
- function optionalText4(data, key) {
176847
+ function optionalText5(data, key) {
176508
176848
  const value = data[key];
176509
176849
  if (value === void 0 || value === null || value === "") return void 0;
176510
176850
  if (typeof value !== "string") throw new Error("workflow frontmatter field " + key + " must be text");
@@ -176547,11 +176887,11 @@ function phaseFromValue(value, index) {
176547
176887
  }
176548
176888
  const data = value;
176549
176889
  const title = requiredText(data, "title");
176550
- const phaseId = optionalText4(data, "id") ?? slug(title) + "-" + (index + 1);
176890
+ const phaseId = optionalText5(data, "id") ?? slug(title) + "-" + (index + 1);
176551
176891
  return {
176552
176892
  id: phaseId,
176553
176893
  title,
176554
- instructions: optionalText4(data, "instructions") ?? "",
176894
+ instructions: optionalText5(data, "instructions") ?? "",
176555
176895
  branches: optionalStringArray(data, "branches"),
176556
176896
  expectedOutputs: optionalStringArray(data, "expectedOutputs"),
176557
176897
  verificationGates: optionalStringArray(data, "verificationGates")
@@ -176660,7 +177000,7 @@ function parsedWorkflow(data, body, input) {
176660
177000
  id: requiredText(data, "id"),
176661
177001
  workspaceId: input.workspaceId,
176662
177002
  title: requiredText(data, "title"),
176663
- description: optionalText4(data, "description") ?? "",
177003
+ description: optionalText5(data, "description") ?? "",
176664
177004
  status: optionalStatus(data),
176665
177005
  version: optionalNumber(data, "version", 1),
176666
177006
  taskLenses: optionalStringArray(data, "taskLenses"),
@@ -176679,9 +177019,9 @@ function parsedWorkflow(data, body, input) {
176679
177019
  sourcePath: normalizeSourcePath(input.sourcePath),
176680
177020
  sourceHash: "",
176681
177021
  contentHash: input.contentHash,
176682
- createdAt: optionalText4(data, "createdAt") ?? now2(),
176683
- updatedAt: optionalText4(data, "updatedAt") ?? now2(),
176684
- ...optionalText4(data, "importedFrom") ? { importedFrom: optionalText4(data, "importedFrom") } : {}
177022
+ createdAt: optionalText5(data, "createdAt") ?? now2(),
177023
+ updatedAt: optionalText5(data, "updatedAt") ?? now2(),
177024
+ ...optionalText5(data, "importedFrom") ? { importedFrom: optionalText5(data, "importedFrom") } : {}
176685
177025
  };
176686
177026
  if (candidate2.phases.length === 0) {
176687
177027
  throw new Error("workflow must contain at least one phase or a non-empty body");
@@ -176780,11 +177120,11 @@ async function syncCanonicalWorkflows(workspace) {
176780
177120
  return { workflows, errors: errors2 };
176781
177121
  }
176782
177122
  function inferTaskLenses(value) {
176783
- const text = value.toLowerCase();
176784
- return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text.includes(term))).map(([lens]) => lens);
177123
+ const text2 = value.toLowerCase();
177124
+ return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text2.includes(term))).map(([lens]) => lens);
176785
177125
  }
176786
177126
  function taskScore(workflow, task) {
176787
- const text = task.toLowerCase();
177127
+ const text2 = task.toLowerCase();
176788
177128
  let score = 0;
176789
177129
  const reasons = [];
176790
177130
  const matchedLenses = /* @__PURE__ */ new Set();
@@ -177051,7 +177391,31 @@ async function recordWorkflowRun(input) {
177051
177391
  throw new Error("Workflow was not found for this workspace");
177052
177392
  }
177053
177393
  if (!input.run.task.trim()) throw new Error("Workflow run task is required");
177054
- return store2.recordRun(input.run);
177394
+ const run = store2.recordRun(input.run);
177395
+ const kind = run.outcome === "passed" && run.verificationVerdict === "passed" ? "verification-passed" : run.outcome === "failed" || run.verificationVerdict === "failed" ? "verification-failed" : void 0;
177396
+ if (!kind) return run;
177397
+ const evidence = /* @__PURE__ */ new Map();
177398
+ evidence.set(workflow.id, "workflow");
177399
+ for (const reference of run.selectedEvidence) {
177400
+ const match2 = /^(claim|durable):(.+)$/.exec(reference);
177401
+ if (!match2) continue;
177402
+ evidence.set(match2[2], match2[1] === "claim" ? "claim" : "durable-memory");
177403
+ }
177404
+ const outcomes = new OutcomeStore();
177405
+ await outcomes.init(workflowStoreDataDir(input.workspace));
177406
+ for (const [candidateId, candidateKind] of evidence) {
177407
+ outcomes.record({
177408
+ projectId: run.projectId,
177409
+ candidateKind,
177410
+ candidateId,
177411
+ kind,
177412
+ sourceRef: "workflow-run:" + run.id,
177413
+ ...run.startingSnapshotId ? { snapshotId: run.startingSnapshotId } : {},
177414
+ ...run.failureReason ? { detail: run.failureReason } : {},
177415
+ observedAt: run.completedAt ?? run.startedAt
177416
+ });
177417
+ }
177418
+ return run;
177055
177419
  }
177056
177420
  async function selectWorkspaceWorkflows(input) {
177057
177421
  const synced = await syncCanonicalWorkflows(input.workspace);
@@ -177077,6 +177441,7 @@ var init_workflows2 = __esm({
177077
177441
  init_workflow_sync();
177078
177442
  init_workspace();
177079
177443
  init_workflow_store();
177444
+ init_outcome_store();
177080
177445
  init_task_lens();
177081
177446
  KNOWN_AGENTS = [
177082
177447
  "windsurf",
@@ -178970,10 +179335,10 @@ function isEmbeddingEnabled() {
178970
179335
  function getVectorDimensions() {
178971
179336
  return embeddingEnabled ? embeddingDimensions : null;
178972
179337
  }
178973
- async function generateEmbedding(text) {
179338
+ async function generateEmbedding(text2) {
178974
179339
  const provider2 = await getEmbeddingProvider();
178975
179340
  if (!provider2) return null;
178976
- return provider2.embedInput ? provider2.embedInput({ modality: "text", text }, { intent: "document" }) : provider2.embed(text);
179341
+ return provider2.embedInput ? provider2.embedInput({ modality: "text", text: text2 }, { intent: "document" }) : provider2.embed(text2);
178977
179342
  }
178978
179343
  async function generateEmbeddingInput(input, options2 = {}) {
178979
179344
  const provider2 = await getEmbeddingProvider();
@@ -180420,7 +180785,7 @@ __export(team_store_exports, {
180420
180785
  isTeamStoreInitialized: () => isTeamStoreInitialized,
180421
180786
  resetTeamStore: () => resetTeamStore
180422
180787
  });
180423
- import { randomUUID as randomUUID10 } from "crypto";
180788
+ import { randomUUID as randomUUID11 } from "crypto";
180424
180789
  import path21 from "path";
180425
180790
  import fs14 from "fs";
180426
180791
  function getTeamStore() {
@@ -180709,7 +181074,7 @@ var init_team_store = __esm({
180709
181074
  * reactivate it (preserving agent_id). Otherwise create a new one.
180710
181075
  */
180711
181076
  registerAgent(input) {
180712
- const instanceId = input.instanceId || randomUUID10();
181077
+ const instanceId = input.instanceId || randomUUID11();
180713
181078
  const now3 = Date.now();
180714
181079
  const existing = this.stmtAgentFindByInstance.get(
180715
181080
  input.projectId,
@@ -180735,7 +181100,7 @@ var init_team_store = __esm({
180735
181100
  this.eventBus?.emit("agent:joined", { agentId: row2.agent_id, projectId: input.projectId, agentType: input.agentType });
180736
181101
  return row2;
180737
181102
  }
180738
- const agentId = randomUUID10();
181103
+ const agentId = randomUUID11();
180739
181104
  this.stmtAgentUpsert.run({
180740
181105
  agent_id: agentId,
180741
181106
  project_id: input.projectId,
@@ -180837,7 +181202,7 @@ var init_team_store = __esm({
180837
181202
  return { error: `Recipient agent '${input.recipientAgentId}' not found \u2014 cannot send to unknown agent` };
180838
181203
  }
180839
181204
  }
180840
- const id = randomUUID10();
181205
+ const id = randomUUID11();
180841
181206
  const now3 = Date.now();
180842
181207
  const row = {
180843
181208
  id,
@@ -180887,7 +181252,7 @@ var init_team_store = __esm({
180887
181252
  // Task Operations (with atomic claim semantics)
180888
181253
  // ═══════════════════════════════════════════════════════════════════
180889
181254
  createTask(input) {
180890
- const taskId = randomUUID10();
181255
+ const taskId = randomUUID11();
180891
181256
  const now3 = Date.now();
180892
181257
  const row = {
180893
181258
  task_id: taskId,
@@ -181159,7 +181524,7 @@ var init_team_store = __esm({
181159
181524
  for (const [agentId, msgs] of Object.entries(snap.messages.inboxes)) {
181160
181525
  for (const msg of msgs) {
181161
181526
  this.stmtMsgInsert.run({
181162
- id: msg.id ?? randomUUID10(),
181527
+ id: msg.id ?? randomUUID11(),
181163
181528
  project_id: "migrated",
181164
181529
  sender_agent_id: msg.from ?? "unknown",
181165
181530
  recipient_agent_id: msg.to === "__broadcast__" ? null : msg.to ?? agentId,
@@ -181521,9 +181886,9 @@ __export(chat_service_exports, {
181521
181886
  askMemoryQuestion: () => askMemoryQuestion,
181522
181887
  askMemoryQuestionStream: () => askMemoryQuestionStream
181523
181888
  });
181524
- function truncate(text, max) {
181525
- if (text.length <= max) return text;
181526
- return `${text.slice(0, max - 1)}\u2026`;
181889
+ function truncate(text2, max) {
181890
+ if (text2.length <= max) return text2;
181891
+ return `${text2.slice(0, max - 1)}\u2026`;
181527
181892
  }
181528
181893
  function buildExcerpt(doc) {
181529
181894
  const combined = [doc.narrative, doc.facts].filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
@@ -182328,7 +182693,7 @@ function evidenceScore2(obs) {
182328
182693
  }
182329
182694
  function scoreForPacket(obs, queryTokens, referenceTime, broadMemoryQuery) {
182330
182695
  let score = 0;
182331
- const text = normalizeText3([
182696
+ const text2 = normalizeText3([
182332
182697
  obs.title,
182333
182698
  obs.narrative,
182334
182699
  obs.entityName,
@@ -182337,15 +182702,15 @@ function scoreForPacket(obs, queryTokens, referenceTime, broadMemoryQuery) {
182337
182702
  ...obs.relatedEntities ?? [],
182338
182703
  ...obs.relatedCommits ?? []
182339
182704
  ].join(" "));
182340
- const matchingTokens = queryTokens.filter((token) => text.includes(token));
182705
+ const matchingTokens = queryTokens.filter((token) => text2.includes(token));
182341
182706
  score += matchingTokens.length * 4;
182342
182707
  if (queryTokens.length > 0 && matchingTokens.length === 0) {
182343
182708
  score -= 8;
182344
182709
  }
182345
- if (broadMemoryQuery && /memorix|memcode|memory-(?:graph|injection|runtime|quality|formation)|graph-context/.test(text)) {
182710
+ if (broadMemoryQuery && /memorix|memcode|memory-(?:graph|injection|runtime|quality|formation)|graph-context/.test(text2)) {
182346
182711
  score += 8;
182347
182712
  }
182348
- if (/\bmemory[- ]?game\b|e2e-test\/memory-game|team-handoff/.test(text)) {
182713
+ if (/\bmemory[- ]?game\b|e2e-test\/memory-game|team-handoff/.test(text2)) {
182349
182714
  score -= broadMemoryQuery ? 12 : 4;
182350
182715
  }
182351
182716
  score += obs.valueCategory === "core" ? 6 : 0;
@@ -182813,8 +183178,8 @@ async function getCliProjectContext(options2) {
182813
183178
  ...identity.warning ? { identityWarning: identity.warning } : {}
182814
183179
  };
182815
183180
  }
182816
- function emitResult(data, text, asJson) {
182817
- console.log(asJson ? JSON.stringify(data, null, 2) : text);
183181
+ function emitResult(data, text2, asJson) {
183182
+ console.log(asJson ? JSON.stringify(data, null, 2) : text2);
182818
183183
  }
182819
183184
  function emitError(message, asJson) {
182820
183185
  console.error(asJson ? JSON.stringify({ error: message }, null, 2) : `Error: ${message}`);
@@ -182942,7 +183307,7 @@ var owner_exports = {};
182942
183307
  __export(owner_exports, {
182943
183308
  resolveLocalMemoryOwner: () => resolveLocalMemoryOwner
182944
183309
  });
182945
- import { randomUUID as randomUUID11 } from "crypto";
183310
+ import { randomUUID as randomUUID12 } from "crypto";
182946
183311
  import { promises as fs17 } from "fs";
182947
183312
  import path24 from "path";
182948
183313
  function ownerPath(dataDir) {
@@ -182972,7 +183337,7 @@ async function resolveLocalMemoryOwner(dataDir, options2 = {}) {
182972
183337
  await fs17.mkdir(path24.dirname(filePath), { recursive: true });
182973
183338
  const created = {
182974
183339
  version: 1,
182975
- id: "local-" + randomUUID11(),
183340
+ id: "local-" + randomUUID12(),
182976
183341
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
182977
183342
  };
182978
183343
  try {
@@ -182995,8 +183360,8 @@ var init_owner = __esm({
182995
183360
  });
182996
183361
 
182997
183362
  // src/memory/long-term-store.ts
182998
- import { randomUUID as randomUUID12 } from "crypto";
182999
- function optionalText5(value) {
183363
+ import { randomUUID as randomUUID13 } from "crypto";
183364
+ function optionalText6(value) {
183000
183365
  return typeof value === "string" && value.trim() ? value : void 0;
183001
183366
  }
183002
183367
  function arrayValue2(value) {
@@ -183021,17 +183386,17 @@ function rowToMemory(row) {
183021
183386
  content: row.content,
183022
183387
  facts: arrayValue2(row.factsJson),
183023
183388
  tags: arrayValue2(row.tagsJson),
183024
- ...optionalText5(row.applicability) ? { applicability: row.applicability } : {},
183389
+ ...optionalText6(row.applicability) ? { applicability: row.applicability } : {},
183025
183390
  origin: row.origin,
183026
183391
  createdAt: row.createdAt,
183027
183392
  updatedAt: row.updatedAt,
183028
- ...optionalText5(row.qualifiedAt) ? { qualifiedAt: row.qualifiedAt } : {},
183029
- ...optionalText5(row.approvedAt) ? { approvedAt: row.approvedAt } : {},
183030
- ...optionalText5(row.archivedAt) ? { archivedAt: row.archivedAt } : {},
183031
- ...optionalText5(row.supersededBy) ? { supersededBy: row.supersededBy } : {},
183032
- ...optionalText5(row.lastValidatedAt) ? { lastValidatedAt: row.lastValidatedAt } : {},
183393
+ ...optionalText6(row.qualifiedAt) ? { qualifiedAt: row.qualifiedAt } : {},
183394
+ ...optionalText6(row.approvedAt) ? { approvedAt: row.approvedAt } : {},
183395
+ ...optionalText6(row.archivedAt) ? { archivedAt: row.archivedAt } : {},
183396
+ ...optionalText6(row.supersededBy) ? { supersededBy: row.supersededBy } : {},
183397
+ ...optionalText6(row.lastValidatedAt) ? { lastValidatedAt: row.lastValidatedAt } : {},
183033
183398
  accessCount: Number(row.accessCount ?? 0),
183034
- ...optionalText5(row.lastAccessedAt) ? { lastAccessedAt: row.lastAccessedAt } : {}
183399
+ ...optionalText6(row.lastAccessedAt) ? { lastAccessedAt: row.lastAccessedAt } : {}
183035
183400
  };
183036
183401
  }
183037
183402
  function rowToEvidence2(row) {
@@ -183041,8 +183406,8 @@ function rowToEvidence2(row) {
183041
183406
  kind: row.kind,
183042
183407
  referenceId: row.referenceId,
183043
183408
  relation: row.relation,
183044
- ...optionalText5(row.locator) ? { locator: row.locator } : {},
183045
- ...optionalText5(row.capturedHash) ? { capturedHash: row.capturedHash } : {},
183409
+ ...optionalText6(row.locator) ? { locator: row.locator } : {},
183410
+ ...optionalText6(row.capturedHash) ? { capturedHash: row.capturedHash } : {},
183046
183411
  createdAt: row.createdAt
183047
183412
  };
183048
183413
  }
@@ -183051,9 +183416,9 @@ function rowToEvent2(row) {
183051
183416
  id: row.id,
183052
183417
  memoryId: row.memoryId,
183053
183418
  kind: row.kind,
183054
- ...optionalText5(row.fromState) ? { fromState: row.fromState } : {},
183055
- ...optionalText5(row.toState) ? { toState: row.toState } : {},
183056
- ...optionalText5(row.detail) ? { detail: row.detail } : {},
183419
+ ...optionalText6(row.fromState) ? { fromState: row.fromState } : {},
183420
+ ...optionalText6(row.toState) ? { toState: row.toState } : {},
183421
+ ...optionalText6(row.detail) ? { detail: row.detail } : {},
183057
183422
  createdAt: row.createdAt
183058
183423
  };
183059
183424
  }
@@ -183155,7 +183520,7 @@ var init_long_term_store = __esm({
183155
183520
  }
183156
183521
  insertEvidence(input) {
183157
183522
  const evidence = {
183158
- id: randomUUID12(),
183523
+ id: randomUUID13(),
183159
183524
  ...input,
183160
183525
  createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
183161
183526
  };
@@ -183182,7 +183547,7 @@ var init_long_term_store = __esm({
183182
183547
  }
183183
183548
  recordEvent(input) {
183184
183549
  const event = {
183185
- id: randomUUID12(),
183550
+ id: randomUUID13(),
183186
183551
  ...input,
183187
183552
  createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
183188
183553
  };
@@ -183270,7 +183635,7 @@ __export(long_term_exports, {
183270
183635
  selectLongTermMemoriesForTask: () => selectLongTermMemoriesForTask,
183271
183636
  supersedeLongTermMemory: () => supersedeLongTermMemory
183272
183637
  });
183273
- import { randomUUID as randomUUID13 } from "crypto";
183638
+ import { randomUUID as randomUUID14 } from "crypto";
183274
183639
  function isOneOf(value, values) {
183275
183640
  return typeof value === "string" && values.includes(value);
183276
183641
  }
@@ -183452,7 +183817,7 @@ async function createManualLongTermMemory(input) {
183452
183817
  const owner = await resolveLocalMemoryOwner(input.dataDir, { create: true });
183453
183818
  if (!owner) throw new Error("Memorix could not resolve a local memory owner.");
183454
183819
  assertScope(input.scope);
183455
- const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" + randomUUID13(), relation: "supports" }];
183820
+ const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" + randomUUID14(), relation: "supports" }];
183456
183821
  return createLongTermMemoryWithDataDir({
183457
183822
  dataDir: input.dataDir,
183458
183823
  originProjectId: input.projectId,
@@ -183507,7 +183872,7 @@ async function createLongTermMemoryWithDataDir(input) {
183507
183872
  assertPortableEvidence(input.scope, portability, evidenceInputs);
183508
183873
  const now3 = (/* @__PURE__ */ new Date()).toISOString();
183509
183874
  const memory = {
183510
- id: randomUUID13(),
183875
+ id: randomUUID14(),
183511
183876
  originProjectId: compactText2(input.originProjectId, "origin project id", 1e3),
183512
183877
  ownerId: compactText2(input.ownerId, "owner id", 160),
183513
183878
  scope: input.scope,
@@ -188960,12 +189325,99 @@ var init_integrate = __esm({
188960
189325
  }
188961
189326
  });
188962
189327
 
189328
+ // src/knowledge/governor.ts
189329
+ function clampRelevance(value) {
189330
+ if (!Number.isFinite(value)) return 0;
189331
+ return Math.max(0, Math.min(1, value));
189332
+ }
189333
+ function classify(candidate2) {
189334
+ const freshness = candidate2.freshness ?? "unknown";
189335
+ const trust = candidate2.trust ?? "historical";
189336
+ const quality = candidate2.quality ?? "probationary";
189337
+ const conflict = candidate2.conflict ?? "none";
189338
+ if (!candidate2.scopeAllowed) {
189339
+ return { disposition: "exclude", reasons: ["scope-forbidden"] };
189340
+ }
189341
+ if (conflict === "confirmed") {
189342
+ return { disposition: "exclude", reasons: ["confirmed-conflict"] };
189343
+ }
189344
+ if (quality === "blocked") {
189345
+ return { disposition: "exclude", reasons: ["blocked-quality"] };
189346
+ }
189347
+ if (quality === "degraded") {
189348
+ return { disposition: "defer", reasons: ["degraded-quality"] };
189349
+ }
189350
+ if (freshness === "stale") {
189351
+ return { disposition: "defer", reasons: ["stale-evidence"] };
189352
+ }
189353
+ const reasons = [];
189354
+ let disposition = "include";
189355
+ if (freshness === "unknown") {
189356
+ disposition = "compact";
189357
+ reasons.push("unknown-freshness");
189358
+ }
189359
+ if (conflict === "possible") {
189360
+ disposition = "compact";
189361
+ reasons.push("possible-conflict");
189362
+ }
189363
+ if (quality === "probationary") {
189364
+ disposition = "compact";
189365
+ reasons.push("probationary-evidence");
189366
+ }
189367
+ if (disposition === "include" && freshness === "current" && trust === "source-backed") {
189368
+ reasons.push("current-source-backed-evidence");
189369
+ } else if (reasons.length === 0) {
189370
+ reasons.push("relevant-evidence");
189371
+ }
189372
+ return { disposition, reasons };
189373
+ }
189374
+ function priority(decision) {
189375
+ const dispositionWeight = {
189376
+ include: 3,
189377
+ compact: 2,
189378
+ defer: 1,
189379
+ exclude: 0
189380
+ };
189381
+ const evidence = Math.min(3, decision.candidate.evidenceCount ?? 0) / 10;
189382
+ return dispositionWeight[decision.disposition] + clampRelevance(decision.candidate.relevance) + evidence;
189383
+ }
189384
+ function governContextCandidates(candidates, maxTokens) {
189385
+ const safeBudget = Math.max(0, Math.floor(maxTokens));
189386
+ const decisions = candidates.map((candidate2) => ({ candidate: candidate2, ...classify(candidate2) }));
189387
+ const eligible = decisions.filter((decision) => decision.disposition === "include" || decision.disposition === "compact").sort((left, right) => priority(right) - priority(left));
189388
+ let usedTokens = 0;
189389
+ for (const decision of eligible) {
189390
+ const tokens = Math.max(0, Math.ceil(decision.candidate.estimatedTokens));
189391
+ if (usedTokens + tokens <= safeBudget) {
189392
+ usedTokens += tokens;
189393
+ continue;
189394
+ }
189395
+ decision.disposition = "defer";
189396
+ decision.reasons = [...decision.reasons, "token-budget"];
189397
+ }
189398
+ const delivered = decisions.filter((decision) => decision.disposition === "include" || decision.disposition === "compact");
189399
+ const mode = delivered.length === 0 ? "abstain" : delivered.some((decision) => decision.disposition === "include") ? "workset" : "card";
189400
+ const cautions = [...new Set(decisions.filter((decision) => decision.disposition !== "include").flatMap((decision) => decision.reasons))];
189401
+ return {
189402
+ mode,
189403
+ budget: { maxTokens: safeBudget, usedTokens },
189404
+ decisions,
189405
+ cautions: cautions.length > 0 ? cautions : ["no-qualified-evidence"]
189406
+ };
189407
+ }
189408
+ var init_governor = __esm({
189409
+ "src/knowledge/governor.ts"() {
189410
+ "use strict";
189411
+ init_esm_shims();
189412
+ }
189413
+ });
189414
+
188963
189415
  // src/knowledge/workset.ts
188964
189416
  function unique(values) {
188965
189417
  return [...new Set(values.filter(Boolean))];
188966
189418
  }
188967
- function short(text, budget = 28) {
188968
- const safe = sanitizeCredentials(text).replace(/\s+/g, " ").trim();
189419
+ function short(text2, budget = 28) {
189420
+ const safe = sanitizeCredentials(text2).replace(/\s+/g, " ").trim();
188969
189421
  return countTextTokens(safe) <= budget ? safe : truncateToTokenBudget(safe, budget);
188970
189422
  }
188971
189423
  function claimAssertion(claim) {
@@ -189096,6 +189548,65 @@ function receiptOmissions(omitted, hiddenCautionMemoryCount) {
189096
189548
  function scheduledActions(cautions) {
189097
189549
  return cautions.filter((caution) => caution.kind === "codegraph-refresh-queued").map((caution) => short(caution.message, 28));
189098
189550
  }
189551
+ function isGovernedDelivery(disposition) {
189552
+ return disposition === "include" || disposition === "compact";
189553
+ }
189554
+ function governOptionalArtifacts(input) {
189555
+ const candidates = [
189556
+ ...input.reliableMemory.map((memory, index) => ({
189557
+ kind: "memory",
189558
+ id: "memory:" + memory.id,
189559
+ estimatedTokens: 10,
189560
+ relevance: Math.max(0.2, 0.9 - index * 0.1),
189561
+ scopeAllowed: true,
189562
+ freshness: freshnessForMemory(memory.status),
189563
+ trust: "historical",
189564
+ quality: memory.status === "current" ? "verified" : "degraded"
189565
+ })),
189566
+ ...input.claims.map((claim, index) => ({
189567
+ kind: "claim",
189568
+ id: "claim:" + claim.id,
189569
+ estimatedTokens: 12,
189570
+ relevance: Math.max(0.2, 0.95 - index * 0.1),
189571
+ scopeAllowed: true,
189572
+ freshness: claim.status === "active" ? "current" : "unknown",
189573
+ trust: "source-backed",
189574
+ quality: claim.reviewState === "approved" ? "verified" : "probationary",
189575
+ conflict: claim.status === "disputed" ? "confirmed" : "none",
189576
+ evidenceCount: claim.evidenceRefs.length
189577
+ })),
189578
+ ...input.durableMemory.map((memory, index) => ({
189579
+ kind: "durable-memory",
189580
+ id: "durable:" + memory.id,
189581
+ estimatedTokens: 14,
189582
+ relevance: Math.max(0.2, 0.8 - index * 0.1),
189583
+ scopeAllowed: true,
189584
+ freshness: memory.state === "approved" ? "current" : "unknown",
189585
+ trust: "source-backed",
189586
+ quality: memory.quality,
189587
+ evidenceCount: memory.evidenceRefs.length
189588
+ })),
189589
+ ...input.workflows.map((workflow, index) => ({
189590
+ kind: "workflow",
189591
+ id: "workflow:" + workflow.id,
189592
+ estimatedTokens: 14,
189593
+ relevance: Math.max(0.2, 0.85 - index * 0.1),
189594
+ scopeAllowed: true,
189595
+ freshness: "current",
189596
+ trust: "source-backed",
189597
+ quality: "verified"
189598
+ }))
189599
+ ];
189600
+ const plan = governContextCandidates(candidates, Number.MAX_SAFE_INTEGER);
189601
+ const permitted = new Set(plan.decisions.filter((decision) => isGovernedDelivery(decision.disposition)).map((decision) => decision.candidate.id));
189602
+ return {
189603
+ plan,
189604
+ reliableMemory: input.reliableMemory.filter((memory) => permitted.has("memory:" + memory.id)),
189605
+ claims: input.claims.filter((claim) => permitted.has("claim:" + claim.id)),
189606
+ durableMemory: input.durableMemory.filter((memory) => permitted.has("durable:" + memory.id)),
189607
+ workflows: input.workflows.filter((workflow) => permitted.has("workflow:" + workflow.id))
189608
+ };
189609
+ }
189099
189610
  function renderTaskWorksetPrompt(input) {
189100
189611
  const maxTokens = input.budget?.maxTokens ?? 180;
189101
189612
  const omitted = [];
@@ -189223,6 +189734,56 @@ function renderTaskWorksetPrompt(input) {
189223
189734
  trust: "source-backed"
189224
189735
  });
189225
189736
  }
189737
+ if (input.codeEvolution && input.codeEvolution.changes.length > 0) {
189738
+ appendLine(lines, "", maxTokens, omitted, "code-evolution-heading");
189739
+ appendLine(lines, "Code changes since prior scan", maxTokens, omitted, "code-evolution-heading");
189740
+ for (const change of input.codeEvolution.changes.slice(0, 3)) {
189741
+ appendLine(
189742
+ lines,
189743
+ "- " + change.kind + ": " + change.path,
189744
+ maxTokens,
189745
+ omitted,
189746
+ "code-evolution-change",
189747
+ selected,
189748
+ {
189749
+ kind: "code-state",
189750
+ id: "snapshot:" + input.codeEvolution.toSnapshotId,
189751
+ reason: "exact file hash change between complete CodeGraph snapshots",
189752
+ freshness: "current",
189753
+ trust: "source-backed"
189754
+ }
189755
+ );
189756
+ }
189757
+ for (const path46 of input.codeEvolution.directlyConnectedPaths.slice(0, 2)) {
189758
+ appendLine(
189759
+ lines,
189760
+ "- connected now: " + path46,
189761
+ maxTokens,
189762
+ omitted,
189763
+ "code-evolution-impact",
189764
+ selected,
189765
+ {
189766
+ kind: "code-state",
189767
+ id: "snapshot:" + input.codeEvolution.toSnapshotId,
189768
+ reason: "bounded current CodeGraph impact relation",
189769
+ freshness: "current",
189770
+ trust: "derived"
189771
+ }
189772
+ );
189773
+ }
189774
+ if ((input.codeEvolution.affectedMemoryCount ?? 0) > 0) {
189775
+ appendLine(
189776
+ lines,
189777
+ "- " + input.codeEvolution.affectedMemoryCount + " stored memory link(s) reference this changed code; reread source before relying on their conclusions.",
189778
+ maxTokens,
189779
+ omitted,
189780
+ "code-evolution-stale-memory"
189781
+ );
189782
+ }
189783
+ if (input.codeEvolution.truncated) {
189784
+ appendLine(lines, "- More connected files exist; inspect CodeGraph before assuming complete impact.", maxTokens, omitted, "code-evolution-truncated");
189785
+ }
189786
+ }
189226
189787
  if (input.semanticCode && (input.semanticCode.entryPoints.length > 0 || input.semanticCode.relations.length > 0)) {
189227
189788
  appendLine(lines, "", maxTokens, omitted, "semantic-code-heading");
189228
189789
  appendLine(lines, "Semantic code outline", maxTokens, omitted, "semantic-code-heading");
@@ -189413,6 +189974,17 @@ async function buildTaskWorkset(input) {
189413
189974
  }));
189414
189975
  let durableMemory = [];
189415
189976
  let durableEvidence = [];
189977
+ let outcomeStore;
189978
+ try {
189979
+ outcomeStore = new OutcomeStore();
189980
+ await outcomeStore.init(input.dataDir);
189981
+ } catch {
189982
+ }
189983
+ const claimQuality = outcomeStore ? outcomeStore.latestForCandidates(input.projectId, "claim", claims.map((claim) => claim.id)) : /* @__PURE__ */ new Map();
189984
+ for (const claim of claims) {
189985
+ const outcomeQuality = qualityFromOutcome(claimQuality.get(claim.id));
189986
+ if (outcomeQuality === "degraded") claim.reviewState = "needs-review";
189987
+ }
189416
189988
  if (task) {
189417
189989
  try {
189418
189990
  const selected = await selectLongTermMemoriesForTask({
@@ -189423,11 +189995,13 @@ async function buildTaskWorkset(input) {
189423
189995
  ...input.reader?.isTeamMember ? { isTeamMember: true } : {},
189424
189996
  limit: 3
189425
189997
  });
189998
+ const durableQuality = outcomeStore ? outcomeStore.latestForCandidates(input.projectId, "durable-memory", selected.map((item) => item.memory.id)) : /* @__PURE__ */ new Map();
189426
189999
  durableMemory = selected.map((item) => ({
189427
190000
  id: item.memory.id,
189428
190001
  kind: item.memory.kind,
189429
190002
  scope: item.memory.scope,
189430
190003
  state: item.memory.state,
190004
+ quality: qualityFromOutcome(durableQuality.get(item.memory.id)) ?? (item.memory.state === "approved" ? "verified" : "probationary"),
189431
190005
  title: item.memory.title,
189432
190006
  summary: renderLongTermMemorySummary(item.memory, 20),
189433
190007
  evidenceRefs: item.evidence.map((evidence) => evidence.id),
@@ -189473,18 +190047,25 @@ async function buildTaskWorkset(input) {
189473
190047
  }
189474
190048
  } catch {
189475
190049
  }
189476
- const evidenceIds = unique(selection.claims.flatMap((claim) => evidenceIdsForClaim(
189477
- claim,
189478
- evidenceByClaim.get(claim.id) ?? []
189479
- )).concat(
189480
- durableMemory.map((memory) => "durable:" + memory.id),
189481
- durableEvidence.map((evidence) => "durable-evidence:" + evidence.id)
189482
- ));
189483
190050
  const verification = unique([
189484
190051
  ...workflows.flatMap((workflow) => workflow.verificationGates),
189485
190052
  ...input.verificationHints
189486
190053
  ]).slice(0, 4);
189487
190054
  const normalizedCautions = unique(cautions.map((caution) => caution.kind)).map((kind) => cautions.find((caution) => caution.kind === kind)).slice(0, 6);
190055
+ const governed = governOptionalArtifacts({
190056
+ reliableMemory: input.reliableMemory?.slice(0, 3) ?? [],
190057
+ claims,
190058
+ durableMemory,
190059
+ workflows
190060
+ });
190061
+ const governedDurableIds = new Set(governed.durableMemory.map((memory) => memory.id));
190062
+ const evidenceIds = unique(governed.claims.flatMap((claim) => evidenceIdsForClaim(
190063
+ claim,
190064
+ evidenceByClaim.get(claim.id) ?? []
190065
+ )).concat(
190066
+ governed.durableMemory.map((memory) => "durable:" + memory.id),
190067
+ durableEvidence.filter((evidence) => governedDurableIds.has(evidence.memoryId)).map((evidence) => "durable-evidence:" + evidence.id)
190068
+ ));
189488
190069
  const continuation = input.continuation && (input.continuation.previousSession || input.continuation.memories.length > 0 || input.continuation.compactCheckpoint) ? {
189489
190070
  ...input.continuation.previousSession ? {
189490
190071
  previousSession: {
@@ -189511,15 +190092,16 @@ async function buildTaskWorkset(input) {
189511
190092
  currentFacts: input.currentFacts?.map((fact) => fact.startsWith("Historical note:") ? short(fact, 48) : short(fact, 28)).slice(0, 4) ?? [],
189512
190093
  ...continuation ? { continuation } : {},
189513
190094
  ...input.codeState ? { codeState: short(input.codeState, 28) } : {},
190095
+ ...input.codeEvolution ? { codeEvolution: input.codeEvolution } : {},
189514
190096
  startHere: unique(input.startHere).slice(0, 5),
189515
190097
  ...input.semanticCode ? { semanticCode: input.semanticCode } : {},
189516
- reliableMemory: input.reliableMemory?.slice(0, 3) ?? [],
190098
+ reliableMemory: governed.reliableMemory,
189517
190099
  cautionMemory: input.cautionMemory?.slice(0, 3) ?? [],
189518
190100
  hiddenCautionMemoryCount: input.hiddenCautionMemoryCount ?? 0,
189519
- claims,
189520
- pages,
189521
- durableMemory,
189522
- workflows,
190101
+ claims: governed.claims,
190102
+ pages: pages.filter((page) => page.claimIds.some((claimId) => governed.claims.some((claim) => claim.id === claimId))),
190103
+ durableMemory: governed.durableMemory,
190104
+ workflows: governed.workflows,
189523
190105
  cautions: normalizedCautions,
189524
190106
  verification,
189525
190107
  evidenceIds,
@@ -189544,6 +190126,17 @@ async function buildTaskWorkset(input) {
189544
190126
  },
189545
190127
  selected: rendered.selected,
189546
190128
  omitted: receiptOmissions(rendered.omittedItems, base.hiddenCautionMemoryCount),
190129
+ governance: {
190130
+ scope: "optional-evidence",
190131
+ mode: governed.plan.mode,
190132
+ decisions: governed.plan.decisions.map((decision) => ({
190133
+ kind: decision.candidate.kind,
190134
+ ...decision.candidate.id ? { id: decision.candidate.id } : {},
190135
+ disposition: decision.disposition,
190136
+ reasons: decision.reasons
190137
+ })),
190138
+ cautions: governed.plan.cautions
190139
+ },
189547
190140
  scheduledActions: scheduledActions(normalizedCautions)
189548
190141
  };
189549
190142
  return {
@@ -189569,8 +190162,11 @@ var init_workset = __esm({
189569
190162
  init_workspace_store();
189570
190163
  init_workspace();
189571
190164
  init_workflow_store();
190165
+ init_outcome_store();
190166
+ init_outcome_types();
189572
190167
  init_workflows2();
189573
190168
  init_long_term();
190169
+ init_governor();
189574
190170
  CONTINUATION_DETAIL_TOKEN_BUDGET = 20;
189575
190171
  }
189576
190172
  });
@@ -189593,19 +190189,19 @@ function readTextIfExists(filePath) {
189593
190189
  }
189594
190190
  }
189595
190191
  function readPackageVersion(rootPath) {
189596
- const text = readTextIfExists(path30.join(rootPath, "package.json"));
189597
- if (!text) return void 0;
190192
+ const text2 = readTextIfExists(path30.join(rootPath, "package.json"));
190193
+ if (!text2) return void 0;
189598
190194
  try {
189599
- const parsed = JSON.parse(text);
190195
+ const parsed = JSON.parse(text2);
189600
190196
  return typeof parsed.version === "string" ? parsed.version : void 0;
189601
190197
  } catch {
189602
190198
  return void 0;
189603
190199
  }
189604
190200
  }
189605
190201
  function readLatestChangelog(rootPath) {
189606
- const text = readTextIfExists(path30.join(rootPath, "CHANGELOG.md"));
189607
- if (!text) return void 0;
189608
- const match2 = text.match(/^##\s+\[?v?([^\]\s]+)\]?\s*(?:-\s*(\d{4}-\d{2}-\d{2}))?/m);
190202
+ const text2 = readTextIfExists(path30.join(rootPath, "CHANGELOG.md"));
190203
+ if (!text2) return void 0;
190204
+ const match2 = text2.match(/^##\s+\[?v?([^\]\s]+)\]?\s*(?:-\s*(\d{4}-\d{2}-\d{2}))?/m);
189609
190205
  if (!match2) return void 0;
189610
190206
  return {
189611
190207
  version: match2[1],
@@ -189806,6 +190402,7 @@ function providerQuality(input) {
189806
190402
  capabilities: {
189807
190403
  declarations: true,
189808
190404
  importHints: true,
190405
+ localRelativeImportTargets: true,
189809
190406
  resolvedRelations: false,
189810
190407
  exactLocations: false
189811
190408
  },
@@ -190822,8 +191419,8 @@ function isNoiseObservation(obs) {
190822
191419
  return NOISE_PATTERNS.some((pattern) => pattern.test(title)) || isCommandTrace(obs);
190823
191420
  }
190824
191421
  function isSystemSelfObservation(obs) {
190825
- const text = stringifyObservation(obs, false);
190826
- return SYSTEM_SELF_PATTERNS.some((pattern) => pattern.test(text));
191422
+ const text2 = stringifyObservation(obs, false);
191423
+ return SYSTEM_SELF_PATTERNS.some((pattern) => pattern.test(text2));
190827
191424
  }
190828
191425
  function readerForAlias(reader, aliases, observation) {
190829
191426
  if (!reader) return void 0;
@@ -190846,8 +191443,8 @@ function continuationTaskTokens(task) {
190846
191443
  function continuationScore(observation, projectTokens, task) {
190847
191444
  let score = scoreObservationForSessionContext(observation, projectTokens);
190848
191445
  if (observation.type === "session-request" || observation.type === "what-changed") score += 1;
190849
- const text = stringifyObservation(observation);
190850
- const matches = continuationTaskTokens(task).filter((token) => text.includes(token)).length;
191446
+ const text2 = stringifyObservation(observation);
191447
+ const matches = continuationTaskTokens(task).filter((token) => text2.includes(token)).length;
190851
191448
  score += Math.min(matches, 2) * 2;
190852
191449
  return score;
190853
191450
  }
@@ -190881,8 +191478,8 @@ async function getSessionResumeBrief(projectId, task, reader) {
190881
191478
  memories
190882
191479
  };
190883
191480
  }
190884
- function compactResumeText(text, limit2) {
190885
- const normalized = text.replace(/\s+/g, " ").trim();
191481
+ function compactResumeText(text2, limit2) {
191482
+ const normalized = text2.replace(/\s+/g, " ").trim();
190886
191483
  return normalized.length <= limit2 ? normalized : `${normalized.slice(0, Math.max(0, limit2 - 3)).trimEnd()}...`;
190887
191484
  }
190888
191485
  function renderSessionResumeCard(brief) {
@@ -190904,11 +191501,11 @@ function renderSessionResumeCard(brief) {
190904
191501
  }
190905
191502
  function scoreObservationForSessionContext(obs, projectTokens, now3 = Date.now()) {
190906
191503
  let score = TYPE_WEIGHTS[obs.type] ?? 1;
190907
- const text = stringifyObservation(obs);
191504
+ const text2 = stringifyObservation(obs);
190908
191505
  const ageDays = Math.max(0, (now3 - new Date(obs.createdAt).getTime()) / (1e3 * 60 * 60 * 24));
190909
191506
  score += Math.max(0.2, 2.5 - Math.min(ageDays, 45) * 0.05);
190910
191507
  if (projectTokens.length > 0) {
190911
- const matchingTokens = projectTokens.filter((token) => text.includes(token));
191508
+ const matchingTokens = projectTokens.filter((token) => text2.includes(token));
190912
191509
  if (matchingTokens.length > 0) {
190913
191510
  score += 2 + matchingTokens.length * 0.6;
190914
191511
  } else if ((obs.filesModified?.length ?? 0) > 0) {
@@ -191224,8 +191821,8 @@ var compaction_checkpoint_store_exports = {};
191224
191821
  __export(compaction_checkpoint_store_exports, {
191225
191822
  CompactionCheckpointStore: () => CompactionCheckpointStore
191226
191823
  });
191227
- import { createHash as createHash13, randomUUID as randomUUID14 } from "crypto";
191228
- function optionalText6(value) {
191824
+ import { createHash as createHash13, randomUUID as randomUUID15 } from "crypto";
191825
+ function optionalText7(value) {
191229
191826
  return typeof value === "string" && value ? value : void 0;
191230
191827
  }
191231
191828
  function optionalNumber2(value) {
@@ -191279,15 +191876,15 @@ function rowToCheckpoint(row) {
191279
191876
  reason: row.reason,
191280
191877
  sourceEvent: row.source_event,
191281
191878
  sourceKey: row.source_key,
191282
- ...optionalText6(row.summary) ? { summary: row.summary } : {},
191879
+ ...optionalText7(row.summary) ? { summary: row.summary } : {},
191283
191880
  ...optionalNumber2(row.tokens_before) !== void 0 ? { tokensBefore: Number(row.tokens_before) } : {},
191284
- ...optionalText6(row.first_kept_entry_id) ? { firstKeptEntryId: row.first_kept_entry_id } : {},
191881
+ ...optionalText7(row.first_kept_entry_id) ? { firstKeptEntryId: row.first_kept_entry_id } : {},
191285
191882
  ...parseDetails(row.details_json) ? { details: parseDetails(row.details_json) } : {},
191286
191883
  transcriptAvailable: Boolean(row.transcript_available),
191287
191884
  status: row.status,
191288
191885
  preCapturedAt: row.pre_captured_at,
191289
- ...optionalText6(row.completed_at) ? { completedAt: row.completed_at } : {},
191290
- ...optionalText6(row.delivered_at) ? { deliveredAt: row.delivered_at } : {},
191886
+ ...optionalText7(row.completed_at) ? { completedAt: row.completed_at } : {},
191887
+ ...optionalText7(row.delivered_at) ? { deliveredAt: row.delivered_at } : {},
191291
191888
  deliveryCount: Number(row.delivery_count ?? 0),
191292
191889
  createdAt: row.created_at,
191293
191890
  updatedAt: row.updated_at
@@ -191325,7 +191922,7 @@ var init_compaction_checkpoint_store = __esm({
191325
191922
  if (pending) return rowToCheckpoint(pending);
191326
191923
  const now3 = input.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString();
191327
191924
  const checkpoint = {
191328
- id: randomUUID14(),
191925
+ id: randomUUID15(),
191329
191926
  projectId: input.projectId,
191330
191927
  sessionId: input.sessionId,
191331
191928
  agent: input.agent,
@@ -191333,7 +191930,7 @@ var init_compaction_checkpoint_store = __esm({
191333
191930
  captureKind: "preflight",
191334
191931
  reason: safeReason(input.reason),
191335
191932
  sourceEvent: input.sourceEvent,
191336
- sourceKey: `pre:${randomUUID14()}`,
191933
+ sourceKey: `pre:${randomUUID15()}`,
191337
191934
  transcriptAvailable: Boolean(input.transcriptAvailable),
191338
191935
  status: "active",
191339
191936
  preCapturedAt: now3,
@@ -191399,7 +191996,7 @@ var init_compaction_checkpoint_store = __esm({
191399
191996
  return this.get(checkpoint2.id);
191400
191997
  }
191401
191998
  const checkpoint = {
191402
- id: randomUUID14(),
191999
+ id: randomUUID15(),
191403
192000
  projectId: input.projectId,
191404
192001
  sessionId: input.sessionId,
191405
192002
  agent: input.agent,
@@ -191661,6 +192258,25 @@ async function buildAutoProjectContext(input) {
191661
192258
  const overview = explain.overview;
191662
192259
  const currentFacts = collectCurrentProjectFacts({ project: input.project, now: now3 });
191663
192260
  const latestSnapshot = overview.code.latestSnapshot;
192261
+ let codeEvolution;
192262
+ if (continuationRequested && latestSnapshot?.previousSnapshotId && latestSnapshot.changedPathCount > 0) {
192263
+ const diff = store2.diffSnapshots(input.project.id, latestSnapshot.previousSnapshotId, latestSnapshot.id);
192264
+ if (diff.available && diff.changes.length > 0) {
192265
+ const impact = store2.impactSlice(input.project.id, diff.changes.map((change) => change.path));
192266
+ const changedFileIds = new Set([
192267
+ ...store2.listSnapshotFiles(diff.fromSnapshotId),
192268
+ ...store2.listSnapshotFiles(diff.toSnapshotId)
192269
+ ].filter((file2) => diff.changes.some((change) => change.path === file2.path)).map((file2) => file2.fileId));
192270
+ codeEvolution = {
192271
+ fromSnapshotId: diff.fromSnapshotId,
192272
+ toSnapshotId: diff.toSnapshotId,
192273
+ changes: diff.changes.slice(0, 5).map((change) => ({ path: change.path, kind: change.kind })),
192274
+ directlyConnectedPaths: impact.directlyConnectedPaths.slice(0, 3),
192275
+ affectedMemoryCount: store2.countStaleObservationRefsForFiles(input.project.id, [...changedFileIds]),
192276
+ truncated: impact.truncated || diff.changes.length > 5
192277
+ };
192278
+ }
192279
+ }
191664
192280
  const sourceSets = lensSourceSets({ task, lens, explain });
191665
192281
  let externalOutline;
191666
192282
  let externalCaution;
@@ -191737,6 +192353,7 @@ async function buildAutoProjectContext(input) {
191737
192353
  currentFacts: worksetFactLines(currentFacts),
191738
192354
  ...continuation ? { continuation } : {},
191739
192355
  codeState: codeStateLine(overview),
192356
+ ...codeEvolution ? { codeEvolution } : {},
191740
192357
  reliableMemory: sourceSets.reliableSources.slice(0, lens.sourceLimit).map((source) => ({
191741
192358
  id: source.observationId,
191742
192359
  title: source.title,
@@ -191788,9 +192405,9 @@ async function buildAutoProjectContext(input) {
191788
192405
  function formatLanguages(overview) {
191789
192406
  return overview.code.languages.length > 0 ? overview.code.languages.map((item) => `${item.language} ${item.files}`).join(", ") : "none indexed yet";
191790
192407
  }
191791
- function compactContinuationText(text, budget) {
192408
+ function compactContinuationText(text2, budget) {
191792
192409
  return truncateToTokenBudget(
191793
- sanitizeCredentials(text).replace(/\s+/g, " ").trim(),
192410
+ sanitizeCredentials(text2).replace(/\s+/g, " ").trim(),
191794
192411
  budget
191795
192412
  );
191796
192413
  }
@@ -192203,6 +192820,13 @@ function formatContextReceipt(receipt) {
192203
192820
  lines.push(`- ${item.kind}: ${item.count} item(s) (${item.reason})`);
192204
192821
  }
192205
192822
  }
192823
+ if (receipt.governance?.decisions.length) {
192824
+ lines.push("", "Optional evidence qualification");
192825
+ for (const item of receipt.governance.decisions.slice(0, 20)) {
192826
+ const id = item.id ? ` ${item.id}` : "";
192827
+ lines.push(`- ${item.kind}${id}: ${item.disposition} (${item.reasons.join(", ")})`);
192828
+ }
192829
+ }
192206
192830
  if (receipt.scheduledActions.length > 0) {
192207
192831
  lines.push("", "Scheduled follow-up");
192208
192832
  for (const action of receipt.scheduledActions) lines.push(`- ${action}`);
@@ -192282,8 +192906,8 @@ __export(context_pack_exports, {
192282
192906
  function uniq2(items) {
192283
192907
  return [...new Set(items)];
192284
192908
  }
192285
- function tokenize5(text) {
192286
- return (text.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1);
192909
+ function tokenize5(text2) {
192910
+ return (text2.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1);
192287
192911
  }
192288
192912
  function timestampOf(observation) {
192289
192913
  return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
@@ -192545,11 +193169,49 @@ function formatUsageHint() {
192545
193169
  "Usage:",
192546
193170
  " memorix codegraph refresh",
192547
193171
  " memorix codegraph status --json",
193172
+ " memorix codegraph diff [--from <snapshot>] [--to <snapshot>]",
193173
+ " memorix codegraph impact --path <relative-source-path>",
192548
193174
  ' memorix codegraph context-pack --task "continue auth bug"',
192549
193175
  "",
192550
193176
  'Tip: use `memorix context "..."` for new work or `memorix resume "..."` for prior work.'
192551
193177
  ].join("\n");
192552
193178
  }
193179
+ function formatDiff(diff, impact) {
193180
+ if (!diff.available) {
193181
+ return `CodeGraph diff is unavailable: ${diff.reason ?? "unknown reason"}. Refresh twice to establish comparable snapshots.`;
193182
+ }
193183
+ const summary = diff.changes.reduce((counts, change) => {
193184
+ counts[change.kind] += 1;
193185
+ return counts;
193186
+ }, { added: 0, modified: 0, removed: 0 });
193187
+ const lines = [
193188
+ `CodeGraph diff: ${diff.fromSnapshotId} -> ${diff.toSnapshotId}`,
193189
+ `- Changed files: ${diff.changes.length} (${summary.added} added, ${summary.modified} modified, ${summary.removed} removed)`
193190
+ ];
193191
+ for (const change of diff.changes.slice(0, 20)) lines.push(`- ${change.kind}: ${change.path}`);
193192
+ if (diff.changes.length > 20) lines.push(`- ${diff.changes.length - 20} additional file change(s) omitted`);
193193
+ if (impact.directlyConnectedPaths.length > 0) {
193194
+ lines.push("", "Current one-hop structural impact");
193195
+ for (const path46 of impact.directlyConnectedPaths.slice(0, 20)) lines.push(`- ${path46}`);
193196
+ }
193197
+ if (impact.relationCount === 0) lines.push("", "No current file-edge relation was found for the changed paths.");
193198
+ if (impact.truncated) lines.push("- Impact relation limit reached; inspect the graph before assuming coverage.");
193199
+ return lines.join("\n");
193200
+ }
193201
+ function formatImpact(impact) {
193202
+ const lines = [
193203
+ `CodeGraph current one-hop impact: ${impact.changedPaths.join(", ")}`,
193204
+ `- Relations inspected: ${impact.relationCount}`
193205
+ ];
193206
+ if (impact.directlyConnectedPaths.length > 0) {
193207
+ lines.push("- Directly connected paths:");
193208
+ for (const path46 of impact.directlyConnectedPaths) lines.push(` - ${path46}`);
193209
+ } else {
193210
+ lines.push("- No current file-edge relation was found for this indexed path.");
193211
+ }
193212
+ if (impact.truncated) lines.push("- Impact relation limit reached; inspect the graph before assuming coverage.");
193213
+ return lines.join("\n");
193214
+ }
192553
193215
  function compactFacts(project) {
192554
193216
  const current = collectCurrentProjectFacts({ project, now: /* @__PURE__ */ new Date() });
192555
193217
  const facts = [];
@@ -192583,9 +193245,13 @@ var init_codegraph = __esm({
192583
193245
  description: "Inspect and refresh CodeGraph Memory for the current project"
192584
193246
  },
192585
193247
  args: {
192586
- action: { type: "string", description: "Action: status, refresh, or context-pack" },
193248
+ action: { type: "string", description: "Action: status, refresh, diff, impact, or context-pack" },
192587
193249
  task: { type: "string", description: "Task text for context-pack" },
193250
+ path: { type: "string", description: "Indexed relative source path for impact" },
192588
193251
  limit: { type: "string", description: "Max active memories to inspect for context-pack" },
193252
+ from: { type: "string", description: "Earlier CodeGraph snapshot id for diff" },
193253
+ to: { type: "string", description: "Later CodeGraph snapshot id for diff" },
193254
+ impactLimit: { type: "string", description: "Maximum graph relations to inspect for diff impact" },
192589
193255
  json: { type: "boolean", description: "Emit machine-readable JSON output" }
192590
193256
  },
192591
193257
  run: async ({ args }) => {
@@ -192608,10 +193274,10 @@ var init_codegraph = __esm({
192608
193274
  command: codegraphConfig.externalCommand,
192609
193275
  timeoutMs: codegraphConfig.externalTimeoutMs
192610
193276
  });
192611
- const text = explicitAction || asJson ? formatStatus(status, providerQuality2.quality) : `${formatStatus(status, providerQuality2.quality)}
193277
+ const text2 = explicitAction || asJson ? formatStatus(status, providerQuality2.quality) : `${formatStatus(status, providerQuality2.quality)}
192612
193278
 
192613
193279
  ${formatUsageHint()}`;
192614
- emitResult({ project, status, providerQuality: providerQuality2.quality }, text, asJson);
193280
+ emitResult({ project, status, providerQuality: providerQuality2.quality }, text2, asJson);
192615
193281
  return;
192616
193282
  }
192617
193283
  case "refresh": {
@@ -192658,6 +193324,41 @@ ${formatUsageHint()}`;
192658
193324
  );
192659
193325
  return;
192660
193326
  }
193327
+ case "diff": {
193328
+ const snapshots = store2.listSnapshots(project.id, 2);
193329
+ const fromSnapshotId = args.from?.trim() || snapshots[1]?.id;
193330
+ const toSnapshotId = args.to?.trim() || snapshots[0]?.id;
193331
+ if (!fromSnapshotId || !toSnapshotId) {
193332
+ emitError('two completed CodeGraph snapshots are required; run "memorix codegraph refresh" again after a code change.', asJson);
193333
+ return;
193334
+ }
193335
+ const diff = store2.diffSnapshots(project.id, fromSnapshotId, toSnapshotId);
193336
+ const impact = store2.impactSlice(
193337
+ project.id,
193338
+ diff.changes.map((change) => change.path),
193339
+ parsePositiveInt(args.impactLimit, 24)
193340
+ );
193341
+ emitResult({ project, diff, impact }, formatDiff(diff, impact), asJson);
193342
+ return;
193343
+ }
193344
+ case "impact": {
193345
+ const sourcePath = args.path?.trim() || positional.slice(1).join(" ").trim();
193346
+ if (!sourcePath) {
193347
+ emitError('path is required for "memorix codegraph impact"', asJson);
193348
+ return;
193349
+ }
193350
+ if (!store2.getFile(project.id, sourcePath)) {
193351
+ emitError(`path is not in the current CodeGraph index: ${sourcePath}. Run "memorix codegraph refresh" and retry.`, asJson);
193352
+ return;
193353
+ }
193354
+ const impact = store2.impactSlice(
193355
+ project.id,
193356
+ [sourcePath],
193357
+ parsePositiveInt(args.impactLimit, 24)
193358
+ );
193359
+ emitResult({ project, impact }, formatImpact(impact), asJson);
193360
+ return;
193361
+ }
192661
193362
  case "context-pack": {
192662
193363
  const task = args.task?.trim() || positional.slice(1).join(" ").trim();
192663
193364
  if (!task) {
@@ -192713,7 +193414,7 @@ ${formatUsageHint()}`;
192713
193414
  return;
192714
193415
  }
192715
193416
  default:
192716
- emitError(`unknown codegraph action "${action}". Use "status", "refresh", or "context-pack".`, asJson);
193417
+ emitError(`unknown codegraph action "${action}". Use "status", "refresh", "diff", "impact", or "context-pack".`, asJson);
192717
193418
  }
192718
193419
  } catch (error40) {
192719
193420
  emitError(error40 instanceof Error ? error40.message : String(error40), asJson);
@@ -192756,19 +193457,19 @@ function buildCompactionWorkset(checkpoint, options2 = {}) {
192756
193457
  const source = sanitizeCredentials(checkpoint.summary?.trim() || fallback);
192757
193458
  const available = Math.max(0, budget - countTextTokens(header) - 4);
192758
193459
  let excerpt = source ? truncateToTokenBudget(source, available) : "";
192759
- let text = `${header}${excerpt ? `### Host checkpoint
193460
+ let text2 = `${header}${excerpt ? `### Host checkpoint
192760
193461
  ${excerpt}` : ""}`.trim();
192761
- while (excerpt && countTextTokens(text) > budget) {
193462
+ while (excerpt && countTextTokens(text2) > budget) {
192762
193463
  const nextExcerptBudget = Math.max(1, Math.floor(countTextTokens(excerpt) * 0.8));
192763
193464
  excerpt = truncateToTokenBudget(excerpt, nextExcerptBudget);
192764
- text = `${header}${excerpt ? `### Host checkpoint
193465
+ text2 = `${header}${excerpt ? `### Host checkpoint
192765
193466
  ${excerpt}` : ""}`.trim();
192766
193467
  }
192767
- if (countTextTokens(text) > budget) text = truncateToTokenBudget(text, budget);
193468
+ if (countTextTokens(text2) > budget) text2 = truncateToTokenBudget(text2, budget);
192768
193469
  return {
192769
193470
  checkpointId: checkpoint.id,
192770
- text,
192771
- tokens: countTextTokens(text)
193471
+ text: text2,
193472
+ tokens: countTextTokens(text2)
192772
193473
  };
192773
193474
  }
192774
193475
  function sourceEvent(input) {
@@ -193019,9 +193720,9 @@ function usage2() {
193019
193720
  ].join("\n");
193020
193721
  }
193021
193722
  function requiredText2(value, field) {
193022
- const text = typeof value === "string" ? value.trim() : "";
193023
- if (!text) throw new Error(field + " is required");
193024
- return text;
193723
+ const text2 = typeof value === "string" ? value.trim() : "";
193724
+ if (!text2) throw new Error(field + " is required");
193725
+ return text2;
193025
193726
  }
193026
193727
  function workflowOutcome(value) {
193027
193728
  if (value === "passed" || value === "failed" || value === "cancelled" || value === "in-progress") return value;
@@ -193614,8 +194315,8 @@ async function extractFactsWithLLM(narrative, title, existingFacts) {
193614
194315
  Content: ${narrative}${existingFacts.length > 0 ? `
193615
194316
  Already known facts (don't repeat): ${existingFacts.join("; ")}` : ""}`;
193616
194317
  const response = await callLLM2(LLM_EXTRACT_PROMPT, input);
193617
- const text = response.content.trim();
193618
- const jsonMatch = text.match(/\{[\s\S]*\}/);
194318
+ const text2 = response.content.trim();
194319
+ const jsonMatch = text2.match(/\{[\s\S]*\}/);
193619
194320
  if (!jsonMatch) return [];
193620
194321
  const parsed = JSON.parse(jsonMatch[0]);
193621
194322
  const facts = parsed.facts;
@@ -193868,8 +194569,8 @@ Facts: ${extracted.facts.join("; ")}
193868
194569
  EXISTING MEMORIES:
193869
194570
  ${existingMemories.map((m5) => `[ID:${m5.id}] ${m5.title} | ${m5.content} | Facts: ${m5.facts}`).join("\n")}`;
193870
194571
  const response = await callLLM2(LLM_RESOLVE_PROMPT, input);
193871
- const text = response.content.trim();
193872
- const jsonMatch = text.match(/\{[\s\S]*\}/);
194572
+ const text2 = response.content.trim();
194573
+ const jsonMatch = text2.match(/\{[\s\S]*\}/);
193873
194574
  if (!jsonMatch) return null;
193874
194575
  const parsed = JSON.parse(jsonMatch[0]);
193875
194576
  const action = parsed.action?.toUpperCase();
@@ -195516,9 +196217,9 @@ __export(identity_exports, {
195516
196217
  default: () => identity_default
195517
196218
  });
195518
196219
  function requiredText3(value, label) {
195519
- const text = typeof value === "string" ? value.trim() : "";
195520
- if (!text) throw new Error(`${label} is required`);
195521
- return text;
196220
+ const text2 = typeof value === "string" ? value.trim() : "";
196221
+ if (!text2) throw new Error(`${label} is required`);
196222
+ return text2;
195522
196223
  }
195523
196224
  var identity_default;
195524
196225
  var init_identity2 = __esm({
@@ -196194,15 +196895,15 @@ function validateSemantics(graph) {
196194
196895
  return warnings;
196195
196896
  }
196196
196897
  function extractJson(raw) {
196197
- let text = raw;
196898
+ let text2 = raw;
196198
196899
  try {
196199
196900
  const envelope = JSON.parse(raw.trim());
196200
196901
  if (envelope && typeof envelope.result === "string" && envelope.type === "result") {
196201
- text = envelope.result;
196902
+ text2 = envelope.result;
196202
196903
  }
196203
196904
  } catch {
196204
196905
  }
196205
- if (text === raw && raw.includes('"type"')) {
196906
+ if (text2 === raw && raw.includes('"type"')) {
196206
196907
  const textBlocks = [];
196207
196908
  for (const line of raw.split("\n")) {
196208
196909
  const trimmed = line.trim();
@@ -196226,27 +196927,27 @@ function extractJson(raw) {
196226
196927
  }
196227
196928
  }
196228
196929
  if (textBlocks.length > 0) {
196229
- text = textBlocks.join("");
196930
+ text2 = textBlocks.join("");
196230
196931
  }
196231
196932
  }
196232
- const fenced = text.match(/```(?:json)?\s*\n?([\s\S]*?)```/);
196933
+ const fenced = text2.match(/```(?:json)?\s*\n?([\s\S]*?)```/);
196233
196934
  if (fenced) {
196234
196935
  const candidate2 = fenced[1].trim();
196235
196936
  if (candidate2.startsWith("{")) return candidate2;
196236
196937
  }
196237
- const braceStart = text.indexOf("{");
196938
+ const braceStart = text2.indexOf("{");
196238
196939
  if (braceStart !== -1) {
196239
- const extracted = extractBalancedJson(text, braceStart);
196940
+ const extracted = extractBalancedJson(text2, braceStart);
196240
196941
  if (extracted) return extracted;
196241
196942
  }
196242
196943
  return null;
196243
196944
  }
196244
- function extractBalancedJson(text, startIdx) {
196945
+ function extractBalancedJson(text2, startIdx) {
196245
196946
  let depth = 0;
196246
196947
  let inString = false;
196247
196948
  let escape2 = false;
196248
- for (let i3 = startIdx; i3 < text.length; i3++) {
196249
- const ch = text[i3];
196949
+ for (let i3 = startIdx; i3 < text2.length; i3++) {
196950
+ const ch = text2[i3];
196250
196951
  if (escape2) {
196251
196952
  escape2 = false;
196252
196953
  continue;
@@ -196264,7 +196965,7 @@ function extractBalancedJson(text, startIdx) {
196264
196965
  else if (ch === "}") {
196265
196966
  depth--;
196266
196967
  if (depth === 0) {
196267
- return text.slice(startIdx, i3 + 1);
196968
+ return text2.slice(startIdx, i3 + 1);
196268
196969
  }
196269
196970
  }
196270
196971
  }
@@ -196484,7 +197185,7 @@ __export(planner_exports, {
196484
197185
  materializeTaskGraph: () => materializeTaskGraph,
196485
197186
  seedAutonomousPipeline: () => seedAutonomousPipeline
196486
197187
  });
196487
- import { randomUUID as randomUUID15 } from "crypto";
197188
+ import { randomUUID as randomUUID16 } from "crypto";
196488
197189
  function isPlannerTask(metadata) {
196489
197190
  if (!metadata) return null;
196490
197191
  try {
@@ -196542,7 +197243,7 @@ function seedAutonomousPipeline(teamStore, projectId, config2, opts) {
196542
197243
  const maxIterations = config2.maxIterations ?? 3;
196543
197244
  const taskBudget = config2.taskBudget ?? 15;
196544
197245
  const structuredPlan = opts?.structuredPlan ?? true;
196545
- const pipelineId = randomUUID15();
197246
+ const pipelineId = randomUUID16();
196546
197247
  const meta = {
196547
197248
  plannerType: "plan",
196548
197249
  pipelineId,
@@ -197438,7 +198139,7 @@ var init_poll2 = __esm({
197438
198139
  if (args.markInboxRead && agentId) {
197439
198140
  teamStore.markAllRead(project.id, agentId);
197440
198141
  }
197441
- const text = [
198142
+ const text2 = [
197442
198143
  poll.agent ? `You: ${shortId(poll.agent.agentId)} (${poll.agent.status})` : "Project-level overview",
197443
198144
  poll.watermark.newObservationCount > 0 ? `${poll.watermark.newObservationCount} new observation(s)` : "No unseen observations",
197444
198145
  poll.inbox.unreadCount > 0 ? `${poll.inbox.unreadCount} unread message(s)` : "Inbox clear",
@@ -197446,7 +198147,7 @@ var init_poll2 = __esm({
197446
198147
  poll.tasks.availableToClaim.length > 0 ? `${poll.tasks.availableToClaim.length} task(s) available to claim` : "No claimable tasks",
197447
198148
  `Team: ${poll.team.activeAgents.length} active / ${poll.team.totalAgents} total`
197448
198149
  ].join("\n");
197449
- emitResult({ project, poll }, text, asJson);
198150
+ emitResult({ project, poll }, text2, asJson);
197450
198151
  } catch (error40) {
197451
198152
  emitError(error40 instanceof Error ? error40.message : String(error40), asJson);
197452
198153
  }
@@ -197522,8 +198223,8 @@ async function loadReceiptObservations(dataDir, projectId) {
197522
198223
  function probeMatches(obs, probe) {
197523
198224
  const query = probe.toLowerCase();
197524
198225
  const facts = safeJsonArray(obs.facts).join(" ");
197525
- const text = [obs.title ?? "", obs.narrative ?? "", facts].join(" ").toLowerCase();
197526
- return query.split(/\s+/).filter(Boolean).some((term) => text.includes(term));
198226
+ const text2 = [obs.title ?? "", obs.narrative ?? "", facts].join(" ").toLowerCase();
198227
+ return query.split(/\s+/).filter(Boolean).some((term) => text2.includes(term));
197527
198228
  }
197528
198229
  async function buildHandoffReceipt(options2 = {}) {
197529
198230
  const cwd = options2.cwd ?? process.cwd();
@@ -205264,7 +205965,7 @@ var require_core2 = __commonJS({
205264
205965
  errorsText(errors2 = this.errors, { separator: separator10 = ", ", dataVar = "data" } = {}) {
205265
205966
  if (!errors2 || errors2.length === 0)
205266
205967
  return "No errors";
205267
- return errors2.map((e4) => `${dataVar}${e4.instancePath} ${e4.message}`).reduce((text, msg) => text + separator10 + msg);
205968
+ return errors2.map((e4) => `${dataVar}${e4.instancePath} ${e4.message}`).reduce((text2, msg) => text2 + separator10 + msg);
205268
205969
  }
205269
205970
  $dataMetaSchema(metaSchema, keywordsJsonPointers) {
205270
205971
  const rules = this.RULES.all;
@@ -207249,7 +207950,7 @@ var require_discriminator = __commonJS({
207249
207950
  error: error40,
207250
207951
  code(cxt) {
207251
207952
  const { gen, data, schema, parentSchema, it } = cxt;
207252
- const { oneOf } = parentSchema;
207953
+ const { oneOf: oneOf2 } = parentSchema;
207253
207954
  if (!it.opts.discriminator) {
207254
207955
  throw new Error("discriminator: requires discriminator option");
207255
207956
  }
@@ -207258,7 +207959,7 @@ var require_discriminator = __commonJS({
207258
207959
  throw new Error("discriminator: requires propertyName");
207259
207960
  if (schema.mapping)
207260
207961
  throw new Error("discriminator: mapping is not supported");
207261
- if (!oneOf)
207962
+ if (!oneOf2)
207262
207963
  throw new Error("discriminator: requires oneOf keyword");
207263
207964
  const valid = gen.let("valid", false);
207264
207965
  const tag = gen.const("tag", (0, codegen_1._)`${data}${(0, codegen_1.getProperty)(tagName)}`);
@@ -207286,8 +207987,8 @@ var require_discriminator = __commonJS({
207286
207987
  const oneOfMapping = {};
207287
207988
  const topRequired = hasRequired(parentSchema);
207288
207989
  let tagRequired = true;
207289
- for (let i3 = 0; i3 < oneOf.length; i3++) {
207290
- let sch = oneOf[i3];
207990
+ for (let i3 = 0; i3 < oneOf2.length; i3++) {
207991
+ let sch = oneOf2[i3];
207291
207992
  if ((sch === null || sch === void 0 ? void 0 : sch.$ref) && !(0, util_1.schemaHasRulesButRef)(sch, it.self.RULES)) {
207292
207993
  const ref = sch.$ref;
207293
207994
  sch = compile_1.resolveRef.call(it.self, it.schemaEnv.root, it.baseId, ref);
@@ -212846,8 +213547,8 @@ async function callVisionLLM(systemPrompt, imageBase64, mimeType) {
212846
213547
  return data.choices[0]?.message?.content ?? "";
212847
213548
  }
212848
213549
  function normalizeText4(value, fallback = "") {
212849
- const text = typeof value === "string" && value.trim() ? value.trim() : fallback;
212850
- return sanitizeCredentials(text).slice(0, MAX_VISION_DESCRIPTION_CHARS);
213550
+ const text2 = typeof value === "string" && value.trim() ? value.trim() : fallback;
213551
+ return sanitizeCredentials(text2).slice(0, MAX_VISION_DESCRIPTION_CHARS);
212851
213552
  }
212852
213553
  function normalizeLabels(value) {
212853
213554
  if (!Array.isArray(value)) return [];
@@ -213336,7 +214037,7 @@ The path should point to a directory containing a .git folder.`
213336
214037
  };
213337
214038
  const server = existingServer ?? new McpServer({
213338
214039
  name: "memorix",
213339
- version: true ? "1.4.1" : "1.0.1"
214040
+ version: true ? "1.4.2" : "1.0.1"
213340
214041
  });
213341
214042
  const originalRegisterTool = server.registerTool.bind(server);
213342
214043
  server.registerTool = ((name, ...args) => {
@@ -214072,10 +214773,10 @@ Use this as the \`topicKey\` parameter in \`memorix_store\` to enable upsert beh
214072
214773
  const duplicate = blockCoveredAutopilotEvidence("memorix_search", result.entries.map((entry) => entry.id), force);
214073
214774
  if (duplicate) return duplicate;
214074
214775
  }
214075
- let text = result.formatted;
214776
+ let text2 = result.formatted;
214076
214777
  try {
214077
214778
  const { getLastSearchMode: getLastSearchMode2 } = await Promise.resolve().then(() => (init_orama_store(), orama_store_exports));
214078
- text += `
214779
+ text2 += `
214079
214780
 
214080
214781
  _Search mode: ${getLastSearchMode2(project.id)}_`;
214081
214782
  } catch {
@@ -214084,7 +214785,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214084
214785
  content: [
214085
214786
  {
214086
214787
  type: "text",
214087
- text
214788
+ text: text2
214088
214789
  }
214089
214790
  ]
214090
214791
  };
@@ -214117,14 +214818,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214117
214818
  query,
214118
214819
  limit: limit2 != null ? coerceNumber(limit2, 5) : void 0
214119
214820
  });
214120
- const text = format === "summary" ? [
214821
+ const text2 = format === "summary" ? [
214121
214822
  `Graph context packet for ${project.name}`,
214122
214823
  `- ${packet.summary}`,
214123
214824
  "",
214124
214825
  ...packet.entities.map((entity) => `* ${entity.name} (#${entity.observationIds.join(", #")})`)
214125
214826
  ].join("\n") : formatGraphContextPrompt(packet);
214126
214827
  return {
214127
- content: [{ type: "text", text }]
214828
+ content: [{ type: "text", text: text2 }]
214128
214829
  };
214129
214830
  }
214130
214831
  );
@@ -214184,7 +214885,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214184
214885
  });
214185
214886
  }
214186
214887
  });
214187
- const text = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "summary" ? formatAutoProjectContextSummary2(context) : formatAutoProjectContextPrompt2(context);
214888
+ const text2 = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "summary" ? formatAutoProjectContextSummary2(context) : formatAutoProjectContextPrompt2(context);
214188
214889
  autopilotRetrievalBoundary = {
214189
214890
  projectId: project.id,
214190
214891
  issuedAt: Date.now(),
@@ -214196,7 +214897,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214196
214897
  readOnly: READ_ONLY_TASK_PATTERN.test(task ?? "")
214197
214898
  };
214198
214899
  return {
214199
- content: [{ type: "text", text }]
214900
+ content: [{ type: "text", text: text2 }]
214200
214901
  };
214201
214902
  }
214202
214903
  );
@@ -214324,9 +215025,9 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214324
215025
  ...external.caution ? { runtimeCautions: [{ kind: "external-codegraph-fallback", message: external.caution }] } : {},
214325
215026
  reader: getObservationReader()
214326
215027
  });
214327
- const text = buildContextPackPrompt2(pack);
215028
+ const text2 = buildContextPackPrompt2(pack);
214328
215029
  return {
214329
- content: [{ type: "text", text }]
215030
+ content: [{ type: "text", text: text2 }]
214330
215031
  };
214331
215032
  }
214332
215033
  );
@@ -214388,7 +215089,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214388
215089
  }) => {
214389
215090
  const unresolved = requireResolvedProject("manage the Knowledge Workspace for the current project");
214390
215091
  if (unresolved) return unresolved;
214391
- const text = (value, isError = false) => ({
215092
+ const text2 = (value, isError = false) => ({
214392
215093
  content: [{ type: "text", text: JSON.stringify(value, null, 2) }],
214393
215094
  ...isError ? { isError: true } : {}
214394
215095
  });
@@ -214425,7 +215126,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214425
215126
  ]);
214426
215127
  if (action === "workspace_init") {
214427
215128
  if (modeValue === "versioned" && !requireText(workspacePath, "path")) {
214428
- return text({ error: "path is required to initialize a versioned Knowledge Workspace." }, true);
215129
+ return text2({ error: "path is required to initialize a versioned Knowledge Workspace." }, true);
214429
215130
  }
214430
215131
  const workspace2 = await initializeKnowledgeWorkspace2({
214431
215132
  projectId: project.id,
@@ -214433,7 +215134,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214433
215134
  mode: modeValue,
214434
215135
  ...modeValue === "versioned" ? { projectRoot: project.rootPath, rootPath: requireText(workspacePath, "path") } : {}
214435
215136
  });
214436
- return text({
215137
+ return text2({
214437
215138
  workspace: {
214438
215139
  id: workspace2.id,
214439
215140
  mode: workspace2.mode,
@@ -214445,7 +215146,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214445
215146
  }
214446
215147
  const workspace = await loadKnowledgeWorkspace2({ projectId: project.id, dataDir: projectDir2, mode: modeValue });
214447
215148
  if (!workspace) {
214448
- return text({ error: "Knowledge Workspace is not initialized. Run workspace_init first." }, true);
215149
+ return text2({ error: "Knowledge Workspace is not initialized. Run workspace_init first." }, true);
214449
215150
  }
214450
215151
  const claims = new ClaimStore2();
214451
215152
  const workspaceStore = new KnowledgeWorkspaceStore2();
@@ -214453,7 +215154,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214453
215154
  if (action === "status") {
214454
215155
  const pages = workspaceStore.listPages(workspace.id);
214455
215156
  const pending = workspaceStore.listProposals(workspace.id, "pending");
214456
- return text({
215157
+ return text2({
214457
215158
  workspace: {
214458
215159
  id: workspace.id,
214459
215160
  mode: workspace.mode,
@@ -214471,7 +215172,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214471
215172
  });
214472
215173
  }
214473
215174
  if (action === "claim_list") {
214474
- return text({
215175
+ return text2({
214475
215176
  claims: claims.listClaims(project.id, { limit: 100 }).map((claim) => ({
214476
215177
  id: claim.id,
214477
215178
  subject: claim.subject,
@@ -214490,18 +215191,18 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214490
215191
  const requestedClaimId = requireText(claimId, "claimId");
214491
215192
  const detail = requireText(reviewDetail, "reviewDetail");
214492
215193
  if (!requestedClaimId || !claimReviewState2 || !detail) {
214493
- return text({ error: "claimId, claimReviewState, and reviewDetail are required for claim_review." }, true);
215194
+ return text2({ error: "claimId, claimReviewState, and reviewDetail are required for claim_review." }, true);
214494
215195
  }
214495
215196
  const existing = claims.getClaim(requestedClaimId);
214496
215197
  if (!existing || existing.projectId !== project.id) {
214497
- return text({ error: "Claim was not found for the current project." }, true);
215198
+ return text2({ error: "Claim was not found for the current project." }, true);
214498
215199
  }
214499
215200
  const claim = reviewClaim2(claims, {
214500
215201
  claimId: requestedClaimId,
214501
215202
  reviewState: claimReviewState2,
214502
215203
  detail
214503
215204
  });
214504
- return text({
215205
+ return text2({
214505
215206
  claim: {
214506
215207
  id: claim.id,
214507
215208
  status: claim.status,
@@ -214513,7 +215214,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214513
215214
  }
214514
215215
  if (action === "compile") {
214515
215216
  const result = await compileKnowledgeWorkspace2({ workspace, claims });
214516
- return text({
215217
+ return text2({
214517
215218
  proposals: result.proposals.map((proposal) => ({
214518
215219
  id: proposal.id,
214519
215220
  targetPath: proposal.targetPath,
@@ -214528,17 +215229,17 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214528
215229
  const codeStore = new CodeGraphStore2();
214529
215230
  await codeStore.init(projectDir2);
214530
215231
  const result = await lintKnowledgeWorkspace2({ workspace, claims, codeStore });
214531
- return text(result);
215232
+ return text2(result);
214532
215233
  }
214533
215234
  if (action === "proposal_apply") {
214534
215235
  const proposal = requireText(proposalId, "proposalId");
214535
- if (!proposal) return text({ error: "proposalId is required for proposal_apply." }, true);
215236
+ if (!proposal) return text2({ error: "proposalId is required for proposal_apply." }, true);
214536
215237
  const result = await applyKnowledgeProposal2({
214537
215238
  workspace,
214538
215239
  proposalId: proposal,
214539
215240
  allowManualOverwrite: !!allowManualOverwrite
214540
215241
  });
214541
- return text({
215242
+ return text2({
214542
215243
  proposal: { id: result.proposal.id, status: result.proposal.status },
214543
215244
  targetPath: result.targetPath
214544
215245
  });
@@ -214548,7 +215249,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214548
215249
  const projectRoot = workspace.projectRoot ?? project.rootPath;
214549
215250
  if (action === "workflow_import") {
214550
215251
  const result = await importWindsurfWorkflows2({ workspace, projectRoot });
214551
- return text({
215252
+ return text2({
214552
215253
  imported: result.imported.map((workflow2) => ({
214553
215254
  id: workflow2.id,
214554
215255
  title: workflow2.title,
@@ -214561,7 +215262,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214561
215262
  }
214562
215263
  const synced = await syncCanonicalWorkflows2(workspace);
214563
215264
  if (action === "workflow_list") {
214564
- return text({
215265
+ return text2({
214565
215266
  workflows: workflowStore.listWorkflows(workspace.id).map((workflow2) => ({
214566
215267
  id: workflow2.id,
214567
215268
  title: workflow2.title,
@@ -214576,9 +215277,9 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214576
215277
  }
214577
215278
  if (action === "workflow_select") {
214578
215279
  const selectedTask = requireText(task, "task");
214579
- if (!selectedTask) return text({ error: "task is required for workflow_select." }, true);
215280
+ if (!selectedTask) return text2({ error: "task is required for workflow_select." }, true);
214580
215281
  const result = await selectWorkspaceWorkflows2({ workspace, task: selectedTask });
214581
- return text({
215282
+ return text2({
214582
215283
  selections: result.selections.map((selection) => ({
214583
215284
  id: selection.workflow.id,
214584
215285
  title: selection.workflow.title,
@@ -214590,16 +215291,16 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214590
215291
  });
214591
215292
  }
214592
215293
  const requestedWorkflowId = requireText(workflowId, "workflowId");
214593
- if (!requestedWorkflowId) return text({ error: "workflowId is required for this workflow action." }, true);
215294
+ if (!requestedWorkflowId) return text2({ error: "workflowId is required for this workflow action." }, true);
214594
215295
  const workflow = workflowStore.getWorkflow(requestedWorkflowId);
214595
215296
  if (!workflow || workflow.workspaceId !== workspace.id) {
214596
- return text({ error: "Workflow was not found for this Knowledge Workspace." }, true);
215297
+ return text2({ error: "Workflow was not found for this Knowledge Workspace." }, true);
214597
215298
  }
214598
215299
  if (action === "workflow_preview" || action === "workflow_apply") {
214599
215300
  const targetAgent = requireText(agent, "agent");
214600
- if (!targetAgent) return text({ error: "agent is required for a workflow adapter action." }, true);
215301
+ if (!targetAgent) return text2({ error: "agent is required for a workflow adapter action." }, true);
214601
215302
  const result = action === "workflow_preview" ? await previewWorkflowAdapter2({ workflow, projectRoot, agent: targetAgent }) : await applyWorkflowAdapter2({ workflow, projectRoot, agent: targetAgent });
214602
- return text({
215303
+ return text2({
214603
215304
  workflowId: workflow.id,
214604
215305
  agent: targetAgent,
214605
215306
  status: result.status,
@@ -214610,8 +215311,8 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214610
215311
  }
214611
215312
  if (action === "workflow_run") {
214612
215313
  const runTask = requireText(task, "task");
214613
- if (!runTask) return text({ error: "task is required for workflow_run." }, true);
214614
- if (!outcome) return text({ error: "outcome is required for workflow_run." }, true);
215314
+ if (!runTask) return text2({ error: "task is required for workflow_run." }, true);
215315
+ if (!outcome) return text2({ error: "outcome is required for workflow_run." }, true);
214615
215316
  const result = await recordWorkflowRun2({
214616
215317
  workspace,
214617
215318
  run: {
@@ -214625,14 +215326,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
214625
215326
  selectedEvidence: [...new Set((evidenceIds ?? []).map((item) => item.trim()).filter(Boolean))]
214626
215327
  }
214627
215328
  });
214628
- return text({
215329
+ return text2({
214629
215330
  id: result.id,
214630
215331
  workflowId: result.workflowId,
214631
215332
  outcome: result.outcome,
214632
215333
  verificationVerdict: result.verificationVerdict
214633
215334
  });
214634
215335
  }
214635
- return text({ error: "Unsupported knowledge action." }, true);
215336
+ return text2({ error: "Unsupported knowledge action." }, true);
214636
215337
  }
214637
215338
  );
214638
215339
  server.registerTool(
@@ -216107,10 +216808,10 @@ Ensure the path points to a directory containing a .git folder (or a subdirector
216107
216808
  ];
216108
216809
  const allSkills = await loadMiniSkills2(projectDir2, project.id);
216109
216810
  const miniSkills = allSkills.filter((s3) => {
216110
- const text = `${s3.title}
216811
+ const text2 = `${s3.title}
216111
216812
  ${s3.sourceEntity}
216112
216813
  ${s3.instruction}`.toLowerCase();
216113
- return !SKILL_NOISE.some((p2) => p2.test(text));
216814
+ return !SKILL_NOISE.some((p2) => p2.test(text2));
216114
216815
  });
216115
216816
  if (miniSkills.length > 0) {
216116
216817
  const formatted = formatMiniSkillsForInjection2(miniSkills);
@@ -220114,7 +220815,7 @@ var init_serve_http = __esm({
220114
220815
  },
220115
220816
  run: async ({ args }) => {
220116
220817
  const { createServer: createServer3 } = await import("http");
220117
- const { randomUUID: randomUUID16 } = await import("crypto");
220818
+ const { randomUUID: randomUUID17 } = await import("crypto");
220118
220819
  const { StreamableHTTPServerTransport: StreamableHTTPServerTransport2 } = await Promise.resolve().then(() => (init_streamableHttp(), streamableHttp_exports));
220119
220820
  const { isInitializeRequest: isInitializeRequest2 } = await Promise.resolve().then(() => (init_types8(), types_exports3));
220120
220821
  const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
@@ -220287,7 +220988,7 @@ var init_serve_http = __esm({
220287
220988
  if (!sessionId && isInitializeRequest2(body)) {
220288
220989
  let createdState = null;
220289
220990
  const transport = new StreamableHTTPServerTransport2({
220290
- sessionIdGenerator: () => randomUUID16(),
220991
+ sessionIdGenerator: () => randomUUID17(),
220291
220992
  enableJsonResponse: true,
220292
220993
  onsessioninitialized: (sid) => {
220293
220994
  if (createdState) sessions.set(sid, createdState);
@@ -221824,21 +222525,21 @@ function isSignificantKnowledge(content) {
221824
222525
  if (!content || typeof content !== "string") {
221825
222526
  return { isSignificant: false, reason: "empty_content", confidence: 1 };
221826
222527
  }
221827
- const text = content.trim();
221828
- const textLower = text.toLowerCase();
222528
+ const text2 = content.trim();
222529
+ const textLower = text2.toLowerCase();
221829
222530
  for (const pattern of SKIP_PATTERNS2) {
221830
- if (pattern.test(text)) {
222531
+ if (pattern.test(text2)) {
221831
222532
  return { isSignificant: false, reason: "skip_pattern", confidence: 0.9 };
221832
222533
  }
221833
222534
  }
221834
222535
  for (const pattern of TECHNICAL_PATTERNS) {
221835
- if (pattern.test(text)) {
222536
+ if (pattern.test(text2)) {
221836
222537
  return { isSignificant: true, reason: "technical_pattern", confidence: 0.85 };
221837
222538
  }
221838
222539
  }
221839
222540
  let codePatternMatches = 0;
221840
222541
  for (const pattern of CODE_PATTERNS) {
221841
- if (pattern.test(text)) {
222542
+ if (pattern.test(text2)) {
221842
222543
  codePatternMatches++;
221843
222544
  }
221844
222545
  }
@@ -221858,14 +222559,14 @@ function isSignificantKnowledge(content) {
221858
222559
  return { isSignificant: true, reason: "moderate_technical_density", confidence: 0.6 };
221859
222560
  }
221860
222561
  }
221861
- if (text.length > 200) {
222562
+ if (text2.length > 200) {
221862
222563
  return { isSignificant: true, reason: "substantial_length", confidence: 0.5 };
221863
222564
  }
221864
222565
  return { isSignificant: false, reason: "no_technical_indicators", confidence: 0.6 };
221865
222566
  }
221866
222567
  function isRetrievedResult(content) {
221867
222568
  if (!content || typeof content !== "string") return false;
221868
- const text = content.toLowerCase();
222569
+ const text2 = content.toLowerCase();
221869
222570
  const retrievedPatterns = [
221870
222571
  /^(memorix_search|memorix_detail|memorix_timeline|search_nodes|read_graph):/i,
221871
222572
  /^(retrieved|result|results|found|matches|nodes|edges|search completed):/i,
@@ -221874,7 +222575,7 @@ function isRetrievedResult(content) {
221874
222575
  /^(totalresults:|searchtime:|tokens:)/i
221875
222576
  ];
221876
222577
  for (const pattern of retrievedPatterns) {
221877
- if (pattern.test(text)) {
222578
+ if (pattern.test(text2)) {
221878
222579
  return true;
221879
222580
  }
221880
222581
  }
@@ -224115,25 +224816,25 @@ function inferType(subject, body) {
224115
224816
  perf: "trade-off"
224116
224817
  };
224117
224818
  if (prefixMap[prefix]) return prefixMap[prefix];
224118
- const text = `${subject} ${body}`.toLowerCase();
224119
- if (/\b(fix|bug|crash|error|issue|hotfix|patch)\b/.test(text)) return "problem-solution";
224120
- if (/\b(feat|feature|add|implement|new)\b/.test(text)) return "what-changed";
224121
- if (/\b(refactor|clean|restructure|reorganize)\b/.test(text)) return "what-changed";
224122
- if (/\b(chore|bump|version|release|publish)\b/.test(text)) return "what-changed";
224123
- if (/\b(doc|readme|changelog)\b/.test(text)) return "how-it-works";
224124
- if (/\b(test|spec|e2e|coverage)\b/.test(text)) return "discovery";
224125
- if (/\b(ci|cd|workflow|deploy|docker)\b/.test(text)) return "what-changed";
224126
- if (/\b(security|vulnerability|cve)\b/.test(text)) return "gotcha";
224127
- if (/\b(revert|rollback)\b/.test(text)) return "problem-solution";
224128
- if (/\b(deprecat|remove|drop)\b/.test(text)) return "decision";
224129
- if (/\b(perf|optim|speed|cache)\b/.test(text)) return "trade-off";
224819
+ const text2 = `${subject} ${body}`.toLowerCase();
224820
+ if (/\b(fix|bug|crash|error|issue|hotfix|patch)\b/.test(text2)) return "problem-solution";
224821
+ if (/\b(feat|feature|add|implement|new)\b/.test(text2)) return "what-changed";
224822
+ if (/\b(refactor|clean|restructure|reorganize)\b/.test(text2)) return "what-changed";
224823
+ if (/\b(chore|bump|version|release|publish)\b/.test(text2)) return "what-changed";
224824
+ if (/\b(doc|readme|changelog)\b/.test(text2)) return "how-it-works";
224825
+ if (/\b(test|spec|e2e|coverage)\b/.test(text2)) return "discovery";
224826
+ if (/\b(ci|cd|workflow|deploy|docker)\b/.test(text2)) return "what-changed";
224827
+ if (/\b(security|vulnerability|cve)\b/.test(text2)) return "gotcha";
224828
+ if (/\b(revert|rollback)\b/.test(text2)) return "problem-solution";
224829
+ if (/\b(deprecat|remove|drop)\b/.test(text2)) return "decision";
224830
+ if (/\b(perf|optim|speed|cache)\b/.test(text2)) return "trade-off";
224130
224831
  return "what-changed";
224131
224832
  }
224132
224833
  function extractConcepts(commit) {
224133
224834
  const concepts = [];
224134
- const text = `${commit.subject} ${commit.body}`;
224835
+ const text2 = `${commit.subject} ${commit.body}`;
224135
224836
  const techPatterns = /\b(react|vue|angular|express|fastify|redis|postgres|mysql|docker|nginx|webpack|vite|tsup|vitest|jest)\b/gi;
224136
- for (const match2 of text.matchAll(techPatterns)) {
224837
+ for (const match2 of text2.matchAll(techPatterns)) {
224137
224838
  concepts.push(match2[0].toLowerCase());
224138
224839
  }
224139
224840
  const scopeMatch = commit.subject.match(/^\w+\(([^)]+)\)/);
@@ -224202,26 +224903,26 @@ function isAllFilesNoise(files, extraPatterns) {
224202
224903
  );
224203
224904
  }
224204
224905
  function matchesGlob(file2, pattern) {
224205
- const text = file2.replace(/\\/g, "/");
224906
+ const text2 = file2.replace(/\\/g, "/");
224206
224907
  const glob = pattern.replace(/\\/g, "/");
224207
224908
  if (!glob) return false;
224208
- let previous = new Array(text.length + 1).fill(false);
224909
+ let previous = new Array(text2.length + 1).fill(false);
224209
224910
  previous[0] = true;
224210
224911
  for (const token of glob) {
224211
- const current = new Array(text.length + 1).fill(false);
224912
+ const current = new Array(text2.length + 1).fill(false);
224212
224913
  if (token === "*") {
224213
224914
  current[0] = previous[0];
224214
- for (let index = 1; index <= text.length; index++) {
224915
+ for (let index = 1; index <= text2.length; index++) {
224215
224916
  current[index] = previous[index] || current[index - 1];
224216
224917
  }
224217
224918
  } else {
224218
- for (let index = 1; index <= text.length; index++) {
224219
- current[index] = previous[index - 1] && (token === "?" || token === text[index - 1]);
224919
+ for (let index = 1; index <= text2.length; index++) {
224920
+ current[index] = previous[index - 1] && (token === "?" || token === text2[index - 1]);
224220
224921
  }
224221
224922
  }
224222
224923
  previous = current;
224223
224924
  }
224224
- return previous[text.length];
224925
+ return previous[text2.length];
224225
224926
  }
224226
224927
  function shouldFilterCommit(commit, config2) {
224227
224928
  const skipMerge = config2?.skipMergeCommits ?? true;
@@ -226479,8 +227180,8 @@ async function inspectPlugin(agent, scope) {
226479
227180
  };
226480
227181
  }
226481
227182
  function looksLikeStaleMemorixCommand(server) {
226482
- const text = [server.command, ...server.args ?? []].join(" ");
226483
- return /[\\/]\.worktrees[\\/]/i.test(text) || /[\\/]dist[\\/]cli[\\/]index\.js/i.test(text);
227183
+ const text2 = [server.command, ...server.args ?? []].join(" ");
227184
+ return /[\\/]\.worktrees[\\/]/i.test(text2) || /[\\/]dist[\\/]cli[\\/]index\.js/i.test(text2);
226484
227185
  }
226485
227186
  function isRecommendedStdioServer(server) {
226486
227187
  const commandBase = basename5(server.command).toLowerCase().replace(/\.(cmd|ps1|exe)$/i, "");
@@ -227641,12 +228342,12 @@ function isLowQuality(title) {
227641
228342
  return LOW_QUALITY_PATTERNS.some((p2) => p2.test(title.trim()));
227642
228343
  }
227643
228344
  function isNoisePollution(obs) {
227644
- const text = [obs.title, obs.narrative, obs.entityName, ...obs.facts ?? [], ...obs.concepts ?? []].filter(Boolean).join("\n");
228345
+ const text2 = [obs.title, obs.narrative, obs.entityName, ...obs.facts ?? [], ...obs.concepts ?? []].filter(Boolean).join("\n");
227645
228346
  for (const p2 of SYSTEM_SELF_PATTERNS2) {
227646
- if (p2.test(text)) return { isNoise: true, reason: "system-self" };
228347
+ if (p2.test(text2)) return { isNoise: true, reason: "system-self" };
227647
228348
  }
227648
228349
  for (const p2 of NOISE_PATTERNS3) {
227649
- if (p2.test(text)) return { isNoise: true, reason: "demo/test/noise" };
228350
+ if (p2.test(text2)) return { isNoise: true, reason: "demo/test/noise" };
227650
228351
  }
227651
228352
  return { isNoise: false, reason: "" };
227652
228353
  }
@@ -228363,8 +229064,8 @@ var init_ring_buffer = __esm({
228363
229064
  }
228364
229065
  maxLines;
228365
229066
  lines = [];
228366
- push(text) {
228367
- for (const line of text.split("\n")) {
229067
+ push(text2) {
229068
+ for (const line of text2.split("\n")) {
228368
229069
  if (line.trim()) {
228369
229070
  this.lines.push(line);
228370
229071
  if (this.lines.length > this.maxLines) this.lines.shift();
@@ -228461,9 +229162,9 @@ function spawnAgentWithStream(command, args, opts, stdinData, onStdoutLine, onCo
228461
229162
  };
228462
229163
  let stdoutPartial = "";
228463
229164
  child.stdout?.on("data", (chunk) => {
228464
- const text = chunk.toString();
228465
- ring.push(text);
228466
- stdoutPartial += text;
229165
+ const text2 = chunk.toString();
229166
+ ring.push(text2);
229167
+ stdoutPartial += text2;
228467
229168
  const lines = stdoutPartial.split("\n");
228468
229169
  stdoutPartial = lines.pop() ?? "";
228469
229170
  for (const line of lines) {
@@ -229863,7 +230564,7 @@ function resetBackoff(taskId) {
229863
230564
  }
229864
230565
  function classifyError(ctx, taskId) {
229865
230566
  const { exitCode, killed, tailOutput, hasEndTurn } = ctx;
229866
- const text = tailOutput.slice(-2e3);
230567
+ const text2 = tailOutput.slice(-2e3);
229867
230568
  if (!killed && exitCode !== 0 && hasEndTurn === false) {
229868
230569
  return {
229869
230570
  category: "truncated",
@@ -229873,7 +230574,7 @@ function classifyError(ctx, taskId) {
229873
230574
  continuationPrompt: "Your previous output was truncated due to output limits. Continue from where you stopped. Do not repeat what you already wrote."
229874
230575
  };
229875
230576
  }
229876
- if (matchesAny(text, TRUNCATED_PATTERNS)) {
230577
+ if (matchesAny(text2, TRUNCATED_PATTERNS)) {
229877
230578
  return {
229878
230579
  category: "truncated",
229879
230580
  strategy: "continue",
@@ -229882,7 +230583,7 @@ function classifyError(ctx, taskId) {
229882
230583
  continuationPrompt: "Your previous output was truncated due to output limits. Continue from where you stopped. Do not repeat what you already wrote."
229883
230584
  };
229884
230585
  }
229885
- if (matchesAny(text, CONTEXT_OVERFLOW_PATTERNS)) {
230586
+ if (matchesAny(text2, CONTEXT_OVERFLOW_PATTERNS)) {
229886
230587
  return {
229887
230588
  category: "context_overflow",
229888
230589
  strategy: "compact_and_retry",
@@ -229890,7 +230591,7 @@ function classifyError(ctx, taskId) {
229890
230591
  reason: "Context overflow detected \u2014 prompt is too large for the model"
229891
230592
  };
229892
230593
  }
229893
- if (matchesAny(text, TRANSIENT_PATTERNS)) {
230594
+ if (matchesAny(text2, TRANSIENT_PATTERNS)) {
229894
230595
  const attempt = taskId ? (backoffState.get(taskId) ?? 0) + 1 : 1;
229895
230596
  if (taskId) backoffState.set(taskId, attempt);
229896
230597
  const baseDelay = 2e3;
@@ -229913,8 +230614,8 @@ function classifyError(ctx, taskId) {
229913
230614
  reason: killed ? "Agent killed by timeout" : `Agent exited with code ${exitCode}`
229914
230615
  };
229915
230616
  }
229916
- function matchesAny(text, patterns) {
229917
- return patterns.some((p2) => p2.test(text));
230617
+ function matchesAny(text2, patterns) {
230618
+ return patterns.some((p2) => p2.test(text2));
229918
230619
  }
229919
230620
  var TRUNCATED_PATTERNS, CONTEXT_OVERFLOW_PATTERNS, TRANSIENT_PATTERNS, backoffState;
229920
230621
  var init_error_recovery = __esm({
@@ -230452,8 +231153,8 @@ function storePipelineSummary(opts) {
230452
231153
  }
230453
231154
  })();
230454
231155
  }
230455
- function sanitizeErrorPattern(text) {
230456
- return text.replace(/[A-Z]:\\(?:[\w.-]+\\)+/gi, "./").replace(/\/(?:home|Users|var|tmp|opt)\/[\w.-]+\//g, "./").replace(/:(\d+):(\d+)/g, ":_:_").replace(/\bline\s+\d+/gi, "line _").replace(/node_modules\/[^\s]+/g, "node_modules/...");
231156
+ function sanitizeErrorPattern(text2) {
231157
+ return text2.replace(/[A-Z]:\\(?:[\w.-]+\\)+/gi, "./").replace(/\/(?:home|Users|var|tmp|opt)\/[\w.-]+\//g, "./").replace(/:(\d+):(\d+)/g, ":_:_").replace(/\bline\s+\d+/gi, "line _").replace(/node_modules\/[^\s]+/g, "node_modules/...");
230457
231158
  }
230458
231159
  function hashErrorPattern(errorOutput) {
230459
231160
  const sanitized = sanitizeErrorPattern(errorOutput).slice(0, 500);
@@ -231988,7 +232689,7 @@ var init_theme = __esm({
231988
232689
  check: "[OK]",
231989
232690
  cross: "[ERROR]",
231990
232691
  info: "[i]",
231991
- pill: (text) => `[${text}]`
232692
+ pill: (text2) => `[${text2}]`
231992
232693
  };
231993
232694
  EDGE_SYMBOLS = {
231994
232695
  supports: "->",
@@ -232116,27 +232817,27 @@ function isFullwidth(ch) {
232116
232817
  if (cp >= 128512 && cp <= 129535) return true;
232117
232818
  return false;
232118
232819
  }
232119
- function previousCursorPos(text, cursorPos) {
232820
+ function previousCursorPos(text2, cursorPos) {
232120
232821
  let start = 0;
232121
- for (const ch of text) {
232822
+ for (const ch of text2) {
232122
232823
  const end = start + ch.length;
232123
232824
  if (end >= cursorPos) return start;
232124
232825
  start = end;
232125
232826
  }
232126
232827
  return 0;
232127
232828
  }
232128
- function nextCursorPos(text, cursorPos) {
232829
+ function nextCursorPos(text2, cursorPos) {
232129
232830
  let start = 0;
232130
- for (const ch of text) {
232831
+ for (const ch of text2) {
232131
232832
  const end = start + ch.length;
232132
232833
  if (start >= cursorPos) return end;
232133
232834
  if (end > cursorPos) return end;
232134
232835
  start = end;
232135
232836
  }
232136
- return text.length;
232837
+ return text2.length;
232137
232838
  }
232138
- function getCharacterAt(text, cursorPos) {
232139
- const codePoint = text.codePointAt(cursorPos);
232839
+ function getCharacterAt(text2, cursorPos) {
232840
+ const codePoint = text2.codePointAt(cursorPos);
232140
232841
  return codePoint === void 0 ? "" : String.fromCodePoint(codePoint);
232141
232842
  }
232142
232843
  function CommandBar({
@@ -232366,9 +233067,9 @@ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-run
232366
233067
  function separator(width = 50) {
232367
233068
  return SEP.thin.repeat(width);
232368
233069
  }
232369
- function truncate2(text, max = 60) {
232370
- if (text.length <= max) return text;
232371
- return `${text.slice(0, max)}\u2026`;
233070
+ function truncate2(text2, max = 60) {
233071
+ if (text2.length <= max) return text2;
233072
+ return `${text2.slice(0, max)}\u2026`;
232372
233073
  }
232373
233074
  function RecentView({ recentMemories, loading }) {
232374
233075
  const filtered = recentMemories.filter((memory) => !DEV_NOISE_PATTERNS.some((pattern) => pattern.test(memory.title)));
@@ -233300,9 +234001,9 @@ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
233300
234001
  function separator4(width = 50) {
233301
234002
  return SEP.thin.repeat(width);
233302
234003
  }
233303
- function truncate3(text, max = 80) {
233304
- if (text.length <= max) return text;
233305
- return `${text.slice(0, max)}...`;
234004
+ function truncate3(text2, max = 80) {
234005
+ if (text2.length <= max) return text2;
234006
+ return `${text2.slice(0, max)}...`;
233306
234007
  }
233307
234008
  function KnowledgeView({ knowledge, loading, selectedItemIdx, itemCount }) {
233308
234009
  if (loading) {
@@ -233496,9 +234197,9 @@ function formatEmbeddingLabel(status, providerName) {
233496
234197
  if (providerName) return "Local ready";
233497
234198
  return "Ready";
233498
234199
  }
233499
- function truncate4(text, max = 60) {
233500
- if (text.length <= max) return text;
233501
- return `${text.slice(0, max)}...`;
234200
+ function truncate4(text2, max = 60) {
234201
+ if (text2.length <= max) return text2;
234202
+ return `${text2.slice(0, max)}...`;
233502
234203
  }
233503
234204
  async function getProjectInfo() {
233504
234205
  try {
@@ -233656,7 +234357,7 @@ async function searchMemories(query, limit2 = 10) {
233656
234357
  return [];
233657
234358
  }
233658
234359
  }
233659
- async function storeQuickMemory(text) {
234360
+ async function storeQuickMemory(text2) {
233660
234361
  try {
233661
234362
  const { initObservations: initObservations2, storeObservation: storeObservation2 } = await Promise.resolve().then(() => (init_observations(), observations_exports));
233662
234363
  const { initObservationStore: initObservationStore2 } = await Promise.resolve().then(() => (init_obs_store(), obs_store_exports));
@@ -233666,15 +234367,15 @@ async function storeQuickMemory(text) {
233666
234367
  const result = await storeObservation2({
233667
234368
  entityName: "quick-note",
233668
234369
  type: "discovery",
233669
- title: text.slice(0, 100),
233670
- narrative: text,
234370
+ title: text2.slice(0, 100),
234371
+ narrative: text2,
233671
234372
  facts: [],
233672
234373
  projectId: proj.id,
233673
234374
  sourceDetail: "explicit",
233674
234375
  visibilityReader: reader,
233675
234376
  ...identity ? { createdByAgentId: identity.agentId } : {}
233676
234377
  });
233677
- return { id: result.observation.id, title: text.slice(0, 100) };
234378
+ return { id: result.observation.id, title: text2.slice(0, 100) };
233678
234379
  } catch {
233679
234380
  return null;
233680
234381
  }
@@ -233872,9 +234573,9 @@ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
233872
234573
  function separator5(width = 50) {
233873
234574
  return SEP.thin.repeat(width);
233874
234575
  }
233875
- function truncate5(text, max = 60) {
233876
- if (text.length <= max) return text;
233877
- return `${text.slice(0, max)}...`;
234576
+ function truncate5(text2, max = 60) {
234577
+ if (text2.length <= max) return text2;
234578
+ return `${text2.slice(0, max)}...`;
233878
234579
  }
233879
234580
  function MemoryView({ projectId, focusRefId, selectedIdx, onNavigateKnowledge, inputFocused }) {
233880
234581
  const [mode, setMode] = useState3("browse");
@@ -234075,9 +234776,9 @@ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
234075
234776
  function separator6(width) {
234076
234777
  return SEP.thin.repeat(Math.max(12, Math.min(width, 72)));
234077
234778
  }
234078
- function truncate6(text, max) {
234079
- if (text.length <= max) return text;
234080
- return `${text.slice(0, max - 1)}\u2026`;
234779
+ function truncate6(text2, max) {
234780
+ if (text2.length <= max) return text2;
234781
+ return `${text2.slice(0, max - 1)}\u2026`;
234081
234782
  }
234082
234783
  function displayWidth(str3) {
234083
234784
  let w3 = 0;
@@ -234091,12 +234792,12 @@ function displayWidth(str3) {
234091
234792
  }
234092
234793
  return w3;
234093
234794
  }
234094
- function cjkAwareLines(text, maxCols) {
234095
- if (maxCols < 4) return [text];
234795
+ function cjkAwareLines(text2, maxCols) {
234796
+ if (maxCols < 4) return [text2];
234096
234797
  const lines = [];
234097
234798
  let line = "";
234098
234799
  let lineW = 0;
234099
- for (const ch of text) {
234800
+ for (const ch of text2) {
234100
234801
  if (ch === "\n") {
234101
234802
  lines.push(line);
234102
234803
  line = "";
@@ -234254,9 +234955,9 @@ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
234254
234955
  function separator7(width = 50) {
234255
234956
  return SEP.thin.repeat(width);
234256
234957
  }
234257
- function truncate7(text, max = 80) {
234258
- if (text.length <= max) return text;
234259
- return `${text.slice(0, max)}...`;
234958
+ function truncate7(text2, max = 80) {
234959
+ if (text2.length <= max) return text2;
234960
+ return `${text2.slice(0, max)}...`;
234260
234961
  }
234261
234962
  function WorkbenchView({ project, contentWidth, viewportHeight, inputFocused }) {
234262
234963
  const MAX_CHAT_MESSAGES = 100;
@@ -234344,12 +235045,12 @@ function WorkbenchView({ project, contentWidth, viewportHeight, inputFocused })
234344
235045
  });
234345
235046
  try {
234346
235047
  const result = await askMemoryQuestionStream(trimmed, history, {
234347
- onChunk: (text) => {
235048
+ onChunk: (text2) => {
234348
235049
  setChatMessages((prev) => {
234349
235050
  const updated = [...prev];
234350
235051
  const lastIdx = updated.length - 1;
234351
235052
  if (lastIdx >= 0 && updated[lastIdx].role === "assistant") {
234352
- updated[lastIdx] = { ...updated[lastIdx], content: updated[lastIdx].content + text };
235053
+ updated[lastIdx] = { ...updated[lastIdx], content: updated[lastIdx].content + text2 };
234353
235054
  }
234354
235055
  return updated;
234355
235056
  });
@@ -234488,9 +235189,9 @@ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
234488
235189
  function separator8(width = 50) {
234489
235190
  return SEP.thin.repeat(width);
234490
235191
  }
234491
- function truncate8(text, max = 80) {
234492
- if (text.length <= max) return text;
234493
- return `${text.slice(0, max)}...`;
235192
+ function truncate8(text2, max = 80) {
235193
+ if (text2.length <= max) return text2;
235194
+ return `${text2.slice(0, max)}...`;
234494
235195
  }
234495
235196
  function GraphView({ projectId, inputFocused, onNavigateKnowledge }) {
234496
235197
  const [graph, setGraph] = useState5(null);
@@ -234809,18 +235510,18 @@ function charWidth(ch) {
234809
235510
  const cp = ch.codePointAt(0);
234810
235511
  return cp >= 19968 && cp <= 40959 || cp >= 12352 && cp <= 12543 || cp >= 44032 && cp <= 55215 || cp >= 65281 && cp <= 65376 || cp >= 13312 && cp <= 19903 ? 2 : 1;
234811
235512
  }
234812
- function fit(text, max) {
235513
+ function fit(text2, max) {
234813
235514
  if (max <= 0) return "";
234814
235515
  let w3 = 0;
234815
- for (const ch of text) {
235516
+ for (const ch of text2) {
234816
235517
  w3 += charWidth(ch);
234817
235518
  if (w3 > max) break;
234818
235519
  }
234819
- if (w3 <= max) return text.padEnd(text.length + (max - w3));
235520
+ if (w3 <= max) return text2.padEnd(text2.length + (max - w3));
234820
235521
  if (max === 1) return "\u2026";
234821
235522
  let result = "";
234822
235523
  let rw = 0;
234823
- for (const ch of text) {
235524
+ for (const ch of text2) {
234824
235525
  const cw = charWidth(ch);
234825
235526
  if (rw + cw > max - 1) break;
234826
235527
  result += ch;
@@ -234896,9 +235597,9 @@ __export(chat_store_exports, {
234896
235597
  ChatTranscriptStore: () => ChatTranscriptStore,
234897
235598
  getChatStore: () => getChatStore
234898
235599
  });
234899
- function safeJsonParse4(text, fallback) {
235600
+ function safeJsonParse4(text2, fallback) {
234900
235601
  try {
234901
- return JSON.parse(text);
235602
+ return JSON.parse(text2);
234902
235603
  } catch {
234903
235604
  return fallback;
234904
235605
  }
@@ -235258,12 +235959,12 @@ function WorkbenchApp({ version: version2, onExitForInteractive }) {
235258
235959
  });
235259
235960
  try {
235260
235961
  const result = await askMemoryQuestionStream(trimmed, history, {
235261
- onChunk: (text) => {
235962
+ onChunk: (text2) => {
235262
235963
  setChatMessages((prev) => {
235263
235964
  const updated = [...prev];
235264
235965
  const lastIdx = updated.length - 1;
235265
235966
  if (lastIdx >= 0 && updated[lastIdx].role === "assistant") {
235266
- updated[lastIdx] = { ...updated[lastIdx], content: updated[lastIdx].content + text };
235967
+ updated[lastIdx] = { ...updated[lastIdx], content: updated[lastIdx].content + text2 };
235267
235968
  }
235268
235969
  return updated;
235269
235970
  });
@@ -236014,11 +236715,11 @@ ${hookScript}`, "utf-8");
236014
236715
  };
236015
236716
  const renderOverlayContent = () => {
236016
236717
  if (!overlayView) return null;
236017
- const fitInline = (text, max) => {
236718
+ const fitInline = (text2, max) => {
236018
236719
  if (max <= 0) return "";
236019
- if (text.length <= max) return text;
236720
+ if (text2.length <= max) return text2;
236020
236721
  if (max === 1) return ".";
236021
- return `${text.slice(0, max - 1)}.`;
236722
+ return `${text2.slice(0, max - 1)}.`;
236022
236723
  };
236023
236724
  switch (overlayView) {
236024
236725
  case "chat":