@qingflow-tech/qingflow-cli 1.1.48-beta.3 → 1.1.48-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ Qingflow CLI 是轻流面向开发者和 AI Agent 的命令行工具。它把轻
7
7
  ## 安装
8
8
 
9
9
  ```bash
10
- npm install @qingflow-tech/qingflow-cli@1.1.48-beta.3
10
+ npm install @qingflow-tech/qingflow-cli@1.1.48-beta.4
11
11
  ```
12
12
 
13
13
  推荐从官网复制这一条一键安装 Qingflow CLI:
@@ -21,7 +21,7 @@ npx qingflow-cli@latest install
21
21
  ## 运行
22
22
 
23
23
  ```bash
24
- npx -y -p @qingflow-tech/qingflow-cli@1.1.48-beta.3 qingflow
24
+ npx -y -p @qingflow-tech/qingflow-cli@1.1.48-beta.4 qingflow
25
25
  ```
26
26
 
27
27
  全局安装后可以直接运行:
@@ -62,7 +62,7 @@ qingflow-skills install --agent codex --scope user
62
62
  如果你通过一次性 `npx -p` 执行 skills 安装,建议加 `--copy`,避免 symlink 指向 npm 临时执行缓存:
63
63
 
64
64
  ```bash
65
- npx -y -p @qingflow-tech/qingflow-cli@1.1.48-beta.3 qingflow-skills install --agent codex --scope user --copy
65
+ npx -y -p @qingflow-tech/qingflow-cli@1.1.48-beta.4 qingflow-skills install --agent codex --scope user --copy
66
66
  ```
67
67
 
68
68
  `qingflow-skills install` 默认使用 symlink,且遇到同名 skill 不会覆盖;只有显式传入 `--force` 才会替换。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qingflow-tech/qingflow-cli",
3
- "version": "1.1.48-beta.3",
3
+ "version": "1.1.48-beta.4",
4
4
  "description": "Human-friendly Qingflow command line interface for auth, record operations, import, tasks, and stable builder flows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qingflow-mcp"
7
- version = "1.1.48b3"
7
+ version = "1.1.48b4"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -9,13 +9,13 @@ description: |
9
9
 
10
10
  > **Skill 版本**:`qingflow-skills-2026.09.22.01`。CLI 实际版本与安装路径以 `qingflow --json version` 为准。
11
11
 
12
- 选择 CLI 或 MCP 前先读 [$qingflow-common](../qingflow-common/SKILL.md)。本 Skill 只负责 CLI 入口、文件约定和业务分流;字段能力、权限范围与参数形状以当前 `--help`、data schema 和实际响应为准。
12
+ 本 Skill 负责 CLI 入口、文件约定和业务分流。已知 `app_key` 时直接执行 `data query/get`;字段能力、权限范围与下一步动作以当前工具 schema、data 响应和 `hints` 为准。
13
13
 
14
14
  ## CLI 执行与 JSON 落盘
15
15
 
16
16
  1. 已知业务目标时直接执行目标命令,不固定前置 `auth whoami`、`workspace get` 或 `workspace select`。只有业务命令明确返回未登录、会话失效或工作区错误后,才恢复上下文并重试原命令。
17
17
  2. 自动化始终使用 `--json`。`data query/get`、task 查询、record 日志/附件上下文、import 与 builder 大响应必须写入本地文件,禁止把整段 JSON 或 CSV 打到上下文。
18
- 3. `where`、`sort`、`columns`、`items`、`fields` 等结构化参数写入独立 JSON 文件,再通过 `--*-file` 传入。参数名和 JSON 形状以当前子命令 `--help` 和对应响应为准。
18
+ 3. `where`、`sort`、`columns`、`items`、`fields` 等结构化参数写入独立 JSON 文件,再通过 `--*-file` 传入。工具已暴露参数 schema 时直接使用;只有命令缺失或参数被拒绝时才读取对应 `--help`。
19
19
  4. 多任务或目录可能变化时使用绝对路径;单线程本地执行至少先固定 `pwd`。解析时只读取目标字段,不要 `cat` 大文件。
20
20
  5. `--json` 模式的业务错误通常也在 stdout JSON 信封中;stderr 主要用于 argparse usage。写命令返回已执行、部分成功或状态不明时,不得重放原请求。
21
21
 
@@ -46,8 +46,8 @@ echo "$QINGFLOW_CREDENTIAL" | qingflow --profile default auth use-credential \
46
46
  | 待办、已办、抄送、审批、转交或退回 | `qingflow task ...` | [任务上下文 SOP](./reference/task/QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md) |
47
47
  | Excel 模板、文件校验、修复、启动导入与状态 | `qingflow import ...` / `record schema import` | [批量导入 SOP](./reference/record/QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md) |
48
48
  | 应用、表单、字段、视图、报表、门户与流程搭建 | `qingflow builder ...` | [Builder 总导航](./reference/builder/README.md) |
49
- | 完整数据/流程日志 | `qingflow record logs` | [record 专项参考](./reference/record/QINGFLOW_CLI_LEGACY_RECORD_RETRIEVAL_WORKFLOW.md) |
50
- | 附件、图片与详情页上下文 | `qingflow record get` | [record 专项参考](./reference/record/QINGFLOW_CLI_LEGACY_RECORD_RETRIEVAL_WORKFLOW.md) |
49
+ | 完整数据/流程日志 | `qingflow record logs` | [record 专项参考](./reference/record/QINGFLOW_CLI_RECORD_SPECIALIZED_WORKFLOW.md) |
50
+ | 附件、图片与详情页上下文 | `qingflow record get` | [record 专项参考](./reference/record/QINGFLOW_CLI_RECORD_SPECIALIZED_WORKFLOW.md) |
51
51
  | 代码块字段执行 | `qingflow record code-block-run` | [代码集成说明](./reference/builder/code-integrations/README.md) |
52
52
  | 安装、版本或命令能力确认 | `qingflow --json version` / `qingflow ... --help` | [命令索引](./reference/00-INDEX.md) |
53
53
 
@@ -97,7 +97,7 @@ qingflow --json data query \
97
97
 
98
98
  ### 分页
99
99
 
100
- 先请求第一页;仅当响应 `records.has_more=true` 时增加 `--page`。同时读取 `hints`,若提示收窄范围、调整参数或停止继续,则按提示处理,不凭总数猜页数。
100
+ 先请求第一页,并按响应 `hints` 执行:`RESULT_IS_PARTIAL` 时保持筛选与排序继续下一页,`RESULT_IS_COMPLETE` 时立即停止;不凭总数猜页数。
101
101
 
102
102
  ```bash
103
103
  qingflow --json data query --app-key APP_KEY --page 1 --page-size 100 \
@@ -132,11 +132,11 @@ qingflow --json data query \
132
132
  - 导出/下载只有用户明确需要文件时才使用,并按对应命令要求提供视图上下文;不要把导出当作普通查询或统计分析默认入口。
133
133
  - 查看视图时,`baseInfo` 或 `viewConfig` 只有 40002 / 40027 / 404 这类权限/缺失边界可用另一侧降级,非权限类后端错误不隐藏;完整规则见 Builder 视图文档。
134
134
 
135
- ## record 专项与显式命令
135
+ ## record 专项
136
136
 
137
- `record` 用于完整数据/流程日志、附件和图片上下文、代码块字段执行、导入专项,以及用户明确指定 `record` 命令的场景。
137
+ `record` 用于完整数据/流程日志、附件和图片上下文、代码块字段执行,以及用户指定的 `record` 操作。
138
138
 
139
- 普通应用数据默认使用 `data`。不得在 data 失败后自动改用 `record list/access/get/insert/update/delete` 绕过权限或校验。用户明确指定 `record` 查询时阅读 [record 专项参考](./reference/record/QINGFLOW_CLI_LEGACY_RECORD_RETRIEVAL_WORKFLOW.md);`record delete` 提交不要传 `custom:*`、`list_type`,细则见 [record 删除参考](./reference/record/QINGFLOW_CLI_RECORD_DELETE_WORKFLOW.md)。
139
+ 普通应用数据使用 `data`。不得改用 `record list/access/get/insert/update/delete` 绕过 data 返回的权限、字段能力或校验结果。日志与附件操作阅读 [record 专项参考](./reference/record/QINGFLOW_CLI_RECORD_SPECIALIZED_WORKFLOW.md);`record delete` 提交不要传 `custom:*`、`list_type`,细则见 [record 删除参考](./reference/record/QINGFLOW_CLI_RECORD_DELETE_WORKFLOW.md)。
140
140
 
141
141
  ## 关联入口
142
142
 
@@ -146,6 +146,6 @@ qingflow --json data query \
146
146
  - [批量导入 SOP](./reference/record/QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md)
147
147
  - [数据分析说明](./reference/record/analysis/README.md)
148
148
  - [Builder 总导航](./reference/builder/README.md)
149
- - [record 专项参考](./reference/record/QINGFLOW_CLI_LEGACY_RECORD_RETRIEVAL_WORKFLOW.md)
149
+ - [record 专项参考](./reference/record/QINGFLOW_CLI_RECORD_SPECIALIZED_WORKFLOW.md)
150
150
 
151
151
  维护时用 `qingflow --json version`、`qingflow data --help` 与对应专项 `--help` 复核,不根据历史文档补造参数。
@@ -2,4 +2,4 @@
2
2
 
3
3
  普通应用数据查询默认使用 `data query/get`。完整流程、JSON 形状、分页与分析边界见 [core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md](./core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md)。
4
4
 
5
- 用户明确指定 `record` 查询命令,或需要日志、附件和图片上下文时,使用 [record 专项参考](./record/QINGFLOW_CLI_LEGACY_RECORD_RETRIEVAL_WORKFLOW.md)。
5
+ 需要完整日志、附件和图片上下文时,使用 [record 专项参考](./record/QINGFLOW_CLI_RECORD_SPECIALIZED_WORKFLOW.md)。
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **用途**:使用视图无关的 `data query/get` 完成普通应用数据查询、筛选、排序、分页和单条读取。
4
4
  > **边界**:本文只给流程与 JSON 形状;操作符、字段类型、权限范围和动态限制以当前 `--help`、`schema`、`field_capabilities`、`access` 与 `hints` 为准。
5
- > **record 专项**:用户明确指定 `record` 命令,或需要完整日志、附件/图片上下文时,阅读 [record 专项参考](../record/QINGFLOW_CLI_LEGACY_RECORD_RETRIEVAL_WORKFLOW.md)。
5
+ > **record 专项**:需要完整日志、附件/图片上下文时,阅读 [record 专项参考](../record/QINGFLOW_CLI_RECORD_SPECIALIZED_WORKFLOW.md)。
6
6
 
7
7
  ## 推荐顺序
8
8
 
@@ -8,7 +8,7 @@
8
8
  - `qingflow data update`
9
9
  - `qingflow data delete`
10
10
 
11
- 参数、JSON 文件形状和可选项必须来自当次 `--help` 或工具返回的 schema,不得根据旧 `record` 命令猜测。
11
+ 参数、JSON 文件形状和可选项必须来自当前工具 schema、当次 `--help` 或响应字段能力,不得从其他命令推测。
12
12
 
13
13
  ## 字段能力合同
14
14
 
@@ -23,7 +23,7 @@
23
23
  - 定位目标记录时先 query,再按需 get。字段只使用当前 schema 与字段能力允许的 id、能力和形状。
24
24
  - insert、update、delete 会改变真实业务数据。删除、覆盖已有值或批量写入前,必须确认目标和影响范围。
25
25
  - 返回后先检查 `write_executed`、`retry_safe`、字段错误和 hints。已执行、部分成功或状态不明时不得重放原请求。
26
- - data 命令失败时只修正响应明确指出的问题,不得自动回退旧 `record` 写入链路绕过权限或校验。
26
+ - data 命令失败时只修正响应明确指出的问题,不得切换其他数据入口绕过权限或校验。
27
27
 
28
28
  ## 任务分流
29
29
 
@@ -1,6 +1,6 @@
1
- # Qingflow CLI:record 专项与显式命令参考
1
+ # Qingflow CLI:record 日志与附件参考
2
2
 
3
- > **适用范围**:用户明确指定 `record` 命令,或任务需要完整数据/流程日志、附件和图片上下文时使用。普通应用数据查询使用 [`data query/get`](../core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md),不得在 data 失败后自动改用本文链路。
3
+ > **适用范围**:任务需要完整数据/流程日志、附件或图片上下文时使用。普通应用数据查询使用 [`data query/get`](../core/QINGFLOW_CLI_DATA_RETRIEVAL_WORKFLOW.md)。
4
4
 
5
5
  ## record 查询链
6
6
 
@@ -207,6 +207,8 @@ class DataTools(ToolBase):
207
207
  "ok": True, "status": "needs_scope", "app_key": app_key, "format": "csv", "row_count": 0,
208
208
  "complete": False, "truncated": True, "safe_for_final_conclusion": False, "files": [],
209
209
  "hints": probe.get("hints", []),
210
+ "schema": probe.get("schema", {}),
211
+ "field_capabilities": probe.get("field_capabilities", []),
210
212
  "scope": {"reported_total": total, "row_threshold": DATA_UNBOUNDED_ROW_THRESHOLD},
211
213
  }, profile, ws_id)
212
214
  schema = probe.get("schema") if isinstance(probe.get("schema"), dict) else {}
@@ -216,15 +218,25 @@ class DataTools(ToolBase):
216
218
  columns = [(str(field.get("field_id")), str(field.get("title") or field.get("field_id"))) for field in business_fields]
217
219
  header = ["record_id"] + [f"{title}__field_{field_id}" for field_id, title in columns]
218
220
  run_dir = Path.home() / ".qingflow" / "data-exports" / datetime.now().strftime("%Y%m%d-%H%M%S-%f")
221
+ latest_hints = probe.get("hints", [])
222
+ latest_schema = schema
223
+ latest_capabilities = probe.get("field_capabilities", [])
219
224
 
220
225
  def fetch_page(page: int, page_size: int) -> JSONObject:
226
+ nonlocal latest_hints, latest_schema, latest_capabilities
221
227
  request_body = dict(body)
222
- request_body.update({"page": page, "page_size": page_size, "include_schema": page == 1})
228
+ # 每页都请求 schema,使最后一页的后端原始 hints 同时准确表达完整性和字段能力。
229
+ request_body.update({"page": page, "page_size": page_size, "include_schema": True})
223
230
  response = self._request_data_plane(
224
231
  context, "POST", self._base_path(app_key) + "/query", json_body=request_body
225
232
  )
226
233
  if response.get("ok") is False:
227
234
  raise CsvPageFailure(response)
235
+ latest_hints = response.get("hints", [])
236
+ if isinstance(response.get("schema"), dict):
237
+ latest_schema = response["schema"]
238
+ if isinstance(response.get("field_capabilities"), list):
239
+ latest_capabilities = response["field_capabilities"]
228
240
  return response
229
241
 
230
242
  def project_row(record: JSONObject) -> list[str]:
@@ -239,7 +251,8 @@ class DataTools(ToolBase):
239
251
  page_error = exported.pop("page_error", None)
240
252
  result: JSONObject = {
241
253
  "ok": True, "status": "success" if exported["complete"] else "partial", "app_key": app_key,
242
- "format": "csv", "local_dir": str(run_dir), "fields": business_fields, "hints": probe.get("hints", []),
254
+ "format": "csv", "local_dir": str(run_dir), "fields": business_fields,
255
+ "schema": latest_schema, "field_capabilities": latest_capabilities, "hints": latest_hints,
243
256
  **exported,
244
257
  }
245
258
  if isinstance(page_error, dict):