minecodex 0.1.1 → 0.1.2

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.
@@ -87,7 +87,7 @@ HTTP + Images UI
87
87
  - Images 服务需要保持运行,才会持续监听新图片;侧边栏注册由 `CodexRuntimeHost` 统一维持。
88
88
  - 每次服务启动都会先开放 health,再在后台补扫停机期间新增的图片并刷新来源名称;初始补扫完成后,运行期间的新图片由文件监听自动加入。手动 Refresh 会再次补扫来源和 Archive 状态,但不会重置筛选、图板模式、详情、滚动位置或列数。刷新 ring 至少显示 1 秒。
89
89
  - 侧边栏使用 Codex 当前未公开的 CDP / DOM 能力,Codex UI 更新后只需调整统一宿主;独立 Web UI 和路径索引不受影响。
90
- - 当前 Codex 的 CSP 会屏蔽普通本地 iframe。统一宿主会先等待原生侧栏完成渲染,再启用 CSP bypass、注册 document-start 脚本,并替换当前 document 中旧的 MineCodex runtime 后显式完成注入;当前实现不会调用会让用户看到页面刷新的 `Page.reload`(Issue #1)。
90
+ - 当前 Codex 的 CSP 会屏蔽普通本地 iframe。统一宿主会先启用 CSP bypass 并注册 document-start 脚本;尚未完成该初始化的首次或旧版 document 会受控 reload 一次。完成初始化后会留下 document 标记,后续 RuntimeHost 重启只替换旧的 MineCodex runtime,不再刷新 Codex 页面(Issue #1)。
91
91
  - 详情打开时会从本机 Session JSONL 按需读取该 ImageGen item 的真实 `revised_prompt` 并缓存到索引;历史记录缺少该事件时明确显示 Prompt 不可用,不从附近文本猜测。
92
92
  - 当前没有发现 Codex 会因运行时间增长而自动清理 `generated_images` 的证据。如果未来观察到真实清理,再决定是否增加可选备份。
93
93
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "images",
4
- "version": "0.1.1",
4
+ "version": "0.1.2",
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.1",
4
+ "version": "0.1.2",
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.1",
4
+ "version": "0.1.2",
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.1",
3
+ "version": "0.1.2",
4
4
  "description": "Lightweight, local-first plugins for the Codex desktop app.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -141,6 +141,9 @@ Host 会再次发送当前状态。功能页面可据此暂停隐藏状态下的
141
141
 
142
142
  - 只在 top frame 安装 Runtime,绝不向业务 iframe 注入 binding token。
143
143
  - Watch / refresh 串行;已连接 Renderer 不重复连接,关闭 target 会清理状态。
144
+ - 本地 Surface 注入前先启用 CSP bypass 并注册 document-start 脚本;缺少初始化标记的
145
+ 首次或旧版 document 只受控 reload 一次。标记存在时,新的 RuntimeHost 会话直接
146
+ 替换旧 Runtime,不刷新当前 Codex 页面。
144
147
  - 入口由 Renderer 内的 MutationObserver 幂等挂载,React 重绘不会产生重复入口。
145
148
  - Summary 根据对话主区域宽度连续派生 `overlay / shift / gutter`:小于 1096px
146
149
  使用临时 Popover;1096–1535px 预留 316px 并把对话内容左移 158px;更宽时
@@ -5,6 +5,8 @@ import path from "node:path";
5
5
 
6
6
  const RUNTIME_VERSION = 99;
7
7
  const HOST_BINDING_NAME = "__codexPersonalHostAction";
8
+ const CSP_BOOTSTRAP_VERSION = 1;
9
+ const CSP_BOOTSTRAP_KEY = "__mineCodexCspBootstrapVersion";
8
10
 
9
11
  export const RESPONSIVE_SUMMARY_LAYOUT = Object.freeze({
10
12
  contentBaseWidth: 736,
@@ -3564,6 +3566,14 @@ export function createRuntimeReadyContract({
3564
3566
  };
3565
3567
  }
3566
3568
 
3569
+ function createDocumentBootstrapSource(source) {
3570
+ return `window[${JSON.stringify(CSP_BOOTSTRAP_KEY)}] = ${CSP_BOOTSTRAP_VERSION};\n${source}`;
3571
+ }
3572
+
3573
+ function documentBootstrapExpression() {
3574
+ return `window[${JSON.stringify(CSP_BOOTSTRAP_KEY)}] === ${CSP_BOOTSTRAP_VERSION}`;
3575
+ }
3576
+
3567
3577
  async function connect(url) {
3568
3578
  const socket = new WebSocket(url);
3569
3579
  const pending = new Map();
@@ -4250,7 +4260,20 @@ export class CodexRuntime {
4250
4260
  bindingToken,
4251
4261
  runtimeSessionId: this.runtimeSessionId,
4252
4262
  });
4253
- const script = await client.send("Page.addScriptToEvaluateOnNewDocument", { source });
4263
+ const bootstrapExpression = documentBootstrapExpression();
4264
+ const script = await client.send("Page.addScriptToEvaluateOnNewDocument", {
4265
+ source: createDocumentBootstrapSource(source),
4266
+ });
4267
+ const documentWasBootstrapped = Boolean(evaluationValue(await client.send("Runtime.evaluate", {
4268
+ expression: bootstrapExpression,
4269
+ returnByValue: true,
4270
+ })));
4271
+ if (!documentWasBootstrapped) {
4272
+ const pageLoaded = client.waitFor("Page.loadEventFired", 20_000);
4273
+ await client.send("Page.reload");
4274
+ await pageLoaded;
4275
+ await waitForExpression(client, bootstrapExpression);
4276
+ }
4254
4277
  await waitForExpression(
4255
4278
  client,
4256
4279
  `document.readyState === "interactive" || document.readyState === "complete"`,