minecodex 0.1.8 → 0.1.9

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "images",
4
- "version": "0.1.8",
4
+ "version": "0.1.9",
5
5
  "label": {
6
6
  "en": "Images",
7
7
  "zh-CN": "图片"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "model-slider",
4
- "version": "0.1.8",
4
+ "version": "0.1.9",
5
5
  "label": {
6
6
  "en": "Model Slider",
7
7
  "zh-CN": "模型滑条"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "notes",
4
- "version": "0.1.8",
4
+ "version": "0.1.9",
5
5
  "label": {
6
6
  "en": "Notes",
7
7
  "zh-CN": "笔记"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecodex",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Lightweight, local-first plugins for the Codex desktop app.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -11,6 +11,7 @@ const CODEX_APP_ORIGIN = "app://-";
11
11
  const SURFACE_LOAD_ACTION = "load-surface";
12
12
  const SURFACE_FRAME_PREFIX = "minecodex-surface-";
13
13
  const LOOPBACK_SURFACE_HOSTS = new Set(["127.0.0.1", "localhost", "::1", "[::1]"]);
14
+ const RIGHT_PANEL_ROUTE_KINDS = Object.freeze(["home", "local-thread"]);
14
15
 
15
16
  export const RESPONSIVE_SUMMARY_LAYOUT = Object.freeze({
16
17
  contentBaseWidth: 736,
@@ -112,6 +113,7 @@ export function createInjectionSource(features, {
112
113
  currentRuntime?.dispose?.();
113
114
 
114
115
  const lifetime = new AbortController();
116
+ const rightPanelRouteKinds = new Set(config.rightPanelRouteKinds);
115
117
 
116
118
  const entryMarker = "data-codex-personal-feature";
117
119
  const pageSurfaceMarker = "data-codex-personal-surface";
@@ -2701,7 +2703,7 @@ export function createInjectionSource(features, {
2701
2703
  return key ? element[key] : null;
2702
2704
  }
2703
2705
 
2704
- function currentTaskScope() {
2706
+ function currentRightPanelScope() {
2705
2707
  let anchor = document.querySelector('[data-app-shell-tabs="true"]');
2706
2708
  let anchorFiber = reactFiberFor(anchor);
2707
2709
  if (!anchorFiber) {
@@ -2718,12 +2720,12 @@ export function createInjectionSource(features, {
2718
2720
  let rootFiber = anchorFiber;
2719
2721
  while (rootFiber.return) rootFiber = rootFiber.return;
2720
2722
 
2721
- const isTaskScope = (value) => (
2723
+ const isRightPanelScope = (value) => (
2722
2724
  value
2723
2725
  && typeof value === "object"
2724
2726
  && typeof value.get === "function"
2725
2727
  && typeof value.set === "function"
2726
- && value.value?.routeKind === "local-thread"
2728
+ && rightPanelRouteKinds.has(value.value?.routeKind)
2727
2729
  && typeof value.query?.getOrFetch === "function"
2728
2730
  );
2729
2731
  const inspected = new Set();
@@ -2734,8 +2736,8 @@ export function createInjectionSource(features, {
2734
2736
  || inspected.has(value)
2735
2737
  ) return null;
2736
2738
  inspected.add(value);
2737
- if (isTaskScope(value)) return value;
2738
- if (isTaskScope(value.current)) return value.current;
2739
+ if (isRightPanelScope(value)) return value;
2740
+ if (isRightPanelScope(value.current)) return value.current;
2739
2741
  return null;
2740
2742
  };
2741
2743
 
@@ -2769,10 +2771,10 @@ export function createInjectionSource(features, {
2769
2771
  return null;
2770
2772
  }
2771
2773
 
2772
- async function waitForCurrentTaskScope() {
2774
+ async function waitForCurrentRightPanelScope() {
2773
2775
  const deadline = performance.now() + 2_000;
2774
2776
  do {
2775
- const scope = currentTaskScope();
2777
+ const scope = currentRightPanelScope();
2776
2778
  if (scope) return scope;
2777
2779
  await new Promise((resolve) => setTimeout(resolve, 50));
2778
2780
  } while (performance.now() < deadline);
@@ -2810,6 +2812,7 @@ export function createInjectionSource(features, {
2810
2812
  typeof controller?.openTab !== "function"
2811
2813
  || typeof controller?.activateTab !== "function"
2812
2814
  || typeof controller?.closeTab !== "function"
2815
+ || !controller?.tabById$
2813
2816
  || typeof jsx?.jsx !== "function"
2814
2817
  || typeof React?.useLayoutEffect !== "function"
2815
2818
  || typeof React?.useRef !== "function"
@@ -2923,17 +2926,31 @@ export function createInjectionSource(features, {
2923
2926
  return reloaded;
2924
2927
  }
2925
2928
 
2929
+ async function waitForNativeDetailTabMount(scope, controller, tabId, detailKey) {
2930
+ const deadline = performance.now() + 2_000;
2931
+ do {
2932
+ let registered = false;
2933
+ try {
2934
+ registered = scope.get(controller.tabById$, tabId) != null;
2935
+ } catch {}
2936
+ if (registered && nativeDetailSurfaceKeys.has(detailKey)) return true;
2937
+ await new Promise((resolve) => setTimeout(resolve, 25));
2938
+ } while (performance.now() < deadline);
2939
+ return false;
2940
+ }
2941
+
2926
2942
  async function openNativeDetailTab(feature, detail) {
2927
2943
  const capability = await loadNativeTabCapability();
2928
2944
  if (!capability) return null;
2929
- const scope = await waitForCurrentTaskScope();
2945
+ const scope = await waitForCurrentRightPanelScope();
2930
2946
  if (!scope) {
2931
- nativeTabCapabilityError = new Error("The current Codex Task scope was not found");
2947
+ nativeTabCapabilityError = new Error("The current Codex right-panel scope was not found");
2932
2948
  return null;
2933
2949
  }
2934
2950
 
2935
2951
  const { controller, jsx } = capability;
2936
2952
  const tabId = `${feature.id}-${detail.id}`;
2953
+ const detailKey = `${feature.id}:${detail.id}`;
2937
2954
  let session = Array.from(nativeOpenTabSessions).find((candidate) => (
2938
2955
  candidate.scope === scope && candidate.tabId === tabId
2939
2956
  ));
@@ -2966,6 +2983,17 @@ export function createInjectionSource(features, {
2966
2983
  return null;
2967
2984
  }
2968
2985
 
2986
+ if (!await waitForNativeDetailTabMount(scope, controller, tabId, detailKey)) {
2987
+ if (isNewSession) nativeOpenTabSessions.delete(session);
2988
+ if (!focusedExisting) {
2989
+ try {
2990
+ controller.closeTab(scope, tabId);
2991
+ } catch {}
2992
+ }
2993
+ nativeTabCapabilityError = new Error("Codex native right-panel Tab did not mount");
2994
+ return null;
2995
+ }
2996
+
2969
2997
  nativeTabCapabilityError = null;
2970
2998
  if (focusedExisting) reloadNativeDetailIfUnready(feature, detail);
2971
2999
  return { tabId, focusedExisting, presentation: "native" };
@@ -3466,6 +3494,7 @@ export function createInjectionSource(features, {
3466
3494
  bindingName,
3467
3495
  bindingToken,
3468
3496
  summaryLayout: RESPONSIVE_SUMMARY_LAYOUT,
3497
+ rightPanelRouteKinds: RIGHT_PANEL_ROUTE_KINDS,
3469
3498
  features: runtimeFeatures,
3470
3499
  })})`;
3471
3500
  }