dsh-pre-duediligence 0.1.33 → 0.1.34

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/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # 更新日志
2
2
  ## [Unreleased]
3
3
 
4
+ ## [0.1.34] - 2026-09-15
5
+
6
+ - 修正启动导航:主体确认前停留对象与目标,确认后展示范围,再进入实际查询阶段。
7
+ - 完成后的风险结论不再显示待研判;明确未发现与结论缺口分开呈现。
8
+ - 默认展开风险采集摘要,统一 PDF/Word/HTML 下载入口,生成后自动下载。
9
+ - 删除宿主技术提示及旧字体配置说明,保留手动阅读位置。
10
+
4
11
  ## [0.1.33] - 2026-09-15
5
12
 
6
13
  - 分离客观数据采集与证据分析,消除跨页重复卡片。
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # dsh-pre-duediligence
2
2
 
3
- 0.1.33 分离资料采集与证据核验:采集仅展示来源数据,核验前置风险研判并展示机会假设、支持、反证及证据缺口。支持有真实引用的阶段性风险分级;无需执行项目合并说明。“现场验证”改为“证据验证”,待沟通事项明确为“待客户确认”。保留报告版本、历史回看及离线中文 PDF/Word 导出。详见 [发布说明](docs/RELEASE-0.1.33.md)。
3
+ 0.1.34 分离资料采集与证据核验:采集仅展示来源数据,核验前置风险研判并展示机会假设、支持、反证及证据缺口。支持有真实引用的阶段性风险分级;无需执行项目合并说明。“现场验证”改为“证据验证”,待沟通事项明确为“待客户确认”。保留报告版本、历史回看及离线中文 PDF/Word 导出。详见 [发布说明](docs/RELEASE-0.1.34.md)。
4
4
 
5
5
  ## 安装与三分钟上手
6
6
 
7
7
  访前尽调智能体:面向拜访前调查,提供企业尽调、客户尽调、客户背景调查、工商核验与风险信息整理;使用企查查 MCP,提供固定路由连续调用、主体确认、动态进度和可下载报告。
8
8
 
9
9
  ```sh
10
- dsh plugin --profile web add dsh-pre-duediligence@0.1.33
10
+ dsh plugin --profile web add dsh-pre-duediligence@0.1.34
11
11
  ```
12
12
 
13
13
  请先满足下文的 DSH 与连接器要求;Better Sidebar 仅在需要可视化工作台时选装。安装后完整停止并重启对应 Profile。
@@ -92,7 +92,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/duhu2000/dsh-pre-duediligenc
92
92
  安装脚本默认向 DSH Web profile 安装两个基础 Bundle:
93
93
 
94
94
  1. `dsh-mcp-connector@0.2.32`:提供通用 MCP 连接器与市场,通过“企查查·企业工商”完成 OAuth,并动态挂载企业、风险、知产、经营、历史和董监高 MCP。
95
- 2. `dsh-pre-duediligence@0.1.33`:提供左侧智能体入口、原生会话首页、提示词生成器、Host 执行门和 Skill。
95
+ 2. `dsh-pre-duediligence@0.1.34`:提供左侧智能体入口、原生会话首页、提示词生成器、Host 执行门和 Skill。
96
96
 
97
97
  默认不会安装 Better Sidebar。需要 Session 级可视化工作台时显式开启:
98
98
 
@@ -120,7 +120,7 @@ dsh web
120
120
 
121
121
  ~~~bash
122
122
  dsh plugin --profile web add dsh-mcp-connector@0.2.32
123
- dsh plugin --profile web add dsh-pre-duediligence@0.1.33 --allow-build=node-pty,dsh-pre-duediligence
123
+ dsh plugin --profile web add dsh-pre-duediligence@0.1.34 --allow-build=node-pty,dsh-pre-duediligence
124
124
  dsh web
125
125
  ~~~
126
126
 
@@ -136,7 +136,7 @@ dsh web
136
136
  dsh plugin --profile web list --depth 0
137
137
  ~~~
138
138
 
139
- 应始终看到所选基线的 Connector 和 `dsh-pre-duediligence@0.1.33`;仅在显式启用或原本已安装时看到 Sidebar。重启 DSH 并连接“企查查·企业工商”后,在左侧菜单点击“访前尽调”进入初始原生会话。无 Sidebar 时可继续生成提示词、回填/发送草稿并在会话中阅读报告;五项流程按钮会提示安装可选工作台。安装 Sidebar 时,右侧工作台初始仍关闭;点击业务按钮可主动打开,正式发送任务被接纳后会自动展开一次。仅回填不会展开,收起后轮询不会重新打开。其右侧“+”菜单不会列出该入口,普通会话保持 DSH 原样。
139
+ 应始终看到所选基线的 Connector 和 `dsh-pre-duediligence@0.1.34`;仅在显式启用或原本已安装时看到 Sidebar。重启 DSH 并连接“企查查·企业工商”后,在左侧菜单点击“访前尽调”进入初始原生会话。无 Sidebar 时可继续生成提示词、回填/发送草稿并在会话中阅读报告;五项流程按钮会提示安装可选工作台。安装 Sidebar 时,右侧工作台初始仍关闭;点击业务按钮可主动打开,正式发送任务被接纳后会自动展开一次。仅回填不会展开,收起后轮询不会重新打开。其右侧“+”菜单不会列出该入口,普通会话保持 DSH 原样。
140
140
 
141
141
  ### 无 Sidebar 功能边界
142
142
 
@@ -0,0 +1,9 @@
1
+ # v0.1.34
2
+
3
+ - 新任务自动展开对象与目标;主体绑定前不进入资料采集。已确认主体先展示范围,再按真实查询进入采集或核验。用户手动浏览后保留当前页,报告完成不强制跳转。
4
+ - 完成后的风险摘要区分本次明确未发现、已发现事项与结论未明确;兼容加粗表格级别和明确的红线文字结论,缺省项不自动判零。
5
+ - 风险明细与采集覆盖默认展示客观摘要,仅长字段保留折叠。
6
+ - 当前报告底部统一下载 PDF(主要)、Word、HTML;PDF/Word 一次点击生成并下载,失败可重试。历史详情使用同一格式入口。
7
+ - 移除底部宿主技术提示及过时的管理员字体配置说明。PDF 内置字体保持不变。
8
+
9
+ 更新不会修改已保存报告正文或重跑历史查询。旧报告缺少明确分级时如实显示结论缺口,需继续尽调补充,不以完成状态代替核验。
package/install.sh CHANGED
@@ -5,7 +5,7 @@ set -euo pipefail
5
5
  readonly PROFILE_NAME="${DSH_PROFILE:-web}"
6
6
  readonly BASELINE="${DSH_PREVISIT_BASELINE:-stable}"
7
7
  readonly WORKBENCH_MODE="${DSH_PREVISIT_WORKBENCH:-off}"
8
- readonly PREVISIT_SPEC="${DSH_PRE_DUEDILIGENCE_SPEC:-dsh-pre-duediligence@0.1.33}"
8
+ readonly PREVISIT_SPEC="${DSH_PRE_DUEDILIGENCE_SPEC:-dsh-pre-duediligence@0.1.34}"
9
9
  readonly LEGACY_PREVISIT_NAME="qcc-previsit-dsh"
10
10
  readonly LEGACY_QCC_OAUTH_NAME="qcc-dsh-mcp-oauth"
11
11
 
package/lib/client.js CHANGED
@@ -1160,11 +1160,18 @@ function parseCardInsights(md) {
1160
1160
  const t = line.trim();
1161
1161
  if (!t.startsWith("|")) continue;
1162
1162
  const cells = t.split("|").slice(1, -1).map((c) => c.trim());
1163
- const level = cells[0] ?? "";
1163
+ const level = strip(cells[0] ?? "");
1164
1164
  const hit = ["\u7EA2\u7EBF", "\u5173\u6CE8", "\u4FE1\u606F"].find((l) => level.startsWith(l));
1165
1165
  if (hit === void 0) continue;
1166
1166
  risks.push({ level: hit, text: strip(cells[1] ?? "") });
1167
1167
  }
1168
+ for (const line of riskSrc.split("\n")) {
1169
+ if (line.trim().startsWith("|")) continue;
1170
+ const text = strip(line).replace(/^[\s#>\-•]+/, "");
1171
+ const match = /^(红线|关注|信息)(?:事项|风险)?\s*[::]\s*(.+)$/.exec(text);
1172
+ if (match) risks.push({ level: match[1], text: match[2] });
1173
+ else if (/^(?:本次(?:核验|核查|尽调)?(?:范围内)?[,, ]*)?未发现(?:重大)?红线(?:风险|事项)?[。;;]?$/.test(text)) risks.push({ level: "\u7EA2\u7EBF", text: "\u672C\u6B21\u672A\u53D1\u73B0\u7EA2\u7EBF" });
1174
+ }
1168
1175
  return {
1169
1176
  found: true,
1170
1177
  state: stateUndetermined ? null : state,
@@ -1189,12 +1196,13 @@ function RiskSummary({ task, insights, running }) {
1189
1196
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "qccPwNote", children: published ? "\u5DF2\u53D1\u5E03\u62A5\u544A\u7ED3\u8BBA\uFF1B\u4E0B\u65B9\u4FDD\u7559\u5728\u7EBF\u6838\u9A8C\u8FC7\u7A0B\u4E0E\u4F9D\u636E\u3002" : available ? "\u9636\u6BB5\u6027\u5224\u65AD \xB7 \u968F\u5DF2\u4FDD\u5B58\u5206\u6790\u8BB0\u5F55\u66F4\u65B0\uFF0C\u5C1A\u975E\u6700\u7EC8\u7ED3\u8BBA\u3002" : running ? "\u98CE\u9669\u5206\u6790\u4E2D\uFF0C\u6682\u672A\u5F62\u6210\u5206\u7EA7\uFF1B\u4E0D\u4EE5\u67E5\u8BE2\u5B8C\u6210\u63A8\u65AD\u65E0\u98CE\u9669\u3002" : "\u5C1A\u672A\u53D6\u5F97\u98CE\u9669\u5206\u7EA7\uFF0C\u4E0D\u4EE3\u8868\u7EA2\u7EBF\u4E3A\u96F6\u3002" }),
1190
1197
  available ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "qccPwRiskTiles", children: ["\u7EA2\u7EBF", "\u5173\u6CE8", "\u4FE1\u606F"].map((level) => {
1191
1198
  const reportRows = insights.risks.filter((row) => row.level === level);
1192
- const items = published ? reportRows.filter((row) => isRiskFindingText(row.text)).map((row) => ({ id: row.text, title: "", text: row.text, time: "", refs: [] })) : live.filter((row) => row.riskLevel === level).map((row) => ({ id: row.id, title: row.title, text: row.summary, time: row.updatedAt, refs: row.evidenceIds }));
1193
- const noFinding = published && !items.length && (reportRows.length > 0 || insights.riskNoRecord);
1199
+ const unresolved = reportRows.some((row) => /^(?:证据不足|结论未明确|尚未形成|待核验|未完成核验)/.test(row.text));
1200
+ const items = published ? reportRows.filter((row) => isRiskFindingText(row.text) && !/^(?:证据不足|结论未明确|尚未形成|待核验|未完成核验)/.test(row.text)).map((row) => ({ id: row.text, title: "", text: row.text, time: "", refs: [] })) : live.filter((row) => row.riskLevel === level).map((row) => ({ id: row.id, title: row.title, text: row.summary, time: row.updatedAt, refs: row.evidenceIds }));
1201
+ const noFinding = published && !unresolved && !items.length && reportRows.some((row) => /^(?:无[。;;]?|本次.*未发现.*|未发现.*|暂无(?:红线|该级别事项).*)$/.test(row.text.trim()));
1194
1202
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("article", { className: "qccPwRiskTile", "data-level": level, "data-clear": noFinding, "data-empty": !items.length, children: [
1195
1203
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "qccPwRiskTileTop", children: [
1196
1204
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: level === "\u7EA2\u7EBF" ? "\u7EA2\u7EBF \xB7 \u4F18\u5148\u6838\u5B9E" : level }),
1197
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: items.length ? items.length : noFinding ? "\u672C\u6B21\u672A\u53D1\u73B0" : "\u5F85\u7814\u5224" })
1205
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: items.length ? items.length : noFinding ? `\u672C\u6B21\u6838\u9A8C\u672A\u53D1\u73B0${level === "\u7EA2\u7EBF" ? "\u7EA2\u7EBF" : "\u8BE5\u7EA7\u522B\u4E8B\u9879"}` : running && !task?.reportReady ? "\u5206\u6790\u4E2D" : "\u7ED3\u8BBA\u672A\u660E\u786E" })
1198
1206
  ] }),
1199
1207
  items.map((row) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
1200
1208
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { children: row.title }),
@@ -1208,7 +1216,7 @@ function RiskSummary({ task, insights, running }) {
1208
1216
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { children: row.refs.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: ref }, ref)) })
1209
1217
  ] }) : null
1210
1218
  ] }, row.id)),
1211
- !items.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: noFinding ? "\u62A5\u544A\u5728\u672C\u6B21\u8986\u76D6\u8303\u56F4\u5185\u672A\u5217\u51FA\u8BE5\u7EA7\u522B\u4E8B\u9879\uFF1B\u4E0D\u4EE3\u8868\u98CE\u9669\u7EDD\u5BF9\u4E0D\u5B58\u5728\u3002" : "\u5C1A\u65E0\u8BE5\u7EA7\u522B\u5224\u65AD\uFF0C\u4E0D\u80FD\u89E3\u91CA\u4E3A\u96F6\u98CE\u9669\u3002" }) : null
1219
+ !items.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: noFinding ? "\u672C\u6B21\u62A5\u544A\u660E\u786E\u672A\u53D1\u73B0\u8BE5\u7EA7\u522B\u4E8B\u9879\uFF1B\u4EC5\u9650\u5DF2\u6838\u9A8C\u8303\u56F4\uFF0C\u4E0D\u4EE3\u8868\u98CE\u9669\u7EDD\u5BF9\u4E0D\u5B58\u5728\u3002" : running && !task?.reportReady ? "\u6B63\u5728\u6574\u7406\u8BE5\u7EA7\u522B\u7ED3\u8BBA\u3002" : "\u62A5\u544A\u672A\u63D0\u4F9B\u53EF\u8BC6\u522B\u7684\u8BE5\u7EA7\u522B\u7ED3\u8BBA\uFF0C\u53EF\u67E5\u770B\u539F\u62A5\u544A\u6216\u7EE7\u7EED\u8865\u5145\u6838\u9A8C\uFF1B\u4E0D\u4EE3\u8868\u4EFB\u52A1\u4ECD\u5728\u8FD0\u884C\uFF0C\u4E5F\u4E0D\u80FD\u89E3\u91CA\u4E3A\u96F6\u98CE\u9669\u3002" }) : null
1212
1220
  ] }, level);
1213
1221
  }) }) : null
1214
1222
  ] });
@@ -1368,6 +1376,8 @@ function selectHostedTask(records, active, dismissedTaskIds) {
1368
1376
  }
1369
1377
  function hostedTaskView(task) {
1370
1378
  if (task.reportReady || HOSTED_TERMINAL.has(task.state)) return "output";
1379
+ if (!task.entity || task.state === "needs-entity-confirmation" || task.state === "needs-entity-search") return "target";
1380
+ if (!task.runs.some((run) => run.dimension !== "entity_search")) return "scope";
1371
1381
  if (task.stage === "output" || task.state === "finalizing") {
1372
1382
  const lastRun = [...task.runs].reverse().find((run) => run.dimension !== "entity_search");
1373
1383
  if (lastRun !== void 0) return VERIFY_RUN.test(`${lastRun.dimension} ${lastRun.toolName ?? ""}`) ? "verify" : "collect";
@@ -1416,7 +1426,8 @@ function syncHostedTaskState(state, record, adopted, locateCurrentStage) {
1416
1426
  };
1417
1427
  const nextTask = captureId !== void 0 && captureId !== record.id ? { ...nextTaskBase, captureId } : nextTaskBase;
1418
1428
  const nextCompany = record.entity?.fullName ?? record.query;
1419
- const nextView = locateCurrentStage && !record.reportReady && !HOSTED_TERMINAL.has(record.state) && state.view !== "history" ? hostedTaskView(record) : state.view;
1429
+ const desiredView = hostedTaskView(record);
1430
+ const nextView = locateCurrentStage && !record.reportReady && !HOSTED_TERMINAL.has(record.state) && state.view !== "history" ? state.view === "target" && record.entity && (desiredView === "collect" || desiredView === "verify") ? "scope" : desiredView : state.view;
1420
1431
  if (previous?.id === nextTask.id && previous.captureId === nextTask.captureId && previous.company === nextTask.company && previous.prompt === nextTask.prompt && previous.createdAt === nextTask.createdAt && previous.nodeBaseline === nextTask.nodeBaseline && previous.seenRunning === nextTask.seenRunning && state.company === nextCompany && state.view === nextView) return state;
1421
1432
  return { ...state, task: nextTask, company: nextCompany, view: nextView };
1422
1433
  }
@@ -1571,60 +1582,44 @@ function PrevisitLogo(props) {
1571
1582
  // src/report-files-panel.tsx
1572
1583
  var import_react2 = require("react");
1573
1584
  var import_jsx_runtime5 = require("react/jsx-runtime");
1574
- function ReportFilesPanel({ taskId, sessionId }) {
1575
- const [files, setFiles] = (0, import_react2.useState)([]), [deliveries, setDeliveries] = (0, import_react2.useState)([]), [busy, setBusy] = (0, import_react2.useState)(false), [error, setError] = (0, import_react2.useState)("");
1576
- const url = `/previsit/api/tasks/${encodeURIComponent(taskId)}/files?sessionId=${encodeURIComponent(sessionId)}`;
1577
- (0, import_react2.useEffect)(() => {
1578
- let active = true;
1579
- setFiles([]);
1580
- setDeliveries([]);
1581
- setError("");
1582
- void fetch(url).then(async (res) => {
1583
- const body = await res.json();
1584
- if (!res.ok || !body.ok || !Array.isArray(body.files) || !Array.isArray(body.deliveries)) throw new Error(body.message ?? "\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25\uFF1A\u8FD4\u56DE\u7ED3\u6784\u4E0D\u5B8C\u6574");
1585
- if (active) {
1586
- setFiles(body.files);
1587
- setDeliveries(body.deliveries);
1588
- }
1589
- }).catch((e) => {
1590
- if (active) setError(String(e));
1591
- });
1592
- return () => {
1593
- active = false;
1594
- };
1595
- }, [url]);
1585
+ async function downloadReportFormat(taskId, sessionId, format) {
1586
+ const root = `/previsit/api/tasks/${encodeURIComponent(taskId)}/files`;
1587
+ const query = `?sessionId=${encodeURIComponent(sessionId)}`;
1588
+ const response = await fetch(root + query, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ format }) });
1589
+ const result = await response.json();
1590
+ if (!response.ok || !result.ok || !result.file?.id || !result.file.fileName) throw new Error(result.message ?? "\u62A5\u544A\u751F\u6210\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5");
1591
+ const file = await fetch(`${root}/${encodeURIComponent(result.file.id)}${query}`);
1592
+ if (!file.ok) throw new Error("\u62A5\u544A\u5DF2\u751F\u6210\uFF0C\u4F46\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5");
1593
+ const url = URL.createObjectURL(await file.blob());
1594
+ const anchor = document.createElement("a");
1595
+ anchor.href = url;
1596
+ anchor.download = result.file.fileName;
1597
+ document.body.append(anchor);
1598
+ anchor.click();
1599
+ anchor.remove();
1600
+ setTimeout(() => URL.revokeObjectURL(url), 0);
1601
+ }
1602
+ function ReportFilesPanel({ taskId, sessionId, onHtml }) {
1603
+ const [busy, setBusy] = (0, import_react2.useState)(null);
1604
+ const [error, setError] = (0, import_react2.useState)("");
1596
1605
  const generate = async (format) => {
1597
- setBusy(true);
1606
+ if (busy) return;
1607
+ setBusy(format);
1598
1608
  setError("");
1599
1609
  try {
1600
- const res = await fetch(url, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ format }) });
1601
- const body = await res.json();
1602
- if (!res.ok || !body.ok) throw new Error(body.message ?? "\u5BFC\u51FA\u5931\u8D25");
1603
- setFiles((previous) => [...previous.filter((f) => f.id !== body.file.id), body.file]);
1604
- } catch (e) {
1605
- setError(e instanceof Error ? e.message : String(e));
1610
+ await downloadReportFormat(taskId, sessionId, format);
1611
+ } catch (cause) {
1612
+ setError(cause instanceof Error ? cause.message : "\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5");
1606
1613
  } finally {
1607
- setBusy(false);
1614
+ setBusy(null);
1608
1615
  }
1609
1616
  };
1610
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "qccPwCard", "aria-label": "\u62A5\u544A\u884D\u751F\u6587\u4EF6", children: [
1611
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: "\u62A5\u544A\u884D\u751F\u6587\u4EF6" }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u8F6C\u6362\u683C\u5F0F\u4E0D\u6539\u53D8\u62A5\u544A\u7248\u672C\u3002\u6B63\u6587\u53CA Markdown \u6807\u8BB0\u4FDD\u7559\uFF0C\u6392\u7248\u4E0D\u7B49\u540C\u4E8E HTML\uFF1BPDF \u9700\u8981\u7BA1\u7406\u5458\u914D\u7F6E\u4E2D\u6587\u5B57\u4F53\u3002" }),
1613
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "qccPwSecondary", disabled: busy, onClick: () => void generate("docx"), children: "\u751F\u6210 Word" }),
1614
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "qccPwSecondary", disabled: busy, onClick: () => void generate("pdf"), children: "\u751F\u6210 PDF" }),
1615
- busy ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: "status", children: "\u6B63\u5728\u8F6C\u6362\uFF0C\u539F\u62A5\u544A\u4FDD\u6301\u4E0D\u53D8\u2026" }) : null,
1616
- error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: "alert", children: error }) : null,
1617
- files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
1618
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: `/previsit/api/tasks/${encodeURIComponent(taskId)}/files/${file.id}?sessionId=${encodeURIComponent(sessionId)}`, download: file.fileName, children: file.fileName }),
1619
- " \xB7 ",
1620
- file.size,
1621
- " \u5B57\u8282"
1622
- ] }, file.id)),
1623
- deliveries.map((d) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
1624
- "\u4EA4\u4ED8\u7533\u8BF7\uFF1A",
1625
- d.destination,
1626
- " \xB7 \u5F85\u914D\u7F6E\uFF0C\u5C1A\u672A\u4E0A\u4F20"
1627
- ] }, d.id))
1617
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "qccPwDownloadActions", "aria-label": "\u4E0B\u8F7D\u62A5\u544A", children: [
1618
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "qccPwSecondary", disabled: busy !== null, onClick: () => void generate("docx"), children: busy === "docx" ? "\u6B63\u5728\u751F\u6210 Word\u2026" : "\u4E0B\u8F7D Word" }),
1619
+ onHtml ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "qccPwSecondary", disabled: busy !== null, onClick: onHtml, children: "\u4E0B\u8F7D HTML" }) : null,
1620
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "qccPwPrimary", disabled: busy !== null, onClick: () => void generate("pdf"), children: busy === "pdf" ? "\u6B63\u5728\u751F\u6210 PDF\u2026" : "\u4E0B\u8F7D PDF" }),
1621
+ busy ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { role: "status", children: "\u751F\u6210\u5B8C\u6210\u540E\u81EA\u52A8\u4E0B\u8F7D" }) : null,
1622
+ error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { role: "alert", children: error }) : null
1628
1623
  ] });
1629
1624
  }
1630
1625
 
@@ -3093,6 +3088,7 @@ html[data-theme="dark"] .qccPrevisitHeroLogo,html.dark .qccPrevisitHeroLogo{colo
3093
3088
  .qccPwScopeList{display:grid;gap:0;margin:0}.qccPwScopeList>div{display:grid;grid-template-columns:96px 1fr;gap:12px;padding:10px 0;border-bottom:1px solid var(--qcc-border)}.qccPwScopeList>div:last-child{border-bottom:0}.qccPwScopeList dt{color:var(--qcc-secondary);font-size:12px}.qccPwScopeList dd{margin:0;color:var(--qcc-text);font-size:12px}
3094
3089
  .qccPwPrompt{max-height:220px;margin:0;padding:11px;border-radius:8px;background:var(--qcc-page);color:var(--qcc-secondary);font:11px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;overflow:auto}
3095
3090
  .qccPwFooter{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 16px;border-top:1px solid var(--qcc-border);background:var(--qcc-surface);flex:none}.qccPwFooterHint{min-width:0;color:var(--qcc-secondary);font-size:10px}.qccPwFooterHint[data-tone="error"]{color:var(--qcc-danger)}.qccPwFooterActions{display:flex;gap:8px;flex:none}.qccPwPrimary,.qccPwSecondary{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:34px;padding:0 13px;border:1px solid var(--qcc-border);border-radius:8px;background:var(--qcc-surface);color:var(--qcc-text);font:inherit;font-size:12px;cursor:pointer}.qccPwPrimary{border-color:var(--qcc-action);background:var(--qcc-action);color:var(--qcc-action-text)}.qccPwPrimary:hover{border-color:var(--qcc-action-hover);background:var(--qcc-action-hover)}.qccPwPrimary[aria-disabled="true"]{border-color:var(--qcc-border);background:var(--qcc-page);color:var(--qcc-secondary)}.qccPwPrimary[aria-disabled="true"]:hover{border-color:var(--qcc-border);background:var(--qcc-page);color:var(--qcc-secondary)}.qccPwSecondary:hover{border-color:var(--qcc-brand);background:var(--qcc-selected);color:var(--qcc-action)}
3091
+ .qccPwDownloadActions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;min-width:0}.qccPwDownloadActions [role="alert"],.qccPwDownloadActions [role="status"]{flex-basis:100%;font-size:12px;overflow-wrap:anywhere}.qccPwDownloadActions [role="alert"]{color:var(--qcc-danger)}.qccPwFooterActions{flex:1;flex-wrap:wrap;justify-content:space-between;min-width:0}.qccPwFooterHint:empty{display:none}.qccPwFooterActions>.qccPwDownloadActions{margin-left:auto}.qccPwDownloadActions button:disabled{opacity:.6;cursor:wait}
3096
3092
  .qccPwReportCard{padding:0;overflow:hidden}.qccPwReportFrame{display:block;width:100%;min-height:480px;border:0;background:#fff}
3097
3093
 
3098
3094
  .qccDockBody{display:grid;gap:12px}.qccDockRow{display:grid;grid-template-columns:68px 1fr;align-items:start;gap:10px}.qccDockLabel{padding-top:7px;color:var(--qcc-secondary);font-size:12px}.qccDockCompany{width:100%;min-height:38px;padding:8px 10px;border:1px solid var(--qcc-border);border-radius:8px;background:var(--qcc-surface);color:var(--qcc-text);font:inherit;font-size:16px;box-sizing:border-box}.qccDockChips{display:flex;flex-wrap:wrap;gap:7px}.qccDockChip{min-height:32px;padding:0 10px;border:1px solid var(--qcc-border);border-radius:8px;background:var(--qcc-surface);color:var(--qcc-secondary);font:inherit;font-size:11px;cursor:pointer}.qccDockChip[data-selected="true"]{border-color:var(--qcc-brand);background:var(--qcc-selected);color:var(--qcc-action)}.qccDockFoot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:4px}.qccDockHint{color:var(--qcc-secondary);font-size:10px;line-height:1.45}.qccDockHint[data-tone="error"]{color:var(--qcc-danger)}.qccDockActions{display:flex;gap:7px;flex:none}.qccDockBtn{min-height:34px;padding:0 11px;border:1px solid var(--qcc-border);border-radius:8px;background:var(--qcc-surface);color:var(--qcc-text);font:inherit;font-size:11px;cursor:pointer}.qccDockPrimary{border-color:var(--qcc-action);background:var(--qcc-action);color:var(--qcc-action-text)}
@@ -3408,8 +3404,8 @@ function OpportunityPanel(props) {
3408
3404
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScanFindings, { task: props.hostedTask }),
3409
3405
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { children: "\u5BA2\u89C2\u6570\u636E\u6458\u8981" }),
3410
3406
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CollectionCards, { task: props.hostedTask }),
3411
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "qccPwCard", children: [
3412
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("summary", { children: "\u98CE\u9669\u660E\u7EC6\u4E0E\u91C7\u96C6\u8986\u76D6" }),
3407
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "qccPwCard", children: [
3408
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { children: "\u98CE\u9669\u660E\u7EC6\u4E0E\u91C7\u96C6\u8986\u76D6" }),
3413
3409
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CollectionCards, { task: props.hostedTask, verification: true })
3414
3410
  ] })
3415
3411
  ] });
@@ -3605,17 +3601,7 @@ function HistoryPanel(props) {
3605
3601
  }, children: continuing ? "\u6B63\u5728\u63D0\u4EA4\u2026" : "\u521B\u5EFA\u8865\u5145\u4EFB\u52A1" }),
3606
3602
  continueError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", children: continueError }) : null
3607
3603
  ] }) : null,
3608
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "qccPwHistoryActions", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3609
- "button",
3610
- {
3611
- type: "button",
3612
- className: "qccPwPrimary",
3613
- disabled: !item.reportReady || !origin.complete || props.downloadingTaskId === item.id,
3614
- title: !origin.complete ? "\u65E7\u8BB0\u5F55\u7F3A\u5C11\u6765\u6E90 Session\uFF0C\u65E0\u6CD5\u5B89\u5168\u4E0B\u8F7D" : item.reportReady ? "\u4E0B\u8F7D\u5DF2\u4FDD\u5B58\u7684 HTML \u62A5\u544A" : "\u62A5\u544A\u5C1A\u672A\u751F\u6210",
3615
- onClick: () => props.onDownload(item),
3616
- children: props.downloadingTaskId === item.id ? "\u6B63\u5728\u4E0B\u8F7D\u2026" : "\u4E0B\u8F7D\u62A5\u544A \u2193"
3617
- }
3618
- ) })
3604
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "qccPwHistoryActions", children: item.reportReady && origin.complete ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ReportFilesPanel, { taskId: item.id, sessionId: item.sessionId, onHtml: () => props.onDownload(item) }, item.id) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "\u62A5\u544A\u5C1A\u672A\u751F\u6210\u6216\u8BB0\u5F55\u6765\u6E90\u4E0D\u5B8C\u6574\uFF0C\u6682\u4E0D\u53EF\u4E0B\u8F7D\u3002" }) })
3619
3605
  ] }),
3620
3606
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("nav", { className: "qccPwStages", "aria-label": "\u5386\u53F2\u4EFB\u52A1\u9636\u6BB5", role: "tablist", children: PREVISIT_PHASES.map((phase) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", role: "tab", "aria-selected": historyPhase === phase, className: "qccPwStage", "data-selected": historyPhase === phase, onClick: () => setHistoryPhase(phase), children: [
3621
3607
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "qccPwStageIcon", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: phase }) }),
@@ -3648,7 +3634,6 @@ function HistoryPanel(props) {
3648
3634
  historyPhase === "verify" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RiskPanel, { task: void 0, hostedTask: item, status, events: hostedToolEvents(item), insights: parseCardInsights(selectedReport ?? "") }) : null,
3649
3635
  historyPhase !== "output" ? null : reportHtml === null ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Feedback, { tone: "notice", title: item.reportReady ? "\u6B63\u5728\u8BFB\u53D6\u62A5\u544A" : "\u62A5\u544A\u5C1A\u672A\u751F\u6210", children: item.reportReady ? "\u5DF2\u627E\u5230\u62A5\u544A\u5236\u54C1\uFF0C\u4F46\u6B63\u6587\u6682\u672A\u8FD4\u56DE\uFF1B\u8BF7\u8FD4\u56DE\u6E05\u5355\u540E\u91CD\u8BD5\u3002" : "\u4EFB\u52A1\u8BE6\u60C5\u5DF2\u6062\u590D\uFF0C\u62A5\u544A\u751F\u6210\u540E\u53EF\u5728\u8FD9\u91CC\u67E5\u770B\u5E76\u4E0B\u8F7D\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "qccPwCard qccPwReportCard", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ReportViewer, { html: reportHtml }) }),
3650
3636
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MaterialPanel, { task: item }),
3651
- item.reportReady && origin.complete ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ReportFilesPanel, { taskId: item.id, sessionId: item.sessionId }, item.id) : null,
3652
3637
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "qccPwNote", children: "\u5386\u53F2\u8BE6\u60C5\u53EA\u8BFB\u53D6\u8BE5\u4EFB\u52A1\u6240\u5C5E Session \u7684 Host \u5236\u54C1\uFF0C\u4E0D\u4F1A\u91CD\u65B0\u8C03\u7528\u4F01\u67E5\u67E5\uFF0C\u4E5F\u4E0D\u4F1A\u8986\u76D6\u5F53\u524D\u4F1A\u8BDD\u4EFB\u52A1\u3002" })
3653
3638
  ] });
3654
3639
  }
@@ -3718,7 +3703,12 @@ function PrevisitWorkbenchTab(props) {
3718
3703
  const setView = (view) => {
3719
3704
  locatePrevisitView(props.shared, sessionId, view);
3720
3705
  };
3721
- const setPhase = (next) => setView(next);
3706
+ const manualNavigation = (0, import_react9.useRef)(false);
3707
+ const navigationTask = (0, import_react9.useRef)();
3708
+ const setPhase = (next) => {
3709
+ manualNavigation.current = true;
3710
+ setView(next);
3711
+ };
3722
3712
  const [runtime, setRuntime] = (0, import_react9.useState)(EMPTY_RUNTIME);
3723
3713
  const [plans, setPlans] = (0, import_react9.useState)([]);
3724
3714
  const [dismissedPlanIds, setDismissedPlanIds] = (0, import_react9.useState)([]);
@@ -3758,14 +3748,16 @@ function PrevisitWorkbenchTab(props) {
3758
3748
  setHostedTask(record);
3759
3749
  setHostError(void 0);
3760
3750
  if (record !== null) {
3751
+ if (navigationTask.current !== void 0 && navigationTask.current !== record.id) manualNavigation.current = false;
3752
+ navigationTask.current = record.id;
3761
3753
  const snapshot = props.ctx.sessions.binding?.(sessionId)?.session.getSnapshot();
3762
3754
  const adopted = snapshot === void 0 ? null : adoptTaskFromSnapshot(snapshot, sessionId, current.minimumNodeBaseline);
3763
3755
  const desiredView = hostedTaskView(record);
3764
3756
  const location = `${record.id}:${desiredView}`;
3765
3757
  const awaitingPlan = snapshot === void 0 ? void 0 : derivePlans(snapshot).find((plan) => plan.taskIds.length === 0 && !dismissedPlanIds.includes(plan.id) && !records.some((task2) => task2.planId === plan.id));
3766
- const shouldLocate = awaitingPlan === void 0 && lastHostedLocation.current !== location;
3758
+ const shouldLocate = !manualNavigation.current && awaitingPlan === void 0 && lastHostedLocation.current !== location;
3767
3759
  props.shared.update(sessionId, (state) => syncHostedTaskState(state, record, adopted, shouldLocate));
3768
- lastHostedLocation.current = location;
3760
+ lastHostedLocation.current = `${record.id}:${props.shared.get(sessionId).view}`;
3769
3761
  } else {
3770
3762
  lastHostedLocation.current = void 0;
3771
3763
  }
@@ -3891,6 +3883,7 @@ function PrevisitWorkbenchTab(props) {
3891
3883
  const insights = (0, import_react9.useMemo)(() => parseCardInsights(cardText), [cardText]);
3892
3884
  const reportHtml = (0, import_react9.useMemo)(() => cardText === null ? null : buildPrevisitReportHtml(cardText), [cardText]);
3893
3885
  const newTask = () => {
3886
+ manualNavigation.current = false;
3894
3887
  props.shared.update(sessionId, (state) => ({
3895
3888
  ...state,
3896
3889
  task: void 0,
@@ -4024,7 +4017,6 @@ function PrevisitWorkbenchTab(props) {
4024
4017
  ] }) : null,
4025
4018
  shared.view !== "history" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ExecutionProgress, { task: hostedTask, status, modelRunning: runtime.available ? runtime.running : void 0, syncError: hostError ?? runtime.lastAgentError ?? void 0 }) : null,
4026
4019
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "qccPwBody", children: [
4027
- shared.view === "output" && hostedTask?.reportReady ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ReportFilesPanel, { taskId: hostedTask.id, sessionId: hostedTask.sessionId }, hostedTask.id) : null,
4028
4020
  shared.view !== "history" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MaterialPanel, { task: hostedTask }) : null,
4029
4021
  shared.view === "target" && pendingPlan !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PlanCard, { plan: pendingPlan, onConfirm: async (message) => {
4030
4022
  await props.startPrompt(sessionId, message, true);
@@ -4032,7 +4024,10 @@ function PrevisitWorkbenchTab(props) {
4032
4024
  }, onDismiss: () => setDismissedPlanIds((ids) => [...ids, pendingPlan.id]) }, pendingPlan.id) : null,
4033
4025
  shared.view === "target" && pendingPlan === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SetupPanel, { sessionId, store: props.shared, task, input: resolveSessionInput(props.ctx, sessionId), send: async (prompt) => {
4034
4026
  await props.startPrompt(sessionId, prompt, true);
4035
- }, start: (prompt) => props.startPrompt(sessionId, prompt), onStarted: () => setPhase("collect") }) : null,
4027
+ }, start: (prompt) => props.startPrompt(sessionId, prompt), onStarted: () => {
4028
+ manualNavigation.current = false;
4029
+ setView("target");
4030
+ } }) : null,
4036
4031
  shared.view === "scope" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScopePanel, { state: shared, task, hostedTask }) : null,
4037
4032
  shared.view === "collect" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OpportunityPanel, { task, hostedTask, status, events: effectiveEvents, insights }) : null,
4038
4033
  shared.view === "verify" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RiskPanel, { task, hostedTask, status, events: effectiveEvents, insights }) : null,
@@ -4057,24 +4052,24 @@ function PrevisitWorkbenchTab(props) {
4057
4052
  void downloadHistoryReport(record);
4058
4053
  },
4059
4054
  onContinue: async (record, intent, requestId) => {
4055
+ manualNavigation.current = false;
4060
4056
  if (hostedTask && !HOSTED_TERMINAL.has(hostedTask.state)) throw new Error("\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u4EFB\u52A1");
4061
4057
  const prompt = `\u8BF7\u57FA\u4E8E\u5386\u53F2\u62A5\u544A\u521B\u5EFA\u8865\u5145\u5C3D\u8C03\uFF0C\u4E0D\u4FEE\u6539\u539F\u62A5\u544A\u3002\u8C03\u7528 previsit_continue\uFF0CparentTaskId=${record.id}\uFF0CrequestId=${requestId}\uFF0Cintent=${JSON.stringify(intent)}\u3002\u6CBF\u7528\u5DF2\u786E\u8BA4\u4E3B\u4F53\uFF0C\u6309\u8FD4\u56DE\u57FA\u7840\u62A5\u544A\u8865\u5145\u5DF2\u652F\u6301\u7EF4\u5EA6\uFF1B\u65E7\u8BC1\u636E\u4FDD\u7559\u539F\u65E5\u671F\u3002\u4F7F\u7528\u65B0\u4EFB\u52A1ID\u5B8C\u6210 previsit_finalize\uFF0C\u751F\u6210\u5B8C\u6574\u66F4\u65B0\u62A5\u544A\u3002`;
4062
4058
  const baseline = await props.startPrompt(sessionId, prompt);
4063
- props.shared.update(sessionId, (state) => ({ ...state, view: "collect", dismissedTaskIds: [.../* @__PURE__ */ new Set([...state.dismissedTaskIds, ...state.task ? [state.task.id] : [], ...hostedTask ? [hostedTask.id] : []])], task: { id: requestId, prompt, company: record.entity?.fullName ?? record.query, createdAt: (/* @__PURE__ */ new Date()).toISOString(), nodeBaseline: baseline, seenRunning: false, selection: state.selection } }));
4059
+ props.shared.update(sessionId, (state) => ({ ...state, view: "scope", dismissedTaskIds: [.../* @__PURE__ */ new Set([...state.dismissedTaskIds, ...state.task ? [state.task.id] : [], ...hostedTask ? [hostedTask.id] : []])], task: { id: requestId, prompt, company: record.entity?.fullName ?? record.query, createdAt: (/* @__PURE__ */ new Date()).toISOString(), nodeBaseline: baseline, seenRunning: false, selection: state.selection } }));
4064
4060
  }
4065
4061
  }
4066
4062
  ) : null
4067
4063
  ] }),
4068
4064
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("footer", { className: "qccPwFooter", children: [
4069
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "qccPwFooterHint", "data-tone": downloadNote === void 0 && hostError === void 0 ? void 0 : "error", children: downloadNote ?? hostError ?? "\u5BBF\u4E3B\u6536\u8D77\u4FA7\u62C9\u6216\u5173\u95ED\u672C Tab \u4E0D\u4F1A\u53D6\u6D88\u4EFB\u52A1\uFF0C\u4E5F\u4E0D\u4F1A\u5220\u9664\u5386\u53F2\u6216\u5236\u54C1\u3002" }),
4065
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "qccPwFooterHint", "data-tone": downloadNote === void 0 && hostError === void 0 ? void 0 : "error", children: downloadNote ?? hostError ?? "" }),
4070
4066
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "qccPwFooterActions", children: [
4071
4067
  shared.view !== "target" && task !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "qccPwSecondary", onClick: newTask, children: "\u65B0\u7684\u5C3D\u8C03" }) : null,
4072
- shared.view === "output" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "qccPwPrimary", "aria-disabled": status !== "ready" || cardText === null, title: status === "ready" ? "\u4E0B\u8F7D\u4E3A HTML \u6587\u4EF6\uFF0C\u53EF\u76F4\u63A5\u6253\u5F00\u6216\u6253\u5370" : "\u62A5\u544A\u5C1A\u672A\u5C31\u7EEA\uFF0C\u70B9\u51FB\u67E5\u770B\u539F\u56E0", onClick: () => {
4068
+ shared.view === "output" && hostedTask?.reportReady ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ReportFilesPanel, { taskId: hostedTask.id, sessionId: hostedTask.sessionId, onHtml: () => {
4073
4069
  void downloadReport();
4074
- }, children: [
4075
- "\u4E0B\u8F7D\u62A5\u544A",
4076
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "\u2193" })
4077
- ] }) : null
4070
+ } }, hostedTask.id) : shared.view === "output" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "qccPwSecondary", "aria-disabled": status !== "ready" || cardText === null, onClick: () => {
4071
+ void downloadReport();
4072
+ }, children: "\u4E0B\u8F7D HTML" }) : null
4078
4073
  ] })
4079
4074
  ] })
4080
4075
  ] });
@@ -4121,7 +4116,7 @@ function apply(ctx) {
4121
4116
  };
4122
4117
  const submissions = installSubmissionReveal(ctx, (sessionId) => {
4123
4118
  try {
4124
- openForSession(sessionId, "collect");
4119
+ openForSession(sessionId, "target");
4125
4120
  } catch (cause) {
4126
4121
  unavailableNotice?.remove();
4127
4122
  const notice = document.createElement("div");
package/lib/index.js CHANGED
@@ -1898,7 +1898,7 @@ function loadBundledSkill() {
1898
1898
  },
1899
1899
  metadata: {
1900
1900
  author: "QCC",
1901
- version: "0.1.33",
1901
+ version: "0.1.34",
1902
1902
  industry: "enterprise-services",
1903
1903
  mcpServers: ["qcc-company", "qcc-risk", "qcc-ipr", "qcc-operation", "qcc-executive"]
1904
1904
  }