minecodex 0.1.7 → 0.1.8

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.7",
4
+ "version": "0.1.8",
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.7",
4
+ "version": "0.1.8",
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.7",
4
+ "version": "0.1.8",
5
5
  "label": {
6
6
  "en": "Notes",
7
7
  "zh-CN": "笔记"
@@ -835,7 +835,7 @@ body[data-surface="editor"] #app {
835
835
  .modal-editor-fields input:focus-visible,
836
836
  .modal-editor-fields textarea:focus-visible {
837
837
  outline: none;
838
- box-shadow: inset 0 0 0 2px var(--notes-focus);
838
+ box-shadow: none;
839
839
  }
840
840
 
841
841
  .modal-command:focus-visible {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecodex",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Lightweight, local-first plugins for the Codex desktop app.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -248,15 +248,12 @@ export function createInjectionSource(features, {
248
248
  const pageSurfaces = new Map();
249
249
  const pinnedSurfaces = new Map();
250
250
  const surfaceRecords = new Map();
251
- const openTabs = new Map();
252
251
  const nativeDetailComponents = new Map();
253
252
  const nativeDetailSurfaceKeys = new Map();
254
253
  const nativeOpenTabSessions = new Set();
255
254
  const summaryStates = new Map();
256
255
  let activePageFeatureId = null;
257
256
  let activePinnedFeatureId = null;
258
- let activeTabKey = null;
259
- let tabHost = null;
260
257
  let ensureQueued = false;
261
258
  let ensureFrame = null;
262
259
  let ensureTimer = null;
@@ -2772,12 +2769,32 @@ export function createInjectionSource(features, {
2772
2769
  return null;
2773
2770
  }
2774
2771
 
2772
+ async function waitForCurrentTaskScope() {
2773
+ const deadline = performance.now() + 2_000;
2774
+ do {
2775
+ const scope = currentTaskScope();
2776
+ if (scope) return scope;
2777
+ await new Promise((resolve) => setTimeout(resolve, 50));
2778
+ } while (performance.now() < deadline);
2779
+ return null;
2780
+ }
2781
+
2782
+ async function waitForNativeTabModuleUrl() {
2783
+ const deadline = performance.now() + 2_000;
2784
+ do {
2785
+ const moduleUrl = nativeTabModuleUrl();
2786
+ if (moduleUrl) return moduleUrl;
2787
+ await new Promise((resolve) => setTimeout(resolve, 50));
2788
+ } while (performance.now() < deadline);
2789
+ return null;
2790
+ }
2791
+
2775
2792
  async function loadNativeTabCapability() {
2776
2793
  if (nativeTabCapability) return nativeTabCapability;
2777
2794
  if (nativeTabCapabilityPromise) return nativeTabCapabilityPromise;
2778
2795
  nativeTabCapabilityPromise = (async () => {
2779
2796
  try {
2780
- const moduleUrl = nativeTabModuleUrl();
2797
+ const moduleUrl = await waitForNativeTabModuleUrl();
2781
2798
  if (!moduleUrl) throw new Error("Codex app-initial modulepreload was not found");
2782
2799
  const appModule = await import(moduleUrl);
2783
2800
  if (typeof appModule.Gtt !== "function") {
@@ -2810,7 +2827,9 @@ export function createInjectionSource(features, {
2810
2827
  return null;
2811
2828
  }
2812
2829
  })();
2813
- return nativeTabCapabilityPromise;
2830
+ const capability = await nativeTabCapabilityPromise;
2831
+ if (!capability) nativeTabCapabilityPromise = null;
2832
+ return capability;
2814
2833
  }
2815
2834
 
2816
2835
  function nativeDetailIcon(feature, detail, jsx) {
@@ -2907,7 +2926,7 @@ export function createInjectionSource(features, {
2907
2926
  async function openNativeDetailTab(feature, detail) {
2908
2927
  const capability = await loadNativeTabCapability();
2909
2928
  if (!capability) return null;
2910
- const scope = currentTaskScope();
2929
+ const scope = await waitForCurrentTaskScope();
2911
2930
  if (!scope) {
2912
2931
  nativeTabCapabilityError = new Error("The current Codex Task scope was not found");
2913
2932
  return null;
@@ -2949,14 +2968,12 @@ export function createInjectionSource(features, {
2949
2968
 
2950
2969
  nativeTabCapabilityError = null;
2951
2970
  if (focusedExisting) reloadNativeDetailIfUnready(feature, detail);
2952
- const fallbackKey = `${feature.id}:${detail.id}`;
2953
- if (openTabs.has(fallbackKey)) closeDetailTab(fallbackKey);
2954
2971
  return { tabId, focusedExisting, presentation: "native" };
2955
2972
  }
2956
2973
 
2957
2974
  function detailTabCapability() {
2958
2975
  return {
2959
- presentation: nativeTabCapability ? "native" : "fallback",
2976
+ presentation: nativeTabCapability ? "native" : "unavailable",
2960
2977
  moduleAsset: nativeTabCapability?.moduleAsset ?? null,
2961
2978
  error: nativeTabCapabilityError?.message ?? null,
2962
2979
  openNativeTabs: nativeOpenTabSessions.size,
@@ -2974,185 +2991,14 @@ export function createInjectionSource(features, {
2974
2991
  nativeDetailSurfaceKeys.clear();
2975
2992
  }
2976
2993
 
2977
- function updateTabHostGeometry() {
2978
- if (!tabHost?.isConnected) return;
2979
- const width = Math.min(620, Math.max(360, innerWidth * 0.44));
2980
- tabHost.style.width = `${Math.min(width, Math.max(300, innerWidth - 72))}px`;
2981
- }
2982
-
2983
- function createTabHost() {
2984
- const host = document.createElement("aside");
2985
- host.setAttribute("data-codex-personal-tab-host", "right");
2986
- host.setAttribute("aria-label", locale === "zh-CN" ? "CodexNotes 工作区标签页" : "CodexNotes workspace tabs");
2987
- host.style.cssText = [
2988
- "position:fixed",
2989
- "top:46px",
2990
- "bottom:0",
2991
- "right:0",
2992
- "z-index:42",
2993
- "display:flex",
2994
- "flex-direction:column",
2995
- "min-width:300px",
2996
- "background:var(--color-token-main-surface-primary)",
2997
- "border-left:0.5px solid var(--color-border)",
2998
- "box-shadow:-8px 0 16px -12px rgba(0,0,0,.24)",
2999
- ].join(";");
3000
- const header = document.createElement("div");
3001
- header.style.cssText = [
3002
- "height:46px",
3003
- "display:flex",
3004
- "align-items:center",
3005
- "padding:0 8px",
3006
- "flex:0 0 auto",
3007
- "background:var(--color-token-main-surface-primary)",
3008
- ].join(";");
3009
- const strip = document.createElement("div");
3010
- strip.setAttribute("data-app-shell-tab-strip-controller", "right");
3011
- strip.setAttribute("data-codex-personal-tab-strip", "true");
3012
- strip.setAttribute("role", "tablist");
3013
- strip.style.cssText = "display:flex;align-items:center;gap:4px;min-width:0;flex:1;overflow-x:auto;height:100%";
3014
- header.append(strip);
3015
- const panels = document.createElement("div");
3016
- panels.setAttribute("data-codex-personal-tab-panels", "true");
3017
- panels.style.cssText = "position:relative;min-height:0;flex:1;background:var(--color-token-main-surface-primary)";
3018
- host.append(header, panels);
3019
- document.body.append(host);
3020
- tabHost = host;
3021
- updateTabHostGeometry();
3022
- return host;
3023
- }
3024
-
3025
- function activateTab(key) {
3026
- const record = openTabs.get(key);
3027
- if (!record) return;
3028
- activeTabKey = key;
3029
- for (const [candidateKey, candidate] of openTabs) {
3030
- const active = candidateKey === key;
3031
- candidate.tabButton.setAttribute("aria-selected", String(active));
3032
- candidate.tab.style.setProperty(
3033
- "--app-shell-tab-background",
3034
- active
3035
- ? "color-mix(in srgb, var(--color-text-foreground) 5%, var(--color-token-main-surface-primary))"
3036
- : "transparent",
3037
- );
3038
- candidate.panel.hidden = !active;
3039
- }
3040
- record.tabButton.focus({ preventScroll: true });
3041
- queueTheme();
3042
- }
3043
-
3044
- function closeDetailTab(key) {
3045
- const record = openTabs.get(key);
3046
- if (!record) return;
3047
- const keys = Array.from(openTabs.keys());
3048
- const index = keys.indexOf(key);
3049
- record.tab.remove();
3050
- record.panel.remove();
3051
- removeSurfaceRecord(record.surfaceRecordKey);
3052
- openTabs.delete(key);
3053
- if (openTabs.size === 0) {
3054
- tabHost?.remove();
3055
- tabHost = null;
3056
- activeTabKey = null;
3057
- updateResponsiveSummaryPresentation();
3058
- return;
3059
- }
3060
- if (activeTabKey === key) {
3061
- const remainingKeys = Array.from(openTabs.keys());
3062
- activateTab(remainingKeys[Math.min(index, remainingKeys.length - 1)]);
3063
- }
3064
- updateResponsiveSummaryPresentation();
3065
- }
3066
-
3067
- function createDetailTab(feature, detail) {
3068
- const host = tabHost?.isConnected ? tabHost : createTabHost();
3069
- const strip = host.querySelector("[data-codex-personal-tab-strip]");
3070
- const panels = host.querySelector("[data-codex-personal-tab-panels]");
3071
- const key = `${feature.id}:${detail.id}`;
3072
- const stableId = `${feature.id}-${detail.id}`;
3073
-
3074
- const tab = document.createElement("div");
3075
- tab.setAttribute("data-app-shell-tab-controller", "right");
3076
- tab.setAttribute("data-tab-id", stableId);
3077
- tab.style.cssText = [
3078
- "position:relative",
3079
- "display:flex",
3080
- "align-items:center",
3081
- "min-width:90px",
3082
- "max-width:160px",
3083
- "height:28px",
3084
- "padding:0 4px 0 8px",
3085
- "border-radius:8px",
3086
- "background:var(--app-shell-tab-background,transparent)",
3087
- "flex:1 0 110px",
3088
- ].join(";");
3089
- const tabButton = document.createElement("button");
3090
- tabButton.type = "button";
3091
- tabButton.setAttribute("role", "tab");
3092
- tabButton.setAttribute("aria-selected", "false");
3093
- tabButton.style.cssText = "display:flex;align-items:center;gap:7px;min-width:0;flex:1;height:100%;padding:0;background:transparent;border:0;color:var(--color-text-foreground);cursor:pointer";
3094
- const icon = createMarkupIcon(detail.icon ?? feature.icon, "icon-xs", 16);
3095
- if (icon) tabButton.append(icon);
3096
- const label = document.createElement("span");
3097
- label.textContent = detail.label;
3098
- label.style.cssText = "min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap";
3099
- tabButton.append(label);
3100
- tabButton.addEventListener("click", () => activateTab(key));
3101
- const close = document.createElement("button");
3102
- close.type = "button";
3103
- close.textContent = "×";
3104
- close.setAttribute("data-app-shell-tab-close-button", "true");
3105
- close.setAttribute(
3106
- "aria-label",
3107
- locale === "zh-CN" ? `关闭${detail.label}标签页` : `Close ${detail.label} tab`,
3108
- );
3109
- close.style.cssText = "width:20px;height:20px;border:0;border-radius:6px;padding:0;background:transparent;color:var(--color-text-foreground-tertiary);font-size:18px;line-height:18px;cursor:pointer";
3110
- close.addEventListener("click", (event) => {
3111
- event.stopPropagation();
3112
- closeDetailTab(key);
3113
- });
3114
- tab.append(tabButton, close);
3115
-
3116
- const panel = document.createElement("div");
3117
- panel.setAttribute("role", "tabpanel");
3118
- panel.setAttribute("aria-label", detail.label);
3119
- panel.setAttribute("data-app-shell-tab-panel-controller", "right");
3120
- panel.setAttribute("data-tab-id", stableId);
3121
- panel.style.cssText = "position:absolute;inset:0;min-height:0;background:var(--color-token-main-surface-primary)";
3122
- const frame = createFrame(feature.id, detail.label);
3123
- panel.append(frame);
3124
- strip.append(tab);
3125
- panels.append(panel);
3126
- const recordKey = surfaceKey(feature.id, "detail", detail.id);
3127
- registerSurface(recordKey, feature, "detail", detail.surfaceUrl, panel, frame, detail.id);
3128
- const record = { key, feature, detail, tab, tabButton, close, panel, frame, surfaceRecordKey: recordKey };
3129
- openTabs.set(key, record);
3130
- return record;
3131
- }
3132
-
3133
- function openFallbackDetailTab(feature, detail) {
3134
- const key = `${feature.id}:${detail.id}`;
3135
- const existing = openTabs.has(key);
3136
- if (!existing) createDetailTab(feature, detail);
3137
- else reloadSurfaceIfUnready(
3138
- surfaceKey(feature.id, "detail", detail.id),
3139
- detail.surfaceUrl,
3140
- );
3141
- activateTab(key);
3142
- updateResponsiveSummaryPresentation();
3143
- return {
3144
- tabId: `${feature.id}-${detail.id}`,
3145
- focusedExisting: existing,
3146
- presentation: "fallback",
3147
- };
3148
- }
3149
-
3150
2994
  async function openDetailTab(featureId, detailId) {
3151
2995
  const feature = featureById.get(featureId);
3152
2996
  const detail = feature?.detailTabs?.find((candidate) => candidate.id === detailId);
3153
2997
  if (!feature || !detail) throw new Error("The requested detail Tab is not registered");
3154
- return await openNativeDetailTab(feature, detail)
3155
- ?? openFallbackDetailTab(feature, detail);
2998
+ const result = await openNativeDetailTab(feature, detail);
2999
+ if (!result) throw nativeTabCapabilityError
3000
+ ?? new Error("Codex native right-panel tabs are unavailable");
3001
+ return result;
3156
3002
  }
3157
3003
 
3158
3004
  function openThread(threadId) {
@@ -3308,7 +3154,6 @@ export function createInjectionSource(features, {
3308
3154
  checkThreadChange();
3309
3155
  updateSidebarSelectedState();
3310
3156
  updatePageSurfacePositions();
3311
- updateTabHostGeometry();
3312
3157
  ensureMainContentObserver();
3313
3158
  updateResponsiveSummaryPresentation();
3314
3159
  const nativeToggle = nativeSummaryButton();
@@ -3449,8 +3294,7 @@ export function createInjectionSource(features, {
3449
3294
  const ownEntry = event.target.closest?.(`[${entryMarker}="${activePinnedFeatureId}"]`);
3450
3295
  const rightWorkspaceInteraction = event.target.closest?.(
3451
3296
  '[data-app-shell-tab-strip-controller="right"],'
3452
- + '[data-app-shell-tab-panel-controller="right"],'
3453
- + '[data-codex-personal-tab-host="right"]',
3297
+ + '[data-app-shell-tab-panel-controller="right"]',
3454
3298
  );
3455
3299
  const promptPreviewInteraction = event.target.closest?.(`[${promptPreviewMarker}]`);
3456
3300
  if (
@@ -3538,7 +3382,6 @@ export function createInjectionSource(features, {
3538
3382
  window.addEventListener("resize", () => {
3539
3383
  closePromptPreview({ immediate: true });
3540
3384
  updatePageSurfacePositions();
3541
- updateTabHostGeometry();
3542
3385
  updateResponsiveSummaryPresentation();
3543
3386
  }, { signal: lifetime.signal });
3544
3387
  const ensureObserver = new MutationObserver(queueEnsure);
@@ -3594,9 +3437,7 @@ export function createInjectionSource(features, {
3594
3437
  closeModalSurface();
3595
3438
  closeNativeDetailTabs();
3596
3439
  restoreModelSelectorEnhancements();
3597
- tabHost?.remove();
3598
3440
  surfaceRecords.clear();
3599
- openTabs.clear();
3600
3441
  if (window.__codexPersonalRuntime === runtimeApi) delete window.__codexPersonalRuntime;
3601
3442
  },
3602
3443
  };