dsh-pre-duediligence 0.1.0 → 0.1.1
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/README.md +10 -10
- package/install.sh +2 -2
- package/lib/client.js +362 -174
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/types/left-sidebar.d.ts +43 -0
- package/lib/types/workbench-v2.d.ts +3 -2
- package/package.json +1 -1
- package/skills/qcc-previsit-onepager/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-pre-duediligence
|
|
2
2
|
|
|
3
|
-
面向 DeepSeek Harness 的 Session
|
|
3
|
+
面向 DeepSeek Harness 的 Session 级访前尽调智能体。业务人员从左侧菜单进入,在会话级工作台定义一次拜访;Agent 调用企查查五类 MCP,使用机会与风险双引擎完成经营状态识别、假设与反证、风险核验,最终交付可追溯的访前尽调报告。
|
|
4
4
|
|
|
5
5
|
## 功能概览
|
|
6
6
|
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
### 工作台
|
|
10
10
|
|
|
11
11
|
- 使用 dsh-better-sidebar 0.17.1,不再使用遮挡对话的自定义浮层
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- 只在 DSH 左侧菜单增加“访前尽调智能体”入口;对应工作台标签在 Better Sidebar 的右侧“+”菜单中隐藏
|
|
13
|
+
- 用户点击左侧入口、工作台真实可见后才挂载业务样式;关闭后立即卸载,不影响 DSH 原页面
|
|
14
14
|
- 四阶段业务导航:
|
|
15
15
|
1. 定义拜访
|
|
16
16
|
2. 机会研判
|
|
@@ -55,7 +55,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/duhu2000/dsh-pre-duediligenc
|
|
|
55
55
|
|
|
56
56
|
1. `dsh-better-sidebar@0.17.1`:提供 Session 级右侧工作台容器。
|
|
57
57
|
2. `dsh-mcp-connector@0.2.32`:提供通用 MCP 连接器与市场,通过“企查查·企业工商”完成 OAuth,并动态挂载企业、风险、知产、经营、历史和董监高 MCP。
|
|
58
|
-
3. `dsh-pre-duediligence@0.1.
|
|
58
|
+
3. `dsh-pre-duediligence@0.1.1`:提供左侧智能体入口、访前工作台、点选拼句器和完整 Skill。
|
|
59
59
|
|
|
60
60
|
安装完成后停止旧的 DSH Web 进程并重新运行:
|
|
61
61
|
|
|
@@ -70,7 +70,7 @@ dsh web
|
|
|
70
70
|
~~~bash
|
|
71
71
|
dsh plugin --profile web add dsh-better-sidebar@0.17.1 --allow-build=node-pty
|
|
72
72
|
dsh plugin --profile web add dsh-mcp-connector@0.2.32
|
|
73
|
-
dsh plugin --profile web add dsh-pre-duediligence@0.1.
|
|
73
|
+
dsh plugin --profile web add dsh-pre-duediligence@0.1.1 --allow-build=dsh-pre-duediligence
|
|
74
74
|
dsh web
|
|
75
75
|
~~~
|
|
76
76
|
|
|
@@ -84,7 +84,7 @@ Better Sidebar 必须使用 `0.17.1`;工作台依赖它的 `targetedOpen` 与
|
|
|
84
84
|
dsh plugin --profile web list --depth 0
|
|
85
85
|
~~~
|
|
86
86
|
|
|
87
|
-
应能看到 `dsh-better-sidebar@0.17.1`、`dsh-mcp-connector@0.2.32` 和 `dsh-pre-duediligence@0.1.
|
|
87
|
+
应能看到 `dsh-better-sidebar@0.17.1`、`dsh-mcp-connector@0.2.32` 和 `dsh-pre-duediligence@0.1.1`。重启 DSH 并连接“企查查·企业工商”后,在左侧菜单点击“访前尽调智能体”打开工作台;Better Sidebar 的右侧“+”菜单不会再列出该入口。点击前 DSH 首页、输入框、消息流和 Session 头部均保持原样。
|
|
88
88
|
|
|
89
89
|
### 从旧访前尽调包迁移
|
|
90
90
|
|
|
@@ -100,7 +100,7 @@ dsh plugin --profile web remove qcc-previsit-dsh
|
|
|
100
100
|
|
|
101
101
|
如果 Web profile 已安装 `qcc-dsh-mcp-oauth`,不要让它与 MCP 连接器同时管理同名企查查 Server:
|
|
102
102
|
|
|
103
|
-
1. 先安装 `dsh-mcp-connector@0.2.32` 和 `dsh-pre-duediligence@0.1.
|
|
103
|
+
1. 先安装 `dsh-mcp-connector@0.2.32` 和 `dsh-pre-duediligence@0.1.1`,完全重启 DSH。
|
|
104
104
|
2. 打开“🧩 MCP连接器”,按界面提示迁移旧企查查授权;也可以重新连接“企查查·企业工商”。
|
|
105
105
|
3. 迁移完成后停止 DSH,执行 `dsh plugin --profile web remove qcc-dsh-mcp-oauth`。
|
|
106
106
|
4. 再次启动 DSH,在“已安装”中确认企查查连接健康,然后执行一次真实企业查询。
|
|
@@ -121,8 +121,8 @@ pnpm check 会执行 TypeScript 类型检查、Vitest 测试和 Host/Client 构
|
|
|
121
121
|
## 人工验收
|
|
122
122
|
|
|
123
123
|
1. 在 DSH 选择一个工作空间和 Session。
|
|
124
|
-
2.
|
|
125
|
-
3.
|
|
124
|
+
2. 确认左侧菜单出现“访前尽调智能体”,同时右侧 Better Sidebar 的“+”菜单不再出现该入口;首页标题、输入框、消息流和 Session 头部均保持 DSH 原样。
|
|
125
|
+
3. 点击左侧“访前尽调智能体”,确认会话级工作台打开;关闭后业务 UI 和样式不再存在。
|
|
126
126
|
4. 打开“定义拜访”,确认所有条件初始都未选择。
|
|
127
127
|
5. 选择“银行/信贷客户经理、首次拜访、风险与涉诉、股权与实控人、15分钟标准、一页纸简报”。
|
|
128
128
|
6. 将占位符替换为完整注册名称“企查查科技股份有限公司”,再切换档位,确认企业名称不丢失。
|
|
@@ -166,7 +166,7 @@ dsh-pre-duediligence/
|
|
|
166
166
|
## 安全与边界
|
|
167
167
|
|
|
168
168
|
- 插件不保存企查查 Token。
|
|
169
|
-
-
|
|
169
|
+
- 插件只在左侧栏增加独立入口,并把承载工作台的 Better Sidebar 标签从右侧“+”菜单隐藏;未点击入口时不挂载业务 DOM 或 CSS,也不修改 DSH 原生文案。
|
|
170
170
|
- 企业事实只能来自本次企查查 MCP 返回。
|
|
171
171
|
- 条件仅生成用户可见文本,不在 Client 侧调用 MCP。
|
|
172
172
|
- 用户点击“开始访前尽调”后才发送。
|
package/install.sh
CHANGED
|
@@ -5,7 +5,7 @@ set -euo pipefail
|
|
|
5
5
|
readonly PROFILE_NAME="${DSH_PROFILE:-web}"
|
|
6
6
|
readonly BETTER_SIDEBAR_SPEC="dsh-better-sidebar@0.17.1"
|
|
7
7
|
readonly MCP_CONNECTOR_SPEC="dsh-mcp-connector@0.2.32"
|
|
8
|
-
readonly PREVISIT_SPEC="${DSH_PRE_DUEDILIGENCE_SPEC:-dsh-pre-duediligence@0.1.
|
|
8
|
+
readonly PREVISIT_SPEC="${DSH_PRE_DUEDILIGENCE_SPEC:-dsh-pre-duediligence@0.1.1}"
|
|
9
9
|
readonly LEGACY_PREVISIT_NAME="qcc-previsit-dsh"
|
|
10
10
|
readonly LEGACY_QCC_OAUTH_NAME="qcc-dsh-mcp-oauth"
|
|
11
11
|
|
|
@@ -59,4 +59,4 @@ else
|
|
|
59
59
|
"重启后打开左侧“🧩 MCP连接器”,选择“企查查·企业工商”并完成 OAuth 授权。" \
|
|
60
60
|
"该连接会提供企业、风险、知产、经营、历史和董监高 MCP。"
|
|
61
61
|
fi
|
|
62
|
-
printf '%s\n' "
|
|
62
|
+
printf '%s\n' "在 DSH 左侧菜单点击“访前尽调智能体”即可打开;右侧标签菜单不再显示该入口,未点击时不会改动原页面。"
|
package/lib/client.js
CHANGED
|
@@ -39,7 +39,7 @@ __export(client_exports, {
|
|
|
39
39
|
module.exports = __toCommonJS(client_exports);
|
|
40
40
|
|
|
41
41
|
// src/workbench-v2.tsx
|
|
42
|
-
var
|
|
42
|
+
var import_react4 = require("react");
|
|
43
43
|
|
|
44
44
|
// src/previsit-dock.tsx
|
|
45
45
|
var import_react = require("react");
|
|
@@ -648,6 +648,55 @@ function PrevisitFields(props) {
|
|
|
648
648
|
var import_react2 = require("react");
|
|
649
649
|
var PREVISIT_WORKBENCH_TAB_ID = "dsh-pre-duediligence:agent";
|
|
650
650
|
var SUPPORTED_SIDEBAR_VERSION = /^0\.17\./u;
|
|
651
|
+
function treeContainsTab(node, tabId) {
|
|
652
|
+
if (node.kind === "leaf") {
|
|
653
|
+
return node.tabs.some((tab) => tab.id === tabId);
|
|
654
|
+
}
|
|
655
|
+
return node.children.some((child) => treeContainsTab(child, tabId));
|
|
656
|
+
}
|
|
657
|
+
function revealState(state, tabId) {
|
|
658
|
+
if (state.floats.some((float) => float.tab.id === tabId)) {
|
|
659
|
+
return state;
|
|
660
|
+
}
|
|
661
|
+
if (treeContainsTab(state.bottomSplits, tabId)) {
|
|
662
|
+
return state.bottomOpen ? state : { ...state, bottomOpen: true };
|
|
663
|
+
}
|
|
664
|
+
if (treeContainsTab(state.splits, tabId)) {
|
|
665
|
+
return state.panelOpen ? state : { ...state, panelOpen: true };
|
|
666
|
+
}
|
|
667
|
+
return state;
|
|
668
|
+
}
|
|
669
|
+
function createRevealController() {
|
|
670
|
+
const targets = /* @__PURE__ */ new Map();
|
|
671
|
+
const pending = /* @__PURE__ */ new Set();
|
|
672
|
+
return {
|
|
673
|
+
attach(sessionId, target) {
|
|
674
|
+
targets.set(sessionId, target);
|
|
675
|
+
if (pending.delete(sessionId)) {
|
|
676
|
+
target.store.reduce((state) => revealState(state, target.tabId));
|
|
677
|
+
}
|
|
678
|
+
return () => {
|
|
679
|
+
if (targets.get(sessionId) === target) {
|
|
680
|
+
targets.delete(sessionId);
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
},
|
|
684
|
+
request(sessionId) {
|
|
685
|
+
const target = targets.get(sessionId);
|
|
686
|
+
if (target === void 0) {
|
|
687
|
+
pending.add(sessionId);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
target.store.reduce((state) => revealState(state, target.tabId));
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function useWorkbenchReveal(controller, props) {
|
|
695
|
+
const sessionId = props.scope.sessionId;
|
|
696
|
+
const store = props.store;
|
|
697
|
+
const tabId = props.tab.id;
|
|
698
|
+
(0, import_react2.useEffect)(() => controller.attach(sessionId, { store, tabId }), [controller, sessionId, store, tabId]);
|
|
699
|
+
}
|
|
651
700
|
function assertBetterSidebar(service) {
|
|
652
701
|
if (!SUPPORTED_SIDEBAR_VERSION.test(service.version)) {
|
|
653
702
|
throw new Error("dsh-pre-duediligence requires dsh-better-sidebar 0.17.x");
|
|
@@ -662,10 +711,146 @@ function registerWorkbenchTab(service, component) {
|
|
|
662
711
|
id: PREVISIT_WORKBENCH_TAB_ID,
|
|
663
712
|
title: "\u8BBF\u524D\u5C3D\u8C03\u667A\u80FD\u4F53",
|
|
664
713
|
order: 30,
|
|
714
|
+
hidden: true,
|
|
665
715
|
single: true,
|
|
666
716
|
component
|
|
667
717
|
});
|
|
668
718
|
}
|
|
719
|
+
function openWorkbench(service, scope, reveal) {
|
|
720
|
+
assertBetterSidebar(service);
|
|
721
|
+
if (!service.isTabEnabled(PREVISIT_WORKBENCH_TAB_ID)) {
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
724
|
+
service.openTab({ type: PREVISIT_WORKBENCH_TAB_ID }, scope);
|
|
725
|
+
if (service.getSnapshot().sessionId === scope.sessionId) {
|
|
726
|
+
reveal.request(scope.sessionId);
|
|
727
|
+
}
|
|
728
|
+
return true;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// src/left-sidebar.tsx
|
|
732
|
+
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
733
|
+
var import_react3 = require("react");
|
|
734
|
+
var import_react_dom2 = require("react-dom");
|
|
735
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
736
|
+
var WORKSPACES_SLOT_SELECTOR = '[data-slot="sidebar.workspaces"]';
|
|
737
|
+
var LAUNCHER_MOUNT_SELECTOR = '[data-previsit-launcher-mount="true"]';
|
|
738
|
+
function ensureLauncherMount() {
|
|
739
|
+
const workspaceSlot = document.querySelector(WORKSPACES_SLOT_SELECTOR);
|
|
740
|
+
const parent = workspaceSlot?.parentElement;
|
|
741
|
+
if (workspaceSlot === null || parent === void 0 || parent === null) return null;
|
|
742
|
+
let mount = parent.querySelector(LAUNCHER_MOUNT_SELECTOR);
|
|
743
|
+
if (mount === null) {
|
|
744
|
+
mount = document.createElement("div");
|
|
745
|
+
mount.dataset.previsitLauncherMount = "true";
|
|
746
|
+
}
|
|
747
|
+
if (mount.parentElement !== parent) parent.insertBefore(mount, workspaceSlot);
|
|
748
|
+
return mount;
|
|
749
|
+
}
|
|
750
|
+
function LeftSidebarEntry(props) {
|
|
751
|
+
const [mount, setMount] = (0, import_react3.useState)(null);
|
|
752
|
+
const [busy, setBusy] = (0, import_react3.useState)(false);
|
|
753
|
+
const [error, setError] = (0, import_react3.useState)();
|
|
754
|
+
const wide = props.wide !== false;
|
|
755
|
+
(0, import_react3.useEffect)(() => {
|
|
756
|
+
let disposed = false;
|
|
757
|
+
const ownedMounts = /* @__PURE__ */ new Set();
|
|
758
|
+
const sync = () => {
|
|
759
|
+
if (disposed) return;
|
|
760
|
+
const next = ensureLauncherMount();
|
|
761
|
+
if (next !== null) ownedMounts.add(next);
|
|
762
|
+
setMount((current) => current === next ? current : next);
|
|
763
|
+
};
|
|
764
|
+
sync();
|
|
765
|
+
const observer = new MutationObserver(sync);
|
|
766
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
767
|
+
return () => {
|
|
768
|
+
disposed = true;
|
|
769
|
+
observer.disconnect();
|
|
770
|
+
for (const owned of ownedMounts) owned.remove();
|
|
771
|
+
};
|
|
772
|
+
}, []);
|
|
773
|
+
const launch = async () => {
|
|
774
|
+
if (busy || props.openAgent === void 0) return;
|
|
775
|
+
setBusy(true);
|
|
776
|
+
setError(void 0);
|
|
777
|
+
try {
|
|
778
|
+
await props.openAgent();
|
|
779
|
+
} catch (reason) {
|
|
780
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
781
|
+
} finally {
|
|
782
|
+
setBusy(false);
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
786
|
+
import_dsh_client_ui_primitives.Button,
|
|
787
|
+
{
|
|
788
|
+
type: "button",
|
|
789
|
+
variant: "ghost",
|
|
790
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives.IconAgentPresetOutline16, { size: 16 }),
|
|
791
|
+
"aria-label": "\u8BBF\u524D\u5C3D\u8C03\u667A\u80FD\u4F53",
|
|
792
|
+
"aria-busy": busy,
|
|
793
|
+
disabled: busy,
|
|
794
|
+
title: error ?? "\u6253\u5F00\u8BBF\u524D\u5C3D\u8C03\u667A\u80FD\u4F53",
|
|
795
|
+
onClick: () => {
|
|
796
|
+
void launch();
|
|
797
|
+
},
|
|
798
|
+
style: {
|
|
799
|
+
boxSizing: "border-box",
|
|
800
|
+
width: wide ? "100%" : 36,
|
|
801
|
+
height: wide ? 40 : 36,
|
|
802
|
+
justifyContent: wide ? "flex-start" : "center",
|
|
803
|
+
borderRadius: wide ? 10 : "50%",
|
|
804
|
+
paddingInline: wide ? 10 : 0,
|
|
805
|
+
whiteSpace: "nowrap"
|
|
806
|
+
},
|
|
807
|
+
children: wide ? busy ? "\u6B63\u5728\u6253\u5F00\u2026" : error === void 0 ? "\u8BBF\u524D\u5C3D\u8C03\u667A\u80FD\u4F53" : "\u6253\u5F00\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5" : null
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
if (mount === null) return button;
|
|
811
|
+
return (0, import_react_dom2.createPortal)(
|
|
812
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
813
|
+
"div",
|
|
814
|
+
{
|
|
815
|
+
"data-wide": wide,
|
|
816
|
+
style: { boxSizing: "border-box", width: wide ? "100%" : 36, paddingRight: wide ? 12 : 0 },
|
|
817
|
+
children: button
|
|
818
|
+
}
|
|
819
|
+
),
|
|
820
|
+
mount
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
async function resolveSessionId(ctx, service) {
|
|
824
|
+
const current = service.getSnapshot().sessionId ?? ctx.sessions.list?.getSnapshot().current;
|
|
825
|
+
if (current !== void 0) return current;
|
|
826
|
+
const workspace = ctx.workspaces?.list?.getSnapshot();
|
|
827
|
+
const workspaceId = workspace?.recentWorkspaceId ?? workspace?.items?.[0]?.workspaceId;
|
|
828
|
+
if (workspaceId === void 0) {
|
|
829
|
+
throw new Error("\u8BF7\u5148\u9009\u62E9\u4E00\u4E2A\u5DE5\u4F5C\u7A7A\u95F4\uFF0C\u518D\u6253\u5F00\u8BBF\u524D\u5C3D\u8C03\u667A\u80FD\u4F53");
|
|
830
|
+
}
|
|
831
|
+
const uiWorkspace = ctx.get?.("uiWorkspace");
|
|
832
|
+
const sessionId = ctx.workspaces?.connectWorkspace !== void 0 ? await ctx.workspaces.connectWorkspace(workspaceId) : uiWorkspace?.connectWorkspace !== void 0 ? await uiWorkspace.connectWorkspace(workspaceId) : await ctx.sessions.create?.({ workspaceId });
|
|
833
|
+
if (sessionId === void 0) {
|
|
834
|
+
throw new Error("\u5F53\u524D DSH \u7248\u672C\u6CA1\u6709\u53EF\u7528\u7684\u4F1A\u8BDD\u521B\u5EFA\u80FD\u529B");
|
|
835
|
+
}
|
|
836
|
+
ctx.sessions.open?.(sessionId);
|
|
837
|
+
return sessionId;
|
|
838
|
+
}
|
|
839
|
+
function registerLeftSidebarLauncher(ctx, service, reveal) {
|
|
840
|
+
ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
841
|
+
name: "sidebar.footer.action",
|
|
842
|
+
id: "dsh-pre-duediligence-launcher",
|
|
843
|
+
order: 20,
|
|
844
|
+
inject: () => ({
|
|
845
|
+
openAgent: async () => {
|
|
846
|
+
const sessionId = await resolveSessionId(ctx, service);
|
|
847
|
+
if (!openWorkbench(service, { sessionId }, reveal)) {
|
|
848
|
+
throw new Error("\u8BBF\u524D\u5C3D\u8C03\u5DE5\u4F5C\u53F0\u5F53\u524D\u4E0D\u53EF\u7528\uFF0C\u8BF7\u68C0\u67E5\u63D2\u4EF6\u914D\u7F6E");
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
})
|
|
852
|
+
}, LeftSidebarEntry));
|
|
853
|
+
}
|
|
669
854
|
|
|
670
855
|
// src/workbench-state.ts
|
|
671
856
|
var PREVISIT_PHASES = ["prepare", "opportunity", "risk", "delivery"];
|
|
@@ -944,8 +1129,8 @@ function riskSteps(events, insights, finished) {
|
|
|
944
1129
|
}
|
|
945
1130
|
|
|
946
1131
|
// src/workbench-v2.tsx
|
|
947
|
-
var
|
|
948
|
-
var inject = ["sessions", "conversation", "betterSidebar"];
|
|
1132
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1133
|
+
var inject = ["slots", "sessions", "workspaces", "conversation", "betterSidebar"];
|
|
949
1134
|
var STYLE_ID = "dsh-pre-duediligence-workbench";
|
|
950
1135
|
var PHASE_LABELS = {
|
|
951
1136
|
prepare: { label: "\u5C3D\u8C03\u8BBE\u5B9A", description: "\u4F01\u4E1A\u3001\u89D2\u8272\u4E0E\u8303\u56F4" },
|
|
@@ -970,40 +1155,40 @@ var EMPTY_RUNTIME = {
|
|
|
970
1155
|
};
|
|
971
1156
|
function Icon({ name }) {
|
|
972
1157
|
const paths = {
|
|
973
|
-
briefcase: /* @__PURE__ */ (0,
|
|
974
|
-
/* @__PURE__ */ (0,
|
|
975
|
-
/* @__PURE__ */ (0,
|
|
1158
|
+
briefcase: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: "3", y: "7", width: "18", height: "12", rx: "2" }),
|
|
1160
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 7V5h8v2M3 12h18M10 12v2h4v-2" })
|
|
976
1161
|
] }),
|
|
977
|
-
prepare: /* @__PURE__ */ (0,
|
|
978
|
-
/* @__PURE__ */ (0,
|
|
979
|
-
/* @__PURE__ */ (0,
|
|
1162
|
+
prepare: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1163
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M5 4h14v16H5z" }),
|
|
1164
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 8h8M8 12h8M8 16h5" })
|
|
980
1165
|
] }),
|
|
981
|
-
opportunity: /* @__PURE__ */ (0,
|
|
982
|
-
/* @__PURE__ */ (0,
|
|
983
|
-
/* @__PURE__ */ (0,
|
|
1166
|
+
opportunity: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1167
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "10.5", cy: "10.5", r: "5.5" }),
|
|
1168
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m15 15 4 4M10.5 7v7M7 10.5h7" })
|
|
984
1169
|
] }),
|
|
985
|
-
risk: /* @__PURE__ */ (0,
|
|
986
|
-
/* @__PURE__ */ (0,
|
|
987
|
-
/* @__PURE__ */ (0,
|
|
1170
|
+
risk: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1171
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 3 3.5 7v5c0 4.6 3.1 7.5 8.5 9 5.4-1.5 8.5-4.4 8.5-9V7z" }),
|
|
1172
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 8v5M12 17h.01" })
|
|
988
1173
|
] }),
|
|
989
|
-
delivery: /* @__PURE__ */ (0,
|
|
990
|
-
/* @__PURE__ */ (0,
|
|
991
|
-
/* @__PURE__ */ (0,
|
|
1174
|
+
delivery: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1175
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
|
|
1176
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
|
|
992
1177
|
] }),
|
|
993
|
-
clock: /* @__PURE__ */ (0,
|
|
994
|
-
/* @__PURE__ */ (0,
|
|
995
|
-
/* @__PURE__ */ (0,
|
|
1178
|
+
clock: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1179
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
|
|
1180
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 7v5l3 2" })
|
|
996
1181
|
] }),
|
|
997
|
-
check: /* @__PURE__ */ (0,
|
|
998
|
-
/* @__PURE__ */ (0,
|
|
999
|
-
/* @__PURE__ */ (0,
|
|
1182
|
+
check: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1183
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
|
|
1184
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m8 12 2.5 2.5L16 9" })
|
|
1000
1185
|
] }),
|
|
1001
|
-
warning: /* @__PURE__ */ (0,
|
|
1002
|
-
/* @__PURE__ */ (0,
|
|
1003
|
-
/* @__PURE__ */ (0,
|
|
1186
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1187
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 3 2.8 20h18.4z" }),
|
|
1188
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 9v4M12 17h.01" })
|
|
1004
1189
|
] })
|
|
1005
1190
|
};
|
|
1006
|
-
return /* @__PURE__ */ (0,
|
|
1191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "qccPwIcon", viewBox: "0 0 24 24", "aria-hidden": "true", children: paths[name] });
|
|
1007
1192
|
}
|
|
1008
1193
|
function collectRuntime(snapshot, baseline) {
|
|
1009
1194
|
const toolNames = /* @__PURE__ */ new Set();
|
|
@@ -1025,11 +1210,11 @@ function collectRuntime(snapshot, baseline) {
|
|
|
1025
1210
|
}
|
|
1026
1211
|
function Feedback(props) {
|
|
1027
1212
|
const icon = props.tone === "success" ? "check" : props.tone === "error" ? "warning" : "clock";
|
|
1028
|
-
return /* @__PURE__ */ (0,
|
|
1029
|
-
/* @__PURE__ */ (0,
|
|
1030
|
-
/* @__PURE__ */ (0,
|
|
1031
|
-
/* @__PURE__ */ (0,
|
|
1032
|
-
/* @__PURE__ */ (0,
|
|
1213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwFeedback", "data-tone": props.tone, role: props.tone === "error" ? "alert" : "status", children: [
|
|
1214
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwFeedbackIcon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { name: icon }) }),
|
|
1215
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1216
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: props.title }),
|
|
1217
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: props.children })
|
|
1033
1218
|
] })
|
|
1034
1219
|
] });
|
|
1035
1220
|
}
|
|
@@ -1042,51 +1227,51 @@ function SetupPanel(props) {
|
|
|
1042
1227
|
start: props.start,
|
|
1043
1228
|
onStarted: props.onStarted
|
|
1044
1229
|
});
|
|
1045
|
-
return /* @__PURE__ */ (0,
|
|
1046
|
-
/* @__PURE__ */ (0,
|
|
1047
|
-
/* @__PURE__ */ (0,
|
|
1048
|
-
/* @__PURE__ */ (0,
|
|
1049
|
-
/* @__PURE__ */ (0,
|
|
1230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "qccPwPanel", children: [
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "qccPwPageHeading", children: [
|
|
1232
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1233
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwEyebrow", children: "PREVISIT" }),
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { children: "\u5C3D\u8C03\u8BBE\u5B9A" })
|
|
1050
1235
|
] }),
|
|
1051
|
-
props.task === void 0 ? null : /* @__PURE__ */ (0,
|
|
1236
|
+
props.task === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwTaskId", children: props.task.id })
|
|
1052
1237
|
] }),
|
|
1053
|
-
/* @__PURE__ */ (0,
|
|
1054
|
-
props.task === void 0 ? null : /* @__PURE__ */ (0,
|
|
1055
|
-
/* @__PURE__ */ (0,
|
|
1056
|
-
/* @__PURE__ */ (0,
|
|
1238
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwCard qccPwSetupCard", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PrevisitFields, { actions, idPrefix: `qccPw-${props.sessionId}` }) }),
|
|
1239
|
+
props.task === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCard", children: [
|
|
1240
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwCardHeader", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "\u5DF2\u53D1\u9001\u7684\u4EFB\u52A1" }) }) }),
|
|
1241
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("pre", { className: "qccPwPrompt", children: props.task.prompt })
|
|
1057
1242
|
] })
|
|
1058
1243
|
] });
|
|
1059
1244
|
}
|
|
1060
1245
|
function Steps(props) {
|
|
1061
|
-
return /* @__PURE__ */ (0,
|
|
1062
|
-
/* @__PURE__ */ (0,
|
|
1063
|
-
/* @__PURE__ */ (0,
|
|
1064
|
-
/* @__PURE__ */ (0,
|
|
1065
|
-
step.note === void 0 ? null : /* @__PURE__ */ (0,
|
|
1246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "qccPwSteps", children: props.steps.map((step, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "qccPwStep", "data-state": step.state, children: [
|
|
1247
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwStepDot", children: step.state === "done" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { name: "check" }) : index + 1 }),
|
|
1248
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "qccPwStepCopy", children: [
|
|
1249
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("b", { children: step.label }),
|
|
1250
|
+
step.note === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("small", { children: step.note })
|
|
1066
1251
|
] })
|
|
1067
1252
|
] }, step.label)) });
|
|
1068
1253
|
}
|
|
1069
1254
|
function Dimensions(props) {
|
|
1070
1255
|
const done = props.items.filter((d) => d.status === "done").length;
|
|
1071
|
-
return /* @__PURE__ */ (0,
|
|
1072
|
-
/* @__PURE__ */ (0,
|
|
1073
|
-
/* @__PURE__ */ (0,
|
|
1074
|
-
done === 0 ? null : /* @__PURE__ */ (0,
|
|
1256
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCard", children: [
|
|
1257
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCardHeader", children: [
|
|
1258
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: props.title }) }),
|
|
1259
|
+
done === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "qccPwMode", children: [
|
|
1075
1260
|
done,
|
|
1076
1261
|
" \u9879"
|
|
1077
1262
|
] })
|
|
1078
1263
|
] }),
|
|
1079
|
-
props.items.length === 0 ? /* @__PURE__ */ (0,
|
|
1264
|
+
props.items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwEmpty", children: props.empty }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwDims", children: props.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwDim", "data-status": item.status, children: item.label }, item.label)) })
|
|
1080
1265
|
] });
|
|
1081
1266
|
}
|
|
1082
1267
|
function StagePanel(props) {
|
|
1083
|
-
return /* @__PURE__ */ (0,
|
|
1084
|
-
/* @__PURE__ */ (0,
|
|
1085
|
-
/* @__PURE__ */ (0,
|
|
1086
|
-
/* @__PURE__ */ (0,
|
|
1087
|
-
/* @__PURE__ */ (0,
|
|
1268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "qccPwPanel", children: [
|
|
1269
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "qccPwPageHeading", children: [
|
|
1270
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1271
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwEyebrow", children: props.eyebrow }),
|
|
1272
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { children: props.title })
|
|
1088
1273
|
] }),
|
|
1089
|
-
props.task === void 0 ? null : /* @__PURE__ */ (0,
|
|
1274
|
+
props.task === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwTaskId", children: props.task.id })
|
|
1090
1275
|
] }),
|
|
1091
1276
|
props.children
|
|
1092
1277
|
] });
|
|
@@ -1098,36 +1283,36 @@ function OpportunityPanel(props) {
|
|
|
1098
1283
|
const steps = opportunitySteps(props.events, insights, finished);
|
|
1099
1284
|
const dims = opportunityDimensions(props.events);
|
|
1100
1285
|
const concluded = insights.state !== null || insights.stateUndetermined;
|
|
1101
|
-
return /* @__PURE__ */ (0,
|
|
1102
|
-
/* @__PURE__ */ (0,
|
|
1103
|
-
/* @__PURE__ */ (0,
|
|
1104
|
-
/* @__PURE__ */ (0,
|
|
1105
|
-
/* @__PURE__ */ (0,
|
|
1106
|
-
/* @__PURE__ */ (0,
|
|
1107
|
-
insights.confidence === null ? null : /* @__PURE__ */ (0,
|
|
1286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(StagePanel, { eyebrow: "OPPORTUNITY", title: "\u7ECF\u8425\u7814\u5224", task: props.task, children: [
|
|
1287
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Steps, { steps }),
|
|
1288
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dimensions, { title: "\u5DF2\u53D6\u5F97", items: dims, empty: running ? "\u6B63\u5728\u5EFA\u7ACB\u4E3B\u4F53\u4E0E\u4FE1\u53F7\u96C6\u2026" : "\u5C3D\u8C03\u5F00\u59CB\u540E\u663E\u793A\u53D6\u5F97\u7684\u7EF4\u5EA6" }),
|
|
1289
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCard", children: [
|
|
1290
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCardHeader", children: [
|
|
1291
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "\u7ECF\u8425\u72B6\u6001" }) }),
|
|
1292
|
+
insights.confidence === null ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "qccPwMode", children: [
|
|
1108
1293
|
"\u7F6E\u4FE1\u5EA6 ",
|
|
1109
1294
|
insights.confidence
|
|
1110
1295
|
] })
|
|
1111
1296
|
] }),
|
|
1112
|
-
/* @__PURE__ */ (0,
|
|
1113
|
-
insights.stateUndetermined ? /* @__PURE__ */ (0,
|
|
1114
|
-
insights.industryLink === null ? null : /* @__PURE__ */ (0,
|
|
1297
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwStateStrip", "data-concluded": concluded, children: BUSINESS_STATES.map((state) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwState", "data-hit": insights.state === state, children: state }, state)) }),
|
|
1298
|
+
insights.stateUndetermined ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwNote", children: "\u72B6\u6001\u672A\u5B9A\uFF1A\u516C\u5F00\u8BC1\u636E\u4E0D\u8DB3\uFF0C\u672C\u6B21\u964D\u7EA7\u4E3A\u6E05\u5355\u5F0F\u7B80\u62A5\u3002" }) : null,
|
|
1299
|
+
insights.industryLink === null ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "qccPwNote", children: [
|
|
1115
1300
|
"\u4EA7\u4E1A\u94FE\u73AF\u8282\uFF1A",
|
|
1116
1301
|
insights.industryLink
|
|
1117
1302
|
] })
|
|
1118
1303
|
] }),
|
|
1119
|
-
/* @__PURE__ */ (0,
|
|
1120
|
-
/* @__PURE__ */ (0,
|
|
1121
|
-
/* @__PURE__ */ (0,
|
|
1122
|
-
insights.hypotheses.length === 0 ? null : /* @__PURE__ */ (0,
|
|
1304
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCard", children: [
|
|
1305
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCardHeader", children: [
|
|
1306
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "\u4E1A\u52A1\u5047\u8BBE" }) }),
|
|
1307
|
+
insights.hypotheses.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "qccPwMode", children: [
|
|
1123
1308
|
insights.hypotheses.length,
|
|
1124
1309
|
" \u6761"
|
|
1125
1310
|
] })
|
|
1126
1311
|
] }),
|
|
1127
|
-
insights.hypotheses.length === 0 ? /* @__PURE__ */ (0,
|
|
1128
|
-
/* @__PURE__ */ (0,
|
|
1129
|
-
/* @__PURE__ */ (0,
|
|
1130
|
-
/* @__PURE__ */ (0,
|
|
1312
|
+
insights.hypotheses.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwEmpty", children: finished ? insights.stateUndetermined ? "\u72B6\u6001\u672A\u5B9A\uFF0C\u672A\u751F\u6210\u5047\u8BBE\uFF1B\u76F8\u5173\u672A\u77E5\u5DF2\u8F6C\u5165\u73B0\u573A\u5FC5\u95EE" : insights.found ? "\u62A5\u544A\u4E2D\u672A\u8BC6\u522B\u51FA\u5047\u8BBE" : "\u62A5\u544A\u672A\u6355\u83B7" : running ? "\u72B6\u6001\u5224\u5B9A\u540E\u751F\u6210" : "\u5C3D\u8C03\u5F00\u59CB\u540E\u663E\u793A" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "qccPwHypos", children: insights.hypotheses.map((h) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
|
|
1313
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwPri", "data-p": h.priority, children: h.priority }),
|
|
1314
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("b", { children: h.id }),
|
|
1315
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: h.text })
|
|
1131
1316
|
] }, h.id)) })
|
|
1132
1317
|
] })
|
|
1133
1318
|
] });
|
|
@@ -1140,49 +1325,49 @@ function RiskPanel(props) {
|
|
|
1140
1325
|
const dims = riskDimensions(props.events);
|
|
1141
1326
|
const real = (level) => insights.risks.filter((r) => r.level === level && !/^(无|—|-|暂无|本次.*未发现)/.test(r.text));
|
|
1142
1327
|
const judged = insights.sections.includes("\u7EA2\u7EBF\u63D0\u793A");
|
|
1143
|
-
return /* @__PURE__ */ (0,
|
|
1144
|
-
/* @__PURE__ */ (0,
|
|
1145
|
-
/* @__PURE__ */ (0,
|
|
1146
|
-
/* @__PURE__ */ (0,
|
|
1147
|
-
/* @__PURE__ */ (0,
|
|
1148
|
-
!judged ? /* @__PURE__ */ (0,
|
|
1328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(StagePanel, { eyebrow: "RISK", title: "\u98CE\u9669\u6838\u67E5", task: props.task, children: [
|
|
1329
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Steps, { steps }),
|
|
1330
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dimensions, { title: "\u5DF2\u6838\u67E5", items: dims, empty: running ? "\u7B49\u5F85\u98CE\u9669\u626B\u63CF\u2026" : "\u5C3D\u8C03\u5F00\u59CB\u540E\u663E\u793A\u6838\u67E5\u7684\u7EF4\u5EA6" }),
|
|
1331
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCard", children: [
|
|
1332
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwCardHeader", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "\u98CE\u9669\u5206\u7EA7" }) }) }),
|
|
1333
|
+
!judged ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwEmpty", children: running ? "\u626B\u63CF\u4E0E\u4E0B\u94BB\u540E\u7ED9\u51FA\u5206\u7EA7" : finished ? "\u62A5\u544A\u672A\u6355\u83B7" : "\u5C3D\u8C03\u5F00\u59CB\u540E\u663E\u793A" }) : insights.riskNoRecord && insights.risks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwNote", children: "\u4F01\u4E1A\u81EA\u8EAB\u98CE\u9669\u626B\u63CF\u672A\u53D1\u73B0\u516C\u5F00\u8BB0\u5F55\uFF1B\u8FD9\u4E0D\u7B49\u4E8E\u4E0D\u5B58\u5728\u5176\u4ED6\u98CE\u9669\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwRiskTiles", children: ["\u7EA2\u7EBF", "\u5173\u6CE8", "\u4FE1\u606F"].map((level) => {
|
|
1149
1334
|
const items = real(level);
|
|
1150
|
-
return /* @__PURE__ */ (0,
|
|
1151
|
-
/* @__PURE__ */ (0,
|
|
1152
|
-
/* @__PURE__ */ (0,
|
|
1153
|
-
/* @__PURE__ */ (0,
|
|
1335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwRiskTile", "data-level": level, "data-empty": items.length === 0, children: [
|
|
1336
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwRiskTileTop", children: [
|
|
1337
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("b", { children: level }),
|
|
1338
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: items.length })
|
|
1154
1339
|
] }),
|
|
1155
|
-
/* @__PURE__ */ (0,
|
|
1340
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: items[0]?.text ?? "\u672C\u6B21\u672A\u53D1\u73B0" })
|
|
1156
1341
|
] }, level);
|
|
1157
1342
|
}) })
|
|
1158
1343
|
] })
|
|
1159
1344
|
] });
|
|
1160
1345
|
}
|
|
1161
1346
|
function ReportViewer(props) {
|
|
1162
|
-
const ref = (0,
|
|
1347
|
+
const ref = (0, import_react4.useRef)(null);
|
|
1163
1348
|
const fit = () => {
|
|
1164
1349
|
const el = ref.current;
|
|
1165
1350
|
const h = el?.contentDocument?.documentElement?.scrollHeight;
|
|
1166
1351
|
if (el !== null && h !== void 0 && h > 0) el.style.height = `${h + 8}px`;
|
|
1167
1352
|
};
|
|
1168
|
-
(0,
|
|
1353
|
+
(0, import_react4.useEffect)(() => {
|
|
1169
1354
|
fit();
|
|
1170
1355
|
}, [props.html]);
|
|
1171
1356
|
const embedded = props.html.replace("</head>", "<style>body{background:#fff}.sheet{margin:0;border:0;border-radius:0;box-shadow:none}.hero{padding:18px 20px 16px}.body{padding:6px 20px 20px}</style></head>");
|
|
1172
|
-
return /* @__PURE__ */ (0,
|
|
1357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("iframe", { ref, className: "qccPwReportFrame", title: "\u5C3D\u8C03\u62A5\u544A", sandbox: "allow-same-origin", srcDoc: embedded, onLoad: fit });
|
|
1173
1358
|
}
|
|
1174
1359
|
function DeliveryPanel(props) {
|
|
1175
1360
|
const ready = props.status === "ready";
|
|
1176
1361
|
if (props.reportHtml !== null) {
|
|
1177
|
-
return /* @__PURE__ */ (0,
|
|
1178
|
-
/* @__PURE__ */ (0,
|
|
1179
|
-
/* @__PURE__ */ (0,
|
|
1180
|
-
/* @__PURE__ */ (0,
|
|
1181
|
-
/* @__PURE__ */ (0,
|
|
1362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "qccPwPanel", children: [
|
|
1363
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "qccPwPageHeading", children: [
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1365
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwEyebrow", children: "REPORT" }),
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { children: "\u5C3D\u8C03\u62A5\u544A" })
|
|
1182
1367
|
] }),
|
|
1183
|
-
props.task === void 0 ? null : /* @__PURE__ */ (0,
|
|
1368
|
+
props.task === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwTaskId", children: props.task.id })
|
|
1184
1369
|
] }),
|
|
1185
|
-
/* @__PURE__ */ (0,
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwCard qccPwReportCard", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReportViewer, { html: props.reportHtml }) })
|
|
1186
1371
|
] });
|
|
1187
1372
|
}
|
|
1188
1373
|
const deliverables = [
|
|
@@ -1195,46 +1380,46 @@ function DeliveryPanel(props) {
|
|
|
1195
1380
|
["\u2466", "\u89E6\u8FBE\u5F00\u573A", "\u6765\u6E90\u3001\u5F52\u5C5E\u3001\u7528\u9014\u4E0E\u5F00\u573A\u767D"],
|
|
1196
1381
|
["\u2467", "\u8986\u76D6\u8BF4\u660E", "\u5DF2\u67E5\u3001\u672A\u67E5\u3001\u5931\u8D25\u4E0E\u8BC1\u636E\u5C42\u7EA7"]
|
|
1197
1382
|
];
|
|
1198
|
-
return /* @__PURE__ */ (0,
|
|
1199
|
-
/* @__PURE__ */ (0,
|
|
1200
|
-
/* @__PURE__ */ (0,
|
|
1201
|
-
/* @__PURE__ */ (0,
|
|
1202
|
-
/* @__PURE__ */ (0,
|
|
1203
|
-
/* @__PURE__ */ (0,
|
|
1383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "qccPwPanel", children: [
|
|
1384
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "qccPwPageHeading", children: [
|
|
1385
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwEyebrow", children: "REPORT" }),
|
|
1387
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { children: "\u5C3D\u8C03\u62A5\u544A" }),
|
|
1388
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "\u4E0D\u662F\u8D44\u6599\u5806\u780C\uFF0C\u53EA\u56DE\u7B54\u56DB\u4EF6\u4E8B\uFF1A\u53BB\u4E0D\u53BB\u3001\u89C1\u8C01\u3001\u804A\u4EC0\u4E48\u3001\u4EC0\u4E48\u4E0D\u80FD\u78B0\u3002" })
|
|
1204
1389
|
] }),
|
|
1205
|
-
props.task === void 0 ? null : /* @__PURE__ */ (0,
|
|
1390
|
+
props.task === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwTaskId", children: props.task.id })
|
|
1206
1391
|
] }),
|
|
1207
|
-
props.task === void 0 ? props.cardCaptured ? /* @__PURE__ */ (0,
|
|
1208
|
-
/* @__PURE__ */ (0,
|
|
1209
|
-
/* @__PURE__ */ (0,
|
|
1210
|
-
/* @__PURE__ */ (0,
|
|
1211
|
-
/* @__PURE__ */ (0,
|
|
1392
|
+
props.task === void 0 ? props.cardCaptured ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Feedback, { tone: "success", title: "\u62A5\u544A\u53EF\u4E0B\u8F7D", children: "\u5F53\u524D\u4F1A\u8BDD\u4E2D\u5DF2\u6709\u5C3D\u8C03\u62A5\u544A\uFF0C\u53EF\u76F4\u63A5\u4E0B\u8F7D\uFF1B\u65B0\u7684\u5C3D\u8C03\u5C06\u91CD\u65B0\u8BA1\u6570\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Feedback, { tone: "notice", title: "\u7B49\u5F85\u8BBE\u5B9A", children: "\u5B8C\u6210\u5C3D\u8C03\u8BBE\u5B9A\u540E\uFF0C\u62A5\u544A\u7ED3\u6784\u4E0E\u6267\u884C\u8FDB\u5EA6\u4F1A\u663E\u793A\u5728\u8FD9\u91CC\u3002" }) : ready ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Feedback, { tone: "success", title: "\u62A5\u544A\u5DF2\u751F\u6210", children: "\u6267\u884C\u5DF2\u7ED3\u675F\u3002\u53EF\u4E0B\u8F7D\u62A5\u544A\uFF0C\u6216\u56DE\u5230\u4F1A\u8BDD\u67E5\u770B\u5B8C\u6574\u5185\u5BB9\u4E0E\u4E8B\u5B9E\u5F15\u7528\u3002" }) : props.status === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Feedback, { tone: "error", title: "\u672C\u6B21\u5C3D\u8C03\u672A\u5B8C\u6574\u5B8C\u6210", children: "\u8BF7\u56DE\u5230\u4F1A\u8BDD\u67E5\u770B\u9519\u8BEF\uFF1B\u5DF2\u53D6\u5F97\u4E8B\u5B9E\u4ECD\u53EF\u4FDD\u7559\uFF0C\u5931\u8D25\u7EF4\u5EA6\u4E0D\u5F97\u5199\u6210\u96F6\u8BB0\u5F55\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Feedback, { tone: "notice", title: props.status === "running" ? "\u6B63\u5728\u751F\u6210\u62A5\u544A" : "\u7B49\u5F85\u5F00\u59CB", children: props.status === "running" && !props.cardCaptured ? "\u4F1A\u8BDD\u82E5\u505C\u5728\u5019\u9009\u4E3B\u4F53\u786E\u8BA4\uFF0C\u8BF7\u5148\u5728\u4F1A\u8BDD\u4E2D\u9009\u5B9A\u4F01\u4E1A\uFF1B\u62A5\u544A\u751F\u6210\u540E\u300C\u4E0B\u8F7D\u62A5\u544A\u300D\u624D\u53EF\u70B9\u3002" : "\u5B8C\u6210\u7ECF\u8425\u4E0E\u98CE\u9669\u4E24\u6761\u7EBF\u540E\uFF0C\u5C06\u81EA\u52A8\u5207\u6362\u5230\u672C\u9875\u3002" }),
|
|
1393
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCard", children: [
|
|
1394
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwCardHeader", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "\u62A5\u544A\u7ED3\u6784" }),
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "\u56FA\u5B9A\u516B\u6BB5\uFF0C\u53EF\u538B\u7F29\u6216\u5C55\u5F00\uFF1B\u4E8B\u5B9E\u3001\u63A8\u7406\u3001\u95EE\u9898\u548C\u8986\u76D6\u8FB9\u754C\u4E0D\u6DF7\u5199\u3002" })
|
|
1212
1397
|
] }) }),
|
|
1213
|
-
/* @__PURE__ */ (0,
|
|
1214
|
-
/* @__PURE__ */ (0,
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1217
|
-
/* @__PURE__ */ (0,
|
|
1398
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwDeliverables", children: deliverables.map(([number, title, detail]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwDeliverable", children: [
|
|
1399
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: number }),
|
|
1400
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1401
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("b", { children: title }),
|
|
1402
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("small", { children: detail })
|
|
1218
1403
|
] })
|
|
1219
1404
|
] }, number)) })
|
|
1220
1405
|
] }),
|
|
1221
|
-
/* @__PURE__ */ (0,
|
|
1222
|
-
/* @__PURE__ */ (0,
|
|
1223
|
-
/* @__PURE__ */ (0,
|
|
1224
|
-
/* @__PURE__ */ (0,
|
|
1406
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCard", children: [
|
|
1407
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "qccPwCardHeader", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
1408
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: "\u6267\u884C\u8986\u76D6" }),
|
|
1409
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "\u8FD9\u662F\u5DE5\u4F5C\u53F0\u4ECE\u5F53\u524D Session \u8BFB\u53D6\u7684\u771F\u5B9E\u6267\u884C\u4E8B\u4EF6\uFF0C\u4E0D\u662F\u5B8C\u6574\u6027\u8BC4\u5206\u3002" })
|
|
1225
1410
|
] }) }),
|
|
1226
|
-
/* @__PURE__ */ (0,
|
|
1227
|
-
/* @__PURE__ */ (0,
|
|
1228
|
-
/* @__PURE__ */ (0,
|
|
1229
|
-
/* @__PURE__ */ (0,
|
|
1411
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwCoverage", children: [
|
|
1412
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwMetric", children: [
|
|
1413
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: props.toolCount }),
|
|
1414
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u5DF2\u8BC6\u522B\u5DE5\u5177\u8C03\u7528" })
|
|
1230
1415
|
] }),
|
|
1231
|
-
/* @__PURE__ */ (0,
|
|
1232
|
-
/* @__PURE__ */ (0,
|
|
1233
|
-
/* @__PURE__ */ (0,
|
|
1416
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwMetric", children: [
|
|
1417
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: props.failedToolCount }),
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u5DE5\u5177\u9519\u8BEF" })
|
|
1234
1419
|
] }),
|
|
1235
|
-
/* @__PURE__ */ (0,
|
|
1236
|
-
/* @__PURE__ */ (0,
|
|
1237
|
-
/* @__PURE__ */ (0,
|
|
1420
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwMetric", children: [
|
|
1421
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: ready ? "4/4" : "\u2014" }),
|
|
1422
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u4E1A\u52A1\u9636\u6BB5" })
|
|
1238
1423
|
] })
|
|
1239
1424
|
] })
|
|
1240
1425
|
] })
|
|
@@ -1271,19 +1456,20 @@ function extractCardFromDom() {
|
|
|
1271
1456
|
}
|
|
1272
1457
|
function PrevisitWorkbenchTab(props) {
|
|
1273
1458
|
const sessionId = props.scope.sessionId;
|
|
1274
|
-
const shared = (0,
|
|
1459
|
+
const shared = (0, import_react4.useSyncExternalStore)(props.shared.subscribe, () => props.shared.get(sessionId));
|
|
1275
1460
|
const task = shared.task;
|
|
1276
1461
|
const setTask = (fn) => props.shared.update(sessionId, (s) => ({ ...s, task: fn(s.task) }));
|
|
1277
|
-
const [phase, setPhase] = (0,
|
|
1278
|
-
const [runtime, setRuntime] = (0,
|
|
1279
|
-
const [completedTaskId, setCompletedTaskId] = (0,
|
|
1280
|
-
const [cardText, setCardText] = (0,
|
|
1281
|
-
const [downloadNote, setDownloadNote] = (0,
|
|
1282
|
-
(
|
|
1462
|
+
const [phase, setPhase] = (0, import_react4.useState)("prepare");
|
|
1463
|
+
const [runtime, setRuntime] = (0, import_react4.useState)(EMPTY_RUNTIME);
|
|
1464
|
+
const [completedTaskId, setCompletedTaskId] = (0, import_react4.useState)();
|
|
1465
|
+
const [cardText, setCardText] = (0, import_react4.useState)(null);
|
|
1466
|
+
const [downloadNote, setDownloadNote] = (0, import_react4.useState)();
|
|
1467
|
+
useWorkbenchReveal(props.reveal, props);
|
|
1468
|
+
(0, import_react4.useInsertionEffect)(() => {
|
|
1283
1469
|
if (!props.visible) return;
|
|
1284
1470
|
return installStyles();
|
|
1285
1471
|
}, [props.visible]);
|
|
1286
|
-
(0,
|
|
1472
|
+
(0, import_react4.useEffect)(() => {
|
|
1287
1473
|
const face = props.ctx.sessions.binding?.(sessionId)?.session;
|
|
1288
1474
|
if (face === void 0) {
|
|
1289
1475
|
return;
|
|
@@ -1325,14 +1511,14 @@ function PrevisitWorkbenchTab(props) {
|
|
|
1325
1511
|
};
|
|
1326
1512
|
const status = deriveWorkbenchStatus(progressInput);
|
|
1327
1513
|
const phaseStates = derivePhaseStates(progressInput);
|
|
1328
|
-
const insights = (0,
|
|
1329
|
-
const reportHtml = (0,
|
|
1514
|
+
const insights = (0, import_react4.useMemo)(() => parseCardInsights(cardText), [cardText]);
|
|
1515
|
+
const reportHtml = (0, import_react4.useMemo)(() => {
|
|
1330
1516
|
if (cardText !== null) return buildPrevisitReportHtml(cardText);
|
|
1331
1517
|
if (status !== "ready" && task === void 0) return null;
|
|
1332
1518
|
const dom = extractCardFromDom();
|
|
1333
1519
|
return dom === null ? null : buildPrevisitReportFromRenderedHtml(dom.html, dom.text);
|
|
1334
1520
|
}, [cardText, status, phase, runtime.toolEvents.length]);
|
|
1335
|
-
(0,
|
|
1521
|
+
(0, import_react4.useEffect)(() => {
|
|
1336
1522
|
if (status !== "ready" && status !== "failed" || task === void 0 || completedTaskId === task.id) {
|
|
1337
1523
|
return;
|
|
1338
1524
|
}
|
|
@@ -1374,53 +1560,53 @@ function PrevisitWorkbenchTab(props) {
|
|
|
1374
1560
|
a.remove();
|
|
1375
1561
|
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
1376
1562
|
};
|
|
1377
|
-
if (!props.visible) return /* @__PURE__ */ (0,
|
|
1378
|
-
return /* @__PURE__ */ (0,
|
|
1379
|
-
/* @__PURE__ */ (0,
|
|
1380
|
-
/* @__PURE__ */ (0,
|
|
1381
|
-
/* @__PURE__ */ (0,
|
|
1382
|
-
/* @__PURE__ */ (0,
|
|
1383
|
-
/* @__PURE__ */ (0,
|
|
1384
|
-
/* @__PURE__ */ (0,
|
|
1385
|
-
/* @__PURE__ */ (0,
|
|
1563
|
+
if (!props.visible) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, {});
|
|
1564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "qccPwShell", "aria-label": "\u8BBF\u524D\u5C3D\u8C03\u5DE5\u4F5C\u53F0", "data-status": status, children: [
|
|
1565
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "qccPwHeader", children: [
|
|
1566
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwBrand", children: [
|
|
1567
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwBrandIcon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { name: "briefcase" }) }),
|
|
1568
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwBrandCopy", children: [
|
|
1569
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwTitleRow", children: [
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "qccPwTitle", children: "\u8BBF\u524D\u5C3D\u8C03\u5DE5\u4F5C\u53F0" }),
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwLiveDot", "data-status": status })
|
|
1386
1572
|
] }),
|
|
1387
|
-
/* @__PURE__ */ (0,
|
|
1573
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "qccPwSubtitle", children: "\u4F01\u67E5\u67E5\u4E8B\u5B9E\u9A71\u52A8 \xB7 \u673A\u4F1A\u4E0E\u98CE\u9669\u53CC\u5F15\u64CE" })
|
|
1388
1574
|
] })
|
|
1389
1575
|
] }),
|
|
1390
|
-
/* @__PURE__ */ (0,
|
|
1391
|
-
/* @__PURE__ */ (0,
|
|
1392
|
-
/* @__PURE__ */ (0,
|
|
1576
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwMeta", children: [
|
|
1577
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwStatus", "data-status": status, children: STATUS_LABELS[status] }),
|
|
1578
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "qccPwSession", children: [
|
|
1393
1579
|
"\u5F53\u524D Session \xB7 ",
|
|
1394
1580
|
sessionId.slice(0, 12)
|
|
1395
1581
|
] })
|
|
1396
1582
|
] })
|
|
1397
1583
|
] }),
|
|
1398
|
-
/* @__PURE__ */ (0,
|
|
1584
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("nav", { className: "qccPwStages", "aria-label": "\u8BBF\u524D\u4EFB\u52A1\u9636\u6BB5", children: PREVISIT_PHASES.map((current) => {
|
|
1399
1585
|
const phaseState = phaseStates.find((item) => item.id === current);
|
|
1400
|
-
return /* @__PURE__ */ (0,
|
|
1401
|
-
/* @__PURE__ */ (0,
|
|
1402
|
-
/* @__PURE__ */ (0,
|
|
1403
|
-
/* @__PURE__ */ (0,
|
|
1404
|
-
/* @__PURE__ */ (0,
|
|
1586
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { type: "button", className: "qccPwStage", "data-selected": phase === current, "data-progress": phaseState?.progress ?? "idle", onClick: () => setPhase(current), children: [
|
|
1587
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwStageIcon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { name: current }) }),
|
|
1588
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "qccPwStageCopy", children: [
|
|
1589
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: PHASE_LABELS[current].label }),
|
|
1590
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("small", { children: PHASE_LABELS[current].description })
|
|
1405
1591
|
] })
|
|
1406
1592
|
] }, current);
|
|
1407
1593
|
}) }),
|
|
1408
|
-
/* @__PURE__ */ (0,
|
|
1409
|
-
phase === "prepare" ? /* @__PURE__ */ (0,
|
|
1410
|
-
phase === "opportunity" ? /* @__PURE__ */ (0,
|
|
1411
|
-
phase === "risk" ? /* @__PURE__ */ (0,
|
|
1412
|
-
phase === "delivery" ? /* @__PURE__ */ (0,
|
|
1594
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwBody", children: [
|
|
1595
|
+
phase === "prepare" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SetupPanel, { sessionId, store: props.shared, task, start: (prompt) => props.startPrompt(sessionId, prompt), onStarted: () => setPhase("opportunity") }) : null,
|
|
1596
|
+
phase === "opportunity" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OpportunityPanel, { task, status, events: runtime.toolEvents, insights }) : null,
|
|
1597
|
+
phase === "risk" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RiskPanel, { task, status, events: runtime.toolEvents, insights }) : null,
|
|
1598
|
+
phase === "delivery" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DeliveryPanel, { task, status, toolCount: runtime.toolNames.length, failedToolCount: runtime.failedToolCount, cardCaptured: cardText !== null, reportHtml }) : null
|
|
1413
1599
|
] }),
|
|
1414
|
-
/* @__PURE__ */ (0,
|
|
1415
|
-
/* @__PURE__ */ (0,
|
|
1416
|
-
/* @__PURE__ */ (0,
|
|
1417
|
-
phase !== "prepare" && task !== void 0 ? /* @__PURE__ */ (0,
|
|
1418
|
-
phase === "delivery" ? /* @__PURE__ */ (0,
|
|
1600
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("footer", { className: "qccPwFooter", children: [
|
|
1601
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "qccPwFooterHint", "data-tone": downloadNote === void 0 ? void 0 : "error", children: downloadNote !== void 0 ? downloadNote : phase === "prepare" ? "" : "\u5DE5\u4F5C\u53F0\u7ED1\u5B9A\u5F53\u524D\u4F1A\u8BDD\uFF0C\u4F01\u4E1A\u4E8B\u5B9E\u4E0E\u5B8C\u6574\u62A5\u544A\u4FDD\u7559\u5728\u4F1A\u8BDD\u4E2D\u3002" }),
|
|
1602
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qccPwFooterActions", children: [
|
|
1603
|
+
phase !== "prepare" && task !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "qccPwSecondary", onClick: newTask, children: "\u65B0\u7684\u5C3D\u8C03" }) : null,
|
|
1604
|
+
phase === "delivery" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { type: "button", className: "qccPwPrimary", title: "\u4E0B\u8F7D\u4E3A HTML \u6587\u4EF6\uFF0C\u53EF\u76F4\u63A5\u6253\u5F00\u6216\u6253\u5370", onClick: downloadReport, children: [
|
|
1419
1605
|
"\u4E0B\u8F7D\u62A5\u544A",
|
|
1420
|
-
/* @__PURE__ */ (0,
|
|
1421
|
-
] }) : phase !== "prepare" ? /* @__PURE__ */ (0,
|
|
1606
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u2193" })
|
|
1607
|
+
] }) : phase !== "prepare" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { type: "button", className: "qccPwPrimary", onClick: returnToConversation, children: [
|
|
1422
1608
|
"\u8FD4\u56DE\u4F1A\u8BDD",
|
|
1423
|
-
/* @__PURE__ */ (0,
|
|
1609
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u2192" })
|
|
1424
1610
|
] }) : null
|
|
1425
1611
|
] })
|
|
1426
1612
|
] })
|
|
@@ -1440,6 +1626,7 @@ function installStyles() {
|
|
|
1440
1626
|
function apply(ctx) {
|
|
1441
1627
|
const service = ctx.betterSidebar;
|
|
1442
1628
|
const shared = createPrevisitStore();
|
|
1629
|
+
const reveal = createRevealController();
|
|
1443
1630
|
const startPrompt = async (sessionId, prompt) => {
|
|
1444
1631
|
const conversation = ctx.sessions.scope?.(sessionId)?.get("conversation");
|
|
1445
1632
|
if (conversation === void 0) throw new Error("conversation unavailable");
|
|
@@ -1448,9 +1635,10 @@ function apply(ctx) {
|
|
|
1448
1635
|
return baseline;
|
|
1449
1636
|
};
|
|
1450
1637
|
ctx.effect(
|
|
1451
|
-
() => registerWorkbenchTab(service, (props) => /* @__PURE__ */ (0,
|
|
1452
|
-
"dsh-pre-duediligence:
|
|
1638
|
+
() => registerWorkbenchTab(service, (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PrevisitWorkbenchTab, { ...props, ctx, shared, reveal, startPrompt })),
|
|
1639
|
+
"dsh-pre-duediligence: hidden workbench tab"
|
|
1453
1640
|
);
|
|
1641
|
+
registerLeftSidebarLauncher(ctx, service, reveal);
|
|
1454
1642
|
}
|
|
1455
1643
|
|
|
1456
1644
|
return module.exports;
|
package/lib/index.js
CHANGED
package/lib/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/skill-file.ts"],
|
|
4
|
-
"sourcesContent": ["import { readFileSync } from \"node:fs\"\nimport { fileURLToPath } from \"node:url\"\n\nimport { parseSkillFile } from \"./skill-file.js\"\n\nexport const inject = [\"skills\"] as const\n\nexport const SKILL_NAME = \"qcc-previsit-onepager\"\nexport const SKILL_DESCRIPTION =\n \"\u8C03\u7528\u4F01\u67E5\u67E5\u4E94\u7C7B MCP \u6267\u884C\u4F01\u4E1A\u8BBF\u524D\u5C3D\u8C03\uFF0C\u4EE5\u673A\u4F1A\u4E0E\u98CE\u9669\u53CC\u5F15\u64CE\u8BC6\u522B\u7ECF\u8425\u72B6\u6001\u3001\u5EFA\u7ACB\u5E76\u53CD\u8BC1\u4E1A\u52A1\u5047\u8BBE\uFF0C\u4EA4\u4ED8\u53EF\u8FFD\u6EAF\u7684\u8BBF\u524D\u5C3D\u8C03\u62A5\u544A\u3002\"\n\ntype SkillRegistration = {\n name: string\n description: string\n whenToUse: string\n content: string\n source: \"bundled\"\n resourceBase: {\n kind: \"directory\"\n path: string\n }\n metadata: Readonly<Record<string, unknown>>\n}\n\nexport type HostContext = {\n skills: {\n register(skill: SkillRegistration): () => void\n }\n}\n\nexport function loadBundledSkill(): SkillRegistration {\n const skillDirectoryUrl = new URL(\"../skills/qcc-previsit-onepager/\", import.meta.url)\n const skillSource = readFileSync(new URL(\"SKILL.md\", skillDirectoryUrl), \"utf8\")\n const { content } = parseSkillFile(skillSource)\n\n return {\n name: SKILL_NAME,\n description: SKILL_DESCRIPTION,\n whenToUse: \"\u7528\u6237\u8981\u6C42\u51C6\u5907\u5BA2\u6237\u62DC\u8BBF\u3001\u8BBF\u524D\u5C3D\u8C03\u3001\u4E00\u9875\u7EB8\u7B80\u62A5\u3001\u6388\u4FE1\u9762\u8C08\u3001\u5546\u52A1\u8C08\u5224\u3001\u7B7E\u7EA6\u6838\u67E5\u3001\u590D\u8BBF\u66F4\u65B0\u3001\u89E6\u8FBE\u8DEF\u5F84\u6216\u5F53\u9762\u63D0\u95EE\u6E05\u5355\u65F6\u4F7F\u7528\u3002\",\n content,\n source: \"bundled\",\n resourceBase: {\n kind: \"directory\",\n path: fileURLToPath(skillDirectoryUrl),\n },\n metadata: {\n author: \"QCC\",\n version: \"0.1.
|
|
4
|
+
"sourcesContent": ["import { readFileSync } from \"node:fs\"\nimport { fileURLToPath } from \"node:url\"\n\nimport { parseSkillFile } from \"./skill-file.js\"\n\nexport const inject = [\"skills\"] as const\n\nexport const SKILL_NAME = \"qcc-previsit-onepager\"\nexport const SKILL_DESCRIPTION =\n \"\u8C03\u7528\u4F01\u67E5\u67E5\u4E94\u7C7B MCP \u6267\u884C\u4F01\u4E1A\u8BBF\u524D\u5C3D\u8C03\uFF0C\u4EE5\u673A\u4F1A\u4E0E\u98CE\u9669\u53CC\u5F15\u64CE\u8BC6\u522B\u7ECF\u8425\u72B6\u6001\u3001\u5EFA\u7ACB\u5E76\u53CD\u8BC1\u4E1A\u52A1\u5047\u8BBE\uFF0C\u4EA4\u4ED8\u53EF\u8FFD\u6EAF\u7684\u8BBF\u524D\u5C3D\u8C03\u62A5\u544A\u3002\"\n\ntype SkillRegistration = {\n name: string\n description: string\n whenToUse: string\n content: string\n source: \"bundled\"\n resourceBase: {\n kind: \"directory\"\n path: string\n }\n metadata: Readonly<Record<string, unknown>>\n}\n\nexport type HostContext = {\n skills: {\n register(skill: SkillRegistration): () => void\n }\n}\n\nexport function loadBundledSkill(): SkillRegistration {\n const skillDirectoryUrl = new URL(\"../skills/qcc-previsit-onepager/\", import.meta.url)\n const skillSource = readFileSync(new URL(\"SKILL.md\", skillDirectoryUrl), \"utf8\")\n const { content } = parseSkillFile(skillSource)\n\n return {\n name: SKILL_NAME,\n description: SKILL_DESCRIPTION,\n whenToUse: \"\u7528\u6237\u8981\u6C42\u51C6\u5907\u5BA2\u6237\u62DC\u8BBF\u3001\u8BBF\u524D\u5C3D\u8C03\u3001\u4E00\u9875\u7EB8\u7B80\u62A5\u3001\u6388\u4FE1\u9762\u8C08\u3001\u5546\u52A1\u8C08\u5224\u3001\u7B7E\u7EA6\u6838\u67E5\u3001\u590D\u8BBF\u66F4\u65B0\u3001\u89E6\u8FBE\u8DEF\u5F84\u6216\u5F53\u9762\u63D0\u95EE\u6E05\u5355\u65F6\u4F7F\u7528\u3002\",\n content,\n source: \"bundled\",\n resourceBase: {\n kind: \"directory\",\n path: fileURLToPath(skillDirectoryUrl),\n },\n metadata: {\n author: \"QCC\",\n version: \"0.1.1\",\n industry: \"enterprise-services\",\n mcpServers: [\"qcc-company\", \"qcc-risk\", \"qcc-ipr\", \"qcc-operation\", \"qcc-executive\"],\n },\n }\n}\n\nexport function apply(ctx: HostContext): void {\n ctx.skills.register(loadBundledSkill())\n}\n", "export type ParsedSkillFile = {\n content: string\n frontmatter: string | null\n}\n\nexport function parseSkillFile(source: string): ParsedSkillFile {\n const normalized = source.replaceAll(\"\\r\\n\", \"\\n\")\n\n if (!normalized.startsWith(\"---\\n\")) {\n return { content: normalized.trim(), frontmatter: null }\n }\n\n const closingMarker = normalized.indexOf(\"\\n---\\n\", 4)\n\n if (closingMarker === -1) {\n throw new Error(\"SKILL.md \u7684 YAML frontmatter \u7F3A\u5C11\u7ED3\u675F\u6807\u8BB0\")\n }\n\n return {\n frontmatter: normalized.slice(4, closingMarker).trim(),\n content: normalized.slice(closingMarker + 5).trim(),\n }\n}\n"],
|
|
5
5
|
"mappings": ";AAAA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;;;ACIvB,SAAS,eAAe,QAAiC;AAC9D,QAAM,aAAa,OAAO,WAAW,QAAQ,IAAI;AAEjD,MAAI,CAAC,WAAW,WAAW,OAAO,GAAG;AACnC,WAAO,EAAE,SAAS,WAAW,KAAK,GAAG,aAAa,KAAK;AAAA,EACzD;AAEA,QAAM,gBAAgB,WAAW,QAAQ,WAAW,CAAC;AAErD,MAAI,kBAAkB,IAAI;AACxB,UAAM,IAAI,MAAM,uEAAoC;AAAA,EACtD;AAEA,SAAO;AAAA,IACL,aAAa,WAAW,MAAM,GAAG,aAAa,EAAE,KAAK;AAAA,IACrD,SAAS,WAAW,MAAM,gBAAgB,CAAC,EAAE,KAAK;AAAA,EACpD;AACF;;;ADjBO,IAAM,SAAS,CAAC,QAAQ;AAExB,IAAM,aAAa;AACnB,IAAM,oBACX;AAqBK,SAAS,mBAAsC;AACpD,QAAM,oBAAoB,IAAI,IAAI,oCAAoC,YAAY,GAAG;AACrF,QAAM,cAAc,aAAa,IAAI,IAAI,YAAY,iBAAiB,GAAG,MAAM;AAC/E,QAAM,EAAE,QAAQ,IAAI,eAAe,WAAW;AAE9C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,IACR,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,MAAM,cAAc,iBAAiB;AAAA,IACvC;AAAA,IACA,UAAU;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,UAAU;AAAA,MACV,YAAY,CAAC,eAAe,YAAY,WAAW,iBAAiB,eAAe;AAAA,IACrF;AAAA,EACF;AACF;AAEO,SAAS,MAAM,KAAwB;AAC5C,MAAI,OAAO,SAAS,iBAAiB,CAAC;AACxC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type BetterSidebarService, type RevealController } from "./better-sidebar.js";
|
|
2
|
+
type SnapshotStore<T> = {
|
|
3
|
+
getSnapshot(): T;
|
|
4
|
+
};
|
|
5
|
+
type WorkspaceSnapshot = {
|
|
6
|
+
items?: Array<{
|
|
7
|
+
workspaceId: string;
|
|
8
|
+
sessionIds?: string[];
|
|
9
|
+
}>;
|
|
10
|
+
recentWorkspaceId?: string;
|
|
11
|
+
};
|
|
12
|
+
type SlotsService = {
|
|
13
|
+
inject(name: string, setup: () => void | (() => void)): unknown;
|
|
14
|
+
register(descriptor: {
|
|
15
|
+
name: string;
|
|
16
|
+
id: string;
|
|
17
|
+
order?: number;
|
|
18
|
+
inject?: () => Record<string, unknown>;
|
|
19
|
+
}, component: (props: LeftSidebarEntryProps) => JSX.Element): () => void;
|
|
20
|
+
};
|
|
21
|
+
export type LeftSidebarHost = {
|
|
22
|
+
slots: SlotsService;
|
|
23
|
+
sessions: {
|
|
24
|
+
list?: SnapshotStore<{
|
|
25
|
+
current?: string;
|
|
26
|
+
}>;
|
|
27
|
+
create?(options: {
|
|
28
|
+
workspaceId: string;
|
|
29
|
+
}): Promise<string>;
|
|
30
|
+
open?(sessionId: string): void;
|
|
31
|
+
};
|
|
32
|
+
workspaces?: {
|
|
33
|
+
list?: SnapshotStore<WorkspaceSnapshot>;
|
|
34
|
+
connectWorkspace?(workspaceId: string): Promise<string>;
|
|
35
|
+
};
|
|
36
|
+
get?(name: string): unknown;
|
|
37
|
+
};
|
|
38
|
+
type LeftSidebarEntryProps = {
|
|
39
|
+
wide?: boolean;
|
|
40
|
+
openAgent?: () => Promise<void>;
|
|
41
|
+
};
|
|
42
|
+
export declare function registerLeftSidebarLauncher(ctx: LeftSidebarHost, service: BetterSidebarService, reveal: RevealController): void;
|
|
43
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type BetterSidebarService } from "./better-sidebar.js";
|
|
2
|
-
|
|
2
|
+
import { type LeftSidebarHost } from "./left-sidebar.js";
|
|
3
|
+
export declare const inject: readonly ["slots", "sessions", "workspaces", "conversation", "betterSidebar"];
|
|
3
4
|
type SnapshotStore<T> = {
|
|
4
5
|
getSnapshot(): T;
|
|
5
6
|
subscribe?(listener: () => void): () => void;
|
|
@@ -30,7 +31,7 @@ type ConversationSnapshot = {
|
|
|
30
31
|
nodes?: ConversationNode[];
|
|
31
32
|
lastAgentError?: string | null;
|
|
32
33
|
};
|
|
33
|
-
type ClientContext = {
|
|
34
|
+
type ClientContext = LeftSidebarHost & {
|
|
34
35
|
sessions: {
|
|
35
36
|
binding?(sessionId: string): {
|
|
36
37
|
session: SnapshotStore<ConversationSnapshot>;
|
package/package.json
CHANGED