-
- {showWorkingDirectoryOverride && (
+
+
+ {showWorkingDirectoryOverride ? (
- )}
+ ) : null}
}
acpSelectorsSlot={
diff --git a/apps/web/src/i18n/resources/en/common.json b/apps/web/src/i18n/resources/en/common.json
index 85933262c..abfa140b1 100644
--- a/apps/web/src/i18n/resources/en/common.json
+++ b/apps/web/src/i18n/resources/en/common.json
@@ -772,10 +772,18 @@
},
"chat": {
"workingDirectoryOverride": "Working directory override",
+ "workingDirectoryOverrideDescription": "Optionally use a different directory for this Agent Node.",
+ "workingDirectoryOverrideActive": "Node working directory: {{path}}",
+ "workingDirectoryOverrideInherited": "Working directory inherited from Profile: {{path}}",
"workingDirectoryInherited": "Inheriting Profile directory: {{path}}",
"workingDirectoryNodeOnly": "Applies only to this Agent Node.",
"workingDirectoryNodeOnlyLocked": "Node-only override captured for this execution.",
"workingDirectoryOverrideSaveFailed": "Failed to save working directory override",
+ "workingDirectoryProfile": "Profile",
+ "workingDirectoryProfileDefault": "Profile directory",
+ "workingDirectoryEffective": "Effective directory",
+ "workingDirectoryNodeOverride": "Node override",
+ "workingDirectoryRestoreInheritance": "Restore Profile inheritance",
"showEarlierTurns": "Show {{count}} earlier turns",
"loadingEarlierTurns": "Loading earlier turns…",
"backToBottom": "Back to bottom",
diff --git a/apps/web/src/i18n/resources/zh-CN/common.json b/apps/web/src/i18n/resources/zh-CN/common.json
index 5e11167b0..b601f7285 100644
--- a/apps/web/src/i18n/resources/zh-CN/common.json
+++ b/apps/web/src/i18n/resources/zh-CN/common.json
@@ -772,10 +772,18 @@
},
"chat": {
"workingDirectoryOverride": "工作目录覆盖",
+ "workingDirectoryOverrideDescription": "可选择仅为此 Agent 节点使用不同的目录。",
+ "workingDirectoryOverrideActive": "节点工作目录:{{path}}",
+ "workingDirectoryOverrideInherited": "工作目录继承自 Profile:{{path}}",
"workingDirectoryInherited": "继承 Profile 目录:{{path}}",
"workingDirectoryNodeOnly": "仅应用于此 Agent 节点。",
"workingDirectoryNodeOnlyLocked": "此执行已固定使用该节点专属覆盖。",
"workingDirectoryOverrideSaveFailed": "保存工作目录覆盖失败",
+ "workingDirectoryProfile": "Profile",
+ "workingDirectoryProfileDefault": "Profile 目录",
+ "workingDirectoryEffective": "有效目录",
+ "workingDirectoryNodeOverride": "节点覆盖",
+ "workingDirectoryRestoreInheritance": "恢复继承 Profile",
"showEarlierTurns": "显示更早的 {{count}} 个轮次",
"loadingEarlierTurns": "正在加载更早的轮次…",
"backToBottom": "回到底部",
diff --git a/docs/architecture/question-node.md b/docs/architecture/question-node.md
index 88dcfae85..d3ae49620 100644
--- a/docs/architecture/question-node.md
+++ b/docs/architecture/question-node.md
@@ -77,7 +77,7 @@ Created like any node via `CREATE_NODES` ([resolveAddNodes.ts](../../apps/web/sr
- **Idle** → double-click opens compose (§5).
- An idle node with `agentBindingPolicy: fixed` opens compose with its persisted binding and a read-only Agent selector. Ordinary Editing nodes retain the picker; Bound nodes cannot switch execution identity even when a first control created no messages.
-- An Editing Node bound to an external Profile exposes an optional Node-specific working-directory override below the Agent selector. Empty means inherit the selected Profile without persisting a copy; an explicit value survives Profile changes and applies only to that Node. The control has no server-local folder picker because the Profile's Agentlet may run on another machine. Binding locks the override with the rest of execution preparation; a locked explicit value remains visible as a read-only summary.
+- An Editing Node bound to an external Profile exposes a Folder button beside the Agent selector. Its Popover shows the Profile and effective directories and optionally edits a Node-specific working-directory override. Empty means inherit the selected Profile without persisting a copy; an explicit value marks the trigger, survives Profile changes, and applies only to that Node. The control has no server-local folder picker because the Profile's Agentlet may run on another machine. Binding locks the override with the rest of execution preparation; a locked explicit value remains available through the same Popover as read-only context.
- After sending: **running → done / error**.
- `AgentThreadService` owns lifecycle for every node-backed invocation, regardless of policy. Admission publishes a new token and `running` before dispatch, installs cancellation before slow preparation, and keeps the turn lease through settlement. `AgentNodeLifecycle` fills only freshly read empty, never-submitted content and projects the matching terminal result. Existing content, previous submission tokens, and legacy conversation history prevent follow-ups from replacing authored text.
- Loading and reconnect observe server state; they never infer success from old history or repair status in the browser. A persisted running node without live tracking after restart does not establish an outcome, introduce a new badge, or trigger replay. Existing retry/admission behavior remains unchanged.