@cortexkit/opencode-magic-context 0.15.7 → 0.16.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.
Files changed (204) hide show
  1. package/README.md +42 -16
  2. package/dist/agents/magic-context-prompt.d.ts +2 -13
  3. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  4. package/dist/config/schema/magic-context.d.ts +67 -4
  5. package/dist/config/schema/magic-context.d.ts.map +1 -1
  6. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  7. package/dist/features/magic-context/compaction.d.ts +1 -1
  8. package/dist/features/magic-context/compaction.d.ts.map +1 -1
  9. package/dist/features/magic-context/compartment-storage.d.ts +1 -1
  10. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  11. package/dist/features/magic-context/compression-depth-storage.d.ts +1 -1
  12. package/dist/features/magic-context/compression-depth-storage.d.ts.map +1 -1
  13. package/dist/features/magic-context/dreamer/lease.d.ts +1 -1
  14. package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
  15. package/dist/features/magic-context/dreamer/queue.d.ts +8 -3
  16. package/dist/features/magic-context/dreamer/queue.d.ts.map +1 -1
  17. package/dist/features/magic-context/dreamer/runner.d.ts +1 -1
  18. package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
  19. package/dist/features/magic-context/dreamer/scheduler.d.ts +1 -1
  20. package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -1
  21. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +1 -1
  22. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  23. package/dist/features/magic-context/dreamer/storage-dream-state.d.ts +1 -1
  24. package/dist/features/magic-context/dreamer/storage-dream-state.d.ts.map +1 -1
  25. package/dist/features/magic-context/git-commits/indexer.d.ts +1 -1
  26. package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -1
  27. package/dist/features/magic-context/git-commits/search-git-commits.d.ts +1 -1
  28. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
  29. package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts +1 -1
  30. package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts.map +1 -1
  31. package/dist/features/magic-context/git-commits/storage-git-commits.d.ts +1 -1
  32. package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -1
  33. package/dist/features/magic-context/key-files/identify-key-files.d.ts +1 -1
  34. package/dist/features/magic-context/key-files/identify-key-files.d.ts.map +1 -1
  35. package/dist/features/magic-context/key-files/read-stats.d.ts +1 -1
  36. package/dist/features/magic-context/key-files/read-stats.d.ts.map +1 -1
  37. package/dist/features/magic-context/key-files/storage-key-files.d.ts +1 -1
  38. package/dist/features/magic-context/key-files/storage-key-files.d.ts.map +1 -1
  39. package/dist/features/magic-context/memory/embedding-backfill.d.ts +1 -1
  40. package/dist/features/magic-context/memory/embedding-backfill.d.ts.map +1 -1
  41. package/dist/features/magic-context/memory/embedding-cache.d.ts +1 -1
  42. package/dist/features/magic-context/memory/embedding-cache.d.ts.map +1 -1
  43. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  44. package/dist/features/magic-context/memory/embedding.d.ts +1 -1
  45. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  46. package/dist/features/magic-context/memory/normalize-hash.d.ts.map +1 -1
  47. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  48. package/dist/features/magic-context/memory/promotion.d.ts +1 -1
  49. package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
  50. package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +1 -1
  51. package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -1
  52. package/dist/features/magic-context/memory/storage-memory-fts.d.ts +1 -1
  53. package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -1
  54. package/dist/features/magic-context/memory/storage-memory.d.ts +1 -1
  55. package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
  56. package/dist/features/magic-context/message-index.d.ts +1 -1
  57. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  58. package/dist/features/magic-context/migrations.d.ts +1 -1
  59. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  60. package/dist/features/magic-context/mock-database.d.ts +1 -1
  61. package/dist/features/magic-context/mock-database.d.ts.map +1 -1
  62. package/dist/features/magic-context/plugin-messages.d.ts +1 -1
  63. package/dist/features/magic-context/plugin-messages.d.ts.map +1 -1
  64. package/dist/features/magic-context/search.d.ts +1 -1
  65. package/dist/features/magic-context/search.d.ts.map +1 -1
  66. package/dist/features/magic-context/sidekick/agent.d.ts +2 -1
  67. package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
  68. package/dist/features/magic-context/sidekick/core.d.ts +38 -0
  69. package/dist/features/magic-context/sidekick/core.d.ts.map +1 -0
  70. package/dist/features/magic-context/storage-db.d.ts +20 -1
  71. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  72. package/dist/features/magic-context/storage-meta-persisted.d.ts +1 -1
  73. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  74. package/dist/features/magic-context/storage-meta-session.d.ts +1 -1
  75. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  76. package/dist/features/magic-context/storage-meta-shared.d.ts +1 -1
  77. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  78. package/dist/features/magic-context/storage-notes.d.ts +1 -1
  79. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  80. package/dist/features/magic-context/storage-ops.d.ts +1 -1
  81. package/dist/features/magic-context/storage-ops.d.ts.map +1 -1
  82. package/dist/features/magic-context/storage-source.d.ts +1 -1
  83. package/dist/features/magic-context/storage-source.d.ts.map +1 -1
  84. package/dist/features/magic-context/storage-tags.d.ts +17 -1
  85. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  86. package/dist/features/magic-context/tagger.d.ts +1 -1
  87. package/dist/features/magic-context/tagger.d.ts.map +1 -1
  88. package/dist/features/magic-context/user-memory/review-user-memories.d.ts +1 -1
  89. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  90. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +1 -1
  91. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  92. package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
  93. package/dist/hooks/magic-context/auto-search-runner.d.ts +1 -1
  94. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  95. package/dist/hooks/magic-context/command-handler.d.ts +1 -1
  96. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  97. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +1 -1
  98. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  99. package/dist/hooks/magic-context/compartment-prompt.d.ts +1 -0
  100. package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
  101. package/dist/hooks/magic-context/compartment-runner-compressor.d.ts +1 -1
  102. package/dist/hooks/magic-context/compartment-runner-compressor.d.ts.map +1 -1
  103. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +1 -1
  104. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
  105. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +1 -0
  106. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  107. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  108. package/dist/hooks/magic-context/compartment-runner-types.d.ts +1 -1
  109. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  110. package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
  111. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  112. package/dist/hooks/magic-context/execute-flush.d.ts +1 -1
  113. package/dist/hooks/magic-context/execute-flush.d.ts.map +1 -1
  114. package/dist/hooks/magic-context/execute-status.d.ts +1 -1
  115. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  116. package/dist/hooks/magic-context/historian-state-file.d.ts +29 -0
  117. package/dist/hooks/magic-context/historian-state-file.d.ts.map +1 -0
  118. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  119. package/dist/hooks/magic-context/inject-compartments.d.ts +1 -1
  120. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  121. package/dist/hooks/magic-context/note-nudger.d.ts +1 -1
  122. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  123. package/dist/hooks/magic-context/nudge-placement-store.d.ts +1 -1
  124. package/dist/hooks/magic-context/nudge-placement-store.d.ts.map +1 -1
  125. package/dist/hooks/magic-context/read-session-chunk.d.ts +39 -0
  126. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  127. package/dist/hooks/magic-context/read-session-db.d.ts +1 -1
  128. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  129. package/dist/hooks/magic-context/read-session-raw.d.ts +1 -1
  130. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  131. package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
  132. package/dist/hooks/magic-context/system-prompt-hash.d.ts +6 -5
  133. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  134. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  135. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  136. package/dist/index.js +8284 -8166
  137. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  138. package/dist/plugin/messages-transform.d.ts +1 -1
  139. package/dist/plugin/rpc-handlers.d.ts +4 -0
  140. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  141. package/dist/plugin/tool-registry.d.ts.map +1 -1
  142. package/dist/shared/conflict-detector.d.ts.map +1 -1
  143. package/dist/shared/data-path.d.ts +22 -0
  144. package/dist/shared/data-path.d.ts.map +1 -1
  145. package/dist/shared/harness.d.ts +43 -0
  146. package/dist/shared/harness.d.ts.map +1 -0
  147. package/dist/shared/rpc-notifications.d.ts +4 -2
  148. package/dist/shared/rpc-notifications.d.ts.map +1 -1
  149. package/dist/shared/sqlite-helpers.d.ts +16 -0
  150. package/dist/shared/sqlite-helpers.d.ts.map +1 -0
  151. package/dist/shared/sqlite.d.ts +55 -0
  152. package/dist/shared/sqlite.d.ts.map +1 -0
  153. package/dist/shared/subagent-runner.d.ts +202 -0
  154. package/dist/shared/subagent-runner.d.ts.map +1 -0
  155. package/dist/shared/tag-transcript.d.ts +66 -0
  156. package/dist/shared/tag-transcript.d.ts.map +1 -0
  157. package/dist/shared/transcript-opencode.d.ts +71 -0
  158. package/dist/shared/transcript-opencode.d.ts.map +1 -0
  159. package/dist/shared/transcript.d.ts +212 -0
  160. package/dist/shared/transcript.d.ts.map +1 -0
  161. package/dist/shared/tui-config.d.ts.map +1 -1
  162. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  163. package/dist/tools/ctx-memory/types.d.ts +13 -2
  164. package/dist/tools/ctx-memory/types.d.ts.map +1 -1
  165. package/dist/tools/ctx-note/tools.d.ts +8 -2
  166. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  167. package/dist/tools/ctx-reduce/tools.d.ts +1 -1
  168. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  169. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  170. package/dist/tools/ctx-search/types.d.ts +8 -2
  171. package/dist/tools/ctx-search/types.d.ts.map +1 -1
  172. package/dist/tui/data/context-db.d.ts.map +1 -1
  173. package/package.json +73 -75
  174. package/src/shared/conflict-detector.test.ts +44 -1
  175. package/src/shared/conflict-detector.ts +24 -8
  176. package/src/shared/data-path.test.ts +53 -1
  177. package/src/shared/data-path.ts +28 -0
  178. package/src/shared/harness.ts +61 -0
  179. package/src/shared/rpc-notifications.ts +11 -5
  180. package/src/shared/sqlite-helpers.ts +27 -0
  181. package/src/shared/sqlite.ts +91 -0
  182. package/src/shared/subagent-runner.ts +206 -0
  183. package/src/shared/tag-transcript.ts +541 -0
  184. package/src/shared/transcript-opencode.ts +259 -0
  185. package/src/shared/transcript.ts +226 -0
  186. package/src/shared/tui-config.ts +34 -8
  187. package/src/tui/data/context-db.ts +5 -1
  188. package/dist/cli/config-paths.d.ts +0 -11
  189. package/dist/cli/config-paths.d.ts.map +0 -1
  190. package/dist/cli/diagnostics.d.ts +0 -82
  191. package/dist/cli/diagnostics.d.ts.map +0 -1
  192. package/dist/cli/doctor.d.ts +0 -5
  193. package/dist/cli/doctor.d.ts.map +0 -1
  194. package/dist/cli/index.d.ts +0 -3
  195. package/dist/cli/index.d.ts.map +0 -1
  196. package/dist/cli/logs.d.ts +0 -22
  197. package/dist/cli/logs.d.ts.map +0 -1
  198. package/dist/cli/opencode-helpers.d.ts +0 -19
  199. package/dist/cli/opencode-helpers.d.ts.map +0 -1
  200. package/dist/cli/prompts.d.ts +0 -14
  201. package/dist/cli/prompts.d.ts.map +0 -1
  202. package/dist/cli/setup.d.ts +0 -2
  203. package/dist/cli/setup.d.ts.map +0 -1
  204. package/dist/cli.js +0 -11287
@@ -0,0 +1,259 @@
1
+ /**
2
+ * OpenCode adapter for the harness-agnostic transcript interface.
3
+ *
4
+ * This is a thin proxy over OpenCode's `MessageLike[]` (i.e. `{ info,
5
+ * parts: unknown[] }[]`) — it does NOT copy data. Mutations through
6
+ * `setText`/`setToolOutput`/`replaceWithSentinel` write directly into
7
+ * the source `parts[]` arrays, exactly as the existing OpenCode-only
8
+ * transform code does today. `commit()` is a no-op because OpenCode's
9
+ * AI SDK reads `parts[]` back from the same array we mutated.
10
+ *
11
+ * This module is the boundary that lets the rest of the transform code
12
+ * (which moves to use the Transcript interface in 4b.2) work both for
13
+ * OpenCode and Pi without branching on harness type. By the end of 4b
14
+ * the only OpenCode-aware code in the plugin is this file plus
15
+ * `messages-transform.ts`.
16
+ *
17
+ * ## Mutation contract recap
18
+ *
19
+ * Magic Context's transform mutates message parts in three ways:
20
+ *
21
+ * 1. **Tag prefix injection** — prepends `§N§ ` to text parts and
22
+ * tool result outputs. Repeated tagging is idempotent because
23
+ * `prependTag` strips any existing prefix first.
24
+ *
25
+ * 2. **Sentinel replacement** — when a queued drop fires, the part is
26
+ * replaced with a `[dropped §N§]` or `[truncated §N§]` placeholder.
27
+ * The original tag number is preserved so the agent's mental
28
+ * model of "what was here" survives.
29
+ *
30
+ * 3. **Structural noise stripping** — `step-start`/`step-finish`
31
+ * wrappers and similar structural metadata are replaced with empty
32
+ * sentinel parts so they don't consume tag numbers or get tagged
33
+ * themselves.
34
+ *
35
+ * The OpenCode adapter implements (1) and (2) by editing `part.text` /
36
+ * `part.state.output` in place. For (3), structural parts surface as
37
+ * `kind: "structural"` so callers can filter them out. Adapter does NOT
38
+ * itself perform stripping — that's the transform pipeline's job, called
39
+ * after the adapter wraps the messages.
40
+ *
41
+ * Step 4b.1 ships the adapter alone. The existing OpenCode transform
42
+ * code keeps using `MessageLike[]` directly until 4b.2 migrates the
43
+ * tagging+drops layer to use Transcript instances.
44
+ */
45
+
46
+ import { isRecord } from "./record-type-guard";
47
+ import type {
48
+ Transcript,
49
+ TranscriptMessage,
50
+ TranscriptPart,
51
+ TranscriptPartKind,
52
+ } from "./transcript";
53
+
54
+ /**
55
+ * The OpenCode `MessageLike` shape. Re-declared here to avoid a circular
56
+ * import with `tag-messages.ts` (which lives in the magic-context hooks
57
+ * tree and depends on storage). Keeping a local minimal type also makes
58
+ * the adapter trivially unit-testable without booting OpenCode SDK
59
+ * types.
60
+ *
61
+ * MUST stay structurally compatible with `tag-messages.ts MessageLike` —
62
+ * if that file's MessageLike adds a required field, this one needs to
63
+ * add it too. The build will fail loudly if the shapes diverge.
64
+ */
65
+ export interface OpenCodeMessageLike {
66
+ info: { id?: string; role?: string; sessionID?: string };
67
+ parts: unknown[];
68
+ }
69
+
70
+ /**
71
+ * Wrap an existing `MessageLike[]` as a Transcript. Zero copies — every
72
+ * `TranscriptPart` returned proxies the matching entry in the source
73
+ * `parts` array, and mutations are reflected immediately.
74
+ */
75
+ export function createOpenCodeTranscript(messages: OpenCodeMessageLike[]): Transcript {
76
+ const transcriptMessages: TranscriptMessage[] = messages.map((message) => ({
77
+ info: {
78
+ id: message.info.id,
79
+ role: message.info.role ?? "unknown",
80
+ sessionId: message.info.sessionID,
81
+ },
82
+ // `parts` is a getter so newly-replaced sentinels inside the
83
+ // underlying array are surfaced on the next read. Cheap; allocs
84
+ // one wrapper per part per access. Adapter callers iterate
85
+ // `messages` once per pass so the cost is O(parts) per pass —
86
+ // same as before the adapter existed.
87
+ get parts(): TranscriptPart[] {
88
+ return message.parts.map((part, index) => createOpenCodePart(message, index, part));
89
+ },
90
+ }));
91
+
92
+ return {
93
+ messages: transcriptMessages,
94
+ harness: "opencode",
95
+ // OpenCode reads parts back from the same `parts[]` array we
96
+ // mutated, so there's nothing to flush. Adapters that buffer
97
+ // mutations (Pi) override this.
98
+ commit(): void {
99
+ /* no-op for OpenCode */
100
+ },
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Construct a TranscriptPart proxy over a single OpenCode part.
106
+ *
107
+ * Held by `parts` getter calls only; never cached because the underlying
108
+ * `parts[]` array can be mutated in place (sentinel replacement) and
109
+ * cached proxies would point at stale data. The constructor cost is
110
+ * trivial — small object literal, no allocations beyond the closure.
111
+ */
112
+ function createOpenCodePart(
113
+ parent: OpenCodeMessageLike,
114
+ index: number,
115
+ rawPart: unknown,
116
+ ): TranscriptPart {
117
+ const kind = classifyOpenCodePart(rawPart);
118
+ const id = extractPartId(rawPart);
119
+
120
+ return {
121
+ kind,
122
+ id,
123
+ getText(): string | undefined {
124
+ return readOpenCodePartText(rawPart);
125
+ },
126
+ setText(newText: string): boolean {
127
+ return writeOpenCodePartText(rawPart, newText);
128
+ },
129
+ setToolOutput(newText: string): boolean {
130
+ return writeOpenCodeToolOutput(rawPart, newText);
131
+ },
132
+ getToolMetadata(): { toolName: string | undefined; inputByteSize: number } {
133
+ return readOpenCodeToolMetadata(rawPart);
134
+ },
135
+ replaceWithSentinel(sentinelText: string): boolean {
136
+ // Build a synthetic text part that carries the sentinel as
137
+ // its content. Subsequent passes see this as a normal text
138
+ // part with kind="text" — but the existing tagging code is
139
+ // idempotent and won't double-tag a part that already has
140
+ // the right prefix, so re-processing is safe.
141
+ //
142
+ // We DON'T preserve the original part type. Sentinels are
143
+ // always text — that's the contract the existing
144
+ // apply-operations code expects.
145
+ const sentinelPart = { type: "text", text: sentinelText };
146
+ parent.parts[index] = sentinelPart;
147
+ return true;
148
+ },
149
+ };
150
+ }
151
+
152
+ /** Classify part kind based on `type` field. Falls back to "unknown". */
153
+ function classifyOpenCodePart(part: unknown): TranscriptPartKind {
154
+ if (!isRecord(part)) return "unknown";
155
+ const type = part.type;
156
+ if (typeof type !== "string") return "unknown";
157
+ switch (type) {
158
+ case "text":
159
+ return "text";
160
+ case "reasoning":
161
+ return "thinking";
162
+ case "tool":
163
+ return "tool_use";
164
+ case "file":
165
+ return "file";
166
+ case "image":
167
+ return "image";
168
+ case "step-start":
169
+ case "step-finish":
170
+ return "structural";
171
+ default:
172
+ return "unknown";
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Extract a stable per-part identifier when present. Used by the dropped-
178
+ * placeholder watermark to track which sentinels are already replayed
179
+ * across passes.
180
+ */
181
+ function extractPartId(part: unknown): string | undefined {
182
+ if (!isRecord(part)) return undefined;
183
+ if (typeof part.id === "string" && part.id.length > 0) return part.id;
184
+ if (typeof part.callID === "string" && part.callID.length > 0) return part.callID;
185
+ return undefined;
186
+ }
187
+
188
+ function readOpenCodePartText(part: unknown): string | undefined {
189
+ if (!isRecord(part)) return undefined;
190
+ if (typeof part.text === "string") return part.text;
191
+ if (typeof part.thinking === "string") return part.thinking;
192
+ if (part.type === "tool") {
193
+ const state = isRecord(part.state) ? part.state : null;
194
+ const output = state && typeof state.output === "string" ? state.output : "";
195
+ return output;
196
+ }
197
+ return undefined;
198
+ }
199
+
200
+ function writeOpenCodePartText(part: unknown, newText: string): boolean {
201
+ if (!isRecord(part)) return false;
202
+ const writable = part as Record<string, unknown>;
203
+ if (typeof writable.text === "string") {
204
+ if (writable.text === newText) return false;
205
+ writable.text = newText;
206
+ return true;
207
+ }
208
+ if (typeof writable.thinking === "string") {
209
+ if (writable.thinking === newText) return false;
210
+ writable.thinking = newText;
211
+ return true;
212
+ }
213
+ return false;
214
+ }
215
+
216
+ function writeOpenCodeToolOutput(part: unknown, newText: string): boolean {
217
+ if (!isRecord(part)) return false;
218
+ if (part.type !== "tool") return false;
219
+ const state = isRecord(part.state) ? (part.state as Record<string, unknown>) : null;
220
+ if (!state) return false;
221
+ if (typeof state.output !== "string") return false;
222
+ if (state.output === newText) return false;
223
+ state.output = newText;
224
+ return true;
225
+ }
226
+
227
+ function readOpenCodeToolMetadata(part: unknown): {
228
+ toolName: string | undefined;
229
+ inputByteSize: number;
230
+ } {
231
+ if (!isRecord(part)) return { toolName: undefined, inputByteSize: 0 };
232
+ if (part.type !== "tool") return { toolName: undefined, inputByteSize: 0 };
233
+
234
+ // OpenCode parts use `tool` as the tool name field; some legacy
235
+ // shapes use `toolName` or `name`. Match all three for forward
236
+ // compatibility with shape evolution.
237
+ const toolName =
238
+ typeof part.tool === "string"
239
+ ? part.tool
240
+ : typeof part.toolName === "string"
241
+ ? part.toolName
242
+ : typeof part.name === "string"
243
+ ? part.name
244
+ : undefined;
245
+
246
+ const state = isRecord(part.state) ? part.state : null;
247
+ const input = state?.input ?? part.args ?? part.input;
248
+
249
+ let inputByteSize = 0;
250
+ if (input !== undefined && input !== null) {
251
+ try {
252
+ inputByteSize = JSON.stringify(input).length;
253
+ } catch {
254
+ inputByteSize = 0;
255
+ }
256
+ }
257
+
258
+ return { toolName, inputByteSize };
259
+ }
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Harness-agnostic transcript interface.
3
+ *
4
+ * Magic Context's transform pipeline operates on messages in a specific
5
+ * shape: ordered messages with role-tagged parts (text, tool, reasoning,
6
+ * tool_result, image), where tagging, sentinel stripping, and queued-drop
7
+ * application MUTATE part content in-place. OpenCode's plugin transform
8
+ * receives a `{ info, parts: unknown[] }[]` array and the AI SDK reads
9
+ * those mutations directly. Pi's `pi.on("context", ...)` event delivers a
10
+ * `AgentMessage[]` and accepts a fully-replaced array as the result.
11
+ *
12
+ * Rather than building a bidirectional `MessageLike[] ↔ AgentMessage[]`
13
+ * adapter (Oracle's rejected Q1 alternative — too much round-trip
14
+ * complexity, double-conversion bugs), this module defines a small
15
+ * adapter contract that:
16
+ *
17
+ * 1. Exposes ordered messages with a *uniform* part-level mutation
18
+ * surface, regardless of underlying shape.
19
+ * 2. Is owned by the harness — OpenCode's adapter mutates `parts[]`
20
+ * directly (zero copies), Pi's adapter rebuilds an `AgentMessage[]`
21
+ * from the mutated transcript only at commit time.
22
+ * 3. Lets the shared transform code (tagging, stripping, drops)
23
+ * operate on `TranscriptPart` interface instances without caring
24
+ * whether they're wrapping `Part` from `@opencode-ai/sdk` or
25
+ * `TextContent | ToolCall | ThinkingContent` from `@mariozechner/pi-ai`.
26
+ *
27
+ * What this interface deliberately does NOT do:
28
+ *
29
+ * - **No data round-trip.** The transcript is a *view* over harness data;
30
+ * it doesn't define a third canonical message shape. There's no JSON
31
+ * serialization, no normalization to a common DTO. Round-trip-free
32
+ * adapters are 10x simpler and faster.
33
+ *
34
+ * - **No mutation semantics divergence.** Both adapters expose the same
35
+ * in-place mutation API (`setText`, `setOutput`, `replaceWithSentinel`).
36
+ * Whether mutation flushes to the source array immediately (OpenCode)
37
+ * or accumulates until `commit()` (Pi) is the adapter's concern.
38
+ *
39
+ * - **No session-storage abstraction.** Compartment storage, ordinals,
40
+ * raw-history reads — those live in feature modules, not here. The
41
+ * transcript only models the *current turn's* live message buffer.
42
+ *
43
+ * Step 4b.1 ships ONLY the interface and OpenCode adapter migration.
44
+ * Pi adapter implementation lands in 4b.2 alongside the Pi context-event
45
+ * wire-up, since the two are co-designed (the Pi adapter has to satisfy
46
+ * the same operations the tagging code calls). 4b.3 wires the Pi
47
+ * compartment trigger and historian invocation. 4b.4 nudges + auto-search.
48
+ */
49
+
50
+ /** Categorical kind of a transcript part, useful for filter predicates. */
51
+ export type TranscriptPartKind =
52
+ | "text"
53
+ | "thinking"
54
+ | "tool_use"
55
+ | "tool_result"
56
+ | "image"
57
+ | "file"
58
+ | "structural"
59
+ | "unknown";
60
+
61
+ /**
62
+ * A single content fragment within a transcript message.
63
+ *
64
+ * The interface is intentionally narrow: it exposes the operations Magic
65
+ * Context's transform code performs (read kind, read text, mutate text,
66
+ * mutate tool output, drop, replace with sentinel) and nothing more. Each
67
+ * harness adapter implements these against its native part type.
68
+ *
69
+ * IMPORTANT: implementations are stateful proxies over the live source
70
+ * data. Calling `setText("...")` on an OpenCode part mutates the
71
+ * underlying `Part.text`; calling it on a Pi part flips a dirty flag and
72
+ * the adapter's `commit()` rebuilds the affected `AgentMessage`. Either
73
+ * way, the transcript code reads back consistent values via `getText()`.
74
+ */
75
+ export interface TranscriptPart {
76
+ /** Discriminator for filter logic. Stable across mutations. */
77
+ readonly kind: TranscriptPartKind;
78
+
79
+ /**
80
+ * Best-effort identifier for cross-pass tracking. May be:
81
+ * - OpenCode part ID (e.g. "prt_..."), stable across passes.
82
+ * - Pi tool-call ID for tool_use/tool_result parts.
83
+ * - undefined for synthetic/structural parts.
84
+ *
85
+ * Pure parts without a stable ID return undefined and are tracked
86
+ * positionally within their containing message instead.
87
+ */
88
+ readonly id: string | undefined;
89
+
90
+ /**
91
+ * The user-/agent-visible text payload, if this part has one. Returns
92
+ * undefined for parts that have no text representation (image, file,
93
+ * structural-only). For thinking parts returns the thinking text. For
94
+ * tool_use returns the JSON-stringified arguments (so size accounting
95
+ * reflects what the model sees). For tool_result returns the
96
+ * concatenated text content of the result.
97
+ */
98
+ getText(): string | undefined;
99
+
100
+ /**
101
+ * Replace the visible text payload. Applies only to text and thinking
102
+ * parts; throws for kinds where mutation isn't meaningful (the caller
103
+ * should check `kind` first).
104
+ *
105
+ * Returns true if the underlying source data actually changed (so
106
+ * deduplication helpers can short-circuit). Returns false when the
107
+ * new text equals the existing text byte-for-byte.
108
+ */
109
+ setText(newText: string): boolean;
110
+
111
+ /**
112
+ * For tool_result parts: replace the text content of the result.
113
+ * For tool_use parts: replace JSON-serialized arguments.
114
+ * For everything else: throws — caller should check `kind` first.
115
+ */
116
+ setToolOutput(newText: string): boolean;
117
+
118
+ /**
119
+ * Tool-specific metadata exposed for tagging/drop accounting:
120
+ * - toolName: tool identifier (e.g. "bash", "ctx_search"). undefined
121
+ * for non-tool parts.
122
+ * - inputByteSize: serialized argument size; used by historian
123
+ * pressure projection to estimate post-drop savings.
124
+ *
125
+ * For non-tool parts both fields are undefined.
126
+ */
127
+ getToolMetadata(): { toolName: string | undefined; inputByteSize: number };
128
+
129
+ /**
130
+ * Replace this part with a sentinel placeholder. Sentinels look like
131
+ * `[dropped §N§]` or `[truncated §N§]` and survive cache-busting
132
+ * cycles by carrying their original tag number. Used by the
133
+ * apply-operations flow when a queued drop fires.
134
+ *
135
+ * Implementations replace the part *in place* in the parent message's
136
+ * part array. The replaced part's `kind` shifts to "structural" so
137
+ * subsequent transform passes don't double-process it.
138
+ *
139
+ * Returns true on success; returns false if the part can't be
140
+ * replaced (e.g. it's already a sentinel, or it's an image part).
141
+ */
142
+ replaceWithSentinel(sentinelText: string): boolean;
143
+ }
144
+
145
+ /**
146
+ * A single message in the transcript, exposing role + ordered parts.
147
+ *
148
+ * Lifetime: a TranscriptMessage is valid only within a single transform
149
+ * pass. Adapters do not guarantee identity across passes — callers must
150
+ * use `info.id` for cross-pass correlation, never the message reference.
151
+ */
152
+ export interface TranscriptMessage {
153
+ /**
154
+ * Lightweight metadata exposed for tagging, sentinel persistence, and
155
+ * cross-pass correlation. Adapters fill these from harness-native
156
+ * fields:
157
+ *
158
+ * - id: provider-stable message ID (OpenCode `msg_...`, Pi entryId).
159
+ * - role: "user" | "assistant" | "system" | "tool" | other custom roles.
160
+ * - sessionId: session identifier, used to scope DB writes.
161
+ *
162
+ * IMPORTANT for Pi: Pi's `ToolResultMessage` has role "toolResult"
163
+ * which the OpenCode-derived transform code expects to NOT be present
164
+ * (OpenCode folds tool results into the next user message's parts).
165
+ * The Pi adapter therefore exposes tool-result messages as parts of a
166
+ * synthetic "user" message in the transcript view, even though the
167
+ * underlying Pi storage has them as separate top-level entries. This
168
+ * is the *only* shape normalization the adapter performs.
169
+ */
170
+ readonly info: { id?: string; role: string; sessionId?: string };
171
+
172
+ /** Ordered parts. Same ordering invariants as the underlying source. */
173
+ readonly parts: TranscriptPart[];
174
+ }
175
+
176
+ /**
177
+ * Adapter contract: everything the transform pipeline calls on a
178
+ * harness-specific transcript implementation.
179
+ *
180
+ * Adapters are owned by the harness adapter layer (OpenCode's
181
+ * messages-transform.ts, Pi's context-event handler). The shared
182
+ * transform code receives a Transcript and operates only through this
183
+ * interface — it never imports from `@opencode-ai/sdk` or
184
+ * `@mariozechner/pi-ai`.
185
+ */
186
+ export interface Transcript {
187
+ /** Ordered messages in the current pass. */
188
+ readonly messages: TranscriptMessage[];
189
+
190
+ /**
191
+ * Adapter identification. Useful for:
192
+ * - Logging (`magic-context[opencode]` vs `magic-context[pi]`).
193
+ * - Per-harness behaviors gated at adapter level (e.g. opencode-only
194
+ * compaction marker injection).
195
+ * - Test assertions confirming the right adapter ran.
196
+ */
197
+ readonly harness: "opencode" | "pi";
198
+
199
+ /**
200
+ * Commit accumulated mutations to the underlying source array.
201
+ *
202
+ * For OpenCode: no-op — parts are mutated directly in `Part.text`/
203
+ * `Part.state.output` and OpenCode reads them back from the same
204
+ * array, so changes are already visible.
205
+ *
206
+ * For Pi: rebuilds a new `AgentMessage[]` from the dirty messages
207
+ * and stores it on the adapter so `pi.on("context", ...)` can return
208
+ * `{ messages }` to Pi. Idempotent: calling twice is safe.
209
+ *
210
+ * Always called exactly once per pass, after the transform pipeline
211
+ * finishes. Adapters that don't need it implement it as a no-op.
212
+ */
213
+ commit(): void;
214
+ }
215
+
216
+ /**
217
+ * Sentinel marker for transcript parts that should be ignored by all
218
+ * downstream transform stages (tagging, drops, indexing). Adapters set
219
+ * this on parts that exist only as structural artifacts (e.g. OpenCode's
220
+ * `step-start`/`step-finish`).
221
+ *
222
+ * Exported so harness adapters can stamp it on synthetic parts they
223
+ * create internally and so test fixtures can construct synthetic
224
+ * transcripts without needing real OpenCode/Pi structures.
225
+ */
226
+ export const STRUCTURAL_SENTINEL_KIND: TranscriptPartKind = "structural";
@@ -12,6 +12,29 @@ import { getOpenCodeConfigPaths } from "./opencode-config-dir";
12
12
  const PLUGIN_NAME = "@cortexkit/opencode-magic-context";
13
13
  const PLUGIN_ENTRY = `${PLUGIN_NAME}@latest`;
14
14
 
15
+ /**
16
+ * Detect whether a tui.json plugin entry already references magic-context, in
17
+ * any form. Covers:
18
+ * - Bare npm name: "@cortexkit/opencode-magic-context"
19
+ * - Versioned npm: "@cortexkit/opencode-magic-context@latest" / "@0.15.7" / etc.
20
+ * - Local dev directory path (absolute or relative): ".../magic-context"
21
+ * or ".../magic-context/packages/plugin"
22
+ * - file:// URLs pointing at the same paths
23
+ * - Tarball paths ending in opencode-magic-context-*.tgz
24
+ *
25
+ * Without the path/URL detection, doctor/setup auto-injection adds the npm
26
+ * @latest entry on top of an existing dev path, double-loading the plugin.
27
+ */
28
+ function isMagicContextEntry(entry: string): boolean {
29
+ if (!entry) return false;
30
+ if (entry === PLUGIN_NAME) return true;
31
+ if (entry.startsWith(`${PLUGIN_NAME}@`)) return true;
32
+ // Local directory paths: match anywhere in the string so the setup pattern
33
+ // (dir-only, dir + /packages/plugin, file:// + either) all qualify.
34
+ if (entry.includes("opencode-magic-context")) return true;
35
+ return false;
36
+ }
37
+
15
38
  function resolveTuiConfigPath(): string {
16
39
  const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
17
40
  const jsoncPath = join(configDir, "tui.jsonc");
@@ -40,20 +63,23 @@ export function ensureTuiPluginEntry(): boolean {
40
63
  ? config.plugin.filter((p): p is string => typeof p === "string")
41
64
  : [];
42
65
 
43
- const existingIdx = plugins.findIndex(
44
- (p) => p === PLUGIN_NAME || p.startsWith(`${PLUGIN_NAME}@`),
45
- );
66
+ const existingIdx = plugins.findIndex(isMagicContextEntry);
46
67
  if (existingIdx >= 0) {
47
- if (plugins[existingIdx] === PLUGIN_ENTRY) {
68
+ const existing = plugins[existingIdx];
69
+ if (existing === PLUGIN_ENTRY) {
48
70
  return false; // Already @latest
49
71
  }
50
- // Only upgrade versionless entries (bare package name) to @latest.
51
- // Pinned versions (e.g. @0.8.10) are left as-is — user chose them intentionally.
52
- const existing = plugins[existingIdx];
72
+ // Only upgrade the bare versionless npm name to @latest.
73
+ // Pinned versions (e.g. @0.8.10), local dev paths
74
+ // (~/Work/OSS/magic-context/packages/plugin), and
75
+ // file:// URLs are all left as-is — the user chose them
76
+ // intentionally and overwriting their dev-loop entry would
77
+ // either double-load the plugin (npm + dev) or replace
78
+ // their working directory pointer.
53
79
  if (existing === PLUGIN_NAME) {
54
80
  plugins[existingIdx] = PLUGIN_ENTRY;
55
81
  } else {
56
- return false; // Pinned version — don't touch
82
+ return false;
57
83
  }
58
84
  } else {
59
85
  plugins.push(PLUGIN_ENTRY);
@@ -12,8 +12,12 @@ export type { SidebarSnapshot, StatusDetail };
12
12
  let rpcClient: MagicContextRpcClient | null = null;
13
13
 
14
14
  function getStorageDir(): string {
15
+ // Plugin v0.16+ uses the shared cortexkit/magic-context path so OpenCode
16
+ // and Pi can share state. The TUI just needs to point its RPC client at
17
+ // the same storage directory the server plugin uses for the lock-file
18
+ // discovery convention.
15
19
  const dataDir = process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
16
- return path.join(dataDir, "opencode", "storage", "plugin", "magic-context");
20
+ return path.join(dataDir, "cortexkit", "magic-context");
17
21
  }
18
22
 
19
23
  /** Initialize the RPC client. Call once on TUI startup. */
@@ -1,11 +0,0 @@
1
- export interface ConfigPaths {
2
- configDir: string;
3
- opencodeConfig: string;
4
- opencodeConfigFormat: "json" | "jsonc" | "none";
5
- magicContextConfig: string;
6
- omoConfig: string | null;
7
- tuiConfig: string;
8
- tuiConfigFormat: "json" | "jsonc" | "none";
9
- }
10
- export declare function detectConfigPaths(): ConfigPaths;
11
- //# sourceMappingURL=config-paths.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-paths.d.ts","sourceRoot":"","sources":["../../src/cli/config-paths.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;CAC9C;AA+BD,wBAAgB,iBAAiB,IAAI,WAAW,CA6C/C"}
@@ -1,82 +0,0 @@
1
- import { type ConfigPaths } from "./config-paths";
2
- export interface DiagnosticReport {
3
- timestamp: string;
4
- platform: string;
5
- arch: string;
6
- nodeVersion: string;
7
- pluginVersion: string;
8
- opencodeInstalled: boolean;
9
- opencodeVersion: string | null;
10
- configPaths: ConfigPaths;
11
- opencodeConfigHasPlugin: boolean;
12
- tuiConfigHasPlugin: boolean;
13
- magicContextConfig: {
14
- exists: boolean;
15
- parseError?: string;
16
- flags: Record<string, unknown>;
17
- };
18
- pluginCache: {
19
- path: string;
20
- cached?: string;
21
- latest?: string;
22
- };
23
- storageDir: {
24
- path: string;
25
- exists: boolean;
26
- contextDbSizeBytes: number;
27
- };
28
- conflicts: {
29
- hasConflict: boolean;
30
- reasons: string[];
31
- };
32
- logFile: {
33
- path: string;
34
- exists: boolean;
35
- sizeKb: number;
36
- };
37
- historianDumps: {
38
- dir: string;
39
- count: number;
40
- recent: HistorianDumpSummary[];
41
- };
42
- /** Most recent historian-failure rows from session_meta across all sessions. */
43
- historianFailures: HistorianFailureSummary[];
44
- }
45
- export interface HistorianDumpSummary {
46
- name: string;
47
- ageMinutes: number;
48
- sizeKb: number;
49
- /** Parsed metadata — only structural fields, never raw XML content. */
50
- meta?: HistorianDumpMeta;
51
- /** If the XML could not be parsed, reason for failure. */
52
- parseError?: string;
53
- }
54
- export interface HistorianDumpMeta {
55
- /** Number of <compartment> elements found. */
56
- compartmentCount: number;
57
- /** Smallest start ordinal across compartments, or null if none. */
58
- minStart: number | null;
59
- /** Largest end ordinal across compartments, or null if none. */
60
- maxEnd: number | null;
61
- /** Value of <unprocessed_from> tag, if present. */
62
- unprocessedFrom: number | null;
63
- /** Number of <fact> items grouped by category. */
64
- factCountByCategory: Record<string, number>;
65
- /** Number of <user_observations> items. */
66
- userObservationCount: number;
67
- /** Total number of compartment ordinal gaps (missing ranges between consecutive compartments). */
68
- ordinalGapCount: number;
69
- /** Total number of overlapping compartment ranges. */
70
- ordinalOverlapCount: number;
71
- }
72
- export interface HistorianFailureSummary {
73
- sessionId: string;
74
- failureCount: number;
75
- /** Sanitized truncated last-error text. May be empty if never set. */
76
- lastError: string;
77
- /** ISO timestamp of last failure, or empty if never failed. */
78
- lastFailureAt: string;
79
- }
80
- export declare function collectDiagnostics(): Promise<DiagnosticReport>;
81
- export declare function renderDiagnosticsMarkdown(report: DiagnosticReport): string;
82
- //# sourceMappingURL=diagnostics.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/cli/diagnostics.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,gBAAgB,CAAC;AAMrE,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,uBAAuB,EAAE,OAAO,CAAC;IACjC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,CAAC;IACF,WAAW,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,UAAU,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,kBAAkB,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,SAAS,EAAE;QACP,WAAW,EAAE,OAAO,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,cAAc,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,oBAAoB,EAAE,CAAC;KAClC,CAAC;IACF,gFAAgF;IAChF,iBAAiB,EAAE,uBAAuB,EAAE,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAC9B,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,mDAAmD;IACnD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kDAAkD;IAClD,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,2CAA2C;IAC3C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kGAAkG;IAClG,eAAe,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,mBAAmB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;CACzB;AAwRD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAgDpE;AASD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CA8E1E"}
@@ -1,5 +0,0 @@
1
- export declare function runDoctor(options?: {
2
- force?: boolean;
3
- issue?: boolean;
4
- }): Promise<number>;
5
- //# sourceMappingURL=doctor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AA4WA,wBAAsB,SAAS,CAC3B,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GACnD,OAAO,CAAC,MAAM,CAAC,CAyejB"}
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=index.d.ts.map