codex-plus-patcher 0.4.1 → 0.6.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.
@@ -9,6 +9,27 @@
9
9
  const styleElements = new Map();
10
10
  const settingsListeners = new Map();
11
11
  const storagePrefix = "codex-plus:plugin:";
12
+ const diagnosticEvents = [];
13
+
14
+ function diagnosticsEnabled() {
15
+ try {
16
+ return globalObject.localStorage?.getItem("codex-plus:diagnostics") === "1";
17
+ } catch {
18
+ return false;
19
+ }
20
+ }
21
+
22
+ function diagnose(event, details = {}) {
23
+ const entry = { event, details, time: new Date().toISOString() };
24
+ diagnosticEvents.push(entry);
25
+ if (diagnosticEvents.length > 200) diagnosticEvents.shift();
26
+ if (diagnosticsEnabled()) {
27
+ try {
28
+ console.info("[Codex Plus]", event, details);
29
+ } catch {}
30
+ }
31
+ return entry;
32
+ }
12
33
 
13
34
  function safeId(id) {
14
35
  if (typeof id !== "string" || id.trim() === "") throw new Error("Codex Plus plugin ids must be non-empty strings");
@@ -258,6 +279,34 @@
258
279
  return null;
259
280
  }
260
281
 
282
+ function ThreadHeaderAccessoryHost({ accessory, context, deps }) {
283
+ const rendered = accessory?.({ context, ...deps }) ?? null;
284
+ diagnose("threadHeader.accessoryHost.render", {
285
+ accessoryName: accessory?.name || null,
286
+ cwd: typeof context?.cwd === "string" ? context.cwd : null,
287
+ rendered: rendered != null,
288
+ });
289
+ return rendered;
290
+ }
291
+
292
+ function renderThreadHeaderAccessories({ context, deps } = {}) {
293
+ const jsx = deps?.jsx;
294
+ if (typeof jsx !== "function") {
295
+ diagnose("threadHeader.render.skip", { reason: "missing-jsx" });
296
+ return null;
297
+ }
298
+ diagnose("threadHeader.render", {
299
+ accessoryCount: CodexPlus.ui.threadHeader.accessories.length,
300
+ cwd: typeof context?.cwd === "string" ? context.cwd : null,
301
+ hostId: context?.hostId ?? null,
302
+ header: context?.header ?? null,
303
+ });
304
+ const rendered = CodexPlus.ui.threadHeader.accessories.map((accessory, index) =>
305
+ jsx(ThreadHeaderAccessoryHost, { accessory, context, deps }, `thread-header-accessory:${index}`),
306
+ );
307
+ return rendered.length === 0 ? null : rendered;
308
+ }
309
+
261
310
  function registerStyle(pluginId, cssText) {
262
311
  if (typeof document === "undefined") return null;
263
312
  const id = `codex-plus-style-${safeId(pluginId)}`;
@@ -288,6 +337,7 @@
288
337
  for (const command of plugin.commands || []) registerCommand({ ...command, plugin: plugin.id });
289
338
  if (plugin.styles) registerStyle(plugin.id, plugin.styles);
290
339
  if (plugin.required || plugin.enabledByDefault) startPlugin(plugin.id);
340
+ diagnose("plugin.register", { id: plugin.id, started: startedPlugins.has(plugin.id) });
291
341
  return plugin;
292
342
  }
293
343
 
@@ -296,6 +346,7 @@
296
346
  if (!plugin || startedPlugins.has(id)) return;
297
347
  plugin.start?.(CodexPlus);
298
348
  startedPlugins.add(id);
349
+ diagnose("plugin.start", { id });
299
350
  }
300
351
 
301
352
  function stopPlugin(id) {
@@ -305,6 +356,10 @@
305
356
  startedPlugins.delete(id);
306
357
  }
307
358
 
359
+ function registerNativeMenuItem(item) {
360
+ return CodexPlus.native.request("native-menu/register-item", item).catch(() => ({ ok: false }));
361
+ }
362
+
308
363
  const CodexPlus = {
309
364
  definePlugin,
310
365
  registerPlugin,
@@ -330,14 +385,36 @@
330
385
  composer: { surfaceDecorators: [], decorateSurface(fn) { this.surfaceDecorators.push(fn); return fn; }, surfaceProps(props) { return applyDecorators(props, this.surfaceDecorators); } },
331
386
  about: { buildInfo: [], addBuildInfo(fn) { this.buildInfo.push(fn); return fn; } },
332
387
  errors: { boundaryDecorators: [], decorateBoundary(fn) { this.boundaryDecorators.push(fn); return fn; }, renderDetails: renderErrorDetails },
388
+ threadHeader: {
389
+ accessories: [],
390
+ addAccessory(fn) {
391
+ this.accessories.push(fn);
392
+ diagnose("threadHeader.addAccessory", { accessoryName: fn?.name || null, accessoryCount: this.accessories.length });
393
+ return fn;
394
+ },
395
+ renderAccessories: renderThreadHeaderAccessories,
396
+ },
397
+ mermaid: {
398
+ diagramDecorators: [],
399
+ decorateDiagram(fn) { this.diagramDecorators.push(fn); return fn; },
400
+ diagramProps(props) { return applyDecorators(props, this.diagramDecorators); },
401
+ },
333
402
  },
334
403
  commands: { register: registerCommand, run: runCommand, all: () => Array.from(commands.values()), menuItems: (group) => Array.from(commands.values()).filter((command) => commandGroups(command).includes(group)) },
404
+ nativeMenus: { registerItem: registerNativeMenuItem },
335
405
  settings: { define: defineSettings },
336
- native: { async request(method, params) { return globalObject.CodexPlusHost?.nativeRequest?.(method, params); } },
406
+ native: { async request(method, params) { return globalObject.codexPlusNative?.request?.(method, params) ?? globalObject.CodexPlusHost?.nativeRequest?.(method, params); } },
337
407
  styles: { register: registerStyle, setRootVars },
408
+ diagnostics: {
409
+ log: diagnose,
410
+ snapshot() { return diagnosticEvents.slice(); },
411
+ clear() { diagnosticEvents.splice(0, diagnosticEvents.length); },
412
+ enabled: diagnosticsEnabled,
413
+ },
338
414
  };
339
415
 
340
416
  globalObject.CodexPlus = CodexPlus;
417
+ globalObject.CodexPlusDiagnostics = CodexPlus.diagnostics;
341
418
  globalObject.CodexPlusHost ||= {};
342
419
  globalObject.CodexPlusHost.register = registerHostModule;
343
420
 
@@ -347,17 +424,31 @@
347
424
  "plugins/diagnosticErrors.js",
348
425
  "plugins/userBubbleColors.js",
349
426
  "plugins/projectColors.js",
427
+ "plugins/projectPathHeader.js",
350
428
  "plugins/sidebarNameBlur.js",
429
+ "plugins/devTools.js",
430
+ "vendor/fzf.umd.js",
431
+ "plugins/projectSelectorShortcut.js",
432
+ "plugins/mermaidFullscreen.js",
351
433
  ];
352
434
 
353
435
  if (typeof document !== "undefined") {
354
436
  const base = new URL(".", document.currentScript?.src || globalObject.location?.href || "");
355
- for (const file of pluginFiles) {
356
- const script = document.createElement("script");
357
- script.src = new URL(file, base).href;
358
- script.async = false;
359
- script.defer = false;
360
- document.head?.appendChild(script);
437
+ if (document.readyState === "loading" && typeof document.write === "function") {
438
+ diagnose("plugins.load", { mode: "document.write", count: pluginFiles.length });
439
+ for (const file of pluginFiles) {
440
+ const src = new URL(file, base).href.replace(/"/g, """);
441
+ document.write(`<script src="${src}"><\/script>`);
442
+ }
443
+ } else {
444
+ diagnose("plugins.load", { mode: "appendChild", count: pluginFiles.length });
445
+ for (const file of pluginFiles) {
446
+ const script = document.createElement("script");
447
+ script.src = new URL(file, base).href;
448
+ script.async = false;
449
+ script.defer = false;
450
+ document.head?.appendChild(script);
451
+ }
361
452
  }
362
453
  }
363
454
  })();