dsh-erpbot 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +198 -2
- package/bot-identity.js +246 -0
- package/client.js +9229 -0
- package/cordis.patch.yml +132 -0
- package/docs/README.md +39 -0
- package/docs/acceptance.md +136 -0
- package/docs/architecture.md +161 -0
- package/docs/bot-agents-spec.md +205 -0
- package/docs/bot-collaboration-spec.md +161 -0
- package/docs/data-contract.md +262 -0
- package/docs/mcp-inventory-analysis.md +58 -0
- package/docs/requirements.md +234 -0
- package/icon.svg +11 -0
- package/index.js +641 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +69 -4
- package/scripts/build.mjs +115 -0
- package/scripts/check-bot-identity.mjs +71 -0
- package/scripts/lint-factories.mjs +315 -0
- package/scripts/lint-scopes.mjs +179 -0
- package/scripts/scaffold-bots.mjs +76 -0
- package/scripts/test-manifest.mjs +72 -0
- package/scripts/verify.mjs +159 -0
- package/spec/README.md +299 -0
- package/spec/base-content-spec.md +129 -0
- package/spec/cai-content-spec.md +257 -0
- package/spec/shui-content-spec.md +252 -0
- package/spec/spec-CORE.md +155 -0
- package/spec/tui-content-spec.md +259 -0
- package/spec/zi-content-spec.md +256 -0
- package/src/README.md +51 -0
- package/src/assistant/index.js +844 -0
- package/src/board-data.js +77 -0
- package/src/bot-data.js +160 -0
- package/src/bundle.json +163 -0
- package/src/cards/index.js +489 -0
- package/src/chart/index.js +186 -0
- package/src/dashboard/index.js +377 -0
- package/src/entry.js +23 -0
- package/src/header.js +19 -0
- package/src/i18n/index.js +622 -0
- package/src/icons.js +115 -0
- package/src/kpi-detail.js +135 -0
- package/src/loader.js +19 -0
- package/src/metric-format.js +90 -0
- package/src/mount.js +126 -0
- package/src/nav.js +11 -0
- package/src/pages-data.js +1093 -0
- package/src/primitives.js +106 -0
- package/src/shell/index.js +124 -0
- package/src/styles.js +2537 -0
- package/src/theme-bridge.js +33 -0
- package/src/workbench/index.js +2043 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mingde431
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,199 @@
|
|
|
1
|
-
#
|
|
1
|
+
# erpBot(Harness Erp)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
一个 DSH(DeepSeek Harness)Web UI 插件:在左侧导航栏顶部新增 **erpBot** 入口,点开是一个按 **Aurora** 主题的财务 / ERP 面板——**1 个总览 + 4 个业务 Bot + 1 个团队模式 + 1 个底座**,支持中英双语,**左下角可切换语言**。
|
|
4
|
+
|
|
5
|
+
## 功能
|
|
6
|
+
|
|
7
|
+
- 左侧导航栏图标列表顶部(`plugins`、自动化任务之上)新增 erpBot 图标(B 字标)。
|
|
8
|
+
- 主面板:Aurora 风格的财务面板(统计卡 + 迷你折线、虚拟信用卡与额度进度、SVG 收支折线图、支出占比环形图、最近交易)。
|
|
9
|
+
- **七个导航目录**:总览 `overview`、账房·财 `finance`、司库·资 `funds`、军师·推 `forecast`、税官·税 `tax`、团队模式 `team`、底座 `base`(MCP 与数据单页)。页面状态写进 `#/erp/<id>`,刷新后停在原页。
|
|
10
|
+
- **左侧 rail**:白色导航组内从上到下是 **erpBot 的 B 字标 + 7 个导航图标**(总览 / 四个 Bot / 团队 / 底座),导航组外左右各留 **8px**;左下角是 erpBot 字标 + 「中 / EN」分段语言开关。列宽不写死,由内容算出(图标按钮 + 组内边距 + 两侧 8px 留白):常规/中档 70px、≤900px 66px、≤560px 60px;B 字标与图标同宽同列,悬浮与选中态沿用原 Aurora 图标列设计。
|
|
11
|
+
- 单一主题:只保留 Aurora 一种风格(源设计里的第二种主题已移除)。
|
|
12
|
+
- 双语:只做 `中文` / `EN` 两种,**默认中文**。切换控件是左下角按钮组(设置、语言)里的**一颗圆按钮**,只显示当前语言(`中` / `EN`),点击即切换。语言是插件内自持状态,不跟随、也不改写宿主的界面语言。
|
|
13
|
+
- **我的卡片是轮播**,最多 5 张(`CARD_LIMIT`):左右两颗圆箭头翻页、底部圆点直接跳转、右上角显示「第 N / 5 张」,并用 `CARD_AUTO_MS`(5.2s)自动轮播。鼠标移入卡片区或键盘聚焦时**暂停**自动轮播,手动翻页后计时器重置,不会刚翻完又被自动切走。卡片数据在 `CARDS` 数组里,每张有自己的品牌、卡号后四位、有效期、安全码、额度进度和配色(`v1`–`v5` 五种 Aurora 家族色调,CSS 类 `.visa.v2…v5`)。源设计里的「添加卡片」按钮已移除。
|
|
14
|
+
- 自适应:面板宽高完全跟随 DSH 分配的槽位区域。
|
|
15
|
+
- **宽度**用容器查询分级重排:`.erp-app` 声明 `container-type:inline-size` / `container-name:erp`,所有断点都是 `@container erp (max-width: 1180/900/720/560px)`,即按**槽位宽度**而非窗口宽度重排(4 列统计卡 → 2 列 → 1 列,row2 / row3 依次塌成单列)。
|
|
16
|
+
- **高度**用 `container-type:size` 的板容器:`.erp-board` 声明 `container-name:board`,短高度断点全部是 `@container board (max-height: 820/680/560/460px)`。**关键点**:旧实现用 `@media (max-height: …)`,测的是浏览器窗口高度;面板实际高度由 DSH 分配,窗口高而面板矮时规则不会触发 → 底部卡片被裁。改成容器查询后,量的是槽位盒子本身。
|
|
17
|
+
- 行高不写死像素:宽屏下 `.t1-main` 用 `grid-template-rows: auto minmax(var(--erp-row2-min),1.42fr) minmax(var(--erp-row3-min),1fr)`,三行**分享**框内剩余高度;各短高度档只把 `--erp-row2-min` / `--erp-row3-min` 改成 `0px`,不再直接写 `grid-template-rows`(否则窄面板单列堆叠时也会被强制 fr 分配,把卡片压成 0 高)。
|
|
18
|
+
- 放不下的信息靠**卡片内部降级**消化,绝不把布局顶出去:图表 `flex:1 1 auto` + `min-height` 触底;`.ov-foot`、`.boost`、`.spark`、`.stat-sub`、`.yc-meta`、时间段等次要信息按高度档依次隐藏;交易行按档留 4/3/2 行;VISA 卡在矮盒里从 1.62:1 卡片切成横向 banner(banner 会为左右箭头预留 `padding`,箭头永远不被品牌字盖住),低于 24px 整卡隐藏;环形图改由行高驱动(`height:100%;width:auto;max-height`),极矮档删环留图例。
|
|
19
|
+
- 图表自身有 `tight` 模式:`drawOverview()` 在 `H < 118` 时收窄内边距、省略非零刻度标签、隐藏 tooltip,但**仍然绘图**(旧实现在 `H < 110` 直接 return,矮面板会留空白卡)。
|
|
20
|
+
- 只有右侧 `.t1-main` 会滚动;左侧 `.t1-rail` 整体 `overflow:hidden`,矮面板下只有主图标组自己滚动(隐藏滚动条),设置/语言那颗底部按钮组 `flex:none` 始终留在左下角。
|
|
21
|
+
- 单列模式(`@container erp (max-width:1180px)`)下卡片区是内容高度,卡面(高度驱动的 1.62:1)会塌成 0,所以这一档给 `.visa-wrap` 单独设 `height:clamp(120px,24cqh,240px)`。
|
|
22
|
+
- 支出构成卡是**二级容器**:`.exp-card` 自己声明 `container-type:inline-size`(`container-name:exp`),环形图直径、圆心文字、图例字号与间距全部用 `clamp(…cqi…)` 按**卡片自身宽度**伸缩;**环形图与图例始终同一行**(窄于 290px 只收紧间距、把环径压到 76–96px,绝不改成上下堆叠——堆叠会把卡脚顶出卡片),窄于 190px 时隐藏百分比,宽于 420px 时环与图例作为整组居中、图例宽度封顶避免两端拉散。环形图再有第三层 `@container donut (max-height:66px)`,环太矮时只保留金额、隐去「支出合计」。560px 档的图例折成两列网格,460px 档(环已隐藏)图例占满卡片宽度、四列一行排开。
|
|
23
|
+
|
|
24
|
+
## 七个导航目录(总览 / 四 Bot / 团队 / 底座)
|
|
25
|
+
|
|
26
|
+
分成四种形态:
|
|
27
|
+
|
|
28
|
+
- **财 / 资 / 推 / 税 = Bot 页**(`BotShell`):顶排仍是 4 个 KPI 卡;KPI 行以下是**一整块对话卡片**(官方 DSH 会话嵌入),不再有常驻左栏。点对话头部的 **Bot 头像**打开右侧配置抽屉:身份(角色定义只读 + 称呼 / 语气 / 时间口径偏好)、技能(本地 8 / 6 / 8 / 6 + 可加载平台技能,上限 12)、记忆(用户身份关系 + 技能清单,存 localStorage)。每个 Bot 一个独立工作区(默认 `D:\erpBot\<bot>`,D 盘不可用时降级到 `Documents\deepseek-harness\erpbot-<bot>`),工作区里的 `bot.json` / `AGENTS.md` / `SKILLS.md` 由挂载时的 `scaffoldAllBots()` 补齐。技能「看结果」在右侧画布抽屉里复用原 12 种渲染器。
|
|
29
|
+
- **团队模式 `team` = 共享工作区**(`TeamShell`):点「团队模式」开一个 `D:\erpBot\team` 的 root 会话,经官方 `remote.agentTeams` 打开 Team 模式,四个财务 Bot 作为子 agent 按 preset 被委派;页面只做**镜像展示**(任务板 / 成员 / 对某个 Bot 下指令),协作逻辑全在 DSH。方案见 `docs/bot-collaboration-spec.md`。
|
|
30
|
+
- **底座 `base` = MCP 与数据单页**:一个导航入口(`底座 · MCP 与数据` / `Base · MCP and Data`),**页内无 tab**;顶排 4 张 KPI(MCP 通道 / 数据源 / 指标 / 质量异常)+ 两栏工作台(左 MCP 清单 + 右接口清单,数据来自 Host 的 `/erp/mcp/list` 与 `/erp/mcp/probe`)。方向与事实依据见 `docs/mcp-inventory-analysis.md`。
|
|
31
|
+
- **总览 `overview`**:待办与跨页状态,布局不变。
|
|
32
|
+
|
|
33
|
+
- 财 / 资 / 推 / 税:账、钱、预测、税(内容见 `spec/` 下四份 `*-content-spec.md`;Bot 身份 / 技能配置同见 `spec/`)。
|
|
34
|
+
- 底座(MCP 与数据)的写边界、审计链、导出与跨页同数规则见 `spec/base-content-spec.md` §6;**审计链唯一在底座**,Bot 只保留回执引用。
|
|
35
|
+
|
|
36
|
+
### KPI 卡(7 种变体,按 `kpi.kind` 渲染)
|
|
37
|
+
|
|
38
|
+
2026-11-12 重做:**每张卡只留三件事** —— 主数字(带单位)、一行口径(`kpi.cardSub`)、一个微型图;账户拆分、三层图例、状态分解、备注全部收进 `MetricDetailModal`。卡的骨架固定为 标题行 → 主数字(+ 仪表环)→ 口径行 → 微型图 + 环比,四列并排时不再出现 8–9px 小字和互相挤压。
|
|
39
|
+
|
|
40
|
+
**金额单位**:payload 仍只写精确到分的元(`¥8,450,000.00`,见 SCHEMA §4),**显示层**由 `moneyParts()` / `compactMoney()` 统一换算:
|
|
41
|
+
|
|
42
|
+
| 量级 | 中文 | English |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| ≥ 1 亿 | `¥1.26亿` | ≥ 1B → `¥1.26B` |
|
|
45
|
+
| ≥ 1 万 | `¥845万`、`¥1,200万`、`¥64.35万` | ≥ 1M → `¥8.45M`;≥ 10K → `¥643.5K` |
|
|
46
|
+
| < 1 万 | 保留精确元 `¥8,640.00` | 同(`¥8,640.00`) |
|
|
47
|
+
|
|
48
|
+
小数点后最多两位、去掉无意义的尾零,溢出时自动进位(`99,999,999` → `1亿`)。浮点单位只用于**读数**:图标 title、弹窗「精确金额」行、构成明细与 `detail.formula` 仍给到分,勾稽不因换算失真。
|
|
49
|
+
|
|
50
|
+
| kind | 卡上长什么样 | 用在哪页 |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `value` | 大数字 + 迷你折线 + 环比 | 财(凭证数)、推(预测收入)、税(应纳增值税) |
|
|
53
|
+
| `split` | 大数字 + 3 段占比条(无文字) | 资(总余额)、税(待缴 → 增值税 / 附加 / 个税) |
|
|
54
|
+
| `stack` | 大数字 + 3 段构成条(无图例) | 资(可用余额三层) |
|
|
55
|
+
| `gauge` | 主数字 + 环形进度(`ratio`) | 财(期末 8/12)、推(预算执行 64%)、税(申报 2/3) |
|
|
56
|
+
| `countdown` | 主数字 + 进度条 + 截止日(口径行) | 税(申报剩 4 天) |
|
|
57
|
+
| `status` | 主数字 + 状态徽标(标题行右侧)+ 一行清单摘要 | 财(待处理单据 37)、资(未达项 3 笔)、推(假设版本 A3) |
|
|
58
|
+
| `delta` | 带符号差异 + 迷你折线 + note 收进弹窗 | 财(借贷差异 ¥0.00)、资(今日净额)、推(与上版差异) |
|
|
59
|
+
|
|
60
|
+
点开卡片进入 `MetricDetailModal`:标题 + 主数字(同单位)+ **精确金额** + 完整口径(`kpi.sub`)+ 可选迷你折线(有 `kpi.spark` 才有)+ **构成明细**(`detail.breakdown`,缺省回退 `kpi.parts` / `kpi.lines`,数值/占比/占比条)+ **统计口径**(`detail.formula`)+ 更新时点。`detail.formula` 就是该数的口径,必须能算。
|
|
61
|
+
|
|
62
|
+
### 右侧主内容(12 种渲染器,按 `section.kind` 分发)
|
|
63
|
+
|
|
64
|
+
| kind | 渲染 | 用在哪页 |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `list` | 行列表(name / desc / badge / tone / meta) | 财应付、税查验、税申报 |
|
|
67
|
+
| `table` | 多列表格 + 合计行 | 财凭证 / 报表、资票据、税销项 / 进项、推管报 |
|
|
68
|
+
| `flow` | 收付款流水(in / out 方向与符号) | 资收付待办、税报送与缴款 |
|
|
69
|
+
| `cards` | 卡片网格(自适应 4 列) | 财固定资产、资账户、推资金计划 |
|
|
70
|
+
| `steps` | 进度条 + 步骤清单(done / active / todo / off) | 财期末关账 12 步 |
|
|
71
|
+
| `checks` | 断言清单(ok / warn / error) | 财试算平衡、财核对底稿 |
|
|
72
|
+
| `bars` | 横向条形(pct + 文本值) | 财应收账龄、推预算编制、推差异归因 |
|
|
73
|
+
| `chart` | 折线 / 柱状 + 标签 + 口径注脚 | 资资金计划、推滚动预测、税税负率 |
|
|
74
|
+
| `donut` | 环形构成 + 图例 | 推成本分摊 |
|
|
75
|
+
| `timeline` | 版本 / 运行时间线 | 推假设版本 A1 → A2 → A3 |
|
|
76
|
+
| `scenarios` | 情景对比表 | 推情景模拟 |
|
|
77
|
+
| `empty` | 未接入占位(旧 `rows` 结构自动降级) | 仅历史数据兜底;全部页面均已接入真实 payload |
|
|
78
|
+
|
|
79
|
+
左栏条目可带 `pill`(如「4 批」「12 步」「2/3」);右栏顶部可带 1–3 个 `summary` 摘要块,底部可带 `foot` 口径落款;`chart` / `donut` / `bars` 等按数据形状各自成图。
|
|
80
|
+
|
|
81
|
+
**图表 / 清单双视图**:`chart` / `donut` / `bars` 三类板块在 payload 里带 `alt`(`{kind:'list'|'table', data}`)时,右栏标题右侧出现「图表 / 清单」切换;图表看趋势,清单看同一口径的明细行(合计对平)。切段时自动回到图表视图。
|
|
82
|
+
|
|
83
|
+
### 数据与维护
|
|
84
|
+
|
|
85
|
+
- 页面数据 = `PAGES.finance/funds/forecast/tax`(`base` 页走 `BaseShell` 专用两栏布局:4 KPI + 左 MCP 清单 + 右接口清单,不再读 `PAGES` 的 sections);源文件 `src/pages-data.js`,**改数据改 payload → `node scripts/build.mjs` → 重启 DSH**,不要手改 `client.js` 里的 `PAGES` 块。
|
|
86
|
+
- payload 契约:`docs/data-contract.md`;四页内容与口径见 `spec/`(`cai` / `zi` / `tui` / `shui` 四份 `*-content-spec.md` 分别对应 `finance` / `funds` / `forecast` / `tax`,文件名沿用旧页 id)与 `docs/bot-agents-spec.md`;`base` 页走 `BaseShell`,数据由 Host 的 `/erp/mcp/*` 路由实时取,不写 payload。
|
|
87
|
+
- **单位只换算在渲染层**:payload 永远写 `¥` + 千分位 + 两位小数(SCHEMA §4 禁止 `万/亿`);`PageKpi` / `MetricDetailModal` 用 `moneyParts()` / `compactMoney()` 显示成 `¥845万` / `¥8.45M`。改单位规则只改这两个函数,别改数据。
|
|
88
|
+
- 卡的短口径在 `kpi.cardSub`(`{zh,en}`,一行以内);完整口径仍是 `kpi.sub`,只出现在弹窗。`caption`(如「剩 4 步」)也在弹窗显示。
|
|
89
|
+
- 静态自检(无浏览器):`node scripts/build.mjs --check`(产物与 src 同步)、`node scripts/test-manifest.mjs`(顺序校验器负面测试)、`node scripts/lint-factories.mjs`(工厂未注入自由引用)、`node scripts/lint-scopes.mjs`(`index.js` 作用域)、`node scripts/check-bot-identity.mjs`(Host 与客户端身份数据一致)。渲染层没有自动化回归脚本,改 UI 后请在 DSH 里逐页目视验收。
|
|
90
|
+
- 内容与口径来源:`spec/`(四份 Bot 规格 + `base-content-spec.md`)与 `docs/`(需求 / 数据契约 / 验收 / 架构)。
|
|
91
|
+
|
|
92
|
+
## 安装状态
|
|
93
|
+
|
|
94
|
+
- **npm**:已发布为 `dsh-erpbot`(https://www.npmjs.com/package/dsh-erpbot)。
|
|
95
|
+
- **Gitee**:源码仓库 https://gitee.com/mingde431/dsh-erpbot 。
|
|
96
|
+
- **本机 `desktop` profile**:`dsh.profile.bundles` 含 `dsh-erpbot`,`dependencies` 为 `link:D:/DSH 插件/dsh-erpbot`(开发期联动),**改动 `client.js` 后需重启 DSH 生效**。
|
|
97
|
+
|
|
98
|
+
## 结构
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
dsh-erpbot/
|
|
102
|
+
├── package.json # bundle manifest:exports / files / dsh.bundle.patch / dsh.client
|
|
103
|
+
├── cordis.patch.yml # 向 profile 的 Cordis 组合插入 dsh-erpbot 条目
|
|
104
|
+
├── index.js # Host 半:Bot 工作区与身份文件自举 + /erp/workspace、/erp/team/*、/erp/mcp/* 路由
|
|
105
|
+
├── bot-identity.js # Host 侧 Bot 身份数据 + AGENTS.md / bot.json 生成器(与客户端同源)
|
|
106
|
+
├── client.js # Client 半【产物】:由 src/ 拼接而成,不要直接改
|
|
107
|
+
├── src/ # Client 半【来源】:7 个功能板块工厂 + 横切小片 + entry 接线
|
|
108
|
+
│ ├── bundle.json # 拼接顺序的唯一声明(order 升序)
|
|
109
|
+
│ ├── entry.js # 唯一接线点:实例化 7 个工厂、解构到顶层
|
|
110
|
+
│ ├── loader.js # __ModuleLoader__.load 开头
|
|
111
|
+
│ ├── mount.js # return { inject, apply } 收尾
|
|
112
|
+
│ ├── i18n/ chart/ assistant/ cards/ dashboard/ workbench/ shell/ # 功能板块(各一个 createXxx 工厂)
|
|
113
|
+
│ └── icons.js styles.js board-data.js pages-data.js bot-data.js nav.js
|
|
114
|
+
│ metric-format.js theme-bridge.js primitives.js kpi-detail.js # 横切共享小片
|
|
115
|
+
├── scripts/ # build.mjs(拼接 + acorn AST 顺序校验)、verify.mjs、test-manifest.mjs、lint-factories.mjs、lint-scopes.mjs、check-bot-identity.mjs、scaffold-bots.mjs
|
|
116
|
+
├── locale/en.json # 显示元数据(插件市场/设置页用)
|
|
117
|
+
├── locale/zh.json
|
|
118
|
+
└── icon.svg # 原创图标(Aurora 渐变 + B 字标)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`client.js` 是 DSH 实际加载的 **单文件 bundle**。源码按**功能板块**拆成 7 个工厂函数
|
|
122
|
+
(`createI18n` / `createChart` / `createAssistant` / `createCards` / `createDashboard` /
|
|
123
|
+
`createWorkbench` / `createShell`),每个板块**依赖对象进、命名空间对象出**;`entry.js`
|
|
124
|
+
按拓扑序实例化它们,`scripts/build.mjs` 纯拼接 + acorn AST 校验顺序。`createAssistant` 现在是
|
|
125
|
+
**四个 Bot 的会话引擎**(工作区 / 会话 / 预填 / 官方会话嵌入 / 团队会话),`createWorkbench` 提供
|
|
126
|
+
`BotShell`(对话页)、`SectionShell`(单页工作台)、`BaseShell`(底座 MCP 两栏)与 `TeamShell`(团队模式镜像页)。详见 `src/README.md`。
|
|
127
|
+
|
|
128
|
+
## 安装
|
|
129
|
+
|
|
130
|
+
```powershell
|
|
131
|
+
# A. 从 npm 装(包名即 npm 上的 dsh-erpbot)
|
|
132
|
+
plugin_manager action:install_bundle target:"dsh-erpbot"
|
|
133
|
+
|
|
134
|
+
# B. 从本地目录装(开发期,plugin_manager 会做 link)
|
|
135
|
+
plugin_manager action:install_bundle target:"D:\DSH 插件\dsh-erpbot"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
安装后读取返回的 `application` / `warnings`;用 `cordis_inspect_query`(provider `Config`, method `listConfigs`)确认出现 `dsh-erpbot` 行,再刷新 GUI 页面即可。
|
|
139
|
+
|
|
140
|
+
只想看源码而不装插件:`git clone https://gitee.com/mingde431/dsh-erpbot.git`。
|
|
141
|
+
|
|
142
|
+
## 开发说明
|
|
143
|
+
|
|
144
|
+
- Client 半用 `window.__ModuleLoader__.load({ id: 'dsh-erpbot', factory(require) {...} })`,React 从 `require('react')` 取,**不要**再装 React 或引 CDN。
|
|
145
|
+
- **改代码:编辑 `src/**` → `node scripts/build.mjs` → 重启 DSH。** 直接改 `client.js` 会被下次构建覆盖。
|
|
146
|
+
- 提交前自检:
|
|
147
|
+
```powershell
|
|
148
|
+
npm install # 首次:装 devDependency acorn(仅校验,不进产物)
|
|
149
|
+
node scripts/build.mjs # 拼接 + AST 顺序校验
|
|
150
|
+
node scripts/build.mjs --check # 产物与 src 同步
|
|
151
|
+
node scripts/test-manifest.mjs # 校验器负面测试
|
|
152
|
+
node scripts/lint-factories.mjs # 工厂未注入自由引用(防运行时空白回归)
|
|
153
|
+
node scripts/check-bot-identity.mjs # Host 与客户端两份 Bot 身份数据一致
|
|
154
|
+
node --check client.js # 产物语法
|
|
155
|
+
```
|
|
156
|
+
- Bot 工作区自举:`bot-identity.js` 是 Host 侧的身份数据与文档生成器,插件挂载时
|
|
157
|
+
`scaffoldAllBots()` 为四个 Bot 补齐 `bot.json` / `AGENTS.md` / `SKILLS.md`(已存在且
|
|
158
|
+
schema 正确则不动)。手动补一次:`node scripts/scaffold-bots.mjs`。
|
|
159
|
+
- 片段是被**字面拼接**的连续行段、共享同一作用域:不要给片段加 `import`/`export`。
|
|
160
|
+
板块之间只通过工厂 `deps` 参数显式通信,不靠自由变量隐式传递。
|
|
161
|
+
|
|
162
|
+
- 客户端 bundle 在启动时加载,**不会热替换**;改完 `client.js` 需要重启 DSH 才生效。
|
|
163
|
+
- 语言:i18n 板块闭包内 `let lang = 'zh'`,`setLang()` 通知 `subscribeLang` 订阅者重绘;`LanguageSwitch` 渲染「中 / EN」两段式胶囊(文案取自 `LANG_BADGE = { zh: '中', en: 'EN' }`),胶囊宽度跟随 rail 列宽、两段均分。字典以 `ctx.locale.register(NS, { zh, en })` 发布。
|
|
164
|
+
- 样式全部以 `.erp-app` 前缀作用域化,不触碰宿主 UI。三层容器查询:`.erp-app`(`inline-size`,面板宽度)、`.erp-board`(`size`,面板高度)、`.exp-card` / `.donut` / `.visa-wrap`(卡片自身盒子)。**不要**用 `@media` 做面板尺寸判断 —— 面板尺寸 ≠ 窗口尺寸。
|
|
165
|
+
- **改 CSS 注释时绝不能出现反引号**:`const CSS = \`` 是模板字符串,注释里的反引号会提前终止它,运行时报 `ReferenceError`(本插件踩过两次)。
|
|
166
|
+
- **新增一页只需三处**:`NAV` 加一条(`id` / `icon` / `key`)、`ZH` + `EN` 各加一条 `nav.<id>`、`PAGES` 加同 id 的配置。配置里有 `sections` 且带 `botId` 的页走 `BotShell`(KPI 行 + 对话卡 + 头像配置);有 `sections` 但无 `botId` 的页走 `SectionShell`(四个 KPI + 段列表工作台);没有 `sections` 就退回总览式 `core` / `sub` 卡片布局。页面 id 必须全小写字母(`readHashPage` 用 `#/erp/([a-z]+)` 解析)。
|
|
167
|
+
- 左侧 rail 是「B 字标当第一个图标」的分组图标列:白卡片里从上到下是 B 字标、7 个导航图标;卡片左右各留 8px(`--erp-rail-gutter`,作用在 `.t1-rail` 的左右 padding 上)。列宽 = 图标按钮 + 组内边距 + 两侧留白,三个 token `--erp-rail-btn` / `--erp-rail-pad` / `--erp-rail-gutter` 都挂在 `.erp-board` 上;B 字标的宽高直接取 `--erp-rail-btn`,所以品牌块和图标永远同宽同列。矮面板下只有导航组自身滚动(含 B 字标),底部语言锁不住不下移。
|
|
168
|
+
- 左侧 rail 底部组只有 **设置 + 语言** 两颗按钮(源设计的登出/危险按钮已移除,`--danger` 相关的 `.rail-btn.danger` 样式与 `ICONS.logout` 一并删除)。
|
|
169
|
+
|
|
170
|
+
## 槽位契约
|
|
171
|
+
|
|
172
|
+
| 槽位 | 注册 | 说明 |
|
|
173
|
+
| --- | --- | --- |
|
|
174
|
+
| `sidebar.panellist` | `id: 'dsh-erpbot'`, `order: -10`, `label: () => t('nav.erp')` | 左侧导航图标行;`order` 为负即排在 `plugins`(0) 之前 |
|
|
175
|
+
| `main` | `key: 'dsh-erpbot'` | 主面板;`key` 必须等于 sidebar 的 `id` 才会被调度 |
|
|
176
|
+
|
|
177
|
+
`label` 用 thunk 形式,每次投影重读,因此切换语言后导航栏文字会跟着变。
|
|
178
|
+
|
|
179
|
+
## 每页内嵌对话(Bot 页)
|
|
180
|
+
|
|
181
|
+
- 入口:财 / 资 / 推 / 税 四页的**对话头部**;右上角 spark 图标、总览 AI 卡、浮动 Dock / Rail / Modal 已退役。
|
|
182
|
+
- 会话:每个 Bot 一个专属工作区(`D:\erpBot\finance|funds|forecast|tax`,Host 半路由 `POST /erp/workspace` 按 `{bot}` 白名单建目录并注册);会话自动创建并持久化在 `localStorage dsh-erpbot.bot.session.v1.<bot>`。
|
|
183
|
+
- 对话正文仍是官方 `conversation.content` 嵌入(`variant: 'embedded'`,固定 Chat),不自绘聊天界面;技能入口只有三条:欢迎 chips 预填 composer、配置抽屉「问这个」、对话回复 / 技能行「看结果」开画布。
|
|
184
|
+
- 配置抽屉:右侧覆盖式(452px,画布 560px,≤900px 全宽),三页签身份 / 技能 / 记忆;记忆存 `localStorage dsh-erpbot.bot.memory.v1.<bot>`,只存身份关系与技能清单,不含业务数据。
|
|
185
|
+
- 改 `client.js` 后需重启 DSH 生效;Host 半路由改动同样需要重启。
|
|
186
|
+
|
|
187
|
+
## 更新日志
|
|
188
|
+
|
|
189
|
+
### 0.1.1(2026-11-13)
|
|
190
|
+
|
|
191
|
+
- 新增「团队模式」页(`TeamShell`):经官方 `remote.agentTeams` 开 Team 会话,页内镜像任务板与成员,可对单个 Bot 下指令。
|
|
192
|
+
- 导航 id 改为英文 `finance` / `funds` / `forecast` / `tax`(旧深链 `#/erp/cai|zi|tui|shui` 不再生效),并新增 `team`。
|
|
193
|
+
- 底座改为 MCP / 接口两栏;Host 新增 `/erp/mcp/list`、`/erp/mcp/probe`、`/erp/team/*` 路由。
|
|
194
|
+
- 挂载时自动为四个 Bot 补 `bot.json` / `AGENTS.md` / `SKILLS.md`;工作台可在页内编辑 `AGENTS.md`(身份四件套 / 技能绑定 / 偏好 / 红线),带磁盘冲突检测。
|
|
195
|
+
- `cordis.patch.yml` 挂 `agent-team` / `tool-agent-team` 与四个 agent preset;新增 `docs/bot-collaboration-spec.md`、`docs/mcp-inventory-analysis.md`。
|
|
196
|
+
|
|
197
|
+
### 0.1.0(2026-11-13)
|
|
198
|
+
|
|
199
|
+
- 首个 npm 版本:总览 + 四个 Bot 页 + 底座,双语、Aurora 主题、官方会话嵌入。
|
package/bot-identity.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bot identity data for the Host half.
|
|
3
|
+
*
|
|
4
|
+
* This is the host-side copy of the four bots' identity, used ONLY to bootstrap
|
|
5
|
+
* a bot workspace on first mount (bot.json + AGENTS.md + SKILLS.md). The browser
|
|
6
|
+
* bundle keeps its own copy in src/bot-data.js for rendering; the two must agree
|
|
7
|
+
* on id / name / role / duties / tone / boundaries / notApplicable / scene, which
|
|
8
|
+
* scripts/check-bot-identity.mjs verifies.
|
|
9
|
+
*
|
|
10
|
+
* @module dsh-erpbot/bot-identity
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Bot id → workspace display title. This whitelist is the whole API surface. */
|
|
14
|
+
export const BOT_TITLES = {
|
|
15
|
+
finance: 'erpBot · 财 Bot',
|
|
16
|
+
funds: 'erpBot · 资 Bot',
|
|
17
|
+
forecast: 'erpBot · 推 Bot',
|
|
18
|
+
tax: 'erpBot · 税 Bot',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Cross-boundary routing: one bot forwards a topic to the other three. */
|
|
22
|
+
const ROUTING = {
|
|
23
|
+
finance: [
|
|
24
|
+
{ zh: '钱够不够、资金缺口 → 司库(funds)', en: 'Cash position, funding gaps → Treasurer (funds)' },
|
|
25
|
+
{ zh: '预算与预测 → 军师(forecast)', en: 'Budget and forecast → Planner (forecast)' },
|
|
26
|
+
{ zh: '税务与申报 → 税官(tax)', en: 'Tax and filing → Tax Officer (tax)' },
|
|
27
|
+
],
|
|
28
|
+
funds: [
|
|
29
|
+
{ zh: '账务处理与凭证 → 账房(finance)', en: 'Bookkeeping and vouchers → Ledger (finance)' },
|
|
30
|
+
{ zh: '资金计划与预测 → 军师(forecast)', en: 'Cash plan and forecast → Planner (forecast)' },
|
|
31
|
+
{ zh: '涉税事项 → 税官(tax)', en: 'Tax matters → Tax Officer (tax)' },
|
|
32
|
+
],
|
|
33
|
+
forecast: [
|
|
34
|
+
{ zh: '已发生事实与账务 → 账房(finance)', en: 'Actuals and bookkeeping → Ledger (finance)' },
|
|
35
|
+
{ zh: '当前资金与收付 → 司库(funds)', en: 'Current cash and payments → Treasurer (funds)' },
|
|
36
|
+
{ zh: '税务申报 → 税官(tax)', en: 'Tax filing → Tax Officer (tax)' },
|
|
37
|
+
],
|
|
38
|
+
tax: [
|
|
39
|
+
{ zh: '账务处理与凭证 → 账房(finance)', en: 'Bookkeeping and vouchers → Ledger (finance)' },
|
|
40
|
+
{ zh: '资金与收付 → 司库(funds)', en: 'Cash and payments → Treasurer (funds)' },
|
|
41
|
+
{ zh: '预算与预测 → 军师(forecast)', en: 'Budget and forecast → Planner (forecast)' },
|
|
42
|
+
],
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The four bots' identity. Mirrors src/bot-data.js field by field. */
|
|
46
|
+
export const BOT_IDENTITY = {
|
|
47
|
+
finance: {
|
|
48
|
+
id: 'finance',
|
|
49
|
+
name: { zh: '账房', en: 'The Ledger' },
|
|
50
|
+
role: { zh: '把账记对、把账关好、把证据留全', en: 'Keep the books correct, close them cleanly, keep the evidence complete' },
|
|
51
|
+
duties: {
|
|
52
|
+
zh: '解释本期账与表的事实:凭证与分录、账簿与试算、往来与资产明细、期末关账、法定报表、核对底稿;先结论,再口径与证据路径。',
|
|
53
|
+
en: 'Explains the facts behind the books and statements: vouchers, ledgers, working-capital and fixed-asset details, the period close, statutory statements and workpapers. Conclusion first, then definition and evidence path.',
|
|
54
|
+
},
|
|
55
|
+
tone: {
|
|
56
|
+
zh: '严谨、审计口吻;短句;主动披露差异与例外;不确定就写「待复核」;不寒暄、不夸张。',
|
|
57
|
+
en: 'Rigorous, audit tone. Short sentences. Volunteers gaps and exceptions. Says pending review when unsure. No small talk, no hype.',
|
|
58
|
+
},
|
|
59
|
+
boundaries: {
|
|
60
|
+
zh: '不审不批不退;不直写 ERP;不替人签批;不重跑批次、不锁账、不解锁、不重出报表、不申报;不改口径、不在前端重算业务数。',
|
|
61
|
+
en: 'Does not review, approve or return items. Does not write to ERP directly. Does not sign for people. Does not rerun batches, lock or unlock periods, reissue statements or file returns. Does not change definitions or recompute business numbers in the front end.',
|
|
62
|
+
},
|
|
63
|
+
notApplicable: {
|
|
64
|
+
zh: '外币折算 / 汇兑损益(单一本位币);合并范围 / 合并抵消 / 权益法(单一法人)。',
|
|
65
|
+
en: 'FX translation and exchange differences (single functional currency); consolidation scope, eliminations and the equity method (single legal entity).',
|
|
66
|
+
},
|
|
67
|
+
scene: {
|
|
68
|
+
zh: '面对「账平不平 / 期末走到哪 / 报表能不能出」类问题时:先给结论(平 / 不平、几步、能否出),再给口径与证据路径(报表 → 底稿 → 账簿 → 凭证);差异必须点名到单据或步骤。',
|
|
69
|
+
en: 'For questions about whether the books balance, where the close stands or whether statements are ready: give the conclusion first, then the definition and the evidence path (statements, workpapers, ledgers, vouchers). Name the document or step behind every gap.',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
funds: {
|
|
73
|
+
id: 'funds',
|
|
74
|
+
name: { zh: '司库', en: 'The Treasurer' },
|
|
75
|
+
role: { zh: '守住可支付能力与安全垫', en: 'Guard the payment capacity and the safety buffer' },
|
|
76
|
+
duties: {
|
|
77
|
+
zh: '解释现在能动多少钱:账户与余额、收付待办、对账与未达、资金计划、受限资金、票据与授信;先给可用口径,再给时点。',
|
|
78
|
+
en: 'Explains how much cash is actually available: accounts, payment queue, reconciliation and unreconciled items, cash plan, restricted funds, bills and credit lines. Availability first, then timestamp.',
|
|
79
|
+
},
|
|
80
|
+
tone: {
|
|
81
|
+
zh: '直接、风险优先、数字先行;先给结论与风险,再给依据;不做预测保证。',
|
|
82
|
+
en: 'Direct, risk-first, numbers first. Conclusion and risk before evidence. Never promises an outcome.',
|
|
83
|
+
},
|
|
84
|
+
boundaries: {
|
|
85
|
+
zh: '不动账、不调账(未达调账凭证由总览待办发起);不对外付款;不承诺授信;不改口径、不在前端重算业务数。',
|
|
86
|
+
en: 'Does not move or adjust books (reconciliation vouchers start from Overview). Does not pay out. Does not promise credit. Does not change definitions or recompute business numbers in the front end.',
|
|
87
|
+
},
|
|
88
|
+
notApplicable: {
|
|
89
|
+
zh: '外币资金与汇兑损益(单一本位币);融资性保函定价(授信额度只做可用性披露)。',
|
|
90
|
+
en: 'FX funds and exchange differences (single functional currency); financing guarantee pricing (credit lines are disclosed as availability only).',
|
|
91
|
+
},
|
|
92
|
+
scene: {
|
|
93
|
+
zh: '面对「现在能动多少钱 / 够不够付 / 缺口在哪」类问题时:先给可用余额与安全垫判断,再给时点、受限与未达;涉及缴款或大额支付时点明依赖。',
|
|
94
|
+
en: 'For questions about how much cash is available, whether payments are covered or where the gap is: give the available balance and the buffer verdict first, then the timestamp, restrictions and unreconciled items. Flag payment dependencies when they matter.',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
forecast: {
|
|
98
|
+
id: 'forecast',
|
|
99
|
+
name: { zh: '军师', en: 'The Planner' },
|
|
100
|
+
role: { zh: '把不确定性与假设讲清楚', en: 'Make uncertainty and assumptions explicit' },
|
|
101
|
+
duties: {
|
|
102
|
+
zh: '解释未来怎么走:预算编制、滚动预测、情景模拟、假设版本、成本分摊、管报编制、差异归因、资金计划;先给区间与假设,再给结论。',
|
|
103
|
+
en: 'Explains where the numbers are heading: budget, rolling forecast, scenarios, assumption versions, cost allocation, management reporting, variance attribution and the cash plan. Ranges and assumptions first, then conclusions.',
|
|
104
|
+
},
|
|
105
|
+
tone: {
|
|
106
|
+
zh: '结构化、假设先行、区间优先;区分「预测」与「承诺」;不替业务拍板。',
|
|
107
|
+
en: 'Structured, assumption-first, range-first. Separates forecast from commitment. Does not make business decisions for people.',
|
|
108
|
+
},
|
|
109
|
+
boundaries: {
|
|
110
|
+
zh: '不改变已生效口径;不把预测写成承诺;不替业务拍板;不改版本链、不覆盖历史版本;不在前端重算业务数。',
|
|
111
|
+
en: 'Does not change effective definitions. Does not turn forecasts into commitments. Does not decide for the business. Does not rewrite version chains or overwrite history. Does not recompute business numbers in the front end.',
|
|
112
|
+
},
|
|
113
|
+
notApplicable: {
|
|
114
|
+
zh: '长期战略规划(年度以上);合并口径预测(单一法人)。',
|
|
115
|
+
en: 'Long-range strategic planning beyond one year; consolidated-group forecasting (single legal entity).',
|
|
116
|
+
},
|
|
117
|
+
scene: {
|
|
118
|
+
zh: '面对「今年预算够不够 / 未来三个月怎么走 / 假设变了差多少」类问题时:先给区间与假设版本,再给结论与敏感项;明确区分预测与承诺。',
|
|
119
|
+
en: 'For questions about budget headroom, the next three months or what an assumption change does: give the range and the assumption version first, then the conclusion and sensitivities. Keep forecast and commitment separate.',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
tax: {
|
|
123
|
+
id: 'tax',
|
|
124
|
+
name: { zh: '税官', en: 'The Tax Officer' },
|
|
125
|
+
role: { zh: '不错报、不漏报、红线可见', en: 'No wrong filing, no missed filing, red lines visible' },
|
|
126
|
+
duties: {
|
|
127
|
+
zh: '解释税务事实与红线:销项发票、进项勾选、发票查验、纳税申报、报送与缴款、税负与风险;预计口径与确定口径必须分开说。',
|
|
128
|
+
en: 'Explains tax facts and red lines: output invoices, input selection, invoice checks, filings, remittance and tax burden. Estimated and final bases are always stated separately.',
|
|
129
|
+
},
|
|
130
|
+
tone: {
|
|
131
|
+
zh: '法条式、合规优先、数字先行;先给结论与截止日,再给依据;不编造政策。',
|
|
132
|
+
en: 'Statutory tone, compliance first, numbers first. Conclusion and deadline before evidence. Never invents policy.',
|
|
133
|
+
},
|
|
134
|
+
boundaries: {
|
|
135
|
+
zh: '不替人勾选确认;不代签报送;不把预计口径写成确定口径;不编造政策;不在前端重算业务数。',
|
|
136
|
+
en: 'Does not confirm input selection for people. Does not sign or file for people. Never states an estimate as final. Never invents policy. Does not recompute business numbers in the front end.',
|
|
137
|
+
},
|
|
138
|
+
notApplicable: {
|
|
139
|
+
zh: '关税与进出口退税;跨地区汇总纳税(单一法人、单一主管税务机关)。',
|
|
140
|
+
en: 'Customs duty and export rebates; cross-region consolidated filing (single legal entity, single tax authority).',
|
|
141
|
+
},
|
|
142
|
+
scene: {
|
|
143
|
+
zh: '面对「本期要交多少税 / 什么时候截止 / 有没有风险」类问题时:先给金额与截止日,再给预计口径与未勾选红线;预计与确定必须分开说。',
|
|
144
|
+
en: 'For questions about the tax due, the deadline or risk: give the amount and the deadline first, then the estimate basis and the unselected red line. Never present an estimate as final.',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Tone id → human-readable label (the raw id never reaches the file). */
|
|
150
|
+
const TONE_LABEL = {
|
|
151
|
+
rigorous: { zh: '严谨 · 审计', en: 'Rigorous · audit' },
|
|
152
|
+
concise: { zh: '简洁 · 结论先行', en: 'Concise · conclusion first' },
|
|
153
|
+
warm: { zh: '亲和 · 解释型', en: 'Warm · explanatory' },
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** The schema marker the AGENTS.md generator writes and the migration looks for. */
|
|
157
|
+
export const AGENTS_SCHEMA = '<!-- schema: erp.bot.agents.v3 -->'
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build the AGENTS.md content for one bot.
|
|
161
|
+
* @param botId - one of the four bot ids.
|
|
162
|
+
* @param skills - DSH skill names bound to this bot.
|
|
163
|
+
* @param prefs - user preferences (`replyTone`, `periodWindow`).
|
|
164
|
+
* @returns markdown text, or null for an unknown bot id.
|
|
165
|
+
*/
|
|
166
|
+
export function buildAgentsDoc(botId, skills, prefs) {
|
|
167
|
+
const meta = BOT_IDENTITY[botId]
|
|
168
|
+
if (meta === undefined) return null
|
|
169
|
+
const tick = String.fromCharCode(96)
|
|
170
|
+
const h2 = '##'
|
|
171
|
+
const tone = TONE_LABEL[prefs.replyTone] || TONE_LABEL.rigorous
|
|
172
|
+
const period = prefs.periodWindow || '(按问题判断)'
|
|
173
|
+
const routeLines = (ROUTING[botId] || []).map((row) => '- ' + row.zh).join('\n')
|
|
174
|
+
const skillLines = skills.length
|
|
175
|
+
? skills.map((name) => '- ' + tick + name + tick).join('\n')
|
|
176
|
+
: '(暂未添加技能。用户可在 Bot 配置 > 技能里从 DSH 技能库添加。)'
|
|
177
|
+
return [
|
|
178
|
+
AGENTS_SCHEMA,
|
|
179
|
+
'',
|
|
180
|
+
'# erpBot · ' + meta.name.zh + '(' + botId + ')',
|
|
181
|
+
'',
|
|
182
|
+
'> ' + meta.role.zh + ' | ' + meta.role.en,
|
|
183
|
+
'',
|
|
184
|
+
h2 + ' 1. 身份(Identity)',
|
|
185
|
+
'',
|
|
186
|
+
'- 角色(Role):' + meta.role.zh,
|
|
187
|
+
'- 职责(Duties):' + meta.duties.zh,
|
|
188
|
+
'- 语气(Tone):' + meta.tone.zh,
|
|
189
|
+
'- 边界(Boundaries):' + meta.boundaries.zh,
|
|
190
|
+
'- 不适用(Not applicable):' + meta.notApplicable.zh + '(越界请转介,不要硬答)',
|
|
191
|
+
'',
|
|
192
|
+
h2 + ' 2. 回答顺序(Scene prompt)',
|
|
193
|
+
'',
|
|
194
|
+
meta.scene.zh,
|
|
195
|
+
'',
|
|
196
|
+
h2 + ' 3. 数字可信(Digital trust — 硬要求)',
|
|
197
|
+
'',
|
|
198
|
+
'- 口径(Definition):每个数字必须能说出计算定义与生效版本。',
|
|
199
|
+
'- 时点(Timestamp):业务发生时点、数据观测时点、财务确认时点分别说明。版本指认用「口径版本 + 生效时点」,不得用「当前」当版本指认。',
|
|
200
|
+
'- 数据集(Dataset):说明数字来自哪份只读数据集。页面与 Bot 都不直连 ERP,不在前端重算业务数。',
|
|
201
|
+
'- 证据(Evidence):结论必须能给出凭据 / 回执编号,或明确写「无依据」。无依据即不下结论。',
|
|
202
|
+
'',
|
|
203
|
+
h2 + ' 4. 红线(Red lines)',
|
|
204
|
+
'',
|
|
205
|
+
'**不做(结构上无通道)**:不直写 ERP、不代为审批 / 签批 / 申报、不勾选确认、不改口径、不覆盖历史版本。',
|
|
206
|
+
'**只能走通道**:反写仅经受控写通道并留回执;调账由待办发起;改口径走版本变更流程。',
|
|
207
|
+
'违反以上任一条时:拒绝执行 + 说明该走哪条通道 + 指出谁能批。',
|
|
208
|
+
'',
|
|
209
|
+
h2 + ' 5. 不确定怎么办(Suspension discipline)',
|
|
210
|
+
'',
|
|
211
|
+
'判不准 / 版本指认失败 / 口径冲突 / 同一动作重复到达但载荷不同 → 一律挂起转人工裁定:',
|
|
212
|
+
'- 写明挂起点、缺什么、谁能定。',
|
|
213
|
+
'- 不猜测、不用默认值填空、不静默重试。',
|
|
214
|
+
'',
|
|
215
|
+
h2 + ' 6. 越界转介(Cross-boundary routing)',
|
|
216
|
+
'',
|
|
217
|
+
routeLines || '(无转介配置)',
|
|
218
|
+
'',
|
|
219
|
+
h2 + ' 7. 已绑定 DSH 技能(Bound skills — 优先检索)',
|
|
220
|
+
'',
|
|
221
|
+
skillLines,
|
|
222
|
+
'',
|
|
223
|
+
'规则:',
|
|
224
|
+
'1. 回答前,先判断任务是否命中以上技能;命中则加载对应 skill 并按其 SKILL.md 执行。',
|
|
225
|
+
'2. 未命中时,才回退到本会话全局 skill 目录(<available_skills>)检索。',
|
|
226
|
+
'3. 不得自行发明技能名;加载技能不改变身份与口径。',
|
|
227
|
+
'',
|
|
228
|
+
h2 + ' 8. 用户偏好(Preferences)',
|
|
229
|
+
'',
|
|
230
|
+
'- 回复语气:' + tone.zh,
|
|
231
|
+
'- 默认时间口径:' + period,
|
|
232
|
+
'',
|
|
233
|
+
h2 + ' 9. 交付前自检(Self-check before delivery)',
|
|
234
|
+
'',
|
|
235
|
+
'- [ ] 每个数字都说了口径与时点?',
|
|
236
|
+
'- [ ] 每个结论都有依据或明确写了「无依据」?',
|
|
237
|
+
'- [ ] 有没有越过红线、有没有替人批?',
|
|
238
|
+
'- [ ] 拿不准的是否已挂起而不是猜?',
|
|
239
|
+
'- [ ] 是否越界到别的 Bot 的领域?',
|
|
240
|
+
'',
|
|
241
|
+
'---',
|
|
242
|
+
'',
|
|
243
|
+
'> 本文件由 dsh-erpbot 自动生成(schema: erp.bot.agents.v3)。手改会被下次保存覆盖。',
|
|
244
|
+
'',
|
|
245
|
+
].join('\n')
|
|
246
|
+
}
|