@finebi/finebi-cli 1.6.1 → 1.6.3
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 +8 -8
- package/package.json +1 -1
- package/skills/finebi-cli-agent/SKILL.md +43 -123
- package/skills/finebi-cli-agent/agents/openai.yaml +1 -1
- package/skills/finebi-cli-agent/references/artifact-ordering.md +3 -3
- package/skills/finebi-cli-agent/references/command-workflows.md +30 -1
- package/skills/finebi-cli-agent/references/dsl-handoff-contract.md +1 -1
- package/skills/finebi-cli-agent/references/handoff-contract.md +6 -4
- package/skills/finebi-cli-agent/references/mutation-confirmation-contract.md +2 -0
- package/skills/finebi-cli-agent/references/scenario-workflows.md +10 -8
- package/skills/finebi-cli-agent/references/web-app.md +4 -2
- package/skills/finebi-cli-agent/references/widget-dsl-core.md +6 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/package.json +1 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/app.js +18 -6
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/browser-auth.js +3 -4
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/config.js +1 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/error-catalog.js +2 -2
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/help.js +8 -5
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/AGENTS.md +18 -5
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/README.md +12 -5
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/acceptance.md +14 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/auth-and-deploy.md +17 -2
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/data-contract.md +66 -38
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/filters.md +2 -2
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/gitignore.template +6 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/scripts/browser-session.mjs +59 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/scripts/dev-proxy.mjs +25 -24
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/scripts/dev-session.mjs +57 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/scripts/session-file.mjs +45 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/App.tsx +8 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/DataTable.tsx +1 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/Widget.tsx +1 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/client.ts +20 -4
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/config.d.ts +2 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/config.js +15 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/normalize.ts +159 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/types.ts +8 -6
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/retail.css +1 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/field-selection.test.mjs +70 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/proxy.test.mjs +20 -5
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/runtime.test.mjs +7 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/session.test.mjs +91 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/table-normalize.test.mjs +189 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/vite-auth.test.mjs +41 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/vite.config.ts +9 -4
- package/src/app.js +18 -6
- package/src/browser-auth.js +3 -4
- package/src/config.js +1 -1
- package/src/error-catalog.js +2 -2
- package/src/help.js +8 -5
- package/templates/web-app/AGENTS.md +18 -5
- package/templates/web-app/README.md +12 -5
- package/templates/web-app/docs/acceptance.md +14 -1
- package/templates/web-app/docs/auth-and-deploy.md +17 -2
- package/templates/web-app/docs/data-contract.md +66 -38
- package/templates/web-app/docs/filters.md +2 -2
- package/templates/web-app/gitignore.template +6 -0
- package/templates/web-app/scripts/browser-session.mjs +59 -0
- package/templates/web-app/scripts/dev-proxy.mjs +25 -24
- package/templates/web-app/scripts/dev-session.mjs +57 -0
- package/templates/web-app/scripts/session-file.mjs +45 -0
- package/templates/web-app/src/App.tsx +8 -1
- package/templates/web-app/src/components/DataTable.tsx +1 -1
- package/templates/web-app/src/components/Widget.tsx +1 -0
- package/templates/web-app/src/finebi/client.ts +20 -4
- package/templates/web-app/src/finebi/config.d.ts +2 -0
- package/templates/web-app/src/finebi/config.js +15 -1
- package/templates/web-app/src/finebi/normalize.ts +159 -1
- package/templates/web-app/src/finebi/types.ts +8 -6
- package/templates/web-app/src/retail.css +1 -1
- package/templates/web-app/tests/field-selection.test.mjs +70 -0
- package/templates/web-app/tests/proxy.test.mjs +20 -5
- package/templates/web-app/tests/runtime.test.mjs +7 -0
- package/templates/web-app/tests/session.test.mjs +91 -0
- package/templates/web-app/tests/table-normalize.test.mjs +189 -0
- package/templates/web-app/tests/vite-auth.test.mjs +41 -0
- package/templates/web-app/vite.config.ts +9 -4
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ finebi-cli app create --name sales-dashboard --path D:\work --layout cockpit
|
|
|
48
48
|
finebi-cli app inspect --path D:\work\sales-dashboard
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
`app create` copies the bundled `web-app` template, sets the project npm name, and records the template version in `public/app-config.json`. It rejects an existing destination and does not install dependencies or run project scripts. `app inspect`
|
|
51
|
+
`app create` copies the bundled `web-app` template, sets the project npm name, and records the template version in `public/app-config.json`. It rejects an existing destination and does not install dependencies or run project scripts. `app inspect` reads a JSON object and reports a configuration summary with `configValidated: false` and `remoteValidated: false`. Optional `--strict` validates against the CLI bundled template rules, which may not match custom app extensions. Inspection is not an acceptance gate; use the generated project tests, build and real browser checks to verify the application.
|
|
52
52
|
|
|
53
53
|
`--layout` accepts `overview` (default), `workbench`, or the green `cockpit` layout. Cockpit shares the existing Cookie query and authentication flow, with configurable KPI/chart/table bindings, independent retries, and a custom month picker. The generated README and `examples/cockpit.config.json` describe the placeholder bindings; no business data or credentials are bundled. Published sources require `directoryEntryId` and a platform HTTP endpoint that supports directory permissions; failed queries never switch sources.
|
|
54
54
|
|
|
@@ -105,13 +105,13 @@ Existing single-environment configuration is exposed as `default`; read-only com
|
|
|
105
105
|
|
|
106
106
|
## Access Key
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
Password login issues a long-lived Access Key by default; browser authorization saves the Key received after approval. Business commands prefer `X-BI-CLI-Access-Key`, then fall back to the session token. The server also accepts `X-FineBI-CLI-Access-Key` as a compatibility alias.
|
|
109
109
|
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
- Add `--no-access-key` to password login to keep only the session token. Password login replaces old Keys with the same machine/profile description; browser authorization does not automatically remove existing Keys.
|
|
111
|
+
- `auth info` shows `authMode` (`access-key` / `session-token` / `none`) with credentials masked.
|
|
112
|
+
- `auth logout` revokes the saved Key before clearing local credentials, even after the JWT expires. Failed revocation preserves credentials for retry; `--force` permits local cleanup without confirmed server revocation.
|
|
113
|
+
|
|
114
|
+
The [authentication contract](../docs/commands/README.md#access-key-行为) defines issuance, profile descriptions, headers, compatibility and failure behavior. Local credential storage is described under [Local Files](#local-files).
|
|
115
115
|
|
|
116
116
|
```powershell
|
|
117
117
|
finebi-cli auth login --username 1
|
|
@@ -267,4 +267,4 @@ Multi-environment `config.json` stores `schemaVersion: 2`, `currentProfile` (nul
|
|
|
267
267
|
|
|
268
268
|
Concurrent logins to the same environment are rejected using `config.json.login-<hex-encoded-name>.lock`; different environments may log in concurrently. Locks are released when the operation settles. If a process is forcibly terminated and leaves a lock behind, verify that the owning operation has stopped before manually removing that lock file.
|
|
269
269
|
|
|
270
|
-
Passwords are not persisted by the CLI.
|
|
270
|
+
Passwords are not persisted by the CLI. Saved session tokens and Access Keys remain usable credential values in `config.json`; they are not encrypted at rest. On POSIX, the CLI restricts the directory to `0700` and the file to `0600`. On Windows, it attempts to remove inherited ACLs and grant access to the current user, SYSTEM and Administrators; failures emit a security warning. Protect this directory and its backups.
|
package/package.json
CHANGED
|
@@ -1,137 +1,57 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: finebi-cli-agent
|
|
3
|
-
description: 使用 FineBI CLI
|
|
3
|
+
description: 使用 FineBI CLI 查询和管理资源、生成组件与仪表板 DSL,或创建连接 FineBI 的动态 HTML 看板和数据 Web 应用。适用于 FineBI 数据、公式、图表、看板及 CLI 连接认证任务。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# FineBI CLI Agent
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
优先使用本 Skill 内置的 CLI 完成 FineBI 资源发现、读取、DSL 制品生成和安全写入,也允许使用通过 npm 安装的全局 `@finebi/finebi-cli`。不得依赖原始源码仓库,也不得调用仓库外的另一项 FineBI Skill 才能完成主流程。
|
|
11
|
-
|
|
12
|
-
## 运行前提
|
|
13
|
-
|
|
14
|
-
- 使用 Node.js 18.17 或更高版本。
|
|
15
|
-
- 确认目标 FineBI 已部署与所选 CLI 兼容的 `plugin-bi-finebi-cli` 服务端插件。
|
|
16
|
-
- 确认 Agent 能访问目标 FineBI HTTP(S) 地址,并能在用户目录写入 `.finebi-cli` 配置。
|
|
17
|
-
- 将包含本文件的目录记为 `<skill-dir>`。所有脚本均使用 `<skill-dir>` 的绝对路径调用,不根据当前工作目录猜测位置。
|
|
18
|
-
|
|
19
|
-
## 按需读取参考
|
|
20
|
-
|
|
21
|
-
- 生成动态 HTML 页面或数据 Web 应用时,读取 [应用模板工作流](references/web-app.md),通过本地 app create 创建工程,再遵循项目 AGENTS.md。
|
|
22
|
-
|
|
23
|
-
- 首次处理业务命令时,读取 [命令工作流](references/command-workflows.md) 的公共约束和目标命令族章节。
|
|
24
|
-
- 包含非只读动作时,读取 [变更计划与删除确认契约](references/mutation-confirmation-contract.md) 的计划、复检和验证规则;包含 `delete` 或失败清理时再读对应章节。
|
|
25
|
-
- 规划 Widget/Dashboard 时按当前场景读取 [场景工作流](references/scenario-workflows.md);构造或消费交接对象时读取 [语义交接契约](references/handoff-contract.md) 和 [DSL 输入契约](references/dsl-handoff-contract.md) 的公共结构及当前场景字段。
|
|
26
|
-
- 生成 Widget DSL 时,读取 [映射规则](references/mapping-rules.md),并按需读取 [Widget DSL API](references/widget-dsl-api.md) 导航的拆分文件,不一次加载全部:写组件前读 [widget-dsl-core.md](references/widget-dsl-core.md)(根入口/字段工厂/Builder);配置图表类型与通道编码读 [widget-dsl-encodings.md](references/widget-dsl-encodings.md);调整样式、视觉通道、轴或排序读 [widget-dsl-styles.md](references/widget-dsl-styles.md);配置过滤、配色、数值格式或查枚举读 [widget-dsl-contexts.md](references/widget-dsl-contexts.md)。
|
|
27
|
-
- 需要可运行的推荐写法示例(分区折线/双轴/表格属性等)时,读取 [Widget DSL 写法示例](references/widget-dsl-api-examples.md)。
|
|
28
|
-
- 生成 Dashboard DSL 时,按需读取 [Dashboard DSL API](references/dashboard-dsl-api.md) 导航的拆分文件,不一次加载全部:写板前读 [dashboard-dsl-core.md](references/dashboard-dsl-core.md)(根入口/布局/移动端/字段写法);挂载或配置具体条目类型读 [dashboard-dsl-items.md](references/dashboard-dsl-items.md);需要可抄写法或场景模板读 [dashboard-dsl-examples.md](references/dashboard-dsl-examples.md)。仅引用已有组件时无需加载 Widget API。产物顺序不清楚时读取 [产物顺序](references/artifact-ordering.md)。
|
|
29
|
-
- 解释或生成公式时,先用 `formula functions` 查询当前 FineBI 公式面板;绑定真实字段后,用 `calculated-field validate` 执行原生校验。
|
|
30
|
-
- 同一连续任务内复用未变化的已读内容;只有文件变化、进入未读能力,或上下文压缩后所需规则已不可用时,才补读相关部分。实时 capability、目标和文件摘要校验仍按变更契约执行,不以文档复用代替。
|
|
8
|
+
使用本 Skill 完成资源发现、DSL 生成、业务执行和验证。参考资料与 CLI 均随包提供,主流程不依赖源码仓库或另一项 FineBI Skill。
|
|
31
9
|
|
|
32
10
|
## 执行入口
|
|
33
11
|
|
|
34
|
-
|
|
12
|
+
将本文件所在目录记为 `<skill-dir>`,使用绝对路径调用。Node.js 要求 18.17 或更高版本。
|
|
35
13
|
|
|
36
14
|
```text
|
|
37
15
|
node "<skill-dir>/scripts/finebi-cli/src/index.js" <built-in-command> ...
|
|
38
|
-
node "<skill-dir>/scripts/finebi-cli-runner.mjs" inspect <resource> <command>
|
|
39
|
-
node "<skill-dir>/scripts/finebi-cli-runner.mjs" run <resource> <command> ... --json
|
|
16
|
+
node "<skill-dir>/scripts/finebi-cli-runner.mjs" inspect <resource> <command> [--profile <name>]
|
|
17
|
+
node "<skill-dir>/scripts/finebi-cli-runner.mjs" run <resource> <command> ... --json [--profile <name>]
|
|
40
18
|
```
|
|
41
19
|
|
|
42
|
-
-
|
|
43
|
-
- `config`、`auth`、`capability`
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- `
|
|
56
|
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
- `
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
### 1. 检查连接与认证
|
|
81
|
-
|
|
82
|
-
先按执行入口规则选定 CLI,再调用其只读状态命令检查配置、认证和 capability 缓存。需要配置地址或登录时,在当前任务范围内说明并执行必要的本地状态变更;缺少目标地址或认证输入时请求补充。成功登录后仍检查 capability 是否刷新成功。
|
|
83
|
-
|
|
84
|
-
### 2. 发现实时能力
|
|
85
|
-
|
|
86
|
-
使用 runner 的 `inspect` 模式核对资源、命令、`mutation`、必填参数、文件类型和响应结构。矩阵与运行时不一致时,以运行时结果阻断本次操作并报告差异,不得沿用旧计划或臆造语法。
|
|
87
|
-
|
|
88
|
-
### 3. 解析资源与字段
|
|
89
|
-
|
|
90
|
-
按照命令工作流使用 `search`、`info`、`definition`、`schema`、`preview` 等只读命令解析准确 ID、归属关系和字段。遍历分页结果;保留空结果、警告和部分数据标记。
|
|
91
|
-
|
|
92
|
-
需要生成 JSON Definition 时,先 `inspect` 对应的 `template` 命令;实时 capability 为 `mutation:false` 时执行它,并以返回的 `definitionSchema`、`definitionTemplate` 和填写指引生成文件。不得凭经验猜测 Definition 结构。
|
|
93
|
-
|
|
94
|
-
模型来源探查先用 `public-ds search` 确认 `type=METRIC_SET` 来源,再调用 `model source-info --id <sourceId>` 获取字段目录和来源展示提示,无需主题。字段状态、来源文本与后续命名空间确认按 [Model 工作流](references/command-workflows.md#76-model-metric-set) 判读。
|
|
95
|
-
|
|
96
|
-
生成制品时,先调用 `subject info` 查看 `resources.models` 主题模型摘要,再用 `model search --subject-id <subjectId>` 消歧主题内模型,并用 `model info --subject-id <subjectId> --id <modelId>` 获取具体指标、数据集字段和模型计算字段。若用户要求的指标集尚未属于主题,确认唯一来源和可编辑目标主题;`model add` 返回的主题内模型 ID 才可用于 `model info/delete` 和字段回查,来源探查不能替代该确认,来源 ID 不得写进 DSL。模型目录命令未出现在实时 capability 时,既有 `widget dsl` 输出中的 `model(...)` 仍可作为只读证据;两类证据都不存在时进入 `BLOCKED`。不得把同名分析表改写成模型指标集。
|
|
97
|
-
|
|
98
|
-
### 4. 生成 Widget/Dashboard DSL
|
|
99
|
-
|
|
100
|
-
需要新建或更新 Widget/Dashboard 时:
|
|
101
|
-
|
|
102
|
-
1. 按语义交接契约构造并校验 `contractVersion: "1.0"` 的交接对象。
|
|
103
|
-
2. 明确列出唯一的绝对 `.js` 产物路径;只写入用户同意的映射路径。
|
|
104
|
-
3. 按 DSL 输入契约、映射规则和对应 API 生成文件。
|
|
105
|
-
4. 物理字段使用 `from("来源表").dim/sum/...`;模型级仅有指标,使用 `model("模型指标集").metrics().sum/avg/min/max/measure(...)`;模型表字段和模型计算字段分别使用 `model("模型指标集").dataset("数据集").dim/sum(...)` 与 `model("模型指标集").calculated().dim/sum(...)`;已保存计算字段使用 `measureID("配置 ID").dim()/sum()`。不把数据集 ID、模型 ID、字段 ID 或关系 ID 写进 DSL,也不把同名 `from(...)` 与 `model(...)` 互换。
|
|
106
|
-
5. Dashboard 统一通过 `.reference("组件名")` 引用组件,不内联组件定义。
|
|
107
|
-
6. 重新读取文件,自检根类型、名称、字段来源、API 和换行。
|
|
108
|
-
|
|
109
|
-
DSL 生成只授权本地文件写入,不授权任何 FineBI 写命令。模型字段支持模型指标、模型表字段和模型计算字段;模型根级维度和记录数不支持。同一作用域内字段展示名无法唯一解析时返回 `BLOCKED`,不得猜测或静默丢弃语义。
|
|
110
|
-
|
|
111
|
-
### 5. 执行只读业务命令
|
|
112
|
-
|
|
113
|
-
展示用途和业务命令 JSON `argv`,再用 runner 的 `run` 模式执行。解析结构化 envelope,只呈现任务所需结果,不重复倾倒原始 stdout。
|
|
114
|
-
|
|
115
|
-
### 6. 冻结写入计划
|
|
116
|
-
|
|
117
|
-
计划前先核对目标命令 help 是否能表达用户要求的名称、路径和其他目标属性。能力不支持时必须说明差距并进入 `BLOCKED`,不得把无法传入的目标写进计划。例如 `subject.add` 只有 `parentId` 时,不得承诺创建指定名称的主题。
|
|
118
|
-
|
|
119
|
-
按照变更确认契约生成计划,包含:精确目标、完整参数、文件绝对路径与 SHA-256、阶段依赖、影响、可逆性、前置验证、后置验证和失败清理策略。删除操作独立成批;不能可靠清理的操作单独执行或放在最后。
|
|
120
|
-
|
|
121
|
-
如果下游文件只能在上游写命令返回服务端实际 ID 后生成,不得在同一计划中使用占位 ID 或预期 ID。应先规划、复检、执行并回查上游资源;再生成下游文件并冻结新的 `planId`,仅包含 `delete` 时等待确认。典型顺序是:创建主题并回查实际 ID → 生成 Analysis DS Definition 并新建计划 → 创建分析表并回查实际 ID → 生成 Widget/Dashboard DSL 并新建计划。
|
|
122
|
-
|
|
123
|
-
生成唯一 `planId`;仅包含 `delete` 时将状态设为 `AWAITING_CONFIRMATION` 并要求用户回复 `确认执行 <planId>`,确认前不得执行该删除计划。不含 `delete` 时直接复检并执行。
|
|
124
|
-
|
|
125
|
-
### 7. 复检、执行与验证
|
|
126
|
-
|
|
127
|
-
按变更契约核验 capability/help、目标和文件摘要;删除计划先收到精确确认,再实时复检。全部符合计划时严格按阶段执行,每阶段完成后立即只读验证;首个写命令失败后立即停止,不得在同一 `planId` 下修改参数、改写文件或换一种 JSON 继续重试。
|
|
128
|
-
|
|
129
|
-
失败时汇总已成功或明确部分成功的资源,按依赖逆序生成新的 `cleanupPlanId`。其中 `delete` 必须独立确认;非删除补偿完成复检后执行。
|
|
130
|
-
|
|
131
|
-
### 8. 完成报告
|
|
132
|
-
|
|
133
|
-
报告每阶段结果、服务端实际 ID、验证证据、未执行项和残留风险。只有所有计划阶段及验证完成时进入 `COMPLETED`。
|
|
134
|
-
|
|
135
|
-
## 阻断输出
|
|
136
|
-
|
|
137
|
-
进入 `BLOCKED` 时报告状态、阻断命令或阶段、已收集只读证据、触发的安全边界,以及继续所需的最小用户操作。不得输出未经验证或可能误导用户执行的写命令。
|
|
20
|
+
- 入口优先级:显式 `FINEBI_CLI_PATH` → 内置 `scripts/finebi-cli/src/index.js` → PATH 中已安装的 `finebi-cli`。显式入口可为 JavaScript 文件、可执行文件或 Windows npm `.cmd`。
|
|
21
|
+
- `config`、`auth`、`capability`、`app` 直接使用所选 CLI;动态业务命令使用 runner。两者必须来自同一安装。全局入口使用 `finebi-cli ...`,JavaScript 入口使用 `node "<入口绝对路径>" ...`。
|
|
22
|
+
- 内置入口存在时不因全局包已安装而替换它。不自动执行 `npm install`、`npm link` 或 `npx`;业务失败不触发换版本重试。缺少入口时说明缺失。
|
|
23
|
+
- 只有远端业务需要可访问的 FineBI、兼容插件和有效身份。首次远端调用前检查连接、认证和 capability;缺少地址或认证输入时请求最小补充。成功登录后确认 capability 刷新成功。
|
|
24
|
+
- 连续任务复用已核实的入口、profile、目标 ID 和未过期的 capability/help;环境、目标前提或 schema 变化时重查。写前复检与删除确认后的实时复检仍按[变更契约](references/mutation-confirmation-contract.md)执行。
|
|
25
|
+
- 多环境任务统一使用 `--profile <name>`;环境发现、登录和默认环境保护见[命令公共规则](references/command-workflows.md#1-使用规则)。不为普通业务任务切换机器默认环境。
|
|
26
|
+
|
|
27
|
+
## 按任务读取
|
|
28
|
+
|
|
29
|
+
先选择当前任务所在行,再读取相关章节;不预先加载所有参考。长文先定位标题或关键符号。同一连续任务复用已读内容,上下文压缩或进入新能力时只补读必要部分。
|
|
30
|
+
|
|
31
|
+
| 当前任务 | 首先读取 | 按需补充 |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| 查询资源、字段或预览数据 | [命令工作流](references/command-workflows.md) §1 和目标资源章节 | 消费 `dashboard data` 时读[结果契约](references/dashboard-data-result.md),保留首视图范围与 warnings |
|
|
34
|
+
| Excel/CSV 到分析表、组件和仪表板 | [文件转看板](references/file-to-dashboard.md) | 只读当前阶段所需的 API 与变更规则 |
|
|
35
|
+
| 创建或修改 Analysis DS 步骤 | [Analysis DS 工作流](references/command-workflows.md#71-analysis-ds) | 写 JS 时读 [Analysis DSL API](references/analysis-dsl-api.md) |
|
|
36
|
+
| 新建或修改 Widget | [场景工作流](references/scenario-workflows.md)+[Widget API 导航](references/widget-dsl-api.md) | [映射规则](references/mapping-rules.md)仅查本次图表、字段与通道;需要推荐写法时读[示例](references/widget-dsl-api-examples.md) |
|
|
37
|
+
| 新建或修改 Dashboard | [场景工作流](references/scenario-workflows.md)+[Dashboard API 导航](references/dashboard-dsl-api.md) | 仅引用已有组件时无需读 Widget API;来源与顺序见[产物顺序](references/artifact-ordering.md) |
|
|
38
|
+
| 解释、生成或排查公式 | [公式入口](references/formula.md) | 教学/离线模板声明假设;实际主题落地前查询目标主题面板,再以同一份 JS 做 `calculated-field validate` |
|
|
39
|
+
| 动态 HTML 看板、数据 Web 应用 | [应用模板工作流](references/web-app.md) | 本地 `app create` 不需要登录;绑定真实数据时再检查连接与业务能力,开发遵循生成项目 AGENTS.md |
|
|
40
|
+
| FineBI 非只读命令或失败清理 | [变更计划与删除确认](references/mutation-confirmation-contract.md) | 读取本次计划、复检、验证及适用的清理章节 |
|
|
41
|
+
| 跨执行体交接 DSL 任务 | [语义交接](references/handoff-contract.md)+[DSL 输入契约](references/dsl-handoff-contract.md) | 完整 JSON 与文件映射用于外部交接;同一 Agent 连续执行按场景流程记录必要语义即可 |
|
|
42
|
+
|
|
43
|
+
## 常用执行路径
|
|
44
|
+
|
|
45
|
+
1. **查询:** 先用 runner `inspect` 确认目标命令的实时能力、参数与 `mutation`,随后 `run`。已知准确 ID 时直接 `info` 核验名称、归属和所需字段;只有缺少 ID 或需消歧时搜索。宣称名称唯一前遍历搜索的全部分页。
|
|
46
|
+
2. **生成:** 本 Agent 可以自行生成和修复本任务的 DSL 文件。按场景流程核实资源、业务语义和唯一产物路径,再按对应 API 生成并回读自检。路径可由用户指定或安排在当前任务隔离临时目录;不为内部语义对象或路径增加审批。只有用户要求审阅或业务歧义尚未消除时才等待用户决定。
|
|
47
|
+
3. **写入:** 用户要求保存、更新或端到端完成时,生成后按变更契约冻结计划、复检、执行并逐阶段只读验证。仅要求生成本地 DSL 时到文件自检结束,不调用 FineBI 写命令。需要上游实际 ID 才能生成下游文件时分阶段规划,禁止占位 ID。
|
|
48
|
+
4. **输出:** 使用[输出策略](references/command-workflows.md#11-输出与上下文)选择投影或落盘。报告实际结果、实际 ID、验证证据、warnings、未完成项和残留风险;只读回查成功不能代替前端显示与出数验证。
|
|
49
|
+
|
|
50
|
+
## 关键边界
|
|
51
|
+
|
|
52
|
+
- 命令存在性、参数、schema 和 `mutation` 以当前连接的 capability/help 为准;`inspect` 只取摘要,不把完整 manifest 放入上下文。读取动态 `template` 前先 inspect,只有 `mutation:false` 才作为只读模板使用。
|
|
53
|
+
- 所有非只读命令完成计划与执行前校验;已授权的 `add/update/data-update` 等非删除动作直接复检执行。只有 `delete` 计划要求 `确认执行 <planId>`,内容变化即使旧确认失效;删除清理同样独立确认。`config/auth/capability` 的必要非删除变更限定在当前任务范围。
|
|
54
|
+
- 不在多个合理资源、字段或关系之间静默选择。字段命名空间、模型来源与主题内模型 ID、组件引用唯一性按对应场景/API 核验,不把同名分析表当作模型。物理字段、模型字段和计算字段的写法见 Widget API 根入口;数据集、模型、字段或关系 ID 不写入 DSL 字段名称。
|
|
55
|
+
- 文件只写入当前任务明确的路径;生成后回读自检,执行前校验 realpath 与 SHA-256。首个写阶段失败即停,汇总实际成功/部分成功资源后重新规划,禁止在原计划内偷偷换参数或文件重试。
|
|
56
|
+
- 密码、token、Cookie、Access Key 不进入命令、日志或回复;密码优先用环境变量或 stdin。业务任务不扫描源码仓库猜命令或绕过 CLI 调内部 API。
|
|
57
|
+
- 能力缺失、歧义或前提不满足时说明阻断阶段、只读证据及继续所需最小输入;不得声称未执行的命令或验证已成功。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: "FineBI CLI Agent"
|
|
3
3
|
short_description: "使用内置 CLI 查询、创建和安全管理 FineBI 资源"
|
|
4
|
-
default_prompt: "使用 $finebi-cli-agent 完成我的 FineBI
|
|
4
|
+
default_prompt: "使用 $finebi-cli-agent 完成我的 FineBI 查询、组件或仪表板需求;非删除操作完成校验后直接执行,删除操作先展示计划并让我确认。"
|
|
5
5
|
|
|
6
6
|
policy:
|
|
7
7
|
allow_implicit_invocation: true
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
按以下顺序写入:
|
|
15
15
|
|
|
16
|
-
1.
|
|
16
|
+
1. 校验语义输入和文件映射;跨执行体使用完整交接 JSON,同一 Agent 可使用已核实的内部记录。
|
|
17
17
|
2. 为每个 `requestedWidgets[]` 生成一个 Widget DSL 文件。
|
|
18
18
|
3. 重新读取并自检全部 Widget 文件。
|
|
19
19
|
4. 当场景为 `CREATE_DASHBOARD` 时生成 Dashboard DSL 文件。
|
|
@@ -25,5 +25,5 @@ Dashboard DSL 只通过 `.reference("组件名")` 挂载组件。即使组件属
|
|
|
25
25
|
|
|
26
26
|
- 任一 Widget 无法映射时停止,不生成 Dashboard。
|
|
27
27
|
- 已写入文件若随后发现自检失败,只修正文件映射中对应的目标文件;不创建替代文件。
|
|
28
|
-
-
|
|
29
|
-
-
|
|
28
|
+
- 文件生成阶段不删除、创建或修改 FineBI 服务端资源。
|
|
29
|
+
- CLI 写入顺序、计划和失败清理属于执行阶段。独立 DSL 编写器只返回本地制品;完整 Agent 在用户请求包含保存或更新时,再按变更契约执行远端阶段。
|
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
搜索结果存在分页时必须遍历完整结果。结果存在多个合理候选时,展示名称、ID 和归属信息,不得静默选择。
|
|
16
16
|
|
|
17
|
+
已知准确资源 ID 时直接 `info` 核验名称、归属和任务需要的字段,不重新遍历全局搜索。只有名称、归属未知或存在冲突时才搜索;按名称生成 Dashboard 引用仍须证明组件名在解析范围内唯一。连续任务可以复用前提未变化的资源证据;写入仍执行变更契约要求的目标复检。
|
|
18
|
+
|
|
19
|
+
### 1.1 输出与上下文
|
|
20
|
+
|
|
21
|
+
- 小结果直接解析 envelope,只向用户呈现任务所需内容,不重复输出原始 stdout。
|
|
22
|
+
- 已知响应结构时用 `--select <paths>` 投影;路径以目标 help/schema 或已有响应为准,不猜字段。保留判断成功/失败、分页、warnings、空结果和部分成功所需的信息;不能通过只选第一条候选制造唯一性。
|
|
23
|
+
- 大型 schema、DSL、数据或未知结构的完整响应用 `--save <绝对路径>` 保存到当前任务隔离目录。stdout 返回的是落盘摘要,业务数据在保存的 JSON envelope 中;随后按需定向读取,不将摘要当作真实查询数据。
|
|
24
|
+
- `--max-chars` 会截断 stdout 文本。runner 需要解析完整 JSON,使用 runner 时选择 `--select` 或 `--save`,不传 `--max-chars`。直接 CLI 的截断输出只能用于快速查看,不能作为完整 JSON、全量候选或验证证据。
|
|
25
|
+
- `--save` 优先于 `--max-chars`;失败 envelope 不做成功数据投影,错误仍应完整检查。落盘文件和摘要可能含业务信息,遵循当前任务的数据与凭据边界。
|
|
26
|
+
|
|
17
27
|
## 2. 当前命令矩阵
|
|
18
28
|
|
|
19
29
|
动态 HTML 看板与数据 Web 应用使用本地 `app create/inspect`,不属于远端 capability;具体开发流程见[应用模板工作流](web-app.md)。
|
|
@@ -104,7 +114,26 @@
|
|
|
104
114
|
(内部试用开关开启的服务器);正式版默认态下 `add` 仅支持原样引用创建(create/from/fromExcel),
|
|
105
115
|
`template` 仅 `basic` 场景,不得规划改表工作流(见第 2 节 † 注)。
|
|
106
116
|
|
|
107
|
-
|
|
117
|
+
#### 7.1.1 创建与读取
|
|
118
|
+
|
|
119
|
+
创建与步骤覆盖均使用 AnalysisTableDsl JS 文件。`add --subject-id <id> --file <x.js>` 创建新表,DSL `from(表原始名)` 声明来源;原始名是 search 返回的 `id`,全局唯一。Excel 源用 `fromExcel(attachId, "Sheet1", ...)`,Sheet 名逐个传字符串,attachId 来自 `upload-excel`。
|
|
120
|
+
|
|
121
|
+
创建后使用响应中的实际 `id`/`ids` 逐一调用 `info`,失败清理必须覆盖 `ids` 中的全部实际 ID。`dsl --id <id>` 反读已保存表的可编辑 DSL 文本(Bean→DSL),用于「读取 → 修改 → 写回」。语句面见 DSL 编写器的 `analysis-dsl-api.md`:来源、过滤、排序、字段设置、公式列、分组汇总、左右合并、上下合并及可选 `resultName` 声明;模板通过 `template --scenario <basic|formula|group|full>` 获取,场景支持以实时能力为准。
|
|
122
|
+
|
|
123
|
+
#### 7.1.2 更新与字段别名
|
|
124
|
+
|
|
125
|
+
`update --id <id> --file <x.js>` 覆盖步骤链,来源不变,DSL `from` 必须匹配现有来源。响应 `changedFields` 表示保存前后字段差分,rename 以旧名消失+新名出现表达。`dsl` 的 `resultToIdentifyNameMap` 列出结果字段名与 identify name 不同的别名;组件引用按 identify name 解析。
|
|
126
|
+
|
|
127
|
+
`resultName(resultFieldName, identifyName)` 的 key 是最后一步结果字段名(字段转义名),value 是对外 identify name;未声明时交给平台。反读输出 `.resultName(...)`,写回保持别名幂等。重命名涉及被引用字段时,生成 `resultName("新名", "旧名")` 保留 identify name。先读 `dsl` 评估别名风险,在写前准备好别名声明;`update` 后检查 `changedFields` 并验证组件出数,不把 DSL 回读一致当作前端验证通过。
|
|
128
|
+
|
|
129
|
+
#### 7.1.3 合并与引擎限制
|
|
130
|
+
|
|
131
|
+
- 左右合并:`join("右表原始名", joinType.X).on(左字段, 右字段).renameResult(旧名, 新名)`。
|
|
132
|
+
- 上下合并:`union("表A").union("表B").alignField(左, 右).withFields(...).withAllFields().renameResult(...)`。
|
|
133
|
+
- 右表和合并表只支持同主题内数据集,使用已核实 ID 的 `info` 或必要的 `analysis-ds.search` 确认归属。结果字段由引擎推导:抽取表合并依据去重成一个字段,直连表全保留;改名使用 `renameResult`,与字段设置的 `rename` 区分。
|
|
134
|
+
- 按第 4 节区分引擎。DIRECT 不因更新状态或摘要 `usable` 执行 `data-update`;SPIDER 的 `data-update` 可能触发重算,不能视为可逆。`delete` 独立确认。
|
|
135
|
+
|
|
136
|
+
#### 7.1.4 主题共享钻取目录
|
|
108
137
|
|
|
109
138
|
主题共享钻取目录:`drill-directory.update --subject-id <id> --file <directory.js>` 使用 `DrillDirectoryModel.builder("目录名").levels([from("表").dim("省"), from("表").dim("市")]).build()` 创建,用 `.dissolve()` 解散。`drill-directory.dsl --subject-id <id> --name <目录名>` 回读;目录按主题内精确名称定位。解散保留原字段,操作影响主题共享字段面板;目录重名且层级不同、字段已属于其他目录时拒绝写入,不能隐式覆盖。
|
|
110
139
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 1. 输入边界
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
独立 DSL 编写器只消费规划器已校验的 JSON 对象;完整 Agent 在同一任务内生成 DSL 时,可使用覆盖必要信息的内部记录,并按本契约核验字段来源、关系和引用。跨执行体仍必须传递完整 `contractVersion: "1.0"` JSON。语义输入不包含 JS 源码,也不授权执行任何 FineBI 写命令。
|
|
6
6
|
|
|
7
7
|
顶层结构:
|
|
8
8
|
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
本契约仅记录 `$finebi-cli-agent` 为 Widget/Dashboard JS 制品解析的业务语义。契约不包含 JS 源码;CLI 命令必须另行遵循通用执行流程,其中仅 `delete` 命令需要人工确认。
|
|
6
6
|
|
|
7
|
+
完整 JSON 用于跨执行体交接。同一 Agent 在一个连续任务内发现资源并生成 DSL 时,可以使用覆盖本次必要信息的结构化记录;下文的字段来源、归属、关系、命名空间和引用校验同样适用。不为内部记录或文件路径增加用户审批。
|
|
8
|
+
|
|
7
9
|
## 规划器请求
|
|
8
10
|
|
|
9
11
|
使用以下 JSON 结构。省略没有实际含义的可选属性;不得臆造占位 ID。
|
|
@@ -154,7 +156,7 @@
|
|
|
154
156
|
1. 对每一对被跨数据集字段引用实际关联的分析表,调用 `relationship info --subject-id <subjectId>` 确认现有关系。
|
|
155
157
|
2. 关系已存在且 `status` 为 `DEFAULT` 时,把该关系写入 `relationships` 数组。
|
|
156
158
|
3. 关系不存在,或存在但 `status` 非 `DEFAULT`(例如 `MISS_FIELD`、`TYPE_NOT_MATCH`)时,不得静默继续;应向用户说明现状。需要新增或替换关系时,按
|
|
157
|
-
|
|
159
|
+
[Relationship 工作流](command-workflows.md#77-relationship)走独立的 `relationship add` 计划、复检和执行流程,无需人工确认;写入成功且只读回查通过后,才把该关系补充进
|
|
158
160
|
`relationships` 数组。
|
|
159
161
|
|
|
160
162
|
`relationships[]` 单条结构:
|
|
@@ -184,7 +186,7 @@
|
|
|
184
186
|
|
|
185
187
|
## JS 制品映射
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
跨执行体消费制品时,调用方、用户或可用生成工作流提供以下 JSON。具有 DSL 生成职责的 Agent 在同一任务内自行记录路径并生成文件,文件回读自检后再消费映射;不要求额外的外部生成器或路径确认。
|
|
188
190
|
|
|
189
191
|
```json
|
|
190
192
|
{
|
|
@@ -201,7 +203,7 @@
|
|
|
201
203
|
- `files` 必须包含每个 `requestedWidgets[].key`,以及存在时的 `requestedDashboard.key`。
|
|
202
204
|
- 每个值都必须是指向现有 `.js` 文件的绝对路径。
|
|
203
205
|
- 将每个值解析为文件系统的 canonical/real path。所得规范路径必须两两不同,因此两个 artifact key 不得通过不同拼写、相对路径片段或符号链接别名指向同一文件。
|
|
204
|
-
-
|
|
206
|
+
- 独立规划器仅消费路径,不从说明性文本推断文件或改写已生成文件;完整 Agent 的生成阶段可按入口职责生成和修复本任务文件,写入计划只消费已校验文件路径,不消费内联 DSL。本契约不要求或指定特定生成器 Skill。
|
|
205
207
|
- 额外且未映射的文件不会生成命令。
|
|
206
208
|
|
|
207
209
|
## 前置资源边界
|
|
@@ -209,4 +211,4 @@
|
|
|
209
211
|
主题、自助数据集、字段或跨数据集关系缺失时,可以先通过通用命令流程创建所需前置资源,但不得把尚未创建的资源或占位 ID
|
|
210
212
|
写入本交接对象。搜索命中 `public-ds` 时,必须先以该公共数据集为来源在目标主题内创建 `analysis-ds`,并使用写响应中的实际 ID 完成 `analysis-ds.info` 和必要的 `preview` 回查;不得把公共数据集 ID 写入 `datasets`,也不得因已经命中公共数据集而继续查询数据连接。前置写操作必须单独规划并复检,创建成功且只读回查后,再生成本契约;仅当前置操作为 `delete` 时等待人工确认。
|
|
211
213
|
|
|
212
|
-
|
|
214
|
+
跨执行体的版本 1.0 制品输入始终是上述 JSON 对象,不以自然语言替代。单 Agent 内部记录不改变该外部交接格式。
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
本契约约束所有非只读命令的计划、复检、执行、验证和失败清理。`add`、`update`、`data-update` 及其他非删除命令不需要人工确认;命令名为 `delete` 的计划必须等待人工确认。人工确认只授权一个内容冻结的删除计划,不授权后续变化或自动清理。
|
|
6
6
|
|
|
7
|
+
用户已明确要求的非删除任务在完成校验后连续执行,不为内部语义对象、临时产物路径或计划生成增加审批。用户要求先审阅时遵循该范围;业务歧义需要澄清;仅生成本地文件的请求不授权远端写入。计划中的 `state` 用于记录执行进度,无需逐步向用户播报状态名。
|
|
8
|
+
|
|
7
9
|
## 2. 冻结计划
|
|
8
10
|
|
|
9
11
|
计划必须使用可见且唯一的 `planId`。非删除计划生成后可以直接复检执行;删除计划必须在一个完整 JSON 代码块中展示并等待确认:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
仅当用户要根据业务描述创建或更新 Widget/Dashboard,且命令需要 JS DSL 文件时使用本文件。资源查询和执行边界仍遵循 `SKILL.md`、`command-workflows.md` 与 `mutation-confirmation-contract.md`;仅 `delete` 命令需要人工确认。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
按入口声明的职责处理 DSL:完整 Agent 在同一任务内生成、回读并修复本次 JS 制品;独立场景规划器只解析语义、消费外部已验证制品。共享流程不扩大独立规划器的文件写入权限。生成本地文件与执行 FineBI 写命令分别遵循用户请求范围。
|
|
8
8
|
|
|
9
9
|
## 2. 解析业务语义
|
|
10
10
|
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
依赖只读命令解析:
|
|
14
14
|
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
15
|
+
1. 已知主题 ID 时直接用 `subject.info` 核验;只有名称或归属不清时才搜索主题,并在证明名称唯一前遍历全部分页。同一连续任务中前提未变化的已核实主题证据可以复用。
|
|
16
|
+
2. 已知数据集 ID 时直接用 `analysis-ds.info` 核验主题、名称和所需字段;需要按表名解析数据集时,先用用户提供的完整名称搜索 `analysis-ds` 和 `public-ds`,遍历全部分页,并按返回的真实名称全等判断唯一精确匹配。
|
|
17
17
|
3. 没有精确匹配时,对分析表和公共数据集执行关键词搜索,结合字段、位置、主题归属、资源类型、引擎类型和用户意图选择候选;多个候选合理时要求用户选择。
|
|
18
18
|
4. 选定资源为 `public-ds` 时,将其作为来源按前置资源流程创建目标主题内的 `analysis-ds`,使用写响应中的全部实际 ID 逐一调用 `analysis-ds.info` 和必要的 `preview`;转换完成前不得构建语义交接对象,也不得继续查询数据连接。
|
|
19
19
|
5. 只有数据集层没有合理候选时,才查询数据连接和物理表,并按前置资源流程创建所需数据集;不得把物理表标识当作数据集 ID。
|
|
@@ -34,13 +34,15 @@
|
|
|
34
34
|
|
|
35
35
|
搜索命中公共数据集时,`analysis-ds.add` 属于交接所需的前置资源创建:DSL 的 `from(表原始名)` 必须引用已验证的公共数据集原始名(`public-ds search` 返回的 `id`,全局唯一),目标主题通过 `--subject-id` 传入;执行后逐一回查服务端返回的分析表实际 ID。不得在前置资源尚未创建时向交接对象填入公共数据集 ID、预期 ID 或占位 ID。
|
|
36
36
|
|
|
37
|
-
## 4.
|
|
37
|
+
## 4. 语义记录与校验
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
同一 Agent 连续完成生成和执行时,记录本次实际用到的主题、来源与字段、关系、图表/布局意图、组件引用和产物路径;按 `handoff-contract.md` 和 DSL 输入契约核验这些信息,不必构造或展示完整交接 JSON。跨执行体交接时使用完整 `contractVersion: "1.0"` JSON 与文件映射。
|
|
40
|
+
|
|
41
|
+
业务目标明确时直接继续,不为内部语义记录或产物路径增加审批;只有业务歧义未消除或用户明确要求先审阅时才等待。用户改变影响制品的语义后,更新记录、重新生成受影响文件并废止对应旧写计划。语义审阅不代替删除计划确认;仅要求本地生成不授权 FineBI 写命令。
|
|
40
42
|
|
|
41
43
|
## 5. JS 制品映射
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
有 DSL 生成职责的执行体自行安排当前任务隔离目录中的唯一绝对路径,或使用用户指定路径;按实际涉及的 API 生成并回读自检后,记录完整 `artifact key -> absolute JS file path` 映射。独立场景规划器仅接收调用方、用户或可用生成工作流提供的现有制品映射,不自行生成或修复 DSL。冻结远端写计划前,每个路径必须:
|
|
44
46
|
|
|
45
47
|
- 是现有 `.js` 文件的绝对路径;
|
|
46
48
|
- 由用户明确提供,或位于为当前任务创建的隔离临时目录;不得根据当前工作目录猜测 `cli/` 或其他项目路径;
|
|
@@ -48,7 +50,7 @@
|
|
|
48
50
|
- 与其他 artifact key 的规范路径不同;
|
|
49
51
|
- 在冻结写计划时记录 SHA-256。
|
|
50
52
|
|
|
51
|
-
缺少 key
|
|
53
|
+
缺少 key、路径不存在、路径重复或文件被修改时,不执行旧写计划。具有生成职责时先补齐或修复本次文件并重新校验;独立规划器报告缺失制品并等待提供。无法满足边界时进入 `BLOCKED`。
|
|
52
54
|
|
|
53
55
|
## 6. 创建 Widget
|
|
54
56
|
|
|
@@ -72,4 +74,4 @@
|
|
|
72
74
|
|
|
73
75
|
以下情况进入 `BLOCKED`:运行时缺少所需命令;资源/字段/引用存在歧义;主题或数据集归属不匹配;JS 映射不完整或文件无效;无法证明 Dashboard 引用组件唯一;运行时 schema 与冻结计划不一致。
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
等待用户明确要求的语义审阅、删除计划确认或包含删除的清理计划确认时,状态为 `AWAITING_CONFIRMATION`。明确任务中的内部语义记录不经过该状态。
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
1. `finebi-cli app create --name <name> --path <parent> [--layout retail]` 创建工程,不安装/运行/发布。米白横向经营简报可选 retail,绿色驾驶舱可选 cockpit;默认 overview,另有 workbench。
|
|
6
6
|
2. 用dashboard search/info/data确认唯一来源、板内entryId、结果字段dId、真实控件filterName;按生成项目 docs/acceptance.md 记录指标口径、单位/时区、筛选范围和数据完整性。样本仅用于理解和测试。
|
|
7
|
-
3. 按生成项目 docs/
|
|
8
|
-
4. `finebi-cli app inspect --path <project
|
|
7
|
+
3. 按生成项目 AGENTS.md 的“阅读路径”分阶段读取文档,不要求开场通读全部说明。先按 docs/acceptance.md 的“最小真实查询”只配置一个真实组件,按 README 安装依赖、配置开发身份并启动实际页面,验证开发代理查询与页面值。CLI 成功不能替代这一步;优先复用已有会话,不重复索要可用身份的密码。
|
|
8
|
+
4. 最小真实查询及适用的代表性图表、筛选链路通过后,再扩展整页绑定。按 docs/design.md 对应章节确定首屏、导航、图表分组和风格差异;请求、认证、解析复用模板src/finebi,图表库和UI组件库按页面需求选择。需要查看绑定摘要时可运行 `finebi-cli app inspect --path <project>`,默认不校验模板字段或展示格式,也不证明应用可用。只有需要检查与 CLI 内置模板的兼容性时才显式使用 `--strict`;定制应用无需通过该检查,不要为消除 strict 报错而删除自定义能力或反复修改应用。验收以项目自身测试、构建和真实浏览器验证为准。
|
|
9
9
|
5. 按生成项目 docs/acceptance.md 分别完成自动测试、构建、test:browser 合成数据验收和真实页面验收,检查整页及窄屏,记录 CLI、开发身份、生产 Cookie 各自的已验证与未验证项。生产部署必须用访问者Cookie,不携带开发身份。
|
|
10
10
|
|
|
11
11
|
内置CLI同样通过 `node "<skill-dir>/scripts/finebi-cli/src/index.js" app ...` 调用,不走动态业务runner。生产页面不调用CLI。禁止将开发时查到的业务数据或token写入HTML/JS/config;无筛选控件不能伪造服务端过滤。pageLimit不是分页,hasNext和warnings必须呈现。不提供发布上传或服务端续页。目录来源显式配置 directoryEntryId,由原生 reportEntryId 透传;目标平台需支持 HTTP 目录权限预检与 MOUNT 查询,不能失败后回退“我的分析”。
|
|
@@ -14,4 +14,6 @@ cockpit 的 examples/cockpit.config.json 仅包含占位绑定,必须替换成
|
|
|
14
14
|
|
|
15
15
|
retail 的 examples/retail.config.json 提供零售场景占位绑定,字段与口径须按同一来源核实;展示格式见生成项目 docs/design.md。不要根据原组件标题猜指标含义,也不要把记录数自动称为去重门店数。真实业务响应和分析结论不进入分发模板。
|
|
16
16
|
|
|
17
|
+
分组表 BIGROUP 可绑定为 type: "table",使用 main 数据集与结果字段 dId;保留父级分组、小计、总计及 UNKNOWN 行,不将汇总和明细混加。日期/数值分组键只保证展示语义,不能按显示文本恢复原值。交叉表 BICROSS 可用 table 展示当前矩阵,通常省略 tableFieldIds/localFilterFieldIds;cross:row、cross:0 等为本次查询槽位,不是 FineBI dId,不能用于 dimensionIds 或固定跨查询图形/KPI 绑定。保留原生行列路径、汇总标记与双轴分页警告,不把当前矩阵宣称为全量。复用模板的行、列指标标题去重(保留真实同名分组层级与原始 path)、DATA 行内部“合计”节点隐藏和 NULL 展示规则,不把真实空值当作不可用或补零;详细判定与范围见生成项目 docs/data-contract.md。
|
|
18
|
+
|
|
17
19
|
模板内置文本、单选/多选、数值选择、日期及日期区间、年月季度、年月区间和已配置时间标签;草稿统一应用,恢复默认与筛选空值分开。配置、状态、请求编码和代理校验共用 src/finebi/filters.js。数值范围、滑块、树/级联和动态候选项暂不支持,不得换成其他类型绕过检查。绑定前核实源控件类型和作用范围,候选项不得冒充完整数据。通用约定、完整支持矩阵、值格式及扩展步骤见生成项目 docs/filters.md。
|
|
@@ -273,6 +273,12 @@ warning 留痕。
|
|
|
273
273
|
- `QuickCalculationType.YEAR_ON_YEAR_*`:同比
|
|
274
274
|
- `QuickCalculationType.MONTH_ON_MONTH_*`:环比
|
|
275
275
|
|
|
276
|
+
快速计算作用于指标引用,可用于 `metric`、`value`、`angle`、`text` 指标槽位,不能用于维度。
|
|
277
|
+
`secondaryCalculation` 只允许用户可切换二次计算的类型显式传入;这类类型省略时默认开启,固定策略类型必须省略该参数。
|
|
278
|
+
内置同比、环比要求组件分析区域存在兼容的显示日期维度。
|
|
279
|
+
完整的组件写法见[快速计算二次开关示例](widget-dsl-api-examples.md#1022-快速计算二次开关)。
|
|
280
|
+
`widget info` 的结构化回读与文本 DSL 是不同输出面,不能用回读字段的枚举范围替代文本 DSL 的能力范围。
|
|
281
|
+
|
|
276
282
|
### 2.5 主题共享钻取目录
|
|
277
283
|
|
|
278
284
|
主题共享钻取目录使用独立命令 `drill-directory update --subject-id <id> --file <directory.js>`:
|
|
@@ -40,6 +40,7 @@ export async function createApp(args, context = {}) {
|
|
|
40
40
|
try {
|
|
41
41
|
const templateRoot = context.templateRoot ? resolve(context.templateRoot) : TEMPLATE_ROOT;
|
|
42
42
|
const templatePackage = JSON.parse(await readFile(resolve(templateRoot, "package.json"), "utf8"));
|
|
43
|
+
const gitignore = await readFile(resolve(templateRoot, "gitignore.template"), "utf8");
|
|
43
44
|
const templateConfigPath = resolve(templateRoot, "public", "app-config.json");
|
|
44
45
|
let config = {schemaVersion: "1", title: name, basePath: "/webroot/decision", layout: "overview", dashboardId: "", maxRows: 1000, pageSize: 8, widgets: [], filters: []};
|
|
45
46
|
try {
|
|
@@ -53,6 +54,7 @@ export async function createApp(args, context = {}) {
|
|
|
53
54
|
return invalid("app.create", error.code === "EEXIST" ? `Destination already exists: ${destination}` : `Cannot create destination: ${error.message}`);
|
|
54
55
|
}
|
|
55
56
|
await copyTemplateContents(templateRoot, destination);
|
|
57
|
+
await writeFile(resolve(destination, ".gitignore"), gitignore, "utf8");
|
|
56
58
|
if(options.value.layout) config.layout=options.value.layout;
|
|
57
59
|
if(config.layout==='cockpit') config.insights=true;
|
|
58
60
|
await mkdir(resolve(destination, "public"), {recursive: true});
|
|
@@ -78,6 +80,7 @@ async function copyTemplateContents(sourceRoot, destinationRoot, relativeDirecto
|
|
|
78
80
|
const destinationDirectory = resolve(destinationRoot, relativeDirectory);
|
|
79
81
|
for (const entry of (await readdir(sourceDirectory, {withFileTypes: true})).sort((left, right) => left.name.localeCompare(right.name, "en"))) {
|
|
80
82
|
const relativePath = `${relativeDirectory}/${entry.name}`.replace(/^\//u, "");
|
|
83
|
+
if (relativePath === ".gitignore" || relativePath === "gitignore.template") continue;
|
|
81
84
|
if (!templatePathAllowed(relativePath)) continue;
|
|
82
85
|
const sourcePath = resolve(sourceDirectory, entry.name);
|
|
83
86
|
const destinationPath = resolve(destinationDirectory, entry.name);
|
|
@@ -111,16 +114,20 @@ async function inspectApp(args) {
|
|
|
111
114
|
if (!(await stat(project)).isDirectory()) return invalid("app.inspect", "path must point to a project directory.");
|
|
112
115
|
const configPath = resolve(project, "public", "app-config.json");
|
|
113
116
|
const config = JSON.parse(await readFile(configPath, "utf8"));
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) return invalid("app.inspect", "app-config.json must contain a JSON object.");
|
|
118
|
+
if (options.value.strict) {
|
|
119
|
+
const {configErrors}=await import('../templates/web-app/src/finebi/config.js');
|
|
120
|
+
const errors = configErrors(config);
|
|
121
|
+
if (errors.length) return failure("app.inspect", cliError("INVALID_ARGUMENT", {path: "public/app-config.json", message: errors.join(" ")}));
|
|
122
|
+
}
|
|
117
123
|
return success("app.inspect", {
|
|
118
124
|
path: project,
|
|
119
|
-
dashboardId: config.dashboardId,
|
|
120
|
-
layout: config.layout,
|
|
125
|
+
dashboardId: config.dashboardId ?? null,
|
|
126
|
+
layout: config.layout ?? null,
|
|
121
127
|
directoryEntryId: config.directoryEntryId || null,
|
|
122
|
-
widgets: config.widgets.length,
|
|
128
|
+
widgets: Array.isArray(config.widgets) ? config.widgets.length : null,
|
|
123
129
|
templateVersion: config.templateVersion || null,
|
|
130
|
+
configValidated: options.value.strict === true,
|
|
124
131
|
remoteValidated: false,
|
|
125
132
|
});
|
|
126
133
|
} catch (error) {
|
|
@@ -133,6 +140,11 @@ function parseOptions(args, command) {
|
|
|
133
140
|
for (let index = 0; index < args.length; index++) {
|
|
134
141
|
const option = args[index];
|
|
135
142
|
if (option === "--json") continue;
|
|
143
|
+
if (option === "--strict" && command === "app.inspect") {
|
|
144
|
+
if (value.strict) return {ok: false, error: invalid(command, "--strict must only be supplied once.")};
|
|
145
|
+
value.strict = true;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
136
148
|
if (!["--name","--path",...(command==='app.create'?['--layout']:[])].includes(option)) return {ok: false, error: invalid(command, `Unsupported option: ${option}`)};
|
|
137
149
|
const key = option.slice(2);
|
|
138
150
|
const next = args[++index];
|
|
@@ -160,9 +160,8 @@ function abortedAuthorization() {
|
|
|
160
160
|
function validateBaseUrl(value) {
|
|
161
161
|
try {
|
|
162
162
|
const url = new URL(value);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
throw new Error("Browser authorization requires HTTPS, except for localhost development.");
|
|
163
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
164
|
+
throw new Error("Browser authorization requires an HTTP or HTTPS URL.");
|
|
166
165
|
}
|
|
167
166
|
if (url.username || url.password || url.search || url.hash) {
|
|
168
167
|
throw new Error("Browser authorization base URL must not contain credentials, a query, or a fragment.");
|
|
@@ -172,7 +171,7 @@ function validateBaseUrl(value) {
|
|
|
172
171
|
return failure("auth.login", cliError("BROWSER_AUTH_URL_INVALID", {
|
|
173
172
|
path: "baseUrl",
|
|
174
173
|
message: error instanceof Error ? error.message : String(error),
|
|
175
|
-
nextActions: ["finebi-cli config set base-url <https-url>"],
|
|
174
|
+
nextActions: ["finebi-cli config set base-url <http-or-https-url>"],
|
|
176
175
|
}));
|
|
177
176
|
}
|
|
178
177
|
}
|
|
@@ -8,7 +8,7 @@ import {CLI_CONFIG_DIRECTORY} from "./branding.js";
|
|
|
8
8
|
import {maskSecret} from "./output.js";
|
|
9
9
|
|
|
10
10
|
export const DEFAULT_TIMEOUT_MS = 30000;
|
|
11
|
-
export const DEFAULT_CAPABILITY_TTL_MS =
|
|
11
|
+
export const DEFAULT_CAPABILITY_TTL_MS = 20 * 60 * 60 * 1000;
|
|
12
12
|
|
|
13
13
|
export function defaultConfigPath(env = process.env) {
|
|
14
14
|
const home = env.USERPROFILE || env.HOME || homedir();
|