@cortexkit/pi-magic-context 0.16.1 → 0.16.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/README.md CHANGED
@@ -28,10 +28,10 @@ Magic Context is a context engine that keeps long Pi sessions productive by:
28
28
 
29
29
  ## Installation
30
30
 
31
- The fastest path is the interactive setup wizard — it registers the extension with Pi, writes a sensible `magic-context.jsonc`, and verifies your model picks against Pi's CLI:
31
+ The fastest path is the unified Magic Context CLI — `--harness pi` selects the Pi-specific setup pipeline (registers the extension with Pi, writes a sensible `magic-context.jsonc`, and verifies your model picks):
32
32
 
33
33
  ```bash
34
- bunx --bun @cortexkit/pi-magic-context@latest setup
34
+ bunx --bun @cortexkit/magic-context@latest setup --harness pi
35
35
  ```
36
36
 
37
37
  This handles everything for you:
@@ -40,24 +40,18 @@ This handles everything for you:
40
40
  3. Prompts you for historian, dreamer, sidekick, and embedding model choices
41
41
  4. Warns about provider-specific gotchas (e.g. GitHub Copilot reasoning models need an explicit `thinking_level`)
42
42
 
43
- If you'd rather install the npm package globally first:
44
-
45
- ```bash
46
- npm install -g @cortexkit/pi-magic-context@latest
47
- # or
48
- bun add -g @cortexkit/pi-magic-context@latest
49
- ```
50
-
51
- Then either run `magic-context-pi setup` or register the extension manually with Pi's own installer:
43
+ If you'd rather register the Pi extension package directly with Pi (skipping the wizard), use Pi's own installer:
52
44
 
53
45
  ```bash
54
46
  pi install npm:@cortexkit/pi-magic-context
55
47
  ```
56
48
 
49
+ This adds the extension to `~/.pi/agent/settings.json` but won't write `magic-context.jsonc` for you — you'll need to create it manually (see Configuration below).
50
+
57
51
  To check installation health later:
58
52
 
59
53
  ```bash
60
- magic-context-pi doctor
54
+ bunx --bun @cortexkit/magic-context@latest doctor --harness pi
61
55
  ```
62
56
 
63
57
  ---
@@ -161,7 +155,8 @@ This package is part of the [magic-context monorepo](https://github.com/cortexki
161
155
  | `dreamer/` | Pi-side adapter for the shared dreamer scheduler |
162
156
  | `system-prompt.ts` | Pi `before_agent_start` injector for `<session-history>`, `<project-memory>`, `<project-docs>` |
163
157
  | `config/` | Pi-convention config loader (`$cwd/.pi/magic-context.jsonc` + `~/.pi/agent/magic-context.jsonc`) |
164
- | `cli/` | `magic-context-pi setup` and `magic-context-pi doctor` |
158
+
159
+ The CLI lives in the unified [`@cortexkit/magic-context`](https://www.npmjs.com/package/@cortexkit/magic-context) package — `setup --harness pi` and `doctor --harness pi` route to the Pi-specific code paths in `packages/cli/src/commands/`.
165
160
 
166
161
  For deeper architectural detail, see the main repo's [ARCHITECTURE.md](https://github.com/cortexkit/magic-context/blob/master/ARCHITECTURE.md).
167
162
 
package/dist/index.js CHANGED
@@ -14064,6 +14064,13 @@ var init_magic_context = __esm(() => {
14064
14064
  min_clusters: exports_external.number().min(1).default(3)
14065
14065
  }).default({ enabled: true, min_clusters: 3 }),
14066
14066
  compaction_markers: exports_external.boolean().default(true),
14067
+ system_prompt_injection: exports_external.object({
14068
+ enabled: exports_external.boolean().default(true),
14069
+ skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
14070
+ }).default({
14071
+ enabled: true,
14072
+ skip_signatures: ["<!-- magic-context: skip -->"]
14073
+ }),
14067
14074
  compressor: exports_external.object({
14068
14075
  enabled: exports_external.boolean().default(true),
14069
14076
  min_compartment_ratio: exports_external.number().min(100).max(1e4).default(DEFAULT_COMPRESSOR_MIN_COMPARTMENT_RATIO),
@@ -158848,8 +158855,8 @@ function enqueueDream(db, projectIdentity, reason, force = false) {
158848
158855
  };
158849
158856
  })();
158850
158857
  }
158851
- function peekQueue(db) {
158852
- const row = db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
158858
+ function peekQueue(db, projectIdentity) {
158859
+ const row = projectIdentity ? db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL AND project_path = ? ORDER BY enqueued_at ASC LIMIT 1").get(projectIdentity) : db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
158853
158860
  if (!row)
158854
158861
  return null;
158855
158862
  return {
@@ -158860,10 +158867,10 @@ function peekQueue(db) {
158860
158867
  startedAt: null
158861
158868
  };
158862
158869
  }
158863
- function dequeueNext(db) {
158870
+ function dequeueNext(db, projectIdentity) {
158864
158871
  const now = Date.now();
158865
158872
  return db.transaction(() => {
158866
- const entry = peekQueue(db);
158873
+ const entry = peekQueue(db, projectIdentity);
158867
158874
  if (!entry)
158868
158875
  return null;
158869
158876
  const result = db.prepare("UPDATE dream_queue SET started_at = ? WHERE id = ? AND started_at IS NULL").run(now, entry.id);
@@ -160276,7 +160283,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
160276
160283
  body: {
160277
160284
  agent: DREAMER_AGENT,
160278
160285
  system: DREAMER_SYSTEM_PROMPT,
160279
- parts: [{ type: "text", text: prompt }]
160286
+ parts: [{ type: "text", text: prompt, synthetic: true }]
160280
160287
  }
160281
160288
  }, { timeoutMs: Math.min(remainingMs, 5 * 60 * 1000), signal: abortController.signal });
160282
160289
  const messagesResponse = await args.client.session.messages({
@@ -160488,7 +160495,7 @@ async function identifyKeyFilesForSession(args) {
160488
160495
  body: {
160489
160496
  agent: DREAMER_AGENT,
160490
160497
  system: KEY_FILES_SYSTEM_PROMPT,
160491
- parts: [{ type: "text", text: prompt }]
160498
+ parts: [{ type: "text", text: prompt, synthetic: true }]
160492
160499
  }
160493
160500
  }, { timeoutMs: Math.min(remainingMs, 300000), signal: abortController.signal });
160494
160501
  const messagesResponse = await args.client.session.messages({
@@ -160672,7 +160679,7 @@ async function runDream(args) {
160672
160679
  body: {
160673
160680
  agent: DREAMER_AGENT,
160674
160681
  system: DREAMER_SYSTEM_PROMPT,
160675
- parts: [{ type: "text", text: taskPrompt }]
160682
+ parts: [{ type: "text", text: taskPrompt, synthetic: true }]
160676
160683
  }
160677
160684
  }, {
160678
160685
  timeoutMs: args.taskTimeoutMinutes * 60 * 1000,
@@ -160901,7 +160908,7 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
160901
160908
  body: {
160902
160909
  agent: DREAMER_AGENT,
160903
160910
  system: DREAMER_SYSTEM_PROMPT,
160904
- parts: [{ type: "text", text: evaluationPrompt }]
160911
+ parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
160905
160912
  }
160906
160913
  }, { timeoutMs: Math.min(remainingMs, 300000), signal: abortController.signal });
160907
160914
  const messagesResponse = await args.client.session.messages({
@@ -160986,7 +160993,7 @@ var MAX_LEASE_RETRIES = 3;
160986
160993
  async function processDreamQueue(args) {
160987
160994
  const maxRuntimeMs = args.maxRuntimeMinutes * 60 * 1000;
160988
160995
  clearStaleEntries(args.db, maxRuntimeMs + 1800000);
160989
- const entry = dequeueNext(args.db);
160996
+ const entry = dequeueNext(args.db, args.projectIdentity);
160990
160997
  if (!entry) {
160991
160998
  return null;
160992
160999
  }
@@ -161081,7 +161088,7 @@ function findProjectsNeedingDream(db) {
161081
161088
  }
161082
161089
  return projects;
161083
161090
  }
161084
- function checkScheduleAndEnqueue(db, schedule) {
161091
+ function checkScheduleAndEnqueue(db, schedule, ownProjectIdentity) {
161085
161092
  if (!isInScheduleWindow(schedule)) {
161086
161093
  return 0;
161087
161094
  }
@@ -161089,8 +161096,9 @@ function checkScheduleAndEnqueue(db, schedule) {
161089
161096
  if (projects.length === 0) {
161090
161097
  return 0;
161091
161098
  }
161099
+ const eligible = ownProjectIdentity ? projects.filter((id) => id === ownProjectIdentity) : projects;
161092
161100
  let enqueued = 0;
161093
- for (const projectIdentity of projects) {
161101
+ for (const projectIdentity of eligible) {
161094
161102
  const entry = enqueueDream(db, projectIdentity, "scheduled");
161095
161103
  if (entry) {
161096
161104
  log(`[dreamer] enqueued project for scheduled dream: ${projectIdentity}`);
@@ -161716,7 +161724,8 @@ async function sweepProject(reg, origin) {
161716
161724
  try {
161717
161725
  const db = openDatabase();
161718
161726
  log(`[dreamer] timer tick (${origin}) ${reg.directory} — checking schedule window "${reg.dreamerConfig.schedule}"`);
161719
- checkScheduleAndEnqueue(db, reg.dreamerConfig.schedule);
161727
+ const registrationIdentity = resolveProjectIdentity(reg.directory);
161728
+ checkScheduleAndEnqueue(db, reg.dreamerConfig.schedule, registrationIdentity);
161720
161729
  await processDreamQueue({
161721
161730
  db,
161722
161731
  client: reg.client,
@@ -161724,7 +161733,8 @@ async function sweepProject(reg, origin) {
161724
161733
  taskTimeoutMinutes: reg.dreamerConfig.task_timeout_minutes,
161725
161734
  maxRuntimeMinutes: reg.dreamerConfig.max_runtime_minutes,
161726
161735
  experimentalUserMemories: reg.experimentalUserMemories,
161727
- experimentalPinKeyFiles: reg.experimentalPinKeyFiles
161736
+ experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
161737
+ projectIdentity: registrationIdentity
161728
161738
  });
161729
161739
  } catch (error48) {
161730
161740
  log(`[dreamer] timer-triggered queue processing failed for ${reg.directory}:`, error48);
@@ -161797,7 +161807,8 @@ function registerPiDreamerProject(opts) {
161797
161807
  taskTimeoutMinutes: opts.config.task_timeout_minutes,
161798
161808
  maxRuntimeMinutes: opts.config.max_runtime_minutes,
161799
161809
  experimentalUserMemories,
161800
- experimentalPinKeyFiles
161810
+ experimentalPinKeyFiles,
161811
+ projectIdentity: opts.projectIdentity
161801
161812
  });
161802
161813
  registeredProjects2.set(opts.projectIdentity, { cleanup, runOnce });
161803
161814
  }
@@ -168559,7 +168570,7 @@ async function runCompressorPass2(args) {
168559
168570
  query: { directory },
168560
168571
  body: {
168561
168572
  agent: HISTORIAN_AGENT2,
168562
- parts: [{ type: "text", text: prompt }]
168573
+ parts: [{ type: "text", text: prompt, synthetic: true }]
168563
168574
  }
168564
168575
  }, { timeoutMs: historianTimeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS });
168565
168576
  const messagesResponse = await client.session.messages({
@@ -168724,7 +168735,7 @@ async function runHistorianPrompt(args) {
168724
168735
  body: {
168725
168736
  agent: agentId,
168726
168737
  ...modelOverride ? { model: modelOverride } : {},
168727
- parts: [{ type: "text", text: prompt }]
168738
+ parts: [{ type: "text", text: prompt, synthetic: true }]
168728
168739
  }
168729
168740
  }, { timeoutMs: timeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS });
168730
168741
  sessionLog(parentSessionId, `historian: prompt completed (attempt ${retryIndex + 1}/${MAX_HISTORIAN_RETRIES + 1})`);
@@ -170017,7 +170028,7 @@ import {
170017
170028
  // package.json
170018
170029
  var package_default = {
170019
170030
  name: "@cortexkit/pi-magic-context",
170020
- version: "0.16.1",
170031
+ version: "0.16.2",
170021
170032
  type: "module",
170022
170033
  description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
170023
170034
  main: "dist/index.js",
@@ -14064,6 +14064,13 @@ var init_magic_context = __esm(() => {
14064
14064
  min_clusters: exports_external.number().min(1).default(3)
14065
14065
  }).default({ enabled: true, min_clusters: 3 }),
14066
14066
  compaction_markers: exports_external.boolean().default(true),
14067
+ system_prompt_injection: exports_external.object({
14068
+ enabled: exports_external.boolean().default(true),
14069
+ skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
14070
+ }).default({
14071
+ enabled: true,
14072
+ skip_signatures: ["<!-- magic-context: skip -->"]
14073
+ }),
14067
14074
  compressor: exports_external.object({
14068
14075
  enabled: exports_external.boolean().default(true),
14069
14076
  min_compartment_ratio: exports_external.number().min(100).max(1e4).default(DEFAULT_COMPRESSOR_MIN_COMPARTMENT_RATIO),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
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",