@guandata/guancli 1.0.9
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/bin/run.js +75 -0
- package/binaries/guancli-darwin-arm64 +0 -0
- package/binaries/guancli-darwin-x64 +0 -0
- package/binaries/guancli-win32-x64.exe +0 -0
- package/package.json +37 -0
- package/skills/guancli/SKILL.md +410 -0
package/bin/run.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { execFileSync, spawnSync } = require("child_process");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
|
|
9
|
+
const PLATFORM_MAP = {
|
|
10
|
+
"darwin-arm64": "guancli-darwin-arm64",
|
|
11
|
+
"darwin-x64": "guancli-darwin-x64",
|
|
12
|
+
"win32-x64": "guancli-win32-x64.exe",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function getBinaryPath() {
|
|
16
|
+
const key = `${process.platform}-${process.arch}`;
|
|
17
|
+
const binaryName = PLATFORM_MAP[key];
|
|
18
|
+
if (!binaryName) {
|
|
19
|
+
console.error(
|
|
20
|
+
`Unsupported platform: ${key}\nSupported: ${Object.keys(PLATFORM_MAP).join(", ")}`
|
|
21
|
+
);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const binaryPath = path.join(__dirname, "..", "binaries", binaryName);
|
|
26
|
+
if (!fs.existsSync(binaryPath)) {
|
|
27
|
+
console.error(
|
|
28
|
+
`Binary not found: ${binaryPath}\nRun 'npm run build' to compile binaries.`
|
|
29
|
+
);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return binaryPath;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (process.argv[2] === "install-skill") {
|
|
37
|
+
const pkgRoot = path.join(__dirname, "..");
|
|
38
|
+
const extraArgs = process.argv.slice(3);
|
|
39
|
+
const args = [
|
|
40
|
+
"skills",
|
|
41
|
+
"add",
|
|
42
|
+
pkgRoot,
|
|
43
|
+
"--skill",
|
|
44
|
+
"guancli",
|
|
45
|
+
"-g",
|
|
46
|
+
"-y",
|
|
47
|
+
...extraArgs,
|
|
48
|
+
];
|
|
49
|
+
console.log("Installing guancli to AI coding assistants...");
|
|
50
|
+
const result = spawnSync("npx", args, { stdio: "inherit", env: process.env, shell: true });
|
|
51
|
+
if (result.error) throw result.error;
|
|
52
|
+
process.exit(result.status || 0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const binary = getBinaryPath();
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
if (process.platform !== "win32") {
|
|
59
|
+
fs.chmodSync(binary, 0o755);
|
|
60
|
+
}
|
|
61
|
+
} catch (_) {
|
|
62
|
+
// chmod may fail in read-only environments; binary might already be executable
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
execFileSync(binary, process.argv.slice(2), {
|
|
67
|
+
stdio: "inherit",
|
|
68
|
+
env: { ...process.env, GUANCLI_PROG_NAME: "guancli" },
|
|
69
|
+
});
|
|
70
|
+
} catch (err) {
|
|
71
|
+
if (err.status != null) {
|
|
72
|
+
process.exit(err.status);
|
|
73
|
+
}
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guandata/guancli",
|
|
3
|
+
"version": "1.0.9",
|
|
4
|
+
"description": "观远 BI 命令行工具 - 通过 API 操作 ETL、数据集、页面、表单等资源",
|
|
5
|
+
"bin": {
|
|
6
|
+
"guancli": "bin/run.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "node scripts/build.js && node scripts/sync-skill.js",
|
|
10
|
+
"prepublishOnly": "node scripts/preflight.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/",
|
|
14
|
+
"binaries/",
|
|
15
|
+
"skills/",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"guandata",
|
|
20
|
+
"bi",
|
|
21
|
+
"cli",
|
|
22
|
+
"etl",
|
|
23
|
+
"agent-skill"
|
|
24
|
+
],
|
|
25
|
+
"license": "UNLICENSED",
|
|
26
|
+
"os": [
|
|
27
|
+
"darwin",
|
|
28
|
+
"win32"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=14"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"registry": "https://registry.npmjs.org/",
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: guancli
|
|
3
|
+
description: 当用户提到观远 BI、ETL、数据集、页面/仪表板分析、血缘、节点 SQL、资源树、页面配置排查、表单填报数据操作,或希望直接分析 BI 项目而不是手工点页面时,主动使用这个 skill。它通过直接调用 BI API 获取数据,并把结果整理成适合 AI 消费的中文结论。支持表单 CRUD(类似 Airtable 风格)。
|
|
4
|
+
compatibility: Requires Node.js 14+. Install via npm install -g @guandata/guancli.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# guancli
|
|
8
|
+
|
|
9
|
+
## 何时优先使用
|
|
10
|
+
|
|
11
|
+
- 用户希望分析观远 BI 项目的 ETL 逻辑、数据集结构、页面/仪表板内容。
|
|
12
|
+
- 用户提供了 BI 系统 URL,需要连接并获取数据。
|
|
13
|
+
- 用户要快速拿到 ETL 清单、节点 SQL、输入输出数据集血缘。
|
|
14
|
+
- 用户在排查 BI 资源配置、页面卡片定义、接口返回或 lineage 关系。
|
|
15
|
+
- 用户需要对表单填报(Form)数据进行 CRUD 操作(查询/插入/更新/删除)。
|
|
16
|
+
|
|
17
|
+
如果用户只想导出 PNG / PDF 成品,不要用本 skill,改用 `guanexport-skill`。
|
|
18
|
+
|
|
19
|
+
## 数据获取方式
|
|
20
|
+
|
|
21
|
+
通过保存的认证信息直接调用 BI HTTP API。
|
|
22
|
+
|
|
23
|
+
## 首次配置(认证)
|
|
24
|
+
|
|
25
|
+
### 方式一:用户名密码登录(推荐)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
guancli auth login
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
交互式输入:
|
|
32
|
+
1. 环境名称(默认 `default`,可自定义如 `staging`、`prod`)
|
|
33
|
+
2. BI 系统 URL(如 `https://bi.example.com`)
|
|
34
|
+
3. 选择登录方式:`1` 用户名密码
|
|
35
|
+
4. Domain(如 `demo`)
|
|
36
|
+
5. 用户名(邮箱)
|
|
37
|
+
6. 密码
|
|
38
|
+
|
|
39
|
+
登录成功后 Token 自动保存在系统标准配置目录下的 `guancli/config.json`。密码方式支持 Token 过期后自动刷新。
|
|
40
|
+
|
|
41
|
+
### 方式二:直接输入 Token
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
guancli auth login
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
选择登录方式 `2`,直接粘贴已有的 Auth Token。适用于已从 Web 界面或其他途径获取 Token 的场景。
|
|
48
|
+
|
|
49
|
+
### 多环境管理
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
guancli auth login --profile staging # 添加 staging 环境
|
|
53
|
+
guancli auth login --profile prod --default # 添加 prod 并设为默认
|
|
54
|
+
guancli auth list # 列出所有环境
|
|
55
|
+
guancli auth status # 查看当前认证状态
|
|
56
|
+
guancli auth use staging # 切换默认环境为 staging
|
|
57
|
+
guancli auth remove staging # 删除 staging 环境
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
使用特定环境(不切换默认):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
guancli --profile staging etl tree
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 先做判断
|
|
67
|
+
|
|
68
|
+
1. 先用 `auth status` 确认认证是否有效。
|
|
69
|
+
2. 如果 Token 过期,密码登录方式会自动刷新;Token 方式需重新登录。
|
|
70
|
+
3. 先判断资源类型:ETL 用 `etl`,数据集用 `ds`,页面/仪表板用 `page`,表单填报用 `form`。
|
|
71
|
+
4. 信息不全时先 `tree` 或 `search`,拿到 ID 后再 `get`。
|
|
72
|
+
|
|
73
|
+
## 标准分析流程
|
|
74
|
+
|
|
75
|
+
### 1. 拉取目录树
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
guancli etl tree
|
|
79
|
+
guancli ds tree
|
|
80
|
+
guancli page tree
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2. 搜索资源
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
guancli etl search # 搜索所有 ETL
|
|
87
|
+
guancli etl search 关键词 # 按关键词搜索
|
|
88
|
+
guancli etl search 关键词 -d <dir_id> # 在指定目录中搜索
|
|
89
|
+
guancli ds search 关键词 # 搜索数据集
|
|
90
|
+
guancli page search 关键词 # 搜索页面
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. 获取详情(含血缘)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
guancli etl get <resource_id> # ETL 详情(含节点、SQL、血缘)
|
|
97
|
+
guancli ds get <resource_id> # 数据集详情(含字段结构、血缘)
|
|
98
|
+
guancli ds get <resource_id> --brief # 数据集轻量输出(省略 Malloy、血缘、公式详情,节省 token)
|
|
99
|
+
guancli page get <resource_id> # 页面详情(含卡片列表、血缘)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**`--brief` 模式**:省略 Malloy 数据源定义、血缘关系、计算字段公式等高 token 内容,只保留基本信息和字段名/类型列表。适合 AI 在上下文受限时快速了解数据集结构。所有 `get` 子命令均支持此选项。
|
|
103
|
+
|
|
104
|
+
### 4. 预览数据集数据
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
guancli ds preview <ds_id> # 预览数据集数据 (表格格式)
|
|
108
|
+
guancli ds preview <ds_id> --limit 20 # 限制预览行数
|
|
109
|
+
guancli ds preview <ds_id> --raw # 输出原始 JSON
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
数据集 ID (dsId) 可通过 `ds tree` 或 `ds search` 获取。
|
|
113
|
+
|
|
114
|
+
#### 带筛选条件预览
|
|
115
|
+
|
|
116
|
+
通过 `--filter` 参数传入筛选条件,每个 `--filter` 值的格式为 `"列名 操作符 [值]"`。
|
|
117
|
+
列名中包含空格时无需特殊处理,解析器会智能定位操作符。
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
guancli ds preview <ds_id> --filter "name EQ 张三"
|
|
121
|
+
guancli ds preview <ds_id> --filter "age GT 18" --filter "city IN 北京,上海,广州"
|
|
122
|
+
guancli ds preview <ds_id> --filter "score BT 60,100"
|
|
123
|
+
guancli ds preview <ds_id> --filter "status IS_NULL"
|
|
124
|
+
guancli ds preview <ds_id> --filter "销售 金额 GT 100" --combine-type OR
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
支持的操作符:
|
|
128
|
+
- 比较:`EQ`(等于)、`NE`(不等于)、`LT`(小于)、`LE`(小于等于)、`GT`(大于)、`GE`(大于等于)
|
|
129
|
+
- 区间:`BT`(between,两个值逗号分隔)
|
|
130
|
+
- 集合:`IN`(多值逗号分隔)
|
|
131
|
+
- 空值:`IS_NULL`、`NOT_NULL`
|
|
132
|
+
- 字符串:`CONTAINS`、`NOT_CONTAINS`、`STARTSWITH`、`NOT_STARTSWITH`、`ENDSWITH`、`NOT_ENDSWITH`
|
|
133
|
+
|
|
134
|
+
`--combine-type` 控制多条件组合方式,默认 `AND`,可设为 `OR`。
|
|
135
|
+
字段类型会自动从数据集 schema 推断,无需手动指定。
|
|
136
|
+
|
|
137
|
+
#### 日期粒度筛选(SUB_DATE)
|
|
138
|
+
|
|
139
|
+
对 DATE/TIMESTAMP 字段,可用 `toYear`/`toQuarter`/`toMonth`/`toDate` 修饰符按粒度筛选。
|
|
140
|
+
语法:`"列名 toGranularity OPERATOR value"`,值使用标准格式,CLI 自动转换为 BI API 格式。
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
guancli card preview <cd_id> --filter "日期字段 toQuarter IN 2026-Q1"
|
|
144
|
+
guancli card preview <cd_id> --filter "日期字段 toQuarter IN 2026-Q1,2026-Q2"
|
|
145
|
+
guancli card preview <cd_id> --filter "日期字段 toYear EQ 2026"
|
|
146
|
+
guancli card preview <cd_id> --filter "日期字段 toMonth EQ 2026-01"
|
|
147
|
+
guancli card preview <cd_id> --filter "日期字段 toDate EQ 2026-01-15"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
值格式规范:
|
|
151
|
+
|
|
152
|
+
| 粒度 | 修饰符 | 值格式 | 示例 |
|
|
153
|
+
|------|--------|--------|------|
|
|
154
|
+
| 年 | `toYear` | `YYYY` | `2026` |
|
|
155
|
+
| 季度 | `toQuarter` | `YYYY-QN` | `2026-Q1` |
|
|
156
|
+
| 月 | `toMonth` | `YYYY-MM` | `2026-01` |
|
|
157
|
+
| 日期 | `toDate` | `YYYY-MM-DD` | `2026-01-15` |
|
|
158
|
+
|
|
159
|
+
可配合 `--filter "维度字段 EQ 值"` 同时使用多个筛选条件。
|
|
160
|
+
|
|
161
|
+
#### 排序和列筛选
|
|
162
|
+
|
|
163
|
+
所有 preview 命令(ds/card)都支持排序和列筛选:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
guancli ds preview <ds_id> --sort-asc name # 按 name 升序 (API 层面排序)
|
|
167
|
+
guancli ds preview <ds_id> --sort-desc id # 按 id 降序 (API 层面排序)
|
|
168
|
+
guancli ds preview <ds_id> --columns "id,name,status" # 只显示指定列
|
|
169
|
+
guancli ds preview <ds_id> --filter "status EQ FAILED" --sort-desc id --columns "id,task_name"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
- `--sort-asc` / `--sort-desc`: 互斥,只能指定一个列。ds preview 的排序通过 API 在数据库层面执行;card preview 的排序在 Go 端对返回数据执行。
|
|
173
|
+
- `--columns`: 逗号分隔的列名列表,只显示指定列(Go 端执行)。
|
|
174
|
+
|
|
175
|
+
### 5. 获取卡片数据
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
guancli card get <cd_id> # 获取卡片元信息
|
|
179
|
+
guancli card preview <cd_id> # 预览卡片数据 (表格格式)
|
|
180
|
+
guancli card preview <cd_id> --limit 20 # 限制预览行数
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
卡片 ID (cdId) 可通过 `page get` 命令查看页面详情获取。
|
|
184
|
+
|
|
185
|
+
#### 带筛选条件预览卡片
|
|
186
|
+
|
|
187
|
+
卡片 preview 同样支持 `--filter` 参数,语法与数据集 preview 一致(含日期粒度筛选)。
|
|
188
|
+
筛选条件会通过 API 传递给后端,适用于 CHART、SELECTOR、TREE_SELECTOR 三种卡片类型。
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
guancli card preview <cd_id> --filter "name EQ 张三"
|
|
192
|
+
guancli card preview <cd_id> --filter "age GT 18" --filter "city IN 北京,上海"
|
|
193
|
+
guancli card preview <cd_id> --filter "利润中心 EQ 华南" --filter "季度(日期) toQuarter IN 2026-Q1"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
字段类型会自动从卡片关联的数据集 schema 推断。日期粒度筛选需配合 `card get` 查看字段配置中的筛选器字段名和粒度。
|
|
197
|
+
|
|
198
|
+
### 6. 表单填报操作 (Form CRUD)
|
|
199
|
+
|
|
200
|
+
类似 Airtable 风格的表单数据 CRUD,用户始终用**字段名**操作,CLI 内部自动映射到 fdId。
|
|
201
|
+
|
|
202
|
+
#### 列出表单
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
guancli form list # 列出所有表单
|
|
206
|
+
guancli form list 关键词 # 搜索表单
|
|
207
|
+
guancli form list --tree # 目录树形式展示
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### 查看表单结构
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
guancli form schema <fmId> # 查看字段结构(LLM 消费核心)
|
|
214
|
+
guancli form schema <fmId> -f json # JSON 格式
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### 查询数据
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
guancli form query <fmId> # 查询数据(默认 50 行)
|
|
221
|
+
guancli form query <fmId> --limit 100 # 指定行数
|
|
222
|
+
guancli form query <fmId> --filter "姓名 EQ 张三" # 筛选
|
|
223
|
+
guancli form query <fmId> --sort-asc 值 # 按值升序
|
|
224
|
+
guancli form query <fmId> --columns "姓名,值" # 只显示指定列
|
|
225
|
+
guancli form query <fmId> -f json # JSON 格式(rowId 完整)
|
|
226
|
+
guancli form query <fmId> -f expanded # PG 风格竖排
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
筛选操作符:`EQ`(等于)、`CONTAINS`(包含)、`STARTSWITH`、`ENDSWITH`、`IS_NULL`、`NOT_NULL`。
|
|
230
|
+
|
|
231
|
+
**重要**:`rowId` 在 auto 表格格式中可能被截断,使用 `-f json` 或 `-f expanded` 获取完整 rowId。
|
|
232
|
+
|
|
233
|
+
#### 插入数据
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
guancli form add <fmId> --data '{"字段名": "值", "数字字段": 42}'
|
|
237
|
+
guancli form add <fmId> --set "字段名=值" --set "数字字段=42"
|
|
238
|
+
echo '[{"字段名":"a"},{"字段名":"b"}]' | guancli form add <fmId> --stdin
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
#### 更新数据
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
guancli form update <fmId> <rowId> --data '{"字段名": "新值"}'
|
|
245
|
+
guancli form update <fmId> <rowId> --set "字段名=新值"
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
`rowId` 通过 `form query` 获取。
|
|
249
|
+
|
|
250
|
+
#### 删除数据
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
guancli form delete <fmId> <rowId> # 删除单行
|
|
254
|
+
guancli form delete <fmId> <rowId1> <rowId2> # 删除多行
|
|
255
|
+
guancli form delete <fmId> --all --yes # 删除全部(需确认)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### 子表操作
|
|
259
|
+
|
|
260
|
+
主表中 `TABLE` / `MATRIX_TABLE` 类型字段对应子表。子表有独立的 `subFmId`,可以用 `schema` 查看其字段结构。
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# 1. 查看主表 schema,找到 TABLE 字段的 subFmId
|
|
264
|
+
guancli form schema <mainFmId>
|
|
265
|
+
# 输出中 TABLE 字段的备注列显示 "子表 subFmId=..."
|
|
266
|
+
|
|
267
|
+
# 2. 查看子表字段结构
|
|
268
|
+
guancli form schema <subFmId>
|
|
269
|
+
|
|
270
|
+
# 3. 查询子表数据(返回结果包含主表字段,rowId 为主表行 ID,subId 为子行 ID)
|
|
271
|
+
guancli form query <subFmId>
|
|
272
|
+
|
|
273
|
+
# 4. 向子表插入行(需指定主表行的 rowId)
|
|
274
|
+
guancli form add <subFmId> --parent-row <主表rowId> --set "字段名=值"
|
|
275
|
+
|
|
276
|
+
# 5. 更新子表行(使用 subId 作为 rowId)
|
|
277
|
+
guancli form update <subFmId> <subId> --set "字段名=新值"
|
|
278
|
+
|
|
279
|
+
# 6. 删除子表行
|
|
280
|
+
guancli form delete <subFmId> <subId>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**子表 ID 映射规则**(AI 调用时注意区分):
|
|
284
|
+
|
|
285
|
+
| 操作 | fmId 参数 | 行 ID 参数 | 额外参数 |
|
|
286
|
+
|------|-----------|-----------|---------|
|
|
287
|
+
| schema | subFmId | - | - |
|
|
288
|
+
| query | subFmId | - | 返回 rowId(主表行) + subId(子行) |
|
|
289
|
+
| add | subFmId | - | `--parent-row <主表rowId>` |
|
|
290
|
+
| update | subFmId | **subId** (作为 rowId 位置参数) | - |
|
|
291
|
+
| delete | subFmId | **subId** (作为 rowId 位置参数) | - |
|
|
292
|
+
|
|
293
|
+
**注意**:
|
|
294
|
+
- 子表 add 内部通过主表 update API 间接完成(后端限制),CLI 自动保留已有子行
|
|
295
|
+
- add 需全量读取子表以保留已有行,子表总行数上限 10000;非并发安全
|
|
296
|
+
- `--stdin` 批量插入部分失败时 CLI 返回非零退出码,summary 中显示成功/失败计数
|
|
297
|
+
|
|
298
|
+
#### 典型工作流
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# 1. 找到表单
|
|
302
|
+
guancli form list 测试
|
|
303
|
+
|
|
304
|
+
# 2. 查看结构
|
|
305
|
+
guancli form schema <fmId>
|
|
306
|
+
|
|
307
|
+
# 3. 插入数据
|
|
308
|
+
guancli form add <fmId> --data '{"测试1": "hello", "值": 42}'
|
|
309
|
+
|
|
310
|
+
# 4. 查询并获取 rowId
|
|
311
|
+
guancli form query <fmId> -f json
|
|
312
|
+
|
|
313
|
+
# 5. 更新
|
|
314
|
+
guancli form update <fmId> <rowId> --set "值=99"
|
|
315
|
+
|
|
316
|
+
# 6. 删除
|
|
317
|
+
guancli form delete <fmId> <rowId>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### 7. 通用 API 调用(原始 JSON)
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
guancli fetch GET /api/health
|
|
324
|
+
guancli fetch GET /api/etl/<id>
|
|
325
|
+
guancli fetch POST /api/resource-atlas/<id> '{"resourceTypeName":"DATA_PROCESS_ETL"}'
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### 8. 输出格式控制
|
|
329
|
+
|
|
330
|
+
`--format` / `-f` 控制 preview 命令的输出格式:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
guancli ds preview <ds_id> # auto: 对齐表格,列>10 或行>20 时自动截断
|
|
334
|
+
guancli ds preview <ds_id> -f csv # CSV 格式
|
|
335
|
+
guancli ds preview <ds_id> -f expanded # PG 风格竖排
|
|
336
|
+
guancli ds preview <ds_id> -f table # 对齐表格
|
|
337
|
+
guancli ds preview <ds_id> -f json # JSON 行记录数组
|
|
338
|
+
guancli ds preview <ds_id> -f json | jq '.[0]' # 配合 jq
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
`--raw` 输出 API 原始 JSON(不经过解析):
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
guancli --raw etl tree
|
|
345
|
+
guancli --raw etl get <id>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Token 管理
|
|
349
|
+
|
|
350
|
+
- 密码登录方式:Token 过期后自动调用 sign-in API 刷新。
|
|
351
|
+
- 每次 API 响应中如果包含新 Token,且距上次签发超过可配置间隔(默认 10 分钟),会自动更新缓存。
|
|
352
|
+
- Token 的签发时间和过期时间记录在配置文件中。
|
|
353
|
+
- 可通过修改 `config.json` 中的 `token_refresh_interval_seconds` 调整刷新间隔。
|
|
354
|
+
|
|
355
|
+
## 输出说明
|
|
356
|
+
|
|
357
|
+
- **目录树**:树形结构(├── └──),包含名称和 ID
|
|
358
|
+
- **搜索结果**:表格式列表,包含名称、ID、状态、路径、调度信息、时间
|
|
359
|
+
- **ETL 详情**:流程摘要 + 节点详细信息(含 Sources/UsedBy 引用)+ 等价 SQL + 血缘关系
|
|
360
|
+
- **数据集详情**:基本信息 + 字段结构(维度/度量/计算字段分类)+ Malloy source 定义 + 血缘关系
|
|
361
|
+
- **页面详情**:页面信息 + 卡片列表(含筛选器配置、交互联动、Malloy 查询)+ 血缘关系
|
|
362
|
+
- **数据集预览**:表格格式预览(列名 + 数据行),显示数据集基本信息和行列统计
|
|
363
|
+
- **卡片数据**:表格格式预览(维度 + 度量),自动检测卡片类型(图表/筛选器/树状筛选器)
|
|
364
|
+
- **表单列表**:表格式列表,包含 fmId、名称、类型、创建者、更新时间
|
|
365
|
+
- **表单结构**:字段定义表格,包含 fdId、名称、类型、必填/可编辑、选项(LLM 消费核心);TABLE 类型字段显示 subFmId
|
|
366
|
+
- **表单数据**:表格格式,首列为 rowId(用于 update/delete),后续为字段列;子表查询结果额外包含 `subId` 列(子行主键,update/delete 时用作 rowId 参数)
|
|
367
|
+
- **表单写操作**(add/update/delete):默认输出 `✓ ...` 文本;`-f json` 时输出结构化 JSON:`{"ok":true,"action":"add","rowId":"...","count":N,"total":N,"failed":N}`。批量插入部分失败时 `ok=false` 且 exit code 非零
|
|
368
|
+
|
|
369
|
+
## 回答风格要求
|
|
370
|
+
|
|
371
|
+
- 用中文输出,优先给"可执行结论"。
|
|
372
|
+
- 不只贴原始命令结果,必须做逻辑归纳(按链路/主题)。
|
|
373
|
+
- 涉及时间相关信息时给出明确日期。
|
|
374
|
+
- 如果用户给的是模糊对象名,先说明你是如何定位到具体资源 ID 的。
|
|
375
|
+
|
|
376
|
+
## 故障排查
|
|
377
|
+
|
|
378
|
+
### Token 过期 / API 401
|
|
379
|
+
|
|
380
|
+
密码登录方式会自动刷新。如果仍然失败,重新登录:
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
guancli auth login
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## 配置文件位置
|
|
387
|
+
|
|
388
|
+
- macOS: `~/Library/Application Support/guancli/config.json`
|
|
389
|
+
- Linux: `~/.config/guancli/config.json`
|
|
390
|
+
- Windows: `%AppData%\\guancli\\config.json`
|
|
391
|
+
|
|
392
|
+
```json
|
|
393
|
+
{
|
|
394
|
+
"profiles": {
|
|
395
|
+
"default": {
|
|
396
|
+
"name": "default",
|
|
397
|
+
"base_url": "https://bi.example.com",
|
|
398
|
+
"domain": "demo",
|
|
399
|
+
"login_id": "user@example.com",
|
|
400
|
+
"password": "yourpassword",
|
|
401
|
+
"auth_method": "password",
|
|
402
|
+
"token": "...",
|
|
403
|
+
"issued_at": 1711234567,
|
|
404
|
+
"expires_at": 0,
|
|
405
|
+
"is_default": true
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
"token_refresh_interval_seconds": 600
|
|
409
|
+
}
|
|
410
|
+
```
|