siluzan-tso-cli 1.1.35-beta.1 → 1.1.35-beta.2
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
CHANGED
|
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
|
51
51
|
siluzan-tso init --force # 强制覆盖已存在文件
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
> **注意**:当前为测试版(1.1.35-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.35-beta.2),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -124884,12 +124884,11 @@ import path18 from "path";
|
|
|
124884
124884
|
// src/commands/market-analysis/report-content.ts
|
|
124885
124885
|
var SILUZAN_ECHARTS_CDN_URL = "https://staticpn.siluzan.com/assets/slz/homeCDN/echarts.js";
|
|
124886
124886
|
var MARKET_REPORT_DIMENSIONS = [
|
|
124887
|
-
// ── 封面与元信息 ──
|
|
124888
124887
|
{
|
|
124889
124888
|
id: "cover",
|
|
124890
124889
|
chapter: "\u5C01\u9762",
|
|
124891
|
-
dimension: "\u62A5\u544A\u6807\u9898\u542B\
|
|
124892
|
-
hint: "\u987B\u542B\u300C\u6218\u7565\u5E02\u573A\u5206\u6790\u300D\
|
|
124890
|
+
dimension: "\u62A5\u544A\u6807\u9898\u542B\u6218\u7565/\u884C\u4E1A/\u5E02\u573A\u5206\u6790\u6807\u8BC6",
|
|
124891
|
+
hint: "\u987B\u542B\u300C\u6218\u7565\u5E02\u573A\u5206\u6790\u300D\u300C\u884C\u4E1A\u5206\u6790\u62A5\u544A\u300D\u300C\u5E02\u573A\u5206\u6790\u62A5\u544A\u300D\u6216\u300C\u884C\u4E1A\u8C03\u67E5\u300D\u7B49"
|
|
124893
124892
|
},
|
|
124894
124893
|
{
|
|
124895
124894
|
id: "cover-kpi",
|
|
@@ -124897,7 +124896,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
124897
124896
|
dimension: "\u6838\u5FC3\u7ED3\u8BBA\u6216 KPI \u6458\u8981",
|
|
124898
124897
|
hint: "\u5C01\u9762\u987B\u6709\u53EF\u626B\u8BFB\u7684\u7ED3\u8BBA\u6BB5\u6216 metric \u5361\u7247\uFF0C\u975E\u4EC5\u6807\u9898"
|
|
124899
124898
|
},
|
|
124900
|
-
// ── 一、市场与趋势诊断 ──
|
|
124901
124899
|
{
|
|
124902
124900
|
id: "ch1",
|
|
124903
124901
|
chapter: "\u4E00\u3001\u5E02\u573A\u4E0E\u8D8B\u52BF\u8BCA\u65AD",
|
|
@@ -124920,7 +124918,7 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
124920
124918
|
id: "ch1-target-geo",
|
|
124921
124919
|
chapter: "\u4E00\u3001\u5E02\u573A\u4E0E\u8D8B\u52BF\u8BCA\u65AD",
|
|
124922
124920
|
dimension: "\u76EE\u6807\u5E02\u573A\u56FD\u5BB6/\u533A\u57DF\u62C6\u89E3",
|
|
124923
|
-
hint: "\u987B\u6309\u56FD\u5BB6\u6216\u533A\u57DF\u5BF9\u6BD4\u89C4\u6A21\u3001\u589E\u957F\u3001\u4F18\u5148\u7EA7\uFF08\u8868\u683C\u6216\u5206\u6BB5\uFF09"
|
|
124921
|
+
hint: "\u987B\u6309\u56FD\u5BB6\u6216\u533A\u57DF\u5BF9\u6BD4\u89C4\u6A21\u3001\u589E\u957F\u3001\u4F18\u5148\u7EA7\uFF08\u8868\u683C\u6216\u5206\u6BB5\uFF09\uFF1B\u4E0E collect \u76EE\u6807\u5E02\u573A\u4E00\u81F4\u66F4\u4F73"
|
|
124924
124922
|
},
|
|
124925
124923
|
{
|
|
124926
124924
|
id: "ch1-pestel",
|
|
@@ -124934,7 +124932,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
124934
124932
|
dimension: "3\u20135 \u5E74\u8D8B\u52BF\u9884\u6D4B\u4E0E\u5047\u8BBE",
|
|
124935
124933
|
hint: "\u987B\u542B\u300C\u9884\u6D4B\u300D\u6216\u300C3\u300D\u5E74/\u300C5\u300D\u5E74\u8D8B\u52BF\u8868\u8FF0"
|
|
124936
124934
|
},
|
|
124937
|
-
// ── 二、目标行业深度洞察 ──
|
|
124938
124935
|
{
|
|
124939
124936
|
id: "ch2",
|
|
124940
124937
|
chapter: "\u4E8C\u3001\u76EE\u6807\u884C\u4E1A\u6DF1\u5EA6\u6D1E\u5BDF",
|
|
@@ -124951,7 +124948,7 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
124951
124948
|
id: "ch2-compliance",
|
|
124952
124949
|
chapter: "\u4E8C\u3001\u76EE\u6807\u884C\u4E1A\u6DF1\u5EA6\u6D1E\u5BDF",
|
|
124953
124950
|
dimension: "\u6CD5\u89C4\u73AF\u5883\u4E0E\u5408\u89C4\u8981\u6C42",
|
|
124954
|
-
hint: "\u987B\u542B\u6CD5\u89C4/\u5408\u89C4\u8868\uFF0C\u542B\u5E94\u5BF9\u7B56\u7565\uFF1B\u5B9C\u542B\u5408\u89C4\
|
|
124951
|
+
hint: "\u987B\u542B\u6CD5\u89C4/\u5408\u89C4\u8868\uFF0C\u542B\u5E94\u5BF9\u7B56\u7565\uFF1B\u5B9C\u542B\u5408\u89C4\u6210\u672C\u6216\u6EA2\u4EF7\u4F30\u7B97"
|
|
124955
124952
|
},
|
|
124956
124953
|
{
|
|
124957
124954
|
id: "ch2-bpmn",
|
|
@@ -124959,7 +124956,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
124959
124956
|
dimension: "\u5178\u578B\u573A\u666F\u4E0E BPMN \u6D41\u7A0B\u5BF9\u6BD4",
|
|
124960
124957
|
hint: "\u987B\u542B\u300C\u539F\u6D41\u7A0B\u300D\u4E0E\u300C\u65B0\u6D41\u7A0B\u300D\u6216 BPMN \u6587\u672C + \u6548\u7387/\u6210\u672C\u91CF\u5316"
|
|
124961
124958
|
},
|
|
124962
|
-
// ── 三、目标受众与场景 ──
|
|
124963
124959
|
{
|
|
124964
124960
|
id: "ch3",
|
|
124965
124961
|
chapter: "\u4E09\u3001\u76EE\u6807\u53D7\u4F17\u4E0E\u573A\u666F",
|
|
@@ -124978,7 +124974,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
124978
124974
|
dimension: "\u4EA7\u54C1\u5E94\u7528\u573A\u666F\u4E0E\u4EF7\u503C\u5206\u6790",
|
|
124979
124975
|
hint: "\u987B\u542B\u5E94\u7528\u573A\u666F\u3001\u5DEE\u5F02\u5316\u3001\u7528\u6237\u4EF7\u503C\u4E0E\u4F01\u4E1A\u4EF7\u503C"
|
|
124980
124976
|
},
|
|
124981
|
-
// ── 四、竞争策略与定位 ──
|
|
124982
124977
|
{
|
|
124983
124978
|
id: "ch4",
|
|
124984
124979
|
chapter: "\u56DB\u3001\u7ADE\u4E89\u7B56\u7565\u4E0E\u5B9A\u4F4D",
|
|
@@ -124989,13 +124984,13 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
124989
124984
|
id: "ch4-competitors",
|
|
124990
124985
|
chapter: "\u56DB\u3001\u7ADE\u4E89\u7B56\u7565\u4E0E\u5B9A\u4F4D",
|
|
124991
124986
|
dimension: "\u4E3B\u8981\u7ADE\u54C1\u8BC6\u522B",
|
|
124992
|
-
hint: "\u987B\u70B9\u540D \u22653 \u4E2A\u7ADE\u54C1\u6216\u5BF9\u6807\u54C1\u724C"
|
|
124987
|
+
hint: "\u987B\u70B9\u540D \u22653 \u4E2A\u7ADE\u54C1\u6216\u5BF9\u6807\u4F01\u4E1A\uFF08\u4E0D\u9650\u5B9A\u884C\u4E1A\u54C1\u724C\uFF09"
|
|
124993
124988
|
},
|
|
124994
124989
|
{
|
|
124995
124990
|
id: "ch4-compare-table",
|
|
124996
124991
|
chapter: "\u56DB\u3001\u7ADE\u4E89\u7B56\u7565\u4E0E\u5B9A\u4F4D",
|
|
124997
|
-
dimension: "\u529F\u80FD\u4E0E\u6027\u80FD\u5BF9\u6BD4\u8868\uFF08\u226510 \u9879 \xD7 \u22653 \
|
|
124998
|
-
hint: "\u987B\u6709\u7ADE\u54C1\u5BF9\u6BD4\u8868\
|
|
124992
|
+
dimension: "\u529F\u80FD\u4E0E\u6027\u80FD\u5BF9\u6BD4\u8868\uFF08\u226510 \u9879 \xD7 \u22653 \u4E3B\u4F53\uFF09",
|
|
124993
|
+
hint: "\u987B\u6709\u7ADE\u54C1\u5BF9\u6BD4\u8868\uFF1A\u22654 \u5217\uFF08\u7EF4\u5EA6+\u591A\u65B9\uFF09\u4E14 \u226511 \u884C"
|
|
124999
124994
|
},
|
|
125000
124995
|
{
|
|
125001
124996
|
id: "ch4-gaps",
|
|
@@ -125009,7 +125004,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
125009
125004
|
dimension: "\u6838\u5FC3\u5B9A\u4F4D\u9648\u8FF0\u4E0E\u5DEE\u5F02\u5316\u7EF4\u5EA6",
|
|
125010
125005
|
hint: "\u987B\u6709\u4E00\u53E5\u5B9A\u4F4D\u9648\u8FF0 + \u591A\u4E2A\u5DEE\u5F02\u5316\u7EF4\u5EA6"
|
|
125011
125006
|
},
|
|
125012
|
-
// ── 五、增长与品牌策略 ──
|
|
125013
125007
|
{
|
|
125014
125008
|
id: "ch5",
|
|
125015
125009
|
chapter: "\u4E94\u3001\u589E\u957F\u4E0E\u54C1\u724C\u7B56\u7565",
|
|
@@ -125034,7 +125028,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
125034
125028
|
dimension: "\u8425\u9500\u4E0E\u9500\u552E\u6218\u672F",
|
|
125035
125029
|
hint: "\u987B\u542B\u5185\u5BB9\u8425\u9500/\u6E20\u9053/KOL/\u9500\u552E\u6A21\u5F0F\u7B49\u6218\u672F\u63CF\u8FF0"
|
|
125036
125030
|
},
|
|
125037
|
-
// ── 六、实施、资源与风险 ──
|
|
125038
125031
|
{
|
|
125039
125032
|
id: "ch6",
|
|
125040
125033
|
chapter: "\u516D\u3001\u5B9E\u65BD\u3001\u8D44\u6E90\u4E0E\u98CE\u9669",
|
|
@@ -125059,7 +125052,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
125059
125052
|
dimension: "\u98CE\u9669\u77E9\u9635\u4E0E\u5E94\u5BF9\u7B56\u7565",
|
|
125060
125053
|
hint: "\u987B\u542B\u5E02\u573A/\u7ADE\u4E89/\u6280\u672F/\u8FD0\u8425\u7B49\u98CE\u9669 + \u6BCF\u7C7B\u5E94\u5BF9\u63AA\u65BD"
|
|
125061
125054
|
},
|
|
125062
|
-
// ── 附录 ──
|
|
125063
125055
|
{
|
|
125064
125056
|
id: "appendix",
|
|
125065
125057
|
chapter: "\u9644\u5F55",
|
|
@@ -125084,7 +125076,6 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
125084
125076
|
dimension: "\u672F\u8BED\u8868\uFF08ROI/CAGR/GTM/BPMN \u7B49\uFF09",
|
|
125085
125077
|
hint: "\u987B\u89E3\u91CA\u81F3\u5C11 3 \u4E2A\u7F29\u5199"
|
|
125086
125078
|
},
|
|
125087
|
-
// ── 呈现规范(原始 prompt HTML 要求)──
|
|
125088
125079
|
{
|
|
125089
125080
|
id: "viz-echarts",
|
|
125090
125081
|
chapter: "\u5448\u73B0",
|
|
@@ -125098,6 +125089,44 @@ var MARKET_REPORT_DIMENSIONS = [
|
|
|
125098
125089
|
hint: "\u987B\u542B Source: \u6216\u300C\u6765\u6E90\u300D\u811A\u6CE8"
|
|
125099
125090
|
}
|
|
125100
125091
|
];
|
|
125092
|
+
function stripHtmlTags(html) {
|
|
125093
|
+
return html.replace(/<script[\s\S]*?<\/script>/gi, " ").replace(/<style[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " ");
|
|
125094
|
+
}
|
|
125095
|
+
function countTableColumns(tableHtml) {
|
|
125096
|
+
const firstRow = tableHtml.match(/<tr[\s\S]*?<\/tr>/i)?.[0] ?? "";
|
|
125097
|
+
const th = (firstRow.match(/<th/gi) ?? []).length;
|
|
125098
|
+
const td = (firstRow.match(/<td/gi) ?? []).length;
|
|
125099
|
+
return Math.max(th, td);
|
|
125100
|
+
}
|
|
125101
|
+
function isCompareTable(tableHtml, html, tableIndex) {
|
|
125102
|
+
const inTable = /对比|竞品|功能|性能|维度|指标|参数/.test(tableHtml);
|
|
125103
|
+
if (inTable) return true;
|
|
125104
|
+
const windowStart = Math.max(0, tableIndex - 600);
|
|
125105
|
+
const windowEnd = Math.min(html.length, tableIndex + tableHtml.length + 400);
|
|
125106
|
+
const nearby = html.slice(windowStart, windowEnd);
|
|
125107
|
+
return /对比|竞品|竞争|功能|性能|对标/.test(nearby);
|
|
125108
|
+
}
|
|
125109
|
+
function findFeatureCompareTableRows(html) {
|
|
125110
|
+
const tables = html.match(/<table[\s\S]*?<\/table>/gi) ?? [];
|
|
125111
|
+
let best = 0;
|
|
125112
|
+
let searchFrom = 0;
|
|
125113
|
+
for (const t of tables) {
|
|
125114
|
+
const tableIndex = html.indexOf(t, searchFrom);
|
|
125115
|
+
searchFrom = tableIndex + 1;
|
|
125116
|
+
if (countTableColumns(t) < 4) continue;
|
|
125117
|
+
if (!isCompareTable(t, html, tableIndex)) continue;
|
|
125118
|
+
const rows = (t.match(/<tr/gi) ?? []).length;
|
|
125119
|
+
if (rows > best) best = rows;
|
|
125120
|
+
}
|
|
125121
|
+
return best;
|
|
125122
|
+
}
|
|
125123
|
+
function countPainPoints(html) {
|
|
125124
|
+
const labeled = (html.match(/痛点\s*\d/gi) ?? []).length;
|
|
125125
|
+
if (labeled >= 4) return labeled;
|
|
125126
|
+
const section = html.match(/痛点[\s\S]{0,3000}/i)?.[0] ?? html;
|
|
125127
|
+
const listItems = (section.match(/<li[^>]*>/gi) ?? []).length;
|
|
125128
|
+
return Math.max(labeled, listItems >= 4 ? 4 : listItems);
|
|
125129
|
+
}
|
|
125101
125130
|
function countEchartsInstances(html) {
|
|
125102
125131
|
const inits = (html.match(/echarts\.init\(/g) ?? []).length;
|
|
125103
125132
|
if (inits > 0) return inits;
|
|
@@ -125106,67 +125135,97 @@ function countEchartsInstances(html) {
|
|
|
125106
125135
|
function hasEchartsCdn(html) {
|
|
125107
125136
|
return /homeCDN\/echarts\.js|echarts\.min\.js|npm\/echarts@/i.test(html);
|
|
125108
125137
|
}
|
|
125109
|
-
function
|
|
125110
|
-
const
|
|
125111
|
-
if (
|
|
125112
|
-
|
|
125113
|
-
|
|
125114
|
-
|
|
125115
|
-
|
|
125116
|
-
|
|
125117
|
-
|
|
125118
|
-
|
|
125119
|
-
|
|
125120
|
-
|
|
125121
|
-
const
|
|
125122
|
-
|
|
125123
|
-
|
|
125124
|
-
|
|
125125
|
-
|
|
125126
|
-
|
|
125127
|
-
|
|
125128
|
-
return best;
|
|
125129
|
-
}
|
|
125130
|
-
function mentionsCompetitors(html) {
|
|
125131
|
-
const brands = ["Apple", "Samsung", "Google", "\u82F9\u679C", "\u4E09\u661F", "\u8C37\u6B4C", "\u534E\u4E3A", "Motorola"];
|
|
125132
|
-
let n = 0;
|
|
125133
|
-
for (const b of brands) {
|
|
125134
|
-
if (html.includes(b)) n++;
|
|
125138
|
+
function countCompetitorMentions(html) {
|
|
125139
|
+
const competitorSection = html.match(/(?:主要)?竞品[\s\S]{0,5000}/i)?.[0] ?? html.match(/竞争对手[\s\S]{0,5000}/i)?.[0] ?? html.match(/对标(?:企业|品牌|公司)[\s\S]{0,5000}/i)?.[0] ?? "";
|
|
125140
|
+
if (competitorSection) {
|
|
125141
|
+
const listItems = (competitorSection.match(/<li[^>]*>[\s\S]*?<\/li>/gi) ?? []).filter(
|
|
125142
|
+
(li) => stripHtmlTags(li).trim().length >= 2
|
|
125143
|
+
);
|
|
125144
|
+
if (listItems.length >= 3) return listItems.length;
|
|
125145
|
+
const inlineList = competitorSection.match(/(?:竞品|竞争对手|对标)[::][\s\S]{0,800}/i)?.[0];
|
|
125146
|
+
if (inlineList) {
|
|
125147
|
+
const parts = stripHtmlTags(inlineList).split(/[、,,;;|]/).map((s) => s.replace(/^(竞品|竞争对手|对标)[::]/, "").trim()).filter((s) => s.length >= 2);
|
|
125148
|
+
if (parts.length >= 3) return parts.length;
|
|
125149
|
+
}
|
|
125150
|
+
const plain = stripHtmlTags(competitorSection);
|
|
125151
|
+
const entities = plain.match(
|
|
125152
|
+
/[\u4e00-\u9fa5A-Za-z0-9&][\u4e00-\u9fa5A-Za-z0-9&.\- ]{1,30}(?:公司|集团|Co\.|Corp|Inc|Ltd|品牌)?/g
|
|
125153
|
+
);
|
|
125154
|
+
if (entities && new Set(entities.map((e) => e.trim())).size >= 3) {
|
|
125155
|
+
return new Set(entities.map((e) => e.trim())).size;
|
|
125156
|
+
}
|
|
125135
125157
|
}
|
|
125136
|
-
|
|
125158
|
+
const tables = html.match(/<table[\s\S]*?<\/table>/gi) ?? [];
|
|
125159
|
+
let searchFrom = 0;
|
|
125160
|
+
for (const t of tables) {
|
|
125161
|
+
const tableIndex = html.indexOf(t, searchFrom);
|
|
125162
|
+
searchFrom = tableIndex + 1;
|
|
125163
|
+
const cols = countTableColumns(t);
|
|
125164
|
+
if (cols >= 4 && isCompareTable(t, html, tableIndex)) {
|
|
125165
|
+
return Math.max(3, cols - 1);
|
|
125166
|
+
}
|
|
125167
|
+
}
|
|
125168
|
+
const globalPlain = stripHtmlTags(html);
|
|
125169
|
+
const named = globalPlain.match(
|
|
125170
|
+
/(?:竞品|竞争对手)[::][^\n。;;]{10,400}/
|
|
125171
|
+
)?.[0] ?? "";
|
|
125172
|
+
if (named) {
|
|
125173
|
+
const parts = named.replace(/^[^::]+[::]/, "").split(/[、,,;;|]/).map((s) => s.trim()).filter((s) => s.length >= 2);
|
|
125174
|
+
if (parts.length >= 3) return parts.length;
|
|
125175
|
+
}
|
|
125176
|
+
return 0;
|
|
125177
|
+
}
|
|
125178
|
+
function splitMarketTokens(value) {
|
|
125179
|
+
return value.split(/[、,,/|]/).map((t) => t.trim()).filter((t) => t.length >= 2);
|
|
125180
|
+
}
|
|
125181
|
+
function hasTargetGeoBreakdown(html, ctx) {
|
|
125182
|
+
const hasMetrics = /规模|增长|优先级|潜力|份额|CAGR|市场容量/.test(html);
|
|
125183
|
+
const hasGeoFrame = /国家|区域|地区|市场/.test(html);
|
|
125184
|
+
if (!hasMetrics || !hasGeoFrame) return false;
|
|
125185
|
+
const targetMarket = ctx.targetMarket?.trim() ?? "";
|
|
125186
|
+
if (targetMarket) {
|
|
125187
|
+
if (/全球|国际|worldwide/i.test(targetMarket)) {
|
|
125188
|
+
return /全球|国际|各区域|分区域|分市场/.test(html);
|
|
125189
|
+
}
|
|
125190
|
+
const tokens = splitMarketTokens(targetMarket);
|
|
125191
|
+
const hit = tokens.filter((t) => html.includes(t)).length;
|
|
125192
|
+
if (hit >= 1) return true;
|
|
125193
|
+
}
|
|
125194
|
+
const regionHits = (html.match(
|
|
125195
|
+
/(?:亚太|欧洲|北美|拉美|中东|非洲|东南亚|全球|[\u4e00-\u9fa5]{2,8}(?:市场|地区|国家|区域))/g
|
|
125196
|
+
) ?? []).length;
|
|
125197
|
+
return regionHits >= 2;
|
|
125198
|
+
}
|
|
125199
|
+
function hasReportTitle(html, ctx) {
|
|
125200
|
+
const hasTitle = /战略市场分析|KA客户|行业分析报告|市场分析报告|行业调查|市场调查/.test(html);
|
|
125201
|
+
if (!hasTitle) return false;
|
|
125202
|
+
return /目标市场|全球市场|行业|细分|market/i.test(html) || !!ctx.targetMarket?.trim() || !!ctx.industry?.trim() || !!ctx.customerName?.trim();
|
|
125137
125203
|
}
|
|
125138
125204
|
var CONTENT_RULES = [
|
|
125139
|
-
{
|
|
125140
|
-
|
|
125141
|
-
test: (h) => /战略市场分析|KA客户/.test(h) && (/目标市场|北美|全球|欧洲|亚太/.test(h) || /targetMarket/i.test(h))
|
|
125142
|
-
},
|
|
125143
|
-
{ id: "cover-kpi", test: (h) => /核心结论|metric|kpi|结论/.test(h) },
|
|
125205
|
+
{ id: "cover", test: (h, ctx) => hasReportTitle(h, ctx) },
|
|
125206
|
+
{ id: "cover-kpi", test: (h) => /核心结论|metric|kpi|结论|摘要|executive summary/i.test(h) },
|
|
125144
125207
|
{ id: "ch1", test: (h) => /市场与趋势诊断/.test(h) },
|
|
125145
125208
|
{
|
|
125146
125209
|
id: "ch1-tam",
|
|
125147
125210
|
test: (h) => (/TAM|SAM|SOM/.test(h) || /市场规模/.test(h)) && /CAGR|增长率|增长趋势/.test(h)
|
|
125148
125211
|
},
|
|
125149
125212
|
{ id: "ch1-value-chain", test: (h) => /价值链|生态定位|产业链/.test(h) },
|
|
125150
|
-
{
|
|
125151
|
-
|
|
125152
|
-
test: (h) => (/美国|加拿大|墨西哥|中国|欧洲/.test(h) || /国家|区域/.test(h)) && /增长|规模|优先级|潜力/.test(h)
|
|
125153
|
-
},
|
|
125154
|
-
{ id: "ch1-pestel", test: (h) => /PESTEL|政策|法规环境|技术趋势/.test(h) },
|
|
125213
|
+
{ id: "ch1-target-geo", test: (h, ctx) => hasTargetGeoBreakdown(h, ctx) },
|
|
125214
|
+
{ id: "ch1-pestel", test: (h) => /PESTEL|政策|法规环境|技术趋势|经济|社会|环境/.test(h) },
|
|
125155
125215
|
{ id: "ch1-forecast", test: (h) => /预测|3.?5年|未来\d/.test(h) },
|
|
125156
125216
|
{ id: "ch2", test: (h) => /行业深度洞察|目标行业/.test(h) },
|
|
125157
125217
|
{ id: "ch2-pain", test: (h, ctx) => ctx.painPointCount >= 4 },
|
|
125158
|
-
{ id: "ch2-compliance", test: (h) =>
|
|
125218
|
+
{ id: "ch2-compliance", test: (h) => /法规|合规/.test(h) && /<table/.test(h) },
|
|
125159
125219
|
{
|
|
125160
125220
|
id: "ch2-bpmn",
|
|
125161
|
-
test: (h) => /原流程|BPMN|介入后|新流程/.test(h) &&
|
|
125221
|
+
test: (h) => /原流程|BPMN|介入后|新流程/.test(h) && /效率|成本|提升|下降|节约/.test(h)
|
|
125162
125222
|
},
|
|
125163
125223
|
{ id: "ch3", test: (h) => /目标受众|受众与场景/.test(h) },
|
|
125164
125224
|
{ id: "ch3-audience", test: (h) => /用户|受众|画像|群体/.test(h) && /<table/.test(h) },
|
|
125165
125225
|
{ id: "ch3-scenario", test: (h) => /应用场景|场景|差异化|用户价值|企业价值/.test(h) },
|
|
125166
125226
|
{ id: "ch4", test: (h) => /竞争策略|竞争.{0,6}定位/.test(h) },
|
|
125167
|
-
{ id: "ch4-competitors", test: (h) =>
|
|
125168
|
-
|
|
125169
|
-
{ id: "ch4-compare-table", test: (h) => competitorCompareTableRows(h) >= 11 },
|
|
125227
|
+
{ id: "ch4-competitors", test: (h, ctx) => ctx.competitorCount >= 3 },
|
|
125228
|
+
{ id: "ch4-compare-table", test: (h, ctx) => ctx.competitorTableRows >= 11 },
|
|
125170
125229
|
{
|
|
125171
125230
|
id: "ch4-gaps",
|
|
125172
125231
|
test: (h) => [
|
|
@@ -125195,11 +125254,22 @@ var CONTENT_RULES = [
|
|
|
125195
125254
|
{ id: "viz-echarts", test: (h, ctx) => hasEchartsCdn(h) && ctx.chartCount >= 1 },
|
|
125196
125255
|
{ id: "viz-source", test: (h) => /Source:|来源:|来源:/.test(h) }
|
|
125197
125256
|
];
|
|
125198
|
-
function
|
|
125257
|
+
function validationContextFromReport(data) {
|
|
125258
|
+
const customerInfo = data.customerInfo && typeof data.customerInfo === "object" && !Array.isArray(data.customerInfo) ? data.customerInfo : {};
|
|
125259
|
+
return {
|
|
125260
|
+
targetMarket: String(data.targetMarket ?? customerInfo.targetMarket ?? "").trim() || void 0,
|
|
125261
|
+
industry: String(customerInfo.industry ?? "").trim() || void 0,
|
|
125262
|
+
customerName: String(customerInfo.customerName ?? "").trim() || void 0
|
|
125263
|
+
};
|
|
125264
|
+
}
|
|
125265
|
+
function validateMarketReportContent(html, reportContext) {
|
|
125199
125266
|
const ctx = {
|
|
125200
|
-
|
|
125267
|
+
...reportContext,
|
|
125268
|
+
tableCount: (html.match(/<table/gi) ?? []).length,
|
|
125201
125269
|
chartCount: countEchartsInstances(html),
|
|
125202
|
-
painPointCount: countPainPoints(html)
|
|
125270
|
+
painPointCount: countPainPoints(html),
|
|
125271
|
+
competitorTableRows: findFeatureCompareTableRows(html),
|
|
125272
|
+
competitorCount: countCompetitorMentions(html)
|
|
125203
125273
|
};
|
|
125204
125274
|
const dimById = new Map(MARKET_REPORT_DIMENSIONS.map((d) => [d.id, d]));
|
|
125205
125275
|
const missing = [];
|
|
@@ -125222,7 +125292,7 @@ function validateMarketReportContent(html) {
|
|
|
125222
125292
|
tables: ctx.tableCount,
|
|
125223
125293
|
charts: ctx.chartCount,
|
|
125224
125294
|
painPoints: ctx.painPointCount,
|
|
125225
|
-
competitorTableRows:
|
|
125295
|
+
competitorTableRows: ctx.competitorTableRows
|
|
125226
125296
|
}
|
|
125227
125297
|
};
|
|
125228
125298
|
}
|
|
@@ -125230,7 +125300,7 @@ function formatMarketReportContentErrors(result) {
|
|
|
125230
125300
|
if (result.ok) return "";
|
|
125231
125301
|
const lines = result.missing.map((m) => ` - [${m.chapter}] ${m.dimension}\uFF1A${m.hint}`);
|
|
125232
125302
|
return [
|
|
125233
|
-
`\u62A5\u544A\u7F3A\u5C11 ${result.missing.length} \u9879\u5FC5\u542B\u5185\u5BB9\uFF08\
|
|
125303
|
+
`\u62A5\u544A\u7F3A\u5C11 ${result.missing.length} \u9879\u5FC5\u542B\u5185\u5BB9\uFF08\u901A\u7528\u884C\u4E1A\u8C03\u67E5\u7EF4\u5EA6\uFF09\uFF1A`,
|
|
125234
125304
|
...lines,
|
|
125235
125305
|
"",
|
|
125236
125306
|
"\u8BF7 Read assets/market-analysis-rules.md\u300C\u539F\u59CB\u4E1A\u52A1\u7EF4\u5EA6\u6E05\u5355\u300D\uFF0CWebSearch \u8865\u5168\u7F3A\u5931\u7AE0\u8282\u540E\u91CD\u5199 market-report.json\u3002"
|
|
@@ -125280,7 +125350,8 @@ async function runMarketAnalysisRender(opts) {
|
|
|
125280
125350
|
console.error("\n\u274C \u62A5\u544A HTML \u5185\u5BB9\u4E3A\u7A7A\n");
|
|
125281
125351
|
process.exit(1);
|
|
125282
125352
|
}
|
|
125283
|
-
const
|
|
125353
|
+
const reportData = asRecord4(dataRaw);
|
|
125354
|
+
const contentCheck = validateMarketReportContent(html, validationContextFromReport(reportData));
|
|
125284
125355
|
if (!contentCheck.ok) {
|
|
125285
125356
|
console.error(`
|
|
125286
125357
|
\u274C ${formatMarketReportContentErrors(contentCheck)}
|
package/dist/skill/_meta.json
CHANGED
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
|
|
28
28
|
### 封面
|
|
29
29
|
|
|
30
|
-
| 维度 | 必含内容
|
|
31
|
-
| -------- |
|
|
32
|
-
| 报告标识 |
|
|
33
|
-
| 执行摘要 | 核心结论段或 KPI/metric 卡片(非仅标题)
|
|
30
|
+
| 维度 | 必含内容 |
|
|
31
|
+
| -------- | ------------------------------------------------------------------------ |
|
|
32
|
+
| 报告标识 | 标题含「战略市场分析」「行业分析报告」「市场分析报告」或「行业调查」等 |
|
|
33
|
+
| 执行摘要 | 核心结论段或 KPI/metric 卡片(非仅标题) |
|
|
34
34
|
|
|
35
35
|
### 一、市场与趋势诊断
|
|
36
36
|
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
| --- | ------------------ | ------------------------------------------------------------------- |
|
|
39
39
|
| 1.1 | 全球市场规模与增长 | TAM/SAM/SOM 或「市场规模」+ CAGR/增长率;**须有 ECharts 图** |
|
|
40
40
|
| 1.2 | 赛道与生态定位 | 价值链/产业链表:上游·中游·下游·服务层 |
|
|
41
|
-
| 1.3 | 目标市场国家拆解 |
|
|
41
|
+
| 1.3 | 目标市场国家拆解 | 按国家/区域:规模、增长、优先级、潜力(与 collect `--target-market` 一致) |
|
|
42
42
|
| 1.4 | 技术趋势 PESTEL | 政策/经济/社会/技术/环境/法规 ≥6 维表或等价结构 |
|
|
43
43
|
| 1.5 | 中期预测 | 未来 3–5 年趋势 + **假设依据** |
|
|
44
44
|
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
|
|
62
62
|
| # | 维度 | 必含内容 |
|
|
63
63
|
| --- | ------------ | ------------------------------------------------------ |
|
|
64
|
-
| 4.1 | 竞品识别 | 点名 **≥3**
|
|
65
|
-
| 4.2 | 功能性能对比 | 对比表 **≥10 行维度** ×
|
|
64
|
+
| 4.1 | 竞品识别 | 点名 **≥3** 个主要竞品/对标企业(**不限定**具体行业品牌) |
|
|
65
|
+
| 4.2 | 功能性能对比 | 对比表 **≥10 行维度** × 维度列 + **≥3** 个对比主体列 + 性能指标行 |
|
|
66
66
|
| 4.3 | 竞争空白 | **功能、场景、用户群、地域** 四类空白(至少覆盖 3 类) |
|
|
67
67
|
| 4.4 | 定位与差异化 | **一句定位陈述** + **3 个差异化维度** |
|
|
68
68
|
|
|
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
$PKG_NAME = 'siluzan-tso-cli'
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
$PKG_VERSION = '1.1.35-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.35-beta.2'
|
|
13
13
|
$CLI_BIN = 'siluzan-tso'
|
|
14
14
|
$SKILL_LABEL = 'Siluzan TSO'
|
|
15
15
|
$INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
|
|
@@ -9,7 +9,7 @@ set -euo pipefail
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
readonly PKG_NAME="siluzan-tso-cli"
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
readonly PKG_VERSION="1.1.35-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.35-beta.2"
|
|
13
13
|
readonly CLI_BIN="siluzan-tso"
|
|
14
14
|
readonly SKILL_LABEL="Siluzan TSO"
|
|
15
15
|
readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
|