@workflow-code/cli 0.2.4-20261012005.codex-studio-integration → 0.2.4-20261012007.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.
- package/dist/index.js +1 -1
- package/dist/web/kanban-workspace.css +76 -10
- package/dist/web/kanban-workspace.js +201 -10
- package/dist/web/resource-preview.css +2172 -0
- package/dist/web/resource-preview.js +16515 -0
- package/dist/web/worker.mjs +3 -3
- package/dist/web/workflow-ui.css +76 -10
- package/dist/web/workflow-ui.js +337 -31
- package/dist/web/workflow-workspace.css +76 -10
- package/dist/web/workflow-workspace.js +329 -29
- package/dist/{web-6SWHMU2A.js → web-ROA37F4H.js} +514 -167
- package/package.json +3 -3
package/dist/web/workflow-ui.js
CHANGED
|
@@ -12643,6 +12643,8 @@
|
|
|
12643
12643
|
"Configuration name": "\u914D\u7F6E\u540D\u79F0",
|
|
12644
12644
|
"Connecting to project": "\u6B63\u5728\u8FDE\u63A5\u9879\u76EE",
|
|
12645
12645
|
"Connection changed.": "\u8FDE\u63A5\u5DF2\u53D8\u66F4\u3002",
|
|
12646
|
+
"Copy timed out.": "\u590D\u5236\u8D85\u65F6\u3002",
|
|
12647
|
+
"Host clipboard is unavailable.": "\u5BBF\u4E3B\u526A\u8D34\u677F\u4E0D\u53EF\u7528\u3002",
|
|
12646
12648
|
"Connection interrupted": "\u8FDE\u63A5\u5DF2\u4E2D\u65AD",
|
|
12647
12649
|
"Connection interrupted.": "\u8FDE\u63A5\u5DF2\u4E2D\u65AD\u3002",
|
|
12648
12650
|
"Connection not verified": "\u8FDE\u63A5\u672A\u9A8C\u8BC1",
|
|
@@ -12883,7 +12885,33 @@
|
|
|
12883
12885
|
"Write file": "\u5199\u5165\u6587\u4EF6",
|
|
12884
12886
|
Yes: "\u662F",
|
|
12885
12887
|
"Zoom in": "\u653E\u5927",
|
|
12886
|
-
"Zoom out": "\u7F29\u5C0F"
|
|
12888
|
+
"Zoom out": "\u7F29\u5C0F",
|
|
12889
|
+
"Open resource": "\u6253\u5F00\u8D44\u6E90",
|
|
12890
|
+
"Show in conversation": "\u5728\u5BF9\u8BDD\u4E2D\u5C55\u793A",
|
|
12891
|
+
"Hide preview": "\u6536\u8D77\u9884\u89C8",
|
|
12892
|
+
"Open in new window": "\u5728\u65B0\u7A97\u53E3\u4E2D\u6253\u5F00",
|
|
12893
|
+
"Tool call details": "\u5DE5\u5177\u8C03\u7528\u8BE6\u60C5",
|
|
12894
|
+
"Please sign in to preview this server resource.": "\u8BF7\u767B\u5F55\u540E\u9884\u89C8\u670D\u52A1\u5668\u8D44\u6E90\u3002",
|
|
12895
|
+
"You do not have access to this resource.": "\u4F60\u6CA1\u6709\u6B64\u8D44\u6E90\u7684\u8BBF\u95EE\u6743\u9650\u3002",
|
|
12896
|
+
"The resource project is unavailable.": "\u8D44\u6E90\u6240\u5C5E\u9879\u76EE\u4E0D\u53EF\u7528\u3002",
|
|
12897
|
+
"The resource project is unavailable. Import or open the target project first.": "\u8D44\u6E90\u6240\u5C5E\u9879\u76EE\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5148\u5BFC\u5165\u6216\u6253\u5F00\u76EE\u6807\u9879\u76EE\u3002",
|
|
12898
|
+
"The project does not allow this storage location.": "\u9879\u76EE\u4E0D\u5141\u8BB8\u4F7F\u7528\u6B64\u5B58\u50A8\u4F4D\u7F6E\u3002",
|
|
12899
|
+
"This resource no longer exists.": "\u6B64\u8D44\u6E90\u5DF2\u4E0D\u5B58\u5728\u3002",
|
|
12900
|
+
"Server source files cannot be previewed by this card.": "\u6B64\u5361\u7247\u4E0D\u652F\u6301\u9884\u89C8\u670D\u52A1\u5668\u6E90\u7801\u6587\u4EF6\u3002",
|
|
12901
|
+
"File is outside this project.": "\u6587\u4EF6\u4E0D\u5728\u6B64\u9879\u76EE\u4E2D\u3002",
|
|
12902
|
+
"File preview exceeds 2 MiB.": "\u6587\u4EF6\u9884\u89C8\u5927\u5C0F\u8D85\u8FC7 2 MiB\u3002",
|
|
12903
|
+
"This project does not provide a Kanban preview.": "\u6B64\u9879\u76EE\u4E0D\u63D0\u4F9B\u770B\u677F\u9884\u89C8\u3002",
|
|
12904
|
+
"Invalid resource preview URL.": "\u8D44\u6E90\u9884\u89C8\u5730\u5740\u65E0\u6548\u3002",
|
|
12905
|
+
"This preview configuration no longer exists.": "\u6B64\u9884\u89C8\u914D\u7F6E\u5DF2\u4E0D\u5B58\u5728\u3002",
|
|
12906
|
+
"Resource access changed. Open the card again.": "\u8D44\u6E90\u8BBF\u95EE\u72B6\u6001\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5361\u7247\u3002",
|
|
12907
|
+
"This resource preview is read-only.": "\u6B64\u8D44\u6E90\u9884\u89C8\u4E3A\u53EA\u8BFB\u3002",
|
|
12908
|
+
"Invalid resource action.": "\u8D44\u6E90\u64CD\u4F5C\u65E0\u6548\u3002",
|
|
12909
|
+
"Run no longer exists.": "\u6B64\u8FD0\u884C\u5DF2\u4E0D\u5B58\u5728\u3002",
|
|
12910
|
+
"Conversation changed.": "\u4F1A\u8BDD\u5DF2\u53D8\u5316\u3002",
|
|
12911
|
+
"Unable to load this preview. Retry or open it separately.": "\u65E0\u6CD5\u52A0\u8F7D\u6B64\u9884\u89C8\uFF0C\u8BF7\u91CD\u8BD5\u6216\u5355\u72EC\u6253\u5F00\u3002",
|
|
12912
|
+
"Open in browser": "\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00",
|
|
12913
|
+
"No resources": "\u6682\u65E0\u8D44\u6E90",
|
|
12914
|
+
"Allow popups to open this resource in a new window.": "\u8BF7\u5141\u8BB8\u5F39\u51FA\u7A97\u53E3\u4EE5\u5355\u72EC\u6253\u5F00\u6B64\u8D44\u6E90\u3002"
|
|
12887
12915
|
};
|
|
12888
12916
|
|
|
12889
12917
|
// src/web/localization.ts
|
|
@@ -16138,7 +16166,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
16138
16166
|
// src/web/resource-cards.ts
|
|
16139
16167
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
16140
16168
|
var string = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
16141
|
-
function conversationResourceCards(items, projectId, conversationId) {
|
|
16169
|
+
function conversationResourceCards(items, projectId, conversationId, storageSource = "local") {
|
|
16142
16170
|
const cards = /* @__PURE__ */ new Map();
|
|
16143
16171
|
for (const [index, item] of items.entries()) {
|
|
16144
16172
|
if (!["agent-part", "opencode-part"].includes(String(item.metadata?.kind)) || item.metadata?.partType !== "tool") {
|
|
@@ -16201,6 +16229,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
16201
16229
|
if (!kind2) {
|
|
16202
16230
|
continue;
|
|
16203
16231
|
}
|
|
16232
|
+
if (kind2 === "kv" || kind2 === "knowledge") {
|
|
16233
|
+
target2.source = input.source ?? storageSource;
|
|
16234
|
+
}
|
|
16204
16235
|
descriptor = { kind: kind2, target: target2, title: record(output?.document)?.title };
|
|
16205
16236
|
}
|
|
16206
16237
|
const kind = descriptor.kind;
|
|
@@ -16209,7 +16240,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
16209
16240
|
}
|
|
16210
16241
|
const target = Object.fromEntries(Object.entries(record(descriptor.target) ?? {}).filter((entry) => typeof entry[1] === "string" && entry[1].length < 8192));
|
|
16211
16242
|
if (target.source === "current") {
|
|
16212
|
-
target.source = "local";
|
|
16243
|
+
target.source = kind === "kv" || kind === "knowledge" ? storageSource : "local";
|
|
16213
16244
|
target.projectId = projectId;
|
|
16214
16245
|
}
|
|
16215
16246
|
if (target.source && !["local", "server"].includes(target.source)) {
|
|
@@ -16235,8 +16266,18 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
16235
16266
|
}
|
|
16236
16267
|
}
|
|
16237
16268
|
const id = string(descriptor.cardId) ?? `${kind}:${JSON.stringify(target)}`;
|
|
16238
|
-
const title = (string(descriptor.title) ?? target.key ?? target.documentId ?? target.filePath ?? target.url ?? target.projectId ?? kind).slice(0, 200);
|
|
16239
|
-
|
|
16269
|
+
const title = (string(descriptor.title) ?? string(record(output?.document)?.title) ?? target.key ?? target.documentId ?? target.filePath ?? target.url ?? target.projectId ?? kind).slice(0, 200);
|
|
16270
|
+
const kanban = record(descriptor.kanban), values = record(kanban?.values);
|
|
16271
|
+
cards.set(id, {
|
|
16272
|
+
id,
|
|
16273
|
+
kind,
|
|
16274
|
+
title,
|
|
16275
|
+
target,
|
|
16276
|
+
itemId: item.id ?? String(index),
|
|
16277
|
+
...typeof descriptor.preview === "boolean" ? { preview: descriptor.preview } : {},
|
|
16278
|
+
...typeof descriptor.pinned === "boolean" ? { pinned: descriptor.pinned } : {},
|
|
16279
|
+
...kind === "kanban" && ["preview", "save"].includes(String(kanban?.mode)) && values && Object.keys(values).length <= 100 && Object.values(values).every((value) => typeof value === "string") ? { kanban: { mode: kanban.mode, values } } : {}
|
|
16280
|
+
});
|
|
16240
16281
|
}
|
|
16241
16282
|
return [...cards.values()];
|
|
16242
16283
|
}
|
|
@@ -16430,15 +16471,53 @@ ${JSON.stringify(output.details, null, 2)}` : "");
|
|
|
16430
16471
|
this.root = root;
|
|
16431
16472
|
this.options = options;
|
|
16432
16473
|
root.className = "message-output";
|
|
16474
|
+
window.addEventListener("message", this.resourceReply);
|
|
16475
|
+
this.resourceTheme.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
|
|
16433
16476
|
}
|
|
16434
16477
|
root;
|
|
16435
16478
|
options;
|
|
16436
16479
|
views = /* @__PURE__ */ new Map();
|
|
16437
16480
|
groups = /* @__PURE__ */ new Map();
|
|
16438
16481
|
activities = /* @__PURE__ */ new Map();
|
|
16439
|
-
|
|
16482
|
+
resourceTheme = new MutationObserver(() => this.syncResourceTheme());
|
|
16483
|
+
syncResourceTheme() {
|
|
16484
|
+
for (const frame of this.root.querySelectorAll(".resource-inline > iframe")) {
|
|
16485
|
+
frame.contentWindow?.postMessage({ type: "workflow-host", theme: document.documentElement.dataset.theme }, location.origin);
|
|
16486
|
+
}
|
|
16487
|
+
}
|
|
16488
|
+
resourceReply = (event) => {
|
|
16489
|
+
const reply = event.data;
|
|
16490
|
+
if (event.source !== null || !reply?.requestId) {
|
|
16491
|
+
return;
|
|
16492
|
+
}
|
|
16493
|
+
const card = Array.from(this.root.querySelectorAll(".resource-card")).find((card2) => card2.dataset.requestId === reply.requestId);
|
|
16494
|
+
if (!card) {
|
|
16495
|
+
return;
|
|
16496
|
+
}
|
|
16497
|
+
const preview = card.querySelector(".resource-inline");
|
|
16498
|
+
if (reply.type === "error") {
|
|
16499
|
+
preview.textContent = reply.message;
|
|
16500
|
+
preview.setAttribute("role", "alert");
|
|
16501
|
+
}
|
|
16502
|
+
if (reply.type === "resource-preview" && reply.action === "inline") {
|
|
16503
|
+
const frame = document.createElement("iframe");
|
|
16504
|
+
frame.title = card.querySelector(".resource-title").textContent ?? "";
|
|
16505
|
+
const address = new URL(reply.url, location.href);
|
|
16506
|
+
address.searchParams.set("resourcePresentation", "card");
|
|
16507
|
+
frame.src = address.href;
|
|
16508
|
+
frame.sandbox.add("allow-scripts", "allow-same-origin");
|
|
16509
|
+
frame.addEventListener("load", () => this.syncResourceTheme());
|
|
16510
|
+
preview.replaceChildren(frame);
|
|
16511
|
+
preview.removeAttribute("role");
|
|
16512
|
+
}
|
|
16513
|
+
};
|
|
16514
|
+
dispose() {
|
|
16515
|
+
window.removeEventListener("message", this.resourceReply);
|
|
16516
|
+
this.resourceTheme.disconnect();
|
|
16517
|
+
}
|
|
16518
|
+
update(message, projectId, conversationId, files, storageSource = "local") {
|
|
16440
16519
|
const items = message.items ?? [];
|
|
16441
|
-
const cards = conversationResourceCards(items, projectId, conversationId);
|
|
16520
|
+
const cards = conversationResourceCards(items, projectId, conversationId, storageSource);
|
|
16442
16521
|
const cardByItem = new Map(cards.map((card) => [card.itemId, card]));
|
|
16443
16522
|
const answers = [...new Map([...message.resolvedInputs ?? [], ...message.submittingInput ? [message.submittingInput] : []].map((answer) => [answer.requestId, answer])).values()];
|
|
16444
16523
|
const ordered = (message.timers ?? []).map((timer) => ({ key: `timer:${timer.timerId}`, timer }));
|
|
@@ -16458,14 +16537,18 @@ ${JSON.stringify(output.details, null, 2)}` : "");
|
|
|
16458
16537
|
const blocks = [];
|
|
16459
16538
|
for (const entry of ordered) {
|
|
16460
16539
|
const content = entry.item?.content;
|
|
16461
|
-
if (content?.tool === "workflow-ui_present_card" && !entry.card) {
|
|
16540
|
+
if (content?.tool === "workflow-ui_present_card" && content.status === "success" && !entry.card) {
|
|
16462
16541
|
continue;
|
|
16463
16542
|
}
|
|
16464
|
-
if (entry.item && content?.tool !== "workflow-ui_present_card") {
|
|
16543
|
+
if (entry.item && (content?.tool !== "workflow-ui_present_card" || content.status !== "success")) {
|
|
16465
16544
|
entry.activity = agentActivity(entry.item, message);
|
|
16466
16545
|
}
|
|
16467
|
-
if (entry.
|
|
16468
|
-
entry.card = conversationResourceCards([entry.item], projectId, conversationId)[0];
|
|
16546
|
+
if (entry.item && content?.tool !== "workflow-ui_present_card" && !entry.card) {
|
|
16547
|
+
entry.card = conversationResourceCards([entry.item], projectId, conversationId, storageSource)[0];
|
|
16548
|
+
}
|
|
16549
|
+
if (entry.card && entry.card.kind !== "file") {
|
|
16550
|
+
blocks.push({ key: `resource:${entry.key}`, card: entry.card, item: entry.item });
|
|
16551
|
+
continue;
|
|
16469
16552
|
}
|
|
16470
16553
|
if (entry.activity) {
|
|
16471
16554
|
const last = blocks.at(-1);
|
|
@@ -16492,7 +16575,7 @@ ${JSON.stringify(output.details, null, 2)}` : "");
|
|
|
16492
16575
|
view.signature = signature;
|
|
16493
16576
|
}
|
|
16494
16577
|
} else if (!view || view.signature !== signature) {
|
|
16495
|
-
const root = entry.answer ? this.answer(entry.answer, message.submittingInput?.requestId === entry.answer.requestId) : entry.timer ? this.timer(entry.timer) : activity ? this.activity(activity, entry.key, entry.card) : entry.card ? this.card(entry.card) : entry.item ? this.item(entry.item, files) : this.markdown(entry.text ?? "", files);
|
|
16578
|
+
const root = entry.answer ? this.answer(entry.answer, message.submittingInput?.requestId === entry.answer.requestId) : entry.timer ? this.timer(entry.timer) : activity ? this.activity(activity, entry.key, entry.card) : entry.card ? this.card(entry.card, entry.item) : entry.item ? this.item(entry.item, files) : this.markdown(entry.text ?? "", files);
|
|
16496
16579
|
if (view?.root instanceof HTMLDetailsElement && root instanceof HTMLDetailsElement) {
|
|
16497
16580
|
root.open = view.root.open;
|
|
16498
16581
|
}
|
|
@@ -16826,13 +16909,67 @@ ${JSON.stringify(output.details, null, 2)}` : "");
|
|
|
16826
16909
|
root.append(entry);
|
|
16827
16910
|
return root;
|
|
16828
16911
|
}
|
|
16829
|
-
card(card) {
|
|
16912
|
+
card(card, item) {
|
|
16913
|
+
const root = document.createElement("section");
|
|
16914
|
+
root.className = "resource-card";
|
|
16915
|
+
root.dataset.cardId = card.id;
|
|
16916
|
+
const row = document.createElement("div");
|
|
16917
|
+
row.className = "resource-card-row";
|
|
16830
16918
|
const button = document.createElement("button");
|
|
16831
|
-
button.className = "resource-
|
|
16832
|
-
button.title =
|
|
16833
|
-
button.innerHTML = `${iconHtml(card.kind === "browser" ? "globe" : card.kind === "file" ? "file" : card.kind === "kv" ? "database" : card.kind === "knowledge" ? "book" : "folder")}<span>${escapeHtml(card.title)}</span
|
|
16834
|
-
button.addEventListener("click", () => this.options.resource(card));
|
|
16835
|
-
|
|
16919
|
+
button.className = "resource-target";
|
|
16920
|
+
button.title = t2("Open resource");
|
|
16921
|
+
button.innerHTML = `${iconHtml(card.kind === "browser" ? "globe" : card.kind === "file" ? "file" : card.kind === "kv" ? "database" : card.kind === "knowledge" ? "book" : card.kind === "kanban" ? "layout" : "folder")}<span class="resource-title">${escapeHtml(card.title)}</span>`;
|
|
16922
|
+
button.addEventListener("click", () => this.options.resource(card, "open"));
|
|
16923
|
+
const preview = document.createElement("div");
|
|
16924
|
+
preview.className = "resource-inline";
|
|
16925
|
+
preview.hidden = true;
|
|
16926
|
+
const toggle = iconButton("eye", t2("Show in conversation"), () => {
|
|
16927
|
+
preview.hidden = !preview.hidden;
|
|
16928
|
+
toggle.setAttribute("aria-expanded", String(!preview.hidden));
|
|
16929
|
+
toggle.title = preview.hidden ? t2("Show in conversation") : t2("Hide preview");
|
|
16930
|
+
if (preview.hidden) {
|
|
16931
|
+
preview.replaceChildren();
|
|
16932
|
+
delete root.dataset.requestId;
|
|
16933
|
+
return;
|
|
16934
|
+
}
|
|
16935
|
+
const requestId = crypto.randomUUID();
|
|
16936
|
+
root.dataset.requestId = requestId;
|
|
16937
|
+
preview.textContent = t2("Loading...");
|
|
16938
|
+
preview.setAttribute("role", "status");
|
|
16939
|
+
this.options.resource(card, "inline", requestId);
|
|
16940
|
+
});
|
|
16941
|
+
toggle.setAttribute("aria-expanded", "false");
|
|
16942
|
+
toggle.dataset.action = "inline";
|
|
16943
|
+
const separate = iconButton("open-preview", t2("Open in new window"), () => this.options.resource(card, "window"));
|
|
16944
|
+
separate.dataset.action = "window";
|
|
16945
|
+
row.append(button, toggle, separate);
|
|
16946
|
+
root.append(row, preview);
|
|
16947
|
+
if (card.kind === "project" || card.kind === "kanban") {
|
|
16948
|
+
row.append(iconButton("folder-opened", t2("Open project"), () => this.options.resource(card, "project")));
|
|
16949
|
+
}
|
|
16950
|
+
if (item) {
|
|
16951
|
+
const details = document.createElement("div");
|
|
16952
|
+
details.className = "resource-call-details";
|
|
16953
|
+
details.hidden = true;
|
|
16954
|
+
const data = document.createElement("pre");
|
|
16955
|
+
data.textContent = JSON.stringify(item.content, null, 2);
|
|
16956
|
+
details.append(data);
|
|
16957
|
+
const inspect = iconButton("info", t2("Tool call details"), () => {
|
|
16958
|
+
details.hidden = !details.hidden;
|
|
16959
|
+
inspect.setAttribute("aria-expanded", String(!details.hidden));
|
|
16960
|
+
});
|
|
16961
|
+
inspect.setAttribute("aria-expanded", "false");
|
|
16962
|
+
row.append(inspect);
|
|
16963
|
+
root.append(details);
|
|
16964
|
+
}
|
|
16965
|
+
if (card.preview && ["project", "kanban", "browser"].includes(card.kind)) {
|
|
16966
|
+
queueMicrotask(() => {
|
|
16967
|
+
if (root.isConnected) {
|
|
16968
|
+
toggle.click();
|
|
16969
|
+
}
|
|
16970
|
+
});
|
|
16971
|
+
}
|
|
16972
|
+
return root;
|
|
16836
16973
|
}
|
|
16837
16974
|
};
|
|
16838
16975
|
|
|
@@ -17024,11 +17161,14 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17024
17161
|
var ConnectionError = class extends Error {
|
|
17025
17162
|
};
|
|
17026
17163
|
var BrowserConnection = class {
|
|
17027
|
-
constructor(emit) {
|
|
17164
|
+
constructor(emit, live = true) {
|
|
17028
17165
|
this.emit = emit;
|
|
17166
|
+
this.live = live;
|
|
17029
17167
|
if (this.token) {
|
|
17168
|
+
const query = new URLSearchParams(location.search);
|
|
17169
|
+
query.delete("session");
|
|
17030
17170
|
sessionStorage.setItem("workflow-web-session", this.token);
|
|
17031
|
-
history.replaceState(null, "", `${location.pathname}${
|
|
17171
|
+
history.replaceState(null, "", `${location.pathname}${query.size ? `?${query}` : ""}`);
|
|
17032
17172
|
}
|
|
17033
17173
|
queueMicrotask(() => {
|
|
17034
17174
|
this.banner = document.createElement("div");
|
|
@@ -17062,6 +17202,7 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17062
17202
|
});
|
|
17063
17203
|
}
|
|
17064
17204
|
emit;
|
|
17205
|
+
live;
|
|
17065
17206
|
clientId = crypto.randomUUID();
|
|
17066
17207
|
source;
|
|
17067
17208
|
banner;
|
|
@@ -17069,10 +17210,11 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17069
17210
|
handshake;
|
|
17070
17211
|
epoch = 0;
|
|
17071
17212
|
retry;
|
|
17213
|
+
snapshotTimer;
|
|
17072
17214
|
status = "connecting";
|
|
17073
17215
|
attempts = 0;
|
|
17074
17216
|
closed = false;
|
|
17075
|
-
token = new URLSearchParams(location.hash.slice(1)).get("session") ?? sessionStorage.getItem("workflow-web-session");
|
|
17217
|
+
token = new URLSearchParams(location.hash.slice(1)).get("session") ?? new URLSearchParams(location.search).get("session") ?? sessionStorage.getItem("workflow-web-session");
|
|
17076
17218
|
update(status) {
|
|
17077
17219
|
this.status = status;
|
|
17078
17220
|
this.emit({ type: "connection", status });
|
|
@@ -17095,6 +17237,7 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17095
17237
|
this.source?.close();
|
|
17096
17238
|
this.source = void 0;
|
|
17097
17239
|
clearTimeout(this.retry);
|
|
17240
|
+
clearTimeout(this.snapshotTimer);
|
|
17098
17241
|
}
|
|
17099
17242
|
interrupted() {
|
|
17100
17243
|
this.disconnect();
|
|
@@ -17148,6 +17291,10 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17148
17291
|
if (!session.ok) {
|
|
17149
17292
|
throw new Error("Cannot connect to the project.");
|
|
17150
17293
|
}
|
|
17294
|
+
if (!this.live) {
|
|
17295
|
+
await this.snapshot(epoch);
|
|
17296
|
+
return;
|
|
17297
|
+
}
|
|
17151
17298
|
const eventsUrl = new URL(this.fileUrl("/api/events"), location.href);
|
|
17152
17299
|
eventsUrl.searchParams.set("clientId", this.clientId);
|
|
17153
17300
|
const source = this.source = new EventSource(eventsUrl.href);
|
|
@@ -17184,6 +17331,39 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17184
17331
|
});
|
|
17185
17332
|
return this.connecting;
|
|
17186
17333
|
}
|
|
17334
|
+
async snapshot(epoch) {
|
|
17335
|
+
if (epoch !== this.epoch || this.closed) {
|
|
17336
|
+
return;
|
|
17337
|
+
}
|
|
17338
|
+
const response = await fetch("/api/resource-state", { headers: this.headers(), signal: AbortSignal.timeout(1e4) });
|
|
17339
|
+
if (epoch !== this.epoch || this.closed) {
|
|
17340
|
+
return;
|
|
17341
|
+
}
|
|
17342
|
+
if (response.status === 401) {
|
|
17343
|
+
this.disconnect();
|
|
17344
|
+
this.update("expired");
|
|
17345
|
+
return;
|
|
17346
|
+
}
|
|
17347
|
+
if (!response.ok) {
|
|
17348
|
+
throw new Error("Cannot connect to the project.");
|
|
17349
|
+
}
|
|
17350
|
+
const state = await response.json();
|
|
17351
|
+
if (epoch !== this.epoch || this.closed) {
|
|
17352
|
+
return;
|
|
17353
|
+
}
|
|
17354
|
+
if (this.status !== "connected") {
|
|
17355
|
+
this.attempts = 0;
|
|
17356
|
+
this.update("connected");
|
|
17357
|
+
}
|
|
17358
|
+
this.emit(state);
|
|
17359
|
+
this.snapshotTimer = setTimeout(() => {
|
|
17360
|
+
void this.snapshot(epoch).catch(() => {
|
|
17361
|
+
if (epoch === this.epoch && !this.closed) {
|
|
17362
|
+
this.interrupted();
|
|
17363
|
+
}
|
|
17364
|
+
});
|
|
17365
|
+
}, 5e3);
|
|
17366
|
+
}
|
|
17187
17367
|
async request(message) {
|
|
17188
17368
|
await this.connecting;
|
|
17189
17369
|
if (this.status !== "connected") {
|
|
@@ -17229,7 +17409,12 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17229
17409
|
return this.token ? { Authorization: `Bearer ${this.token}` } : {};
|
|
17230
17410
|
}
|
|
17231
17411
|
fileUrl(path) {
|
|
17232
|
-
|
|
17412
|
+
if (!this.token) {
|
|
17413
|
+
return path;
|
|
17414
|
+
}
|
|
17415
|
+
const url = new URL(path, location.href);
|
|
17416
|
+
url.searchParams.set("session", this.token);
|
|
17417
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
17233
17418
|
}
|
|
17234
17419
|
publicFiles(value) {
|
|
17235
17420
|
if (Array.isArray(value)) {
|
|
@@ -17386,8 +17571,71 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17386
17571
|
}
|
|
17387
17572
|
};
|
|
17388
17573
|
|
|
17574
|
+
// src/web/ui/clipboard-bridge.ts
|
|
17575
|
+
var ClipboardBridge = class {
|
|
17576
|
+
constructor(send, browserWrite, requiresHost = false) {
|
|
17577
|
+
this.send = send;
|
|
17578
|
+
this.browserWrite = browserWrite;
|
|
17579
|
+
this.requiresHost = requiresHost;
|
|
17580
|
+
}
|
|
17581
|
+
send;
|
|
17582
|
+
browserWrite;
|
|
17583
|
+
requiresHost;
|
|
17584
|
+
enabled = false;
|
|
17585
|
+
pending = /* @__PURE__ */ new Map();
|
|
17586
|
+
enable(version) {
|
|
17587
|
+
this.enabled = version === 1;
|
|
17588
|
+
}
|
|
17589
|
+
async writeText(text3) {
|
|
17590
|
+
if (!this.enabled) {
|
|
17591
|
+
if (this.requiresHost) {
|
|
17592
|
+
throw new Error(t2("Host clipboard is unavailable."));
|
|
17593
|
+
}
|
|
17594
|
+
return this.browserWrite(text3);
|
|
17595
|
+
}
|
|
17596
|
+
const requestId = crypto.randomUUID();
|
|
17597
|
+
return new Promise((resolve, reject) => {
|
|
17598
|
+
const timer = setTimeout(() => {
|
|
17599
|
+
this.pending.delete(requestId);
|
|
17600
|
+
reject(new Error(t2("Copy timed out.")));
|
|
17601
|
+
}, 1e4);
|
|
17602
|
+
this.pending.set(requestId, { resolve, reject, timer });
|
|
17603
|
+
try {
|
|
17604
|
+
this.send({ type: "workflow-clipboard", version: 1, command: "writeText", requestId, text: text3 });
|
|
17605
|
+
} catch (error) {
|
|
17606
|
+
clearTimeout(timer);
|
|
17607
|
+
this.pending.delete(requestId);
|
|
17608
|
+
reject(error);
|
|
17609
|
+
}
|
|
17610
|
+
});
|
|
17611
|
+
}
|
|
17612
|
+
receive(reply) {
|
|
17613
|
+
if (reply?.version !== 1 || typeof reply.requestId !== "string" || typeof reply.ok !== "boolean" || reply.error !== void 0 && typeof reply.error !== "string") {
|
|
17614
|
+
return;
|
|
17615
|
+
}
|
|
17616
|
+
const pending = this.pending.get(reply.requestId);
|
|
17617
|
+
if (!pending) {
|
|
17618
|
+
return;
|
|
17619
|
+
}
|
|
17620
|
+
this.pending.delete(reply.requestId);
|
|
17621
|
+
clearTimeout(pending.timer);
|
|
17622
|
+
if (reply.ok) {
|
|
17623
|
+
pending.resolve();
|
|
17624
|
+
} else {
|
|
17625
|
+
pending.reject(new Error(reply.error || t2("Host clipboard is unavailable.")));
|
|
17626
|
+
}
|
|
17627
|
+
}
|
|
17628
|
+
dispose() {
|
|
17629
|
+
for (const pending of this.pending.values()) {
|
|
17630
|
+
clearTimeout(pending.timer);
|
|
17631
|
+
pending.reject(new Error(t2("Connection changed.")));
|
|
17632
|
+
}
|
|
17633
|
+
this.pending.clear();
|
|
17634
|
+
}
|
|
17635
|
+
};
|
|
17636
|
+
|
|
17389
17637
|
// src/web/ui/host.ts
|
|
17390
|
-
function acquireWorkflowHost() {
|
|
17638
|
+
function acquireWorkflowHost(options = {}) {
|
|
17391
17639
|
const embedded = globalThis.acquireVsCodeApi;
|
|
17392
17640
|
if (embedded) {
|
|
17393
17641
|
return embedded();
|
|
@@ -17407,13 +17655,20 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17407
17655
|
window.parent.postMessage(message, "*");
|
|
17408
17656
|
}
|
|
17409
17657
|
});
|
|
17658
|
+
let resourceHost = false;
|
|
17659
|
+
const clipboard = new ClipboardBridge(
|
|
17660
|
+
(message) => window.parent.postMessage(message, "*"),
|
|
17661
|
+
(text3) => navigator.clipboard.writeText(text3),
|
|
17662
|
+
window.parent !== window && document.body.dataset.accountHost === "true"
|
|
17663
|
+
);
|
|
17664
|
+
addEventListener("pagehide", () => clipboard.dispose());
|
|
17410
17665
|
const connection = new BrowserConnection((message) => {
|
|
17411
17666
|
if (message.type === "state" && message.account) {
|
|
17412
17667
|
accountPanel.update(message.account);
|
|
17413
17668
|
}
|
|
17414
17669
|
trace.receive(message);
|
|
17415
17670
|
emit(message);
|
|
17416
|
-
});
|
|
17671
|
+
}, options.live);
|
|
17417
17672
|
const request = async (message) => {
|
|
17418
17673
|
for (const entry of await connection.request(message)) {
|
|
17419
17674
|
handleReply(entry);
|
|
@@ -17429,6 +17684,16 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17429
17684
|
if (event.data.traceVersion !== void 0) {
|
|
17430
17685
|
trace.enable(event.data.traceVersion);
|
|
17431
17686
|
}
|
|
17687
|
+
if (event.data.clipboardVersion !== void 0) {
|
|
17688
|
+
clipboard.enable(event.data.clipboardVersion);
|
|
17689
|
+
}
|
|
17690
|
+
if (event.data.resourceVersion === 1) {
|
|
17691
|
+
resourceHost = true;
|
|
17692
|
+
}
|
|
17693
|
+
if (event.data.resourceError) {
|
|
17694
|
+
emit(event.data.resourceError);
|
|
17695
|
+
}
|
|
17696
|
+
clipboard.receive(event.data.clipboard);
|
|
17432
17697
|
const traceCommand = trace.command(event.data.traceCommand);
|
|
17433
17698
|
if (traceCommand) {
|
|
17434
17699
|
void request(traceCommand).catch((error) => trace.receive({ type: "trace-run", runId: traceCommand.id, error: error.message }));
|
|
@@ -17445,7 +17710,14 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17445
17710
|
}
|
|
17446
17711
|
return;
|
|
17447
17712
|
}
|
|
17448
|
-
if (reply.type === "
|
|
17713
|
+
if (reply.type === "resource-preview") {
|
|
17714
|
+
reply.url = connection.fileUrl(reply.url);
|
|
17715
|
+
if (reply.action === "inline") {
|
|
17716
|
+
emit(reply);
|
|
17717
|
+
} else {
|
|
17718
|
+
window.open(reply.url, "_blank", "noopener");
|
|
17719
|
+
}
|
|
17720
|
+
} else if (reply.type === "download") {
|
|
17449
17721
|
const url = URL.createObjectURL(new Blob([reply.content], { type: reply.mimeType ?? "application/json" }));
|
|
17450
17722
|
const link = document.createElement("a");
|
|
17451
17723
|
link.href = url;
|
|
@@ -17513,6 +17785,29 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17513
17785
|
if (message.type === "ready") {
|
|
17514
17786
|
return;
|
|
17515
17787
|
}
|
|
17788
|
+
if (message.type === "resource" && message.action !== "inline" && resourceHost) {
|
|
17789
|
+
window.parent.postMessage({ type: "workflow-resource", version: 1, request: message }, "*");
|
|
17790
|
+
return;
|
|
17791
|
+
}
|
|
17792
|
+
if (message.type === "resource" && message.action !== "inline") {
|
|
17793
|
+
const popup = window.open("", "_blank");
|
|
17794
|
+
try {
|
|
17795
|
+
const reply = (await connection.request(message)).find((reply2) => reply2.type === "resource-preview");
|
|
17796
|
+
if (reply && popup) {
|
|
17797
|
+
popup.opener = null;
|
|
17798
|
+
popup.location.href = connection.fileUrl(reply.url);
|
|
17799
|
+
} else {
|
|
17800
|
+
popup?.close();
|
|
17801
|
+
if (reply) {
|
|
17802
|
+
emit({ type: "error", message: t2("Allow popups to open this resource in a new window.") });
|
|
17803
|
+
}
|
|
17804
|
+
}
|
|
17805
|
+
} catch (error) {
|
|
17806
|
+
popup?.close();
|
|
17807
|
+
emit({ type: "error", requestId: message.requestId, message: error.message });
|
|
17808
|
+
}
|
|
17809
|
+
return;
|
|
17810
|
+
}
|
|
17516
17811
|
if (message.type === "trace") {
|
|
17517
17812
|
if (trace.open(message)) {
|
|
17518
17813
|
return;
|
|
@@ -17522,8 +17817,13 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
17522
17817
|
}
|
|
17523
17818
|
}
|
|
17524
17819
|
if (message.type === "copy") {
|
|
17525
|
-
|
|
17526
|
-
|
|
17820
|
+
try {
|
|
17821
|
+
await clipboard.writeText(message.text);
|
|
17822
|
+
} catch (error) {
|
|
17823
|
+
emit({ type: "error", message: error.message });
|
|
17824
|
+
return false;
|
|
17825
|
+
}
|
|
17826
|
+
return true;
|
|
17527
17827
|
}
|
|
17528
17828
|
if (message.type === "attach") {
|
|
17529
17829
|
chooseFiles(message);
|
|
@@ -18249,8 +18549,10 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
18249
18549
|
error.textContent = message;
|
|
18250
18550
|
error.hidden = false;
|
|
18251
18551
|
}
|
|
18252
|
-
function copy2(text3, button) {
|
|
18253
|
-
vscode.postMessage({ type: "copy", text: text3 })
|
|
18552
|
+
async function copy2(text3, button) {
|
|
18553
|
+
if (await vscode.postMessage({ type: "copy", text: text3 }) === false) {
|
|
18554
|
+
return;
|
|
18555
|
+
}
|
|
18254
18556
|
button.innerHTML = iconHtml("check");
|
|
18255
18557
|
button.title = t2("Copied");
|
|
18256
18558
|
setTimeout(() => {
|
|
@@ -18285,7 +18587,7 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
18285
18587
|
plan: (text3) => dialogs.plan(text3),
|
|
18286
18588
|
file: (id) => post({ type: "open-file", id }),
|
|
18287
18589
|
image: (src, title) => dialogs.image(src, title),
|
|
18288
|
-
resource: (card) => post({ type: "resource", messageId: view.message.id, cardId: card.id })
|
|
18590
|
+
resource: (card, action, requestId2) => post({ type: "resource", messageId: view.message.id, cardId: card.id, action, requestId: requestId2 })
|
|
18289
18591
|
});
|
|
18290
18592
|
const actions = root.querySelector(".message-actions");
|
|
18291
18593
|
actions.prepend(iconButton("history", t2("Trace"), () => post({ type: "trace", messageId: view.message.id, runId: view.message.runId })));
|
|
@@ -18316,7 +18618,7 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
18316
18618
|
if (message.role === "user") {
|
|
18317
18619
|
view.content.textContent = message.content;
|
|
18318
18620
|
} else {
|
|
18319
|
-
view.output.update(message, state.project.id, state.activeId, (currentSession()?.messages ?? []).flatMap((entry) => [...entry.files ?? [], ...entry.attachments ?? []]));
|
|
18621
|
+
view.output.update(message, state.project.id, state.activeId, (currentSession()?.messages ?? []).flatMap((entry) => [...entry.files ?? [], ...entry.attachments ?? []]), state.project.projectInfo?.dataStorage?.mode === "server" ? "server" : "local");
|
|
18320
18622
|
}
|
|
18321
18623
|
view.error.textContent = message.error ?? "";
|
|
18322
18624
|
view.error.hidden = !message.error;
|
|
@@ -18407,6 +18709,9 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
18407
18709
|
draftFiles = session.draft?.attachments ?? [];
|
|
18408
18710
|
editingQueueId = session.draft?.editingQueueId;
|
|
18409
18711
|
renderedSession = next.activeId;
|
|
18712
|
+
for (const view of messages.values()) {
|
|
18713
|
+
view.output?.dispose();
|
|
18714
|
+
}
|
|
18410
18715
|
messages.clear();
|
|
18411
18716
|
transcript.replaceChildren();
|
|
18412
18717
|
document.querySelector("#error").hidden = true;
|
|
@@ -18449,6 +18754,7 @@ ${state.user?.avatarUrl ?? ""}`;
|
|
|
18449
18754
|
});
|
|
18450
18755
|
for (const [id, view] of messages) {
|
|
18451
18756
|
if (!active.has(id)) {
|
|
18757
|
+
view.output?.dispose();
|
|
18452
18758
|
view.root.remove();
|
|
18453
18759
|
messages.delete(id);
|
|
18454
18760
|
}
|
|
@@ -1072,23 +1072,89 @@ main {
|
|
|
1072
1072
|
margin-top: 12px;
|
|
1073
1073
|
}
|
|
1074
1074
|
.resource-card {
|
|
1075
|
-
display:
|
|
1076
|
-
|
|
1077
|
-
gap: 8px;
|
|
1075
|
+
display: block;
|
|
1076
|
+
width: 100%;
|
|
1078
1077
|
min-width: 0;
|
|
1079
|
-
|
|
1080
|
-
min-height: 36px;
|
|
1081
|
-
padding: 6px 10px;
|
|
1078
|
+
margin: 8px 0;
|
|
1082
1079
|
border: 1px solid var(--border);
|
|
1083
1080
|
border-radius: 6px;
|
|
1084
1081
|
background: var(--vscode-editor-background);
|
|
1082
|
+
overflow: hidden;
|
|
1083
|
+
container-type: inline-size;
|
|
1084
|
+
}
|
|
1085
|
+
.resource-card-row {
|
|
1086
|
+
display: flex;
|
|
1087
|
+
align-items: center;
|
|
1088
|
+
gap: 4px;
|
|
1089
|
+
min-height: 44px;
|
|
1090
|
+
padding: 4px 8px;
|
|
1091
|
+
}
|
|
1092
|
+
.resource-target {
|
|
1093
|
+
display: flex;
|
|
1094
|
+
align-items: center;
|
|
1095
|
+
gap: 10px;
|
|
1096
|
+
flex: 1;
|
|
1097
|
+
min-width: 0;
|
|
1098
|
+
min-height: 36px;
|
|
1099
|
+
padding: 6px 4px;
|
|
1100
|
+
border: 0;
|
|
1101
|
+
background: transparent;
|
|
1085
1102
|
text-align: left;
|
|
1086
1103
|
}
|
|
1087
|
-
.resource-
|
|
1104
|
+
.resource-target > .codicon {
|
|
1105
|
+
flex: none;
|
|
1106
|
+
color: var(--muted);
|
|
1107
|
+
}
|
|
1108
|
+
.resource-title {
|
|
1088
1109
|
min-width: 0;
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1110
|
+
white-space: normal;
|
|
1111
|
+
overflow-wrap: anywhere;
|
|
1112
|
+
line-height: 1.5;
|
|
1113
|
+
}
|
|
1114
|
+
.resource-card-row > .icon-button {
|
|
1115
|
+
flex: none;
|
|
1116
|
+
width: 28px;
|
|
1117
|
+
height: 28px;
|
|
1118
|
+
}
|
|
1119
|
+
@container (max-width: 280px) {
|
|
1120
|
+
.resource-card-row {
|
|
1121
|
+
flex-wrap: wrap;
|
|
1122
|
+
}
|
|
1123
|
+
.resource-target {
|
|
1124
|
+
flex-basis: 100%;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
.resource-inline {
|
|
1128
|
+
height: 360px;
|
|
1129
|
+
max-height: 70vh;
|
|
1130
|
+
min-height: 160px;
|
|
1131
|
+
border-top: 1px solid var(--border);
|
|
1132
|
+
overflow: auto;
|
|
1133
|
+
}
|
|
1134
|
+
.resource-inline[role] {
|
|
1135
|
+
padding: 12px;
|
|
1136
|
+
color: var(--muted);
|
|
1137
|
+
}
|
|
1138
|
+
.resource-inline[role=alert] {
|
|
1139
|
+
color: var(--vscode-errorForeground);
|
|
1140
|
+
}
|
|
1141
|
+
.resource-inline iframe {
|
|
1142
|
+
display: block;
|
|
1143
|
+
width: 100%;
|
|
1144
|
+
height: 100%;
|
|
1145
|
+
border: 0;
|
|
1146
|
+
}
|
|
1147
|
+
.resource-call-details {
|
|
1148
|
+
padding: 8px 12px;
|
|
1149
|
+
border-top: 1px solid var(--border);
|
|
1150
|
+
max-height: 320px;
|
|
1151
|
+
overflow: auto;
|
|
1152
|
+
}
|
|
1153
|
+
.resource-call-details pre {
|
|
1154
|
+
margin: 0;
|
|
1155
|
+
font-size: 11px;
|
|
1156
|
+
white-space: pre-wrap;
|
|
1157
|
+
overflow-wrap: anywhere;
|
|
1092
1158
|
}
|
|
1093
1159
|
.input-prompt {
|
|
1094
1160
|
margin: 16px 0;
|