@cortexkit/pi-magic-context 0.21.1 → 0.21.4

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/index.js CHANGED
@@ -8163,10 +8163,10 @@ var require_stringify = __commonJS((exports, module) => {
8163
8163
  replacer = null;
8164
8164
  indent = EMPTY;
8165
8165
  };
8166
- var join8 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
8166
+ var join9 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
8167
8167
  var join_content = (inside, value, gap) => {
8168
8168
  const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
8169
- return join8(comment, inside, gap);
8169
+ return join9(comment, inside, gap);
8170
8170
  };
8171
8171
  var stringify_string = (holder, key, value) => {
8172
8172
  const raw = get_raw_string_literal(holder, key);
@@ -8188,13 +8188,13 @@ var require_stringify = __commonJS((exports, module) => {
8188
8188
  if (i !== 0) {
8189
8189
  inside += COMMA;
8190
8190
  }
8191
- const before = join8(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
8191
+ const before = join9(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
8192
8192
  inside += before || LF + deeper_gap;
8193
8193
  inside += stringify(i, value, deeper_gap) || STR_NULL;
8194
8194
  inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
8195
8195
  after_comma = process_comments(value, AFTER(i), deeper_gap);
8196
8196
  }
8197
- inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8197
+ inside += join9(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8198
8198
  return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
8199
8199
  };
8200
8200
  var object_stringify = (value, gap) => {
@@ -8215,13 +8215,13 @@ var require_stringify = __commonJS((exports, module) => {
8215
8215
  inside += COMMA;
8216
8216
  }
8217
8217
  first = false;
8218
- const before = join8(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
8218
+ const before = join9(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
8219
8219
  inside += before || LF + deeper_gap;
8220
8220
  inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
8221
8221
  after_comma = process_comments(value, AFTER(key), deeper_gap);
8222
8222
  };
8223
8223
  keys.forEach(iteratee);
8224
- inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8224
+ inside += join9(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
8225
8225
  return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
8226
8226
  };
8227
8227
  function stringify(key, holder, gap) {
@@ -8342,8 +8342,8 @@ var init_rpc_notifications = __esm(() => {
8342
8342
  });
8343
8343
 
8344
8344
  // src/index.ts
8345
- import { createRequire as createRequire3 } from "node:module";
8346
- import { join as join18 } from "node:path";
8345
+ import { createRequire as createRequire4 } from "node:module";
8346
+ import { join as join19 } from "node:path";
8347
8347
 
8348
8348
  // ../plugin/src/features/magic-context/memory/project-identity.ts
8349
8349
  import { execSync } from "node:child_process";
@@ -145216,9 +145216,22 @@ init_logger();
145216
145216
  // src/subagent-runner.ts
145217
145217
  import * as childProcess from "node:child_process";
145218
145218
  import { existsSync as existsSync6 } from "node:fs";
145219
- import { dirname as dirname3, resolve as resolvePath } from "node:path";
145219
+ import { createRequire as createRequire3 } from "node:module";
145220
+ import { dirname as dirname3, join as join8, resolve as resolvePath } from "node:path";
145220
145221
  import { createInterface } from "node:readline";
145221
145222
  import { fileURLToPath } from "node:url";
145223
+ function resolveBundledPiCli() {
145224
+ try {
145225
+ const require_ = createRequire3(import.meta.url);
145226
+ const pkgJson = require_.resolve("@earendil-works/pi-coding-agent/package.json");
145227
+ const cliPath = join8(dirname3(pkgJson), "dist/cli.js");
145228
+ if (existsSync6(cliPath))
145229
+ return cliPath;
145230
+ return null;
145231
+ } catch {
145232
+ return null;
145233
+ }
145234
+ }
145222
145235
  function resolveSubagentEntryPath() {
145223
145236
  try {
145224
145237
  const here = dirname3(fileURLToPath(import.meta.url));
@@ -145242,7 +145255,16 @@ class PiSubagentRunner {
145242
145255
  piBinary;
145243
145256
  spawnImpl;
145244
145257
  constructor(options = {}) {
145245
- this.piBinary = options.piBinary ?? "pi";
145258
+ if (options.piBinary) {
145259
+ this.piBinary = options.piBinary;
145260
+ } else {
145261
+ const bundled = resolveBundledPiCli();
145262
+ if (bundled) {
145263
+ this.piBinary = bundled;
145264
+ } else {
145265
+ this.piBinary = "pi";
145266
+ }
145267
+ }
145246
145268
  this.spawnImpl = options.spawnImpl ?? childProcess.spawn;
145247
145269
  }
145248
145270
  async run(options) {
@@ -145853,7 +145875,7 @@ function clearStaleEntries(db, maxAgeMs) {
145853
145875
  init_logger();
145854
145876
  // ../plugin/src/features/magic-context/dreamer/runner.ts
145855
145877
  import { existsSync as existsSync8 } from "node:fs";
145856
- import { join as join10 } from "node:path";
145878
+ import { join as join11 } from "node:path";
145857
145879
 
145858
145880
  // ../plugin/src/shared/index.ts
145859
145881
  init_logger();
@@ -146148,14 +146170,14 @@ await init_sqlite();
146148
146170
 
146149
146171
  // ../plugin/src/features/magic-context/key-files/identify-key-files.ts
146150
146172
  import { readFileSync as readFileSync4 } from "node:fs";
146151
- import { join as join9 } from "node:path";
146173
+ import { join as join10 } from "node:path";
146152
146174
  init_logger();
146153
146175
 
146154
146176
  // ../plugin/src/features/magic-context/key-files/aft-availability.ts
146155
146177
  var import_comment_json = __toESM(require_src2(), 1);
146156
146178
  import { existsSync as existsSync7, readFileSync as readFileSync3 } from "node:fs";
146157
146179
  import { homedir as homedir3 } from "node:os";
146158
- import { join as join8 } from "node:path";
146180
+ import { join as join9 } from "node:path";
146159
146181
  var overrideAvailability = null;
146160
146182
  function parseConfig(path5) {
146161
146183
  if (!existsSync7(path5))
@@ -146182,10 +146204,10 @@ function hasAftAtKeys(value, keys) {
146182
146204
  function getAftAvailability() {
146183
146205
  const home = process.env.HOME || homedir3();
146184
146206
  const opencodePaths = [
146185
- join8(home, ".config", "opencode", "opencode.jsonc"),
146186
- join8(home, ".config", "opencode", "opencode.json")
146207
+ join9(home, ".config", "opencode", "opencode.jsonc"),
146208
+ join9(home, ".config", "opencode", "opencode.json")
146187
146209
  ];
146188
- const piPaths = [join8(home, ".pi", "agent", "settings.json")];
146210
+ const piPaths = [join9(home, ".pi", "agent", "settings.json")];
146189
146211
  const checkedPaths = [...opencodePaths, ...piPaths];
146190
146212
  let opencode = false;
146191
146213
  for (const path5 of opencodePaths) {
@@ -146275,6 +146297,43 @@ function normalizeProjectRelativePath(projectPath, filePath) {
146275
146297
  return null;
146276
146298
  return rel;
146277
146299
  }
146300
+ function isDocumentationOrMetaFile(rel) {
146301
+ const lower = rel.toLowerCase();
146302
+ if (lower.endsWith(".md") || lower.endsWith(".mdx") || lower.endsWith(".rst"))
146303
+ return true;
146304
+ if (lower.endsWith(".txt"))
146305
+ return true;
146306
+ const base = lower.split("/").pop() ?? "";
146307
+ const baseNoExt = base.replace(/\.[^.]+$/, "");
146308
+ const META_BASENAMES = new Set([
146309
+ "license",
146310
+ "licence",
146311
+ "notice",
146312
+ "copying",
146313
+ "authors",
146314
+ "contributors",
146315
+ "changelog",
146316
+ "changes",
146317
+ "history",
146318
+ "readme",
146319
+ "contributing",
146320
+ "code_of_conduct",
146321
+ "security",
146322
+ "support",
146323
+ "maintainers",
146324
+ "governance",
146325
+ "package-lock",
146326
+ "bun.lock",
146327
+ "bun.lockb",
146328
+ "yarn.lock",
146329
+ "pnpm-lock",
146330
+ "cargo.lock",
146331
+ "uv.lock",
146332
+ "poetry.lock",
146333
+ "gemfile.lock"
146334
+ ]);
146335
+ return META_BASENAMES.has(base) || META_BASENAMES.has(baseNoExt);
146336
+ }
146278
146337
  function primarySessionIds(db) {
146279
146338
  try {
146280
146339
  const rows = db.prepare("SELECT session_id AS sessionId FROM session_meta WHERE is_subagent = 0").all();
@@ -146306,6 +146365,8 @@ function collectKeyFileCandidates(args) {
146306
146365
  const rel = normalizeProjectRelativePath(args.projectPath, row.file_path);
146307
146366
  if (!rel)
146308
146367
  continue;
146368
+ if (isDocumentationOrMetaFile(rel))
146369
+ continue;
146309
146370
  const timestamp = toMs(row.time_created);
146310
146371
  const candidate = byPath.get(rel) ?? {
146311
146372
  path: rel,
@@ -146442,7 +146503,8 @@ Rules:
146442
146503
  - Total approx_token_estimate must be < ${args.config.token_budget}.
146443
146504
  - path must be relative, no .., no absolute paths, no symlinks escaping project root.
146444
146505
  - path must be unique case-sensitively and case-insensitively.
146445
- - content must be plain text; no XML tags inside.`;
146506
+ - content must be plain text; no XML tags inside.
146507
+ - DO NOT pick prose documentation (README.md, CONTRIBUTING.md, CHANGELOG, LICENSE, *.md/*.mdx/*.rst/*.txt) or lockfiles. Key files are project SOURCE the agent needs repeated orientation context on, not reference docs. Project docs are surfaced through a separate injection path.`;
146446
146508
  }
146447
146509
  function validateLlmOutput(raw, config, projectPath) {
146448
146510
  let obj;
@@ -146572,7 +146634,7 @@ async function runKeyFilesLlm(args) {
146572
146634
  });
146573
146635
  const messagesResponse = await args.client.session.messages({
146574
146636
  path: { id: agentSessionId },
146575
- query: { directory: args.projectPath }
146637
+ query: { directory: args.projectPath, limit: 50 }
146576
146638
  });
146577
146639
  const messages = normalizeSDKResponse(messagesResponse, [], {
146578
146640
  preferResponseOnMissingData: true
@@ -146609,7 +146671,7 @@ async function runKeyFilesTask(args) {
146609
146671
  if (row.staleReason !== null || row.generationConfigHash !== configHash)
146610
146672
  return false;
146611
146673
  try {
146612
- return sha256(readFileSync4(join9(projectPath, row.path))) === row.contentHash;
146674
+ return sha256(readFileSync4(join10(projectPath, row.path))) === row.contentHash;
146613
146675
  } catch {
146614
146676
  return false;
146615
146677
  }
@@ -147680,7 +147742,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
147680
147742
  });
147681
147743
  const messagesResponse = await args.client.session.messages({
147682
147744
  path: { id: agentSessionId },
147683
- query: { directory: args.sessionDirectory }
147745
+ query: { directory: args.sessionDirectory, limit: 50 }
147684
147746
  });
147685
147747
  const messages = normalizeSDKResponse(messagesResponse, [], {
147686
147748
  preferResponseOnMissingData: true
@@ -147806,7 +147868,7 @@ function logWithStackHead(message, stackHead) {
147806
147868
  log(message, stackHead ? { stackHead } : undefined);
147807
147869
  }
147808
147870
  function getOpenCodeDbPath2() {
147809
- return join10(getDataDir(), "opencode", "opencode.db");
147871
+ return join11(getDataDir(), "opencode", "opencode.db");
147810
147872
  }
147811
147873
  function openOpenCodeDb() {
147812
147874
  const dbPath = getOpenCodeDbPath2();
@@ -147941,8 +148003,8 @@ async function runDream(args) {
147941
148003
  try {
147942
148004
  const docsDir = args.sessionDirectory ?? args.projectIdentity;
147943
148005
  const existingDocs = taskName === "maintain-docs" ? {
147944
- architecture: existsSync8(join10(docsDir, "ARCHITECTURE.md")),
147945
- structure: existsSync8(join10(docsDir, "STRUCTURE.md"))
148006
+ architecture: existsSync8(join11(docsDir, "ARCHITECTURE.md")),
148007
+ structure: existsSync8(join11(docsDir, "STRUCTURE.md"))
147946
148008
  } : undefined;
147947
148009
  const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
147948
148010
  id: um.id,
@@ -147986,7 +148048,7 @@ async function runDream(args) {
147986
148048
  }
147987
148049
  const messagesResponse = await args.client.session.messages({
147988
148050
  path: { id: agentSessionId },
147989
- query: { directory: args.sessionDirectory ?? args.projectIdentity }
148051
+ query: { directory: args.sessionDirectory ?? args.projectIdentity, limit: 50 }
147990
148052
  });
147991
148053
  const messages = normalizeSDKResponse(messagesResponse, [], {
147992
148054
  preferResponseOnMissingData: true
@@ -148247,6 +148309,13 @@ async function evaluateSmartNotes(args) {
148247
148309
  For each note below, determine whether its surface condition has been met.
148248
148310
  You have access to tools like GitHub CLI (gh), web search, and the local codebase to verify conditions.
148249
148311
 
148312
+ You DO NOT have access to:
148313
+ - Any conversation between the user and the original agent that wrote the note
148314
+ - The state of any active session, including whether messages have been sent
148315
+ - The current task, mood, or intent of the human user
148316
+
148317
+ If a condition references conversation context the user is having ("When the user mentions X", "When they ask to do Y", "When we revisit Z", "When relevant to current discussion", etc.), it is UNEVALUATABLE — skip it (do not include in results) so the note stays pending. These are misuse cases that should never have been written as smart notes; leaving them pending is the correct outcome, the dreamer's archive-stale task will eventually retire them.
148318
+
148250
148319
  ## Pending Smart Notes
148251
148320
 
148252
148321
  ${noteDescriptions}
@@ -148255,7 +148324,8 @@ ${noteDescriptions}
148255
148324
 
148256
148325
  1. Check each condition using the tools available to you.
148257
148326
  2. Be conservative — only mark a condition as met when you have clear evidence.
148258
- 3. Respond with a JSON array of results:
148327
+ 3. Skip conditions that depend on session/conversation context you cannot observe — do not invent a "false" verdict for them, just omit them from your response.
148328
+ 4. Respond with a JSON array of results:
148259
148329
 
148260
148330
  \`\`\`json
148261
148331
  [
@@ -148263,7 +148333,7 @@ ${noteDescriptions}
148263
148333
  ]
148264
148334
  \`\`\`
148265
148335
 
148266
- Only include notes whose conditions you could definitively evaluate. Skip notes where you cannot determine the status (they will be re-evaluated next run).`;
148336
+ Only include notes whose conditions you could definitively evaluate against external signals. Skip notes where you cannot determine the status (they will be re-evaluated next run, or eventually archived as stale).`;
148267
148337
  const taskStartedAt = Date.now();
148268
148338
  let agentSessionId = null;
148269
148339
  const abortController = new AbortController;
@@ -148309,7 +148379,7 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
148309
148379
  });
148310
148380
  const messagesResponse = await args.client.session.messages({
148311
148381
  path: { id: agentSessionId },
148312
- query: { directory: args.sessionDirectory ?? args.projectIdentity }
148382
+ query: { directory: args.sessionDirectory ?? args.projectIdentity, limit: 50 }
148313
148383
  });
148314
148384
  const messages = normalizeSDKResponse(messagesResponse, [], {
148315
148385
  preferResponseOnMissingData: true
@@ -163017,7 +163087,6 @@ var MagicContextConfigSchema = exports_external.object({
163017
163087
  enabled: exports_external.boolean().default(true),
163018
163088
  min_clusters: exports_external.number().min(1).default(3)
163019
163089
  }).default({ enabled: true, min_clusters: 3 }),
163020
- compaction_markers: exports_external.boolean().default(true),
163021
163090
  system_prompt_injection: exports_external.object({
163022
163091
  enabled: exports_external.boolean().default(true),
163023
163092
  skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
@@ -163130,7 +163199,7 @@ function getEmbeddingProviderIdentity(config2) {
163130
163199
  // ../plugin/src/features/magic-context/memory/embedding-local.ts
163131
163200
  import { mkdirSync as mkdirSync4 } from "node:fs";
163132
163201
  import { open, stat, unlink, writeFile } from "node:fs/promises";
163133
- import { dirname as dirname4, join as join11 } from "node:path";
163202
+ import { dirname as dirname4, join as join12 } from "node:path";
163134
163203
  import { pathToFileURL } from "node:url";
163135
163204
  init_data_path();
163136
163205
  init_logger();
@@ -163197,7 +163266,7 @@ async function injectWasmOrtForElectron() {
163197
163266
  const { createRequire: createRequireFn } = await import("node:module");
163198
163267
  const requireFn = createRequireFn(import.meta.url);
163199
163268
  const pkgPath = requireFn.resolve("onnxruntime-web/package.json");
163200
- const distDir = join11(dirname4(pkgPath), "dist");
163269
+ const distDir = join12(dirname4(pkgPath), "dist");
163201
163270
  const wasmPathsPrefix = `${pathToFileURL(distDir).href}/`;
163202
163271
  if (ortWeb.env?.wasm) {
163203
163272
  ortWeb.env.wasm.wasmPaths = wasmPathsPrefix;
@@ -163308,7 +163377,7 @@ class LocalEmbeddingProvider {
163308
163377
  if (LogLevel && "ERROR" in LogLevel) {
163309
163378
  env.logLevel = LogLevel.ERROR;
163310
163379
  }
163311
- const modelCacheDir = join11(getMagicContextStorageDir(), "models");
163380
+ const modelCacheDir = join12(getMagicContextStorageDir(), "models");
163312
163381
  try {
163313
163382
  mkdirSync4(modelCacheDir, { recursive: true });
163314
163383
  env.cacheDir = modelCacheDir;
@@ -163316,7 +163385,7 @@ class LocalEmbeddingProvider {
163316
163385
  log("[magic-context] could not create model cache dir, using library default");
163317
163386
  }
163318
163387
  const createPipeline = transformersModule.pipeline;
163319
- const lockPath = join11(modelCacheDir, ".load.lock");
163388
+ const lockPath = join12(modelCacheDir, ".load.lock");
163320
163389
  const releaseLock = await acquireModelLoadLock(lockPath);
163321
163390
  const stopHeartbeat = startLockHeartbeat(lockPath);
163322
163391
  try {
@@ -164670,7 +164739,7 @@ function handleUntrustedLoad(db, projectIdentity, directory, detailed) {
164670
164739
  // src/config/index.ts
164671
164740
  import { existsSync as existsSync10, readFileSync as readFileSync6 } from "node:fs";
164672
164741
  import { homedir as homedir5 } from "node:os";
164673
- import { join as join12 } from "node:path";
164742
+ import { join as join13 } from "node:path";
164674
164743
 
164675
164744
  // ../plugin/src/config/variable.ts
164676
164745
  import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
@@ -164738,12 +164807,12 @@ function substituteConfigVariables(input) {
164738
164807
  var import_comment_json2 = __toESM(require_src2(), 1);
164739
164808
  var CONFIG_FILE_NAME = "magic-context";
164740
164809
  function getProjectConfigPaths(cwd) {
164741
- const basePath = join12(cwd, ".pi", CONFIG_FILE_NAME);
164810
+ const basePath = join13(cwd, ".pi", CONFIG_FILE_NAME);
164742
164811
  return [`${basePath}.jsonc`, `${basePath}.json`];
164743
164812
  }
164744
164813
  function getUserConfigPaths() {
164745
164814
  const home = process.env.HOME ?? homedir5();
164746
- const basePath = join12(home, ".pi", "agent", CONFIG_FILE_NAME);
164815
+ const basePath = join13(home, ".pi", "agent", CONFIG_FILE_NAME);
164747
164816
  return [`${basePath}.jsonc`, `${basePath}.json`];
164748
164817
  }
164749
164818
  function resolveFirstExisting(paths) {
@@ -169243,7 +169312,7 @@ function getReducedRecompTokenBudget(currentBudget) {
169243
169312
  // ../plugin/src/hooks/magic-context/historian-state-file.ts
169244
169313
  init_data_path();
169245
169314
  import { mkdirSync as mkdirSync5, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
169246
- import { join as join13 } from "node:path";
169315
+ import { join as join14 } from "node:path";
169247
169316
  var HISTORIAN_STATE_INLINE_THRESHOLD = 30000;
169248
169317
  function maybeWriteHistorianStateFile(sessionId, existingState, directory) {
169249
169318
  if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
@@ -169251,7 +169320,7 @@ function maybeWriteHistorianStateFile(sessionId, existingState, directory) {
169251
169320
  try {
169252
169321
  const dir = getProjectMagicContextHistorianDir(directory);
169253
169322
  mkdirSync5(dir, { recursive: true });
169254
- const path5 = join13(dir, `state-${sessionId}-${Date.now()}.xml`);
169323
+ const path5 = join14(dir, `state-${sessionId}-${Date.now()}.xml`);
169255
169324
  writeFileSync2(path5, existingState, "utf8");
169256
169325
  return path5;
169257
169326
  } catch {
@@ -170211,7 +170280,7 @@ function stripPiDroppedPlaceholderMessages(args) {
170211
170280
  // src/system-prompt.ts
170212
170281
  import { createHash as createHash8 } from "node:crypto";
170213
170282
  import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
170214
- import { join as join15 } from "node:path";
170283
+ import { join as join16 } from "node:path";
170215
170284
 
170216
170285
  // ../plugin/src/agents/magic-context-prompt.ts
170217
170286
  function getToolHistoryGuidance(dropToolStructure) {
@@ -170302,7 +170371,7 @@ Prefer many small targeted operations over one large blanket operation. Compress
170302
170371
 
170303
170372
  // ../plugin/src/hooks/magic-context/key-files-block.ts
170304
170373
  import { readFileSync as readFileSync7, realpathSync as realpathSync3 } from "node:fs";
170305
- import { join as join14, sep as sep2 } from "node:path";
170374
+ import { join as join15, sep as sep2 } from "node:path";
170306
170375
  init_logger();
170307
170376
  var cachedKeyFilesBySession = new Map;
170308
170377
  var staleUpdates = new Map;
@@ -170355,7 +170424,7 @@ function buildKeyFilesBlock(db, projectPath, config2 = { enabled: true, tokenBud
170355
170424
  let nextStale = null;
170356
170425
  let observed = false;
170357
170426
  try {
170358
- const absPath = join14(projectPath, row.path);
170427
+ const absPath = join15(projectPath, row.path);
170359
170428
  const real = realpathSync3(absPath);
170360
170429
  if (!isUnderProject(projectPath, real)) {
170361
170430
  nextStale = "missing";
@@ -170438,7 +170507,7 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
170438
170507
  function readProjectDocs(directory) {
170439
170508
  const sections = [];
170440
170509
  for (const filename of DOC_FILES) {
170441
- const filePath = join15(directory, filename);
170510
+ const filePath = join16(directory, filename);
170442
170511
  try {
170443
170512
  if (existsSync11(filePath)) {
170444
170513
  const content = readFileSync8(filePath, "utf-8").trim();
@@ -171329,104 +171398,52 @@ function resolveSessionId2(ctx) {
171329
171398
  return;
171330
171399
  }
171331
171400
  }
171332
- function collectMessageEntryIds(ctx, expectedLength, sessionId, strict = false) {
171401
+ function collectMessageEntryIdsByRef(ctx, messages, sessionId) {
171333
171402
  const sm = ctx.sessionManager;
171334
171403
  if (typeof sm?.getBranch !== "function")
171335
- return;
171404
+ return null;
171336
171405
  let entries;
171337
171406
  try {
171338
171407
  entries = sm.getBranch.call(sm);
171339
- } catch {
171340
- return;
171408
+ } catch (error51) {
171409
+ sessionLog(sessionId ?? "pi", `collectMessageEntryIdsByRef getBranch failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
171410
+ return null;
171341
171411
  }
171342
171412
  if (!Array.isArray(entries))
171343
- return;
171344
- let compactionIndex = -1;
171345
- let firstKeptEntryId;
171346
- for (let i = entries.length - 1;i >= 0; i--) {
171347
- const e = entries[i];
171348
- if (e && typeof e === "object" && e.type === "compaction") {
171349
- compactionIndex = i;
171350
- if (typeof e.firstKeptEntryId === "string") {
171351
- firstKeptEntryId = e.firstKeptEntryId;
171352
- }
171353
- break;
171354
- }
171355
- }
171356
- const ids = [];
171357
- const isEmitEligible = (entry) => {
171413
+ return null;
171414
+ const entryIdByMsgRef = new Map;
171415
+ for (const entry of entries) {
171358
171416
  if (!entry || typeof entry !== "object")
171359
- return false;
171360
- const t = entry.type;
171361
- const id = entry.id;
171362
- if (typeof id !== "string")
171363
- return false;
171364
- if (t === "message")
171365
- return true;
171366
- if (t === "custom_message")
171367
- return true;
171368
- if (t === "branch_summary") {
171369
- const summary = entry.summary;
171370
- return typeof summary === "string" && summary.length > 0;
171371
- }
171372
- return false;
171373
- };
171374
- if (compactionIndex >= 0) {
171375
- ids.push(undefined);
171376
- if (firstKeptEntryId !== undefined) {
171377
- let foundFirstKept = false;
171378
- for (let i = 0;i < compactionIndex; i++) {
171379
- const entry = entries[i];
171380
- const entryId = entry?.id;
171381
- if (typeof entryId === "string" && entryId === firstKeptEntryId) {
171382
- foundFirstKept = true;
171383
- }
171384
- if (!foundFirstKept)
171385
- continue;
171386
- if (isEmitEligible(entry)) {
171387
- ids.push(entry.id);
171388
- }
171389
- }
171390
- }
171391
- for (let i = compactionIndex + 1;i < entries.length; i++) {
171392
- const entry = entries[i];
171393
- if (isEmitEligible(entry)) {
171394
- ids.push(entry.id);
171395
- }
171396
- }
171397
- } else {
171398
- for (const entry of entries) {
171399
- if (isEmitEligible(entry)) {
171400
- ids.push(entry.id);
171401
- }
171402
- }
171417
+ continue;
171418
+ const e = entry;
171419
+ if (e.type !== "message")
171420
+ continue;
171421
+ if (typeof e.id !== "string")
171422
+ continue;
171423
+ if (!e.message || typeof e.message !== "object")
171424
+ continue;
171425
+ entryIdByMsgRef.set(e.message, e.id);
171403
171426
  }
171404
- if (ids.length !== expectedLength) {
171405
- const sm2 = sm;
171406
- const totalEntries = entries.length;
171407
- log(`[magic-context][pi]${sessionId ? `[${sessionId}]` : ""} collectMessageEntryIds length mismatch: ` + `expected=${expectedLength} got=${ids.length} (compactionIndex=${compactionIndex} ` + `firstKeptEntryId=${firstKeptEntryId ?? "<none>"} totalBranchEntries=${totalEntries})` + ` — best-effort mapping returned; boundary trim may not match exactly`);
171408
- if (strict)
171409
- return;
171410
- const _unused = sm2;
171411
- if (ids.length < expectedLength) {
171412
- const padded = [];
171413
- for (let i = 0;i < expectedLength - ids.length; i++) {
171414
- padded.push(undefined);
171415
- }
171416
- padded.push(...ids);
171417
- return padded;
171427
+ const result = new Array(messages.length);
171428
+ let resolved = 0;
171429
+ for (let i = 0;i < messages.length; i++) {
171430
+ const msg = messages[i];
171431
+ if (!msg || typeof msg !== "object") {
171432
+ result[i] = undefined;
171433
+ continue;
171434
+ }
171435
+ const id = entryIdByMsgRef.get(msg);
171436
+ if (typeof id === "string") {
171437
+ result[i] = id;
171438
+ resolved += 1;
171439
+ } else {
171440
+ result[i] = undefined;
171418
171441
  }
171419
- return ids.slice(ids.length - expectedLength);
171420
171442
  }
171421
- return ids;
171422
- }
171423
- function collectMessageEntryIdsStrict(ctx, expectedLength, sessionId) {
171424
- try {
171425
- return collectMessageEntryIds(ctx, expectedLength, sessionId, true) ?? null;
171426
- } catch (error51) {
171427
- sessionLog(sessionId ?? "pi", `collectMessageEntryIdsStrict failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
171428
- return null;
171443
+ if (resolved < messages.length) {
171444
+ log(`[magic-context][pi]${sessionId ? `[${sessionId}]` : ""} ` + `collectMessageEntryIdsByRef: resolved=${resolved}/${messages.length} ` + `(branchEntries=${entries.length}, messageEntries=${entryIdByMsgRef.size}) — ` + `unmapped slots fall through to synthesized ids; boundary lookup still works ` + `for any compartment whose start/end message is among the resolved set`);
171429
171445
  }
171446
+ return result;
171430
171447
  }
171431
171448
  function registerPiContextHandler(pi, options) {
171432
171449
  const tagger = createTagger();
@@ -171467,7 +171484,7 @@ function registerPiContextHandler(pi, options) {
171467
171484
  const unregisterRaw = setRawMessageProvider(sessionId, rawMessageProvider);
171468
171485
  rawMessageProviderUnregistersBySession.set(sessionId, unregisterRaw);
171469
171486
  scheduleReconciliation(options.db, sessionId, readRawSessionMessages);
171470
- const strictEntryIds = collectMessageEntryIdsStrict(ctx, event.messages.length, sessionId);
171487
+ const strictEntryIds = collectMessageEntryIdsByRef(ctx, event.messages, sessionId);
171471
171488
  const tLastUser = performance.now();
171472
171489
  const latestUser = findLatestUserMessageIdPi(event.messages, buildPiMessageIdByIndex(event.messages, strictEntryIds));
171473
171490
  logTransformTiming(sessionId, "findLastUserMessageId", tLastUser);
@@ -171600,7 +171617,7 @@ function registerPiContextHandler(pi, options) {
171600
171617
  const isCacheBusting = historyRefreshSessions.has(sessionId);
171601
171618
  sessionLog(sessionId, `transform: usage=${usagePercentage.toFixed(1)}% (${usageInputTokens} tokens, limit=${usageContextLimit ?? "?"}) decision=${schedulerDecision}${forceMaterialization ? " force=true" : ""}${isEmergency ? " EMERGENCY=true" : ""}${isCacheBusting ? " busting=true" : ""}`);
171602
171619
  logTransformTiming(sessionId, "emergencyRecoveryBlock", tEmergencyRecovery);
171603
- const entryIds = collectMessageEntryIds(ctx, event.messages.length, sessionId);
171620
+ const entryIds = collectMessageEntryIdsByRef(ctx, event.messages, sessionId) ?? undefined;
171604
171621
  const result = await runPipeline({
171605
171622
  db: options.db,
171606
171623
  tagger,
@@ -172468,7 +172485,7 @@ init_logger();
172468
172485
  init_data_path();
172469
172486
  init_logger();
172470
172487
  await init_sqlite();
172471
- import { join as join16 } from "node:path";
172488
+ import { join as join17 } from "node:path";
172472
172489
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
172473
172490
  function randomBase62(length) {
172474
172491
  const chars = [];
@@ -172489,7 +172506,7 @@ function generatePartId(timestampMs, counter = 0n) {
172489
172506
  return generateId("prt", timestampMs, counter);
172490
172507
  }
172491
172508
  function getOpenCodeDbPath3() {
172492
- return join16(getDataDir(), "opencode", "opencode.db");
172509
+ return join17(getDataDir(), "opencode", "opencode.db");
172493
172510
  }
172494
172511
  var cachedWriteDb = null;
172495
172512
  var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
@@ -173009,7 +173026,7 @@ async function runCompressorPass2(args) {
173009
173026
  });
173010
173027
  const messagesResponse = await client.session.messages({
173011
173028
  path: { id: agentSessionId },
173012
- query: { directory }
173029
+ query: { directory, limit: 50 }
173013
173030
  });
173014
173031
  const messages = normalizeSDKResponse(messagesResponse, [], {
173015
173032
  preferResponseOnMissingData: true
@@ -173047,7 +173064,7 @@ async function runCompressorPass2(args) {
173047
173064
 
173048
173065
  // ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
173049
173066
  import { mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
173050
- import { join as join17 } from "node:path";
173067
+ import { join as join18 } from "node:path";
173051
173068
  init_data_path();
173052
173069
  function historianResponseDumpDir(directory) {
173053
173070
  return getProjectMagicContextHistorianDir(directory);
@@ -173194,7 +173211,7 @@ async function runHistorianPrompt(args) {
173194
173211
  }
173195
173212
  const messagesResponse = await client.session.messages({
173196
173213
  path: { id: agentSessionId },
173197
- query: { directory: sessionDirectory }
173214
+ query: { directory: sessionDirectory, limit: 50 }
173198
173215
  });
173199
173216
  const messages = normalizeSDKResponse(messagesResponse, [], {
173200
173217
  preferResponseOnMissingData: true
@@ -173301,7 +173318,7 @@ function dumpHistorianResponse(sessionId, directory, label, text) {
173301
173318
  mkdirSync6(dumpDir, { recursive: true });
173302
173319
  const safeSessionId = sanitizeDumpName(sessionId);
173303
173320
  const safeLabel = sanitizeDumpName(label);
173304
- const dumpPath = join17(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
173321
+ const dumpPath = join18(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
173305
173322
  writeFileSync3(dumpPath, text, "utf8");
173306
173323
  sessionLog(sessionId, "compartment agent: historian response dumped", {
173307
173324
  label,
@@ -173531,7 +173548,7 @@ async function executePartialRecompInternal(deps, range) {
173531
173548
  }
173532
173549
  deps.onCompartmentStatePublished?.(sessionId);
173533
173550
  const lastEnd = merged[merged.length - 1]?.endMessage ?? snapEnd;
173534
- if (deps.experimentalCompactionMarkers && lastEnd > 0) {
173551
+ if (lastEnd > 0) {
173535
173552
  updateCompactionMarkerAfterPublication(db, sessionId, lastEnd, deps.directory);
173536
173553
  const stalePending = getPendingCompactionMarkerState(db, sessionId);
173537
173554
  if (stalePending) {
@@ -173790,7 +173807,7 @@ Found ${existingStaging.compartments.length} staged compartment(s) from ${existi
173790
173807
  if (lastCompartmentEnd2 > 0) {
173791
173808
  queueDropsForCompartmentalizedMessages(db, sessionId, lastCompartmentEnd2);
173792
173809
  }
173793
- if (deps.experimentalCompactionMarkers && lastCompartmentEnd2 > 0) {
173810
+ if (lastCompartmentEnd2 > 0) {
173794
173811
  updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd2, deps.directory);
173795
173812
  const stalePending = getPendingCompactionMarkerState(db, sessionId);
173796
173813
  if (stalePending) {
@@ -174507,7 +174524,7 @@ import {
174507
174524
  // package.json
174508
174525
  var package_default = {
174509
174526
  name: "@cortexkit/pi-magic-context",
174510
- version: "0.21.1",
174527
+ version: "0.21.4",
174511
174528
  type: "module",
174512
174529
  description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
174513
174530
  main: "dist/index.js",
@@ -180210,7 +180227,7 @@ async function persistPiPressureFromMessageEnd(args) {
180210
180227
  }
180211
180228
  var PLUGIN_VERSION = (() => {
180212
180229
  try {
180213
- const req = createRequire3(import.meta.url);
180230
+ const req = createRequire4(import.meta.url);
180214
180231
  return req("../package.json").version;
180215
180232
  } catch {
180216
180233
  return "0.0.0";
@@ -180288,7 +180305,7 @@ function resolveDreamerFromConfig(config2) {
180288
180305
  }
180289
180306
  async function src_default2(pi) {
180290
180307
  const storageDir = getMagicContextStorageDir();
180291
- const dbPath = join18(storageDir, "context.db");
180308
+ const dbPath = join19(storageDir, "context.db");
180292
180309
  let db;
180293
180310
  try {
180294
180311
  db = openDatabase();
@@ -156796,7 +156796,6 @@ var MagicContextConfigSchema = exports_external.object({
156796
156796
  enabled: exports_external.boolean().default(true),
156797
156797
  min_clusters: exports_external.number().min(1).default(3)
156798
156798
  }).default({ enabled: true, min_clusters: 3 }),
156799
- compaction_markers: exports_external.boolean().default(true),
156800
156799
  system_prompt_injection: exports_external.object({
156801
156800
  enabled: exports_external.boolean().default(true),
156802
156801
  skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.21.1",
3
+ "version": "0.21.4",
4
4
  "type": "module",
5
5
  "description": "Pi coding agent extension for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",