@qingflow-tech/qingflow-cli 1.1.45-beta.2 → 1.1.45-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.45-beta.
|
|
10
|
+
npm install @qingflow-tech/qingflow-cli@1.1.45-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.45-beta.
|
|
24
|
+
npx -y -p @qingflow-tech/qingflow-cli@1.1.45-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.45-beta.
|
|
65
|
+
npx -y -p @qingflow-tech/qingflow-cli@1.1.45-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.45-beta.
|
|
3
|
+
"version": "1.1.45-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
|
@@ -444,7 +444,7 @@ qingflow auth logout --forget-persisted
|
|
|
444
444
|
| **app / portal / view / chart** | `app list [--query 关键词]` → **`app get --app-key`**(`accessible_views` / `view_id`、`import_capability`)· `builder package list [--query 关键词]` → `builder package get --package-id` · `portal list` · `portal get --dash-key` · `view get --view-id`(只读视图元信息;`baseInfo` 或 `viewConfig` 只有 40002 / 40027 / 404 这类权限/缺失边界可用另一侧降级,非权限类后端错误不隐藏;解析 app 仅依赖同源 view/form 与可见应用树,不回退旧应用搜索)· `chart get --chart-id`(图表 `baseInfo` / 数据 / 配置分阶段读取;单个辅助阶段 40002 / 40027 / 404 只作为 warning,非权限类后端错误不隐藏) |
|
|
445
445
|
| **record** | `record schema insert`(新建记录 insert-ready schema,仅 `--app-key`)· **`browse`/`list`/`access`:`--app-key` + `--view-id`(缺一常 CONFIG)** · `record list --query ... [--query-field FIELD_ID] [--page-size N]` 用于候选定位/样本浏览 · `record get --record-id` 读详情页首屏上下文 · `record logs --record-id` 读完整数据/流程日志 JSONL · `record insert --items-file`(单条也是 items 一行)· `schema update --record-id [--view-id]` / **`update`**(单条 `--fields-file` **或** 批量 `--items-file`/`--dry-run`,二者勿混)· `record delete --app-key --record-id --view-id system:*` / `--record-ids-file` · `export start/direct --view-id` 仅用于明确导出文件 · **大 schema**:先 **[FIELD_DATA_TYPES](./reference/core/QINGFLOW_CLI_FIELD_DATA_TYPES.md)** / **[RECORD_CREATE](./reference/record/QINGFLOW_CLI_RECORD_CREATE_WORKFLOW.md)** / **[RECORD_UPDATE](./reference/record/QINGFLOW_CLI_RECORD_UPDATE_WORKFLOW.md)** / **[RECORD_DELETE](./reference/record/QINGFLOW_CLI_RECORD_DELETE_WORKFLOW.md)**,再 `-h` |
|
|
446
446
|
| **import** | `record schema import?` · `import template` → `verify` → `repair?` → `start`(**`being-enter-auditing` 必填**)→ `status`(**三者 selector 只选一**);导入权限预检的 `baseInfo` 只有 40002 / 40027 / 404 可降级为 unknown,非权限错误不能当成无导入权或继续执行;**链路与本机目录**只靠本节不够 → **[RECORD_IMPORT](./reference/record/QINGFLOW_CLI_RECORD_IMPORT_WORKFLOW.md)** |
|
|
447
|
-
| **builder** | **搭建/系统化配置**:先按 **[INDEX](./reference/00-INDEX.md)** / **[BUILDER](./reference/builder/README.md)** 选主路径,再读 `builder contract`。**完整系统/应用包**:`builder package apply --config-file` → 每个应用依次执行 `builder app-form schema`、更新时 `get --app-key APP_KEY --being-draft`、`validate --schema-version VERSION --file DECLARATION.json`、`apply --file DECLARATION.json`(固定版本、完整声明、记录返回的 `appKey`)→ 视图(按钮随视图 `action_buttons` 写)→ 门户(缺报表时写 `chart`)→ 发布/回读。旧 `schema apply` / `layout apply` 不在当前 CLI parser 中。超时、`partial_success`、`write_executed=true`、`safe_to_retry=false` 或回读不完整时先读取 AppForm draft/published,再恢复,不得重复创建或创建 V2/测试/随机后缀绕过重名。**单应用**:新建和更新遵循同一 AppForm CLI 链路,再按需求配置流程/视图。更新动作归入对应资源文档:AppForm [30](./reference/builder/30-schema-fields.md)、视图 [50](./reference/builder/50-views.md)、报表 [60](./reference/builder/60-charts.md)、门户 [70](./reference/builder/70-portal.md)、关联资源/非主链路按钮维护 [80](./reference/builder/80-buttons-associated-resources.md)、流程 [90](./reference/builder/90-workflow.md)、发布 [99](./reference/builder/99-publish-verify.md)
|
|
447
|
+
| **builder** | **搭建/系统化配置**:先按 **[INDEX](./reference/00-INDEX.md)** / **[BUILDER](./reference/builder/README.md)** 选主路径,再读 `builder contract`。**完整系统/应用包**:`builder package apply --config-file` → 每个应用依次执行 `builder app-form schema`、更新时 `get --app-key APP_KEY --being-draft`、`validate --schema-version VERSION --file DECLARATION.json`、`apply --file DECLARATION.json`(固定版本、完整声明、记录返回的 `appKey`)→ 视图(按钮随视图 `action_buttons` 写)→ 门户(缺报表时写 `chart`)→ 发布/回读。旧 `schema apply` / `layout apply` 不在当前 CLI parser 中。超时、`partial_success`、`write_executed=true`、`safe_to_retry=false` 或回读不完整时先读取 AppForm draft/published,再恢复,不得重复创建或创建 V2/测试/随机后缀绕过重名。**单应用**:新建和更新遵循同一 AppForm CLI 链路,再按需求配置流程/视图。更新动作归入对应资源文档:AppForm [30](./reference/builder/30-schema-fields.md)、视图 [50](./reference/builder/50-views.md)、报表 [60](./reference/builder/60-charts.md)、门户 [70](./reference/builder/70-portal.md)、关联资源/非主链路按钮维护 [80](./reference/builder/80-buttons-associated-resources.md)、流程 [90](./reference/builder/90-workflow.md)、发布 [99](./reference/builder/99-publish-verify.md)。 |
|
|
448
448
|
| **task**(须落盘见上文) | `task list [--task-box][--flow-status][--app-key][--query] --page --page-size`(**枚举、`--query`、与 `record` 视图口径勿混**:见上文 SOP · **[TASK_CONTEXT](./reference/task/QINGFLOW_CLI_TASK_CONTEXT_WORKFLOW.md)**)· **`get`/`log`/`report`/`action`**:默认只传 `task list` 返回的 **`data.items[].task_id`**;`report` 另须必选 **`--report-id`**;`action` **无 `--dry-run`** |
|
|
449
449
|
|
|
450
450
|
**高发必败**:旧应用搜索入口 · **`record list`/`browse`/`access` 缺 `--view-id`** · **`task report` 缺 `--report-id`** · **`record update` 批量与单条参数混用**。
|
|
@@ -541,53 +541,3 @@ def validate_code_block_static(code: str) -> list[dict[str, str]]:
|
|
|
541
541
|
}
|
|
542
542
|
)
|
|
543
543
|
return errors
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
# ---------------------------------------------------------------------------
|
|
547
|
-
# 代码块字段占位符编码
|
|
548
|
-
#
|
|
549
|
-
# 后端 codeBlockTest 运行时通过 CustomPushContentConverter.getQueId 解码代码里的
|
|
550
|
-
# ``qf_field.{label$$<encoded>$$}`` 段(私有混淆编码,非十进制),再按解码出的十进制
|
|
551
|
-
# queId 匹配 --test-case 的 keyQueId 填值;匹配不上会静默跳过(占位符原样留跑)。
|
|
552
|
-
# AI 生成的代码按十进制 queId 书写(与 skill/编辑器上下文一致),本模块在真跑前把
|
|
553
|
-
# 纯数字的 ``$$<digits>$$`` 段编码为运行时形态——与后端采纳链路(encryptQueId)同一
|
|
554
|
-
# 编码、同一"纯数字才编码"规则,已编码(含字母)的段原样保留,避免双重编码。
|
|
555
|
-
# ---------------------------------------------------------------------------
|
|
556
|
-
|
|
557
|
-
_ENC_KEY = 1000013
|
|
558
|
-
_INT_TO_HEX = "0123456789ABCDEF"
|
|
559
|
-
_DECIMAL_PLACEHOLDER = re.compile(r"\$\$(-?\d+)\$\$")
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
def encode_que_id(que_id: int) -> str:
|
|
563
|
-
"""Java ``CustomPushContentConverter.encryptQueId`` 的逐行为等价移植。"""
|
|
564
|
-
have_prefix = que_id < 0
|
|
565
|
-
abs_id = abs(que_id)
|
|
566
|
-
ran = abs_id * 17
|
|
567
|
-
inp = str(abs_id)
|
|
568
|
-
seeds: list[int] = []
|
|
569
|
-
salt_sum = 0
|
|
570
|
-
for _ in range(max(0, 4 - len(inp))):
|
|
571
|
-
tmp = (ran % 20) + 71
|
|
572
|
-
ran = ((ran + 13) * 17) % _ENC_KEY
|
|
573
|
-
salt_sum += tmp
|
|
574
|
-
seeds.append(tmp)
|
|
575
|
-
result = [(salt_sum + i + int(ch, 16)) % 15 for i, ch in enumerate(inp)]
|
|
576
|
-
for seed in seeds:
|
|
577
|
-
pos = (ran + seed) % len(result)
|
|
578
|
-
ran = ((ran + 13) * 17) % _ENC_KEY
|
|
579
|
-
result.insert(pos, seed)
|
|
580
|
-
encoded = "".join(chr(value) if value > 15 else _INT_TO_HEX[value] for value in result)
|
|
581
|
-
return ("-" if have_prefix else "") + encoded
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
def encode_code_block_field_ids(code: str) -> str:
|
|
585
|
-
"""把代码里的十进制 queId 占位符段编码为后端运行时形态。
|
|
586
|
-
|
|
587
|
-
仅处理纯数字(可带负号)的 ``$$...$$`` 段;混有字母的段视为已编码,原样保留。
|
|
588
|
-
"""
|
|
589
|
-
if not isinstance(code, str):
|
|
590
|
-
return code
|
|
591
|
-
return _DECIMAL_PLACEHOLDER.sub(
|
|
592
|
-
lambda match: f"$${encode_que_id(int(match.group(1)))}$$", code
|
|
593
|
-
)
|
|
@@ -7,7 +7,6 @@ from pathlib import Path
|
|
|
7
7
|
from ..context import CliContext
|
|
8
8
|
from ...app_form_validator import (
|
|
9
9
|
AppFormValidationError,
|
|
10
|
-
encode_code_block_field_ids,
|
|
11
10
|
validate_code_block_static,
|
|
12
11
|
validate_declaration,
|
|
13
12
|
validate_formula_expression,
|
|
@@ -474,9 +473,6 @@ def _handle_app_form_validate_formula(args: argparse.Namespace, context: CliCont
|
|
|
474
473
|
|
|
475
474
|
def _handle_app_form_validate_code_block(args: argparse.Namespace, context: CliContext) -> dict:
|
|
476
475
|
code = _read_code_arg(args.code)
|
|
477
|
-
# 后端运行时按 encryptQueId 的编码形态解码代码里的 $$id$$ 段再匹配 test-case 填值;
|
|
478
|
-
# AI 生成的代码是十进制 queId,先编码归一化(含字母的已编码段原样保留,防双重编码)。
|
|
479
|
-
code = encode_code_block_field_ids(code)
|
|
480
476
|
test_case = load_json_value(
|
|
481
477
|
args.test_case, option_name="--test-case", max_bytes=1 * 1024 * 1024, max_depth=32
|
|
482
478
|
)
|