@fieldwangai/agentflow 0.1.160 → 0.1.163
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/bin/lib/auth.mjs +231 -14
- package/bin/lib/catalog-flows.mjs +2 -0
- package/bin/lib/cli-auth-page.mjs +103 -0
- package/bin/lib/flow-dsl/codegen.mjs +23 -2
- package/bin/lib/flow-dsl/lint.mjs +44 -0
- package/bin/lib/flow-dsl/parser.mjs +68 -1
- package/bin/lib/marketplace-usage.mjs +218 -0
- package/bin/lib/marketplace.mjs +183 -3
- package/bin/lib/node-package-manifest.mjs +1 -1
- package/bin/lib/skill-runtime.mjs +6 -0
- package/bin/lib/spaces.mjs +200 -0
- package/bin/lib/table.mjs +2 -3
- package/bin/lib/ui-server.mjs +471 -84
- package/bin/lib/workspace-draft.mjs +74 -0
- package/bin/lib/workspace-routes.mjs +484 -4
- package/bin/lib/workspace-server.mjs +373 -30
- package/bin/lib/workspace-state.mjs +2 -1
- package/builtin/nodes/agent_subAgent.md +5 -1
- package/builtin/nodes/context_bundle.md +44 -0
- package/builtin/nodes/context_knowledge.md +29 -0
- package/builtin/nodes/context_skills.md +29 -0
- package/builtin/nodes/context_workspace.md +36 -0
- package/builtin/nodes/control_while.md +12 -5
- package/builtin/nodes/tool_git_worktree_load.md +4 -3
- package/builtin/pipelines/new/workspace.flow.js +1 -1
- package/builtin/web-ui/dist/assets/{WorkflowAssistantThread-Bfo9Ythw.js → WorkflowAssistantThread-DmhIgoD7.js} +1 -1
- package/builtin/web-ui/dist/assets/index-CI9J6Unt.js +873 -0
- package/builtin/web-ui/dist/assets/index-DY5vE7v1.css +1 -0
- package/builtin/web-ui/dist/index.html +2 -2
- package/package.json +5 -1
- package/shared/slot-types.js +1 -0
- package/skills/agentflow-author-flow/SKILL.md +81 -8
- package/skills/agentflow-author-flow/agents/openai.yaml +3 -3
- package/skills/agentflow-cli/SKILL.md +179 -27
- package/skills/agentflow-cli/agents/openai.yaml +2 -2
- package/skills/agentflow-cli/runtime/bin/lib/skill-runtime.mjs +14879 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/agent_subAgent.md +38 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/context_bundle.md +44 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/context_knowledge.md +29 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/context_skills.md +29 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/context_workspace.md +36 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_agent_toBool.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_anyOne.md +19 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_cancelled.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_cd_workspace.md +50 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_delay.md +31 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_end.md +13 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_if.md +21 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_interval_loop.md +55 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_load_mcp.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_load_skills.md +35 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_parse_json.md +25 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_start.md +13 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_subflow_call.md +27 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_toBool.md +27 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_user_workspace.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_wait_until.md +34 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_while.md +131 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_ascii.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_chart.md +32 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_code.md +39 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_html.md +32 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_image.md +36 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_markdown.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_mermaid.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_react_app.md +53 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_table.md +32 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_bool.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_file.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_json.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_password.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_str.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_display_share_link.md +47 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_get_env.md +20 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_git_checkout.md +70 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_git_worktree_load.md +74 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_git_worktree_unload.md +52 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_gitlab_create_mr.md +114 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_jenkins_build.md +67 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_load_key.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_nodejs.md +52 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_print.md +21 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_save_key.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_set_run_env.md +38 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_user_ask.md +27 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_user_check.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_wecom_send_app_markdown.md +57 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_wecom_send_group_markdown.md +45 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_one_click_task.md +44 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_run.md +16 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_scheduled_run.md +16 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_subflow_input.md +14 -0
- package/skills/agentflow-cli/runtime/package.json +6 -0
- package/skills/agentflow-cli/scripts/agentflow-auth-store.mjs +113 -0
- package/skills/agentflow-cli/scripts/agentflow-cli.mjs +457 -28
- package/skills/agentflow-cli/scripts/agentflow-runtime.mjs +11 -4
- package/skills/agentflow-flow-add-instances/SKILL.md +2 -2
- package/skills/agentflow-flow-dsl/SKILL.md +73 -8
- package/skills/agentflow-flow-dsl/agents/openai.yaml +2 -2
- package/skills/agentflow-flow-dsl/references/node-calls.md +6 -2
- package/skills/agentflow-flow-dsl/references/subflow-authoring.md +34 -7
- package/skills/agentflow-flow-edit-node-fields/SKILL.md +3 -3
- package/skills/agentflow-flow-recipes/SKILL.md +1 -1
- package/skills/agentflow-flow-recipes/references/recipes.md +1 -2
- package/skills/agentflow-flow-sync-ui/SKILL.md +1 -1
- package/skills/agentflow-node-dsl/SKILL.md +5 -13
- package/skills/agentflow-node-reference/references/builtin-nodes.md +37 -5
- package/skills/agentflow-workspace-markdown/SKILL.md +1 -1
- package/builtin/web-ui/dist/assets/index-XbeI5foV.js +0 -872
- package/builtin/web-ui/dist/assets/index-e1omCEau.css +0 -1
- package/skills/agentflow-workspace-graph/SKILL.md +0 -85
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
import { getAgentflowDataRoot } from "./paths.mjs";
|
|
6
|
+
|
|
7
|
+
export const SPACES_FILENAME = "spaces.json";
|
|
8
|
+
|
|
9
|
+
function spacesPath() {
|
|
10
|
+
return path.join(getAgentflowDataRoot(), SPACES_FILENAME);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function cleanText(value, max = 200) {
|
|
14
|
+
return String(value || "").trim().slice(0, max);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function normalizeSpaceSlug(value = "") {
|
|
18
|
+
return String(value || "")
|
|
19
|
+
.trim()
|
|
20
|
+
.toLowerCase()
|
|
21
|
+
.replace(/[^a-z0-9_-]+/g, "-")
|
|
22
|
+
.replace(/^-+|-+$/g, "")
|
|
23
|
+
.slice(0, 64);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function normalizeSpaceVisibility(value = "public") {
|
|
27
|
+
return String(value || "").trim().toLowerCase() === "private" ? "private" : "public";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function normalizeSpacePagePath(value = "/") {
|
|
31
|
+
const raw = String(value || "").trim();
|
|
32
|
+
if (!raw || raw === "/") return "/";
|
|
33
|
+
const parts = raw.split("/").map((part) => normalizeSpaceSlug(part)).filter(Boolean);
|
|
34
|
+
return parts.length ? `/${parts.join("/")}` : "/";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function normalizePage(page = {}, index = 0) {
|
|
38
|
+
const shareId = cleanText(page.shareId, 160);
|
|
39
|
+
if (!shareId) return null;
|
|
40
|
+
const pagePath = normalizeSpacePagePath(page.path || page.route || "/");
|
|
41
|
+
return {
|
|
42
|
+
id: cleanText(page.id, 100) || `page_${crypto.randomBytes(8).toString("hex")}`,
|
|
43
|
+
title: cleanText(page.title, 160) || (pagePath === "/" ? "首页" : pagePath.split("/").filter(Boolean).pop()),
|
|
44
|
+
path: pagePath,
|
|
45
|
+
shareId,
|
|
46
|
+
hidden: page.hidden === true,
|
|
47
|
+
order: Number.isFinite(Number(page.order)) ? Number(page.order) : index,
|
|
48
|
+
createdAt: cleanText(page.createdAt, 80) || new Date().toISOString(),
|
|
49
|
+
updatedAt: cleanText(page.updatedAt, 80) || new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function normalizeSpace(space = {}) {
|
|
54
|
+
const ownerId = cleanText(space.ownerId, 100);
|
|
55
|
+
const slug = normalizeSpaceSlug(space.slug);
|
|
56
|
+
if (!ownerId || !slug) return null;
|
|
57
|
+
const pages = (Array.isArray(space.pages) ? space.pages : [])
|
|
58
|
+
.map(normalizePage)
|
|
59
|
+
.filter(Boolean)
|
|
60
|
+
.sort((a, b) => a.order - b.order || a.createdAt.localeCompare(b.createdAt));
|
|
61
|
+
return {
|
|
62
|
+
id: cleanText(space.id, 100) || `space_${crypto.randomBytes(8).toString("hex")}`,
|
|
63
|
+
ownerId,
|
|
64
|
+
slug,
|
|
65
|
+
title: cleanText(space.title, 160) || slug,
|
|
66
|
+
description: cleanText(space.description, 1000),
|
|
67
|
+
visibility: normalizeSpaceVisibility(space.visibility),
|
|
68
|
+
status: String(space.status || "active").trim().toLowerCase() === "paused" ? "paused" : "active",
|
|
69
|
+
pages,
|
|
70
|
+
createdAt: cleanText(space.createdAt, 80) || new Date().toISOString(),
|
|
71
|
+
updatedAt: cleanText(space.updatedAt, 80) || new Date().toISOString(),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function readSpaces() {
|
|
76
|
+
const file = spacesPath();
|
|
77
|
+
if (!fs.existsSync(file)) return [];
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
80
|
+
const input = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.spaces) ? parsed.spaces : [];
|
|
81
|
+
return input.map(normalizeSpace).filter(Boolean);
|
|
82
|
+
} catch {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function writeSpaces(spaces = []) {
|
|
88
|
+
const file = spacesPath();
|
|
89
|
+
const normalized = (Array.isArray(spaces) ? spaces : []).map(normalizeSpace).filter(Boolean);
|
|
90
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
91
|
+
const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
92
|
+
fs.writeFileSync(temp, `${JSON.stringify({ version: 1, spaces: normalized }, null, 2)}\n`, "utf-8");
|
|
93
|
+
fs.renameSync(temp, file);
|
|
94
|
+
return normalized;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function listSpacesForUser(userId = "", isAdmin = false) {
|
|
98
|
+
const actor = cleanText(userId, 100);
|
|
99
|
+
return readSpaces().filter((space) => isAdmin || space.ownerId === actor);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function getSpaceById(id = "") {
|
|
103
|
+
const wanted = cleanText(id, 100);
|
|
104
|
+
return readSpaces().find((space) => space.id === wanted) || null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function getSpaceByRoute(ownerId = "", slug = "") {
|
|
108
|
+
const owner = cleanText(ownerId, 100);
|
|
109
|
+
const safeSlug = normalizeSpaceSlug(slug);
|
|
110
|
+
return readSpaces().find((space) => space.ownerId === owner && space.slug === safeSlug) || null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function createSpace({ ownerId, slug, title, description = "", visibility = "public" } = {}) {
|
|
114
|
+
const owner = cleanText(ownerId, 100);
|
|
115
|
+
const safeSlug = normalizeSpaceSlug(slug || title);
|
|
116
|
+
if (!owner) return { error: "Missing space owner" };
|
|
117
|
+
if (!safeSlug) return { error: "Space slug must contain letters or numbers" };
|
|
118
|
+
const spaces = readSpaces();
|
|
119
|
+
if (spaces.some((space) => space.ownerId === owner && space.slug === safeSlug)) {
|
|
120
|
+
return { error: "Space slug already exists" };
|
|
121
|
+
}
|
|
122
|
+
const now = new Date().toISOString();
|
|
123
|
+
const space = normalizeSpace({
|
|
124
|
+
id: `space_${crypto.randomBytes(8).toString("hex")}`,
|
|
125
|
+
ownerId: owner,
|
|
126
|
+
slug: safeSlug,
|
|
127
|
+
title: title || safeSlug,
|
|
128
|
+
description,
|
|
129
|
+
visibility,
|
|
130
|
+
pages: [],
|
|
131
|
+
createdAt: now,
|
|
132
|
+
updatedAt: now,
|
|
133
|
+
});
|
|
134
|
+
spaces.push(space);
|
|
135
|
+
writeSpaces(spaces);
|
|
136
|
+
return { space };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function updateSpace(id = "", patch = {}) {
|
|
140
|
+
const spaces = readSpaces();
|
|
141
|
+
const index = spaces.findIndex((space) => space.id === cleanText(id, 100));
|
|
142
|
+
if (index < 0) return { error: "Space not found" };
|
|
143
|
+
const current = spaces[index];
|
|
144
|
+
const nextSlug = patch.slug == null ? current.slug : normalizeSpaceSlug(patch.slug);
|
|
145
|
+
if (!nextSlug) return { error: "Space slug must contain letters or numbers" };
|
|
146
|
+
if (spaces.some((space, itemIndex) => itemIndex !== index && space.ownerId === current.ownerId && space.slug === nextSlug)) {
|
|
147
|
+
return { error: "Space slug already exists" };
|
|
148
|
+
}
|
|
149
|
+
const next = normalizeSpace({
|
|
150
|
+
...current,
|
|
151
|
+
...(patch.title == null ? {} : { title: patch.title }),
|
|
152
|
+
...(patch.description == null ? {} : { description: patch.description }),
|
|
153
|
+
...(patch.visibility == null ? {} : { visibility: patch.visibility }),
|
|
154
|
+
...(patch.status == null ? {} : { status: patch.status }),
|
|
155
|
+
slug: nextSlug,
|
|
156
|
+
updatedAt: new Date().toISOString(),
|
|
157
|
+
});
|
|
158
|
+
spaces[index] = next;
|
|
159
|
+
writeSpaces(spaces);
|
|
160
|
+
return { space: next };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function upsertSpacePage(spaceId = "", input = {}) {
|
|
164
|
+
const spaces = readSpaces();
|
|
165
|
+
const spaceIndex = spaces.findIndex((space) => space.id === cleanText(spaceId, 100));
|
|
166
|
+
if (spaceIndex < 0) return { error: "Space not found" };
|
|
167
|
+
const space = spaces[spaceIndex];
|
|
168
|
+
const pagePath = normalizeSpacePagePath(input.path || "/");
|
|
169
|
+
const existingIndex = space.pages.findIndex((page) => page.path === pagePath);
|
|
170
|
+
const previous = existingIndex >= 0 ? space.pages[existingIndex] : {};
|
|
171
|
+
const page = normalizePage({
|
|
172
|
+
...previous,
|
|
173
|
+
...input,
|
|
174
|
+
id: previous.id || input.id,
|
|
175
|
+
path: pagePath,
|
|
176
|
+
order: existingIndex >= 0 ? previous.order : space.pages.length,
|
|
177
|
+
createdAt: previous.createdAt || input.createdAt,
|
|
178
|
+
updatedAt: new Date().toISOString(),
|
|
179
|
+
}, existingIndex >= 0 ? existingIndex : space.pages.length);
|
|
180
|
+
if (!page) return { error: "Missing display share" };
|
|
181
|
+
if (existingIndex >= 0) space.pages[existingIndex] = page;
|
|
182
|
+
else space.pages.push(page);
|
|
183
|
+
space.updatedAt = new Date().toISOString();
|
|
184
|
+
spaces[spaceIndex] = normalizeSpace(space);
|
|
185
|
+
writeSpaces(spaces);
|
|
186
|
+
return { space: spaces[spaceIndex], page };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function deleteSpacePage(spaceId = "", pageId = "") {
|
|
190
|
+
const spaces = readSpaces();
|
|
191
|
+
const spaceIndex = spaces.findIndex((space) => space.id === cleanText(spaceId, 100));
|
|
192
|
+
if (spaceIndex < 0) return { error: "Space not found" };
|
|
193
|
+
const before = spaces[spaceIndex].pages.length;
|
|
194
|
+
spaces[spaceIndex].pages = spaces[spaceIndex].pages.filter((page) => page.id !== cleanText(pageId, 100));
|
|
195
|
+
if (spaces[spaceIndex].pages.length === before) return { error: "Space page not found" };
|
|
196
|
+
spaces[spaceIndex].pages = spaces[spaceIndex].pages.map((page, index) => ({ ...page, order: index }));
|
|
197
|
+
spaces[spaceIndex].updatedAt = new Date().toISOString();
|
|
198
|
+
writeSpaces(spaces);
|
|
199
|
+
return { space: spaces[spaceIndex] };
|
|
200
|
+
}
|
package/bin/lib/table.mjs
CHANGED