@dazitech/cli 3.0.2 → 3.0.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.
@@ -3061,11 +3061,27 @@ var AuthError = class extends DaziError {
3061
3061
  }
3062
3062
  };
3063
3063
  var NetworkError = class extends DaziError {
3064
- constructor(message, status) {
3064
+ constructor(message, status, request) {
3065
3065
  super(message, "ERR_NETWORK", 3);
3066
3066
  this.status = status;
3067
+ this.request = request;
3067
3068
  this.name = "NetworkError";
3068
3069
  }
3070
+ /** 多行人类可读详情,写入 stderr / OutputChannel */
3071
+ formatDetailLines() {
3072
+ const lines = [`\u9519\u8BEF: ${this.message}`];
3073
+ const r = this.request;
3074
+ if (!r)
3075
+ return lines;
3076
+ if (r.label)
3077
+ lines.push(`\u6B65\u9AA4: ${r.label}`);
3078
+ lines.push(`\u8BF7\u6C42: ${r.method} ${r.path}`);
3079
+ lines.push(`\u5B8C\u6574 URL: ${r.url}`);
3080
+ lines.push(`HTTP \u72B6\u6001: ${r.status}`);
3081
+ if (r.responseSnippet)
3082
+ lines.push(`\u54CD\u5E94\u6458\u8981: ${r.responseSnippet}`);
3083
+ return lines;
3084
+ }
3069
3085
  };
3070
3086
 
3071
3087
  // cli/shared/src/auth.js
@@ -3084,30 +3100,74 @@ function loadAuth() {
3084
3100
  }
3085
3101
 
3086
3102
  // cli/shared/src/httpClient.js
3103
+ var SNIPPET_MAX = 280;
3104
+ function truncateSnippet(text) {
3105
+ const oneLine = text.replace(/\s+/g, " ").trim();
3106
+ if (oneLine.length <= SNIPPET_MAX)
3107
+ return oneLine;
3108
+ return `${oneLine.slice(0, SNIPPET_MAX)}\u2026`;
3109
+ }
3110
+ function buildHttpErrorMessage(ctx, detail) {
3111
+ const parts = [
3112
+ ctx.label ? `${ctx.label}\u5931\u8D25` : "HTTP \u8BF7\u6C42\u5931\u8D25",
3113
+ `[${ctx.status} ${ctx.method} ${ctx.path}]`,
3114
+ detail
3115
+ ].filter(Boolean);
3116
+ return parts.join(" \u2014 ");
3117
+ }
3087
3118
  async function apiRequest(path7, opts = {}) {
3088
3119
  const auth = opts.token || opts.serverUrl ? { token: opts.token ?? "", serverUrl: opts.serverUrl ?? "" } : loadAuth();
3089
- const url = `${auth.serverUrl.replace(/\/$/, "")}${path7}`;
3120
+ const method = (opts.method ?? "GET").toUpperCase();
3121
+ const serverBase = auth.serverUrl.replace(/\/$/, "");
3122
+ const url = `${serverBase}${path7}`;
3090
3123
  const headers = {
3091
3124
  "Content-Type": "application/json",
3092
3125
  Authorization: `Bearer ${auth.token}`,
3093
3126
  ...opts.headers
3094
3127
  };
3095
3128
  const res = await fetch(url, {
3096
- method: opts.method ?? "GET",
3129
+ method,
3097
3130
  headers,
3098
3131
  body: opts.body != null ? JSON.stringify(opts.body) : void 0
3099
3132
  });
3100
3133
  if (!res.ok) {
3101
- let msg = `HTTP ${res.status} ${res.statusText}`;
3102
- try {
3103
- const j = await res.json();
3104
- if (j.message)
3105
- msg = j.message;
3106
- } catch {
3134
+ let detail = `HTTP ${res.status} ${res.statusText}`;
3135
+ let responseSnippet;
3136
+ const rawText = await res.text();
3137
+ if (rawText) {
3138
+ responseSnippet = truncateSnippet(rawText);
3139
+ try {
3140
+ const j = JSON.parse(rawText);
3141
+ if (typeof j.detail === "string" && j.detail.trim()) {
3142
+ detail = j.detail;
3143
+ } else if (Array.isArray(j.detail) && j.detail.length) {
3144
+ detail = j.detail.map((d) => d.msg ?? JSON.stringify(d)).join("; ");
3145
+ } else if (j.message) {
3146
+ detail = j.message;
3147
+ }
3148
+ } catch {
3149
+ if (rawText.trim() && detail.startsWith("HTTP ")) {
3150
+ detail = `\u975E JSON \u54CD\u5E94\uFF08\u53EF\u80FD\u662F\u7F51\u5173/\u524D\u7AEF 404\uFF09`;
3151
+ }
3152
+ }
3107
3153
  }
3108
- throw new NetworkError(msg, res.status);
3154
+ const ctx = {
3155
+ method,
3156
+ path: path7,
3157
+ url,
3158
+ status: res.status,
3159
+ label: opts.label,
3160
+ responseSnippet
3161
+ };
3162
+ throw new NetworkError(buildHttpErrorMessage(ctx, detail), res.status, ctx);
3163
+ }
3164
+ if (res.status === 204 || res.headers.get("content-length") === "0") {
3165
+ return void 0;
3109
3166
  }
3110
- return res.json();
3167
+ const text = await res.text();
3168
+ if (!text.trim())
3169
+ return void 0;
3170
+ return JSON.parse(text);
3111
3171
  }
3112
3172
 
3113
3173
  // cli/shared/src/output.js
@@ -3121,7 +3181,12 @@ function fail(code, message) {
3121
3181
  printJsonSummary({ ok: false, error: { code, message } });
3122
3182
  }
3123
3183
  function handleError(err) {
3124
- if (err instanceof Error) {
3184
+ if (err instanceof NetworkError) {
3185
+ for (const line of err.formatDetailLines()) {
3186
+ console.error(line);
3187
+ }
3188
+ fail(err.code, err.message);
3189
+ } else if (err instanceof Error) {
3125
3190
  const code = err.code ?? "ERR_UNKNOWN";
3126
3191
  console.error(`\u9519\u8BEF: ${err.message}`);
3127
3192
  fail(code, err.message);
@@ -3913,7 +3978,7 @@ function makeMcpCommand() {
3913
3978
  result: {
3914
3979
  protocolVersion: "2024-11-05",
3915
3980
  capabilities: { tools: {} },
3916
- serverInfo: { name: "dazi-onto", version: "3.0.2" }
3981
+ serverInfo: { name: "dazi-onto", version: "3.0.3" }
3917
3982
  }
3918
3983
  };
3919
3984
  process.stdout.write(JSON.stringify(response) + "\n");
@@ -3936,7 +4001,7 @@ function makeMcpCommand() {
3936
4001
 
3937
4002
  // cli/dazi-onto/src/index.ts
3938
4003
  var program2 = new Command();
3939
- program2.name("dazi-onto").description("\u642D\u5B50 Onto CLI \u2014 \u672C\u4F53\uFF08Ontology\uFF09\u7BA1\u7406").version("3.0.2", "-v, --version");
4004
+ program2.name("dazi-onto").description("\u642D\u5B50 Onto CLI \u2014 \u672C\u4F53\uFF08Ontology\uFF09\u7BA1\u7406").version("3.0.3", "-v, --version");
3940
4005
  program2.addCommand(makeSpaceCommand());
3941
4006
  program2.addCommand(makeFunctionCommand());
3942
4007
  program2.addCommand(makeActionCommand());
package/dist/clis/dazi.js CHANGED
@@ -3659,11 +3659,27 @@ var AuthError = class extends DaziError {
3659
3659
  }
3660
3660
  };
3661
3661
  var NetworkError = class extends DaziError {
3662
- constructor(message, status) {
3662
+ constructor(message, status, request) {
3663
3663
  super(message, "ERR_NETWORK", 3);
3664
3664
  this.status = status;
3665
+ this.request = request;
3665
3666
  this.name = "NetworkError";
3666
3667
  }
3668
+ /** 多行人类可读详情,写入 stderr / OutputChannel */
3669
+ formatDetailLines() {
3670
+ const lines = [`\u9519\u8BEF: ${this.message}`];
3671
+ const r = this.request;
3672
+ if (!r)
3673
+ return lines;
3674
+ if (r.label)
3675
+ lines.push(`\u6B65\u9AA4: ${r.label}`);
3676
+ lines.push(`\u8BF7\u6C42: ${r.method} ${r.path}`);
3677
+ lines.push(`\u5B8C\u6574 URL: ${r.url}`);
3678
+ lines.push(`HTTP \u72B6\u6001: ${r.status}`);
3679
+ if (r.responseSnippet)
3680
+ lines.push(`\u54CD\u5E94\u6458\u8981: ${r.responseSnippet}`);
3681
+ return lines;
3682
+ }
3667
3683
  };
3668
3684
 
3669
3685
  // cli/shared/src/auth.js
@@ -3700,30 +3716,74 @@ function tryLoadAuth() {
3700
3716
  }
3701
3717
 
3702
3718
  // cli/shared/src/httpClient.js
3719
+ var SNIPPET_MAX = 280;
3720
+ function truncateSnippet(text2) {
3721
+ const oneLine = text2.replace(/\s+/g, " ").trim();
3722
+ if (oneLine.length <= SNIPPET_MAX)
3723
+ return oneLine;
3724
+ return `${oneLine.slice(0, SNIPPET_MAX)}\u2026`;
3725
+ }
3726
+ function buildHttpErrorMessage(ctx, detail) {
3727
+ const parts = [
3728
+ ctx.label ? `${ctx.label}\u5931\u8D25` : "HTTP \u8BF7\u6C42\u5931\u8D25",
3729
+ `[${ctx.status} ${ctx.method} ${ctx.path}]`,
3730
+ detail
3731
+ ].filter(Boolean);
3732
+ return parts.join(" \u2014 ");
3733
+ }
3703
3734
  async function apiRequest(path13, opts = {}) {
3704
3735
  const auth = opts.token || opts.serverUrl ? { token: opts.token ?? "", serverUrl: opts.serverUrl ?? "" } : loadAuth();
3705
- const url = `${auth.serverUrl.replace(/\/$/, "")}${path13}`;
3736
+ const method = (opts.method ?? "GET").toUpperCase();
3737
+ const serverBase = auth.serverUrl.replace(/\/$/, "");
3738
+ const url = `${serverBase}${path13}`;
3706
3739
  const headers = {
3707
3740
  "Content-Type": "application/json",
3708
3741
  Authorization: `Bearer ${auth.token}`,
3709
3742
  ...opts.headers
3710
3743
  };
3711
3744
  const res = await fetch(url, {
3712
- method: opts.method ?? "GET",
3745
+ method,
3713
3746
  headers,
3714
3747
  body: opts.body != null ? JSON.stringify(opts.body) : void 0
3715
3748
  });
3716
3749
  if (!res.ok) {
3717
- let msg = `HTTP ${res.status} ${res.statusText}`;
3718
- try {
3719
- const j = await res.json();
3720
- if (j.message)
3721
- msg = j.message;
3722
- } catch {
3750
+ let detail = `HTTP ${res.status} ${res.statusText}`;
3751
+ let responseSnippet;
3752
+ const rawText = await res.text();
3753
+ if (rawText) {
3754
+ responseSnippet = truncateSnippet(rawText);
3755
+ try {
3756
+ const j = JSON.parse(rawText);
3757
+ if (typeof j.detail === "string" && j.detail.trim()) {
3758
+ detail = j.detail;
3759
+ } else if (Array.isArray(j.detail) && j.detail.length) {
3760
+ detail = j.detail.map((d) => d.msg ?? JSON.stringify(d)).join("; ");
3761
+ } else if (j.message) {
3762
+ detail = j.message;
3763
+ }
3764
+ } catch {
3765
+ if (rawText.trim() && detail.startsWith("HTTP ")) {
3766
+ detail = `\u975E JSON \u54CD\u5E94\uFF08\u53EF\u80FD\u662F\u7F51\u5173/\u524D\u7AEF 404\uFF09`;
3767
+ }
3768
+ }
3723
3769
  }
3724
- throw new NetworkError(msg, res.status);
3770
+ const ctx = {
3771
+ method,
3772
+ path: path13,
3773
+ url,
3774
+ status: res.status,
3775
+ label: opts.label,
3776
+ responseSnippet
3777
+ };
3778
+ throw new NetworkError(buildHttpErrorMessage(ctx, detail), res.status, ctx);
3779
+ }
3780
+ if (res.status === 204 || res.headers.get("content-length") === "0") {
3781
+ return void 0;
3725
3782
  }
3726
- return res.json();
3783
+ const text2 = await res.text();
3784
+ if (!text2.trim())
3785
+ return void 0;
3786
+ return JSON.parse(text2);
3727
3787
  }
3728
3788
 
3729
3789
  // cli/shared/src/output.js
@@ -3737,7 +3797,12 @@ function fail(code, message) {
3737
3797
  printJsonSummary({ ok: false, error: { code, message } });
3738
3798
  }
3739
3799
  function handleError(err2) {
3740
- if (err2 instanceof Error) {
3800
+ if (err2 instanceof NetworkError) {
3801
+ for (const line of err2.formatDetailLines()) {
3802
+ console.error(line);
3803
+ }
3804
+ fail(err2.code, err2.message);
3805
+ } else if (err2 instanceof Error) {
3741
3806
  const code = err2.code ?? "ERR_UNKNOWN";
3742
3807
  console.error(`\u9519\u8BEF: ${err2.message}`);
3743
3808
  fail(code, err2.message);
@@ -3959,7 +4024,7 @@ function makeEnvCommand() {
3959
4024
  return new Command("env").description("\u663E\u793A\u73AF\u5883\u4FE1\u606F").action(() => {
3960
4025
  const auth = tryLoadAuth();
3961
4026
  const env = {
3962
- version: "3.0.2",
4027
+ version: "3.0.3",
3963
4028
  node: process.version,
3964
4029
  platform: `${import_os5.default.type()} ${import_os5.default.arch()}`,
3965
4030
  serverUrl: getServerUrl(),
@@ -5629,7 +5694,7 @@ function dispatch(msg) {
5629
5694
  result: {
5630
5695
  protocolVersion: "2024-11-05",
5631
5696
  capabilities: { tools: {} },
5632
- serverInfo: { name: "dazi", version: "3.0.2" }
5697
+ serverInfo: { name: "dazi", version: "3.0.3" }
5633
5698
  }
5634
5699
  };
5635
5700
  case "initialized":
@@ -5752,7 +5817,7 @@ function forwardToCli(cliName, extraArgs) {
5752
5817
  process.exit(result.status ?? 1);
5753
5818
  }
5754
5819
  var program2 = new Command();
5755
- program2.name("dazi").description("\u642D\u5B50 v3 \u2014 Onto / Flow / App \u7EDF\u4E00 CLI").version("3.0.2", "-v, --version");
5820
+ program2.name("dazi").description("\u642D\u5B50 v3 \u2014 Onto / Flow / App \u7EDF\u4E00 CLI").version("3.0.3", "-v, --version");
5756
5821
  program2.addCommand(makeAuthCommand());
5757
5822
  program2.addCommand(makeDoctorCommand());
5758
5823
  program2.addCommand(makeEnvCommand());
@@ -1,7 +1,7 @@
1
1
  # 流程项目 AI 工作手册
2
2
 
3
3
  **文档 ID**: `flow/ai-workflow-playbook`
4
- **适用**: Cursor / Trae / 任何 Agent 修改 `项目/flow_*/流程/<名>/`
4
+ **适用**: Cursor / Trae / 任何 Agent 修改 `项目/<业务名>/流程/flows/<流程名>/`
5
5
 
6
6
  > 完整文件规范见 [流程本地文件规范](./local-files-spec.md)。
7
7
 
@@ -34,20 +34,21 @@
34
34
  ## 3. 标准流程(改现有 excel-python)
35
35
 
36
36
  ```powershell
37
- cd "项目\flow_xxx\流程\<流程名>"
37
+ # 推荐绝对路径(禁止在 dazi-work 根 --dir .)
38
+ $flowDir = "D:\path\to\dazi-work\项目\<业务名>\流程\flows\<流程名>"
38
39
 
39
- dazi flow project doctor --dir .
40
+ dazi flow project doctor --dir $flowDir
40
41
  # 若不一致:
41
- dazi flow project repair-meta --dir .
42
+ dazi flow project repair-meta --dir $flowDir
42
43
 
43
44
  # 改 flow.json 配置后:
44
- dazi flow project push --dir . --canvas
45
+ dazi flow project push --dir $flowDir --canvas
45
46
 
46
47
  # 改 code.py 后:
47
- dazi flow node push --node <node_uuid> --dir .
48
+ dazi flow node push --node <node_uuid> --dir $flowDir
48
49
 
49
- dazi flow run node-exec --node <node_uuid> --dir .
50
- dazi flow run flow-exec --dir . --type debug
50
+ dazi flow run node-exec --node <node_uuid> --dir $flowDir
51
+ dazi flow run flow-exec --dir $flowDir --type debug
51
52
  ```
52
53
 
53
54
  确认终端出现 **`✅ 画布已全量推送`**。
@@ -1,7 +1,7 @@
1
1
  # 数据流程项目开发指南
2
2
 
3
3
  **文档 ID**: `flow/flow-project-guide`
4
- **适用**: `dazi-vscode` v3.1+、`dazi-work` 工作区、`项目/flow_*` 流程项目
4
+ **适用**: `dazi-vscode` v3.0.3+、`dazi-work` 工作区、业务项目 `项目/<业务名>/`
5
5
 
6
6
  ---
7
7
 
@@ -11,8 +11,8 @@
11
11
  | ---------- | --------------------------------------------------------------- | ------------------- |
12
12
  | CLI 入口 | `dazi flow …` → `dazi-flow`(Trae / VS Code / Cursor 交付环境) |
13
13
  | **本地文件** | **[流程本地文件规范](./local-files-spec.md)**(AI 必读) |
14
- | 工作区 | `dazi-work` + `项目/flow_<名>/` |
15
- | 本地流程树 | `流程/<名>/flow.json` + `节点/<名>/code.*` |
14
+ | 工作区 | `dazi-work` + `项目/<业务名>/`(含 `本体/`、`流程/`、`应用/`) |
15
+ | 本地流程树 | `流程/flows/<流程名>/flow.json` + `节点/<名>/code.*` |
16
16
  | 画布真理源 | **`flow.json`**(= 平台 `config_json` 镜像,代码已剥离) |
17
17
  | 代码真理源 | \*\*`节点/<名>/code.sql | py`** + `node push` |
18
18
  | 主交互 | **资源管理器右键** + MVP 流程设计器 |
@@ -29,24 +29,28 @@ dazi-work/
29
29
  ├── scripts/
30
30
  │ └── dazi.ps1 ← 终端/Trae 中运行搭子 CLI 的入口
31
31
  └── 项目/
32
- └── flow_数据集成01/
33
- ├── README.md 项目元信息
34
- ├── 快速启动.md 项目级入门
35
- ├── 规划/
32
+ └── 财务分析02/ ← 业务项目名(无 flow_/onto_/app_ 前缀)
33
+ ├── README.md
34
+ ├── 本体/ontos/…
35
+ ├── 应用/apps/…
36
36
  └── 流程/
37
- └── 客户数据清洗/ ← 一个流程 = 一个目录
38
- ├── 快速启动_<流程名>.md pull 后生成(flowId、常用命令、AI 单文件入口)
39
- ├── flow.json ★ 画布(节点配置 + 边,不含代码正文)
40
- ├── flow.meta.json flowId、uuid 映射、代码指纹(pull / node new / repair-meta 维护,勿手改)
41
- ├── 节点/
42
- │ └── SQL查询/
43
- ├── code.sql ★ 代码唯一真理源
44
- │ └── node.info.json
45
- ├── 变量/ 调试 Run 变量只读派生(schema + 预览)
46
- └── sales_df.json
47
- └── _run/ 测试/运行产物(*.last-error.md 等)
37
+ ├── README.md 流程工作区说明
38
+ ├── 规划/
39
+ └── flows/ 各流程实例容器
40
+ └── 客户数据清洗/ ← 一个流程 = 一个目录
41
+ ├── 快速启动_<流程名>.md pull 后生成(flowId、绝对路径命令、AI 入口)
42
+ ├── flow.json ★ 画布(节点配置 + 边,不含代码正文)
43
+ ├── flow.meta.json flowId、uuid 映射、代码指纹(勿手改)
44
+ ├── 节点/
45
+ │ └── SQL查询/
46
+ ├── code.sql 代码唯一真理源
47
+ └── node.info.json
48
+ ├── 变量/ 调试 Run 变量只读派生
49
+ └── _run/ 测试/运行产物(*.last-error.md 等)
48
50
  ```
49
51
 
52
+ > **禁止**在 `dazi-work` **工作区根**对流程命令使用 `--dir .`(可能误读根目录残留的 `flow.meta.json`,导致 flowId 与目标流程不一致)。`--dir` 必须指向含 `flow.json` 的 `flows/<流程名>/` 目录,**推荐绝对路径**。
53
+
50
54
  **关键约定**
51
55
 
52
56
  - 节点 `type` 在画布上恒为 `"custom"`,**业务类型在 `data.type`**(如 `sql-query`、`python-script`)。
@@ -82,23 +86,30 @@ dazi flow <子命令...>
82
86
  | `dazi-flow run node-exec …` | `dazi flow run node-exec …` |
83
87
  | `dazi-flow variable pull …` | `dazi flow variable pull …` |
84
88
 
85
- **工作目录技巧**:多数命令支持 `--dir <流程目录>`。也可 **`cd` 到流程目录**后省略 `--dir`(cwd `流程/<名>/`)。
89
+ **`--dir` 约定**(Trae / Agent 必读):
90
+
91
+ | 方式 | 说明 |
92
+ |------|------|
93
+ | **推荐:绝对路径** | `--dir "D:\path\to\dazi-work\项目\<业务名>\流程\flows\<流程名>"`,不依赖终端 `cd` |
94
+ | 可选:`cd` + `--dir .` | 仅当已确认终端位于目标 `flows/<流程名>/` 时 |
95
+ | **禁止** | 在 `dazi-work` 根执行 `project status/push/pull --dir .` |
96
+
97
+ CLI 会校验目录含 `flow.json`;从 `节点/` 子路径执行时可向上解析到流程目录。
86
98
 
87
99
  ```powershell
88
- # dazi-work
100
+ # 鉴权(可在 dazi-work 根)
89
101
  cd D:\path\to\dazi-work
90
102
  dazi auth whoami
91
103
 
92
- # 拉取平台流程到本地(首次)
93
- dazi flow project pull --flow 98 --dir "项目\flow_流程项目01\流程\MyFlow0529"
104
+ # 拉取平台流程(推荐绝对路径 --dir)
105
+ dazi flow project pull --flow 98 --dir "D:\path\to\dazi-work\项目\财务分析02\流程\flows\MyFlow0529"
94
106
 
95
- # 进入流程目录后,后续命令可省略 --dir
96
- cd "项目\flow_流程项目01\流程\MyFlow0529"
97
- dazi flow project status
98
- dazi flow node push --node <node_uuid>
107
+ # 状态自检:输出 flowId / 流程名须与 快速启动_*.md 一致
108
+ dazi flow project status --dir "D:\path\to\dazi-work\项目\财务分析02\流程\flows\MyFlow0529"
109
+ dazi flow node push --node <node_uuid> --dir "D:\path\to\dazi-work\项目\财务分析02\流程\flows\MyFlow0529"
99
110
  ```
100
111
 
101
- **常用子命令速查**(拉取 / 提交 / 测试 / 变量等)见 [Flow 文档索引 · 流程项目常用命令](./flows-guide.md#流程项目flow_-常用命令)。Plan、数据源等专题见 [执行计划](./plan-guide.md)、[数据源管理](./source-guide.md)。
112
+ **常用子命令速查**见 [Flow 文档索引 · 流程项目常用命令](./flows-guide.md#流程项目业务项目常用命令)。Plan、数据源等见 [执行计划](./plan-guide.md)、[数据源管理](./source-guide.md)。
102
113
 
103
114
  ---
104
115
 
@@ -106,7 +117,7 @@ dazi flow node push --node <node_uuid>
106
117
 
107
118
  ```text
108
119
  1. 新建或拉取
109
- 扩展:项目/flow_* → 新建流程 / 拉取平台流程
120
+ 扩展:右键 `流程/flows/` → 新建流程 / 拉取平台流程
110
121
  CLI: flow project pull --flow <id> --dir <流程目录>
111
122
 
112
123
  2. 改代码
@@ -163,7 +174,7 @@ dazi flow node push --node <node_uuid>
163
174
  | `节点/<名>/code.*` | 提交、测试、拉取 |
164
175
  | `变量/` | 同步变量到本地 |
165
176
  | `变量/<名>.json` | 刷新变量、查看变量信息 |
166
- | `项目/flow_*` | 新建流程、拉取平台流程 |
177
+ | `流程/flows/`(容器目录) | 新建流程、拉取平台流程 |
167
178
  | **数据资源 → 文件上传管理** | 浏览平台登记文件、**拉取到本地资源**、复制 AI 附加说明 |
168
179
 
169
180
  设计器工具栏:**保存 / 校验 / 运行 / 提交 / 拉取**。
@@ -508,3 +519,4 @@ VS Code **打开流程设计器**(右键 `flow.json`)时:
508
519
  | 变量查看失败 | 先 **测试节点** 或 **运行流程**;确认 `flow.meta.json` 有 `flowId` |
509
520
  | 节点测试报缺上游变量 | 先运行上游节点,或 **运行整流程(debug)** 再测当前节点 |
510
521
  | 代码改了平台没更新 | `node push` 或 `project push`;看 `project status` 是否脏 |
522
+ | flowId 与文档不一致 | 在 dazi-work 根或错误目录执行 `--dir .`;改用 `flows/<名>/` 绝对路径 |
@@ -23,34 +23,41 @@
23
23
 
24
24
  ## 终端命令前缀
25
25
 
26
- 在 **`dazi-work` 根目录**(Trae、VS Code、Cursor 交付环境):
26
+ 命令前缀(Trae、VS Code、Cursor 交付环境):
27
27
 
28
28
  ```powershell
29
29
  dazi flow <子命令...>
30
30
  ```
31
31
 
32
- 等价于开发时的 `dazi-flow <子命令...>`。示例:
32
+ 等价于开发时的 `dazi-flow <子命令...>`。
33
+
34
+ > **流程子命令的 `--dir`** 须指向 `项目/<业务名>/流程/flows/<流程名>/`(含 `flow.json`),**推荐绝对路径**。**禁止**在 `dazi-work` 工作区根使用 `--dir .`。
35
+
36
+ 示例:
33
37
 
34
38
  ```powershell
35
39
  dazi flow flows list
36
- dazi flow project pull --flow 98 --dir "项目\flow_xxx\流程\MyFlow"
40
+ dazi flow project pull --flow 98 --dir "D:\path\to\dazi-work\项目\财务分析02\流程\flows\MyFlow"
41
+ dazi flow project status --dir "D:\path\to\dazi-work\项目\财务分析02\流程\flows\MyFlow"
37
42
  ```
38
43
 
39
44
  ---
40
45
 
41
- ## 流程项目(`项目/flow_*`)常用命令
42
-
43
- | 任务 | 命令 |
44
- | ------------------ | --------------------------------------------------- |
45
- | 拉取平台流程到本地 | `flow project pull --flow <id> --dir <流程目录>` |
46
- | 提交代码 + 画布 | `flow project push --dir <流程目录> --canvas` |
47
- | 目录一致性检查 | `flow project doctor --dir <流程目录>` |
48
- | 修复 meta 索引 | `flow project repair-meta --dir <流程目录>` |
49
- | 查看本地改动 | `flow project status --dir <流程目录>` |
50
- | 提交单个节点代码 | `flow node push --node <uuid> --dir <流程目录>` |
51
- | 单节点测试 | `flow run node-exec --node <uuid> --dir <流程目录>` |
52
- | 整流程运行 | `flow run flow-exec --dir <流程目录> --type debug` |
53
- | 拉取变量 | `flow variable pull --name <名> --dir <流程目录>` |
46
+ ## 流程项目(业务项目)常用命令
47
+
48
+ | 任务 | 命令 |
49
+ | ------------------ | -------------------------------------------------------------------- |
50
+ | 拉取平台流程到本地 | `flow project pull --flow <id> --dir <flows/<名>/绝对路径>` |
51
+ | 提交代码 + 画布 | `flow project push --dir <flows/<名>/绝对路径> --canvas` |
52
+ | 目录一致性检查 | `flow project doctor --dir <flows/<名>/绝对路径>` |
53
+ | 修复 meta 索引 | `flow project repair-meta --dir <flows/<名>/绝对路径>` |
54
+ | 查看本地改动 | `flow project status --dir <flows/<名>/绝对路径>` |
55
+ | 提交单个节点代码 | `flow node push --node <uuid> --dir <flows/<名>/绝对路径>` |
56
+ | 单节点测试 | `flow run node-exec --node <uuid> --dir <flows/<名>/绝对路径>` |
57
+ | 整流程运行 | `flow run flow-exec --dir <flows/<名>/绝对路径> --type debug` |
58
+ | 拉取变量 | `flow variable pull --name <名> --dir <flows/<名>/绝对路径>` |
59
+
60
+ `<flows/<名>/绝对路径>` = `…/项目/<业务名>/流程/flows/<流程名>`。执行 `status` 后核对输出的 **flowId / 流程名** 与 `快速启动_*.md` 一致。
54
61
 
55
62
  扩展侧栏/资源管理器右键与上表 **同源**,见 [flow-project-guide](./flow-project-guide.md#6-资源管理器菜单主交互)。
56
63
 
@@ -1,7 +1,7 @@
1
1
  # 流程本地文件规范与示例
2
2
 
3
3
  **文档 ID**: `flow/local-files-spec`
4
- **适用**: `项目/flow_*/流程/<名>/` 目录、AI Agent、流程设计器
4
+ **适用**: `项目/<业务名>/流程/flows/<流程名>/` 目录、AI Agent、流程设计器
5
5
  **关联**: [AI 工作手册](./ai-workflow-playbook.md)、[数据流程项目开发指南](./flow-project-guide.md)
6
6
 
7
7
  ---
@@ -24,10 +24,10 @@
24
24
  ## 2. 标准目录树
25
25
 
26
26
  ```text
27
- 流程/<流程名>/
27
+ 项目/<业务名>/流程/flows/<流程名>/
28
28
  ├── flow.json # 画布真理源(轻量,无 pythonCode/sql 正文)
29
29
  ├── flow.meta.json # 工程索引(CLI 维护)
30
- ├── 快速启动_<流程名>.md # pull 后生成(含一致性检查)
30
+ ├── 快速启动_<流程名>.md # pull 后生成(含绝对路径命令、一致性检查)
31
31
  ├── 节点/
32
32
  │ └── Excel成本报表解析/
33
33
  │ ├── code.py # 代码真理源
@@ -1,7 +1,7 @@
1
1
  # 节点代码编写指南
2
2
 
3
3
  **文档 ID**: `flow/node-code-guide`
4
- **适用**: `项目/flow_*/流程/<名>/节点/<节点名>/code.*`
4
+ **适用**: `项目/<业务名>/流程/flows/<流程名>/节点/<节点名>/code.*`
5
5
  **前置**: **[流程本地文件规范](./local-files-spec.md)**(必读)、[数据流程项目开发指南](./flow-project-guide.md)、[流程变量系统指南](./variables-guide.md)
6
6
 
7
7
  > 设计器「打开代码」依赖 `flow.meta.json` 中该节点的 `dir`+`codeFile`。若打不开,先 `dazi flow project doctor` → `repair-meta`。
@@ -40,19 +40,19 @@
40
40
  ## 2. 修改代码的标准流程
41
41
 
42
42
  ```powershell
43
- # 1. 进入流程目录(dazi-work 根下)
44
- cd "项目\flow_xxx\流程\MyFlow"
43
+ # 1. 确定流程目录(推荐绝对路径)
44
+ $flowDir = "D:\path\to\dazi-work\项目\<业务名>\流程\flows\MyFlow"
45
45
 
46
46
  # 2. 编辑 节点/SQL查询/code.sql 等
47
47
 
48
48
  # 3. 查看是否有本地改动
49
- dazi flow project status
49
+ dazi flow project status --dir $flowDir
50
50
 
51
- # 4. 单节点测试(会先 GET debug-run,再 POST 单节点运行)
52
- dazi flow run node-exec --node <node_uuid> --dir .
51
+ # 4. 单节点测试
52
+ dazi flow run node-exec --node <node_uuid> --dir $flowDir
53
53
 
54
54
  # 5. 提交代码到平台
55
- dazi flow node push --node <node_uuid> --dir .
55
+ dazi flow node push --node <node_uuid> --dir $flowDir
56
56
  ```
57
57
 
58
58
  `node_uuid` 在 `flow.meta.json` → `nodes.<uuid>`,或设计器属性面板、 `node.info.json` 中查看。
@@ -3,17 +3,17 @@
3
3
  **文档 ID**: `flow/run-guide`
4
4
 
5
5
  **命令前缀**(`dazi-work` 根):`dazi flow …`
6
- **流程项目**:在 `项目/flow_*/流程/<名>/` 下执行,或使用 `--dir <流程目录>`。
6
+ **流程项目**:`--dir` 指向 `项目/<业务名>/流程/flows/<流程名>/`(**推荐绝对路径**;禁止在 `dazi-work` 根 `--dir .`)。
7
7
 
8
8
  ---
9
9
 
10
10
  ## 1. 流程项目:单节点测试(最常用)
11
11
 
12
12
  ```powershell
13
- cd "项目\flow_xxx\流程\MyFlow"
13
+ $flowDir = "D:\path\to\dazi-work\项目\<业务名>\流程\flows\MyFlow"
14
14
 
15
15
  # 按 node_uuid 测试(CLI 内部翻译为语义 nodeId)
16
- dazi flow run node-exec --node <node_uuid> --dir .
16
+ dazi flow run node-exec --node <node_uuid> --dir $flowDir
17
17
  ```
18
18
 
19
19
  **行为**
@@ -84,16 +84,16 @@ GET /flows/{id}/debug-run → 绑定 ads_flows.debug_run_id
84
84
  ```
85
85
 
86
86
  ```powershell
87
- cd "项目\flow_xxx\流程\MyFlow"
87
+ $flowDir = "D:\path\to\dazi-work\项目\<业务名>\流程\flows\MyFlow"
88
88
 
89
89
  # 先运行产出变量的上游节点,或整流程 debug
90
- dazi flow run node-exec --node <上游uuid> --dir .
90
+ dazi flow run node-exec --node <上游uuid> --dir $flowDir
91
91
 
92
92
  # 拉取单个变量(列信息 + 前 10 行)
93
- dazi flow variable pull --name sales_clean --dir .
93
+ dazi flow variable pull --name sales_clean --dir $flowDir
94
94
 
95
95
  # 同步调试 Run 中全部变量
96
- dazi flow variable sync --dir .
96
+ dazi flow variable sync --dir $flowDir
97
97
  ```
98
98
 
99
99
  - 设计器:选中节点 → **`output_variable_name`** 旁 **📊**
@@ -49,7 +49,7 @@ dazi onto function list --space <space-id>
49
49
  | ---------------------------------------------------------------- | ----------------------------------------------------------------------- |
50
50
  | `dazi auth whoami` | 原 `dazi auth whoami` |
51
51
  | `dazi onto script publish ...` | 原 `dazi onto script publish ...`(**勿用** `dazi-onto`) |
52
- | `dazi flow project pull --flow 98 --dir 项目\flow_x\流程\MyFlow` | 流程项目拉取 |
52
+ | `dazi flow project pull --flow 98 --dir …\项目\<业务名>\流程\flows\MyFlow` | 流程项目拉取(`--dir` 推荐绝对路径) |
53
53
  | `dazi flow run node-exec --node <uuid> --dir <流程目录>` | 单节点测试 |
54
54
  | `pnpm run dazi-app -- upload ...` | 原 `dazi-app upload ...`(须在**应用项目根**,含 `sdk/`、`templates/`) |
55
55
 
@@ -65,7 +65,8 @@ dazi onto function list --space <space-id>
65
65
  因此文档里的 `dazi-flow project pull …` 在 Trae / VS Code 交付环境中应写为:
66
66
 
67
67
  ```powershell
68
- dazi flow project pull --flow 98 --dir "项目\flow_xxx\流程\MyFlow"
68
+ # --dir 须指向 flows/<流程名>/(含 flow.json);禁止在 dazi-work --dir .
69
+ dazi flow project pull --flow 98 --dir "D:\path\to\dazi-work\项目\财务分析02\流程\flows\MyFlow"
69
70
  ```
70
71
 
71
72
  流程项目开发详见 [flow/flow-project-guide](../flow/flow-project-guide.md)。