dsh-pre-duediligence 0.1.0

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/lib/index.js ADDED
@@ -0,0 +1,57 @@
1
+ // src/index.ts
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ // src/skill-file.ts
6
+ function parseSkillFile(source) {
7
+ const normalized = source.replaceAll("\r\n", "\n");
8
+ if (!normalized.startsWith("---\n")) {
9
+ return { content: normalized.trim(), frontmatter: null };
10
+ }
11
+ const closingMarker = normalized.indexOf("\n---\n", 4);
12
+ if (closingMarker === -1) {
13
+ throw new Error("SKILL.md \u7684 YAML frontmatter \u7F3A\u5C11\u7ED3\u675F\u6807\u8BB0");
14
+ }
15
+ return {
16
+ frontmatter: normalized.slice(4, closingMarker).trim(),
17
+ content: normalized.slice(closingMarker + 5).trim()
18
+ };
19
+ }
20
+
21
+ // src/index.ts
22
+ var inject = ["skills"];
23
+ var SKILL_NAME = "qcc-previsit-onepager";
24
+ var SKILL_DESCRIPTION = "\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";
25
+ function loadBundledSkill() {
26
+ const skillDirectoryUrl = new URL("../skills/qcc-previsit-onepager/", import.meta.url);
27
+ const skillSource = readFileSync(new URL("SKILL.md", skillDirectoryUrl), "utf8");
28
+ const { content } = parseSkillFile(skillSource);
29
+ return {
30
+ name: SKILL_NAME,
31
+ description: SKILL_DESCRIPTION,
32
+ 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",
33
+ content,
34
+ source: "bundled",
35
+ resourceBase: {
36
+ kind: "directory",
37
+ path: fileURLToPath(skillDirectoryUrl)
38
+ },
39
+ metadata: {
40
+ author: "QCC",
41
+ version: "0.1.0",
42
+ industry: "enterprise-services",
43
+ mcpServers: ["qcc-company", "qcc-risk", "qcc-ipr", "qcc-operation", "qcc-executive"]
44
+ }
45
+ };
46
+ }
47
+ function apply(ctx) {
48
+ ctx.skills.register(loadBundledSkill());
49
+ }
50
+ export {
51
+ SKILL_DESCRIPTION,
52
+ SKILL_NAME,
53
+ apply,
54
+ inject,
55
+ loadBundledSkill
56
+ };
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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.0\",\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
+ "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
+ "names": []
7
+ }
@@ -0,0 +1,18 @@
1
+ import { type ReactNode } from "react";
2
+ import type { BetterSidebarService, SessionScope, SidebarState, SidebarStore, TabComponentProps } from "dsh-better-sidebar/client/service";
3
+ export type { BetterSidebarService, SessionScope, SidebarState, SidebarStore };
4
+ export type BetterSidebarTabProps = Pick<TabComponentProps, "scope" | "visible" | "store" | "tab">;
5
+ export declare const PREVISIT_WORKBENCH_TAB_ID = "dsh-pre-duediligence:agent";
6
+ type RevealTarget = {
7
+ store: SidebarStore;
8
+ tabId: string;
9
+ };
10
+ export type RevealController = {
11
+ attach(sessionId: string, target: RevealTarget): () => void;
12
+ request(sessionId: string): void;
13
+ };
14
+ export declare function createRevealController(): RevealController;
15
+ export declare function useWorkbenchReveal(controller: RevealController, props: Pick<BetterSidebarTabProps, "scope" | "store" | "tab">): void;
16
+ export declare function assertBetterSidebar(service: BetterSidebarService): void;
17
+ export declare function registerWorkbenchTab(service: BetterSidebarService, component: (props: BetterSidebarTabProps) => ReactNode): () => void;
18
+ export declare function openWorkbench(service: BetterSidebarService, scope: SessionScope, reveal: RevealController): boolean;
@@ -0,0 +1,3 @@
1
+ export { apply, inject } from "./workbench-v2.js";
2
+ export { applySelection, composeFullSentence, composeImperative, createTaskId, generateFromSelection, serializePrevisitRequest, updateManualText, validateComposerText, } from "./composer-model.js";
3
+ export type { ComposerSelection, ComposerState } from "./composer-model.js";
@@ -0,0 +1,125 @@
1
+ export declare const COMPANY_PLACEHOLDER = "\uFF08\u8FD9\u91CC\u8F93\u5165\u4F01\u4E1A\u540D\uFF09";
2
+ export type ComposerOption = {
3
+ id: string;
4
+ label: string;
5
+ phrase: string;
6
+ extraClause?: string;
7
+ };
8
+ export declare const ROLE_OPTIONS: readonly [{
9
+ readonly id: "bank_rm";
10
+ readonly label: "银行/信贷客户经理";
11
+ readonly phrase: "银行对公客户经理";
12
+ }, {
13
+ readonly id: "sales";
14
+ readonly label: "销售/BD";
15
+ readonly phrase: "销售";
16
+ }, {
17
+ readonly id: "procure";
18
+ readonly label: "采购/供应链";
19
+ readonly phrase: "采购负责人";
20
+ }, {
21
+ readonly id: "invest";
22
+ readonly label: "投资机构";
23
+ readonly phrase: "投资机构人员";
24
+ }, {
25
+ readonly id: "gov";
26
+ readonly label: "政府/园区招商";
27
+ readonly phrase: "园区招商人员";
28
+ }, {
29
+ readonly id: "other";
30
+ readonly label: "其他";
31
+ readonly phrase: "准备拜访企业的商务人员";
32
+ }];
33
+ export declare const PURPOSE_OPTIONS: readonly [{
34
+ readonly id: "first";
35
+ readonly label: "首次拜访";
36
+ readonly phrase: "首次";
37
+ }, {
38
+ readonly id: "nego";
39
+ readonly label: "谈判前拜访";
40
+ readonly phrase: "在商务谈判前";
41
+ }, {
42
+ readonly id: "revisit";
43
+ readonly label: "复访";
44
+ readonly phrase: "复访前更新式地";
45
+ readonly extraClause: "如有此前对该企业的尽调记录,请对比说明变化;若无记录,请照常全量尽调并注明是首次。";
46
+ }];
47
+ export declare const FOCUS_OPTIONS: readonly [{
48
+ readonly id: "risk";
49
+ readonly label: "风险与涉诉";
50
+ readonly phrase: "风险与涉诉";
51
+ }, {
52
+ readonly id: "equity";
53
+ readonly label: "股权与实控人";
54
+ readonly phrase: "股权与实控人";
55
+ }, {
56
+ readonly id: "finance";
57
+ readonly label: "经营与财务";
58
+ readonly phrase: "经营与财务";
59
+ }, {
60
+ readonly id: "contact";
61
+ readonly label: "联系人与触达";
62
+ readonly phrase: "联系人与触达路径";
63
+ }, {
64
+ readonly id: "ipr";
65
+ readonly label: "知识产权";
66
+ readonly phrase: "知识产权";
67
+ }, {
68
+ readonly id: "bidding";
69
+ readonly label: "招投标业绩";
70
+ readonly phrase: "招投标业绩";
71
+ }];
72
+ export declare const BUDGET_OPTIONS: readonly [{
73
+ readonly id: "fast";
74
+ readonly label: "3分钟速览";
75
+ readonly phrase: "速览";
76
+ }, {
77
+ readonly id: "standard";
78
+ readonly label: "15分钟标准";
79
+ readonly phrase: "标准";
80
+ }, {
81
+ readonly id: "deep";
82
+ readonly label: "深度尽调";
83
+ readonly phrase: "深度";
84
+ }];
85
+ export declare const OUTPUT_OPTIONS: readonly [{
86
+ readonly id: "onepager";
87
+ readonly label: "一页纸简报";
88
+ readonly phrase: "一页纸简报";
89
+ }, {
90
+ readonly id: "questions";
91
+ readonly label: "提问清单为主";
92
+ readonly phrase: "以当面提问清单为主的简报";
93
+ }, {
94
+ readonly id: "full";
95
+ readonly label: "完整报告";
96
+ readonly phrase: "完整尽调报告";
97
+ }, {
98
+ readonly id: "share";
99
+ readonly label: "可转发摘要";
100
+ readonly phrase: "适合转发给同事的简短摘要";
101
+ }];
102
+ export type ComposerSelection = {
103
+ role?: string;
104
+ purpose?: string;
105
+ focus: string[];
106
+ budget?: string;
107
+ output?: string;
108
+ };
109
+ export type ComposerMode = "generated" | "manual";
110
+ export type ComposerState = {
111
+ text: string;
112
+ lastGenerated: string;
113
+ lastCompany: string;
114
+ mode: ComposerMode;
115
+ };
116
+ export declare const EMPTY_SELECTION: ComposerSelection;
117
+ export declare const EMPTY_COMPOSER_STATE: ComposerState;
118
+ export declare function composeFullSentence(selection: ComposerSelection, company?: string): string;
119
+ export declare function composeImperative(selection: ComposerSelection): string;
120
+ export declare function updateManualText(state: ComposerState, text: string): ComposerState;
121
+ export declare function applySelection(state: ComposerState, selection: ComposerSelection, companyOverride?: string): ComposerState;
122
+ export declare function generateFromSelection(state: ComposerState, selection: ComposerSelection): ComposerState;
123
+ export declare function validateComposerText(text: string): string | undefined;
124
+ export declare function createTaskId(now?: Date, randomValue?: number): string;
125
+ export declare function serializePrevisitRequest(text: string, taskId: string): string;
@@ -0,0 +1,23 @@
1
+ export declare const inject: readonly ["skills"];
2
+ export declare const SKILL_NAME = "qcc-previsit-onepager";
3
+ export declare const SKILL_DESCRIPTION = "\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";
4
+ type SkillRegistration = {
5
+ name: string;
6
+ description: string;
7
+ whenToUse: string;
8
+ content: string;
9
+ source: "bundled";
10
+ resourceBase: {
11
+ kind: "directory";
12
+ path: string;
13
+ };
14
+ metadata: Readonly<Record<string, unknown>>;
15
+ };
16
+ export type HostContext = {
17
+ skills: {
18
+ register(skill: SkillRegistration): () => void;
19
+ };
20
+ };
21
+ export declare function loadBundledSkill(): SkillRegistration;
22
+ export declare function apply(ctx: HostContext): void;
23
+ export {};
@@ -0,0 +1,51 @@
1
+ import { type PrevisitStore } from "./previsit-store.js";
2
+ import { type CardSnapshot } from "./report-export.js";
3
+ type InputStateLike = {
4
+ draft: string;
5
+ phase?: string;
6
+ };
7
+ export type PrevisitDockProps = {
8
+ sessionId: string;
9
+ useInput: <S>(sel: (s: InputStateLike) => S) => S;
10
+ useSession?: <S>(sel: (s: CardSnapshot) => S) => S;
11
+ inputActions?: {
12
+ setDraft(text: string): void;
13
+ } | undefined;
14
+ store: PrevisitStore;
15
+ start: (prompt: string) => Promise<number>;
16
+ open: (phase?: "opportunity") => void;
17
+ };
18
+ declare function composerTextarea(): HTMLTextAreaElement | null;
19
+ declare function writeDraft(actions: PrevisitDockProps["inputActions"], text: string): void;
20
+ export { writeDraft as writeComposerDraft, composerTextarea };
21
+ export type ComposerActions = ReturnType<typeof usePrevisitComposer>;
22
+ export declare function usePrevisitComposer(args: {
23
+ sessionId: string;
24
+ store: PrevisitStore;
25
+ readDraft: () => string;
26
+ writeDraft: (text: string) => void;
27
+ start: (prompt: string) => Promise<number>;
28
+ onStarted?: () => void;
29
+ }): {
30
+ state: import("./previsit-store.js").PrevisitSessionState;
31
+ manual: boolean;
32
+ error: string | undefined;
33
+ submitting: boolean;
34
+ summary: string[];
35
+ toggleSingle: (key: "role" | "purpose" | "budget" | "output", id: string) => void;
36
+ toggleFocus: (id: string) => void;
37
+ setCompany: (company: string) => void;
38
+ append: () => void;
39
+ reset: () => void;
40
+ startTask: () => Promise<void>;
41
+ };
42
+ export declare function PrevisitFields(props: {
43
+ actions: ComposerActions;
44
+ idPrefix: string;
45
+ startLabel?: string;
46
+ }): JSX.Element;
47
+ export declare function PrevisitDock(props: PrevisitDockProps): JSX.Element;
48
+ export declare function DiligenceModeBar(props: {
49
+ sessionId: string;
50
+ store: PrevisitStore;
51
+ }): JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { type ComposerSelection, type ComposerState } from "./composer-model.js";
2
+ export type ActiveTask = {
3
+ id: string;
4
+ prompt: string;
5
+ createdAt: string;
6
+ nodeBaseline: number;
7
+ seenRunning: boolean;
8
+ selection: ComposerSelection;
9
+ };
10
+ export type DiligenceMode = "previsit" | "onboarding" | "transaction" | "ongoing";
11
+ export type PrevisitSessionState = {
12
+ selection: ComposerSelection;
13
+ company: string;
14
+ composer: ComposerState;
15
+ task: ActiveTask | undefined;
16
+ panel: DiligenceMode | null;
17
+ };
18
+ export declare const EMPTY_SESSION_STATE: PrevisitSessionState;
19
+ export type PrevisitStore = {
20
+ get(sessionId: string): PrevisitSessionState;
21
+ update(sessionId: string, fn: (state: PrevisitSessionState) => PrevisitSessionState): void;
22
+ subscribe(listener: () => void): () => void;
23
+ };
24
+ export declare function createPrevisitStore(): PrevisitStore;
25
+ export declare function summarizeSelection(state: PrevisitSessionState, labels: {
26
+ role: (id: string) => string | undefined;
27
+ purpose: (id: string) => string | undefined;
28
+ focus: (id: string) => string | undefined;
29
+ budget: (id: string) => string | undefined;
30
+ output: (id: string) => string | undefined;
31
+ }): string[];
@@ -0,0 +1,43 @@
1
+ export type ReportMeta = {
2
+ company?: string;
3
+ generatedAt?: string;
4
+ };
5
+ export type CardNode = {
6
+ kind?: string;
7
+ role?: string;
8
+ text?: string;
9
+ content?: unknown;
10
+ message?: {
11
+ content?: unknown;
12
+ } | null;
13
+ parts?: Array<{
14
+ text?: string;
15
+ type?: string;
16
+ } | string>;
17
+ call?: {
18
+ name?: string;
19
+ } | null;
20
+ };
21
+ export type CardSnapshot = {
22
+ nodes?: CardNode[];
23
+ running?: boolean;
24
+ };
25
+ export declare function adoptTaskFromSnapshot(snapshot: CardSnapshot): {
26
+ id: string;
27
+ prompt: string;
28
+ nodeBaseline: number;
29
+ } | null;
30
+ export declare function extractCardText(snapshot: CardSnapshot, baseline: number): string | null;
31
+ export declare function humanizeCell(text: string): string;
32
+ export declare function stripFactIds(text: string): string;
33
+ export declare function humanizeHypothesis(text: string): string;
34
+ export declare function normalizeHeading(text: string): string;
35
+ export declare function renderCardMarkdown(md: string): string;
36
+ export type ReportHero = {
37
+ company: string;
38
+ anchor: string;
39
+ when: string;
40
+ };
41
+ export declare function wrapPrevisitReport(bodyHtml: string, m: ReportHero): string;
42
+ export declare function buildPrevisitReportHtml(cardMarkdown: string, meta?: ReportMeta): string;
43
+ export declare function buildPrevisitReportFromRenderedHtml(bodyHtml: string, plainText: string, meta?: ReportMeta): string;
@@ -0,0 +1,5 @@
1
+ export type ParsedSkillFile = {
2
+ content: string;
3
+ frontmatter: string | null;
4
+ };
5
+ export declare function parseSkillFile(source: string): ParsedSkillFile;
@@ -0,0 +1,40 @@
1
+ export type ToolEvent = {
2
+ name: string;
3
+ status: "running" | "done" | "failed";
4
+ };
5
+ export type StepState = "done" | "active" | "idle";
6
+ export type Step = {
7
+ label: string;
8
+ state: StepState;
9
+ note?: string | undefined;
10
+ };
11
+ export type Dimension = {
12
+ label: string;
13
+ status: "done" | "running" | "failed";
14
+ };
15
+ export declare function opportunityDimensions(events: ToolEvent[]): Dimension[];
16
+ export declare function riskDimensions(events: ToolEvent[]): Dimension[];
17
+ export declare const BUSINESS_STATES: readonly ["产能建设期", "客户导入期", "产能爬坡期", "订单增长期", "稳定经营期", "收缩承压期", "资本运作期", "风险暴露期"];
18
+ export type Hypothesis = {
19
+ id: string;
20
+ priority: string;
21
+ text: string;
22
+ };
23
+ export type RiskItem = {
24
+ level: "红线" | "关注" | "信息";
25
+ text: string;
26
+ };
27
+ export type CardInsights = {
28
+ found: boolean;
29
+ state: string | null;
30
+ stateUndetermined: boolean;
31
+ confidence: string | null;
32
+ industryLink: string | null;
33
+ hypotheses: Hypothesis[];
34
+ risks: RiskItem[];
35
+ riskNoRecord: boolean;
36
+ sections: string[];
37
+ };
38
+ export declare function parseCardInsights(md: string | null): CardInsights;
39
+ export declare function opportunitySteps(events: ToolEvent[], insights: CardInsights, finished: boolean): Step[];
40
+ export declare function riskSteps(events: ToolEvent[], insights: CardInsights, finished: boolean): Step[];
@@ -0,0 +1,20 @@
1
+ export declare const PREVISIT_PHASES: readonly ["prepare", "opportunity", "risk", "delivery"];
2
+ export type PrevisitPhase = (typeof PREVISIT_PHASES)[number];
3
+ export type PhaseProgress = "idle" | "active" | "done" | "failed";
4
+ export type WorkbenchStatus = "empty" | "waiting-agent" | "running" | "ready" | "failed";
5
+ export type SessionProgressInput = {
6
+ hasTask: boolean;
7
+ running: boolean;
8
+ seenRunning: boolean;
9
+ lastAgentError: string | null;
10
+ partial: boolean;
11
+ toolNames: string[];
12
+ };
13
+ export type PhaseState = {
14
+ id: PrevisitPhase;
15
+ progress: PhaseProgress;
16
+ };
17
+ export declare function isOpportunityTool(name: string): boolean;
18
+ export declare function isRiskTool(name: string): boolean;
19
+ export declare function deriveWorkbenchStatus(input: SessionProgressInput): WorkbenchStatus;
20
+ export declare function derivePhaseStates(input: SessionProgressInput): PhaseState[];
@@ -0,0 +1 @@
1
+ export declare const WORKBENCH_CSS: string;
@@ -0,0 +1,46 @@
1
+ import { type BetterSidebarService } from "./better-sidebar.js";
2
+ export declare const inject: readonly ["sessions", "conversation", "betterSidebar"];
3
+ type SnapshotStore<T> = {
4
+ getSnapshot(): T;
5
+ subscribe?(listener: () => void): () => void;
6
+ };
7
+ type ConversationNode = {
8
+ kind?: string;
9
+ role?: string;
10
+ call?: {
11
+ name?: string;
12
+ } | null;
13
+ isError?: boolean;
14
+ text?: string;
15
+ content?: unknown;
16
+ message?: {
17
+ content?: unknown;
18
+ } | null;
19
+ parts?: Array<{
20
+ text?: string;
21
+ type?: string;
22
+ } | string>;
23
+ };
24
+ type ConversationSnapshot = {
25
+ running?: boolean;
26
+ partial?: unknown | null;
27
+ runningCalls?: Array<{
28
+ name?: string;
29
+ }>;
30
+ nodes?: ConversationNode[];
31
+ lastAgentError?: string | null;
32
+ };
33
+ type ClientContext = {
34
+ sessions: {
35
+ binding?(sessionId: string): {
36
+ session: SnapshotStore<ConversationSnapshot>;
37
+ } | undefined;
38
+ scope?(sessionId: string): {
39
+ get(name: string): unknown;
40
+ } | undefined;
41
+ };
42
+ betterSidebar: BetterSidebarService;
43
+ effect(setup: () => void | (() => void), label?: string): unknown;
44
+ };
45
+ export declare function apply(ctx: ClientContext): void;
46
+ export {};
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "dsh-pre-duediligence",
3
+ "version": "0.1.0",
4
+ "description": "Session 级 DeepSeek Harness 访前尽调工作台,使用企查查 MCP 生成可追溯的访前尽调报告。",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/duhu2000/dsh-pre-duediligence.git"
9
+ },
10
+ "homepage": "https://github.com/duhu2000/dsh-pre-duediligence#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/duhu2000/dsh-pre-duediligence/issues"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "type": "module",
18
+ "packageManager": "pnpm@10.17.0",
19
+ "main": "lib/index.js",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./lib/types/index.d.ts",
23
+ "default": "./lib/index.js"
24
+ },
25
+ "./client": {
26
+ "types": "./lib/types/client.d.ts",
27
+ "default": "./lib/client.js"
28
+ },
29
+ "./cordis.patch.yml": "./cordis.patch.yml",
30
+ "./package.json": "./package.json"
31
+ },
32
+ "files": [
33
+ "lib",
34
+ "skills",
35
+ "install.sh",
36
+ "cordis.patch.yml",
37
+ "README.md",
38
+ "THIRD_PARTY_NOTICES.md",
39
+ "LICENSE"
40
+ ],
41
+ "scripts": {
42
+ "build": "node scripts/build.mjs && tsc -p tsconfig.build.json",
43
+ "typecheck": "tsc -p tsconfig.json --noEmit",
44
+ "test": "vitest run",
45
+ "check": "pnpm run typecheck && pnpm run test && pnpm run build",
46
+ "prepare": "pnpm run build",
47
+ "prepublishOnly": "pnpm run check"
48
+ },
49
+ "dsh": {
50
+ "bundle": {
51
+ "patch": "./cordis.patch.yml"
52
+ },
53
+ "client": {
54
+ "platform": "web",
55
+ "inject": [
56
+ "@deepseek-ai/dsh-client-runtime",
57
+ "@deepseek-ai/dsh-client-ui-conversation",
58
+ "@deepseek-ai/dsh-client-ui-sidebar"
59
+ ]
60
+ }
61
+ },
62
+ "engines": {
63
+ "node": ">=20",
64
+ "dsh": ">=0.1.1-rc.2"
65
+ },
66
+ "peerDependencies": {
67
+ "dsh-better-sidebar": "0.17.1",
68
+ "react": ">=18",
69
+ "react-dom": ">=18"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "react": {
73
+ "optional": true
74
+ },
75
+ "react-dom": {
76
+ "optional": true
77
+ }
78
+ },
79
+ "devDependencies": {
80
+ "@deepseek-ai/cordis": "4.0.2",
81
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2",
82
+ "@deepseek-ai/dsh-invariants": "0.1.1-rc.2",
83
+ "@types/node": "^22.15.0",
84
+ "@types/react": "^18.3.0",
85
+ "@types/react-dom": "^18.3.0",
86
+ "esbuild": "^0.25.0",
87
+ "react": "^18.3.1",
88
+ "react-dom": "^18.3.1",
89
+ "typescript": "^5.9.0",
90
+ "vitest": "^3.2.0"
91
+ },
92
+ "keywords": [
93
+ "deepseek-harness",
94
+ "dsh-plugin",
95
+ "qichacha",
96
+ "qcc",
97
+ "mcp",
98
+ "previsit"
99
+ ]
100
+ }