pi-supernova 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@
6
6
 
7
7
  - Native adapters are now included in `nova.search` / `nova.describe` with schemas matching the callable adapter, even when the host catalog omits parameters or the adapter name.
8
8
 
9
+ ## [0.0.4] - 2026-09-03
10
+
11
+ ### Fixed
12
+
13
+ - OMP no longer hangs on "Loading plugins…" — removed top-level import of `@oh-my-pi/pi-coding-agent/tui` from the extension (portable framed chrome only).
14
+
9
15
  ## [0.0.3] - 2026-09-03
10
16
 
11
17
  ### Changed
package/index.js CHANGED
@@ -1,16 +1,4 @@
1
-
2
- let Type;
3
- try {
4
- Type = (await import("typebox")).Type;
5
- } catch {
6
- Type = {
7
- Object: (props, opts) => ({ type: "object", properties: props || {}, additionalProperties: false, ...opts }),
8
- String: (opts) => ({ type: "string", ...opts }),
9
- Integer: (opts) => ({ type: "integer", ...opts }),
10
- Optional: (s) => ({ ...s }),
11
- };
12
- }
13
-
1
+ import { createRequire } from "node:module";
14
2
  import { isString, isFunction } from "./decode.js";
15
3
  import { buildCatalog, searchCatalog, describeTool, mergeNativeToolDefinitions } from "./catalog.js";
16
4
  import { loadConfig } from "./config.js";
@@ -25,6 +13,20 @@ import {
25
13
 
26
14
  export { extractOperationsFromCode, renderSupernovaCall, renderSupernovaResult, SafeText };
27
15
 
16
+ // Sync only — never top-level await. Dynamic import of host/deps hung OMP plugin load.
17
+ const require = createRequire(import.meta.url);
18
+ let Type;
19
+ try {
20
+ Type = require("typebox").Type;
21
+ } catch {
22
+ Type = {
23
+ Object: (props, opts) => ({ type: "object", properties: props || {}, additionalProperties: false, ...opts }),
24
+ String: (opts) => ({ type: "string", ...opts }),
25
+ Integer: (opts) => ({ type: "integer", ...opts }),
26
+ Optional: (s) => ({ ...s }),
27
+ };
28
+ }
29
+
28
30
  function result(text, details) {
29
31
  return { content: [{ type: "text", text }], details };
30
32
  }
package/omp-frame.js CHANGED
@@ -1,10 +1,8 @@
1
1
  /**
2
- * OMP-native tool chrome for supernova.
2
+ * OMP-style rounded tool chrome for supernova.
3
3
  *
4
- * Prefer host `framedBlock` + `renderStatusLine` from
5
- * `@oh-my-pi/pi-coding-agent/tui` (same path read/write/edit use). Fall back to a
6
- * portable rounded frame that matches that look when the import is unavailable
7
- * (Pi path-install / unit tests).
4
+ * Intentionally self-contained never dynamic-imports `@oh-my-pi/pi-coding-agent`
5
+ * (that hung OMP plugin load). Geometry matches native write/edit framedBlock.
8
6
  */
9
7
 
10
8
  import { clampLine, measureWidth, wrapPlainToWidth } from "./render-measure.js";
@@ -20,32 +18,12 @@ const DEFAULT_BOX = {
20
18
  teeRight: "├",
21
19
  };
22
20
 
23
- let hostFramedBlock = null;
24
- let hostRenderStatusLine = null;
25
- let hostMarkFramed = null;
26
- let hostResolved = false;
27
-
28
- export async function ensureOmpChrome() {
29
- if (hostResolved) return;
30
- hostResolved = true;
31
- for (const spec of ["@oh-my-pi/pi-coding-agent/tui", "@oh-my-pi/pi-coding-agent/tui/index.js"]) {
32
- try {
33
- const tui = await import(spec);
34
- if (typeof tui.framedBlock === "function") hostFramedBlock = tui.framedBlock;
35
- if (typeof tui.renderStatusLine === "function") hostRenderStatusLine = tui.renderStatusLine;
36
- if (typeof tui.markFramedBlockComponent === "function") hostMarkFramed = tui.markFramedBlockComponent;
37
- if (hostFramedBlock && hostRenderStatusLine) return;
38
- } catch {
39
- // Pi / tests / plain node — use portable frame.
40
- }
41
- }
21
+ export function hasHostFramedBlock() {
22
+ return false;
42
23
  }
43
24
 
44
- /** Kick off resolution at module load (extension hosts support top-level await). */
45
- await ensureOmpChrome();
46
-
47
- export function hasHostFramedBlock() {
48
- return typeof hostFramedBlock === "function" && typeof hostRenderStatusLine === "function";
25
+ export async function ensureOmpChrome() {
26
+ // No-op: portable frame only. Kept so call sites stay stable.
49
27
  }
50
28
 
51
29
  function boxOf(theme) {
@@ -69,8 +47,6 @@ function borderPaint(theme, state, borderColor) {
69
47
  }
70
48
 
71
49
  function statusHeader(theme, { title, description, state, spinnerFrame, icon, iconOverride }) {
72
- // Match native Write/Edit: framed call heads omit the pending hourglass; only
73
- // pass an icon when the caller sets one (error / running / success glyph).
74
50
  const resolvedIcon =
75
51
  iconOverride !== undefined
76
52
  ? undefined
@@ -79,21 +55,12 @@ function statusHeader(theme, { title, description, state, spinnerFrame, icon, ic
79
55
  : state === "error"
80
56
  ? "error"
81
57
  : undefined;
82
- if (hostRenderStatusLine) {
83
- return hostRenderStatusLine(
84
- {
85
- icon: resolvedIcon,
86
- iconOverride,
87
- spinnerFrame,
88
- title,
89
- description,
90
- },
91
- theme,
92
- );
93
- }
94
58
  const titleText = theme?.fg ? theme.fg("accent", title) : title;
95
59
  const descText = description ? (theme?.fg ? theme.fg("muted", description) : description) : "";
96
- const prefix = state === "error" ? (theme?.fg ? theme.fg("error", "✗ ") : "✗ ") : "";
60
+ let prefix = "";
61
+ if (iconOverride) prefix = `${iconOverride} `;
62
+ else if (resolvedIcon === "error") prefix = theme?.fg ? theme.fg("error", "✗ ") : "✗ ";
63
+ else if (resolvedIcon === "running" || spinnerFrame) prefix = theme?.fg ? theme.fg("dim", "… ") : "… ";
97
64
  return descText ? `${prefix}${titleText}: ${descText}` : `${prefix}${titleText}`;
98
65
  }
99
66
 
@@ -135,9 +102,6 @@ function bgFnForState(theme, state) {
135
102
  return undefined;
136
103
  }
137
104
 
138
- /**
139
- * Portable rounded frame matching OMP output-block geometry.
140
- */
141
105
  export function renderPortableFrame(theme, { header, sections = [], state = "pending", borderColor, width }) {
142
106
  const w = Math.max(8, width | 0);
143
107
  const box = boxOf(theme);
@@ -161,7 +125,7 @@ export function renderPortableFrame(theme, { header, sections = [], state = "pen
161
125
  return padLine(`${border(left)}${trimmed}${border(h.repeat(fill))}${border(right)}`, w, bgFn);
162
126
  };
163
127
 
164
- const contentWidth = Math.max(1, w - 2 - 2); // borders + 1-col pad each side
128
+ const contentWidth = Math.max(1, w - 2 - 2);
165
129
  const lines = [];
166
130
  lines.push(paintBar(box.topLeft, box.topRight, header));
167
131
 
@@ -188,7 +152,7 @@ export function createPortableFramedComponent(theme, build) {
188
152
  let cacheWidth;
189
153
  let cacheKey;
190
154
  let cacheLines;
191
- const comp = {
155
+ return {
192
156
  render(width) {
193
157
  const opts = build(width);
194
158
  const key = `${opts.state}|${opts.borderColor}|${opts.header}|${(opts.sections || [])
@@ -206,17 +170,9 @@ export function createPortableFramedComponent(theme, build) {
206
170
  cacheWidth = undefined;
207
171
  },
208
172
  };
209
- if (hostMarkFramed) return hostMarkFramed(comp);
210
- return comp;
211
173
  }
212
174
 
213
- /**
214
- * Build a framed nova card. Uses host framedBlock when available (OMP).
215
- */
216
175
  export function novaFramedBlock(theme, build) {
217
- if (hostFramedBlock) {
218
- return hostFramedBlock(theme, build);
219
- }
220
176
  return createPortableFramedComponent(theme, build);
221
177
  }
222
178
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-supernova",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Dual-host CodeMode for Pi/OMP: progressive tool discovery, result bottleneck, and Amdahl Auto parallel.",
5
5
  "type": "module",
6
6
  "author": "AdityaVG13",
package/render.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  wrapPlainToWidth,
20
20
  fitPath,
21
21
  } from "./render-measure.js";
22
- import { ensureOmpChrome, hasHostFramedBlock, novaFramedBlock, novaStatusLine } from "./omp-frame.js";
22
+ import { novaFramedBlock, novaStatusLine } from "./omp-frame.js";
23
23
 
24
24
  export { measureWidth, hardTruncate, clampLine, wrapPlainToWidth, fitPath };
25
25
 
@@ -348,7 +348,6 @@ function detectResultHost(options, ctxOrArgs) {
348
348
  ) {
349
349
  return "omp";
350
350
  }
351
- if (hasHostFramedBlock()) return "omp";
352
351
  return "pi";
353
352
  }
354
353
 
@@ -445,7 +444,7 @@ function formatOpBodyLine(theme, op) {
445
444
  }
446
445
 
447
446
  function shouldUseOmpFrame(host) {
448
- return host === "omp" || hasHostFramedBlock();
447
+ return host === "omp";
449
448
  }
450
449
 
451
450
  /**
@@ -529,7 +528,6 @@ export function renderSupernovaCall(a, b, c) {
529
528
  const timeStr = formatElapsed(context?.state);
530
529
 
531
530
  if (shouldUseOmpFrame(host)) {
532
- void ensureOmpChrome();
533
531
  return renderOmpCallCard(theme, {
534
532
  ops,
535
533
  timeStr,
@@ -642,7 +640,6 @@ export function renderSupernovaResult(resultArg, optionsArg, themeArg, contextAr
642
640
  const useOmp = shouldUseOmpFrame(host);
643
641
 
644
642
  if (useOmp) {
645
- void ensureOmpChrome();
646
643
  if (isPartial && !isErr) {
647
644
  // Streaming partials stay quiet until body content exists — same as Pi.
648
645
  const partialBody = buildResultBody(theme, { payload, context, expanded });