@workflow-code/cli 0.2.4-20261013004.codex-studio-integration → 0.2.4-20261013006.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.
@@ -16136,6 +16136,45 @@
16136
16136
  "{0}{1} \xB7 {2} items": "\u5DF2{0}{1} \xB7 {2} \u9879",
16137
16137
  "{1} in {0}": "{0} \u4E2D {1}",
16138
16138
  "Account balance ${0}": "\u8D26\u6237\u4F59\u989D ${0}",
16139
+ "Account balance": "\u8D26\u6237\u4F59\u989D",
16140
+ "Account changed. Refresh usage.": "\u8D26\u53F7\u5DF2\u5207\u6362\uFF0C\u8BF7\u91CD\u65B0\u83B7\u53D6\u7528\u91CF\u3002",
16141
+ "AI usage": "AI \u7528\u91CF",
16142
+ All: "\u5168\u90E8",
16143
+ "Basic information": "\u57FA\u672C\u4FE1\u606F",
16144
+ Declarations: "\u58F0\u660E",
16145
+ "Default name": "\u9ED8\u8BA4\u540D\u79F0",
16146
+ "Entrypoints granted": "\u5165\u53E3\u8C03\u7528\u6388\u6743",
16147
+ "Knowledge read granted": "\u77E5\u8BC6\u5E93\u8BFB\u53D6\u6388\u6743",
16148
+ "Knowledge write granted": "\u77E5\u8BC6\u5E93\u5199\u5165\u6388\u6743",
16149
+ "KV read granted": "KV \u8BFB\u53D6\u6388\u6743",
16150
+ "KV write granted": "KV \u5199\u5165\u6388\u6743",
16151
+ "Limit reached": "\u989D\u5EA6\u5DF2\u7528\u5C3D",
16152
+ "Loading usage...": "\u6B63\u5728\u52A0\u8F7D\u7528\u91CF...",
16153
+ Local: "\u672C\u5730",
16154
+ "Local and server": "\u672C\u5730\u4E0E\u670D\u52A1\u5668",
16155
+ "Local path": "\u672C\u5730\u8DEF\u5F84",
16156
+ "Localized names": "\u591A\u8BED\u8A00\u540D\u79F0",
16157
+ "Multiple languages": "\u591A\u8BED\u8A00",
16158
+ "Multiple platforms": "\u591A\u5E73\u53F0",
16159
+ "Not allowed": "\u4E0D\u5141\u8BB8",
16160
+ "Not available": "\u6682\u65E0\u6570\u636E",
16161
+ "Not declared": "\u672A\u58F0\u660E",
16162
+ "Platform independent": "\u5E73\u53F0\u65E0\u5173",
16163
+ "Platform support": "\u5E73\u53F0\u652F\u6301",
16164
+ Prefixes: "\u524D\u7F00",
16165
+ "Project declarations": "\u9879\u76EE\u58F0\u660E",
16166
+ "Project information": "\u9879\u76EE\u4FE1\u606F",
16167
+ "Project type": "\u9879\u76EE\u7C7B\u578B",
16168
+ "Project UUID": "\u9879\u76EE UUID",
16169
+ "Related project: {0}": "\u5173\u8054\u9879\u76EE\uFF1A{0}",
16170
+ "Storage location": "\u5B58\u50A8\u4F4D\u7F6E",
16171
+ "Usage unavailable": "\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u7528\u91CF",
16172
+ Used: "\u5DF2\u4F7F\u7528",
16173
+ Version: "\u7248\u672C",
16174
+ "Working directory": "\u5DE5\u4F5C\u76EE\u5F55",
16175
+ "{0} (default)": "{0}\uFF08\u9ED8\u8BA4\uFF09",
16176
+ "{0} remaining": "\u5269\u4F59 {0}",
16177
+ "{0} usage": "{0}\u7528\u91CF",
16139
16178
  "Add attachment": "\u6DFB\u52A0\u9644\u4EF6",
16140
16179
  "Agent run": "Agent \u8FD0\u884C",
16141
16180
  "All chats": "\u5168\u90E8\u804A\u5929",
@@ -19614,6 +19653,17 @@ ${state2.user?.avatarUrl ?? ""}`;
19614
19653
  }
19615
19654
 
19616
19655
  // src/web/workflow-types.ts
19656
+ var projectTypeLabels = {
19657
+ get conversation() {
19658
+ return t2("Conversation");
19659
+ },
19660
+ get workflow() {
19661
+ return t2("Workflow");
19662
+ },
19663
+ get kanban() {
19664
+ return t2("Kanban");
19665
+ }
19666
+ };
19617
19667
  function workflowParameters(project, entrypointId2) {
19618
19668
  return project.entrypoints.find((entry) => entry.id === entrypointId2) ?? project;
19619
19669
  }
@@ -19769,11 +19819,20 @@ ${state2.user?.avatarUrl ?? ""}`;
19769
19819
  const label = document.createElement("span");
19770
19820
  label.className = "param-action-label";
19771
19821
  const view = { action, button, label };
19822
+ if (action.kind === "quick" && action.id === "ai") {
19823
+ button.classList.add("param-action-ai");
19824
+ button.append(icon("sparkle"));
19825
+ }
19772
19826
  if (action.kind === "auxiliary") {
19773
19827
  button.append(icon("settings"));
19774
19828
  view.count = document.createElement("small");
19775
19829
  }
19776
19830
  button.append(label);
19831
+ if (action.kind === "quick") {
19832
+ view.summary = document.createElement("span");
19833
+ view.summary.className = "param-action-summary";
19834
+ button.append(view.summary);
19835
+ }
19777
19836
  if (view.count) {
19778
19837
  button.append(view.count);
19779
19838
  }
@@ -19830,14 +19889,17 @@ ${state2.user?.avatarUrl ?? ""}`;
19830
19889
  view.button.hidden = fields2.length === 0;
19831
19890
  view.button.disabled = disabled2 || (action.kind === "auxiliary" ? loading : fields2.every((field) => states[field.name]?.disabled === true || this.visibleOptions(field).length === 0));
19832
19891
  const summaries = action.summary?.map((name) => fields2.find((field) => field.name === name)).filter((field) => !!field && !!values[field.name]?.length).map((field) => parameterSelectionLabel(field, values[field.name], states[field.name])) ?? [];
19833
- view.label.textContent = action.kind === "quick" && summaries.length ? `${action.label}: ${summaries.join(" \xB7 ")}` : action.label;
19892
+ view.label.textContent = action.label;
19893
+ if (view.summary) {
19894
+ view.summary.textContent = summaries.join(" \xB7 ");
19895
+ view.summary.hidden = !summaries.length;
19896
+ }
19834
19897
  if (view.count) {
19835
19898
  view.count.textContent = String(fields2.length);
19836
19899
  }
19837
19900
  view.button.setAttribute("aria-busy", String(loading));
19838
19901
  }
19839
- view.button.title = view.label.textContent || "";
19840
- view.button.ariaLabel = view.label.textContent || "";
19902
+ view.button.title = view.button.ariaLabel = [view.label.textContent, view.summary?.textContent].filter(Boolean).join(": ");
19841
19903
  }
19842
19904
  if (this.active) {
19843
19905
  if (disabled2 || this.active.button.hidden) {
@@ -21333,15 +21395,101 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21333
21395
  }
21334
21396
  };
21335
21397
 
21398
+ // src/web/ui/project-information.ts
21399
+ function access(rule) {
21400
+ if (rule?.mode === "all") {
21401
+ return t2("All");
21402
+ }
21403
+ if (rule?.mode === "none") {
21404
+ return t2("Not allowed");
21405
+ }
21406
+ if (rule?.mode === "prefixes") {
21407
+ return `${t2("Prefixes")}: ${rule.prefixes.join(", ")}`;
21408
+ }
21409
+ return t2("Not declared");
21410
+ }
21411
+ function projectInformation(project) {
21412
+ const info = project.projectInfo;
21413
+ const storage = { local: t2("Local"), server: t2("Server"), both: t2("Local and server") };
21414
+ const declarations = { multilingual: t2("Multiple languages"), multiplatform: t2("Multiple platforms") };
21415
+ const platforms = { macos: "macOS", windows: "Windows", web: "Web" };
21416
+ const sections = [{
21417
+ title: t2("Basic information"),
21418
+ expanded: true,
21419
+ rows: [
21420
+ { label: t2("Default name"), value: project.manifest?.name || project.name },
21421
+ { label: t2("Project type"), value: projectTypeLabels[project.projectType] },
21422
+ { label: t2("Version"), value: project.manifest?.version || t2("Not declared") },
21423
+ { label: t2("Project UUID"), value: project.id },
21424
+ { label: project.assistant ? t2("Working directory") : t2("Local path"), value: project.assistant?.workdir || project.folderPath }
21425
+ ]
21426
+ }, {
21427
+ title: t2("Project declarations"),
21428
+ expanded: true,
21429
+ rows: [
21430
+ { label: t2("Storage location"), value: info?.dataStorage ? storage[info.dataStorage.mode] : t2("Not declared") },
21431
+ { label: t2("Platform support"), value: info?.platformSupport.mode === "specific" ? info.platformSupport.platforms.map((id) => platforms[id] || id).join(", ") : t2("Platform independent") },
21432
+ { label: t2("Declarations"), value: info?.declarations.map((id) => declarations[id] || id).join(", ") || t2("Not declared") }
21433
+ ]
21434
+ }];
21435
+ if (info && Object.keys(info.localizedNames).length) {
21436
+ sections.push({ title: t2("Localized names"), rows: Object.entries(info.localizedNames).map(([label, value]) => ({ label, value })) });
21437
+ }
21438
+ for (const relation of info?.relatedProjects ?? []) {
21439
+ const grant = relation.grantToRelatedProject;
21440
+ sections.push({ title: t2("Related project: {0}", relation.alias), rows: [
21441
+ { label: t2("Project UUID"), value: relation.projectId },
21442
+ { label: t2("KV read granted"), value: access(grant.read) },
21443
+ { label: t2("KV write granted"), value: access(grant.write) },
21444
+ { label: t2("Knowledge read granted"), value: access(grant.knowledge?.read) },
21445
+ { label: t2("Knowledge write granted"), value: access(grant.knowledge?.write) },
21446
+ { label: t2("Entrypoints granted"), value: access(grant.entrypoints) }
21447
+ ] });
21448
+ }
21449
+ if (project.entrypoints.length) {
21450
+ sections.push({ title: t2("Entrypoints"), rows: project.entrypoints.map((entry) => ({
21451
+ label: entry.title || entry.id,
21452
+ value: entry.id === project.defaultEntrypoint ? t2("{0} (default)", entry.id) : entry.id
21453
+ })) });
21454
+ }
21455
+ return sections;
21456
+ }
21457
+
21458
+ // src/web/ui/ai-usage.ts
21459
+ function usageAmount(value) {
21460
+ return value != null && Number.isFinite(Number(value)) ? `$${Math.max(0, Number(value)).toFixed(2)}` : t2("Not available");
21461
+ }
21462
+ function usagePeriods(subscription) {
21463
+ const labels = { daily: t2("Daily"), weekly: t2("Weekly"), monthly: t2("Monthly") };
21464
+ return ["daily", "weekly", "monthly"].map((period) => {
21465
+ const rawUsed = subscription[`${period}UsageUsd`], rawLimit = subscription[`${period}LimitUsd`];
21466
+ const used = Number.isFinite(Number(rawUsed)) && rawUsed != null ? Math.max(0, Number(rawUsed)) : void 0;
21467
+ const limit = rawLimit === null ? null : Number.isFinite(Number(rawLimit)) && rawLimit !== void 0 ? Math.max(0, Number(rawLimit)) : void 0;
21468
+ const ratio = used !== void 0 && limit !== null && limit !== void 0 ? limit > 0 ? used / limit : 1 : void 0;
21469
+ return {
21470
+ period,
21471
+ label: labels[period],
21472
+ used,
21473
+ limit,
21474
+ ratio,
21475
+ status: ratio === void 0 ? "" : ratio >= 1 ? "exhausted" : ratio >= 0.8 ? "near-limit" : "",
21476
+ remaining: used !== void 0 && limit !== null && limit !== void 0 ? Math.max(0, limit - used) : void 0
21477
+ };
21478
+ });
21479
+ }
21480
+
21336
21481
  // src/web/ui/conversation-tools.ts
21337
21482
  var ConversationTools = class {
21338
21483
  dialog = document.createElement("dialog");
21339
21484
  body = document.createElement("div");
21340
21485
  title = document.createElement("h2");
21341
21486
  usageOpen = false;
21487
+ usageRequestId;
21342
21488
  refresh;
21343
21489
  constructor() {
21344
21490
  this.dialog.className = "conversation-dialog";
21491
+ this.title.id = "conversation-dialog-title";
21492
+ this.dialog.setAttribute("aria-labelledby", this.title.id);
21345
21493
  const header = document.createElement("header");
21346
21494
  header.append(this.title, iconButton("close", t2("Close"), () => this.close()));
21347
21495
  this.body.className = "dialog-body";
@@ -21355,6 +21503,7 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21355
21503
  }
21356
21504
  }
21357
21505
  });
21506
+ this.dialog.addEventListener("cancel", () => this.close());
21358
21507
  }
21359
21508
  get open() {
21360
21509
  return this.dialog.open;
@@ -21362,13 +21511,20 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21362
21511
  close() {
21363
21512
  this.dialog.close();
21364
21513
  this.usageOpen = false;
21514
+ this.usageRequestId = void 0;
21365
21515
  this.refresh?.remove();
21366
21516
  this.refresh = void 0;
21367
21517
  }
21518
+ closeUsage() {
21519
+ if (this.usageOpen) {
21520
+ this.close();
21521
+ }
21522
+ }
21368
21523
  show(title) {
21369
21524
  this.close();
21370
21525
  this.title.textContent = title;
21371
21526
  this.body.replaceChildren();
21527
+ this.body.setAttribute("aria-busy", "false");
21372
21528
  this.dialog.showModal();
21373
21529
  }
21374
21530
  plan(content) {
@@ -21386,6 +21542,35 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21386
21542
  image.className = "image-preview";
21387
21543
  this.body.append(image);
21388
21544
  }
21545
+ projectInfo(project) {
21546
+ this.show(t2("Project information"));
21547
+ const heading = document.createElement("h3");
21548
+ heading.className = "project-information-name";
21549
+ heading.textContent = project.name;
21550
+ this.body.append(heading);
21551
+ if (project.manifest?.description) {
21552
+ const description = document.createElement("p");
21553
+ description.className = "project-information-description";
21554
+ description.textContent = project.manifest.description;
21555
+ this.body.append(description);
21556
+ }
21557
+ for (const section of projectInformation(project)) {
21558
+ const details = document.createElement("details");
21559
+ details.className = "project-information-section";
21560
+ details.open = !!section.expanded;
21561
+ const summary = document.createElement("summary");
21562
+ summary.innerHTML = `${iconHtml("chevron-right")}<span>${escapeHtml(section.title)}</span>`;
21563
+ const list = document.createElement("dl");
21564
+ for (const row of section.rows) {
21565
+ const label = document.createElement("dt"), value = document.createElement("dd");
21566
+ label.textContent = row.label;
21567
+ value.textContent = row.value;
21568
+ list.append(label, value);
21569
+ }
21570
+ details.append(summary, list);
21571
+ this.body.append(details);
21572
+ }
21573
+ }
21389
21574
  permissions(parameters2, policies, changed) {
21390
21575
  this.show(t2("Tool permissions"));
21391
21576
  const tools = parameters2.tools ?? [];
@@ -21429,35 +21614,46 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21429
21614
  }
21430
21615
  }
21431
21616
  usage(load) {
21432
- this.show(t2("System AI"));
21617
+ this.show(t2("AI usage"));
21433
21618
  this.usageOpen = true;
21434
- const refresh = this.refresh = iconButton("refresh", t2("Refresh usage"), () => {
21435
- this.body.textContent = t2("Loading...");
21436
- load();
21437
- });
21619
+ const refresh = this.refresh = iconButton("refresh", t2("Refresh usage"), () => this.loadUsage(load));
21438
21620
  this.dialog.querySelector("header").insertBefore(refresh, this.dialog.querySelector("header > button:last-child"));
21439
- this.body.textContent = t2("Loading...");
21440
- load();
21621
+ this.loadUsage(load);
21441
21622
  }
21442
- usageResult(data, error) {
21443
- if (!this.usageOpen) {
21444
- return;
21623
+ loadUsage(load) {
21624
+ this.body.innerHTML = `<div class="usage-status" role="status">${iconHtml("loading")}<span>${t2("Loading usage...")}</span></div>`;
21625
+ this.body.setAttribute("aria-busy", "true");
21626
+ if (this.refresh) {
21627
+ this.refresh.disabled = true;
21445
21628
  }
21446
- this.body.replaceChildren();
21447
- if (error) {
21448
- this.body.textContent = error;
21629
+ this.usageRequestId = crypto.randomUUID();
21630
+ load(this.usageRequestId);
21631
+ }
21632
+ usageResult(requestId2, data, error) {
21633
+ if (!this.usageOpen || requestId2 !== this.usageRequestId) {
21449
21634
  return;
21450
21635
  }
21451
- if (!data) {
21636
+ this.body.replaceChildren();
21637
+ this.body.setAttribute("aria-busy", "false");
21638
+ if (this.refresh) {
21639
+ this.refresh.disabled = false;
21640
+ }
21641
+ if (error || !data) {
21642
+ const status = document.createElement("p");
21643
+ status.className = error ? "error usage-status" : "usage-status";
21644
+ status.setAttribute("role", error ? "alert" : "status");
21645
+ status.textContent = error || t2("Usage unavailable");
21646
+ this.body.append(status);
21452
21647
  return;
21453
21648
  }
21454
- const balance = document.createElement("p");
21455
- balance.textContent = t2("Account balance ${0}", Number(data.balance ?? 0).toFixed(2));
21649
+ const balance = document.createElement("div");
21650
+ balance.className = "usage-balance";
21651
+ balance.innerHTML = `<span>${t2("Account balance")}</span><strong>${escapeHtml(usageAmount(data.balance))}</strong><small>USD</small>`;
21456
21652
  this.body.append(balance);
21457
- const labels = { daily: t2("Daily"), weekly: t2("Weekly"), monthly: t2("Monthly") };
21458
21653
  const plans = data.groups.filter((group) => group.subscriptionType === "subscription" && group.subscription?.status === "active");
21459
21654
  if (!plans.length) {
21460
21655
  const empty = document.createElement("p");
21656
+ empty.className = "usage-status";
21461
21657
  empty.textContent = t2("No active subscriptions");
21462
21658
  this.body.append(empty);
21463
21659
  }
@@ -21467,19 +21663,24 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21467
21663
  const title = document.createElement("h3");
21468
21664
  title.textContent = plan.name;
21469
21665
  section.append(title);
21470
- for (const period of ["daily", "weekly", "monthly"]) {
21471
- const limit = plan.subscription[`${period}LimitUsd`];
21472
- const used = Number(plan.subscription[`${period}UsageUsd`] ?? 0);
21666
+ for (const period of usagePeriods(plan.subscription)) {
21473
21667
  const row = document.createElement("div");
21474
- const label = document.createElement("span");
21475
- label.textContent = `${labels[period]} $${used.toFixed(2)} / ${limit === null ? t2("Unlimited") : `$${Number(limit).toFixed(2)}`}`;
21476
- row.append(label);
21477
- if (limit !== null && limit > 0) {
21668
+ row.className = "usage-period";
21669
+ row.dataset.status = period.status;
21670
+ const used = period.used === void 0 ? t2("Not available") : usageAmount(period.used);
21671
+ const limit = period.limit === null ? t2("Unlimited") : period.limit === void 0 ? t2("Not available") : usageAmount(period.limit);
21672
+ row.innerHTML = `<div class="usage-period-heading"><span>${period.label}</span><strong>${period.ratio === void 0 ? escapeHtml(limit) : `${Math.round(period.ratio * 100)}%`}</strong></div><div class="usage-period-amount"><strong>${escapeHtml(used)}</strong><span>/ ${escapeHtml(limit)}</span></div>`;
21673
+ if (period.ratio !== void 0) {
21478
21674
  const progress = document.createElement("progress");
21479
- progress.max = limit;
21480
- progress.value = used;
21675
+ progress.max = 1;
21676
+ progress.value = Math.min(1, period.ratio);
21677
+ progress.ariaLabel = t2("{0} usage", period.label);
21481
21678
  row.append(progress);
21482
21679
  }
21680
+ const remaining = document.createElement("span");
21681
+ remaining.className = "usage-period-remaining";
21682
+ remaining.textContent = period.status === "exhausted" ? t2("Limit reached") : period.remaining === void 0 ? t2("Used") : t2("{0} remaining", usageAmount(period.remaining));
21683
+ row.append(remaining);
21483
21684
  section.append(row);
21484
21685
  }
21485
21686
  this.body.append(section);
@@ -21618,7 +21819,7 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21618
21819
  var host = acquireWorkflowHost();
21619
21820
  app.classList.add("workflow-app");
21620
21821
  app.innerHTML = `
21621
- <header class="toolbar"><div class="project-title"><button id="menu-toggle" class="icon-button" aria-label="${t2("Show runs")}" title="${t2("Show runs")}">${iconHtml("layout-sidebar-left")}</button><span class="project-icon">${iconHtml("symbol-event")}</span><h1 id="workflow-title">Workflow</h1></div><div class="toolbar-actions"><button id="usage" class="icon-button" title="${t2("System AI usage")}" aria-label="${t2("System AI usage")}" hidden>${iconHtml("dashboard")}</button><button id="tools" class="icon-button" title="${t2("Tool permissions")}" aria-label="${t2("Tool permissions")}">${iconHtml("tools")}</button></div></header>
21822
+ <header class="toolbar"><div class="project-title"><button id="menu-toggle" class="icon-button" aria-label="${t2("Show runs")}" title="${t2("Show runs")}">${iconHtml("layout-sidebar-left")}</button><button id="project-info" class="icon-button" title="${t2("Project information")}" aria-label="${t2("Project information")}" aria-haspopup="dialog">${iconHtml("info")}</button><span class="project-icon">${iconHtml("symbol-event")}</span><h1 id="workflow-title">Workflow</h1></div><div class="toolbar-actions"><button id="usage" class="icon-button usage-button" title="${t2("System AI usage")}" aria-label="${t2("System AI usage")}" aria-haspopup="dialog" hidden>${iconHtml("dashboard")}<span>${t2("AI usage")}</span></button><button id="tools" class="icon-button" title="${t2("Tool permissions")}" aria-label="${t2("Tool permissions")}">${iconHtml("tools")}</button></div></header>
21622
21823
  <aside id="project-menu" class="project-menu" aria-label="${t2("Runs")}"><div class="menu-heading"><span>${t2("Runs")}</span><div class="menu-actions"><button id="history-toggle" class="icon-button" aria-label="${t2("Search runs")}" title="${t2("Search runs")}">${iconHtml("search")}</button><button id="new" class="icon-button" aria-label="${t2("New run")}" title="${t2("New run")}">${iconHtml("add")}</button><button id="hide-menu" class="icon-button" aria-label="${t2("Hide runs")}" title="${t2("Hide runs")}">${iconHtml("chevron-left")}</button></div></div><section id="run-history"><nav id="run-list"></nav><div id="empty-history" class="no-history">${t2("No runs")}</div><button id="load-more-history" class="all-history" hidden>${iconHtml("chevron-down")}<span>${t2("Load more")}</span></button></section></aside>
21623
21824
  <main><div id="error" class="error" role="alert" hidden></div><div id="active-run" class="workflow-active" hidden><button id="show-active" class="workflow-active-link"></button><button id="stop-active" class="icon-button" title="${t2("Stop run")}" aria-label="${t2("Stop run")}">${iconHtml("debug-stop")}</button></div>
21624
21825
  <div id="workspace-scroll" class="workspace-scroll"><section id="entrypoints" class="workflow-entrypoints" aria-label="${t2("Workflow entrypoint")}"></section>
@@ -21693,8 +21894,6 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21693
21894
  app.classList.toggle("menu-open", open);
21694
21895
  element("menu-toggle").hidden = open;
21695
21896
  element("menu-toggle").setAttribute("aria-expanded", String(open));
21696
- const actions = document.querySelector(narrow.matches && open ? ".menu-actions" : ".toolbar-actions");
21697
- actions.prepend(element("usage"), element("tools"));
21698
21897
  persist();
21699
21898
  }
21700
21899
  menu(menuOpen);
@@ -21937,7 +22136,9 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
21937
22136
  element("entrypoints").hidden = !!run;
21938
22137
  element("run-detail").hidden = !run;
21939
22138
  if (!run) {
21940
- fields.close();
22139
+ if (renderedRun) {
22140
+ fields.close();
22141
+ }
21941
22142
  renderedRun = "";
21942
22143
  controls();
21943
22144
  return;
@@ -22010,6 +22211,9 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
22010
22211
  const authChanged = revision !== next.authenticationRevision;
22011
22212
  revision = next.authenticationRevision;
22012
22213
  state = next;
22214
+ if (authChanged) {
22215
+ dialogs.closeUsage();
22216
+ }
22013
22217
  if (!draftsLoaded) {
22014
22218
  for (const key of Object.keys(drafts)) {
22015
22219
  delete drafts[key];
@@ -22103,7 +22307,13 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
22103
22307
  draft().policies = structuredClone(policies);
22104
22308
  post({ type: "tool-policy", policies });
22105
22309
  });
22106
- element("usage").onclick = () => dialogs.usage(() => post({ type: "usage" }));
22310
+ element("usage").onclick = () => dialogs.usage((requestId2) => post({ type: "usage", requestId: requestId2 }));
22311
+ element("project-info").onclick = () => {
22312
+ if (state) {
22313
+ fields.close();
22314
+ dialogs.projectInfo(state.project);
22315
+ }
22316
+ };
22107
22317
  addEventListener("message", (event) => {
22108
22318
  const message = event.data;
22109
22319
  if (message?.type === "state" && message.project?.projectType === "workflow") {
@@ -22115,6 +22325,9 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
22115
22325
  if (restored) {
22116
22326
  resolve();
22117
22327
  }
22328
+ if (!connected) {
22329
+ dialogs.closeUsage();
22330
+ }
22118
22331
  } else if (message?.type === "params" && message.requestId === requestId && message.entrypointId === entrypointId) {
22119
22332
  resolving = false;
22120
22333
  if (message.error) {
@@ -22139,8 +22352,12 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
22139
22352
  }
22140
22353
  }
22141
22354
  } else if (message?.type === "usage") {
22142
- dialogs.usageResult(message.usage);
22355
+ dialogs.usageResult(message.requestId, message.usage);
22143
22356
  } else if (message?.type === "error") {
22357
+ if (message.requestType === "usage") {
22358
+ dialogs.usageResult(message.requestId, void 0, message.message);
22359
+ return;
22360
+ }
22144
22361
  submitting = false;
22145
22362
  resolving = false;
22146
22363
  controls();
@@ -22151,9 +22368,6 @@ ${JSON.stringify(output2.details, null, 2)}` : "");
22151
22368
  if (message.requestType === "workflow-resume") {
22152
22369
  prompt?.setBusy(false, message.message);
22153
22370
  }
22154
- if (message.requestType === "usage") {
22155
- dialogs.usageResult(void 0, message.message);
22156
- }
22157
22371
  }
22158
22372
  });
22159
22373
  host.postMessage({ type: "ready" });
@@ -64,6 +64,45 @@ var messages_zh_cn_default = {
64
64
  "{0}{1} \xB7 {2} items": "\u5DF2{0}{1} \xB7 {2} \u9879",
65
65
  "{1} in {0}": "{0} \u4E2D {1}",
66
66
  "Account balance ${0}": "\u8D26\u6237\u4F59\u989D ${0}",
67
+ "Account balance": "\u8D26\u6237\u4F59\u989D",
68
+ "Account changed. Refresh usage.": "\u8D26\u53F7\u5DF2\u5207\u6362\uFF0C\u8BF7\u91CD\u65B0\u83B7\u53D6\u7528\u91CF\u3002",
69
+ "AI usage": "AI \u7528\u91CF",
70
+ All: "\u5168\u90E8",
71
+ "Basic information": "\u57FA\u672C\u4FE1\u606F",
72
+ Declarations: "\u58F0\u660E",
73
+ "Default name": "\u9ED8\u8BA4\u540D\u79F0",
74
+ "Entrypoints granted": "\u5165\u53E3\u8C03\u7528\u6388\u6743",
75
+ "Knowledge read granted": "\u77E5\u8BC6\u5E93\u8BFB\u53D6\u6388\u6743",
76
+ "Knowledge write granted": "\u77E5\u8BC6\u5E93\u5199\u5165\u6388\u6743",
77
+ "KV read granted": "KV \u8BFB\u53D6\u6388\u6743",
78
+ "KV write granted": "KV \u5199\u5165\u6388\u6743",
79
+ "Limit reached": "\u989D\u5EA6\u5DF2\u7528\u5C3D",
80
+ "Loading usage...": "\u6B63\u5728\u52A0\u8F7D\u7528\u91CF...",
81
+ Local: "\u672C\u5730",
82
+ "Local and server": "\u672C\u5730\u4E0E\u670D\u52A1\u5668",
83
+ "Local path": "\u672C\u5730\u8DEF\u5F84",
84
+ "Localized names": "\u591A\u8BED\u8A00\u540D\u79F0",
85
+ "Multiple languages": "\u591A\u8BED\u8A00",
86
+ "Multiple platforms": "\u591A\u5E73\u53F0",
87
+ "Not allowed": "\u4E0D\u5141\u8BB8",
88
+ "Not available": "\u6682\u65E0\u6570\u636E",
89
+ "Not declared": "\u672A\u58F0\u660E",
90
+ "Platform independent": "\u5E73\u53F0\u65E0\u5173",
91
+ "Platform support": "\u5E73\u53F0\u652F\u6301",
92
+ Prefixes: "\u524D\u7F00",
93
+ "Project declarations": "\u9879\u76EE\u58F0\u660E",
94
+ "Project information": "\u9879\u76EE\u4FE1\u606F",
95
+ "Project type": "\u9879\u76EE\u7C7B\u578B",
96
+ "Project UUID": "\u9879\u76EE UUID",
97
+ "Related project: {0}": "\u5173\u8054\u9879\u76EE\uFF1A{0}",
98
+ "Storage location": "\u5B58\u50A8\u4F4D\u7F6E",
99
+ "Usage unavailable": "\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u7528\u91CF",
100
+ Used: "\u5DF2\u4F7F\u7528",
101
+ Version: "\u7248\u672C",
102
+ "Working directory": "\u5DE5\u4F5C\u76EE\u5F55",
103
+ "{0} (default)": "{0}\uFF08\u9ED8\u8BA4\uFF09",
104
+ "{0} remaining": "\u5269\u4F59 {0}",
105
+ "{0} usage": "{0}\u7528\u91CF",
67
106
  "Add attachment": "\u6DFB\u52A0\u9644\u4EF6",
68
107
  "Agent run": "Agent \u8FD0\u884C",
69
108
  "All chats": "\u5168\u90E8\u804A\u5929",
@@ -3551,12 +3590,16 @@ ${token}`;
3551
3590
  if (!connection) {
3552
3591
  throw new Error("Workflow Server login is not configured.");
3553
3592
  }
3593
+ const revision = authRevision;
3554
3594
  const response = await fetch(`${connection.serverUrl}/api/auth/sub2api/catalog`, { headers: { Authorization: `Bearer ${connection.accessToken}` }, signal: AbortSignal.timeout(15e3), redirect: "error" });
3555
3595
  const result = await response.json();
3596
+ if (revision !== authRevision) {
3597
+ throw new Error(t("Account changed. Refresh usage."));
3598
+ }
3556
3599
  if (!response.ok || result.errCode !== 0) {
3557
3600
  throw new Error(result.errMessage || "Cannot load usage.");
3558
3601
  }
3559
- replies.push({ type: "usage", sessionId: current?.id, usage: result.data });
3602
+ replies.push({ type: "usage", requestId: message.requestId, sessionId: current?.id, usage: result.data });
3560
3603
  break;
3561
3604
  }
3562
3605
  case "login": {
@@ -3710,7 +3753,7 @@ ${token}`;
3710
3753
  const operation = () => handleMessage(message).then((value2) => {
3711
3754
  messages = value2;
3712
3755
  });
3713
- const concurrent = ["resolve", "ready", "resource", "resource-data", "resource-refresh", "resource-select", "resource-bridge", "kanban-bridge", "kanban-method-state", "kanban-method-reply", "kanban-methods"].includes(message.type);
3756
+ const concurrent = ["resolve", "ready", "usage", "resource", "resource-data", "resource-refresh", "resource-select", "resource-bridge", "kanban-bridge", "kanban-method-state", "kanban-method-reply", "kanban-methods"].includes(message.type);
3714
3757
  const task = concurrent ? operation() : mutations.catch(() => void 0).then(operation);
3715
3758
  if (!concurrent) {
3716
3759
  mutations = task;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workflow-code/cli",
3
- "version": "0.2.4-20261013004.codex-studio-integration",
3
+ "version": "0.2.4-20261013006.codex-studio-integration",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "workflow-code": "./dist/index.js"
@@ -37,15 +37,15 @@
37
37
  "vitest": "^4.1.7",
38
38
  "workflow-code": "0.2.4-20260929001",
39
39
  "@workflow-code/auth-config": "0.1.0",
40
- "@workflow-code/i18n": "0.1.0",
41
40
  "@workflow-code/execution-targets": "0.1.0",
41
+ "@workflow-code/i18n": "0.1.0",
42
42
  "@workflow-code/kanban-project": "0.1.0",
43
- "@workflow-code/openai-responses": "0.1.0",
44
43
  "@workflow-code/project-dependencies": "0.1.0",
44
+ "@workflow-code/openai-responses": "0.1.0",
45
45
  "@workflow-code/project-info": "0.1.0",
46
46
  "@workflow-code/project-upload": "0.1.0",
47
- "@workflow-code/workflow-ids": "0.1.0",
48
47
  "@workflow-code/runtime-compatibility": "0.1.0",
48
+ "@workflow-code/workflow-ids": "0.1.0",
49
49
  "@workflow-code/workflow-mcp": "0.1.0"
50
50
  },
51
51
  "scripts": {