@workflow-code/cli 0.2.4-20261013006.codex-studio-integration → 0.2.4-20261013007.codex-studio-integration

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.
@@ -1044,6 +1044,30 @@ main {
1044
1044
  height: 100%;
1045
1045
  object-fit: cover;
1046
1046
  }
1047
+ .attachment-image {
1048
+ position: relative;
1049
+ padding: 0;
1050
+ border: 0;
1051
+ background: transparent;
1052
+ }
1053
+ .attachment-image .attachment-preview {
1054
+ width: 88px;
1055
+ height: 88px;
1056
+ background: transparent;
1057
+ }
1058
+ .message .attachment-image .attachment-preview {
1059
+ width: 120px;
1060
+ height: 120px;
1061
+ }
1062
+ .attachment-image .attachment-preview img {
1063
+ object-fit: contain;
1064
+ }
1065
+ .attachment-image > .icon-button {
1066
+ position: absolute;
1067
+ top: 0;
1068
+ right: 0;
1069
+ background: var(--vscode-editor-background);
1070
+ }
1047
1071
  #draft-attachments {
1048
1072
  padding: 0 16px;
1049
1073
  }
@@ -14401,14 +14401,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
14401
14401
  DocumentFragment,
14402
14402
  HTMLTemplateElement,
14403
14403
  Node,
14404
- Element,
14404
+ Element: Element2,
14405
14405
  NodeFilter,
14406
14406
  NamedNodeMap = window2.NamedNodeMap || window2.MozNamedAttrMap,
14407
14407
  HTMLFormElement,
14408
14408
  DOMParser,
14409
14409
  trustedTypes
14410
14410
  } = window2;
14411
- const ElementPrototype = Element.prototype;
14411
+ const ElementPrototype = Element2.prototype;
14412
14412
  const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
14413
14413
  const remove = lookupGetter(ElementPrototype, "remove");
14414
14414
  const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
@@ -14862,7 +14862,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
14862
14862
  _forceRemove(currentNode);
14863
14863
  return true;
14864
14864
  }
14865
- if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
14865
+ if (currentNode instanceof Element2 && !_checkValidNamespace(currentNode)) {
14866
14866
  _forceRemove(currentNode);
14867
14867
  return true;
14868
14868
  }
@@ -15871,6 +15871,28 @@ ${state2.user?.avatarUrl ?? ""}`;
15871
15871
  }
15872
15872
  };
15873
15873
 
15874
+ // src/web/ui/edit-commands.ts
15875
+ function pasteHostClipboard(clipboard) {
15876
+ if (typeof clipboard.text !== "string" || clipboard.image !== void 0 && !ArrayBuffer.isView(clipboard.image)) {
15877
+ return;
15878
+ }
15879
+ const target = document.activeElement;
15880
+ if (!(target instanceof HTMLElement) || !target.matches("textarea, input, [contenteditable=true]") || target.matches(":disabled, [readonly]")) {
15881
+ return;
15882
+ }
15883
+ const transfer = new DataTransfer();
15884
+ transfer.setData("text/plain", clipboard.text);
15885
+ if (clipboard.image && clipboard.image.byteLength) {
15886
+ const image = new Uint8Array(clipboard.image.buffer, clipboard.image.byteOffset, clipboard.image.byteLength);
15887
+ transfer.items.add(new File([new Uint8Array(image)], "clipboard.png", { type: "image/png" }));
15888
+ }
15889
+ const event = new ClipboardEvent("paste", { bubbles: true, cancelable: true, clipboardData: transfer });
15890
+ target.dispatchEvent(event);
15891
+ if (!event.defaultPrevented && clipboard.text) {
15892
+ document.execCommand("insertText", false, clipboard.text);
15893
+ }
15894
+ }
15895
+
15874
15896
  // src/web/ui/host.ts
15875
15897
  function acquireWorkflowHost(options = {}) {
15876
15898
  const embedded = globalThis.acquireVsCodeApi;
@@ -15892,13 +15914,62 @@ ${state2.user?.avatarUrl ?? ""}`;
15892
15914
  window.parent.postMessage(message, "*");
15893
15915
  }
15894
15916
  });
15895
- let resourceHost = false;
15917
+ let resourceHost = false, editHost = false, nativePasteHost = false;
15918
+ let contextInput, lastInput;
15919
+ const captureInput = (input) => {
15920
+ const field = input;
15921
+ return { element: input, selection: typeof field.selectionStart === "number" && typeof field.selectionEnd === "number" ? { start: field.selectionStart, end: field.selectionEnd, direction: field.selectionDirection ?? "none", value: field.value } : void 0 };
15922
+ };
15923
+ const rememberInput = () => {
15924
+ const input = document.activeElement;
15925
+ if (input instanceof HTMLElement && input.matches("textarea, input, [contenteditable=true]")) {
15926
+ lastInput = captureInput(input);
15927
+ }
15928
+ };
15896
15929
  const clipboard = new ClipboardBridge(
15897
15930
  (message) => window.parent.postMessage(message, "*"),
15898
15931
  (text2) => navigator.clipboard.writeText(text2),
15899
15932
  window.parent !== window && document.body.dataset.accountHost === "true"
15900
15933
  );
15901
15934
  addEventListener("pagehide", () => clipboard.dispose());
15935
+ addEventListener("keydown", (event) => {
15936
+ if (!editHost || !nativePasteHost || event.defaultPrevented || event.key.toLowerCase() !== "v" || !(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey || !(event.target instanceof Element) || !event.target.closest("textarea, input, [contenteditable=true]")) {
15937
+ return;
15938
+ }
15939
+ event.preventDefault();
15940
+ contextInput = void 0;
15941
+ rememberInput();
15942
+ window.parent.postMessage({ type: "workflow-edit", version: 1, command: "paste" }, "*");
15943
+ });
15944
+ addEventListener("contextmenu", (event) => {
15945
+ if (!editHost || event.defaultPrevented || !(event.target instanceof Element)) {
15946
+ return;
15947
+ }
15948
+ const input = event.target.closest("textarea, input, [contenteditable=true]");
15949
+ if (!input) {
15950
+ return;
15951
+ }
15952
+ event.preventDefault();
15953
+ input.focus({ preventScroll: true });
15954
+ contextInput = lastInput = captureInput(input);
15955
+ window.parent.postMessage({ type: "workflow-contextmenu", version: 1, x: event.clientX, y: event.clientY }, "*");
15956
+ });
15957
+ addEventListener("focusin", (event) => {
15958
+ if (event.target instanceof Element && event.target !== contextInput?.element && event.target.matches("textarea, input, [contenteditable=true]")) {
15959
+ contextInput = void 0;
15960
+ }
15961
+ rememberInput();
15962
+ });
15963
+ addEventListener("input", rememberInput);
15964
+ addEventListener("selectionchange", rememberInput, true);
15965
+ addEventListener("pointerdown", (event) => {
15966
+ if (event.button !== 2) {
15967
+ contextInput = void 0;
15968
+ }
15969
+ if (event.target instanceof Element && !event.target.closest("textarea, input, [contenteditable=true]")) {
15970
+ lastInput = void 0;
15971
+ }
15972
+ });
15902
15973
  const connection = new BrowserConnection((message) => {
15903
15974
  if (message.type === "state" && message.account) {
15904
15975
  accountPanel.update(message.account);
@@ -15923,17 +15994,37 @@ ${state2.user?.avatarUrl ?? ""}`;
15923
15994
  }
15924
15995
  if (event.data.clipboardVersion !== void 0) {
15925
15996
  clipboard.enable(event.data.clipboardVersion);
15926
- if (event.data.clipboardVersion === 1) {
15997
+ editHost = event.data.clipboardVersion === 1;
15998
+ if (editHost) {
15927
15999
  window.parent.postMessage({ type: "workflow-edit", version: 1 }, "*");
15928
16000
  }
15929
16001
  }
15930
16002
  if (event.data.resourceVersion === 1) {
15931
16003
  resourceHost = true;
15932
16004
  }
16005
+ if (event.data.nativePasteVersion !== void 0) {
16006
+ nativePasteHost = event.data.nativePasteVersion === 1;
16007
+ }
15933
16008
  if (event.data.resourceError) {
15934
16009
  emit(event.data.resourceError);
15935
16010
  }
15936
- if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
16011
+ if ((event.data.restoreFocus === true || event.data.clipboardData && document.activeElement === document.body) && ["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
16012
+ const context = contextInput ?? lastInput;
16013
+ contextInput = void 0;
16014
+ if (context) {
16015
+ const input = context.element;
16016
+ if (!input.isConnected || context.selection && input.value !== context.selection.value) {
16017
+ return;
16018
+ }
16019
+ input.focus({ preventScroll: true });
16020
+ if (context.selection) {
16021
+ input.setSelectionRange(context.selection.start, context.selection.end, context.selection.direction);
16022
+ }
16023
+ }
16024
+ }
16025
+ if (event.data.editCommand === "paste" && event.data.clipboardData) {
16026
+ pasteHostClipboard(event.data.clipboardData);
16027
+ } else if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
15937
16028
  document.execCommand(event.data.editCommand);
15938
16029
  }
15939
16030
  clipboard.receive(event.data.clipboard);
@@ -1044,6 +1044,30 @@ main {
1044
1044
  height: 100%;
1045
1045
  object-fit: cover;
1046
1046
  }
1047
+ .attachment-image {
1048
+ position: relative;
1049
+ padding: 0;
1050
+ border: 0;
1051
+ background: transparent;
1052
+ }
1053
+ .attachment-image .attachment-preview {
1054
+ width: 88px;
1055
+ height: 88px;
1056
+ background: transparent;
1057
+ }
1058
+ .message .attachment-image .attachment-preview {
1059
+ width: 120px;
1060
+ height: 120px;
1061
+ }
1062
+ .attachment-image .attachment-preview img {
1063
+ object-fit: contain;
1064
+ }
1065
+ .attachment-image > .icon-button {
1066
+ position: absolute;
1067
+ top: 0;
1068
+ right: 0;
1069
+ background: var(--vscode-editor-background);
1070
+ }
1047
1071
  #draft-attachments {
1048
1072
  padding: 0 16px;
1049
1073
  }
@@ -14401,14 +14401,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
14401
14401
  DocumentFragment,
14402
14402
  HTMLTemplateElement,
14403
14403
  Node,
14404
- Element,
14404
+ Element: Element2,
14405
14405
  NodeFilter,
14406
14406
  NamedNodeMap = window2.NamedNodeMap || window2.MozNamedAttrMap,
14407
14407
  HTMLFormElement,
14408
14408
  DOMParser,
14409
14409
  trustedTypes
14410
14410
  } = window2;
14411
- const ElementPrototype = Element.prototype;
14411
+ const ElementPrototype = Element2.prototype;
14412
14412
  const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
14413
14413
  const remove = lookupGetter(ElementPrototype, "remove");
14414
14414
  const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
@@ -14862,7 +14862,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
14862
14862
  _forceRemove(currentNode);
14863
14863
  return true;
14864
14864
  }
14865
- if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
14865
+ if (currentNode instanceof Element2 && !_checkValidNamespace(currentNode)) {
14866
14866
  _forceRemove(currentNode);
14867
14867
  return true;
14868
14868
  }
@@ -15871,6 +15871,28 @@ ${state.user?.avatarUrl ?? ""}`;
15871
15871
  }
15872
15872
  };
15873
15873
 
15874
+ // src/web/ui/edit-commands.ts
15875
+ function pasteHostClipboard(clipboard) {
15876
+ if (typeof clipboard.text !== "string" || clipboard.image !== void 0 && !ArrayBuffer.isView(clipboard.image)) {
15877
+ return;
15878
+ }
15879
+ const target = document.activeElement;
15880
+ if (!(target instanceof HTMLElement) || !target.matches("textarea, input, [contenteditable=true]") || target.matches(":disabled, [readonly]")) {
15881
+ return;
15882
+ }
15883
+ const transfer = new DataTransfer();
15884
+ transfer.setData("text/plain", clipboard.text);
15885
+ if (clipboard.image && clipboard.image.byteLength) {
15886
+ const image = new Uint8Array(clipboard.image.buffer, clipboard.image.byteOffset, clipboard.image.byteLength);
15887
+ transfer.items.add(new File([new Uint8Array(image)], "clipboard.png", { type: "image/png" }));
15888
+ }
15889
+ const event = new ClipboardEvent("paste", { bubbles: true, cancelable: true, clipboardData: transfer });
15890
+ target.dispatchEvent(event);
15891
+ if (!event.defaultPrevented && clipboard.text) {
15892
+ document.execCommand("insertText", false, clipboard.text);
15893
+ }
15894
+ }
15895
+
15874
15896
  // src/web/ui/host.ts
15875
15897
  function acquireWorkflowHost(options = {}) {
15876
15898
  const embedded = globalThis.acquireVsCodeApi;
@@ -15892,13 +15914,62 @@ ${state.user?.avatarUrl ?? ""}`;
15892
15914
  window.parent.postMessage(message, "*");
15893
15915
  }
15894
15916
  });
15895
- let resourceHost = false;
15917
+ let resourceHost = false, editHost = false, nativePasteHost = false;
15918
+ let contextInput, lastInput;
15919
+ const captureInput = (input) => {
15920
+ const field = input;
15921
+ return { element: input, selection: typeof field.selectionStart === "number" && typeof field.selectionEnd === "number" ? { start: field.selectionStart, end: field.selectionEnd, direction: field.selectionDirection ?? "none", value: field.value } : void 0 };
15922
+ };
15923
+ const rememberInput = () => {
15924
+ const input = document.activeElement;
15925
+ if (input instanceof HTMLElement && input.matches("textarea, input, [contenteditable=true]")) {
15926
+ lastInput = captureInput(input);
15927
+ }
15928
+ };
15896
15929
  const clipboard = new ClipboardBridge(
15897
15930
  (message) => window.parent.postMessage(message, "*"),
15898
15931
  (text2) => navigator.clipboard.writeText(text2),
15899
15932
  window.parent !== window && document.body.dataset.accountHost === "true"
15900
15933
  );
15901
15934
  addEventListener("pagehide", () => clipboard.dispose());
15935
+ addEventListener("keydown", (event) => {
15936
+ if (!editHost || !nativePasteHost || event.defaultPrevented || event.key.toLowerCase() !== "v" || !(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey || !(event.target instanceof Element) || !event.target.closest("textarea, input, [contenteditable=true]")) {
15937
+ return;
15938
+ }
15939
+ event.preventDefault();
15940
+ contextInput = void 0;
15941
+ rememberInput();
15942
+ window.parent.postMessage({ type: "workflow-edit", version: 1, command: "paste" }, "*");
15943
+ });
15944
+ addEventListener("contextmenu", (event) => {
15945
+ if (!editHost || event.defaultPrevented || !(event.target instanceof Element)) {
15946
+ return;
15947
+ }
15948
+ const input = event.target.closest("textarea, input, [contenteditable=true]");
15949
+ if (!input) {
15950
+ return;
15951
+ }
15952
+ event.preventDefault();
15953
+ input.focus({ preventScroll: true });
15954
+ contextInput = lastInput = captureInput(input);
15955
+ window.parent.postMessage({ type: "workflow-contextmenu", version: 1, x: event.clientX, y: event.clientY }, "*");
15956
+ });
15957
+ addEventListener("focusin", (event) => {
15958
+ if (event.target instanceof Element && event.target !== contextInput?.element && event.target.matches("textarea, input, [contenteditable=true]")) {
15959
+ contextInput = void 0;
15960
+ }
15961
+ rememberInput();
15962
+ });
15963
+ addEventListener("input", rememberInput);
15964
+ addEventListener("selectionchange", rememberInput, true);
15965
+ addEventListener("pointerdown", (event) => {
15966
+ if (event.button !== 2) {
15967
+ contextInput = void 0;
15968
+ }
15969
+ if (event.target instanceof Element && !event.target.closest("textarea, input, [contenteditable=true]")) {
15970
+ lastInput = void 0;
15971
+ }
15972
+ });
15902
15973
  const connection = new BrowserConnection((message) => {
15903
15974
  if (message.type === "state" && message.account) {
15904
15975
  accountPanel.update(message.account);
@@ -15923,17 +15994,37 @@ ${state.user?.avatarUrl ?? ""}`;
15923
15994
  }
15924
15995
  if (event.data.clipboardVersion !== void 0) {
15925
15996
  clipboard.enable(event.data.clipboardVersion);
15926
- if (event.data.clipboardVersion === 1) {
15997
+ editHost = event.data.clipboardVersion === 1;
15998
+ if (editHost) {
15927
15999
  window.parent.postMessage({ type: "workflow-edit", version: 1 }, "*");
15928
16000
  }
15929
16001
  }
15930
16002
  if (event.data.resourceVersion === 1) {
15931
16003
  resourceHost = true;
15932
16004
  }
16005
+ if (event.data.nativePasteVersion !== void 0) {
16006
+ nativePasteHost = event.data.nativePasteVersion === 1;
16007
+ }
15933
16008
  if (event.data.resourceError) {
15934
16009
  emit(event.data.resourceError);
15935
16010
  }
15936
- if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
16011
+ if ((event.data.restoreFocus === true || event.data.clipboardData && document.activeElement === document.body) && ["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
16012
+ const context = contextInput ?? lastInput;
16013
+ contextInput = void 0;
16014
+ if (context) {
16015
+ const input = context.element;
16016
+ if (!input.isConnected || context.selection && input.value !== context.selection.value) {
16017
+ return;
16018
+ }
16019
+ input.focus({ preventScroll: true });
16020
+ if (context.selection) {
16021
+ input.setSelectionRange(context.selection.start, context.selection.end, context.selection.direction);
16022
+ }
16023
+ }
16024
+ }
16025
+ if (event.data.editCommand === "paste" && event.data.clipboardData) {
16026
+ pasteHostClipboard(event.data.clipboardData);
16027
+ } else if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
15937
16028
  document.execCommand(event.data.editCommand);
15938
16029
  }
15939
16030
  clipboard.receive(event.data.clipboard);
@@ -1044,6 +1044,30 @@ main {
1044
1044
  height: 100%;
1045
1045
  object-fit: cover;
1046
1046
  }
1047
+ .attachment-image {
1048
+ position: relative;
1049
+ padding: 0;
1050
+ border: 0;
1051
+ background: transparent;
1052
+ }
1053
+ .attachment-image .attachment-preview {
1054
+ width: 88px;
1055
+ height: 88px;
1056
+ background: transparent;
1057
+ }
1058
+ .message .attachment-image .attachment-preview {
1059
+ width: 120px;
1060
+ height: 120px;
1061
+ }
1062
+ .attachment-image .attachment-preview img {
1063
+ object-fit: contain;
1064
+ }
1065
+ .attachment-image > .icon-button {
1066
+ position: absolute;
1067
+ top: 0;
1068
+ right: 0;
1069
+ background: var(--vscode-editor-background);
1070
+ }
1047
1071
  #draft-attachments {
1048
1072
  padding: 0 16px;
1049
1073
  }
@@ -14897,14 +14897,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
14897
14897
  DocumentFragment,
14898
14898
  HTMLTemplateElement,
14899
14899
  Node: Node2,
14900
- Element,
14900
+ Element: Element2,
14901
14901
  NodeFilter: NodeFilter2,
14902
14902
  NamedNodeMap = window2.NamedNodeMap || window2.MozNamedAttrMap,
14903
14903
  HTMLFormElement,
14904
14904
  DOMParser,
14905
14905
  trustedTypes
14906
14906
  } = window2;
14907
- const ElementPrototype = Element.prototype;
14907
+ const ElementPrototype = Element2.prototype;
14908
14908
  const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
14909
14909
  const remove = lookupGetter(ElementPrototype, "remove");
14910
14910
  const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
@@ -15358,7 +15358,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
15358
15358
  _forceRemove(currentNode);
15359
15359
  return true;
15360
15360
  }
15361
- if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
15361
+ if (currentNode instanceof Element2 && !_checkValidNamespace(currentNode)) {
15362
15362
  _forceRemove(currentNode);
15363
15363
  return true;
15364
15364
  }
@@ -17835,6 +17835,28 @@ ${state.user?.avatarUrl ?? ""}`;
17835
17835
  }
17836
17836
  };
17837
17837
 
17838
+ // src/web/ui/edit-commands.ts
17839
+ function pasteHostClipboard(clipboard) {
17840
+ if (typeof clipboard.text !== "string" || clipboard.image !== void 0 && !ArrayBuffer.isView(clipboard.image)) {
17841
+ return;
17842
+ }
17843
+ const target = document.activeElement;
17844
+ if (!(target instanceof HTMLElement) || !target.matches("textarea, input, [contenteditable=true]") || target.matches(":disabled, [readonly]")) {
17845
+ return;
17846
+ }
17847
+ const transfer = new DataTransfer();
17848
+ transfer.setData("text/plain", clipboard.text);
17849
+ if (clipboard.image && clipboard.image.byteLength) {
17850
+ const image = new Uint8Array(clipboard.image.buffer, clipboard.image.byteOffset, clipboard.image.byteLength);
17851
+ transfer.items.add(new File([new Uint8Array(image)], "clipboard.png", { type: "image/png" }));
17852
+ }
17853
+ const event = new ClipboardEvent("paste", { bubbles: true, cancelable: true, clipboardData: transfer });
17854
+ target.dispatchEvent(event);
17855
+ if (!event.defaultPrevented && clipboard.text) {
17856
+ document.execCommand("insertText", false, clipboard.text);
17857
+ }
17858
+ }
17859
+
17838
17860
  // src/web/ui/host.ts
17839
17861
  function acquireWorkflowHost(options = {}) {
17840
17862
  const embedded = globalThis.acquireVsCodeApi;
@@ -17856,13 +17878,62 @@ ${state.user?.avatarUrl ?? ""}`;
17856
17878
  window.parent.postMessage(message, "*");
17857
17879
  }
17858
17880
  });
17859
- let resourceHost = false;
17881
+ let resourceHost = false, editHost = false, nativePasteHost = false;
17882
+ let contextInput, lastInput;
17883
+ const captureInput = (input) => {
17884
+ const field = input;
17885
+ return { element: input, selection: typeof field.selectionStart === "number" && typeof field.selectionEnd === "number" ? { start: field.selectionStart, end: field.selectionEnd, direction: field.selectionDirection ?? "none", value: field.value } : void 0 };
17886
+ };
17887
+ const rememberInput = () => {
17888
+ const input = document.activeElement;
17889
+ if (input instanceof HTMLElement && input.matches("textarea, input, [contenteditable=true]")) {
17890
+ lastInput = captureInput(input);
17891
+ }
17892
+ };
17860
17893
  const clipboard = new ClipboardBridge(
17861
17894
  (message) => window.parent.postMessage(message, "*"),
17862
17895
  (text3) => navigator.clipboard.writeText(text3),
17863
17896
  window.parent !== window && document.body.dataset.accountHost === "true"
17864
17897
  );
17865
17898
  addEventListener("pagehide", () => clipboard.dispose());
17899
+ addEventListener("keydown", (event) => {
17900
+ if (!editHost || !nativePasteHost || event.defaultPrevented || event.key.toLowerCase() !== "v" || !(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey || !(event.target instanceof Element) || !event.target.closest("textarea, input, [contenteditable=true]")) {
17901
+ return;
17902
+ }
17903
+ event.preventDefault();
17904
+ contextInput = void 0;
17905
+ rememberInput();
17906
+ window.parent.postMessage({ type: "workflow-edit", version: 1, command: "paste" }, "*");
17907
+ });
17908
+ addEventListener("contextmenu", (event) => {
17909
+ if (!editHost || event.defaultPrevented || !(event.target instanceof Element)) {
17910
+ return;
17911
+ }
17912
+ const input = event.target.closest("textarea, input, [contenteditable=true]");
17913
+ if (!input) {
17914
+ return;
17915
+ }
17916
+ event.preventDefault();
17917
+ input.focus({ preventScroll: true });
17918
+ contextInput = lastInput = captureInput(input);
17919
+ window.parent.postMessage({ type: "workflow-contextmenu", version: 1, x: event.clientX, y: event.clientY }, "*");
17920
+ });
17921
+ addEventListener("focusin", (event) => {
17922
+ if (event.target instanceof Element && event.target !== contextInput?.element && event.target.matches("textarea, input, [contenteditable=true]")) {
17923
+ contextInput = void 0;
17924
+ }
17925
+ rememberInput();
17926
+ });
17927
+ addEventListener("input", rememberInput);
17928
+ addEventListener("selectionchange", rememberInput, true);
17929
+ addEventListener("pointerdown", (event) => {
17930
+ if (event.button !== 2) {
17931
+ contextInput = void 0;
17932
+ }
17933
+ if (event.target instanceof Element && !event.target.closest("textarea, input, [contenteditable=true]")) {
17934
+ lastInput = void 0;
17935
+ }
17936
+ });
17866
17937
  const connection = new BrowserConnection((message) => {
17867
17938
  if (message.type === "state" && message.account) {
17868
17939
  accountPanel.update(message.account);
@@ -17887,17 +17958,37 @@ ${state.user?.avatarUrl ?? ""}`;
17887
17958
  }
17888
17959
  if (event.data.clipboardVersion !== void 0) {
17889
17960
  clipboard.enable(event.data.clipboardVersion);
17890
- if (event.data.clipboardVersion === 1) {
17961
+ editHost = event.data.clipboardVersion === 1;
17962
+ if (editHost) {
17891
17963
  window.parent.postMessage({ type: "workflow-edit", version: 1 }, "*");
17892
17964
  }
17893
17965
  }
17894
17966
  if (event.data.resourceVersion === 1) {
17895
17967
  resourceHost = true;
17896
17968
  }
17969
+ if (event.data.nativePasteVersion !== void 0) {
17970
+ nativePasteHost = event.data.nativePasteVersion === 1;
17971
+ }
17897
17972
  if (event.data.resourceError) {
17898
17973
  emit(event.data.resourceError);
17899
17974
  }
17900
- if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
17975
+ if ((event.data.restoreFocus === true || event.data.clipboardData && document.activeElement === document.body) && ["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
17976
+ const context = contextInput ?? lastInput;
17977
+ contextInput = void 0;
17978
+ if (context) {
17979
+ const input = context.element;
17980
+ if (!input.isConnected || context.selection && input.value !== context.selection.value) {
17981
+ return;
17982
+ }
17983
+ input.focus({ preventScroll: true });
17984
+ if (context.selection) {
17985
+ input.setSelectionRange(context.selection.start, context.selection.end, context.selection.direction);
17986
+ }
17987
+ }
17988
+ }
17989
+ if (event.data.editCommand === "paste" && event.data.clipboardData) {
17990
+ pasteHostClipboard(event.data.clipboardData);
17991
+ } else if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
17901
17992
  document.execCommand(event.data.editCommand);
17902
17993
  }
17903
17994
  clipboard.receive(event.data.clipboard);
@@ -18636,31 +18727,36 @@ ${state.user?.avatarUrl ?? ""}`;
18636
18727
  container.replaceChildren();
18637
18728
  container.hidden = !attachments.length;
18638
18729
  for (const file of attachments) {
18730
+ const isImage = file.kind === "image";
18639
18731
  const item = document.createElement("div");
18640
- item.className = "attachment";
18732
+ item.className = `attachment${isImage ? " attachment-image" : ""}`;
18641
18733
  const preview = document.createElement("button");
18642
18734
  preview.type = "button";
18643
18735
  preview.className = "attachment-preview";
18644
- preview.title = file.name;
18645
- if (file.kind === "image" && file.previewUrl) {
18736
+ preview.title = isImage ? t2("Image") : file.name;
18737
+ preview.setAttribute("aria-label", preview.title);
18738
+ if (isImage && file.previewUrl) {
18646
18739
  const image = document.createElement("img");
18647
18740
  image.src = file.previewUrl;
18648
- image.alt = file.name;
18741
+ image.alt = t2("Image");
18649
18742
  preview.append(image);
18650
18743
  } else {
18651
18744
  preview.innerHTML = iconHtml(file.mimeType.startsWith("audio/") ? "unmute" : file.mimeType.startsWith("video/") ? "device-camera-video" : "file");
18652
18745
  }
18653
18746
  preview.addEventListener("click", () => {
18654
- if (file.kind === "image" && file.previewUrl) {
18655
- dialogs.image(file.previewUrl, file.name);
18747
+ if (isImage && file.previewUrl) {
18748
+ dialogs.image(file.previewUrl, t2("Image"));
18656
18749
  } else {
18657
18750
  post({ type: "open-file", id: file.id });
18658
18751
  }
18659
18752
  });
18660
- const name = document.createElement("span");
18661
- name.textContent = file.name;
18662
- name.title = file.name;
18663
- item.append(preview, name);
18753
+ item.append(preview);
18754
+ if (!isImage) {
18755
+ const name = document.createElement("span");
18756
+ name.textContent = file.name;
18757
+ name.title = file.name;
18758
+ item.append(name);
18759
+ }
18664
18760
  if (removable) {
18665
18761
  item.append(iconButton("close", t2("Remove attachment"), () => {
18666
18762
  draftFiles = draftFiles.filter((entry) => entry.id !== file.id);
@@ -1044,6 +1044,30 @@ main {
1044
1044
  height: 100%;
1045
1045
  object-fit: cover;
1046
1046
  }
1047
+ .attachment-image {
1048
+ position: relative;
1049
+ padding: 0;
1050
+ border: 0;
1051
+ background: transparent;
1052
+ }
1053
+ .attachment-image .attachment-preview {
1054
+ width: 88px;
1055
+ height: 88px;
1056
+ background: transparent;
1057
+ }
1058
+ .message .attachment-image .attachment-preview {
1059
+ width: 120px;
1060
+ height: 120px;
1061
+ }
1062
+ .attachment-image .attachment-preview img {
1063
+ object-fit: contain;
1064
+ }
1065
+ .attachment-image > .icon-button {
1066
+ position: absolute;
1067
+ top: 0;
1068
+ right: 0;
1069
+ background: var(--vscode-editor-background);
1070
+ }
1047
1071
  #draft-attachments {
1048
1072
  padding: 0 16px;
1049
1073
  }
@@ -17930,14 +17930,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
17930
17930
  DocumentFragment,
17931
17931
  HTMLTemplateElement,
17932
17932
  Node,
17933
- Element,
17933
+ Element: Element2,
17934
17934
  NodeFilter,
17935
17935
  NamedNodeMap = window2.NamedNodeMap || window2.MozNamedAttrMap,
17936
17936
  HTMLFormElement,
17937
17937
  DOMParser,
17938
17938
  trustedTypes
17939
17939
  } = window2;
17940
- const ElementPrototype = Element.prototype;
17940
+ const ElementPrototype = Element2.prototype;
17941
17941
  const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
17942
17942
  const remove = lookupGetter(ElementPrototype, "remove");
17943
17943
  const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
@@ -18391,7 +18391,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
18391
18391
  _forceRemove(currentNode);
18392
18392
  return true;
18393
18393
  }
18394
- if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
18394
+ if (currentNode instanceof Element2 && !_checkValidNamespace(currentNode)) {
18395
18395
  _forceRemove(currentNode);
18396
18396
  return true;
18397
18397
  }
@@ -19415,6 +19415,28 @@ ${state2.user?.avatarUrl ?? ""}`;
19415
19415
  }
19416
19416
  };
19417
19417
 
19418
+ // src/web/ui/edit-commands.ts
19419
+ function pasteHostClipboard(clipboard) {
19420
+ if (typeof clipboard.text !== "string" || clipboard.image !== void 0 && !ArrayBuffer.isView(clipboard.image)) {
19421
+ return;
19422
+ }
19423
+ const target = document.activeElement;
19424
+ if (!(target instanceof HTMLElement) || !target.matches("textarea, input, [contenteditable=true]") || target.matches(":disabled, [readonly]")) {
19425
+ return;
19426
+ }
19427
+ const transfer = new DataTransfer();
19428
+ transfer.setData("text/plain", clipboard.text);
19429
+ if (clipboard.image && clipboard.image.byteLength) {
19430
+ const image = new Uint8Array(clipboard.image.buffer, clipboard.image.byteOffset, clipboard.image.byteLength);
19431
+ transfer.items.add(new File([new Uint8Array(image)], "clipboard.png", { type: "image/png" }));
19432
+ }
19433
+ const event = new ClipboardEvent("paste", { bubbles: true, cancelable: true, clipboardData: transfer });
19434
+ target.dispatchEvent(event);
19435
+ if (!event.defaultPrevented && clipboard.text) {
19436
+ document.execCommand("insertText", false, clipboard.text);
19437
+ }
19438
+ }
19439
+
19418
19440
  // src/web/ui/host.ts
19419
19441
  function acquireWorkflowHost(options = {}) {
19420
19442
  const embedded = globalThis.acquireVsCodeApi;
@@ -19436,13 +19458,62 @@ ${state2.user?.avatarUrl ?? ""}`;
19436
19458
  window.parent.postMessage(message, "*");
19437
19459
  }
19438
19460
  });
19439
- let resourceHost = false;
19461
+ let resourceHost = false, editHost = false, nativePasteHost = false;
19462
+ let contextInput, lastInput;
19463
+ const captureInput = (input) => {
19464
+ const field = input;
19465
+ return { element: input, selection: typeof field.selectionStart === "number" && typeof field.selectionEnd === "number" ? { start: field.selectionStart, end: field.selectionEnd, direction: field.selectionDirection ?? "none", value: field.value } : void 0 };
19466
+ };
19467
+ const rememberInput = () => {
19468
+ const input = document.activeElement;
19469
+ if (input instanceof HTMLElement && input.matches("textarea, input, [contenteditable=true]")) {
19470
+ lastInput = captureInput(input);
19471
+ }
19472
+ };
19440
19473
  const clipboard = new ClipboardBridge(
19441
19474
  (message) => window.parent.postMessage(message, "*"),
19442
19475
  (text3) => navigator.clipboard.writeText(text3),
19443
19476
  window.parent !== window && document.body.dataset.accountHost === "true"
19444
19477
  );
19445
19478
  addEventListener("pagehide", () => clipboard.dispose());
19479
+ addEventListener("keydown", (event) => {
19480
+ if (!editHost || !nativePasteHost || event.defaultPrevented || event.key.toLowerCase() !== "v" || !(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey || !(event.target instanceof Element) || !event.target.closest("textarea, input, [contenteditable=true]")) {
19481
+ return;
19482
+ }
19483
+ event.preventDefault();
19484
+ contextInput = void 0;
19485
+ rememberInput();
19486
+ window.parent.postMessage({ type: "workflow-edit", version: 1, command: "paste" }, "*");
19487
+ });
19488
+ addEventListener("contextmenu", (event) => {
19489
+ if (!editHost || event.defaultPrevented || !(event.target instanceof Element)) {
19490
+ return;
19491
+ }
19492
+ const input = event.target.closest("textarea, input, [contenteditable=true]");
19493
+ if (!input) {
19494
+ return;
19495
+ }
19496
+ event.preventDefault();
19497
+ input.focus({ preventScroll: true });
19498
+ contextInput = lastInput = captureInput(input);
19499
+ window.parent.postMessage({ type: "workflow-contextmenu", version: 1, x: event.clientX, y: event.clientY }, "*");
19500
+ });
19501
+ addEventListener("focusin", (event) => {
19502
+ if (event.target instanceof Element && event.target !== contextInput?.element && event.target.matches("textarea, input, [contenteditable=true]")) {
19503
+ contextInput = void 0;
19504
+ }
19505
+ rememberInput();
19506
+ });
19507
+ addEventListener("input", rememberInput);
19508
+ addEventListener("selectionchange", rememberInput, true);
19509
+ addEventListener("pointerdown", (event) => {
19510
+ if (event.button !== 2) {
19511
+ contextInput = void 0;
19512
+ }
19513
+ if (event.target instanceof Element && !event.target.closest("textarea, input, [contenteditable=true]")) {
19514
+ lastInput = void 0;
19515
+ }
19516
+ });
19446
19517
  const connection = new BrowserConnection((message) => {
19447
19518
  if (message.type === "state" && message.account) {
19448
19519
  accountPanel.update(message.account);
@@ -19467,17 +19538,37 @@ ${state2.user?.avatarUrl ?? ""}`;
19467
19538
  }
19468
19539
  if (event.data.clipboardVersion !== void 0) {
19469
19540
  clipboard.enable(event.data.clipboardVersion);
19470
- if (event.data.clipboardVersion === 1) {
19541
+ editHost = event.data.clipboardVersion === 1;
19542
+ if (editHost) {
19471
19543
  window.parent.postMessage({ type: "workflow-edit", version: 1 }, "*");
19472
19544
  }
19473
19545
  }
19474
19546
  if (event.data.resourceVersion === 1) {
19475
19547
  resourceHost = true;
19476
19548
  }
19549
+ if (event.data.nativePasteVersion !== void 0) {
19550
+ nativePasteHost = event.data.nativePasteVersion === 1;
19551
+ }
19477
19552
  if (event.data.resourceError) {
19478
19553
  emit(event.data.resourceError);
19479
19554
  }
19480
- if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
19555
+ if ((event.data.restoreFocus === true || event.data.clipboardData && document.activeElement === document.body) && ["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
19556
+ const context = contextInput ?? lastInput;
19557
+ contextInput = void 0;
19558
+ if (context) {
19559
+ const input = context.element;
19560
+ if (!input.isConnected || context.selection && input.value !== context.selection.value) {
19561
+ return;
19562
+ }
19563
+ input.focus({ preventScroll: true });
19564
+ if (context.selection) {
19565
+ input.setSelectionRange(context.selection.start, context.selection.end, context.selection.direction);
19566
+ }
19567
+ }
19568
+ }
19569
+ if (event.data.editCommand === "paste" && event.data.clipboardData) {
19570
+ pasteHostClipboard(event.data.clipboardData);
19571
+ } else if (["paste", "copy", "cut", "selectAll", "undo", "redo"].includes(event.data.editCommand)) {
19481
19572
  document.execCommand(event.data.editCommand);
19482
19573
  }
19483
19574
  clipboard.receive(event.data.clipboard);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workflow-code/cli",
3
- "version": "0.2.4-20261013006.codex-studio-integration",
3
+ "version": "0.2.4-20261013007.codex-studio-integration",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "workflow-code": "./dist/index.js"
@@ -40,8 +40,8 @@
40
40
  "@workflow-code/execution-targets": "0.1.0",
41
41
  "@workflow-code/i18n": "0.1.0",
42
42
  "@workflow-code/kanban-project": "0.1.0",
43
- "@workflow-code/project-dependencies": "0.1.0",
44
43
  "@workflow-code/openai-responses": "0.1.0",
44
+ "@workflow-code/project-dependencies": "0.1.0",
45
45
  "@workflow-code/project-info": "0.1.0",
46
46
  "@workflow-code/project-upload": "0.1.0",
47
47
  "@workflow-code/runtime-compatibility": "0.1.0",