@guandata/guancli 1.0.60 → 1.0.61

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,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## @guandata/guancli 1.0.61 - 2026-09-18
4
+
5
+ - 指标取数不再静默忽略无效筛选与排序字段:`--dim`、`--filter`、`--sort-asc`/`--sort-desc` 都按指标详情中的字段校验,未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;结构化 `--filter-json`/`--filter-file` 在解析阶段返回 `FILTER_UNKNOWN_FIELD`,不会透传未知字段。
6
+ - 排序目标除了适用维度和时间维度,还接受保存卡片中真实存在的高级计算列,以及泛化查询结果列名 `<指标名>_<后缀>`(如 `_yoy`、`_recent_7d`、`_percentage`、`_rank`)。
7
+ - 指标详情 `publicDimensionMap` 中唯一映射到一个适用维度的公共维度名,可直接用于 `--dim`、日期粒度表达式、排序和筛选;同名映射到多个物理字段时明确报歧义,不猜测字段。
8
+
3
9
  ## @guandata/guancli 1.0.60 - 2026-09-17
4
10
 
5
11
  - 新增内部 OAuth2 应用认证:整体注入 `GUANCLI_OAUTH2_BASE_URL`、`GUANCLI_OAUTH2_ACCESS_TOKEN` 与用户身份(`GUANCLI_OAUTH2_UID` 或 `GUANCLI_OAUTH2_LOGIN_ID`);CLI 不保存、不交换也不刷新该 Token,且 OAuth2 与 OIDC 变量同时出现时明确报错,不回退本地 profile。
package/README.md CHANGED
@@ -43,6 +43,11 @@ guancli chatbi query --theme-name "经营主题" --message "最近30天营业收
43
43
 
44
44
  ## 版本更新
45
45
 
46
+ ### @guandata/guancli 1.0.61
47
+
48
+ - 指标取数会校验 `--dim`、`--filter` 和排序字段:未命中指标详情字段时返回明确错误,不再静默忽略条件。
49
+ - 排序支持保存卡片的高级计算列与泛化结果列名;唯一映射的公共维度名可用于维度、排序和筛选。
50
+
46
51
  ### @guandata/guancli 1.0.60
47
52
 
48
53
  - 新增内部 OAuth2 应用认证,按 `GUANCLI_OAUTH2_*` 整体注入环境与用户身份,CLI 不保存、不刷新该 Token。
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guandata/guancli",
3
- "version": "1.0.60",
3
+ "version": "1.0.61",
4
4
  "description": "观远 BI 命令行工具 - 通过 API 操作 ETL、数据集、页面、表单等资源,并提供 ChatBI 问数/洞察能力",
5
5
  "bin": {
6
6
  "guancli": "bin/run.js"
@@ -156,7 +156,7 @@ guancli 在这条链路上只出只读的那一环:`guancli page search` / `pa
156
156
  - query 的业务列可以是中文,每个中文层级都用 `["字段名"]`:例如 `.data[] | .["组织"]["名称"]`,每一个中文层级都要引用,不能只改顶层。search/get 的 canonical 英文字段与 query 的业务列名要分开理解。文件模式的 `path` 指向行数组,行数组没有 `rowCount`;先按 `resultMode` 分支再消费,示例见 `references/metric-commands.md`。
157
157
  - 必须解析的命令不得用 `2>/dev/null` 隐藏 stderr,也不得用 `2>&1` 将错误文本送入 JSON 解码器。不要用会让末端命令成功掩盖上游失败的管道;允许组合执行时用 `&&` 衔接“输出到文件 → 解析摘要”,不为读取文件另起一轮推理,必须使用管道时先启用 `set -o pipefail`。
158
158
  - 同类语法错误只允许出现一次;第一次失败后先执行对应命令的 `--help` 或读取本 Skill 的参考文档,再按真实契约纠正,不连续尝试相近写法。
159
- - 普通 `--filter`、可重复 `--filter-json`、单个 `--filter-file` 三选一,禁止混用。复杂筛选优先使用 `--filter-json`(可重复)或 `--filter-file` 条件树。参数和口径明确时直接查询;需要检查计划或排查复杂参数时才用 `--dry-run -f json`。dry-run 只读取指标详情做查询维度、筛选字段和类型校验,不执行指标取数,也不支持普通文件或 stderr 输出目标。不支持的 `--dim` 返回 `METRIC_UNSUPPORTED_DIMENSION`。条件组使用 `combineType: AND|OR` 和 `conditions` 数组,叶子使用 `field/operator/value|values`;`IN` 至少一个值,`BT` 恰好两个值。当前指标取数接口不能无损表达多分支 OR,真实执行会在取数前返回 `FILTER_OR_EXECUTION_UNSUPPORTED`,不得拆成多次聚合查询后拼接。失败时按稳定错误码修正,不猜错误文本。
159
+ - 普通 `--filter`、可重复 `--filter-json`、单个 `--filter-file` 三选一,禁止混用。复杂筛选优先使用 `--filter-json`(可重复)或 `--filter-file` 条件树。参数和口径明确时直接查询;需要检查计划或排查复杂参数时才用 `--dry-run -f json`。dry-run 只读取指标详情做查询维度、筛选字段和类型校验,不执行指标取数,也不支持普通文件或 stderr 输出目标;保存卡片高级计算列不在指标详情中,因此这类排序候选在 dry-run 中不会被猜测为有效,真实执行时才读取既有卡片编辑配置校验。不支持的 `--dim`、普通 `--filter` 的字段、`--sort-asc`/`--sort-desc` 的字段都按指标详情中的字段(适用维度 / 时间维度 / 指标字段名)校验,未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;结构化 `--filter-json`/`--filter-file` 在解析阶段按同一份字段集合校验,未命中返回 `FILTER_UNKNOWN_FIELD`。两类错误都不会静默忽略条件或透传未知字段。普通展示别名只对 `--dim` 与排序生效;若指标详情的 `publicDimensionMap` 把唯一公共维度名映射到一个适用维度,则 `--dim`、排序和筛选也可使用该公共维度名,CLI 会保留物理 `fdId` 并把公共维度名作为 alias;同名映射到多个物理字段时拒绝猜测。仅由 CLI 为排序注入、以指标 ID 充当 `fdId` 的“指标名伪字段”不能用于筛选,若指标详情的 `fdInfos` 本身含同名原始字段和真实 `fdId`,仍可正常筛选。`--sort-asc`/`--sort-desc` 额外接受保存卡片中真实存在的高级计算列,以及泛化查询的结果列名 `<指标名>_<后缀>`(`_yoy`/`_mom`/`_qoq`/`_wow`/`_dod`/`_ytd`/`_qtd`/`_mtd`/`_wtd`/`_dtd`/`_last`/`_recent_*`/`_percentage`/`_rank`)。遇到这些错误时先用 `guancli metric get` 读取适用维度再改字段。条件组使用 `combineType: AND|OR` 和 `conditions` 数组,叶子使用 `field/operator/value|values`;`IN` 至少一个值,`BT` 恰好两个值。当前指标取数接口不能无损表达多分支 OR,真实执行会在取数前返回 `FILTER_OR_EXECUTION_UNSUPPORTED`,不得拆成多次聚合查询后拼接。失败时按稳定错误码修正,不猜错误文本。
160
160
  - 搜索并同时查看业务口径、数据集和适用维度等详情时,优先使用 `guancli metric search --fuzzy <keyword> --limit <N> --with-detail --brief -f json`,不要先 search 再逐个 get,也不要为终端阅读额外拼 jq。只查单个指标详情时优先使用 `guancli metric get <metric_id> --brief`;只裁剪指标查询结果列时使用 `metric query --columns`。可复制模板见 `references/metric-commands.md`。
161
161
  - 业务词不能直接命中指标时,候选发现必须遵守单批预算:一次性生成“原词 + 最多 4 个必要同义词/等价表达”,按 trim、空白归一化和大小写不敏感语义去重,保留原词在首位,然后只执行一次 `metric search --fuzzy`。不得把同义词拆成多次查询,不得通过调换顺序、改写等价词或查询子集重复搜索;如果单批无候选,立即结束本轮候选发现并说明已尝试关键词、搜索范围、无结果原因和 `stop_reason=no_candidate_within_budget`。后端最多接受 10 个模糊关键词,但 Agent 候选发现预算默认最多 5 个;不要缓存或跨请求复用“未找到指标”的结论。完整协议见 `references/metric-commands.md`。
162
162
  - 指标结果加工前,先读取成功 query envelope 的实际 `columns` 和行对象 keys,按业务含义选择列;禁止硬编码或猜测指标展示列名(包括高级计算后缀),也不能按列位置取值。使用 `python3 references/examples/metric-query-rows.py <envelope.json> --list-columns` 发现列,再用 `--column "<已确认的实际列名>"` 精确选择;候选缺失或多义时停止并返回实际列集合,不猜近似名称。该参数属于消费 recipe,不是 `guancli metric query` 的参数。
@@ -240,13 +240,13 @@ guancli metric query <metric_id> [flags]
240
240
  | --- | --- | --- |
241
241
  | `--limit int` | `50` | 数据行数限制 |
242
242
  | `--dim strings` | 无 | 维度名称,可多次指定,也支持逗号、中文逗号、顿号分隔;日期子类型写作 `"订单日期 toMonth"` |
243
- | `--filter stringArray` | 无 | 筛选条件,格式:`"列名 操作符 值"`,可多次指定 |
244
- | `--filter-json stringArray` | 无 | 结构化筛选 JSON,可重复;与 --filter/--filter-file 互斥;支持嵌套 AND/OR 条件树 |
243
+ | `--filter stringArray` | 无 | 筛选条件,格式:`"列名 操作符 值"`,可多次指定;列名必须是该指标详情中的字段(适用维度 / 时间维度 / 指标字段名),未命中返回 `METRIC_UNSUPPORTED_DIMENSION`,不会静默忽略 |
244
+ | `--filter-json stringArray` | 无 | 结构化筛选 JSON,可重复;与 --filter/--filter-file 互斥;支持嵌套 AND/OR 条件树;字段未命中该指标字段时在解析阶段返回 `FILTER_UNKNOWN_FIELD` |
245
245
  | `--filter-file string` | 无 | 从 JSON 文件读取一棵结构化条件树;与 `--filter`、`--filter-json` 互斥 |
246
246
  | `--combine-type string` | `AND` | 多条件组合方式:`AND` 或 `OR` |
247
247
  | `--dry-run` | `false` | 只返回规范化查询计划、字段类型和稳定错误码,不执行指标取数;必须同时使用 `-f json`,且不支持普通文件或 stderr 输出目标 |
248
- | `--sort-asc string` | 无 | 按列升序排序;日期子类型使用与 `--dim` 相同的粒度表达式;与 `--sort-desc` 互斥 |
249
- | `--sort-desc string` | 无 | 按列降序排序;日期子类型使用与 `--dim` 相同的粒度表达式;与 `--sort-asc` 互斥 |
248
+ | `--sort-asc string` | 无 | 按列升序排序;排序目标可以是适用维度 / 时间维度、指标名本身、保存卡片中真实存在的高级计算列,或泛化结果列名 `<指标名>_<后缀>`(`_yoy`/`_mom`/`_qoq`/`_wow`/`_dod`/`_ytd`/`_qtd`/`_mtd`/`_wtd`/`_dtd`/`_last`/`_recent_*`/`_percentage`/`_rank`);日期子类型使用与 `--dim` 相同的粒度表达式;未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;与 `--sort-desc` 互斥 |
249
+ | `--sort-desc string` | 无 | 按列降序排序;合法排序目标与 `--sort-asc` 相同(适用维度 / 时间维度、指标名、泛化结果列名);日期子类型使用与 `--dim` 相同的粒度表达式;未命中返回 `METRIC_UNSUPPORTED_DIMENSION`;与 `--sort-asc` 互斥 |
250
250
  | `--columns strings` | 无 | 只显示指定列,逗号分隔,在 CLI 端执行 |
251
251
  | `--precision int` | `6` | 没有有效指标格式时的数值最大小数位数;传 `-1` 保留原始精度 |
252
252
  | `--value-format string` | `formatted` | `formatted` 按指标格式输出;`raw` 保留原始数值 |
@@ -258,6 +258,8 @@ search/get 的 `data` 使用直接由后端字段构造的 canonical 模型:`i
258
258
 
259
259
  query dry-run 的 `dimensions` 保留用户输入的字符串数组,并额外返回 `resolvedDimensions`。后者是 CLI 最终发送给查询接口的维度对象,可用于确认日期子类型是否解析到了预期的 `fdId`、`fdType=SUB_DATE`、`parentFdName` 和 `granularity`。
260
260
 
261
+ 筛选字段通常必须使用指标详情中的原始字段名。例外是指标详情 `publicDimensionMap` 中能唯一映射到一个适用维度的公共维度名:维度、日期粒度、排序和筛选均可使用该名称,CLI 仍发送物理字段 `fdId`,并在维度 alias 中保留公共维度名;同名映射到多个物理字段时会拒绝猜测。指标名仅作为排序伪字段、没有对应真实字段 `fdId` 时不能筛选;若 `fdInfos` 本身存在同名原始字段和真实 `fdId`,该字段仍可筛选。排序目标只在来自指标详情、当前泛化参数,或保存卡片编辑配置中真实带 `advCalc` 的字段时通过;仅与指标名具有相同前缀不能证明字段有效。dry-run 只读取指标详情,因此不会猜测保存卡片高级计算列有效;真实执行会在修改隔离编辑会话前读取既有卡片编辑配置并校验。
262
+
261
263
  ### 日期子类型维度
262
264
 
263
265
  日期维度可在字段名后增加粒度修饰符:
@@ -202,7 +202,11 @@ guancli metric query <metric_id> --profile default --dim 城市 --rank-top 5 --r
202
202
 
203
203
  ### 泛化结果列的发现与选择
204
204
 
205
- `--recent/--xtd/--compare` 的窗口和展示列名不能互相推导。消费前先读实际 `columns` 和行对象 keys,禁止硬编码展示列名或拼接 `_recent_7d` 等后缀;仅按业务意图确认实际列,不按列顺序或近似名称猜测。列缺失或多个候选同时存在时停止,返回实际列集合。
205
+ `--recent/--xtd/--compare` 的窗口和展示列名不能互相推导。**解析结果**前先读实际 `columns` 和行对象 keys,禁止凭猜测硬编码展示列名;仅按业务意图确认实际列,不按列顺序或近似名称猜测。列缺失或多个候选同时存在时停止,返回实际列集合。
206
+
207
+ **排序是例外**:`--sort-asc`/`--sort-desc` 可以直接用推导出的结果列名 `<指标名>_<后缀>`(`_yoy`/`_mom`/`_qoq`/`_wow`/`_dod`/`_ytd`/`_qtd`/`_mtd`/`_wtd`/`_dtd`/`_last`/`_recent_*`/`_percentage`/`_rank`)作为排序目标,CLI 的排序白名单接受它(实测 `_yoy`、`_percentage` 与实际响应列名一致)。这类列只存在于响应中、不在指标详情里,因此不要拿它去 `--filter` 或 `--dim`;两者仍只接受指标详情中的字段,未命中会返回 `METRIC_UNSUPPORTED_DIMENSION`(结构化筛选为 `FILTER_UNKNOWN_FIELD`)。
208
+
209
+ 若指标详情返回 `publicDimensionMap`,并且某个公共维度名只对应一个适用物理字段,则 `--dim`、日期粒度表达式、排序和筛选都可直接使用公共维度名。请求仍使用物理 `fdId`,维度 alias 保留公共维度名;同名公共维度对应多个物理字段时 CLI 会报歧义,不会任选一个字段。
206
210
 
207
211
  复用 [查询结果消费 recipe](metric-commands.md#查询结果消费):成功取得 `-f json` envelope 后,用 `python3 references/examples/metric-query-rows.py query-envelope.json --list-columns` 发现列,再用 `--column "<已确认的实际列名>"` 精确选择。这些是 Python recipe 参数,不是 query 参数。inline/file 分支、失败时保留 stderr 和停止解析沿用同一 recipe。
208
212