@dazitech/cli 3.0.2 → 3.0.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 +2 -2
- package/dist/clis/dazi-app.js +1 -1
- package/dist/clis/dazi-flow.js +2395 -1680
- package/dist/clis/dazi-onto.js +79 -14
- package/dist/clis/dazi.js +80 -15
- package/dist/docs/flow/ai-workflow-playbook.md +9 -8
- package/dist/docs/flow/flow-project-guide.md +41 -29
- package/dist/docs/flow/flows-guide.md +23 -16
- package/dist/docs/flow/local-files-spec.md +3 -3
- package/dist/docs/flow/node-code-guide.md +7 -7
- package/dist/docs/flow/run-guide.md +3 -3
- package/dist/docs/flow/variables-guide.md +4 -4
- package/dist/docs/guides/cli-invocation.md +3 -2
- package/dist/docs/guides/cli-reference.md +3 -1
- package/dist/docs/guides/flow-consistency-checklist.md +3 -3
- package/dist/docs/guides/quickstart.md +1 -1
- package/dist/docs/guides/troubleshooting.md +6 -5
- package/dist/docs/index.json +1 -1
- package/dist/examples/index.json +1 -1
- package/dist/prompts/index.json +1 -1
- package/package.json +1 -1
package/dist/clis/dazi-onto.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
3981
|
+
serverInfo: { name: "dazi-onto", version: "3.0.4" }
|
|
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.
|
|
4004
|
+
program2.name("dazi-onto").description("\u642D\u5B50 Onto CLI \u2014 \u672C\u4F53\uFF08Ontology\uFF09\u7BA1\u7406").version("3.0.4", "-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
|
|
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
|
|
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
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
4027
|
+
version: "3.0.4",
|
|
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.
|
|
5697
|
+
serverInfo: { name: "dazi", version: "3.0.4" }
|
|
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.
|
|
5820
|
+
program2.name("dazi").description("\u642D\u5B50 v3 \u2014 Onto / Flow / App \u7EDF\u4E00 CLI").version("3.0.4", "-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 修改
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
4
|
+
**适用**: `dazi-vscode` v3.0.4+、`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` +
|
|
15
|
-
| 本地流程树 |
|
|
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_
|
|
33
|
-
├── README.md
|
|
34
|
-
├──
|
|
35
|
-
├──
|
|
32
|
+
└── 财务分析02/ ← 业务项目名(无 flow_/onto_/app_ 前缀)
|
|
33
|
+
├── README.md
|
|
34
|
+
├── 本体/ontos/…
|
|
35
|
+
├── 应用/apps/…
|
|
36
36
|
└── 流程/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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 "
|
|
104
|
+
# 拉取平台流程(推荐绝对路径 --dir)
|
|
105
|
+
dazi flow project pull --flow 98 --dir "D:\path\to\dazi-work\项目\财务分析02\流程\flows\MyFlow0529"
|
|
94
106
|
|
|
95
|
-
#
|
|
96
|
-
|
|
97
|
-
dazi flow
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
|
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
|
-
|
|
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 "
|
|
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
|
-
##
|
|
42
|
-
|
|
43
|
-
| 任务 | 命令
|
|
44
|
-
| ------------------ |
|
|
45
|
-
| 拉取平台流程到本地 | `flow project pull --flow <id> --dir
|
|
46
|
-
| 提交代码 + 画布 | `flow project push --dir
|
|
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
|
|
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
|
-
**适用**:
|
|
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
|
-
**适用**:
|
|
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.
|
|
44
|
-
|
|
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.
|
|
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
|
-
|
|
6
|
+
**流程项目**:`--dir` 指向 `项目/<业务名>/流程/flows/<流程名>/`(**推荐绝对路径**;禁止在 `dazi-work` 根 `--dir .`)。
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
## 1. 流程项目:单节点测试(最常用)
|
|
11
11
|
|
|
12
12
|
```powershell
|
|
13
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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)。
|