@cortexkit/pi-magic-context 0.28.0 → 0.29.1

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.
@@ -8080,6 +8080,102 @@ function closeQuietly(db) {
8080
8080
  // ../plugin/src/features/magic-context/migrations.ts
8081
8081
  init_logger();
8082
8082
 
8083
+ // ../plugin/src/features/magic-context/storage-schema-helpers.ts
8084
+ function ensureColumn(db, table, column, definition) {
8085
+ if (!/^[a-z][a-z0-9_]*$/.test(table) || !/^[a-z][a-z0-9_]*$/.test(column) || !/^[A-Z0-9_"'(),[\]\s]+$/i.test(definition)) {
8086
+ throw new Error(`Unsafe schema identifier: ${table}.${column} ${definition}`);
8087
+ }
8088
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
8089
+ if (rows.some((row) => row.name === column)) {
8090
+ return;
8091
+ }
8092
+ try {
8093
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
8094
+ } catch (err) {
8095
+ const recheck = db.prepare(`PRAGMA table_info(${table})`).all();
8096
+ if (recheck.some((row) => row.name === column)) {
8097
+ return;
8098
+ }
8099
+ throw err;
8100
+ }
8101
+ }
8102
+ function healAllNullColumns(db) {
8103
+ healNullTextColumns(db);
8104
+ healNullIntegerColumns(db);
8105
+ healMissingMemoryBlockIds(db);
8106
+ }
8107
+ function healMissingMemoryBlockIds(db) {
8108
+ try {
8109
+ db.prepare("UPDATE session_meta SET memory_block_cache = '' WHERE memory_block_cache != '' AND (memory_block_ids IS NULL OR memory_block_ids = '') AND memory_block_count > 0").run();
8110
+ } catch {}
8111
+ }
8112
+ function healNullTextColumns(db) {
8113
+ const columns = [
8114
+ ["cache_ttl", ""],
8115
+ ["last_nudge_band", ""],
8116
+ ["last_nudge_level", ""],
8117
+ ["last_transform_error", ""],
8118
+ ["nudge_anchor_message_id", ""],
8119
+ ["nudge_anchor_text", ""],
8120
+ ["sticky_turn_reminder_text", ""],
8121
+ ["sticky_turn_reminder_message_id", ""],
8122
+ ["note_nudge_trigger_message_id", ""],
8123
+ ["note_nudge_sticky_text", ""],
8124
+ ["note_nudge_sticky_message_id", ""],
8125
+ ["last_todo_state", ""],
8126
+ ["todo_synthetic_call_id", ""],
8127
+ ["todo_synthetic_anchor_message_id", ""],
8128
+ ["todo_synthetic_state_json", ""],
8129
+ ["system_prompt_hash", ""],
8130
+ ["stripped_placeholder_ids", ""],
8131
+ ["stale_reduce_stripped_ids", ""],
8132
+ ["processed_image_stripped_ids", ""],
8133
+ ["memory_block_cache", ""],
8134
+ ["memory_block_ids", ""],
8135
+ ["compaction_marker_state", ""],
8136
+ ["key_files", ""]
8137
+ ];
8138
+ for (const [column, fallback] of columns) {
8139
+ try {
8140
+ db.prepare(`UPDATE session_meta SET ${column} = ? WHERE ${column} IS NULL`).run(fallback);
8141
+ } catch (_error) {}
8142
+ }
8143
+ }
8144
+ function healNullIntegerColumns(db) {
8145
+ const columns = [
8146
+ ["times_execute_threshold_reached", 0],
8147
+ ["compartment_in_progress", 0],
8148
+ ["historian_failure_count", 0],
8149
+ ["cleared_reasoning_through_tag", 0],
8150
+ ["memory_block_count", 0],
8151
+ ["system_prompt_tokens", 0],
8152
+ ["conversation_tokens", 0],
8153
+ ["tool_call_tokens", 0],
8154
+ ["note_nudge_trigger_pending", 0],
8155
+ ["observed_safe_input_tokens", 0],
8156
+ ["cache_alert_sent", 0],
8157
+ ["new_work_tokens", 0],
8158
+ ["total_input_tokens", 0],
8159
+ ["last_emergency_input_sample", 0],
8160
+ ["channel2_nudge_claimed_at", 0],
8161
+ ["last_usage_context_limit", 0],
8162
+ ["prior_boundary_ordinal", 1],
8163
+ ["protected_tail_policy_version", 0],
8164
+ ["protected_tail_drain_window_started_at", 0],
8165
+ ["protected_tail_drain_tokens", 0],
8166
+ ["recovery_no_eligible_head_count", 0],
8167
+ ["force_emergency_bypass_window_start", 0],
8168
+ ["force_emergency_bypass_used", 0],
8169
+ ["emergency_drain_active", 0],
8170
+ ["historian_drain_failure_at", 0]
8171
+ ];
8172
+ for (const [column, fallback] of columns) {
8173
+ try {
8174
+ db.prepare(`UPDATE session_meta SET ${column} = ? WHERE ${column} IS NULL`).run(fallback);
8175
+ } catch (_error) {}
8176
+ }
8177
+ }
8178
+
8083
8179
  // ../plugin/src/features/magic-context/workspaces.ts
8084
8180
  import { createHash as createHash2 } from "node:crypto";
8085
8181
 
@@ -9923,6 +10019,17 @@ function runMigrations(db) {
9923
10019
  log(`[migrations] schema version now: ${MIGRATIONS[MIGRATIONS.length - 1].version}`);
9924
10020
  }
9925
10021
 
10022
+ // ../plugin/src/shared/commit-detection.ts
10023
+ var HASH_HEX = "[0-9a-f]{7,12}";
10024
+ var COMMIT_HASH_TEST_PATTERN = new RegExp(`\\b${HASH_HEX}\\b`, "i");
10025
+ var COMMIT_VERB_PATTERN = /\b(?:commit(?:ted|ting|s)?|cherry-?pick(?:ed|ing|s)?|merge[ds]?|merging|rebas(?:e|ed|es|ing))\b/i;
10026
+ function textMentionsRecentCommit(text) {
10027
+ return COMMIT_HASH_TEST_PATTERN.test(text) && COMMIT_VERB_PATTERN.test(text);
10028
+ }
10029
+ function createCommitHashExtractPattern() {
10030
+ return new RegExp(`\`?\\b(${HASH_HEX})\\b\`?`, "gi");
10031
+ }
10032
+
9926
10033
  // ../plugin/src/shared/internal-initiator-marker.ts
9927
10034
  var OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->";
9928
10035
 
@@ -142374,8 +142481,6 @@ var decoder = {
142374
142481
  };
142375
142482
 
142376
142483
  // ../plugin/src/hooks/magic-context/read-session-formatting.ts
142377
- var COMMIT_HASH_PATTERN = /`?\b([0-9a-f]{6,12})\b`?/gi;
142378
- var COMMIT_HINT_PATTERN = /\b(commit(?:ted)?|cherry-?pick(?:ed)?|hash(?:es)?|sha)\b/i;
142379
142484
  var MAX_COMMITS_PER_BLOCK = 5;
142380
142485
  function hasMeaningfulUserText(parts) {
142381
142486
  for (const part of parts) {
@@ -142479,7 +142584,7 @@ function formatBlock(block) {
142479
142584
  function extractCommitHashes(text) {
142480
142585
  const hashes = [];
142481
142586
  const seen = new Set;
142482
- for (const match of text.matchAll(COMMIT_HASH_PATTERN)) {
142587
+ for (const match of text.matchAll(createCommitHashExtractPattern())) {
142483
142588
  const hash = match[1]?.toLowerCase();
142484
142589
  if (!hash || seen.has(hash))
142485
142590
  continue;
@@ -142492,10 +142597,10 @@ function extractCommitHashes(text) {
142492
142597
  }
142493
142598
  function compactTextForSummary(text, role) {
142494
142599
  const commitHashes = role === "assistant" ? extractCommitHashes(text) : [];
142495
- if (commitHashes.length === 0 || !COMMIT_HINT_PATTERN.test(text)) {
142600
+ if (commitHashes.length === 0 || !COMMIT_VERB_PATTERN.test(text)) {
142496
142601
  return { text, commitHashes };
142497
142602
  }
142498
- const withoutHashes = text.replace(COMMIT_HASH_PATTERN, "").replace(/\(\s*\)/g, "").replace(/\s+,/g, ",").replace(/,\s*,+/g, ", ").replace(/\s{2,}/g, " ").replace(/\s+([,.;:])/g, "$1").trim();
142603
+ const withoutHashes = text.replace(createCommitHashExtractPattern(), "").replace(/\(\s*\)/g, "").replace(/\s+,/g, ",").replace(/,\s*,+/g, ", ").replace(/\s{2,}/g, " ").replace(/\s+([,.;:])/g, "$1").trim();
142499
142604
  return {
142500
142605
  text: withoutHashes.length > 0 ? withoutHashes : text,
142501
142606
  commitHashes
@@ -143907,11 +144012,6 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
143907
144012
  ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
143908
144013
  ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
143909
144014
  }
143910
- function healAllNullColumns(db) {
143911
- healNullTextColumns(db);
143912
- healNullIntegerColumns(db);
143913
- healMissingMemoryBlockIds(db);
143914
- }
143915
144015
  var CHANNEL2_CLAIM_TTL_MS = 120000;
143916
144016
  function healWedgedChannel2Claims(db) {
143917
144017
  try {
@@ -143919,95 +144019,6 @@ function healWedgedChannel2Claims(db) {
143919
144019
  db.prepare("UPDATE session_meta SET channel2_nudge_state = 'pending', channel2_nudge_claimed_at = 0 WHERE channel2_nudge_state = 'claimed' AND (channel2_nudge_claimed_at IS NULL OR channel2_nudge_claimed_at = 0 OR channel2_nudge_claimed_at <= ?)").run(staleBefore);
143920
144020
  } catch {}
143921
144021
  }
143922
- function healMissingMemoryBlockIds(db) {
143923
- try {
143924
- db.prepare("UPDATE session_meta SET memory_block_cache = '' WHERE memory_block_cache != '' AND (memory_block_ids IS NULL OR memory_block_ids = '') AND memory_block_count > 0").run();
143925
- } catch {}
143926
- }
143927
- function healNullTextColumns(db) {
143928
- const columns = [
143929
- ["cache_ttl", ""],
143930
- ["last_nudge_band", ""],
143931
- ["last_nudge_level", ""],
143932
- ["last_transform_error", ""],
143933
- ["nudge_anchor_message_id", ""],
143934
- ["nudge_anchor_text", ""],
143935
- ["sticky_turn_reminder_text", ""],
143936
- ["sticky_turn_reminder_message_id", ""],
143937
- ["note_nudge_trigger_message_id", ""],
143938
- ["note_nudge_sticky_text", ""],
143939
- ["note_nudge_sticky_message_id", ""],
143940
- ["last_todo_state", ""],
143941
- ["todo_synthetic_call_id", ""],
143942
- ["todo_synthetic_anchor_message_id", ""],
143943
- ["todo_synthetic_state_json", ""],
143944
- ["system_prompt_hash", ""],
143945
- ["stripped_placeholder_ids", ""],
143946
- ["stale_reduce_stripped_ids", ""],
143947
- ["processed_image_stripped_ids", ""],
143948
- ["memory_block_cache", ""],
143949
- ["memory_block_ids", ""],
143950
- ["compaction_marker_state", ""],
143951
- ["key_files", ""]
143952
- ];
143953
- for (const [column, fallback] of columns) {
143954
- try {
143955
- db.prepare(`UPDATE session_meta SET ${column} = ? WHERE ${column} IS NULL`).run(fallback);
143956
- } catch (_error) {}
143957
- }
143958
- }
143959
- function healNullIntegerColumns(db) {
143960
- const columns = [
143961
- ["times_execute_threshold_reached", 0],
143962
- ["compartment_in_progress", 0],
143963
- ["historian_failure_count", 0],
143964
- ["cleared_reasoning_through_tag", 0],
143965
- ["memory_block_count", 0],
143966
- ["system_prompt_tokens", 0],
143967
- ["conversation_tokens", 0],
143968
- ["tool_call_tokens", 0],
143969
- ["note_nudge_trigger_pending", 0],
143970
- ["observed_safe_input_tokens", 0],
143971
- ["cache_alert_sent", 0],
143972
- ["new_work_tokens", 0],
143973
- ["total_input_tokens", 0],
143974
- ["last_emergency_input_sample", 0],
143975
- ["channel2_nudge_claimed_at", 0],
143976
- ["last_usage_context_limit", 0],
143977
- ["prior_boundary_ordinal", 1],
143978
- ["protected_tail_policy_version", 0],
143979
- ["protected_tail_drain_window_started_at", 0],
143980
- ["protected_tail_drain_tokens", 0],
143981
- ["recovery_no_eligible_head_count", 0],
143982
- ["force_emergency_bypass_window_start", 0],
143983
- ["force_emergency_bypass_used", 0],
143984
- ["emergency_drain_active", 0],
143985
- ["historian_drain_failure_at", 0]
143986
- ];
143987
- for (const [column, fallback] of columns) {
143988
- try {
143989
- db.prepare(`UPDATE session_meta SET ${column} = ? WHERE ${column} IS NULL`).run(fallback);
143990
- } catch (_error) {}
143991
- }
143992
- }
143993
- function ensureColumn(db, table, column, definition) {
143994
- if (!/^[a-z][a-z0-9_]*$/.test(table) || !/^[a-z][a-z0-9_]*$/.test(column) || !/^[A-Z0-9_"'(),[\]\s]+$/i.test(definition)) {
143995
- throw new Error(`Unsafe schema identifier: ${table}.${column} ${definition}`);
143996
- }
143997
- const rows = db.prepare(`PRAGMA table_info(${table})`).all();
143998
- if (rows.some((row) => row.name === column)) {
143999
- return;
144000
- }
144001
- try {
144002
- db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
144003
- } catch (err) {
144004
- const recheck = db.prepare(`PRAGMA table_info(${table})`).all();
144005
- if (recheck.some((row) => row.name === column)) {
144006
- return;
144007
- }
144008
- throw err;
144009
- }
144010
- }
144011
144022
  function openDatabase(dbPathOrOptions) {
144012
144023
  const options = typeof dbPathOrOptions === "string" ? { dbPath: dbPathOrOptions } : dbPathOrOptions;
144013
144024
  const explicitDbPath = options?.dbPath !== undefined;
@@ -159431,7 +159442,6 @@ var CANONICAL_DREAM_TASKS = [
159431
159442
  "refresh-primers"
159432
159443
  ];
159433
159444
  var AGENTIC_DREAM_TASKS = ["curate", "maintain-docs"];
159434
- var AGENTIC_SET = new Set(AGENTIC_DREAM_TASKS);
159435
159445
  var MEMORY_DOMAIN_TASKS = [
159436
159446
  "map-memories",
159437
159447
  "verify",
@@ -159667,6 +159677,7 @@ var MagicContextConfigSchema = exports_external.object({
159667
159677
  }).describe("Embedding provider configuration"),
159668
159678
  temporal_awareness: exports_external.boolean().default(true).describe('Inject wall-clock gap markers (<!-- +Xm -->) between user messages where > 5 min elapsed since the previous message, and add start/end date attributes on compartments. Gives the agent a sense of session pacing and "how long ago" across multi-day sessions. Graduated from experimental.temporal_awareness; default: true (set false to opt out).'),
159669
159679
  keep_subagents: exports_external.boolean().default(false).describe("Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, sidekick, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect."),
159680
+ smart_drops: exports_external.boolean().default(false).describe("Content-aware reclaim of provably-superseded tool output, layered on the existing execute-pass auto-drop. When on: superseded todowrite (keep newest 1), spent ctx_reduce (keep newest 5), and zero-value meta (bash_status, bash_kill, ctx_note read/dismiss) outputs are dropped; older edits to a file are compressed to a filePath-preserving marker while the newest edit per file stays full. Only acts on passes already busting the cache, so it never originates a cache bust. Honors the protected-tag reserve. Experimental: opt-in, default off until cache stability is proven; when off the wire is byte-identical to the positional-only reclaim. Requires a restart."),
159670
159681
  caveman_text_compression: exports_external.object({
159671
159682
  enabled: exports_external.boolean().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Only active when ctx_reduce_enabled=false. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
159672
159683
  min_chars: exports_external.number().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
@@ -163577,6 +163588,36 @@ function isRecord(value) {
163577
163588
  return typeof value === "object" && value !== null && !Array.isArray(value);
163578
163589
  }
163579
163590
 
163591
+ // ../plugin/src/hooks/magic-context/edit-marker.ts
163592
+ var TRUNCATION_SENTINEL = "...[truncated]";
163593
+ var EDIT_REGION_HINT_LEN = 40;
163594
+ var PATH_KEYS = new Set(["filePath", "file_path", "path"]);
163595
+ var DIFF_KEYS = new Set(["oldString", "newString", "content", "old_string", "new_string"]);
163596
+ function safeSlice(str, maxLen) {
163597
+ if (str.length <= maxLen)
163598
+ return str;
163599
+ const lastCharCode = str.charCodeAt(maxLen - 1);
163600
+ if (lastCharCode >= 55296 && lastCharCode <= 56319) {
163601
+ return str.slice(0, maxLen - 1);
163602
+ }
163603
+ return str.slice(0, maxLen);
163604
+ }
163605
+ function isEditTool(name2) {
163606
+ return name2 === "edit" || name2 === "write";
163607
+ }
163608
+ function applyEditMarkerToInput(input) {
163609
+ for (const key of Object.keys(input)) {
163610
+ if (PATH_KEYS.has(key))
163611
+ continue;
163612
+ const value = input[key];
163613
+ if (typeof value !== "string" || !DIFF_KEYS.has(key))
163614
+ continue;
163615
+ if (value.endsWith(TRUNCATION_SENTINEL))
163616
+ continue;
163617
+ input[key] = value.length > EDIT_REGION_HINT_LEN ? `${safeSlice(value, EDIT_REGION_HINT_LEN)}${TRUNCATION_SENTINEL}` : value;
163618
+ }
163619
+ }
163620
+
163580
163621
  // ../plugin/src/hooks/magic-context/tool-drop-target.ts
163581
163622
  var IGNORE_PART_TYPES = new Set([
163582
163623
  "thinking",
@@ -171706,7 +171747,7 @@ function toTagEntry(row) {
171706
171747
  messageId: row.message_id,
171707
171748
  type,
171708
171749
  status,
171709
- dropMode: row.drop_mode === "truncated" ? "truncated" : "full",
171750
+ dropMode: row.drop_mode === "truncated" ? "truncated" : row.drop_mode === "edit_marker" ? "edit_marker" : "full",
171710
171751
  toolName: row.tool_name ?? null,
171711
171752
  inputByteSize: row.input_byte_size ?? 0,
171712
171753
  byteSize: row.byte_size,
@@ -172613,7 +172654,7 @@ function createCtxNoteTool(deps) {
172613
172654
  parameters: ParamsSchema3,
172614
172655
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
172615
172656
  const sessionId = ctx.sessionManager.getSessionId();
172616
- const action2 = params.action ?? (typeof params.content === "string" ? "write" : "read");
172657
+ const action2 = params.action ?? (params.content?.trim() ? "write" : "read");
172617
172658
  if (action2 === "write") {
172618
172659
  const content = params.content?.trim();
172619
172660
  if (!content)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.28.0",
3
+ "version": "0.29.1",
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",