@fieldwangai/agentflow 0.1.162 → 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.
Files changed (41) hide show
  1. package/bin/lib/flow-dsl/codegen.mjs +23 -2
  2. package/bin/lib/flow-dsl/lint.mjs +44 -0
  3. package/bin/lib/flow-dsl/parser.mjs +68 -1
  4. package/bin/lib/marketplace-usage.mjs +218 -0
  5. package/bin/lib/marketplace.mjs +183 -3
  6. package/bin/lib/node-package-manifest.mjs +1 -1
  7. package/bin/lib/spaces.mjs +200 -0
  8. package/bin/lib/ui-server.mjs +251 -67
  9. package/bin/lib/workspace-routes.mjs +189 -2
  10. package/bin/lib/workspace-server.mjs +367 -30
  11. package/bin/lib/workspace-state.mjs +2 -1
  12. package/builtin/nodes/agent_subAgent.md +5 -1
  13. package/builtin/nodes/context_bundle.md +44 -0
  14. package/builtin/nodes/context_knowledge.md +29 -0
  15. package/builtin/nodes/context_skills.md +29 -0
  16. package/builtin/nodes/context_workspace.md +36 -0
  17. package/builtin/nodes/control_while.md +7 -0
  18. package/builtin/nodes/tool_git_worktree_load.md +4 -3
  19. package/builtin/web-ui/dist/assets/{WorkflowAssistantThread-CTrXOZ00.js → WorkflowAssistantThread-DmhIgoD7.js} +1 -1
  20. package/builtin/web-ui/dist/assets/index-CI9J6Unt.js +873 -0
  21. package/builtin/web-ui/dist/assets/index-DY5vE7v1.css +1 -0
  22. package/builtin/web-ui/dist/index.html +2 -2
  23. package/package.json +1 -1
  24. package/shared/slot-types.js +1 -0
  25. package/skills/agentflow-cli/SKILL.md +50 -3
  26. package/skills/agentflow-cli/runtime/bin/lib/skill-runtime.mjs +120 -6
  27. package/skills/agentflow-cli/runtime/builtin/nodes/agent_subAgent.md +5 -1
  28. package/skills/agentflow-cli/runtime/builtin/nodes/context_bundle.md +44 -0
  29. package/skills/agentflow-cli/runtime/builtin/nodes/context_knowledge.md +29 -0
  30. package/skills/agentflow-cli/runtime/builtin/nodes/context_skills.md +29 -0
  31. package/skills/agentflow-cli/runtime/builtin/nodes/context_workspace.md +36 -0
  32. package/skills/agentflow-cli/runtime/builtin/nodes/control_while.md +7 -0
  33. package/skills/agentflow-cli/runtime/builtin/nodes/tool_git_worktree_load.md +4 -3
  34. package/skills/agentflow-cli/runtime/package.json +1 -1
  35. package/skills/agentflow-cli/scripts/agentflow-cli.mjs +64 -0
  36. package/skills/agentflow-flow-dsl/SKILL.md +48 -2
  37. package/skills/agentflow-flow-dsl/references/node-calls.md +6 -2
  38. package/skills/agentflow-flow-dsl/references/subflow-authoring.md +34 -7
  39. package/skills/agentflow-node-reference/references/builtin-nodes.md +37 -5
  40. package/builtin/web-ui/dist/assets/index-5uJFccdX.css +0 -1
  41. package/builtin/web-ui/dist/assets/index-BeUfNQRL.js +0 -873
@@ -82,7 +82,7 @@ Draft → 试运行 → 动态修改 → 明确确认 → 发布/定时流程;
82
82
  ## 图结构:workspace.flow.js
83
83
 
84
84
  ```js
85
- import { agent, control, display, file, flow, provide, tool } from "agentflow/flow";
85
+ import { agent, context, control, display, file, flow, provide, tool } from "agentflow/flow";
86
86
  import collectMetrics from "./nodes/collect-metrics"; // 代码节点
87
87
 
88
88
  const dateStr = provide.str("查询日期", { value: "2026-08-06" });
@@ -104,6 +104,46 @@ export const run = flow("Run", collect, analyse, chart);
104
104
 
105
105
  `provide.*` 只是数据源,没有 prev/next 槽,**不要放进 `flow(...)` 链**——被谁引用就跟谁跑。
106
106
 
107
+ ## Context 资源
108
+
109
+ 知识库、Skills 和可写代码仓属于执行上下文,不是业务数据,也不是控制步骤。使用一等
110
+ `context.*` 资源声明它们,再通过一个强类型 Bundle 连接 Agent:
111
+
112
+ ```js
113
+ const productKnowledge = context.knowledge("Likee 产品知识", {
114
+ workspaceIds: ["current"], // 内置 ID;其它值必须原样取自 GET /api/workspaces
115
+ });
116
+
117
+ const developmentSkills = context.skills("研发技能", {
118
+ skills: ["prd-flow", "agentflow-flow-dsl"],
119
+ });
120
+
121
+ const codeWorkspace = context.workspace("执行代码仓", {
122
+ workspaceId: "current",
123
+ access: "read-write",
124
+ });
125
+
126
+ const prdContext = context.bundle("PRD 研发上下文", {
127
+ knowledge: productKnowledge,
128
+ skills: developmentSkills,
129
+ workspace: codeWorkspace,
130
+ });
131
+
132
+ const analyse = agent.subAgent("分析需求", { context: prdContext }, `读取 Context 后分析需求。`);
133
+ export const runWithContext = flow("Run", analyse);
134
+ ```
135
+
136
+ - `context.knowledge / skills / workspace / bundle` 都没有 `prev/next`,不要写进 `flow(...)`。
137
+ 它们通过数据依赖在消费者之前加载。
138
+ - `workspaceIds` 和 `workspaceId` 必须来自当前用户 `GET /api/workspaces` 返回的真实 `id`。不要猜测
139
+ `knowledge://` URI,也不要把 `path/repoUrl/token` 写入 DSL;路径、仓库与凭证由运行环境按用户解析。
140
+ - Skill key 必须来自 `GET /api/skills`。Flow 只保存 Workspace ID 与 Skill key 这些稳定引用。
141
+ - `agent.subAgent` 优先只接一个 `context:context` 引脚。旧的 `knowledgeContext / skillsContext /
142
+ workspaceContext / mcpContext` 文本引脚继续兼容,但新流程不要重复连接两套。
143
+ - Bundle 组合的是执行上下文;普通业务字段仍使用单独的数据引脚,不能塞进 Context。
144
+ - 画布手动创建时,从 Provide/Context 分类添加资源节点,把 Knowledge、Skills、Workspace 分别接入
145
+ Context Bundle,再把 Bundle 的紫色 `context` 输出接到 Agent、Subflow Call 或 While。
146
+
107
147
  ## 四条铁律
108
148
 
109
149
  1. 节点全部声明在**模块顶层**,不要写进函数
@@ -167,6 +207,8 @@ export const run = flow("Run", read, advance, show);
167
207
  - `flow.call(label, subflow, pins)` 是父流程里的真实控制节点,动态引脚由契约生成。
168
208
  - 禁止父流程和内部节点直接跨边界连线;所有值必须经过 `flow.call`。
169
209
  - 禁止递归调用。当前第一版也不允许子流程内部 `wait/deferred`;调用帧恢复能力补齐前会明确失败。
210
+ - Context 需要跨边界时,显式声明 `const contextIn = flow.input("context", "context")`,加入子流程
211
+ inputs,并由父图 `flow.call(..., { context: prdContext })` 传入;禁止直接从父图连接内部 Agent。
170
212
 
171
213
  **`flow.fork` 不是并行。** 它是「一个 `next` 接多个下游」的写法——`flow(a, b, c)` 是线性的,
172
214
  没法在链里写出扇出,所以有了它。编译出来就是两条边,图里不存在 fork 这个东西:
@@ -190,6 +232,7 @@ build.next → testB.prev
190
232
 
191
233
  ```js
192
234
  const advance = control.while("推进到人工边界", {
235
+ context: prdContext,
193
236
  state: initial.value,
194
237
  maxIterations: "20",
195
238
  timeout: "30m",
@@ -200,6 +243,8 @@ export const run4 = flow("Run", advance, report); // done 才继续;wait 会
200
243
  - Condition 固定输出 `decision`,Body 固定输出下一版 `state`;两者都可选输出 `summary`。
201
244
  - `state` 是用户可见的业务状态载体。`iteration`、`idempotencyKey` 由运行时注入,保留在 DSL
202
245
  契约中,但不要要求普通用户在画布上配置或连接。
246
+ - `context` 与 `state` 分离:While 启动时捕获一次 Context,Condition/Body 只有显式声明
247
+ `flow.input("context", "context")` 才会收到它;Context 不进入 state、history 或 checkpoint。
203
248
  - `maxIterations` 和 `timeout` 必须显式设置。新流程不要使用旧的脚本式 While,除非用户要求兼容。
204
249
  - Condition/Body 的完整声明、状态迁移、固定输出和手动画布编辑方式都在专项规范中;不要凭记忆简写。
205
250
 
@@ -276,7 +321,8 @@ const doc = display.html("使用说明", { content: file("docs/guide.html") });
276
321
  | 一行 shell 就能搞定 | `tool.nodejs("名字", {}, \`node -e "..."\`)` |
277
322
  | 给用户看结果 | `display.markdown` / `.code` / `.html` / `.chart` / `.table` |
278
323
  | 加载 skills 给下游 agent | `control.loadSkills` → `skillsContext` |
279
- | 加载知识库 / 代码仓 | `control.cdWorkspace` → `knowledgeContext` |
324
+ | 新流程声明知识库 | `context.knowledge({ workspaceIds })` → Context Bundle |
325
+ | 兼容旧流程加载知识库 / 代码仓 | `control.cdWorkspace` → `knowledgeContext` |
280
326
  | 固定文本 / JSON / 密钥 | `provide.str` / `provide.json` / `provide.password` |
281
327
  | 文本显式解析为 JSON | `control.parseJson` |
282
328
  | 文本转 bool 做分支 | `control.agentToBool` → `prediction` |
@@ -7,14 +7,18 @@
7
7
 
8
8
  | 调用 | 输入引脚 | 输出引脚 |
9
9
  |------|----------|----------|
10
- | `agent.subAgent` | workspaceContext:text, skillsContext:text, mcpContext:text, knowledgeContext:text | result:text |
10
+ | `agent.subAgent` | context:context, workspaceContext:text, skillsContext:text, mcpContext:text, knowledgeContext:text | result:text |
11
+ | `context.bundle` | knowledgeContext:text, skillsContext:text, workspaceContext:text, mcpContext:text | context:context |
12
+ | `context.knowledge` | workspaceIds:json | knowledgeContext:text |
13
+ | `context.skills` | skills:json | skillsContext:text |
14
+ | `context.workspace` | workspaceId:text, access:text | workspaceContext:text |
11
15
  | `control.cdWorkspace` | path:text, label:text, knowledgeContext:text, workspaceContext:text | knowledgeContext:text, workspaceContext:text, cwd:file |
12
16
  | `control.if` | prediction:bool | — |
13
17
  | `control.loadMcp` | serverNames:text | mcpContext:text |
14
18
  | `control.loadSkills` | skillKeys:text | skillsContext:text |
15
19
  | `control.parseJson` | value:text | result:json |
16
20
  | `control.userWorkspace` | — | workspaceContext:text, cwd:file |
17
- | `control.while` | state:json, maxIterations:text, timeout:text | result:json, state:json, decision:text, iterations:text, summary:text, history:json, checkpointFingerprint:text |
21
+ | `control.while` | context:context, state:json, maxIterations:text, timeout:text | result:json, state:json, decision:text, iterations:text, summary:text, history:json, checkpointFingerprint:text |
18
22
  | `display.ascii` | content:text | content:text |
19
23
  | `display.chart` | content:text, filePath:file, workspaceContext:text | content:text |
20
24
  | `display.code` | content:text, language:text, fileName:text, wrap:bool | content:text |
@@ -63,6 +63,25 @@ export const run = flow("Run", callInspect, showSummary);
63
63
  - 一个内部节点只能属于一个子流程。禁止直接跨边界连线、跨子流程连线和递归调用。
64
64
  - 当前子流程内部不接受 `wait/deferred`。需要暂停 While 时,由 Condition 返回 `wait`。
65
65
 
66
+ 执行上下文跨子流程时使用强类型契约,不要拆回四根文本线,也不要跨边界直连:
67
+
68
+ ```js
69
+ const contextIn = flow.input("context", "context");
70
+ const inspect = agent.subAgent("分析", { context: contextIn.value }, `使用已授权上下文分析。`);
71
+
72
+ export const inspectWithContext = flow.subflow(
73
+ "带上下文的分析",
74
+ { context: contextIn },
75
+ flow(inspect),
76
+ { result: inspect.result },
77
+ );
78
+
79
+ const callInspect = flow.call("调用分析", inspectWithContext, { context: prdContext });
80
+ ```
81
+
82
+ `context` 只承载知识、Skills、Workspace、MCP 等执行资源;业务参数仍逐项声明。运行时传递已解析
83
+ Bundle,但凭证始终由环境持有,不写入 DSL 或子流程输出。
84
+
66
85
  普通子流程的输出契约可以变化。画布编辑器中把某个内部数据输出拖到 Return 的 `add output`,再命名
67
86
  输出;重命名或删除后,所有父图 `SUBFLOW CALL` 的同名输出及相关连线必须同步迁移或移除。
68
87
 
@@ -103,33 +122,35 @@ export const run = flow("Run", callInspect, showSummary);
103
122
 
104
123
  ```js
105
124
  const conditionState = flow.input("state", "json");
125
+ const conditionContext = flow.input("context", "context");
106
126
  const conditionIteration = flow.input("iteration", "text");
107
127
  const check = agent.subAgent(
108
128
  "判断是否继续",
109
- { state: conditionState.value },
129
+ { context: conditionContext.value, state: conditionState.value },
110
130
  `检查 state。只返回 continue、wait、done 或 fail 之一。`,
111
131
  );
112
132
 
113
133
  export const shouldContinue = flow.subflow(
114
134
  "是否继续",
115
- { state: conditionState, iteration: conditionIteration },
135
+ { context: conditionContext, state: conditionState, iteration: conditionIteration },
116
136
  flow(check),
117
137
  { decision: check.result },
118
138
  );
119
139
 
120
140
  const bodyState = flow.input("state", "json");
141
+ const bodyContext = flow.input("context", "context");
121
142
  const bodyIteration = flow.input("iteration", "text");
122
143
  const bodyKey = flow.input("idempotencyKey", "text");
123
144
  const step = tool.nodejs(
124
145
  "推进一轮",
125
- { state: bodyState.value, idempotencyKey: bodyKey.value },
146
+ { context: bodyContext.value, state: bodyState.value, idempotencyKey: bodyKey.value },
126
147
  `node ${flowDir}/scripts/advance-one.mjs`,
127
148
  );
128
149
  const nextState = control.parseJson("校验下一版状态", { value: step.result });
129
150
 
130
151
  export const advanceOne = flow.subflow(
131
152
  "执行一轮",
132
- { state: bodyState, iteration: bodyIteration, idempotencyKey: bodyKey },
153
+ { context: bodyContext, state: bodyState, iteration: bodyIteration, idempotencyKey: bodyKey },
133
154
  flow(step, nextState),
134
155
  { state: nextState.result },
135
156
  );
@@ -138,6 +159,7 @@ const initial = provide.json("初始状态", {
138
159
  value: "{\"cursor\":0,\"records\":[],\"valid\":[],\"invalid\":[]}",
139
160
  });
140
161
  const loop = control.while("逐条处理", {
162
+ context: prdContext,
141
163
  state: initial.value,
142
164
  maxIterations: "20",
143
165
  timeout: "30m",
@@ -152,8 +174,11 @@ export const run = flow("Run", loop, summarize, report);
152
174
 
153
175
  | 子流程 | DSL 输入 | DSL 输出 | 产品画布中用户需要理解的部分 |
154
176
  |--------|----------|----------|--------------------------------|
155
- | Condition | `state:json`, `iteration:text` | 必需 `decision:text`;可选 `summary:text` | `state → decision` |
156
- | Body | `state:json`, `iteration:text`, `idempotencyKey:text` | 必需 `state:json`;可选 `summary:text` | `stateₙ → stateₙ₊₁` |
177
+ | Condition | `state:json`, `iteration:text`;可选 `context:context` | 必需 `decision:text`;可选 `summary:text` | `state → decision` |
178
+ | Body | `state:json`, `iteration:text`, `idempotencyKey:text`;可选 `context:context` | 必需 `state:json`;可选 `summary:text` | `stateₙ → stateₙ₊₁` |
179
+
180
+ `context:context` 是 Condition/Body 的可选显式输入。While 顶层连接 Context 后,运行时在循环开始时
181
+ 捕获一次,并只转发给声明了该输入的子流程。它不属于业务状态,不进入 Return、history 或 checkpoint。
157
182
 
158
183
  While Return 是固定契约:Condition 只能返回 `decision/summary`,Body 只能返回 `state/summary`。
159
184
  不要在 While Return 添加任意顶层变量。普通 Subflow Return 才支持动态输出。
@@ -201,7 +226,9 @@ React 组件名、CSS 类名和像素尺寸属于实现细节,不写入 DSL。
201
226
  4. 点击 Body 卡片进入编辑器,连接 Start `state` 到单轮处理节点,最后把完整下一版 JSON 状态连到
202
227
  Return `state`;文本结果先经过 `control.parseJson`。
203
228
  5. 需要摘要时连接可选 `summary`。不要寻找或手工连接 `iteration/idempotencyKey` 产品引脚。
204
- 6. 返回父图,确认 Condition/Body 卡片、状态流说明和两条调用虚线仍存在。
229
+ 6. 需要知识库、Skills 或代码仓时,把 Context Bundle 接到 While 的紫色 `context` 引脚;在需要它的
230
+ Condition/Body 子图 Start 契约中声明 `context`,再接到内部 Agent。不要把 Context 放进 state。
231
+ 7. 返回父图,确认 Condition/Body 卡片、状态流说明和两条调用虚线仍存在。
205
232
 
206
233
  创建普通子流程时,Start/Return 的控制线和数据线方式相同;区别是 Return 输出可以通过 `add output`
207
234
  扩展,父图 SUBFLOW CALL 会同步出现同名输出。
@@ -16,9 +16,9 @@
16
16
  ### agent_subAgent
17
17
 
18
18
  - Display: 子 Agent
19
- - Description: 利用子 Agent 执行任务;可接收 knowledgeContext 读取知识库,可接收 workspaceContext 切换执行工作区,并接收 skillsContext / mcpContext 注入已加载 skills 与 MCP 工具清单。
19
+ - Description: 利用子 Agent 执行任务;新流程优先接收一个强类型 context Bundle。knowledgeContextworkspaceContextskillsContextmcpContext 保留为旧流程兼容引脚。
20
20
  - Runtime: agent/runner
21
- - Inputs: 0. `prev`:node; 1. `workspaceContext`:text; 2. `skillsContext`:text; 3. `mcpContext`:text; 4. `knowledgeContext`:text
21
+ - Inputs: 0. `prev`:node; 1. `context`:context; 2. `workspaceContext`:text; 3. `skillsContext`:text; 4. `mcpContext`:text; 5. `knowledgeContext`:text
22
22
  - Outputs: 0. `next`:node; 1. `result`:text
23
23
 
24
24
  ### workspace_one_click_task
@@ -82,9 +82,9 @@
82
82
  ### control_while
83
83
 
84
84
  - Display: While
85
- - Description: Repeatedly execute either an explicit Condition/Body subflow pair or one legacy deterministic step command (`script` or `scriptRef`) without adding a cycle to the Workspace graph. A Run restarted after `wait` resumes from the saved output state. Preferred DSL form: `control.while("Advance", { state, maxIterations, timeout }, conditionFlow, bodyFlow)`. Condition must accept `state` and `iteration`, and return `decision` plus optional `summary`. Only `continue` invokes Body. Body must accept `state`, `iteration`, and `idempotencyKey`, and return the next `state` plus optional `summary`. `wait`, `done`, and `fail` skip Body. In legacy script mode, the command runs once per iteration and stdout must be exactly one JSON object: `{"decision":"continue|wait|done|fail","state":{},"summary":"..."}`. `continue` starts another iteration, `wait` pauses this Run before downstream nodes, `done` continues downstream, and `fail` fails the node. A missing `state` keeps the previous state. Each step receives `AGENTFLOW_WHILE_STATE` (JSON), the absolute `AGENTFLOW_WHILE_ITERATION`, `AGENTFLOW_WHILE_MAX_ITERATIONS`, `AGENTFLOW_WHILE_TIMEOUT_MS`, and a stable per-iteration `AGENTFLOW_WHILE_IDEMPOTENCY_KEY`. Pass the idempotency key to external write APIs when they support one. Write progress logs to stderr because stdout is reserved for the decision object. The command also supports the same runtime placeholders as `tool.nodejs`, including `${flowDir}` and `${workspaceRoot}`. A waiting checkpoint retains state, history, elapsed active time, and the next absolute iteration. `maxIterations` and `timeout` are cumulative across resumes. A changed input resets the checkpoint; a matching but malformed checkpoint fails closed. Step output is schema-strict and bounded: unknown fields are rejected, state/stdout are limited to 1 MiB, stderr to 256 KiB, and summary to 4000 characters.
85
+ - Description: Repeatedly execute either an explicit Condition/Body subflow pair or one legacy deterministic step command (`script` or `scriptRef`) without adding a cycle to the Workspace graph. A Run restarted after `wait` resumes from the saved output state. Preferred DSL form: `control.while("Advance", { state, maxIterations, timeout }, conditionFlow, bodyFlow)`. An optional typed `context` input is captured once before iteration and forwarded only to Condition/Body subflows that explicitly declare `flow.input("context", "context")`. Context is never copied into business state, history, or checkpoints. Condition must accept `state` and `iteration`, and return `decision` plus optional `summary`. Only `continue` invokes Body. Body must accept `state`, `iteration`, and `idempotencyKey`, and return the next `state` plus optional `summary`. `wait`, `done`, and `fail` skip Body. In legacy script mode, the command runs once per iteration and stdout must be exactly one JSON object: `{"decision":"continue|wait|done|fail","state":{},"summary":"..."}`. `continue` starts another iteration, `wait` pauses this Run before downstream nodes, `done` continues downstream, and `fail` fails the node. A missing `state` keeps the previous state. Each step receives `AGENTFLOW_WHILE_STATE` (JSON), the absolute `AGENTFLOW_WHILE_ITERATION`, `AGENTFLOW_WHILE_MAX_ITERATIONS`, `AGENTFLOW_WHILE_TIMEOUT_MS`, and a stable per-iteration `AGENTFLOW_WHILE_IDEMPOTENCY_KEY`. Pass the idempotency key to external write APIs when they support one. Write progress logs to stderr because stdout is reserved for the decision object. The command also supports the same runtime placeholders as `tool.nodejs`, including `${flowDir}` and `${workspaceRoot}`. A waiting checkpoint retains state, history, elapsed active time, and the next absolute iteration. `maxIterations` and `timeout` are cumulative across resumes. A changed input resets the checkpoint; a matching but malformed checkpoint fails closed. Step output is schema-strict and bounded: unknown fields are rejected, state/stdout are limited to 1 MiB, stderr to 256 KiB, and summary to 4000 characters.
86
86
  - Runtime: bounded Condition/Body state machine
87
- - Inputs: 0. `prev`:node; 1. `state`:json = null; 2. `maxIterations`:text = 20; 3. `timeout`:text = 30m
87
+ - Inputs: 0. `prev`:node; 1. `context`:context; 2. `state`:json = null; 3. `maxIterations`:text = 20; 4. `timeout`:text = 30m
88
88
  - Outputs: 0. `next`:node; 1. `result`:json; 2. `state`:json = null; 3. `decision`:text; 4. `iterations`:text = 0; 5. `summary`:text; 6. `history`:json = []; 7. `checkpointFingerprint`:text
89
89
 
90
90
  ### workspace_run
@@ -124,7 +124,7 @@
124
124
  ### tool_git_worktree_load
125
125
 
126
126
  - Display: Load Worktree
127
- - Description: Create or reuse a Git worktree and expose it as the downstream workspace context. - `repoPath` is required unless `gitContext.repoPath` is connected. - `workspaceContext` is required so the node can preserve the previous execution context. - `branch` is optional. When empty, AgentFlow creates a detached worktree at the current HEAD. - `worktreePath` is optional. When empty, AgentFlow creates a temporary worktree under the current run temp directory. - A worktree created by this node during the current Workspace run is removed when the run finishes or is stopped, even when `worktreePath` is explicitly set. - Existing registered worktrees under the current flow workspace are also removed after the run, covering leftovers from previous interrupted runs. - Existing registered worktrees outside the current flow workspace are reused and not removed automatically unless this run created them. - Existing worktree paths are reused only when they are registered by `git worktree list` for the given repo. - `pruneMissing` defaults to true. When Git has a registered worktree whose directory is missing, AgentFlow runs `git worktree prune` before adding it again. - `force` defaults to false. When true, AgentFlow passes `--force` to `git worktree add`.
127
+ - Description: Create or reuse a Git worktree and expose it as the downstream workspace context. - `repoPath` is required unless `gitContext.repoPath` is connected. - `workspaceContext` is required so the node can preserve the previous execution context. - `branch` is optional. When empty, AgentFlow creates a detached worktree at the current HEAD. - `worktreePath` is optional. When empty, AgentFlow creates a managed execution worktree under `.workspace/agentflow/run-workspaces/`, separate from node temp files and durable `outputs/` artifacts. - A `wait` checkpoint retains the execution worktree. The next run reuses the retained output path so loop state and code changes remain available while resuming. - On terminal completion or stop, AgentFlow removes clean managed worktrees. Dirty worktrees are preserved with a warning instead of being force-deleted. - Existing registered worktrees under the current flow workspace are managed by the same lifecycle policy. - Existing registered worktrees outside the current flow workspace are reused and not removed automatically unless this run created them. - Existing worktree paths are reused only when they are registered by `git worktree list` for the given repo. - `pruneMissing` defaults to true. When Git has a registered worktree whose directory is missing, AgentFlow runs `git worktree prune` before adding it again. - `force` defaults to false. When true, AgentFlow passes `--force` to `git worktree add`.
128
128
  - Runtime: local-only
129
129
  - Inputs: 0. `prev`:node; 1. `repoPath`:file; 2. `branch`:text; 3. `worktreePath`:file; 4. `pruneMissing`:bool = true; 5. `force`:bool = false; 6. `gitContext`:text; 7. `workspaceContext`:text
130
130
  - Outputs: 0. `next`:node; 1. `worktreePath`:file; 2. `branch`:text; 3. `commit`:text; 4. `workspaceContext`:text; 5. `gitContext`:text
@@ -261,6 +261,38 @@
261
261
 
262
262
  ## provide
263
263
 
264
+ ### context_bundle
265
+
266
+ - Display: Context Bundle
267
+ - Description: Compose knowledge, skills, workspace, and MCP resources into one strongly typed Context value that can cross Agent, Subflow, and While boundaries.
268
+ - Runtime: local-only
269
+ - Inputs: 0. `knowledgeContext`:text; 1. `skillsContext`:text; 2. `workspaceContext`:text; 3. `mcpContext`:text
270
+ - Outputs: 0. `context`:context
271
+
272
+ ### context_knowledge
273
+
274
+ - Display: Knowledge Context
275
+ - Description: Select one or more read-only knowledge sources by their authenticated Workspace catalog IDs. The runtime resolves IDs from the same catalog as GET /api/workspaces; paths and credentials are not stored in Flow DSL.
276
+ - Runtime: local-only
277
+ - Inputs: 0. `workspaceIds`:json = []
278
+ - Outputs: 0. `knowledgeContext`:text
279
+
280
+ ### context_skills
281
+
282
+ - Display: Skills Context
283
+ - Description: Declare versioned skills as a reusable Context resource. This is a data resource and does not participate in the prev/next control chain.
284
+ - Runtime: local-only
285
+ - Inputs: 0. `skills`:json = []
286
+ - Outputs: 0. `skillsContext`:text
287
+
288
+ ### context_workspace
289
+
290
+ - Display: Workspace Context
291
+ - Description: Bind one authenticated Workspace catalog entry as execution context. The Flow stores only workspaceId; paths and credentials remain runtime-owned.
292
+ - Runtime: local-only
293
+ - Inputs: 0. `workspaceId`:text = current; 1. `access`:text = read-write
294
+ - Outputs: 0. `workspaceContext`:text
295
+
264
296
  ### provide_bool
265
297
 
266
298
  - Display: Boolean