@hedeqiang/dsh-nl2sql 0.11.1 → 0.12.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/CHANGELOG.md CHANGED
@@ -1,52 +1,87 @@
1
- # 更新日志
1
+ # Changelog
2
2
 
3
- 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
3
+ All notable changes to this project are documented in this file.
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
5
 
5
- ## [未发布]
6
+ ## [Unreleased]
7
+
8
+ ## [0.12.0] - 2026-11-12
9
+
10
+ ### Added
11
+ - One-click member adding: people and groups that talked to a bot, and the groups a bot is in, are offered in the member form with their ids, names and emails filled in. People and groups refused because they are not members yet are listed at the top of **Members & access**.
12
+ - Bots know the member's data sources: every question carries a catalog of the sources the member may use (type, database, description, main tables); the agent switches to the matching source and states which one it used. A source named in the question, or one whose business knowledge matches, is selected automatically.
13
+ - Bot commands: `数据源` lists sources with descriptions, `切换 <name>` pins a source (fuzzy match), `自动` returns to automatic selection. The reply footer shows the source actually used.
14
+
15
+ ### Changed
16
+ - README rewritten in English (Chinese in `README.zh-CN.md`) with screenshots, security model and installation from npm; added a Code of Conduct, issue and pull request templates, and an English development guide (`docs/development.md`). `docs/CHANNELS.md` moved to `docs/channels.md`.
17
+ - List separators and label colons in the page follow the UI language.
18
+
19
+ ## [0.11.2] - 2026-11-12
20
+
21
+ ### Added
22
+ - Dashboards show each chart's data source (and flag deleted sources); a dashboard that mixes sources lists them and can be scoped to *All sources* or *Only the current source* (remembered per browser). Reordering while scoped keeps hidden charts in place.
23
+ - Large results in IM messages: messages say how many rows are shown (Lark cards up to 50 rows with paging, Telegram 20, WeCom and DingTalk 10). Lark app bots and Telegram attach the full data as an Excel file (`attachFull`, on by default); a failed attachment does not fail the message and is noted in the delivery log.
24
+
25
+ ### Changed
26
+ - README installation instructions now use npm (**Plugins → Add plugin** or `dsh plugin add`), with upgrade, uninstall and from-source steps.
6
27
 
7
28
  ## [0.11.1] - 2026-11-12
8
29
 
9
- ### 修复
10
- - 中文界面下渠道类型、配置说明、推荐问题等显示为英文:读取 Harness 语言设置的方式有误(LocaleSnapshot 的 `active` 字段),已修正并加了回归测试。
30
+ ### Added
31
+ - Release workflow: pushing a `v*` tag checks, packs and publishes to npm with trusted publishing and provenance, and creates the GitHub release.
11
32
 
12
- ### 新增
13
- - GitHub Actions 发布流程:推送 `v*` 版本标签后自动检查、打包,并通过 npm 可信发布(OIDC,带来源证明)发布到 npm,同时创建 GitHub Release。
33
+ ### Fixed
34
+ - Channel catalog text, suggested questions and number units showed in English in the Chinese UI (the UI read the wrong field of the Harness locale snapshot).
14
35
 
15
36
  ## [0.11.0] - 2026-11-12
16
37
 
17
- ### 新增
18
- - 渠道架构:IM 平台改为适配器(`channels/`),统一的消息模型、能力声明、表单定义和机器人接口,详见 [docs/CHANNELS.md](docs/CHANNELS.md)。
19
- - 新平台:Telegram(推送、长轮询机器人、按钮)、企业微信(群机器人推送;智能机器人长连接问答与推送)、钉钉(自定义机器人推送;企业内部应用机器人 Stream 模式问答与推送)。以上新平台仅用模拟服务测试,尚未在真实账号上验证。
20
- - 成员身份支持多平台(`identities`),机器人按渠道配置,可同时运行多个。
21
- - 页面:「渠道」按平台分组、两步添加(选平台与类型 → 按表单填写),能力标签、配置步骤、选择群聊、测试;成员页「机器人」总览;成员身份编辑;设置「渠道与机器人」。
22
- - 问答页「试试这些问题」支持「换一批」;删除单条历史记录;「最近的提问」可删除并支持「显示更多」。
38
+ ### Added
39
+ - Channel adapter architecture (`channels/`): a platform-neutral message model, capability declarations, form schemas and a bot interface ([docs/channels.md](docs/channels.md)).
40
+ - Telegram (push, long-polling bot, inline buttons), WeCom (group webhook push; AI bot over the long connection) and DingTalk (custom robot push; internal app robot over Stream mode). These adapters are tested against local fakes only.
41
+ - Multi-platform member identities; one bot per channel, several bots at once.
42
+ - Redesigned pages: channels grouped by platform with a two-step add dialog, a bots overview, an identities editor, and a *Channels & bots* settings group.
43
+ - Ask page: shuffle suggested questions, delete single history entries, show more recent questions.
23
44
 
24
- ### 兼容
25
- - 旧的飞书渠道、机器人配置、成员字段和设置在首次加载时自动迁移;旧的 RPC 与数据格式继续可用。
45
+ ### Changed
46
+ - Existing Lark channels, bot settings, member fields and settings are migrated on first load; old RPCs and payloads keep working.
26
47
 
27
48
  ## [0.10.0] - 2026-11-12
28
49
 
29
- ### 新增
30
- - 飞书回复卡片上的交互按钮:按维度拆分、为什么变化、明细、固定到看板(经长连接回传,服务端校验权限)。
31
- - 业务知识「建议」:从 👍 反馈、重复出现的查询、常用聚合和取值映射中自动生成样例、指标、备注和词表建议,人工确认后采纳。
32
- - 开源准备:MIT 许可证、README、贡献指南、安全策略、CI。
50
+ ### Added
51
+ - Interactive buttons on Lark answer cards: break down by a dimension, why did it change, details, pin to dashboard (via the long connection, re-authorized per click).
52
+ - Knowledge suggestions mined from 👍 feedback, repeated queries, common aggregates and value mappings, accepted by a person.
53
+ - Open-source groundwork: MIT license, README, contributing guide, security policy, CI.
33
54
 
34
- ### 修复
35
- - `token_code` 等加密货币业务字段不再被误判为敏感字段。
36
- - 评测比对能识别同一组数字的不同排布(一行多列 / 多行一列)。
55
+ ### Fixed
56
+ - Business columns such as `token_code` are no longer treated as sensitive.
57
+ - Evaluation recognises the same numbers in pivoted shapes (one row with many columns vs. many rows).
37
58
 
38
59
  ## [0.9.0] - 2026-11-12
39
- - 页面改为 5 个常用页签 + 「管理」区;设置分组(说明、未保存提示、恢复默认、配置导出导入)。
40
- - 首次使用引导;问答页推荐问题与最近提问。
41
- - 看板拖拽排序、三档宽度、刷新与缓存状态;页面内提示替代浏览器弹窗;英文界面完整翻译。
42
- - 上传分块暂存;MySQL / PostgreSQL 大结果流式截断;大库按问题挑选相关表;日志保留条数可配置。
60
+
61
+ ### Changed
62
+ - Page reorganised into five tabs plus a **Manage** area; grouped settings with descriptions, unsaved-changes bar, reset to defaults and configuration export / import.
63
+ - Onboarding checklist; suggested and recent questions on the Ask page.
64
+ - Dashboard drag-to-reorder, three widths, refresh and cache status; in-page dialogs instead of browser pop-ups; complete English UI.
65
+ - Chunked uploads; streamed truncation of large MySQL / PostgreSQL results; relevant-table selection for large schemas; configurable log retention.
43
66
 
44
67
  ## [0.8.0] - 2026-11-12
45
- - 只读角色、行级权限、调度器补查与状态、日志迁移到 SQLite、代码拆分为 `service/` 与 `client-src/`、测试套件。
46
- - 安全修复:按方言词法的只读检查(修复 PostgreSQL 可写入问题)、访问控制绕过、飞书成员数据源范围、飞书回答错位。
68
+
69
+ ### Added
70
+ - Viewer role, row-level rules, scheduler catch-up and status, logs stored in SQLite, `service/` and `client-src/` split, test suite.
71
+
72
+ ### Security
73
+ - Per-dialect lexing for read-only admission (fixes writes through PostgreSQL), access-control bypasses, Lark member data source scopes, mismatched Lark answers.
47
74
 
48
75
  ## [0.7.0] - 2026-11-11
49
- - 指标告警、飞书 @机器人问答、下钻与归因、准确率评测、表结构变更检测、指标工具、多看板、Excel 导出、CSV / Excel 上传、结果持久化与缓存、业务知识导入导出、多用户权限与审计。
50
76
 
51
- ## [0.6.0] 及更早
52
- - 界面重设计;飞书推送(Markdown 与原生图表);访问控制、反馈闭环、看板全局筛选;PostgreSQL / Elasticsearch、SSH 隧道、隐私设置、自动概览、定时报告;语义层、关系图、扫描保护、历史与审计、看板;MVP。
77
+ ### Added
78
+ - Metric alerts, Lark @-mention bot, drill-down and attribution, accuracy evaluation, schema change detection, metric tool, multiple dashboards, Excel export, CSV / Excel upload, persisted results and cache, knowledge import / export, members, permissions and audit.
79
+
80
+ ## [0.6.0] and earlier
81
+
82
+ - Redesigned UI; Lark push (Markdown and native charts); access control, feedback loop, dashboard global filters; PostgreSQL / Elasticsearch, SSH tunnels, privacy settings, automatic overviews, scheduled reports; semantic layer, ER graph, scan guard, history and audit, dashboards; first version.
83
+
84
+ [Unreleased]: https://github.com/hedeqiang/dsh-nl2sql/compare/v0.12.0...HEAD
85
+ [0.12.0]: https://github.com/hedeqiang/dsh-nl2sql/compare/v0.11.2...v0.12.0
86
+ [0.11.2]: https://github.com/hedeqiang/dsh-nl2sql/compare/v0.11.1...v0.11.2
87
+ [0.11.1]: https://github.com/hedeqiang/dsh-nl2sql/releases/tag/v0.11.1
package/README.md CHANGED
@@ -1,89 +1,175 @@
1
- # dsh-nl2sql · 数据问答
1
+ <div align="center">
2
2
 
3
- [DeepSeek Harness](https://github.com/deepseek-ai) 的企业级 NL2SQL 插件:连接数据库,用自然语言提问,Agent 写只读 SQL、执行并在对话中画图;结果可以固定到看板、推送到飞书,还能在飞书群里直接 @机器人提问。
3
+ # dsh-nl2sql
4
4
 
5
- [English](README.en.md)
5
+ **Ask your databases in plain language — inside [DeepSeek Harness](https://github.com/deepseek-ai).**
6
6
 
7
- ## 功能
7
+ The agent writes read-only SQL, runs it and charts the answer in the conversation.<br>
8
+ Pin results to dashboards, schedule reports and alerts, and push them to Lark / Feishu, Telegram, WeCom or DingTalk — or let teammates @-mention a bot in their group chat.
8
9
 
9
- **问答与分析**
10
- - 数据源:MySQL 5.7+、PostgreSQL、Elasticsearch(SQL),支持 SSH 隧道;也可以上传 CSV / Excel(存为本机 SQLite)。
11
- - 表结构分析:识别表的角色、字段语义(时间 / 度量 / 枚举 / 敏感)、推断表间关系,提供关系图。
12
- - 自然语言提问:在 Harness 对话中进行,Agent 使用 `nl2sql_*` 工具查询,结果在对话中渲染为 ECharts 图表或表格。
13
- - 下钻与归因:按维度拆分、查看明细、「为什么变化」——比较两个时段并按维度贡献排序。
14
- - 指标库与业务知识:词表、指标口径(Agent 用 `nl2sql_metric` 按口径查询)、字段备注、样例问答;支持导入导出。
15
- - 准确率评测:用样例问答作为评测集,Agent 从零作答后与样例结果比对。
10
+ [![npm](https://img.shields.io/npm/v/@hedeqiang/dsh-nl2sql?color=3370ff)](https://www.npmjs.com/package/@hedeqiang/dsh-nl2sql)
11
+ [![check](https://github.com/hedeqiang/dsh-nl2sql/actions/workflows/check.yml/badge.svg)](https://github.com/hedeqiang/dsh-nl2sql/actions/workflows/check.yml)
12
+ [![license](https://img.shields.io/npm/l/@hedeqiang/dsh-nl2sql)](LICENSE)
16
13
 
17
- **看板与推送**
18
- - 多看板、全局筛选(时间范围 / 维度)、拖拽排序、三档宽度、快照、Excel 导出。
19
- - IM 渠道:飞书 / Lark、Telegram、企业微信、钉钉(推送 Markdown 与结果,图表按平台能力用原生图表、图片或表格);架构见 [docs/CHANNELS.md](docs/CHANNELS.md),新增平台只需实现一个适配器。
20
- - 定时报告(基于 Harness 定时任务)、指标告警(阈值 / 环比 / 异常 / 无数据)、表结构变更检测。
21
- - 群聊 @机器人提问:飞书长连接、Telegram 长轮询、企业微信智能机器人长连接、钉钉 Stream 模式,都不需要公网地址。
14
+ English · [简体中文](README.zh-CN.md)
22
15
 
23
- **安全与治理**
24
- - 只读执行:按方言词法检查语句(MySQL / PostgreSQL / SQLite / ES),只读事务,PostgreSQL 使用扩展协议拒绝多语句,服务端超时,大结果流式截断。
25
- - 访问控制:按表允许 / 排除、隐藏列、脱敏列;大表全表扫描保护。
26
- - 成员与权限:飞书用户 / 群的数据源范围、只读角色(只能用指标库、已验证样例和看板)、行级权限(自动注入过滤,无法安全改写的查询直接拒绝)。
27
- - 隐私:可设置发给模型的内容(不发 / 统计摘要 / 前 N 行),敏感字段默认脱敏;审计记录归属到具体的人。
16
+ </div>
28
17
 
29
- ## 安装
18
+ ![Dashboard with charts from two data sources](docs/images/dashboard.png)
30
19
 
31
- 需要 DeepSeek Harness 桌面版或 `dsh web`。
20
+ ## Contents
21
+
22
+ - [Features](#features)
23
+ - [Requirements](#requirements)
24
+ - [Installation](#installation)
25
+ - [Quick start](#quick-start)
26
+ - [IM channels and bots](#im-channels-and-bots)
27
+ - [Security model](#security-model)
28
+ - [Data and privacy](#data-and-privacy)
29
+ - [Limitations](#limitations)
30
+ - [Development](#development)
31
+ - [Contributing](#contributing)
32
+ - [License](#license)
33
+
34
+ ## Features
35
+
36
+ **Ask and analyze**
37
+ - Data sources: MySQL 5.7+, PostgreSQL, Elasticsearch (SQL), optionally through an SSH tunnel, and CSV / Excel uploads stored as local SQLite.
38
+ - Schema analysis: table roles, column semantics (time / measure / enum / sensitive), inferred relations and an ER graph.
39
+ - Natural-language questions in any Harness conversation through the `nl2sql_*` agent tools; results render as interactive ECharts charts or tables.
40
+ - Drill-down: split by a dimension, show the rows behind a point, and *why did it change* — rank dimensions by their contribution between two periods.
41
+ - Business knowledge: glossary, governed metrics (queried with `nl2sql_metric`), column notes and verified question → SQL examples, with import / export and suggestions mined from history and feedback.
42
+ - Accuracy evaluation: replay the verified examples, or let the agent answer them from scratch and compare results.
43
+
44
+ **Share and automate**
45
+ - Multiple dashboards with global filters, drag-to-reorder, three widths, snapshots and Excel export. A dashboard may mix data sources; every chart shows where it comes from.
46
+ - Scheduled reports, metric alerts (threshold / change / anomaly / missing data) and schema change detection.
47
+ - Push to Lark / Feishu, Telegram, WeCom and DingTalk; charts are sent as native card charts, images or tables depending on the platform, and large results come with the full data as an Excel attachment where the platform allows files.
48
+ - Chat bots that answer @-mentions in group chats without a public URL (Lark long connection, Telegram long polling, WeCom AI bot long connection, DingTalk Stream mode).
49
+
50
+ **Govern**
51
+ - Read-only by construction, table / column access policies with masking, and a full-scan guard.
52
+ - Members with roles (admin / analyst / viewer), data source scopes and row-level rules for people and group chats on every IM platform.
53
+ - Audit history attributed to people, and a setting for exactly what query data the model may see.
54
+
55
+ <table>
56
+ <tr>
57
+ <td width="50%"><img src="docs/images/schema.png" alt="Schema analysis with column roles"></td>
58
+ <td width="50%"><img src="docs/images/channels.png" alt="IM channels grouped by platform"></td>
59
+ </tr>
60
+ <tr>
61
+ <td align="center"><sub>Schema analysis</sub></td>
62
+ <td align="center"><sub>IM channels</sub></td>
63
+ </tr>
64
+ </table>
65
+
66
+ ## Requirements
67
+
68
+ - [DeepSeek Harness](https://github.com/deepseek-ai) 0.2 or later — the desktop app or `dsh web`.
69
+ - Network access from the Harness machine to your databases (directly or through SSH).
70
+ - A **read-only database account** is strongly recommended (see [Security model](#security-model)).
71
+
72
+ ## Installation
73
+
74
+ **From the Harness UI (recommended)**
75
+
76
+ 1. Open **Plugins** in the sidebar and choose **Add plugin**.
77
+ 2. Enter `@hedeqiang/dsh-nl2sql` (optionally pinned, e.g. `@hedeqiang/dsh-nl2sql@0.11.2`), then install and enable it.
78
+ 3. **Data Q&A** appears in the sidebar, and a *Data Q&A* agent preset is available for new conversations.
79
+
80
+ You can also simply ask the Harness agent: *"install the plugin @hedeqiang/dsh-nl2sql"*.
81
+
82
+ **From the command line**
32
83
 
33
84
  ```bash
34
- # 从源码(开发)
35
- git clone <this repo> dsh-nl2sql && cd dsh-nl2sql
36
- pnpm install --ignore-scripts # 依赖:mysql2、pg、ssh2、echarts、@larksuiteoapi/node-sdk、@resvg/resvg-js
85
+ dsh plugin --profile desktop add @hedeqiang/dsh-nl2sql # the desktop app uses the "desktop" profile; dsh web uses "web"
37
86
  ```
38
87
 
39
- 然后在 Harness 中让 Agent 安装本地目录(插件管理器 `install_bundle`,目标为本目录的绝对路径),或在 profile 的 `package.json` 中加入:
88
+ Then enable it on the **Plugins** page, or restart Harness.
40
89
 
41
- ```json
42
- { "dsh": { "profile": { "bundles": ["@hedeqiang/dsh-nl2sql"] } },
43
- "dependencies": { "@hedeqiang/dsh-nl2sql": "link:/path/to/dsh-nl2sql" } }
90
+ **Upgrade and uninstall**
91
+
92
+ ```bash
93
+ dsh plugin --profile desktop update @hedeqiang/dsh-nl2sql
94
+ dsh plugin --profile desktop remove @hedeqiang/dsh-nl2sql
44
95
  ```
45
96
 
46
- 发布到 npm 后可直接安装 `@hedeqiang/dsh-nl2sql`。
97
+ Configuration and data live in `~/.dsh/nl2sql` and survive upgrades and uninstalls; older configuration is migrated automatically on first load. Delete the directory yourself if you no longer need it.
98
+
99
+ All dependencies ship prebuilt binaries, so no install scripts need to run.
100
+
101
+ ## Quick start
102
+
103
+ 1. **Data Q&A → Manage → Data sources** — add a database, or upload a CSV / Excel file.
104
+ 2. **Schema** — run the analysis (it reads metadata and a small sample of enum values, never full tables).
105
+ 3. **Ask** — type a question, e.g. *"daily orders and revenue over the last 30 days"*. The agent picks tables, writes SQL for your dialect, runs it and draws a chart. You can also choose the *Data Q&A* preset in any conversation.
106
+ 4. **Dashboard** — pin useful charts, add filters, export or send them.
107
+ 5. **Knowledge** — add glossary terms, metric definitions and verified examples to make answers consistent; run an evaluation to measure accuracy.
108
+
109
+ ## IM channels and bots
110
+
111
+ Every platform is an adapter under [`channels/`](channels); the core only talks to the adapter interface described in [docs/channels.md](docs/channels.md).
47
112
 
48
- ## 使用
113
+ | Platform | Push | Charts | Buttons | Bot without public URL |
114
+ |---|---|---|---|---|
115
+ | Lark / Feishu — group webhook | ✓ | native card charts | – | – |
116
+ | Lark / Feishu — app bot | ✓ (+ Excel attachment) | native charts or images | ✓ | ✓ long connection |
117
+ | Telegram | ✓ (+ Excel attachment) | images | ✓ inline keyboard | ✓ long polling |
118
+ | WeCom — group webhook | ✓ | images | – | – |
119
+ | WeCom — AI bot | ✓ (chats that messaged the bot) | tables | – | ✓ long connection |
120
+ | DingTalk — custom robot | ✓ (optional signing) | tables | – | – |
121
+ | DingTalk — internal app robot | ✓ | tables | – | ✓ Stream mode |
49
122
 
50
- 1. 左侧栏打开「数据问答」→「管理 → 数据源」,添加数据库(建议使用只读账号)或上传文件。
51
- 2. 「表结构」→ 分析表结构。
52
- 3. 「问答」页提问,或在任意对话中选择「数据问答」预设直接提问。
53
- 4. 把满意的图表固定到「看板」;在「业务知识」补充词表、指标和样例,提高准确率。
54
- 5. 「管理 → 推送渠道」添加飞书机器人;「告警与报告」配置自动任务;「成员与权限」开通飞书群提问。
123
+ Add a channel in **Manage → Channels**: pick the platform and connection type, and the form shows the console steps for that platform. People and groups are granted access in **Manage → Members & access**; anyone who has talked to a bot can be added with one click.
55
124
 
56
- 飞书应用机器人所需权限与长连接配置步骤见页面「成员与权限 → 飞书机器人 → 飞书开放平台配置步骤」。
125
+ In a group chat, members @-mention the bot and ask. The bot knows which data sources the member may use and picks the matching one. Chat commands: `help`, `数据源` (list sources), `切换 <name>` (pin a source), `自动` (pick automatically again), `新对话` / `reset` (new conversation).
57
126
 
58
- ## 数据与隐私
127
+ > The Telegram, WeCom and DingTalk adapters are tested against local fakes of their APIs and have not yet been verified with real accounts; Lark has been used with real workspaces. Reports from real deployments are welcome.
59
128
 
60
- | 内容 | 位置 |
129
+ ## Security model
130
+
131
+ - **Read-only queries.** Every statement passes a per-dialect lexer (MySQL, PostgreSQL, SQLite, Elasticsearch SQL) that admits only `SELECT` / `SHOW` / `DESCRIBE` / `EXPLAIN`; queries run in read-only transactions with server-side timeouts, PostgreSQL uses the extended protocol (no multi-statement strings), and large results are streamed and truncated.
132
+ - **Access policies.** Allow or deny tables, hide or mask columns, and refuse full scans of large tables unless confirmed.
133
+ - **Members.** Data source scopes, a viewer role (metric library, verified examples and dashboards only) and row-level rules that are injected into queries — queries that cannot be rewritten safely are refused.
134
+ - **Bot actions.** Buttons on IM messages carry opaque tokens only; every click is re-authorized for the person who clicked.
135
+
136
+ The lexer is a first line of defence, not a substitute for database permissions: **always connect with a read-only account.** See [SECURITY.md](SECURITY.md) to report a vulnerability.
137
+
138
+ ## Data and privacy
139
+
140
+ | What | Where |
61
141
  |---|---|
62
- | 配置(数据源、看板、知识、告警、成员、设置) | `~/.dsh/nl2sql/state.json` |
63
- | 查询结果、缓存、快照、日志(历史 / 审计 / 反馈 / 推送 / 告警) | `~/.dsh/nl2sql/results.sqlite` |
64
- | 上传的文件 | `~/.dsh/nl2sql/files/` |
65
- | 数据库密码、飞书密钥 | Harness 凭据库 |
142
+ | Configuration (data sources, dashboards, knowledge, alerts, members, channels, settings) | `~/.dsh/nl2sql/state.json` |
143
+ | Query results, cache, snapshots and logs (history, audit, feedback, deliveries, alerts) | `~/.dsh/nl2sql/results.sqlite` |
144
+ | Uploaded files | `~/.dsh/nl2sql/files/` |
145
+ | Database passwords, SSH keys, bot secrets | the Harness credential store |
146
+
147
+ **Settings → Data shown to the model** controls what query data reaches the LLM: nothing, per-column statistics (default) or the first *N* rows. Sensitive columns are masked by default. Anything you push to an IM platform leaves your machine.
148
+
149
+ ## Limitations
66
150
 
67
- 发给模型的内容由「设置 → 模型可见数据」决定:默认只发表结构、枚举字段取值和查询结果的统计摘要,不发明细行。推送到飞书的内容会离开本机。
151
+ - Alerts and the daily schema check run inside the Harness process: nothing is checked while Harness is closed; one catch-up run happens after it starts.
152
+ - The local page has owner rights and no login; do not expose the Harness web port to untrusted networks.
153
+ - Row-level rules apply to IM members; queries with subqueries, CTEs or `UNION` are refused under row-level rules.
154
+ - Legacy `.xls` files are not supported (use `.xlsx` or CSV).
68
155
 
69
- ## 开发
156
+ ## Development
70
157
 
71
158
  ```bash
72
- npm test # 全部测试(需要 Harness 桌面版作为 Node 运行时;本机 MySQL / PostgreSQL 可选,不可用时跳过)
73
- npm test -- --fast # 仅单元测试和界面测试
74
- node scripts/build-client.mjs # 修改 client-src/ 后生成 lib/client.js
75
- node scripts/build-echarts.mjs
159
+ git clone https://github.com/hedeqiang/dsh-nl2sql.git
160
+ cd dsh-nl2sql
161
+ pnpm install --ignore-scripts
162
+ npm test # full suite; local MySQL / PostgreSQL are used when available
163
+ npm run test:fast # unit + UI tests only
164
+ node scripts/build-client.mjs # regenerate lib/client.js after editing client-src/
76
165
  ```
77
166
 
78
- 目录结构与约定见 [DEVELOPMENT.md](DEVELOPMENT.md);隔离的准确率评测环境见 [eval/README.md](eval/README.md)。
167
+ Install your checkout as a linked plugin with **Plugins → Add plugin** and the absolute directory path; re-enable the plugin to load changes. Project layout, conventions and test setup are in [docs/development.md](docs/development.md); an isolated accuracy benchmark lives in [eval/](eval/README.md).
79
168
 
80
- ## 已知限制
169
+ ## Contributing
81
170
 
82
- - 告警和每日表结构检查在 Harness 进程内调度:Harness 关闭期间不检查,重新打开后补查一次。
83
- - 行级权限只对飞书成员生效;本机页面始终是所有者权限,没有登录机制。
84
- - 行级权限下不支持子查询、CTE、UNION(会被拒绝)。
85
- - 不支持旧版 `.xls`。
171
+ Issues and pull requests are welcome — please read [CONTRIBUTING.md](CONTRIBUTING.md) and follow the [Code of Conduct](CODE_OF_CONDUCT.md). Release notes are in [CHANGELOG.md](CHANGELOG.md).
86
172
 
87
- ## 许可证
173
+ ## License
88
174
 
89
- [MIT](LICENSE)
175
+ [MIT](LICENSE) © hedeqiang
@@ -0,0 +1,175 @@
1
+ <div align="center">
2
+
3
+ # dsh-nl2sql
4
+
5
+ **在 [DeepSeek Harness](https://github.com/deepseek-ai) 里用自然语言问数据库。**
6
+
7
+ Agent 编写只读 SQL、执行并在对话中画图。<br>
8
+ 结果可以固定到看板、定时报告和告警,推送到飞书、Telegram、企业微信、钉钉,也可以让同事在群里直接 @机器人 提问。
9
+
10
+ [![npm](https://img.shields.io/npm/v/@hedeqiang/dsh-nl2sql?color=3370ff)](https://www.npmjs.com/package/@hedeqiang/dsh-nl2sql)
11
+ [![check](https://github.com/hedeqiang/dsh-nl2sql/actions/workflows/check.yml/badge.svg)](https://github.com/hedeqiang/dsh-nl2sql/actions/workflows/check.yml)
12
+ [![license](https://img.shields.io/npm/l/@hedeqiang/dsh-nl2sql)](LICENSE)
13
+
14
+ [English](README.md) · 简体中文
15
+
16
+ </div>
17
+
18
+ ![包含两个数据源图表的看板](docs/images/dashboard.png)
19
+
20
+ ## 目录
21
+
22
+ - [功能](#功能)
23
+ - [环境要求](#环境要求)
24
+ - [安装](#安装)
25
+ - [快速开始](#快速开始)
26
+ - [IM 渠道与机器人](#im-渠道与机器人)
27
+ - [安全模型](#安全模型)
28
+ - [数据与隐私](#数据与隐私)
29
+ - [已知限制](#已知限制)
30
+ - [开发](#开发)
31
+ - [参与贡献](#参与贡献)
32
+ - [许可证](#许可证)
33
+
34
+ ## 功能
35
+
36
+ **提问与分析**
37
+ - 数据源:MySQL 5.7+、PostgreSQL、Elasticsearch(SQL),可经 SSH 隧道;也可以上传 CSV / Excel,保存为本机 SQLite。
38
+ - 表结构分析:识别表的角色、字段语义(时间 / 度量 / 枚举 / 敏感),推断表间关系,提供关系图。
39
+ - 在任意 Harness 对话中用自然语言提问,Agent 通过 `nl2sql_*` 工具查询,结果渲染为可交互的 ECharts 图表或表格。
40
+ - 下钻:按维度拆分、查看某个点的明细,以及「为什么变化」——比较两个时段并按维度贡献排序。
41
+ - 业务知识:词表、指标口径(`nl2sql_metric` 按口径查询)、字段备注、已验证的问题 → SQL 样例;支持导入导出,并能从历史和反馈中自动生成建议。
42
+ - 准确率评测:回放样例,或让 Agent 从零作答后与样例结果比对。
43
+
44
+ **共享与自动化**
45
+ - 多看板、全局筛选、拖拽排序、三档宽度、快照、Excel 导出;一个看板可以放多个数据源的图表,每个图表标注来源。
46
+ - 定时报告、指标告警(阈值 / 环比 / 异常 / 无数据)、表结构变更检测。
47
+ - 推送到飞书、Telegram、企业微信、钉钉:图表按平台能力用原生卡片图表、图片或表格发送;结果过大时,在能发文件的平台附带完整数据 Excel。
48
+ - 群聊机器人回答 @提问,不需要公网地址(飞书长连接、Telegram 长轮询、企业微信智能机器人长连接、钉钉 Stream 模式)。
49
+
50
+ **治理**
51
+ - 只读执行;表 / 字段级访问控制与脱敏;大表全表扫描保护。
52
+ - 成员:各 IM 平台的个人和群都可以设置角色(管理员 / 分析师 / 只读)、数据源范围和行级权限。
53
+ - 审计记录归属到具体的人;可以精确设置哪些查询数据会发给模型。
54
+
55
+ <table>
56
+ <tr>
57
+ <td width="50%"><img src="docs/images/schema.png" alt="表结构分析"></td>
58
+ <td width="50%"><img src="docs/images/channels.png" alt="按平台分组的 IM 渠道"></td>
59
+ </tr>
60
+ <tr>
61
+ <td align="center"><sub>表结构分析</sub></td>
62
+ <td align="center"><sub>IM 渠道</sub></td>
63
+ </tr>
64
+ </table>
65
+
66
+ ## 环境要求
67
+
68
+ - [DeepSeek Harness](https://github.com/deepseek-ai) 0.2 及以上(桌面版或 `dsh web`)。
69
+ - Harness 所在机器能访问数据库(直连或经 SSH)。
70
+ - 强烈建议使用**只读数据库账号**(见[安全模型](#安全模型))。
71
+
72
+ ## 安装
73
+
74
+ **在 Harness 界面中安装(推荐)**
75
+
76
+ 1. 左侧栏打开 **插件**,选择 **添加插件**。
77
+ 2. 输入 `@hedeqiang/dsh-nl2sql`(可指定版本,如 `@hedeqiang/dsh-nl2sql@0.11.2`),安装并启用。
78
+ 3. 左侧栏出现 **数据问答**,新建对话时也可以选择「数据问答」预设。
79
+
80
+ 也可以直接对 Harness 的 Agent 说:「安装插件 @hedeqiang/dsh-nl2sql」。
81
+
82
+ **命令行**
83
+
84
+ ```bash
85
+ dsh plugin --profile desktop add @hedeqiang/dsh-nl2sql # 桌面版的 profile 是 desktop;dsh web 默认是 web
86
+ ```
87
+
88
+ 然后在 **插件** 页启用,或重启 Harness。
89
+
90
+ **升级与卸载**
91
+
92
+ ```bash
93
+ dsh plugin --profile desktop update @hedeqiang/dsh-nl2sql
94
+ dsh plugin --profile desktop remove @hedeqiang/dsh-nl2sql
95
+ ```
96
+
97
+ 配置和数据保存在 `~/.dsh/nl2sql`,升级、卸载都不会删除;旧版本的配置会在首次加载时自动迁移。不再需要时请手动删除该目录。
98
+
99
+ 所有依赖都提供预编译包,安装时不需要运行构建脚本。
100
+
101
+ ## 快速开始
102
+
103
+ 1. **数据问答 → 管理 → 数据源**:添加数据库,或上传 CSV / Excel。
104
+ 2. **表结构**:运行分析(只读取元数据和少量枚举取值样本,不会扫描整表)。
105
+ 3. **问答**:输入问题,例如「最近 30 天每天的订单量和金额」。Agent 选择表、按方言编写 SQL、执行并画图。也可以在任意对话中选择「数据问答」预设。
106
+ 4. **看板**:固定有用的图表,添加筛选,导出或发送。
107
+ 5. **业务知识**:补充词表、指标口径和已验证样例,让回答口径一致;运行评测衡量准确率。
108
+
109
+ ## IM 渠道与机器人
110
+
111
+ 每个平台都是 [`channels/`](channels) 下的一个适配器,核心逻辑只依赖 [docs/channels.md](docs/channels.md) 中定义的接口。
112
+
113
+ | 平台 | 推送 | 图表 | 按钮 | 无需公网地址的机器人 |
114
+ |---|---|---|---|---|
115
+ | 飞书 — 群机器人(Webhook) | ✓ | 原生卡片图表 | – | – |
116
+ | 飞书 — 应用机器人 | ✓(附带 Excel) | 原生图表或图片 | ✓ | ✓ 长连接 |
117
+ | Telegram | ✓(附带 Excel) | 图片 | ✓ 内联按钮 | ✓ 长轮询 |
118
+ | 企业微信 — 群机器人 | ✓ | 图片 | – | – |
119
+ | 企业微信 — 智能机器人 | ✓(仅已给机器人发过消息的会话) | 表格 | – | ✓ 长连接 |
120
+ | 钉钉 — 自定义机器人 | ✓(支持加签) | 表格 | – | – |
121
+ | 钉钉 — 企业内部应用机器人 | ✓ | 表格 | – | ✓ Stream 模式 |
122
+
123
+ 在 **管理 → 渠道** 添加渠道:选择平台和接入方式,表单会显示该平台开放平台的配置步骤。在 **管理 → 成员与权限** 给个人和群开通权限,和机器人说过话的人或群可以一键添加。
124
+
125
+ 群成员 @机器人 直接提问。机器人知道该成员能用哪些数据源,并自动选择匹配的那个。群内命令:`帮助`、`数据源`(列出可用数据源)、`切换 <名称>`(固定数据源)、`自动`(恢复自动选择)、`新对话`。
126
+
127
+ > Telegram、企业微信、钉钉适配器目前只在本地模拟的平台接口上测试过,尚未在真实账号上验证;飞书已在真实环境中使用。欢迎反馈实际部署情况。
128
+
129
+ ## 安全模型
130
+
131
+ - **只读查询。** 每条语句都经过按方言的词法检查(MySQL、PostgreSQL、SQLite、Elasticsearch SQL),只允许 `SELECT` / `SHOW` / `DESCRIBE` / `EXPLAIN`;查询在只读事务中执行并有服务端超时;PostgreSQL 使用扩展协议(不接受多语句);大结果流式读取并截断。
132
+ - **访问控制。** 允许或排除表、隐藏或脱敏字段;大表全表扫描需要确认。
133
+ - **成员。** 数据源范围、只读角色(只能用指标库、已验证样例和看板),以及自动注入查询的行级权限——无法安全改写的查询直接拒绝。
134
+ - **机器人按钮。** IM 消息上的按钮只携带不透明令牌,每次点击都会对点击者重新鉴权。
135
+
136
+ 词法检查只是第一道防线,不能替代数据库权限:**请始终使用只读账号连接。** 安全问题的报告方式见 [SECURITY.md](SECURITY.md)。
137
+
138
+ ## 数据与隐私
139
+
140
+ | 内容 | 位置 |
141
+ |---|---|
142
+ | 配置(数据源、看板、业务知识、告警、成员、渠道、设置) | `~/.dsh/nl2sql/state.json` |
143
+ | 查询结果、缓存、快照和日志(历史、审计、反馈、推送记录、告警记录) | `~/.dsh/nl2sql/results.sqlite` |
144
+ | 上传的文件 | `~/.dsh/nl2sql/files/` |
145
+ | 数据库密码、SSH 密钥、机器人密钥 | Harness 凭据库 |
146
+
147
+ **设置 → 模型可见数据** 决定哪些查询数据会发给大模型:不发、按列统计摘要(默认)或前 *N* 行。敏感字段默认脱敏。推送到 IM 平台的内容会离开本机。
148
+
149
+ ## 已知限制
150
+
151
+ - 告警和每日表结构检查在 Harness 进程内运行:Harness 关闭期间不检查,启动后补查一次。
152
+ - 本机页面拥有所有者权限,没有登录机制;不要把 Harness Web 端口暴露到不可信网络。
153
+ - 行级权限作用于 IM 成员;在行级权限下,含子查询、CTE 或 `UNION` 的查询会被拒绝。
154
+ - 不支持旧版 `.xls`(请使用 `.xlsx` 或 CSV)。
155
+
156
+ ## 开发
157
+
158
+ ```bash
159
+ git clone https://github.com/hedeqiang/dsh-nl2sql.git
160
+ cd dsh-nl2sql
161
+ pnpm install --ignore-scripts
162
+ npm test # 全部测试;本机有 MySQL / PostgreSQL 时会用到
163
+ npm run test:fast # 只跑单元测试和界面测试
164
+ node scripts/build-client.mjs # 修改 client-src/ 后重新生成 lib/client.js
165
+ ```
166
+
167
+ 在 **插件 → 添加插件** 中填入本目录的绝对路径即可以链接方式安装,改代码后重新启用插件生效。目录结构、约定和测试说明见 [docs/development.md](docs/development.md);隔离的准确率评测环境见 [eval/](eval/README.md)。
168
+
169
+ ## 参与贡献
170
+
171
+ 欢迎提交 Issue 和 Pull Request,请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 并遵守[行为准则](CODE_OF_CONDUCT.md)。版本说明见 [CHANGELOG.md](CHANGELOG.md)。
172
+
173
+ ## 许可证
174
+
175
+ [MIT](LICENSE) © hedeqiang
@@ -159,7 +159,7 @@ export function resultAsDingText(r, maxRows = 10, maxCols = 6) {
159
159
  const cell = (c, v) => (c.kind === 'number' ? fmtNum(v) : cellText(v, 30)).replace(/\|/g, '|')
160
160
  const out = [`**${cols.map(c => c.name).join(' | ')}**`, '', ...rows.map((row, i) => `${i + 1}. ${cols.map((c, j) => cell(c, row[j])).join(' | ')}`)]
161
161
  const total = r.rowCount ?? r.rows.length
162
- if (total > rows.length) out.push('', `> 共 ${total} 行,仅显示前 ${rows.length} 行`)
162
+ if (total > rows.length) out.push('', `> 共 ${total} 行,仅显示前 ${rows.length} 行;完整数据可在数据问答页面查看或导出 Excel`)
163
163
  return out.join('\n')
164
164
  }
165
165
 
@@ -508,7 +508,7 @@ const webhookKind = {
508
508
  { key: 'webhookUrl', type: 'secret', secret: true, required: true, label: { zh: 'Webhook 地址', en: 'Webhook URL' }, placeholder: 'https://oapi.dingtalk.com/robot/send?access_token=…', pattern: WEBHOOK_RE.source, help: { zh: '群设置 → 机器人 → 添加机器人 → 自定义,完成后复制 Webhook', en: 'Group settings → Bots → Add → Custom, then copy the webhook' } },
509
509
  { key: 'signSecret', type: 'secret', secret: true, required: false, label: { zh: '加签密钥(可选)', en: 'Signing secret (optional)' }, placeholder: 'SEC…', help: { zh: '安全设置选择「加签」时显示的 SEC 开头字符串', en: 'The SEC… string shown when “Sign” is selected in security settings' } },
510
510
  ],
511
- capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', buttons: false, bot: false, listTargets: false, mentionAll: true, maxMessageBytes: MD_LIMIT },
511
+ capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', tableRows: 10, files: false, buttons: false, bot: false, listTargets: false, mentionAll: true, maxMessageBytes: MD_LIMIT },
512
512
  setupSteps: {
513
513
  zh: [
514
514
  '在钉钉群:群设置 → 机器人 → 添加机器人 → 自定义(通过 Webhook 接入)。',
@@ -542,7 +542,7 @@ const appKind = {
542
542
  { key: 'openConversationId', type: 'text', required: false, label: { zh: '推送目标群(openConversationId,可选)', en: 'Push target group (openConversationId, optional)' }, placeholder: 'cid…', help: { zh: '机器人收到该群消息时的 conversationId(以 cid 开头)', en: 'The conversationId (cid…) seen in a message from that group' } },
543
543
  { key: 'userId', type: 'text', required: false, label: { zh: '推送目标成员 userId(可选)', en: 'Push target member userId (optional)' }, help: { zh: '未填群会话 ID 时,推送到该成员与机器人的单聊', en: 'Used when no group is set: pushes to the member’s chat with the bot' } },
544
544
  ],
545
- capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', buttons: false, bot: true, listTargets: false, mentionAll: false, maxMessageBytes: MD_LIMIT },
545
+ capabilities: { push: true, markdown: 'basic', charts: 'none', chartModes: ['table'], tables: 'text', tableRows: 10, files: false, buttons: false, bot: true, listTargets: false, mentionAll: false, maxMessageBytes: MD_LIMIT },
546
546
  setupSteps: {
547
547
  zh: [
548
548
  '钉钉开发者后台(open-dev.dingtalk.com)→ 应用开发 → 企业内部应用 → 创建应用,记下 Client ID 与 Client Secret。',
package/channels/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Channel adapter registry (see docs/CHANNELS.md).
2
+ * Channel adapter registry (see docs/channels.md).
3
3
  *
4
4
  * Built-in adapters: lark (static), telegram / wecom / dingtalk (loaded with
5
5
  * dynamic import so a missing or broken module never breaks the registry).