dsh-industry-research 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.
Files changed (99) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +201 -0
  3. package/README.es.md +175 -0
  4. package/README.hi.md +175 -0
  5. package/README.md +175 -0
  6. package/README.pt.md +175 -0
  7. package/README.zh.md +175 -0
  8. package/THIRD_PARTY_NOTICES.md +21 -0
  9. package/cordis.patch.yml +44 -0
  10. package/lib/index.js +2080 -0
  11. package/lib/types/chain.d.ts +68 -0
  12. package/lib/types/chain.d.ts.map +1 -0
  13. package/lib/types/chain.js +88 -0
  14. package/lib/types/chain.js.map +1 -0
  15. package/lib/types/company.d.ts +121 -0
  16. package/lib/types/company.d.ts.map +1 -0
  17. package/lib/types/company.js +170 -0
  18. package/lib/types/company.js.map +1 -0
  19. package/lib/types/config.d.ts +72 -0
  20. package/lib/types/config.d.ts.map +1 -0
  21. package/lib/types/config.js +86 -0
  22. package/lib/types/config.js.map +1 -0
  23. package/lib/types/engine-bridge.d.ts +68 -0
  24. package/lib/types/engine-bridge.d.ts.map +1 -0
  25. package/lib/types/engine-bridge.js +18 -0
  26. package/lib/types/engine-bridge.js.map +1 -0
  27. package/lib/types/events.d.ts +79 -0
  28. package/lib/types/events.d.ts.map +1 -0
  29. package/lib/types/events.js +13 -0
  30. package/lib/types/events.js.map +1 -0
  31. package/lib/types/index.d.ts +58 -0
  32. package/lib/types/index.d.ts.map +1 -0
  33. package/lib/types/index.js +111 -0
  34. package/lib/types/index.js.map +1 -0
  35. package/lib/types/paths.d.ts +45 -0
  36. package/lib/types/paths.d.ts.map +1 -0
  37. package/lib/types/paths.js +93 -0
  38. package/lib/types/paths.js.map +1 -0
  39. package/lib/types/report.d.ts +134 -0
  40. package/lib/types/report.d.ts.map +1 -0
  41. package/lib/types/report.js +278 -0
  42. package/lib/types/report.js.map +1 -0
  43. package/lib/types/sources.d.ts +55 -0
  44. package/lib/types/sources.d.ts.map +1 -0
  45. package/lib/types/sources.js +73 -0
  46. package/lib/types/sources.js.map +1 -0
  47. package/lib/types/timeline.d.ts +78 -0
  48. package/lib/types/timeline.d.ts.map +1 -0
  49. package/lib/types/timeline.js +129 -0
  50. package/lib/types/timeline.js.map +1 -0
  51. package/lib/types/toolkit.d.ts +61 -0
  52. package/lib/types/toolkit.d.ts.map +1 -0
  53. package/lib/types/toolkit.js +77 -0
  54. package/lib/types/toolkit.js.map +1 -0
  55. package/lib/types/tools/company.d.ts +36 -0
  56. package/lib/types/tools/company.d.ts.map +1 -0
  57. package/lib/types/tools/company.js +139 -0
  58. package/lib/types/tools/company.js.map +1 -0
  59. package/lib/types/tools/map.d.ts +44 -0
  60. package/lib/types/tools/map.d.ts.map +1 -0
  61. package/lib/types/tools/map.js +211 -0
  62. package/lib/types/tools/map.js.map +1 -0
  63. package/lib/types/tools/report.d.ts +61 -0
  64. package/lib/types/tools/report.d.ts.map +1 -0
  65. package/lib/types/tools/report.js +277 -0
  66. package/lib/types/tools/report.js.map +1 -0
  67. package/lib/types/tools/track.d.ts +46 -0
  68. package/lib/types/tools/track.d.ts.map +1 -0
  69. package/lib/types/tools/track.js +188 -0
  70. package/lib/types/tools/track.js.map +1 -0
  71. package/lib/types/version.d.ts +8 -0
  72. package/lib/types/version.d.ts.map +1 -0
  73. package/lib/types/version.js +8 -0
  74. package/lib/types/version.js.map +1 -0
  75. package/lib/types/web.d.ts +74 -0
  76. package/lib/types/web.d.ts.map +1 -0
  77. package/lib/types/web.js +60 -0
  78. package/lib/types/web.js.map +1 -0
  79. package/package.json +143 -0
  80. package/skills/company-research-method/SKILL.md +50 -0
  81. package/skills/industry-research-method/SKILL.md +57 -0
  82. package/skills/industry-research-method/references/frameworks.md +42 -0
  83. package/src/chain.ts +132 -0
  84. package/src/company.ts +238 -0
  85. package/src/config.ts +154 -0
  86. package/src/engine-bridge.ts +62 -0
  87. package/src/events.ts +82 -0
  88. package/src/index.ts +139 -0
  89. package/src/paths.ts +96 -0
  90. package/src/report.ts +326 -0
  91. package/src/sources.ts +95 -0
  92. package/src/timeline.ts +155 -0
  93. package/src/toolkit.ts +87 -0
  94. package/src/tools/company.ts +157 -0
  95. package/src/tools/map.ts +241 -0
  96. package/src/tools/report.ts +304 -0
  97. package/src/tools/track.ts +223 -0
  98. package/src/version.ts +8 -0
  99. package/src/web.ts +94 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/timeline.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GAAG;IAC1B,kGAAkG;IAClG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,6DAA6D;IAC7D,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,iHAAiH;IACjH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,KAAK,EAAE,aAAa,EAAE,CAAA;IACtB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAehD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAe9G;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAsBvG;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,aAAa,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAoB7H"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * The per-industry timeline store (`timeline.jsonl`): one JSON entry per line,
3
+ * appended by `industry_track`, deduplicated by normalized URL, and capped by
4
+ * `timelineMaxEntries` (oldest entries dropped first). Pure file store — the
5
+ * web retrieval policy lives in `tools/track.ts`.
6
+ * @module dsh-industry-research/timeline
7
+ */
8
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
9
+ import { dirname } from 'node:path';
10
+ /**
11
+ * Normalize a URL for dedupe: lowercase scheme and host, strip default ports,
12
+ * strip a lone trailing slash on the path. Unparseable URLs are returned
13
+ * verbatim (dedupe then falls back to exact string equality).
14
+ * @param url - the raw URL.
15
+ * @returns the normalized dedupe key.
16
+ */
17
+ export function normalizeUrl(url) {
18
+ try {
19
+ const parsed = new URL(url);
20
+ parsed.protocol = parsed.protocol.toLowerCase();
21
+ parsed.hostname = parsed.hostname.toLowerCase();
22
+ if ((parsed.protocol === 'https:' && parsed.port === '443') || (parsed.protocol === 'http:' && parsed.port === '80')) {
23
+ parsed.port = '';
24
+ }
25
+ if (parsed.pathname.length > 1 && parsed.pathname.endsWith('/')) {
26
+ parsed.pathname = parsed.pathname.slice(0, -1);
27
+ }
28
+ return parsed.toString();
29
+ }
30
+ catch {
31
+ return url;
32
+ }
33
+ }
34
+ /**
35
+ * Decide whether a source URL passes the host allow/block lists. Entries are
36
+ * host suffixes (`gov.cn` matches `www.gov.cn`) or URL prefixes
37
+ * (`https://www.gov.cn/zhengce/`). The blocklist wins. An empty allowlist
38
+ * allows every host.
39
+ * @param url - the candidate URL.
40
+ * @param allowlist - configured allow entries.
41
+ * @param blocklist - configured block entries.
42
+ * @returns whether the URL may be tracked.
43
+ */
44
+ export function sourceAllowed(url, allowlist, blocklist) {
45
+ let host = '';
46
+ try {
47
+ host = new URL(url).hostname.toLowerCase();
48
+ }
49
+ catch {
50
+ host = '';
51
+ }
52
+ const matches = (entry) => {
53
+ const normalized = entry.toLowerCase();
54
+ if (normalized.includes('://'))
55
+ return url.toLowerCase().startsWith(normalized);
56
+ return host === normalized || host.endsWith(`.${normalized}`);
57
+ };
58
+ if (blocklist.some(matches))
59
+ return false;
60
+ if (allowlist.length === 0)
61
+ return true;
62
+ return allowlist.some(matches);
63
+ }
64
+ /**
65
+ * Read a timeline store, tolerating a missing file. Corrupt lines are skipped
66
+ * and counted (never silently: the caller surfaces the count), because a
67
+ * single torn line must not drop the rest of a durable log.
68
+ * @param path - absolute path of the JSONL file.
69
+ * @returns the parsed entries plus the number of skipped corrupt lines.
70
+ */
71
+ export async function readTimeline(path) {
72
+ let text;
73
+ try {
74
+ text = await readFile(path, 'utf8');
75
+ }
76
+ catch (error) {
77
+ if (error.code === 'ENOENT')
78
+ return { entries: [], corrupt: 0 };
79
+ throw error;
80
+ }
81
+ const entries = [];
82
+ let corrupt = 0;
83
+ for (const line of text.split('\n')) {
84
+ const trimmed = line.trim();
85
+ if (trimmed.length === 0)
86
+ continue;
87
+ try {
88
+ const parsed = JSON.parse(trimmed);
89
+ if (typeof parsed.url !== 'string' || typeof parsed.title !== 'string')
90
+ throw new Error('missing fields');
91
+ entries.push(parsed);
92
+ }
93
+ catch {
94
+ corrupt += 1;
95
+ }
96
+ }
97
+ return { entries, corrupt };
98
+ }
99
+ /**
100
+ * Merge a batch into the store and persist: dedupe by normalized URL (both
101
+ * against the store and within the batch), append the survivors, and rewrite
102
+ * the file keeping only the newest `maxEntries` when the cap is exceeded.
103
+ * @param path - absolute path of the JSONL file.
104
+ * @param batch - candidate entries, in arrival order.
105
+ * @param maxEntries - retention cap (oldest dropped first).
106
+ * @returns the merge outcome.
107
+ */
108
+ export async function mergeTimeline(path, batch, maxEntries) {
109
+ const { entries } = await readTimeline(path);
110
+ const seen = new Set(entries.map(entry => normalizeUrl(entry.url)));
111
+ const added = [];
112
+ let duplicates = 0;
113
+ for (const entry of batch) {
114
+ const key = normalizeUrl(entry.url);
115
+ if (seen.has(key)) {
116
+ duplicates += 1;
117
+ continue;
118
+ }
119
+ seen.add(key);
120
+ added.push(entry);
121
+ }
122
+ const merged = [...entries, ...added];
123
+ const kept = merged.length > maxEntries ? merged.slice(merged.length - maxEntries) : merged;
124
+ const truncated = kept.length !== merged.length;
125
+ await mkdir(dirname(path), { recursive: true });
126
+ await writeFile(path, kept.map(entry => JSON.stringify(entry)).join('\n') + (kept.length > 0 ? '\n' : ''), 'utf8');
127
+ return { added, duplicates, total: kept.length, truncated };
128
+ }
129
+ //# sourceMappingURL=timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/timeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared helpers for the four research tools: workspace resolution from the
3
+ * calling agent's session and per-industry directory layout. The layout is:
4
+ *
5
+ * ```
6
+ * <cwd>/<industryRoot>/<industry>/chain.json industry_map
7
+ * <cwd>/<industryRoot>/<industry>/timeline.jsonl industry_track
8
+ * <cwd>/<industryRoot>/<industry>/sources.json source registry
9
+ * <cwd>/<industryRoot>/<industry>/notes/ seed notes
10
+ * <cwd>/<industryRoot>/<industry>/reports/<ts>/ industry_report
11
+ * <cwd>/<industryRoot>/companies/<slug>/card.* company_scan
12
+ * ```
13
+ * @module dsh-industry-research/toolkit
14
+ */
15
+ import type { ToolRunContext } from '@deepseek-ai/dsh-tools';
16
+ import type { ResolvedConfig } from './config.js';
17
+ /**
18
+ * Resolve the session workspace the calling agent operates in. The tools are
19
+ * workspace-bound by design; without an agent-owned session cwd there is no
20
+ * honest place to persist artifacts, so this fails loud.
21
+ * @param exec - the tool execution context.
22
+ * @returns the absolute workspace root.
23
+ */
24
+ export declare function workspaceOf(exec: ToolRunContext): string;
25
+ /**
26
+ * Resolve and validate the directory of one industry under the configured
27
+ * root. The industry name is validated as a single safe path segment.
28
+ * @param config - resolved plugin config.
29
+ * @param cwd - absolute workspace root.
30
+ * @param industry - the raw industry argument.
31
+ * @returns `{ root, dir, name }` — absolute industry root, absolute industry directory, and the validated segment.
32
+ */
33
+ export declare function industryDirOf(config: ResolvedConfig, cwd: string, industry: string): {
34
+ root: string;
35
+ dir: string;
36
+ name: string;
37
+ };
38
+ /**
39
+ * Resolve and validate the directory of one company card under the shared
40
+ * companies root.
41
+ * @param config - resolved plugin config.
42
+ * @param cwd - absolute workspace root.
43
+ * @param company - the raw company name argument.
44
+ * @returns `{ root, dir, slug }` — absolute industry root, absolute company directory, and the validated slug.
45
+ */
46
+ export declare function companyDirOf(config: ResolvedConfig, cwd: string, company: string): {
47
+ root: string;
48
+ dir: string;
49
+ slug: string;
50
+ };
51
+ /** The `chain.json` path of an industry directory. */
52
+ export declare function chainPathOf(dir: string): string;
53
+ /** The `timeline.jsonl` path of an industry directory. */
54
+ export declare function timelinePathOf(dir: string): string;
55
+ /** The `sources.json` path of an industry directory. */
56
+ export declare function sourcesPathOf(dir: string): string;
57
+ /** The `notes/` directory of an industry directory. */
58
+ export declare function notesDirOf(dir: string): string;
59
+ /** The `reports/` directory of an industry directory. */
60
+ export declare function reportsDirOf(dir: string): string;
61
+ //# sourceMappingURL=toolkit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolkit.d.ts","sourceRoot":"","sources":["../../src/toolkit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAMxD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAIhI;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAI9H;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Shared helpers for the four research tools: workspace resolution from the
3
+ * calling agent's session and per-industry directory layout. The layout is:
4
+ *
5
+ * ```
6
+ * <cwd>/<industryRoot>/<industry>/chain.json industry_map
7
+ * <cwd>/<industryRoot>/<industry>/timeline.jsonl industry_track
8
+ * <cwd>/<industryRoot>/<industry>/sources.json source registry
9
+ * <cwd>/<industryRoot>/<industry>/notes/ seed notes
10
+ * <cwd>/<industryRoot>/<industry>/reports/<ts>/ industry_report
11
+ * <cwd>/<industryRoot>/companies/<slug>/card.* company_scan
12
+ * ```
13
+ * @module dsh-industry-research/toolkit
14
+ */
15
+ import { join } from 'node:path';
16
+ import { resolveContained, resolveIndustryRoot, safeSegment } from "./paths.js";
17
+ /**
18
+ * Resolve the session workspace the calling agent operates in. The tools are
19
+ * workspace-bound by design; without an agent-owned session cwd there is no
20
+ * honest place to persist artifacts, so this fails loud.
21
+ * @param exec - the tool execution context.
22
+ * @returns the absolute workspace root.
23
+ */
24
+ export function workspaceOf(exec) {
25
+ const cwd = exec.agent?.session.header.cwd;
26
+ if (cwd === undefined || cwd.trim().length === 0) {
27
+ throw new Error('this tool requires an agent-owned session workspace (session.header.cwd is unset)');
28
+ }
29
+ return cwd;
30
+ }
31
+ /**
32
+ * Resolve and validate the directory of one industry under the configured
33
+ * root. The industry name is validated as a single safe path segment.
34
+ * @param config - resolved plugin config.
35
+ * @param cwd - absolute workspace root.
36
+ * @param industry - the raw industry argument.
37
+ * @returns `{ root, dir, name }` — absolute industry root, absolute industry directory, and the validated segment.
38
+ */
39
+ export function industryDirOf(config, cwd, industry) {
40
+ const name = safeSegment('industry', industry);
41
+ const root = resolveIndustryRoot(cwd, config.industryRoot);
42
+ return { root, dir: resolveContained(root, name), name };
43
+ }
44
+ /**
45
+ * Resolve and validate the directory of one company card under the shared
46
+ * companies root.
47
+ * @param config - resolved plugin config.
48
+ * @param cwd - absolute workspace root.
49
+ * @param company - the raw company name argument.
50
+ * @returns `{ root, dir, slug }` — absolute industry root, absolute company directory, and the validated slug.
51
+ */
52
+ export function companyDirOf(config, cwd, company) {
53
+ const slug = safeSegment('company', company);
54
+ const root = resolveIndustryRoot(cwd, config.industryRoot);
55
+ return { root, dir: join(root, 'companies', slug), slug };
56
+ }
57
+ /** The `chain.json` path of an industry directory. */
58
+ export function chainPathOf(dir) {
59
+ return join(dir, 'chain.json');
60
+ }
61
+ /** The `timeline.jsonl` path of an industry directory. */
62
+ export function timelinePathOf(dir) {
63
+ return join(dir, 'timeline.jsonl');
64
+ }
65
+ /** The `sources.json` path of an industry directory. */
66
+ export function sourcesPathOf(dir) {
67
+ return join(dir, 'sources.json');
68
+ }
69
+ /** The `notes/` directory of an industry directory. */
70
+ export function notesDirOf(dir) {
71
+ return join(dir, 'notes');
72
+ }
73
+ /** The `reports/` directory of an industry directory. */
74
+ export function reportsDirOf(dir) {
75
+ return join(dir, 'reports');
76
+ }
77
+ //# sourceMappingURL=toolkit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolkit.js","sourceRoot":"","sources":["../../src/toolkit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE/E;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAoB;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAA;IAC1C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAA;IACtG,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAAsB,EAAE,GAAW,EAAE,QAAgB;IACjF,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;IAC1D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB,EAAE,GAAW,EAAE,OAAe;IAC/E,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;IAC1D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;AAC3D,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;AAChC,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;AACpC,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;AAClC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AAC3B,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The `company_scan` tool: scan one company from user-supplied workspace data
3
+ * files (primary) plus an optional `ctx.web` public-source complement, and
4
+ * persist a company card (`card.json` + `card.md`) whose every figure can be
5
+ * cited back to a file and a line. Paid/login-walled sources are out of scope
6
+ * — the user passes their exports in via `dataFiles`. v1 reads text formats
7
+ * only (no PDF).
8
+ * @module dsh-industry-research/tools/company
9
+ */
10
+ import type { Context } from '@deepseek-ai/cordis';
11
+ import type { ResolvedConfig } from '../config.js';
12
+ import type { CompanyCard } from '../company.js';
13
+ /** The canonical value returned by `company_scan`. */
14
+ export interface CompanyScanValue {
15
+ name: string;
16
+ slug: string;
17
+ /** Absolute company card directory. */
18
+ dir: string;
19
+ cardPath: string;
20
+ cardJsonPath: string;
21
+ /** The persisted card. */
22
+ card: CompanyCard;
23
+ /** Data files rejected this call, with the reason. */
24
+ rejected: Array<{
25
+ path: string;
26
+ reason: string;
27
+ }>;
28
+ }
29
+ /**
30
+ * Build the `company_scan` tool definition.
31
+ * @param ctx - the plugin context (optional web lookup).
32
+ * @param config - the resolved plugin config.
33
+ * @returns the tool definition to register.
34
+ */
35
+ export declare function buildCompanyScanTool(ctx: Context, config: ResolvedConfig): import("@deepseek-ai/dsh-tools").ToolDefinition;
36
+ //# sourceMappingURL=company.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company.d.ts","sourceRoot":"","sources":["../../../src/tools/company.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,eAAe,CAAA;AAK/D,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,0BAA0B;IAC1B,IAAI,EAAE,WAAW,CAAA;IACjB,sDAAsD;IACtD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAClD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,mDAqHxE"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * The `company_scan` tool: scan one company from user-supplied workspace data
3
+ * files (primary) plus an optional `ctx.web` public-source complement, and
4
+ * persist a company card (`card.json` + `card.md`) whose every figure can be
5
+ * cited back to a file and a line. Paid/login-walled sources are out of scope
6
+ * — the user passes their exports in via `dataFiles`. v1 reads text formats
7
+ * only (no PDF).
8
+ * @module dsh-industry-research/tools/company
9
+ */
10
+ import { defineTool } from '@deepseek-ai/dsh-tools';
11
+ import { boundFigures, scanFile, writeCard } from "../company.js";
12
+ import { lookupWeb, requestSignal, webErrorMessage } from "../web.js";
13
+ import { resolveWorkspaceFile } from "../paths.js";
14
+ import { companyDirOf, workspaceOf } from "../toolkit.js";
15
+ /**
16
+ * Build the `company_scan` tool definition.
17
+ * @param ctx - the plugin context (optional web lookup).
18
+ * @param config - the resolved plugin config.
19
+ * @returns the tool definition to register.
20
+ */
21
+ export function buildCompanyScanTool(ctx, config) {
22
+ return defineTool({
23
+ name: 'company_scan',
24
+ description: '公司研究员的速览卡工具:以用户提供的工作区数据文件(年报摘录、数据表)为主、ctx.web 公开检索为辅,产出公司速览卡(业务结构 / 财务要点 / 风险点框架),所有数字都能标注来源文件与行号。不接付费/需登录数据源;缺口显式声明,禁止编造公司数字。仅供研究,不构成投资建议。',
25
+ parameters: {
26
+ name: { type: 'string', required: true, description: '公司名(作为目录段,如「样例酒业」)' },
27
+ dataFiles: { type: 'array', items: { type: 'string' }, description: '工作区内数据文件的相对路径列表(.md/.txt/.csv/.tsv/.json;v1 不解析 PDF)' },
28
+ web: { type: 'boolean', description: '是否做 web 公开源补充检索(默认 true;config.offline 时自动跳过)' },
29
+ },
30
+ output: {
31
+ schema: {
32
+ type: 'object',
33
+ properties: {
34
+ name: { type: 'string', required: true },
35
+ slug: { type: 'string', required: true },
36
+ dir: { type: 'string', required: true },
37
+ cardPath: { type: 'string', required: true },
38
+ cardJsonPath: { type: 'string', required: true },
39
+ card: { type: 'json', required: true },
40
+ rejected: { type: 'array', items: { type: 'json' }, required: true },
41
+ },
42
+ additionalProperties: false,
43
+ },
44
+ render: (_args, value) => {
45
+ const current = value;
46
+ const card = current.card;
47
+ const lines = [
48
+ `公司速览卡「${card.name}」→ ${current.cardPath}`,
49
+ `数据文件 ${card.sources.length} 份,数字候选行 ${card.figureCandidates.length} 行(引用数字必须标注文件与行号)。`,
50
+ ];
51
+ if (card.webSources !== null && card.webSources.length > 0) {
52
+ lines.push(`公开源 ${card.webSources.length} 条:${card.webSources.map(source => source.title ?? source.url).join(';')}`);
53
+ }
54
+ if (current.rejected.length > 0) {
55
+ lines.push(`未采纳文件 ${current.rejected.length} 份:${current.rejected.map(entry => `${entry.path}(${entry.reason})`).join(';')}`);
56
+ }
57
+ if (card.gaps.length > 0)
58
+ lines.push(`缺口声明:${card.gaps.join(';')}`);
59
+ return [{ type: 'text', text: lines.join('\n') }];
60
+ },
61
+ },
62
+ timeoutMs: Math.max(30_000, config.fetchTimeoutMs * 3),
63
+ async execute(args, exec) {
64
+ const cwd = workspaceOf(exec);
65
+ const { dir, slug } = companyDirOf(config, cwd, args.name);
66
+ const now = new Date().toISOString();
67
+ const gaps = [];
68
+ const rejected = [];
69
+ const scanned = [];
70
+ for (const file of args.dataFiles ?? []) {
71
+ let absolute;
72
+ try {
73
+ absolute = resolveWorkspaceFile(cwd, file);
74
+ }
75
+ catch (error) {
76
+ throw error;
77
+ }
78
+ try {
79
+ scanned.push(await scanFile(absolute, config.scan.maxFileBytes));
80
+ }
81
+ catch (error) {
82
+ rejected.push({ path: file, reason: error instanceof Error ? error.message : String(error) });
83
+ }
84
+ }
85
+ if ((args.dataFiles ?? []).length === 0) {
86
+ gaps.push('未提供数据文件(dataFiles):业务结构 / 财务要点 / 风险点均待补');
87
+ }
88
+ let webSources = null;
89
+ if (args.web === false) {
90
+ gaps.push('按调用方要求未做 web 公开源检索');
91
+ }
92
+ else if (config.offline) {
93
+ gaps.push('config.offline 为 true,未做 web 公开源检索');
94
+ }
95
+ else {
96
+ const web = lookupWeb(ctx);
97
+ if (web === undefined) {
98
+ gaps.push('ctx.web 未挂载,未做 web 公开源检索');
99
+ }
100
+ else {
101
+ try {
102
+ const outcome = await web.search({ query: `${args.name} 公司 业务 简介`, maxResults: 5 }, requestSignal(exec.signal, config.fetchTimeoutMs));
103
+ webSources = outcome.sources.map(source => ({
104
+ url: source.url,
105
+ ...(source.title !== undefined ? { title: source.title } : {}),
106
+ ...(source.snippet !== undefined ? { snippet: source.snippet } : {}),
107
+ ...(source.publishedAt !== undefined ? { publishedAt: source.publishedAt } : {}),
108
+ }));
109
+ }
110
+ catch (error) {
111
+ gaps.push(`web 公开源检索失败:${webErrorMessage(error)}`);
112
+ }
113
+ }
114
+ }
115
+ const figures = boundFigures(scanned.flatMap(file => file.figures), config);
116
+ const totalFigures = scanned.reduce((sum, file) => sum + file.figures.length, 0);
117
+ if (totalFigures > figures.length) {
118
+ gaps.push(`数字候选行超出 scan.maxFigureCandidates(${totalFigures} > ${figures.length}),仅保留前 ${figures.length} 行`);
119
+ }
120
+ if (scanned.length > 0 && totalFigures === 0) {
121
+ gaps.push('数据文件中未发现数字行:财务要点待补');
122
+ }
123
+ const card = {
124
+ name: args.name.trim(),
125
+ slug,
126
+ asOf: now,
127
+ sources: scanned.map(file => file.source),
128
+ outline: scanned.flatMap(file => file.outline !== undefined ? [file.outline] : []),
129
+ figureCandidates: figures,
130
+ webSources,
131
+ gaps,
132
+ disclaimer: '仅供研究,不构成投资建议',
133
+ };
134
+ const { cardJsonPath, cardPath } = await writeCard(dir, card);
135
+ return { name: card.name, slug, dir, cardPath, cardJsonPath, card, rejected };
136
+ },
137
+ });
138
+ }
139
+ //# sourceMappingURL=company.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company.js","sourceRoot":"","sources":["../../../src/tools/company.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The `industry_map` tool: build or update one industry's chain map. The
3
+ * model authors the ChainMap (guided by the industry-research-method skill);
4
+ * the tool validates it (dangling edges, unsourced numbers, illegal tiers),
5
+ * persists `chain.json`, registers seed/web material as citable sources, and
6
+ * lists the explicit gap slots. Called without a `chain` argument it returns
7
+ * the current map plus the registered sources, so the model can iterate.
8
+ * @module dsh-industry-research/tools/map
9
+ */
10
+ import type { Context } from '@deepseek-ai/cordis';
11
+ import type { ResolvedConfig } from '../config.js';
12
+ import type { ChainMap } from '../chain.js';
13
+ import type { SourceEntry } from '../sources.js';
14
+ import type { WebSource } from '../web.js';
15
+ /** The canonical value returned by `industry_map`. */
16
+ export interface IndustryMapValue {
17
+ industry: string;
18
+ /** Absolute industry directory. */
19
+ dir: string;
20
+ /** Absolute path of `chain.json` (present once a map was committed). */
21
+ chainPath: string;
22
+ /** Whether this call committed a new map. */
23
+ updated: boolean;
24
+ /** The current map after this call; null when none exists yet. */
25
+ chain: ChainMap | null;
26
+ /** Explicit gap slots of the current map. */
27
+ gaps: string[];
28
+ /** All registered citable sources of this industry. */
29
+ sources: SourceEntry[];
30
+ /** Refs registered by this call (seed note, seed files, web digest). */
31
+ seedRefs: string[];
32
+ /** Web-assist digest; null when the assist did not run. */
33
+ webDigest: WebSource[] | null;
34
+ /** Why the web assist did not run; null when it ran or was not requested. */
35
+ webNote: string | null;
36
+ }
37
+ /**
38
+ * Build the `industry_map` tool definition.
39
+ * @param ctx - the plugin context (event emission + optional web lookup).
40
+ * @param config - the resolved plugin config.
41
+ * @returns the tool definition to register.
42
+ */
43
+ export declare function buildIndustryMapTool(ctx: Context, config: ResolvedConfig): import("@deepseek-ai/dsh-tools").ToolDefinition;
44
+ //# sourceMappingURL=map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../../src/tools/map.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAK1C,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,mCAAmC;IACnC,GAAG,EAAE,MAAM,CAAA;IACX,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAA;IACjB,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAA;IAChB,kEAAkE;IAClE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAA;IACtB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,uDAAuD;IACvD,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,2DAA2D;IAC3D,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAC7B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAsDD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,mDAsIxE"}