@agentrouter-top/relay-dsh-plugin-codex 0.2.2-agentrouter.5 → 0.2.2-agentrouter.6

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.
@@ -12,5 +12,10 @@ export function readActivityPayload(value) {
12
12
  for (const key of ["summary", "input", "output", "exitCode", "commandActions"]) {
13
13
  if (activity[key] !== undefined && typeof activity[key] !== "string") return null;
14
14
  }
15
+ if (activity.imageGeneration !== undefined) {
16
+ const image = activity.imageGeneration;
17
+ if (activity.type !== "imageGeneration" || !image || typeof image !== "object" || image.version !== 1
18
+ || (image.attachmentId !== undefined && (typeof image.attachmentId !== "string" || !image.attachmentId))) return null;
19
+ }
15
20
  return value;
16
21
  }
@@ -0,0 +1,19 @@
1
+ # Image generation presentation v1
2
+
3
+ Relay projects native Codex `imageGeneration` item start/completion into a dot-matrix
4
+ waiting frame. This is not a partial image, estimated progress, or a new image tool.
5
+ Only a successful attachment import associates `activity.imageGeneration.attachmentId`
6
+ with the existing DSH image block. Projection matches that exact ID within the same
7
+ DSH step, keeps the generation key, and consumes only the matched image occurrence.
8
+ Parallel images cannot be paired by arrival order. Old activity without this optional
9
+ version-1 metadata, MCP images and image-view results keep their existing renderers.
10
+
11
+ The enhanced Codex process projection owns the frame. Native/fallback DSH transcripts
12
+ retain their tool and image rows. Failure/interruption stops the animation without
13
+ adding a warning badge; existing actual turn errors remain available. Reduced-motion
14
+ uses a static dot field. The final result uses DSH's public `renderMessageImages`, so
15
+ the independent Viewer plugin continues to handle viewing and downloading.
16
+
17
+ No Codex prompt, gateway, credentials, tool implementation, Desktop code, or session
18
+ history is modified. Image URLs and private filesystem paths are not added to the
19
+ presentation metadata.
package/lib/client.js CHANGED
@@ -193,13 +193,13 @@ window.__ModuleLoader__.load({
193
193
  }
194
194
  //#endregion
195
195
  //#region \0relay-css-module:.\src\client\AdvancedDebug.module.css.mjs
196
- const css$3 = ".Y4qSZW_section{width:100%;max-width:780px;color:var(--dsw-alias-label-primary)}.Y4qSZW_settingRow{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:20px;min-height:58px;padding:8px 0;display:flex}.Y4qSZW_statusRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:flex-start;gap:10px;min-height:70px;padding:10px 0;display:flex}.Y4qSZW_statusDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:8px;height:8px;margin-top:6px}.Y4qSZW_statusRow[data-codex-status=connected] .Y4qSZW_statusDot{background:#27a65b}.Y4qSZW_statusRow[data-codex-status=connection-failed] .Y4qSZW_statusDot,.Y4qSZW_statusRow[data-codex-status=unavailable] .Y4qSZW_statusDot,.Y4qSZW_statusRow[data-codex-status=rebind-required] .Y4qSZW_statusDot{background:#d94841}.Y4qSZW_settingCopy code{color:var(--dsw-alias-label-tertiary);font-size:11px}.Y4qSZW_statusBadge{border-radius:999px;padding:2px 7px;font-size:11px;font-weight:600;line-height:16px}.Y4qSZW_statusError{color:#d94841;background:#d9484124}.Y4qSZW_statusRebind{color:#a95d00;background:#c26a0029}.Y4qSZW_settingCopy{flex-direction:column;gap:2px;min-width:0;display:flex}.Y4qSZW_settingCopy strong{font-size:14px;font-weight:500;line-height:20px}.Y4qSZW_settingCopy span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.Y4qSZW_switch{cursor:pointer;flex:none;width:36px;height:20px;display:inline-flex;position:relative}.Y4qSZW_switch input{opacity:0;width:1px;height:1px;position:absolute}.Y4qSZW_switch span{background:var(--dsw-alias-fill-l2);border-radius:10px;width:100%;transition:background-color .12s}.Y4qSZW_switch span:after{background:var(--dsw-alias-bg-layer-1);content:\"\";border-radius:50%;width:16px;height:16px;transition:transform .12s;position:absolute;top:2px;left:2px;box-shadow:0 1px 3px #0003}.Y4qSZW_switch input:checked+span{background:var(--dsw-alias-state-business-primary)}.Y4qSZW_switch input:checked+span:after{transform:translate(16px)}.Y4qSZW_switch input:focus-visible+span{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.Y4qSZW_marker{display:none}[data-relay-simple-conversation=true] [role=tablist]{display:none}";
197
- const tagId$3 = "@agentrouter-top/relay-dsh-plugin-codex/AdvancedDebug.module.css";
198
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
196
+ const css$4 = ".Y4qSZW_section{width:100%;max-width:780px;color:var(--dsw-alias-label-primary)}.Y4qSZW_settingRow{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:20px;min-height:58px;padding:8px 0;display:flex}.Y4qSZW_statusRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:flex-start;gap:10px;min-height:70px;padding:10px 0;display:flex}.Y4qSZW_statusDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:8px;height:8px;margin-top:6px}.Y4qSZW_statusRow[data-codex-status=connected] .Y4qSZW_statusDot{background:#27a65b}.Y4qSZW_statusRow[data-codex-status=connection-failed] .Y4qSZW_statusDot,.Y4qSZW_statusRow[data-codex-status=unavailable] .Y4qSZW_statusDot,.Y4qSZW_statusRow[data-codex-status=rebind-required] .Y4qSZW_statusDot{background:#d94841}.Y4qSZW_settingCopy code{color:var(--dsw-alias-label-tertiary);font-size:11px}.Y4qSZW_statusBadge{border-radius:999px;padding:2px 7px;font-size:11px;font-weight:600;line-height:16px}.Y4qSZW_statusError{color:#d94841;background:#d9484124}.Y4qSZW_statusRebind{color:#a95d00;background:#c26a0029}.Y4qSZW_settingCopy{flex-direction:column;gap:2px;min-width:0;display:flex}.Y4qSZW_settingCopy strong{font-size:14px;font-weight:500;line-height:20px}.Y4qSZW_settingCopy span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.Y4qSZW_switch{cursor:pointer;flex:none;width:36px;height:20px;display:inline-flex;position:relative}.Y4qSZW_switch input{opacity:0;width:1px;height:1px;position:absolute}.Y4qSZW_switch span{background:var(--dsw-alias-fill-l2);border-radius:10px;width:100%;transition:background-color .12s}.Y4qSZW_switch span:after{background:var(--dsw-alias-bg-layer-1);content:\"\";border-radius:50%;width:16px;height:16px;transition:transform .12s;position:absolute;top:2px;left:2px;box-shadow:0 1px 3px #0003}.Y4qSZW_switch input:checked+span{background:var(--dsw-alias-state-business-primary)}.Y4qSZW_switch input:checked+span:after{transform:translate(16px)}.Y4qSZW_switch input:focus-visible+span{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.Y4qSZW_marker{display:none}[data-relay-simple-conversation=true] [role=tablist]{display:none}";
197
+ const tagId$4 = "@agentrouter-top/relay-dsh-plugin-codex/AdvancedDebug.module.css";
198
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
199
199
  const tag = document.createElement("style");
200
200
  tag.dataset.plugin = "@agentrouter-top/relay-dsh-plugin-codex";
201
- tag.dataset.pluginCss = tagId$3;
202
- tag.textContent = css$3;
201
+ tag.dataset.pluginCss = tagId$4;
202
+ tag.textContent = css$4;
203
203
  document.head.appendChild(tag);
204
204
  }
205
205
  var AdvancedDebug_module_css_default = {
@@ -34889,6 +34889,10 @@ window.__ModuleLoader__.load({
34889
34889
  "exitCode",
34890
34890
  "commandActions"
34891
34891
  ]) if (activity[key] !== void 0 && typeof activity[key] !== "string") return null;
34892
+ if (activity.imageGeneration !== void 0) {
34893
+ const image = activity.imageGeneration;
34894
+ if (activity.type !== "imageGeneration" || !image || typeof image !== "object" || image.version !== 1 || image.attachmentId !== void 0 && (typeof image.attachmentId !== "string" || !image.attachmentId)) return null;
34895
+ }
34892
34896
  return value;
34893
34897
  }
34894
34898
  //#endregion
@@ -35213,13 +35217,13 @@ window.__ModuleLoader__.load({
35213
35217
  }
35214
35218
  //#endregion
35215
35219
  //#region \0relay-css-module:.\src\client\CodexActivityView.module.css.mjs
35216
- const css$2 = ".jIHzgW_activity{width:min(100%,960px);color:var(--dsw-alias-label-secondary)}.jIHzgW_row{gap:8px;min-width:0;max-width:100%}.jIHzgW_title{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;font-size:14px;line-height:24px;overflow:hidden}.jIHzgW_summary{min-width:0;color:var(--dsw-alias-label-tertiary);flex:1;align-items:center;gap:8px;font-size:13px;line-height:20px;display:flex}.jIHzgW_summary :first-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.jIHzgW_detail{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-background-container,#f6f6f7);color:var(--dsw-alias-label-secondary);border-radius:8px;margin:8px 0 12px 28px;overflow:hidden}.jIHzgW_detailBlock{min-width:0}.jIHzgW_detailLabel{color:var(--dsw-alias-label-tertiary);padding:10px 12px 0;font-size:13px;line-height:18px}.jIHzgW_detail pre{max-height:360px;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-markdown-code-block-small);white-space:pre-wrap;word-break:break-word;margin:0;padding:10px 12px 12px;overflow:auto}.jIHzgW_provenance{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;padding:10px 12px 0;font-size:12px;line-height:18px;overflow:hidden}.jIHzgW_footer{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);justify-content:space-between;gap:12px;padding:8px 12px;font-size:13px;line-height:18px;display:flex}";
35217
- const tagId$2 = "@agentrouter-top/relay-dsh-plugin-codex/CodexActivityView.module.css";
35218
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
35220
+ const css$3 = ".jIHzgW_activity{width:min(100%,960px);color:var(--dsw-alias-label-secondary)}.jIHzgW_row{gap:8px;min-width:0;max-width:100%}.jIHzgW_title{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;font-size:14px;line-height:24px;overflow:hidden}.jIHzgW_summary{min-width:0;color:var(--dsw-alias-label-tertiary);flex:1;align-items:center;gap:8px;font-size:13px;line-height:20px;display:flex}.jIHzgW_summary :first-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.jIHzgW_detail{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-background-container,#f6f6f7);color:var(--dsw-alias-label-secondary);border-radius:8px;margin:8px 0 12px 28px;overflow:hidden}.jIHzgW_detailBlock{min-width:0}.jIHzgW_detailLabel{color:var(--dsw-alias-label-tertiary);padding:10px 12px 0;font-size:13px;line-height:18px}.jIHzgW_detail pre{max-height:360px;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-markdown-code-block-small);white-space:pre-wrap;word-break:break-word;margin:0;padding:10px 12px 12px;overflow:auto}.jIHzgW_provenance{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;padding:10px 12px 0;font-size:12px;line-height:18px;overflow:hidden}.jIHzgW_footer{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);justify-content:space-between;gap:12px;padding:8px 12px;font-size:13px;line-height:18px;display:flex}";
35221
+ const tagId$3 = "@agentrouter-top/relay-dsh-plugin-codex/CodexActivityView.module.css";
35222
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
35219
35223
  const tag = document.createElement("style");
35220
35224
  tag.dataset.plugin = "@agentrouter-top/relay-dsh-plugin-codex";
35221
- tag.dataset.pluginCss = tagId$2;
35222
- tag.textContent = css$2;
35225
+ tag.dataset.pluginCss = tagId$3;
35226
+ tag.textContent = css$3;
35223
35227
  document.head.appendChild(tag);
35224
35228
  }
35225
35229
  var CodexActivityView_module_css_default = {
@@ -35722,6 +35726,24 @@ window.__ModuleLoader__.load({
35722
35726
  const last = text.at(-1);
35723
35727
  return last ? [last] : [];
35724
35728
  }
35729
+ /** Place each generated attachment in its original generation frame. Never guess
35730
+ * by filename, nearest activity, or cross-turn order. Legacy/MCP images stay native. */
35731
+ function imageGenerationFrames(segments) {
35732
+ const consumed = /* @__PURE__ */ new Set();
35733
+ const frames = /* @__PURE__ */ new Map();
35734
+ for (const segment of segments) {
35735
+ const generation = segment.activity?.imageGeneration;
35736
+ if (segment.kind !== "activity" || generation?.version !== 1) continue;
35737
+ const image = generation.attachmentId ? segments.find((candidate) => candidate.kind === "image" && candidate.step === segment.step && !consumed.has(candidate.key) && candidate.attachment?.attachmentId === generation.attachmentId) : void 0;
35738
+ if (image) consumed.add(image.key);
35739
+ frames.set(segment.key, {
35740
+ ...segment,
35741
+ kind: "image",
35742
+ attachment: image?.attachment
35743
+ });
35744
+ }
35745
+ return segments.filter((segment) => !consumed.has(segment.key)).map((segment) => frames.get(segment.key) ?? segment);
35746
+ }
35725
35747
  const codexProcessDefinition = {
35726
35748
  kind: "relay-codex-process",
35727
35749
  target: "chat",
@@ -35906,6 +35928,53 @@ window.__ModuleLoader__.load({
35906
35928
  return value.length > 15 ? `${value.slice(0, 8)}...${value.slice(-4)}` : value;
35907
35929
  }
35908
35930
  //#endregion
35931
+ //#region \0relay-css-module:.\src\client\CodexImageGeneration.module.css.mjs
35932
+ const css$2 = ".gSdKhG_frame{border-radius:16px;width:min(100%,480px);min-width:0;overflow:hidden}.gSdKhG_placeholder{aspect-ratio:1;background:var(--dsw-alias-bg-layer-2,#f3f4f6);color:var(--dsw-alias-label-secondary,#646b77);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:inherit;place-items:end center;display:grid;position:relative;overflow:hidden}.gSdKhG_field{color:var(--dsw-alias-label-tertiary,#9299a3);opacity:.48;background:currentColor;position:absolute;inset:18px;overflow:hidden;mask-image:radial-gradient(circle,#000 1.2px,#0000 1.5px);mask-size:12px 12px}.gSdKhG_light{background:linear-gradient(115deg, transparent 28%, var(--dsw-alias-label-primary,#343b46) 48%, transparent 68%);animation:3.6s ease-in-out infinite alternate gSdKhG_codex-image-shimmer;position:absolute;inset:-55%}.gSdKhG_label{z-index:1;text-align:center;background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:12px;margin:0 16px 24px;padding:6px 12px;font-size:13px;line-height:20px}.gSdKhG_frame[data-state=stopped] .gSdKhG_light{opacity:.25;animation:none}@keyframes gSdKhG_codex-image-shimmer{0%{opacity:.35;transform:translate(-30%,-12%)}to{opacity:1;transform:translate(30%,12%)}}@media (prefers-reduced-motion:reduce){.gSdKhG_light{opacity:.55;animation:none}}";
35933
+ const tagId$2 = "@agentrouter-top/relay-dsh-plugin-codex/CodexImageGeneration.module.css";
35934
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
35935
+ const tag = document.createElement("style");
35936
+ tag.dataset.plugin = "@agentrouter-top/relay-dsh-plugin-codex";
35937
+ tag.dataset.pluginCss = tagId$2;
35938
+ tag.textContent = css$2;
35939
+ document.head.appendChild(tag);
35940
+ }
35941
+ var CodexImageGeneration_module_css_default = {
35942
+ "codex-image-shimmer": "gSdKhG_codex-image-shimmer",
35943
+ "field": "gSdKhG_field",
35944
+ "frame": "gSdKhG_frame",
35945
+ "label": "gSdKhG_label",
35946
+ "light": "gSdKhG_light",
35947
+ "placeholder": "gSdKhG_placeholder"
35948
+ };
35949
+ //#endregion
35950
+ //#region src/client/CodexImageGeneration.tsx
35951
+ function CodexImageGeneration({ segment, running, renderMessageImages }) {
35952
+ const pending = !segment.attachment && running && segment.activity?.status !== "error";
35953
+ const label = pending ? "正在生成图片" : "图片生成已结束,未提供可显示的图片";
35954
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
35955
+ className: CodexImageGeneration_module_css_default.frame,
35956
+ "data-codex-image-generation": segment.key,
35957
+ "data-state": segment.attachment ? "ready" : pending ? "generating" : "stopped",
35958
+ "aria-busy": pending,
35959
+ children: segment.attachment ? renderMessageImages({
35960
+ images: [{ attachment: segment.attachment }],
35961
+ align: "start"
35962
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
35963
+ className: CodexImageGeneration_module_css_default.placeholder,
35964
+ role: "status",
35965
+ "aria-live": "polite",
35966
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
35967
+ className: CodexImageGeneration_module_css_default.field,
35968
+ "aria-hidden": "true",
35969
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: CodexImageGeneration_module_css_default.light })
35970
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
35971
+ className: CodexImageGeneration_module_css_default.label,
35972
+ children: label
35973
+ })]
35974
+ })
35975
+ });
35976
+ }
35977
+ //#endregion
35909
35978
  //#region src/client/process-files.ts
35910
35979
  function codexProducedFileMentions(segments, openFile, native) {
35911
35980
  const paths = /* @__PURE__ */ new Set();
@@ -36058,9 +36127,10 @@ window.__ModuleLoader__.load({
36058
36127
  };
36059
36128
  }, [state.status]);
36060
36129
  const answerKeys = new Set(codexProcessAnswerSegments(state).map((segment) => segment.key));
36061
- const finalIndex = state.segments.findIndex((segment) => answerKeys.has(segment.key));
36062
- const process = finalIndex < 0 ? state.segments : state.segments.slice(0, finalIndex);
36063
- const answer = finalIndex < 0 ? [] : state.segments.slice(finalIndex);
36130
+ const segments = imageGenerationFrames(state.segments);
36131
+ const finalIndex = segments.findIndex((segment) => answerKeys.has(segment.key));
36132
+ const process = finalIndex < 0 ? segments : segments.slice(0, finalIndex);
36133
+ const answer = finalIndex < 0 ? [] : segments.slice(finalIndex);
36064
36134
  const deliverables = process.filter((segment) => segment.kind === "image");
36065
36135
  const hasProcess = process.some((segment) => segment.kind !== "text" || Boolean(segment.text?.trim()));
36066
36136
  const open = expanded ?? (state.status === "running" || answer.length === 0 && deliverables.length === 0);
@@ -36115,7 +36185,11 @@ window.__ModuleLoader__.load({
36115
36185
  });
36116
36186
  }
36117
36187
  function ProcessItems({ segments, renderMessageImages, running, fileMentions, showImages = true }) {
36118
- return groupProcessSegments(segments).map((item) => "activities" in item ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActivityGroup, { segments: item.activities }, item.key) : item.kind === "image" && item.attachment ? showImages ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderMessageImages({
36188
+ return groupProcessSegments(segments).map((item) => "activities" in item ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActivityGroup, { segments: item.activities }, item.key) : item.activity?.imageGeneration ? showImages ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexImageGeneration, {
36189
+ segment: item,
36190
+ running,
36191
+ renderMessageImages
36192
+ }, item.key) : null : item.kind === "image" && item.attachment ? showImages ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderMessageImages({
36119
36193
  images: [{ attachment: item.attachment }],
36120
36194
  align: "start"
36121
36195
  }) }, item.key) : null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {