@cortexkit/opencode-magic-context 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +2 -2
  2. package/dist/config/index.d.ts.map +1 -1
  3. package/dist/features/magic-context/compaction-marker.d.ts +17 -0
  4. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  5. package/dist/features/magic-context/compartment-storage.d.ts +11 -0
  6. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  7. package/dist/features/magic-context/dreamer/lease.d.ts +1 -0
  8. package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
  9. package/dist/features/magic-context/dreamer/queue.d.ts.map +1 -1
  10. package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
  11. package/dist/features/magic-context/key-files/aft-availability.d.ts +11 -0
  12. package/dist/features/magic-context/key-files/aft-availability.d.ts.map +1 -0
  13. package/dist/features/magic-context/key-files/identify-key-files.d.ts +45 -0
  14. package/dist/features/magic-context/key-files/identify-key-files.d.ts.map +1 -1
  15. package/dist/features/magic-context/key-files/project-key-files.d.ts +42 -0
  16. package/dist/features/magic-context/key-files/project-key-files.d.ts.map +1 -0
  17. package/dist/features/magic-context/key-files/read-history.d.ts +26 -0
  18. package/dist/features/magic-context/key-files/read-history.d.ts.map +1 -0
  19. package/dist/features/magic-context/memory/embedding-identity.d.ts +11 -0
  20. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -0
  21. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  22. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  23. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  24. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  25. package/dist/features/magic-context/overflow-detection.d.ts +1 -1
  26. package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
  27. package/dist/features/magic-context/storage-db.d.ts +1 -0
  28. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  29. package/dist/features/magic-context/storage-meta-persisted.d.ts +64 -0
  30. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  31. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  32. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  33. package/dist/features/magic-context/storage.d.ts +1 -1
  34. package/dist/features/magic-context/storage.d.ts.map +1 -1
  35. package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
  36. package/dist/hooks/auto-update-checker/cache.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/boundary-execution.d.ts +24 -0
  38. package/dist/hooks/magic-context/boundary-execution.d.ts.map +1 -0
  39. package/dist/hooks/magic-context/cache-busting-signals.d.ts +10 -0
  40. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -0
  41. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  42. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +50 -0
  43. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  45. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +1 -1
  46. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  47. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/compartment-runner-types.d.ts +16 -7
  50. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/compartment-runner.d.ts +7 -2
  52. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/event-handler.d.ts +1 -0
  54. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/historian-state-file.d.ts +25 -11
  56. package/dist/hooks/magic-context/historian-state-file.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/hook-handlers.d.ts +11 -4
  58. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  60. package/dist/hooks/magic-context/inject-compartments.d.ts +2 -1
  61. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  62. package/dist/hooks/magic-context/key-files-block.d.ts +27 -0
  63. package/dist/hooks/magic-context/key-files-block.d.ts.map +1 -0
  64. package/dist/hooks/magic-context/live-session-state.d.ts +3 -1
  65. package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
  66. package/dist/hooks/magic-context/read-session-db.d.ts +2 -0
  67. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  69. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +10 -4
  70. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/transform-context-state.d.ts +5 -2
  72. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  73. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +15 -1
  74. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  75. package/dist/hooks/magic-context/transform.d.ts +3 -0
  76. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  77. package/dist/index.js +2316 -1112
  78. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  79. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  80. package/dist/plugin/sidebar-snapshot-cache.d.ts.map +1 -1
  81. package/dist/shared/conflict-detector.d.ts +49 -0
  82. package/dist/shared/conflict-detector.d.ts.map +1 -1
  83. package/dist/shared/conflict-fixer.d.ts +1 -1
  84. package/dist/shared/conflict-fixer.d.ts.map +1 -1
  85. package/dist/shared/data-path.d.ts +84 -0
  86. package/dist/shared/data-path.d.ts.map +1 -1
  87. package/dist/shared/logger.d.ts +6 -0
  88. package/dist/shared/logger.d.ts.map +1 -1
  89. package/dist/shared/rpc-client.d.ts +2 -1
  90. package/dist/shared/rpc-client.d.ts.map +1 -1
  91. package/dist/shared/rpc-notifications.d.ts +3 -2
  92. package/dist/shared/rpc-notifications.d.ts.map +1 -1
  93. package/dist/shared/rpc-server.d.ts +3 -0
  94. package/dist/shared/rpc-server.d.ts.map +1 -1
  95. package/dist/shared/rpc-types.d.ts +1 -0
  96. package/dist/shared/rpc-types.d.ts.map +1 -1
  97. package/dist/shared/rpc-utils.d.ts +13 -2
  98. package/dist/shared/rpc-utils.d.ts.map +1 -1
  99. package/dist/shared/stable-json.d.ts +21 -0
  100. package/dist/shared/stable-json.d.ts.map +1 -0
  101. package/dist/shared/transcript.d.ts +2 -2
  102. package/dist/tui/data/context-db.d.ts.map +1 -1
  103. package/package.json +1 -1
  104. package/src/shared/conflict-detector.ts +4 -4
  105. package/src/shared/conflict-fixer.test.ts +124 -0
  106. package/src/shared/conflict-fixer.ts +34 -28
  107. package/src/shared/data-path.test.ts +38 -0
  108. package/src/shared/data-path.ts +99 -0
  109. package/src/shared/logger.ts +29 -3
  110. package/src/shared/rpc-client.test.ts +161 -0
  111. package/src/shared/rpc-client.ts +82 -22
  112. package/src/shared/rpc-notifications.test.ts +20 -0
  113. package/src/shared/rpc-notifications.ts +9 -6
  114. package/src/shared/rpc-server.ts +42 -4
  115. package/src/shared/rpc-types.ts +1 -0
  116. package/src/shared/rpc-utils.ts +59 -3
  117. package/src/shared/stable-json.test.ts +87 -0
  118. package/src/shared/stable-json.ts +37 -0
  119. package/src/shared/transcript.ts +2 -2
  120. package/src/tui/data/context-db.ts +20 -1
@@ -1 +1 @@
1
- {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAqDyvJ,CAAC;;;;;;;;;;;;qBAAzyD,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAAmxqB,CAAC;;;;;;EADj1wB"}
1
+ {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAqDsjJ,CAAC;;;;;;;;;;;;qBAA7pC,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAAuttB,CAAC;;;;;;EAD9t0B"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,KAAK,eAAe,IAAI,QAAQ,EAAgB,MAAM,mCAAmC,CAAC;AAQnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AASlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAmDzE,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,eAAe,CAySjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CAkKd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAoIN"}
1
+ {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,KAAK,eAAe,IAAI,QAAQ,EAAgB,MAAM,mCAAmC,CAAC;AAQnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AASlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAmDzE,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,eAAe,CAySjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CAkKd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAuIN"}
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-snapshot-cache.d.ts","sourceRoot":"","sources":["../../src/plugin/sidebar-snapshot-cache.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAY3D;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACpC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,eAAe,GACvB,eAAe,CAsCjB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
1
+ {"version":3,"file":"sidebar-snapshot-cache.d.ts","sourceRoot":"","sources":["../../src/plugin/sidebar-snapshot-cache.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAY3D;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACpC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,eAAe,GACvB,eAAe,CA6CjB;AAQD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
@@ -18,6 +18,55 @@ export interface ConflictResult {
18
18
  * Checks: OpenCode compaction, DCP plugin, OMO conflicting hooks.
19
19
  */
20
20
  export declare function detectConflicts(directory: string): ConflictResult;
21
+ /**
22
+ * Canonical npm package names that represent the conflicting plugin.
23
+ * Matched against the npm-style segment of each plugin entry, so:
24
+ * - "@tarquinen/opencode-dcp" ✓ direct match
25
+ * - "@tarquinen/opencode-dcp@latest" ✓ version suffix stripped
26
+ * - "@tarquinen/opencode-dcp@^3.1.0" ✓ semver suffix stripped
27
+ * - "file:///path/to/opencode-dcp-fork" ✗ unrelated path
28
+ *
29
+ * forks/renames that don't ship the conflicting transform/system hooks are
30
+ * intentionally NOT matched.
31
+ */
32
+ export declare const DCP_PACKAGE_NAMES: Set<string>;
33
+ /**
34
+ * Match a plugin entry against a set of canonical npm package names.
35
+ *
36
+ * A plugin entry can be:
37
+ * - "pkg-name"
38
+ * - "pkg-name@version"
39
+ * - "@scope/pkg-name"
40
+ * - "@scope/pkg-name@version"
41
+ * - "file://..." or other URL/path forms (never matched here)
42
+ *
43
+ * For the canonical-name path we only match the exact package name (with
44
+ * optional version suffix). file:// paths and forks with different
45
+ * package names are intentionally NOT matched — even if a path string
46
+ * happens to contain a substring like "oh-my-opencode" (e.g. forks like
47
+ * "oh-my-opencode-slim" published under a different package name).
48
+ */
49
+ export declare function matchesPackageName(entry: string, canonicalNames: Set<string>): boolean;
50
+ /** Extract the package-name string from a plugin entry.
51
+ * OpenCode supports two forms:
52
+ * - plain string: "@scope/pkg@latest"
53
+ * - tuple [name, opts]: ["@scope/pkg@latest", { ... }]
54
+ * Returns null for any other shape (numbers, objects, etc.). */
55
+ export declare function extractPluginName(entry: unknown): string | null;
56
+ /**
57
+ * Canonical OMO npm package names. The plugin publishes under both names as
58
+ * a versioned alias (latest 3.17.5 on npm at time of writing).
59
+ *
60
+ * Forks under a different package name (e.g. `oh-my-opencode-slim`,
61
+ * `oh-my-opencode-cli`, etc.) are intentionally NOT matched here — they
62
+ * don't ship the `preemptive-compaction`, `context-window-monitor`, or
63
+ * `anthropic-context-window-limit-recovery` hooks that conflict with
64
+ * Magic Context. See https://github.com/cortexkit/magic-context/issues/43.
65
+ *
66
+ * The legacy `@code-yeongyu/` scope is no longer used — both names are
67
+ * unscoped on npm.
68
+ */
69
+ export declare const OMO_PACKAGE_NAMES: Set<string>;
21
70
  /**
22
71
  * Generate a short conflict summary for ignored message display.
23
72
  */
@@ -1 +1 @@
1
- {"version":3,"file":"conflict-detector.d.ts","sourceRoot":"","sources":["../../src/shared/conflict-detector.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,cAAc;IAC3B,8CAA8C;IAC9C,WAAW,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2DAA2D;IAC3D,SAAS,EAAE;QACP,cAAc,EAAE,OAAO,CAAC;QACxB,eAAe,EAAE,OAAO,CAAC;QACzB,SAAS,EAAE,OAAO,CAAC;QACnB,uBAAuB,EAAE,OAAO,CAAC;QACjC,uBAAuB,EAAE,OAAO,CAAC;QACjC,oBAAoB,EAAE,OAAO,CAAC;KACjC,CAAC;CACL;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAyDjE;AAsQD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAWlE"}
1
+ {"version":3,"file":"conflict-detector.d.ts","sourceRoot":"","sources":["../../src/shared/conflict-detector.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,cAAc;IAC3B,8CAA8C;IAC9C,WAAW,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2DAA2D;IAC3D,SAAS,EAAE;QACP,cAAc,EAAE,OAAO,CAAC;QACxB,eAAe,EAAE,OAAO,CAAC;QACzB,SAAS,EAAE,OAAO,CAAC;QACnB,uBAAuB,EAAE,OAAO,CAAC;QACjC,uBAAuB,EAAE,OAAO,CAAC;QACjC,oBAAoB,EAAE,OAAO,CAAC;KACjC,CAAC;CACL;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAyDjE;AA4ED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,aAAuC,CAAC;AAOtE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAoBtF;AAED;;;;iEAIiE;AACjE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI/D;AAwCD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,aAAiD,CAAC;AAoEhF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAWlE"}
@@ -1,3 +1,3 @@
1
- import type { ConflictResult } from "./conflict-detector";
1
+ import { type ConflictResult } from "./conflict-detector";
2
2
  export declare function fixConflicts(directory: string, conflicts: ConflictResult["conflicts"]): string[];
3
3
  //# sourceMappingURL=conflict-fixer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conflict-fixer.d.ts","sourceRoot":"","sources":["../../src/shared/conflict-fixer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAmG1D,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG,MAAM,EAAE,CAiHhG"}
1
+ {"version":3,"file":"conflict-fixer.d.ts","sourceRoot":"","sources":["../../src/shared/conflict-fixer.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,cAAc,EAItB,MAAM,qBAAqB,CAAC;AAqG7B,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG,MAAM,EAAE,CA+GhG"}
@@ -1,4 +1,88 @@
1
+ import { type HarnessId } from "./harness";
1
2
  export declare function getDataDir(): string;
3
+ /**
4
+ * Per-harness scratch directory under the OS temp dir.
5
+ *
6
+ * Layout:
7
+ * - OpenCode: `${os.tmpdir()}/opencode/magic-context/`
8
+ * - Pi: `${os.tmpdir()}/pi/magic-context/`
9
+ *
10
+ * Why a per-harness subtree of `os.tmpdir()`:
11
+ * 1. OpenCode Desktop runs as an Electron app with a permission sandbox.
12
+ * Writing to arbitrary tmp paths can trigger user-visible permission
13
+ * prompts; the `${tmpdir}/opencode/` subtree is allow-listed by
14
+ * OpenCode, so anything we put under it never asks for permission.
15
+ * 2. Splitting OpenCode from Pi keeps their logs and historian dump
16
+ * directories cleanly separated. `doctor --issue` for each harness
17
+ * reports diagnostics from the matching subtree, so an OpenCode
18
+ * issue report never includes Pi log noise (and vice versa).
19
+ * 3. Pi has no permission sandbox, so the path choice is purely
20
+ * cosmetic for Pi — it just keeps the layout symmetric.
21
+ *
22
+ * Pass an explicit `harness` only when the caller already knows the
23
+ * harness without relying on the global `setHarness()` state (e.g. the
24
+ * CLI's doctor commands, which target a specific harness regardless of
25
+ * which plugin is loaded). Production runtime callers should omit it so
26
+ * the helper picks up the boot-time harness automatically.
27
+ */
28
+ export declare function getMagicContextTempDir(harness?: HarnessId): string;
29
+ /**
30
+ * Standard log file path the plugin writes to. Pi and OpenCode write to
31
+ * SEPARATE logs under their respective harness subtrees so a single
32
+ * machine running both harnesses doesn't interleave session traces.
33
+ *
34
+ * The plugin's buffered logger calls this on every flush rather than
35
+ * caching, so `setHarness("pi")` taking effect after module load is
36
+ * reflected in the next flush.
37
+ */
38
+ export declare function getMagicContextLogPath(harness?: HarnessId): string;
39
+ /**
40
+ * Directory used for both historian validation-failure dumps and the
41
+ * existing-state offload XMLs that large historian/recomp passes write
42
+ * before invoking the model. Per-harness so dumps from different
43
+ * harnesses don't collide on filename and so `doctor --issue` for each
44
+ * harness reports only its own historian artifacts.
45
+ */
46
+ export declare function getMagicContextHistorianDir(harness?: HarnessId): string;
47
+ /**
48
+ * Project-local magic-context artifact directory.
49
+ *
50
+ * Layout: `<project-directory>/.opencode/magic-context/`
51
+ *
52
+ * Used for artifacts that the historian/recomp pipeline writes during a run
53
+ * and that the model is asked to read via its native Read tool. OpenCode's
54
+ * `external_directory` permission system asks the user before reading any
55
+ * file outside the project directory or its worktree, which interrupts every
56
+ * historian run when artifacts live under `os.tmpdir()`. Writing under the
57
+ * project's own `.opencode/` subtree falls inside the project boundary and
58
+ * never triggers a permission prompt.
59
+ *
60
+ * The `.opencode/` parent dir is OpenCode's own per-project convention (used
61
+ * for project-local config, plans, dumps, plugin installs). Anchoring
62
+ * magic-context artifacts under `.opencode/magic-context/` keeps them
63
+ * co-located with related OpenCode metadata and makes them easy for users to
64
+ * locate when debugging.
65
+ *
66
+ * Logger does NOT use this — log files stay in the per-harness tmp subtree
67
+ * because they are written by the plugin process itself (no model-side Read
68
+ * tool call, no permission prompt) and span sessions/projects.
69
+ */
70
+ export declare function getProjectMagicContextDir(directory: string): string;
71
+ /**
72
+ * Project-local historian artifact directory.
73
+ *
74
+ * Layout: `<project-directory>/.opencode/magic-context/historian/`
75
+ *
76
+ * Used for:
77
+ * - existing-state offload XMLs that long historian/recomp passes write
78
+ * before invoking the model (the model reads the file via Read tool)
79
+ * - validation-failure dump XMLs preserved for debugging
80
+ *
81
+ * Callers must `mkdirSync(dir, { recursive: true })` before writing — the
82
+ * `.opencode/` parent may not exist on a fresh project, and write failures
83
+ * here must degrade gracefully (e.g. historian falls back to inline state).
84
+ */
85
+ export declare function getProjectMagicContextHistorianDir(directory: string): string;
2
86
  export declare function getOpenCodeStorageDir(): string;
3
87
  /**
4
88
  * Resolve the shared magic-context storage directory.
@@ -1 +1 @@
1
- {"version":3,"file":"data-path.d.ts","sourceRoot":"","sources":["../../src/shared/data-path.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,uCAAuC,IAAI,MAAM,CAEhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
1
+ {"version":3,"file":"data-path.d.ts","sourceRoot":"","sources":["../../src/shared/data-path.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEvD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,SAAwB,GAAG,MAAM,CAEhF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,SAAwB,GAAG,MAAM,CAEhF;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,SAAwB,GAAG,MAAM,CAErF;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kCAAkC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,uCAAuC,IAAI,MAAM,CAEhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -1,4 +1,10 @@
1
1
  export declare function log(message: string, data?: unknown): void;
2
2
  export declare function sessionLog(sessionId: string, message: string, data?: unknown): void;
3
+ /**
4
+ * Resolve the current log file path. The path is harness-aware (see
5
+ * {@link getMagicContextLogPath}) and re-evaluated on every call, so callers
6
+ * who format diagnostic output with this value always see the path the next
7
+ * flush will actually use.
8
+ */
3
9
  export declare function getLogFilePath(): string;
4
10
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/shared/logger.ts"],"names":[],"mappings":"AAmCA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAmBzD;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/shared/logger.ts"],"names":[],"mappings":"AAuDA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAmBzD;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -1,6 +1,7 @@
1
1
  export declare class MagicContextRpcClient {
2
2
  private port;
3
- private portFilePath;
3
+ private portDir;
4
+ private legacyPortFilePath;
4
5
  private healthChecked;
5
6
  constructor(storageDir: string, directory: string);
6
7
  /** Call an RPC method. Retries port resolution if the server isn't ready yet. */
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-client.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-client.ts"],"names":[],"mappings":"AAOA,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAS;gBAElB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAIjD,iFAAiF;IAC3E,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,CAAC,CAAC;IAoBb,4CAA4C;IACtC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YASvB,WAAW;IAkCzB,OAAO,CAAC,YAAY;YAaN,WAAW;YAWX,gBAAgB;IAU9B,KAAK,IAAI,IAAI;CAIhB"}
1
+ {"version":3,"file":"rpc-client.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-client.ts"],"names":[],"mappings":"AAiBA,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,aAAa,CAAS;gBAElB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAKjD,iFAAiF;IAC3E,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,CAAC,CAAC;IAiDb,4CAA4C;IACtC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YASvB,WAAW;IAkCzB,OAAO,CAAC,YAAY;YA4BN,WAAW;YAWX,gBAAgB;IAU9B,KAAK,IAAI,IAAI;CAIhB"}
@@ -7,15 +7,16 @@
7
7
  * because the server runs in a separate process from the TUI client.
8
8
  */
9
9
  export interface RpcNotification {
10
+ id: number;
10
11
  type: string;
11
12
  payload: Record<string, unknown>;
12
13
  sessionId?: string;
13
14
  }
14
15
  /** Push a notification for TUI to pick up via polling. */
15
16
  export declare function pushNotification(type: string, payload: Record<string, unknown>, sessionId?: string): void;
16
- /** Drain and return all pending notifications atomically.
17
+ /** Return pending notifications after acking the client's last received id.
17
18
  * Updates lastDrainAt so isTuiConnected() reflects recent activity. */
18
- export declare function drainNotifications(): RpcNotification[];
19
+ export declare function drainNotifications(lastReceivedId?: number): RpcNotification[];
19
20
  /** Whether a TUI client is actively polling for notifications.
20
21
  * Returns true only if the TUI has drained within the last 3 seconds.
21
22
  * This prevents stale-connected state after TUI closes or disconnects. */
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-notifications.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AASD,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,CAAC,EAAE,MAAM,GACnB,IAAI,CAMN;AAED;wEACwE;AACxE,wBAAgB,kBAAkB,IAAI,eAAe,EAAE,CAKtD;AAED;;2EAE2E;AAC3E,wBAAgB,cAAc,IAAI,OAAO,CAExC"}
1
+ {"version":3,"file":"rpc-notifications.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAUD,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,CAAC,EAAE,MAAM,GACnB,IAAI,CAMN;AAED;wEACwE;AACxE,wBAAgB,kBAAkB,CAAC,cAAc,SAAI,GAAG,eAAe,EAAE,CAMxE;AAED;;2EAE2E;AAC3E,wBAAgB,cAAc,IAAI,OAAO,CAExC"}
@@ -4,11 +4,14 @@ export declare class MagicContextRpcServer {
4
4
  private port;
5
5
  private handlers;
6
6
  private portFilePath;
7
+ private portDir;
8
+ private startedAt;
7
9
  constructor(storageDir: string, directory: string);
8
10
  /** Register an RPC method handler. */
9
11
  handle(method: string, handler: RpcHandler): void;
10
12
  /** Start the server on a random port, write port to disk. */
11
13
  start(): Promise<number>;
14
+ private warnIfOtherLiveInstance;
12
15
  /** Stop the server and clean up port file. */
13
16
  stop(): void;
14
17
  private dispatch;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-server.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-server.ts"],"names":[],"mappings":"AAMA,KAAK,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAExF,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,YAAY,CAAS;gBAEjB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAIjD,sCAAsC;IACtC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAIjD,6DAA6D;IACvD,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAsC9B,8CAA8C;IAC9C,IAAI,IAAI,IAAI;IAYZ,OAAO,CAAC,QAAQ;CA4DnB"}
1
+ {"version":3,"file":"rpc-server.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-server.ts"],"names":[],"mappings":"AAaA,KAAK,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAExF,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAc;gBAEnB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAKjD,sCAAsC;IACtC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAIjD,6DAA6D;IACvD,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkD9B,OAAO,CAAC,uBAAuB;IAgB/B,8CAA8C;IAC9C,IAAI,IAAI,IAAI;IAYZ,OAAO,CAAC,QAAQ;CA4DnB"}
@@ -84,6 +84,7 @@ export interface StatusDetail extends SidebarSnapshot {
84
84
  compressionUsage: string | null;
85
85
  }
86
86
  export interface RpcNotificationMessage {
87
+ id: number;
87
88
  type: string;
88
89
  payload: Record<string, unknown>;
89
90
  sessionId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC9C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC9C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1,8 +1,19 @@
1
+ export interface RpcPortFileRecord {
2
+ port: number;
3
+ pid: number;
4
+ started_at: number;
5
+ }
1
6
  /**
2
7
  * Stable hash for a project directory — scopes RPC port files per-project
3
8
  * so multiple OpenCode instances don't collide.
4
9
  */
5
10
  export declare function projectHash(directory: string): string;
6
- /** Per-project RPC port file path. */
7
- export declare function rpcPortFilePath(storageDir: string, directory: string): string;
11
+ /** Directory containing per-process RPC discovery files for a project. */
12
+ export declare function rpcPortDir(storageDir: string, directory: string): string;
13
+ /** Per-process RPC port file path. */
14
+ export declare function rpcPortFilePath(storageDir: string, directory: string, pid?: number): string;
15
+ /** Legacy single-port file used by v0.18.0 and earlier. */
16
+ export declare function legacyRpcPortFilePath(storageDir: string, directory: string): string;
17
+ export declare function isPidAlive(pid: number): boolean;
18
+ export declare function parseRpcPortFile(content: string, fallbackPid?: number): RpcPortFileRecord | null;
8
19
  //# sourceMappingURL=rpc-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-utils.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-utils.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7E"}
1
+ {"version":3,"file":"rpc-utils.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-utils.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,SAAc,GAAG,MAAM,CAEhG;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ/C;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,SAAI,GAAG,iBAAiB,GAAG,IAAI,CAwB3F"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Process-local deterministic JSON serialization for JSON-like plain
3
+ * objects. Keys are sorted by code-point order (NOT locale-sensitive).
4
+ *
5
+ * Contract:
6
+ * - Stable for plain objects, arrays, primitives, and `null`.
7
+ * - `undefined` serialized as the string "undefined".
8
+ * - Circular references serialized as the string `"[Circular]"`.
9
+ * - **NOT** a canonical cross-runtime / cross-locale JSON serializer.
10
+ * Two different runtimes that disagree on `JSON.stringify` of primitives
11
+ * (none known today) would produce different output.
12
+ *
13
+ * Used for:
14
+ * - `tool_definition_measurements` fingerprint hashing
15
+ * - `pending_compaction_marker_state` CAS comparison
16
+ *
17
+ * If a future use case needs true canonical JSON (e.g. cross-process
18
+ * signing), build a separate utility — do NOT widen this contract.
19
+ */
20
+ export declare function stableStringify(value: unknown, seen?: WeakSet<object>): string;
21
+ //# sourceMappingURL=stable-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable-json.d.ts","sourceRoot":"","sources":["../../src/shared/stable-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,kBAAwB,GAAG,MAAM,CAiBpF"}
@@ -22,7 +22,7 @@
22
22
  * 3. Lets the shared transform code (tagging, stripping, drops)
23
23
  * operate on `TranscriptPart` interface instances without caring
24
24
  * whether they're wrapping `Part` from `@opencode-ai/sdk` or
25
- * `TextContent | ToolCall | ThinkingContent` from `@mariozechner/pi-ai`.
25
+ * `TextContent | ToolCall | ThinkingContent` from `@earendil-works/pi-ai`.
26
26
  *
27
27
  * What this interface deliberately does NOT do:
28
28
  *
@@ -169,7 +169,7 @@ export interface TranscriptMessage {
169
169
  * messages-transform.ts, Pi's context-event handler). The shared
170
170
  * transform code receives a Transcript and operates only through this
171
171
  * interface — it never imports from `@opencode-ai/sdk` or
172
- * `@mariozechner/pi-ai`.
172
+ * `@earendil-works/pi-ai`.
173
173
  */
174
174
  export interface Transcript {
175
175
  /** Ordered messages in the current pass. */
@@ -1 +1 @@
1
- {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAa9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAG/B;AA4ED,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAchE"}
1
+ {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAc9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAI/B;AAsFD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -179,7 +179,7 @@ function readUserCompaction(): { auto: boolean; prune: boolean; resolved: boolea
179
179
  * forks/renames that don't ship the conflicting transform/system hooks are
180
180
  * intentionally NOT matched.
181
181
  */
182
- const DCP_PACKAGE_NAMES = new Set(["@tarquinen/opencode-dcp"]);
182
+ export const DCP_PACKAGE_NAMES = new Set(["@tarquinen/opencode-dcp"]);
183
183
 
184
184
  function checkDcpPlugin(directory: string): boolean {
185
185
  const plugins = collectPluginEntries(directory);
@@ -202,7 +202,7 @@ function checkDcpPlugin(directory: string): boolean {
202
202
  * happens to contain a substring like "oh-my-opencode" (e.g. forks like
203
203
  * "oh-my-opencode-slim" published under a different package name).
204
204
  */
205
- function matchesPackageName(entry: string, canonicalNames: Set<string>): boolean {
205
+ export function matchesPackageName(entry: string, canonicalNames: Set<string>): boolean {
206
206
  // Skip URL/path forms — only npm-style entries can be canonically matched.
207
207
  // (Local file:// checkouts of canonical plugins are rare; users running
208
208
  // those need to ensure the path itself doesn't match a fork's name.)
@@ -229,7 +229,7 @@ function matchesPackageName(entry: string, canonicalNames: Set<string>): boolean
229
229
  * - plain string: "@scope/pkg@latest"
230
230
  * - tuple [name, opts]: ["@scope/pkg@latest", { ... }]
231
231
  * Returns null for any other shape (numbers, objects, etc.). */
232
- function extractPluginName(entry: string | [string, unknown]): string | null {
232
+ export function extractPluginName(entry: unknown): string | null {
233
233
  if (typeof entry === "string") return entry;
234
234
  if (Array.isArray(entry) && typeof entry[0] === "string") return entry[0];
235
235
  return null;
@@ -286,7 +286,7 @@ function collectPluginEntries(directory: string): string[] {
286
286
  * The legacy `@code-yeongyu/` scope is no longer used — both names are
287
287
  * unscoped on npm.
288
288
  */
289
- const OMO_PACKAGE_NAMES = new Set(["oh-my-opencode", "oh-my-openagent"]);
289
+ export const OMO_PACKAGE_NAMES = new Set(["oh-my-opencode", "oh-my-openagent"]);
290
290
 
291
291
  function checkOmoHooks(directory: string): {
292
292
  preemptiveCompaction: boolean;
@@ -0,0 +1,124 @@
1
+ /// <reference types="bun-types" />
2
+
3
+ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
4
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
6
+ import { join } from "node:path";
7
+ import { parse as parseJsonc } from "comment-json";
8
+ import { fixConflicts } from "./conflict-fixer";
9
+
10
+ const noOmoConflicts = {
11
+ omoPreemptiveCompaction: false,
12
+ omoContextWindowMonitor: false,
13
+ omoAnthropicRecovery: false,
14
+ };
15
+
16
+ describe("fixConflicts", () => {
17
+ let root: string;
18
+ let projectDir: string;
19
+ let userConfigDir: string;
20
+ let originalEnv: Record<string, string | undefined>;
21
+
22
+ beforeEach(() => {
23
+ root = mkdtempSync(join(tmpdir(), "mc-conflict-fixer-"));
24
+ projectDir = join(root, "project");
25
+ userConfigDir = join(root, "user-config", "opencode");
26
+ mkdirSync(projectDir, { recursive: true });
27
+ mkdirSync(userConfigDir, { recursive: true });
28
+ originalEnv = {
29
+ OPENCODE_CONFIG_DIR: process.env.OPENCODE_CONFIG_DIR,
30
+ XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
31
+ };
32
+ process.env.OPENCODE_CONFIG_DIR = userConfigDir;
33
+ delete process.env.XDG_CONFIG_HOME;
34
+ });
35
+
36
+ afterEach(() => {
37
+ for (const [key, value] of Object.entries(originalEnv)) {
38
+ if (value === undefined) delete process.env[key];
39
+ else process.env[key] = value;
40
+ }
41
+ rmSync(root, { recursive: true, force: true });
42
+ });
43
+
44
+ it("preserves JSONC comments and tuple plugin entries while removing canonical DCP", () => {
45
+ const configPath = join(projectDir, "opencode.jsonc");
46
+ writeFileSync(
47
+ configPath,
48
+ `{
49
+ // keep this file-level comment
50
+ "plugin": [
51
+ ["@plannotator/opencode@latest", { "workflow": "plan-agent" }],
52
+ ["@tarquinen/opencode-dcp@latest", { "enabled": true }],
53
+ "@cortexkit/opencode-magic-context@latest"
54
+ ],
55
+ "compaction": {
56
+ // keep this compaction comment
57
+ "auto": true,
58
+ "prune": true
59
+ }
60
+ }
61
+ `,
62
+ );
63
+
64
+ const actions = fixConflicts(projectDir, {
65
+ compactionAuto: true,
66
+ compactionPrune: true,
67
+ dcpPlugin: true,
68
+ ...noOmoConflicts,
69
+ });
70
+
71
+ const updatedText = readFileSync(configPath, "utf-8");
72
+ const updated = parseJsonc(updatedText) as Record<string, unknown>;
73
+ expect(actions).toEqual(["Disabled auto-compaction", "Removed opencode-dcp plugin"]);
74
+ expect(updatedText).toContain("keep this file-level comment");
75
+ expect(updatedText).toContain("keep this compaction comment");
76
+ expect(updated.compaction).toEqual({ auto: false, prune: false });
77
+ expect(updated.plugin).toEqual([
78
+ ["@plannotator/opencode@latest", { workflow: "plan-agent" }],
79
+ "@cortexkit/opencode-magic-context@latest",
80
+ ]);
81
+ });
82
+
83
+ it("skips non-existent target files instead of creating user config", () => {
84
+ const actions = fixConflicts(projectDir, {
85
+ compactionAuto: true,
86
+ compactionPrune: true,
87
+ dcpPlugin: true,
88
+ ...noOmoConflicts,
89
+ });
90
+
91
+ expect(actions).toEqual([]);
92
+ expect(existsSync(join(userConfigDir, "opencode.json"))).toBe(false);
93
+ expect(existsSync(join(userConfigDir, "opencode.jsonc"))).toBe(false);
94
+ });
95
+
96
+ it("keeps DCP forks and substring-only names because matching is canonical", () => {
97
+ const configPath = join(projectDir, "opencode.json");
98
+ writeFileSync(
99
+ configPath,
100
+ JSON.stringify({
101
+ plugin: [
102
+ "@some-fork/opencode-dcp-fork",
103
+ "file:///tmp/opencode-dcp-dev",
104
+ ["@other/opencode-dcp-slim@latest", { enabled: true }],
105
+ ],
106
+ }),
107
+ );
108
+
109
+ const actions = fixConflicts(projectDir, {
110
+ compactionAuto: false,
111
+ compactionPrune: false,
112
+ dcpPlugin: true,
113
+ ...noOmoConflicts,
114
+ });
115
+
116
+ const updated = parseJsonc(readFileSync(configPath, "utf-8")) as Record<string, unknown>;
117
+ expect(actions).toEqual([]);
118
+ expect(updated.plugin).toEqual([
119
+ "@some-fork/opencode-dcp-fork",
120
+ "file:///tmp/opencode-dcp-dev",
121
+ ["@other/opencode-dcp-slim@latest", { enabled: true }],
122
+ ]);
123
+ });
124
+ });