hoomanjs 1.22.2 → 1.23.1
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 +39 -9
- package/dist/acp/acp-agent.js +48 -9
- package/dist/acp/acp-agent.js.map +1 -1
- package/dist/acp/approvals.d.ts +1 -1
- package/dist/acp/approvals.js +4 -3
- package/dist/acp/approvals.js.map +1 -1
- package/dist/acp/sessions/config-options.d.ts +6 -3
- package/dist/acp/sessions/config-options.js +46 -6
- package/dist/acp/sessions/config-options.js.map +1 -1
- package/dist/acp/sessions/store.d.ts +8 -0
- package/dist/acp/sessions/store.js.map +1 -1
- package/dist/chat/app.d.ts +1 -2
- package/dist/chat/app.js +209 -31
- package/dist/chat/app.js.map +1 -1
- package/dist/chat/approvals.d.ts +1 -3
- package/dist/chat/approvals.js +4 -3
- package/dist/chat/approvals.js.map +1 -1
- package/dist/chat/components/Composer.d.ts +3 -2
- package/dist/chat/components/Composer.js +5 -5
- package/dist/chat/components/Composer.js.map +1 -1
- package/dist/chat/components/PromptInput.d.ts +3 -2
- package/dist/chat/components/PromptInput.js +2 -1
- package/dist/chat/components/PromptInput.js.map +1 -1
- package/dist/chat/components/ScrollView.d.ts +5 -0
- package/dist/chat/components/ScrollView.js +8 -2
- package/dist/chat/components/ScrollView.js.map +1 -1
- package/dist/chat/components/SelectPicker.d.ts +11 -0
- package/dist/chat/components/SelectPicker.js +7 -0
- package/dist/chat/components/SelectPicker.js.map +1 -0
- package/dist/chat/components/SlashCommands.d.ts +2 -1
- package/dist/chat/components/SlashCommands.js +9 -3
- package/dist/chat/components/SlashCommands.js.map +1 -1
- package/dist/chat/components/StatusBar.d.ts +3 -1
- package/dist/chat/components/StatusBar.js +18 -2
- package/dist/chat/components/StatusBar.js.map +1 -1
- package/dist/chat/components/ThinkingStatus.js +1 -1
- package/dist/chat/components/ThinkingStatus.js.map +1 -1
- package/dist/chat/components/TranscriptViewport.js +1 -1
- package/dist/chat/components/TranscriptViewport.js.map +1 -1
- package/dist/chat/components/markdown/BlockRenderer.d.ts +6 -1
- package/dist/chat/components/markdown/BlockRenderer.js +16 -14
- package/dist/chat/components/markdown/BlockRenderer.js.map +1 -1
- package/dist/chat/components/markdown/CodeBlock.d.ts +3 -1
- package/dist/chat/components/markdown/CodeBlock.js +3 -3
- package/dist/chat/components/markdown/CodeBlock.js.map +1 -1
- package/dist/chat/components/markdown/MarkdownMessage.js +2 -2
- package/dist/chat/components/markdown/MarkdownMessage.js.map +1 -1
- package/dist/chat/components/markdown/MarkdownTable.d.ts +2 -1
- package/dist/chat/components/markdown/MarkdownTable.js +2 -2
- package/dist/chat/components/markdown/MarkdownTable.js.map +1 -1
- package/dist/chat/components/prompt-input/hooks/usePromptInputController.d.ts +1 -1
- package/dist/chat/components/prompt-input/hooks/usePromptInputController.js.map +1 -1
- package/dist/chat/components/prompt-input/usePromptInputController.d.ts +11 -1
- package/dist/chat/components/prompt-input/usePromptInputController.js +55 -3
- package/dist/chat/components/prompt-input/usePromptInputController.js.map +1 -1
- package/dist/chat/index.d.ts +0 -1
- package/dist/chat/index.js +1 -1
- package/dist/chat/index.js.map +1 -1
- package/dist/cli.js +38 -16
- package/dist/cli.js.map +1 -1
- package/dist/core/agent/index.d.ts +4 -0
- package/dist/core/agent/index.js +25 -6
- package/dist/core/agent/index.js.map +1 -1
- package/dist/core/agent/mode-aware-tool-registry.d.ts +10 -0
- package/dist/core/agent/mode-aware-tool-registry.js +21 -0
- package/dist/core/agent/mode-aware-tool-registry.js.map +1 -0
- package/dist/core/agent/sync-tool-registry-mode.d.ts +6 -0
- package/dist/core/agent/sync-tool-registry-mode.js +15 -0
- package/dist/core/agent/sync-tool-registry-mode.js.map +1 -0
- package/dist/core/agents/definitions.d.ts +1 -1
- package/dist/core/agents/definitions.js +2 -17
- package/dist/core/agents/definitions.js.map +1 -1
- package/dist/core/agents/tools.d.ts +1 -1
- package/dist/core/agents/tools.js +1 -1
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/prompts/agents/research.md +15 -14
- package/dist/core/prompts/modes/ask.md +21 -0
- package/dist/core/prompts/{agents → modes}/plan.md +6 -8
- package/dist/core/prompts/session-mode-appendix.d.ts +5 -0
- package/dist/core/prompts/session-mode-appendix.js +53 -0
- package/dist/core/prompts/session-mode-appendix.js.map +1 -0
- package/dist/core/prompts/static/planning.md +34 -0
- package/dist/core/prompts/static/subagents.md +2 -2
- package/dist/core/prompts/system.js +3 -2
- package/dist/core/prompts/system.js.map +1 -1
- package/dist/core/session-config.d.ts +0 -3
- package/dist/core/session-config.js +0 -7
- package/dist/core/session-config.js.map +1 -1
- package/dist/core/state/agent-app-state.d.ts +6 -0
- package/dist/core/state/agent-app-state.js +11 -0
- package/dist/core/state/agent-app-state.js.map +1 -0
- package/dist/core/state/plan.d.ts +23 -0
- package/dist/core/state/plan.js +34 -0
- package/dist/core/state/plan.js.map +1 -0
- package/dist/core/state/session-mode.d.ts +23 -0
- package/dist/core/state/session-mode.js +21 -0
- package/dist/core/state/session-mode.js.map +1 -0
- package/dist/core/state/tool-approvals.d.ts +13 -1
- package/dist/core/state/tool-approvals.js +138 -5
- package/dist/core/state/tool-approvals.js.map +1 -1
- package/dist/core/state/yolo.d.ts +12 -0
- package/dist/core/state/yolo.js +9 -0
- package/dist/core/state/yolo.js.map +1 -0
- package/dist/core/tools/filesystem.js +1 -19
- package/dist/core/tools/filesystem.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/plan.d.ts +4 -0
- package/dist/core/tools/plan.js +113 -0
- package/dist/core/tools/plan.js.map +1 -0
- package/dist/core/tools/wiki.d.ts +2 -2
- package/dist/core/utils/normalize-user-path.d.ts +4 -0
- package/dist/core/utils/normalize-user-path.js +31 -0
- package/dist/core/utils/normalize-user-path.js.map +1 -0
- package/dist/core/utils/paths.d.ts +1 -0
- package/dist/core/utils/paths.js +3 -0
- package/dist/core/utils/paths.js.map +1 -1
- package/dist/daemon/approvals.d.ts +1 -3
- package/dist/daemon/approvals.js +4 -3
- package/dist/daemon/approvals.js.map +1 -1
- package/dist/daemon/index.d.ts +0 -1
- package/dist/daemon/index.js +0 -3
- package/dist/daemon/index.js.map +1 -1
- package/dist/exec/approvals.d.ts +1 -3
- package/dist/exec/approvals.js +4 -3
- package/dist/exec/approvals.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chat/components/ModelPicker.d.ts +0 -10
- package/dist/chat/components/ModelPicker.js +0 -7
- package/dist/chat/components/ModelPicker.js.map +0 -1
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
## Research Agent
|
|
2
2
|
|
|
3
|
-
You are
|
|
3
|
+
You are the specialized research sub-agent for {{ name }}. You are the **only** delegated read-only helper the parent agent uses to explore and investigate before it takes action.
|
|
4
4
|
|
|
5
|
-
Your job is to
|
|
5
|
+
Your job is to explore the relevant working directory and codebase, pull in external sources when useful, and return **high-signal findings** so the parent agent knows what exists, how things fit together, and what is still uncertain.
|
|
6
6
|
|
|
7
7
|
This is a strict read-only role:
|
|
8
8
|
|
|
9
9
|
- Do not create, edit, move, or delete files.
|
|
10
10
|
- Do not run commands that change system state.
|
|
11
|
-
- Do not
|
|
11
|
+
- Do not present guesses as facts; label inference clearly.
|
|
12
12
|
|
|
13
13
|
How to work:
|
|
14
14
|
|
|
15
|
-
1.
|
|
16
|
-
2. Explore efficiently:
|
|
17
|
-
3. Prefer concrete evidence over
|
|
18
|
-
4. Surface contradictions,
|
|
19
|
-
5.
|
|
15
|
+
1. Parse the parent’s question and decide what evidence is needed (files, layout, docs, APIs, prior patterns, web or fetched sources).
|
|
16
|
+
2. Explore efficiently: orient with layout and search, then drill into the smallest set of paths that answer the question.
|
|
17
|
+
3. Prefer concrete evidence (paths, symbols, snippets, URLs, quoted facts) over narrative.
|
|
18
|
+
4. Surface contradictions, risks, edge cases, and dependencies when they matter for the parent’s next move.
|
|
19
|
+
5. When helpful, note sensible alternatives or trade-offs **as analysis**, not as instructions—the parent decides what to execute.
|
|
20
|
+
6. Stop once the parent can act or answer without redundant digging.
|
|
20
21
|
|
|
21
22
|
Quality bar:
|
|
22
23
|
|
|
23
24
|
- Be precise, not verbose.
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
25
|
+
- Separate **confirmed**, **likely**, and **unknown**.
|
|
26
|
+
- Say what additional check would resolve each unknown.
|
|
27
|
+
- Suggest how the parent could **verify** conclusions (what to read, run, or compare)—without performing mutating steps yourself.
|
|
27
28
|
|
|
28
29
|
Return format:
|
|
29
30
|
|
|
30
|
-
1. **Findings**
|
|
31
|
-
2. **Open Questions / Uncertainties**
|
|
32
|
-
3. **Recommended Next Step for Parent Agent**
|
|
31
|
+
1. **Findings** — short bullets with evidence (paths, identifiers, sources).
|
|
32
|
+
2. **Open Questions / Uncertainties** — only if relevant.
|
|
33
|
+
3. **Recommended Next Step for Parent Agent** — one concise action grounded in your findings.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Ask mode
|
|
2
|
+
|
|
3
|
+
You are in **ask** mode: a narrowed tool surface for exploration, research, and answering questions.
|
|
4
|
+
|
|
5
|
+
### Role
|
|
6
|
+
|
|
7
|
+
- Explain architecture, behavior, APIs, and trade-offs from what you can inspect with available tools.
|
|
8
|
+
- Help the user reason through options and risks in prose.
|
|
9
|
+
- Stay aligned with **read-oriented** work: prefer inspection and analysis over changing their repo or runtime.
|
|
10
|
+
|
|
11
|
+
### Discipline
|
|
12
|
+
|
|
13
|
+
- Do **not** imply you can use tools that are not exposed in this phase.
|
|
14
|
+
- If the user needs a **written plan on disk** and the staged planning workflow, they should switch to **plan** mode (or **default** when those tools are available).
|
|
15
|
+
- If they want **full implementation** or unrestricted editing commands, they should switch to **default** mode (or approve work explicitly once they have switched).
|
|
16
|
+
- When **`run_agents`** is available, use it only for **read-only** parallel exploration; you remain responsible for synthesizing answers.
|
|
17
|
+
|
|
18
|
+
### Output
|
|
19
|
+
|
|
20
|
+
- Be direct and structured; mention what you reviewed when it helps the user trust your conclusions.
|
|
21
|
+
- If the task clearly requires implementation or destructive actions, say what is needed and which mode or approval path fits — do not substitute unrestricted execution.
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Planning mode
|
|
2
2
|
|
|
3
|
-
You are a
|
|
3
|
+
You are in planning mode, your job is to design a practical, low-risk plan. **Executing that plan requires an explicit go-ahead from the user** after they have reviewed it—not merely leaving plan mode.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This is a strict read-only role **for your direct edits**:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Do not create, edit, move, or delete files.
|
|
10
|
-
- Do not run commands that change system state.
|
|
7
|
+
- Do not create, edit, move, or delete files **yourself** other than the plan file itself (delegated **`run_agents`** jobs should stay read-only exploration).
|
|
8
|
+
- Do not run commands that change system state **directly** from tools that are not exposed here.
|
|
11
9
|
- Do not produce the final deliverable; focus on strategy.
|
|
12
10
|
|
|
13
11
|
Planning process:
|
|
@@ -32,4 +30,4 @@ Return format:
|
|
|
32
30
|
2. **Execution Steps** - numbered sequence, each step actionable.
|
|
33
31
|
3. **Critical Areas** - what matters and why.
|
|
34
32
|
4. **Risks and Mitigations** - specific, not generic.
|
|
35
|
-
5. **Validation Plan** - how
|
|
33
|
+
5. **Validation Plan** - how you should confirm correctness after implementation (once approved).
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LocalAgent } from "@strands-agents/sdk";
|
|
2
|
+
import type { SessionMode } from "../state/session-mode.js";
|
|
3
|
+
export declare function composeSystemPromptWithSessionMode(base: string, mode: SessionMode): string;
|
|
4
|
+
/** Applies the session-mode appendix to `base` and updates `agent.systemPrompt` when it changes. */
|
|
5
|
+
export declare function refreshAgentSystemPromptForSessionMode(agent: LocalAgent, base: string): void;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { getModeState } from "../state/session-mode.js";
|
|
5
|
+
const SECTION_BREAK = "\n\n---\n\n";
|
|
6
|
+
let cachedPlanAppendix = null;
|
|
7
|
+
let cachedAskAppendix = null;
|
|
8
|
+
function readBundledModeFile(file) {
|
|
9
|
+
const dir = join(dirname(fileURLToPath(import.meta.url)), "modes");
|
|
10
|
+
const full = join(dir, file);
|
|
11
|
+
if (!existsSync(full)) {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
return readFileSync(full, "utf8").trim();
|
|
15
|
+
}
|
|
16
|
+
function appendixForMode(mode) {
|
|
17
|
+
switch (mode) {
|
|
18
|
+
case "plan": {
|
|
19
|
+
if (cachedPlanAppendix === null) {
|
|
20
|
+
cachedPlanAppendix = readBundledModeFile("plan.md");
|
|
21
|
+
}
|
|
22
|
+
return cachedPlanAppendix;
|
|
23
|
+
}
|
|
24
|
+
case "ask": {
|
|
25
|
+
if (cachedAskAppendix === null) {
|
|
26
|
+
cachedAskAppendix = readBundledModeFile("ask.md");
|
|
27
|
+
}
|
|
28
|
+
return cachedAskAppendix;
|
|
29
|
+
}
|
|
30
|
+
default:
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function composeSystemPromptWithSessionMode(base, mode) {
|
|
35
|
+
const extra = appendixForMode(mode);
|
|
36
|
+
if (!extra) {
|
|
37
|
+
return base;
|
|
38
|
+
}
|
|
39
|
+
if (!base) {
|
|
40
|
+
return extra;
|
|
41
|
+
}
|
|
42
|
+
return `${base}${SECTION_BREAK}${extra}`;
|
|
43
|
+
}
|
|
44
|
+
/** Applies the session-mode appendix to `base` and updates `agent.systemPrompt` when it changes. */
|
|
45
|
+
export function refreshAgentSystemPromptForSessionMode(agent, base) {
|
|
46
|
+
const mode = getModeState(agent).mode;
|
|
47
|
+
const next = composeSystemPromptWithSessionMode(base, mode);
|
|
48
|
+
const cur = typeof agent.systemPrompt === "string" ? agent.systemPrompt : "";
|
|
49
|
+
if (cur !== next && typeof agent.systemPrompt === "string") {
|
|
50
|
+
agent.systemPrompt = next;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=session-mode-appendix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-mode-appendix.js","sourceRoot":"","sources":["../../../src/core/prompts/session-mode-appendix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,MAAM,aAAa,GAAG,aAAa,CAAC;AAEpC,IAAI,kBAAkB,GAAkB,IAAI,CAAC;AAC7C,IAAI,iBAAiB,GAAkB,IAAI,CAAC;AAE5C,SAAS,mBAAmB,CAAC,IAA0B;IACrD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED,SAAS,eAAe,CAAC,IAAiB;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,IAAI,kBAAkB,KAAK,IAAI,EAAE,CAAC;gBAChC,kBAAkB,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBAC/B,iBAAiB,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACpD,CAAC;YACD,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QACD;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,IAAY,EACZ,IAAiB;IAEjB,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,GAAG,IAAI,GAAG,aAAa,GAAG,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,sCAAsC,CACpD,KAAiB,EACjB,IAAY;IAEZ,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;IACtC,MAAM,IAAI,GAAG,kCAAkC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC3D,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
## Planning workflow
|
|
2
|
+
|
|
3
|
+
Before large or risky changes, use **plan mode** so you explore options with a reduced tool surface and write the plan to disk. After you leave plan mode, full tools return—but you implement **only after the user explicitly approves** (see below).
|
|
4
|
+
|
|
5
|
+
### When to enter plan mode
|
|
6
|
+
|
|
7
|
+
Call **`enter_plan_mode`** when the task is multi-step, ambiguous, or could cause harm if executed hastily (wide refactors, migrations, security-sensitive edits, or unclear requirements).
|
|
8
|
+
|
|
9
|
+
### While in plan mode
|
|
10
|
+
|
|
11
|
+
- You receive a **`plan_file`** path under the app plans directory. Expand it with **`read_file`**, **`write_file`**, and **`edit_file`** as needed (paths must stay within allowed locations).
|
|
12
|
+
- Prefer **`think`** or **`update_todos`** to organize reasoning; avoid shell and other tools not exposed in this phase.
|
|
13
|
+
- **`run_agents`** is available: use it for **read-only** parallel exploration when splitting investigations helps (same discipline as subagents—narrow prompts, synthesize results yourself). Child agents are constrained like other tooling in this phase; you remain responsible for the plan document.
|
|
14
|
+
|
|
15
|
+
### Leaving plan mode
|
|
16
|
+
|
|
17
|
+
When the written plan is concrete enough to **review**, call **`exit_plan_mode`**. You will see a short preview of the plan file; afterward the full tool set is available again.
|
|
18
|
+
|
|
19
|
+
Do **not** call **`exit_plan_mode`** until you have entered plan mode with **`enter_plan_mode`** and drafted content in the plan file.
|
|
20
|
+
|
|
21
|
+
### After exiting plan mode (user approval gate)
|
|
22
|
+
|
|
23
|
+
**Leaving plan mode is not permission to implement.** It only ends the restricted planning phase so you can discuss the plan with the user.
|
|
24
|
+
|
|
25
|
+
Until the user **explicitly approves** execution—clear wording such as agreeing to the plan, asking you to proceed, implement it, apply it, or “execute”—you must **not** start substantive implementation work (code changes, destructive commands, migrations, broad edits, or following numbered execution steps from the plan).
|
|
26
|
+
|
|
27
|
+
After **`exit_plan_mode`**, default behavior:
|
|
28
|
+
|
|
29
|
+
1. Briefly summarize what you drafted and where the plan file lives (if helpful).
|
|
30
|
+
2. Ask whether they want you to proceed as written, want revisions first, or want to cancel—unless they have already given explicit approval in the same turn.
|
|
31
|
+
|
|
32
|
+
If they approve only part of the plan, restrict implementation to that scope. If they ask for changes, revise the plan or re-enter plan mode as appropriate **before** executing.
|
|
33
|
+
|
|
34
|
+
Only after **explicit user approval** should you implement or execute the plan using your normal tools.
|
|
@@ -6,7 +6,7 @@ Use this tool when delegation makes the response better:
|
|
|
6
6
|
|
|
7
7
|
- The task has independent parts that can run in parallel.
|
|
8
8
|
- You need deeper investigation before writing a final answer.
|
|
9
|
-
- You want
|
|
9
|
+
- You want focused read-only exploration of the workspace, sources, and context.
|
|
10
10
|
|
|
11
11
|
Use delegation thoughtfully:
|
|
12
12
|
|
|
@@ -23,6 +23,6 @@ Do not use `run_agents` when:
|
|
|
23
23
|
|
|
24
24
|
Output expectations:
|
|
25
25
|
|
|
26
|
-
- Child agents are read-only and return findings
|
|
26
|
+
- Child agents are read-only and return findings for you to interpret.
|
|
27
27
|
- You are responsible for synthesizing child outputs into one coherent response.
|
|
28
28
|
- If child outputs conflict, resolve the conflict explicitly and explain why.
|
|
@@ -21,6 +21,7 @@ const STATIC_PROMPT_FILES = [
|
|
|
21
21
|
"wiki.md",
|
|
22
22
|
"skills.md",
|
|
23
23
|
"subagents.md",
|
|
24
|
+
"planning.md",
|
|
24
25
|
];
|
|
25
26
|
const HARNESS_PROMPT_FILES = [
|
|
26
27
|
{ key: "behaviour", file: "behaviour.md" },
|
|
@@ -62,12 +63,12 @@ export class System {
|
|
|
62
63
|
return this.config.tools.shell.enabled;
|
|
63
64
|
case "sleep.md":
|
|
64
65
|
return this.config.tools.sleep.enabled;
|
|
65
|
-
case "daemon.md":
|
|
66
|
-
return this.mode === "daemon";
|
|
67
66
|
case "wiki.md":
|
|
68
67
|
return this.config.tools.wiki.enabled;
|
|
69
68
|
case "subagents.md":
|
|
70
69
|
return this.config.tools.agents.enabled;
|
|
70
|
+
case "daemon.md":
|
|
71
|
+
return this.mode === "daemon";
|
|
71
72
|
case "thinking.md":
|
|
72
73
|
default:
|
|
73
74
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/core/prompts/system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;AAE/B,gEAAgE;AAChE,MAAM,mBAAmB,GAAG;IAC1B,aAAa;IACb,gBAAgB;IAChB,QAAQ;IACR,SAAS;IACT,aAAa;IACb,eAAe;IACf,UAAU;IACV,eAAe;IACf,UAAU;IACV,UAAU;IACV,QAAQ;IACR,WAAW;IACX,SAAS;IACT,WAAW;IACX,cAAc;
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/core/prompts/system.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,6 @@ import { Config } from "./config.js";
|
|
|
4
4
|
* rewriting the shared on-disk config file.
|
|
5
5
|
*/
|
|
6
6
|
export declare class SessionConfig extends Config {
|
|
7
|
-
#private;
|
|
8
|
-
get yolo(): boolean;
|
|
9
|
-
setYolo(value: boolean): void;
|
|
10
7
|
persist(): void;
|
|
11
8
|
}
|
|
12
9
|
export declare function createSessionConfig(): SessionConfig;
|
|
@@ -5,13 +5,6 @@ import { configJsonPath } from "./utils/paths.js";
|
|
|
5
5
|
* rewriting the shared on-disk config file.
|
|
6
6
|
*/
|
|
7
7
|
export class SessionConfig extends Config {
|
|
8
|
-
#yolo = false;
|
|
9
|
-
get yolo() {
|
|
10
|
-
return this.#yolo;
|
|
11
|
-
}
|
|
12
|
-
setYolo(value) {
|
|
13
|
-
this.#yolo = value;
|
|
14
|
-
}
|
|
15
8
|
persist() {
|
|
16
9
|
// Session config overrides are intentionally ephemeral.
|
|
17
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-config.js","sourceRoot":"","sources":["../../src/core/session-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,MAAM;
|
|
1
|
+
{"version":3,"file":"session-config.js","sourceRoot":"","sources":["../../src/core/session-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,MAAM;IACvB,OAAO;QACrB,wDAAwD;IAC1D,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,aAAa,CAAC,cAAc,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Agent } from "@strands-agents/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* Copies every entry from `from.appState` onto `to.appState` (via Strands `getAll` / `set`).
|
|
4
|
+
* Use after recreating an agent so plan mode, yolo, session allowlists, todos, etc. survive.
|
|
5
|
+
*/
|
|
6
|
+
export declare function copyAgentAppState(from: Agent, to: Agent): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copies every entry from `from.appState` onto `to.appState` (via Strands `getAll` / `set`).
|
|
3
|
+
* Use after recreating an agent so plan mode, yolo, session allowlists, todos, etc. survive.
|
|
4
|
+
*/
|
|
5
|
+
export function copyAgentAppState(from, to) {
|
|
6
|
+
const data = from.appState.getAll();
|
|
7
|
+
for (const key of Object.keys(data)) {
|
|
8
|
+
to.appState.set(key, data[key]);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=agent-app-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-app-state.js","sourceRoot":"","sources":["../../../src/core/state/agent-app-state.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAW,EAAE,EAAS;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAE,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const PLAN_FILE_STATE_KEY = "hooman.planFile";
|
|
2
|
+
export declare const PLAN_ENTER_REASON_STATE_KEY = "hooman.enterReason";
|
|
3
|
+
export declare const PLAN_ENTERED_AT_STATE_KEY = "hooman.enteredAt";
|
|
4
|
+
type AppStateLike = {
|
|
5
|
+
get<T = unknown>(key: string): T;
|
|
6
|
+
set(key: string, value: unknown): void;
|
|
7
|
+
};
|
|
8
|
+
type AgentLike = {
|
|
9
|
+
appState: AppStateLike;
|
|
10
|
+
};
|
|
11
|
+
export type PlanState = {
|
|
12
|
+
planFile: string | null;
|
|
13
|
+
enterReason: string | null;
|
|
14
|
+
enteredAt: string | null;
|
|
15
|
+
};
|
|
16
|
+
export declare function getPlanState(agent: AgentLike): PlanState;
|
|
17
|
+
export declare function setPlanState(agent: AgentLike, snapshot: {
|
|
18
|
+
planFile: string;
|
|
19
|
+
enterReason?: string | undefined;
|
|
20
|
+
enteredAt: string;
|
|
21
|
+
}): void;
|
|
22
|
+
export declare function clearPlanState(agent: AgentLike): void;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const PLAN_FILE_STATE_KEY = "hooman.planFile";
|
|
2
|
+
export const PLAN_ENTER_REASON_STATE_KEY = "hooman.enterReason";
|
|
3
|
+
export const PLAN_ENTERED_AT_STATE_KEY = "hooman.enteredAt";
|
|
4
|
+
export function getPlanState(agent) {
|
|
5
|
+
const rawPlanFile = agent.appState.get(PLAN_FILE_STATE_KEY);
|
|
6
|
+
const planFile = typeof rawPlanFile === "string" && rawPlanFile.trim()
|
|
7
|
+
? rawPlanFile.trim()
|
|
8
|
+
: null;
|
|
9
|
+
const rawEnterReason = agent.appState.get(PLAN_ENTER_REASON_STATE_KEY);
|
|
10
|
+
const enterReason = typeof rawEnterReason === "string" && rawEnterReason.trim()
|
|
11
|
+
? rawEnterReason.trim()
|
|
12
|
+
: null;
|
|
13
|
+
const rawEnteredAt = agent.appState.get(PLAN_ENTERED_AT_STATE_KEY);
|
|
14
|
+
const enteredAt = typeof rawEnteredAt === "string" && rawEnteredAt.trim()
|
|
15
|
+
? rawEnteredAt.trim()
|
|
16
|
+
: null;
|
|
17
|
+
return { planFile, enterReason, enteredAt };
|
|
18
|
+
}
|
|
19
|
+
export function setPlanState(agent, snapshot) {
|
|
20
|
+
agent.appState.set(PLAN_FILE_STATE_KEY, snapshot.planFile);
|
|
21
|
+
if (snapshot.enterReason?.trim()) {
|
|
22
|
+
agent.appState.set(PLAN_ENTER_REASON_STATE_KEY, snapshot.enterReason.trim());
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
agent.appState.set(PLAN_ENTER_REASON_STATE_KEY, null);
|
|
26
|
+
}
|
|
27
|
+
agent.appState.set(PLAN_ENTERED_AT_STATE_KEY, snapshot.enteredAt);
|
|
28
|
+
}
|
|
29
|
+
export function clearPlanState(agent) {
|
|
30
|
+
agent.appState.set(PLAN_FILE_STATE_KEY, null);
|
|
31
|
+
agent.appState.set(PLAN_ENTER_REASON_STATE_KEY, null);
|
|
32
|
+
agent.appState.set(PLAN_ENTERED_AT_STATE_KEY, null);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/core/state/plan.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AACrD,MAAM,CAAC,MAAM,2BAA2B,GAAG,oBAAoB,CAAC;AAChE,MAAM,CAAC,MAAM,yBAAyB,GAAG,kBAAkB,CAAC;AAiB5D,MAAM,UAAU,YAAY,CAAC,KAAgB;IAC3C,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC5D,MAAM,QAAQ,GACZ,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE;QACnD,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE;QACpB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,cAAc,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACvE,MAAM,WAAW,GACf,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,CAAC,IAAI,EAAE;QACzD,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE;QACvB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACnE,MAAM,SAAS,GACb,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,EAAE;QACrD,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE;QACrB,CAAC,CAAC,IAAI,CAAC;IACX,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,KAAgB,EAChB,QAIC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,mBAAmB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3D,IAAI,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;QACjC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAChB,2BAA2B,EAC3B,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAC5B,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAgB;IAC7C,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IAC9C,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC;IACtD,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const MODE_STATE_KEY = "mode";
|
|
3
|
+
export declare const SessionModeSchema: z.ZodEnum<{
|
|
4
|
+
default: "default";
|
|
5
|
+
plan: "plan";
|
|
6
|
+
ask: "ask";
|
|
7
|
+
}>;
|
|
8
|
+
export type SessionMode = z.infer<typeof SessionModeSchema>;
|
|
9
|
+
type AppStateLike = {
|
|
10
|
+
get<T = unknown>(key: string): T;
|
|
11
|
+
set(key: string, value: unknown): void;
|
|
12
|
+
};
|
|
13
|
+
type AgentLike = {
|
|
14
|
+
appState: AppStateLike;
|
|
15
|
+
};
|
|
16
|
+
export type ModeState = {
|
|
17
|
+
mode: SessionMode;
|
|
18
|
+
};
|
|
19
|
+
export declare function normalizeSessionMode(value: unknown): SessionMode;
|
|
20
|
+
export declare function getModeState(agent: AgentLike): ModeState;
|
|
21
|
+
export declare function setSessionMode(agent: AgentLike, mode: SessionMode): void;
|
|
22
|
+
export declare function clearModeToDefault(agent: AgentLike): void;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const MODE_STATE_KEY = "mode";
|
|
3
|
+
export const SessionModeSchema = z.enum(["default", "plan", "ask"]);
|
|
4
|
+
export function normalizeSessionMode(value) {
|
|
5
|
+
const parsed = SessionModeSchema.safeParse(value);
|
|
6
|
+
return parsed.success ? parsed.data : "default";
|
|
7
|
+
}
|
|
8
|
+
function normalizeMode(value) {
|
|
9
|
+
return normalizeSessionMode(value);
|
|
10
|
+
}
|
|
11
|
+
export function getModeState(agent) {
|
|
12
|
+
const mode = normalizeMode(agent.appState.get(MODE_STATE_KEY));
|
|
13
|
+
return { mode };
|
|
14
|
+
}
|
|
15
|
+
export function setSessionMode(agent, mode) {
|
|
16
|
+
agent.appState.set(MODE_STATE_KEY, mode);
|
|
17
|
+
}
|
|
18
|
+
export function clearModeToDefault(agent) {
|
|
19
|
+
agent.appState.set(MODE_STATE_KEY, "default");
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=session-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-mode.js","sourceRoot":"","sources":["../../../src/core/state/session-mode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAgBpE,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAgB;IAC3C,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IAC/D,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAgB,EAAE,IAAiB;IAChE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAgB;IACjD,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -5,8 +5,20 @@ type AppStateLike = {
|
|
|
5
5
|
type AgentLike = {
|
|
6
6
|
appState: AppStateLike;
|
|
7
7
|
};
|
|
8
|
+
export declare const ENTER_PLAN_MODE_TOOL = "enter_plan_mode";
|
|
9
|
+
export declare const EXIT_PLAN_MODE_TOOL = "exit_plan_mode";
|
|
8
10
|
export declare const INTERNAL_ALWAYS_ALLOWED: Set<string>;
|
|
11
|
+
export declare const PLAN_MODE_ALWAYS_ALLOWED: Set<string>;
|
|
12
|
+
export declare const PLAN_MODE_VISIBLE: Set<string>;
|
|
13
|
+
/** Same narrowed surface as plan mode but without plan lifecycle tools. */
|
|
14
|
+
export declare const ASK_MODE_VISIBLE: Set<string>;
|
|
9
15
|
export declare function getSessionAllowedTools(agent: AgentLike): string[];
|
|
10
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Session-wide tool allowlist ("always allow" in UI), plus implicit allow for
|
|
18
|
+
* read/write/edit when paths resolve under attachments, plans, or skills (reads)
|
|
19
|
+
* or plans only (writes/edits).
|
|
20
|
+
*/
|
|
21
|
+
export declare function isToolSessionAllowed(agent: AgentLike, toolName: string, toolInput?: unknown): boolean;
|
|
22
|
+
export declare function isToolVisible(mode: string, toolName: string): boolean;
|
|
11
23
|
export declare function allowToolForSession(agent: AgentLike, toolName: string): void;
|
|
12
24
|
export {};
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
+
import { RUN_AGENTS_TOOL_NAME } from "../agents/tools.js";
|
|
2
|
+
import { getModeState } from "./session-mode.js";
|
|
3
|
+
import { isResolvedPathInsideDir, normalizeUserPath, } from "../utils/normalize-user-path.js";
|
|
4
|
+
import { attachmentsPath, plansPath, skillsPath } from "../utils/paths.js";
|
|
1
5
|
const SESSION_ALLOWED_TOOLS_KEY = "allowedTools";
|
|
6
|
+
const READ_FILE_TOOL = "read_file";
|
|
7
|
+
const READ_MULTIPLE_FILES_TOOL = "read_multiple_files";
|
|
8
|
+
const WRITE_FILE_TOOL = "write_file";
|
|
9
|
+
const EDIT_FILE_TOOL = "edit_file";
|
|
10
|
+
export const ENTER_PLAN_MODE_TOOL = "enter_plan_mode";
|
|
11
|
+
export const EXIT_PLAN_MODE_TOOL = "exit_plan_mode";
|
|
2
12
|
export const INTERNAL_ALWAYS_ALLOWED = new Set([
|
|
3
13
|
// Strands / runtime
|
|
4
14
|
"strands_structured_output",
|
|
@@ -7,7 +17,7 @@ export const INTERNAL_ALWAYS_ALLOWED = new Set([
|
|
|
7
17
|
// Thinking
|
|
8
18
|
"think",
|
|
9
19
|
// Agent orchestration
|
|
10
|
-
|
|
20
|
+
RUN_AGENTS_TOOL_NAME,
|
|
11
21
|
// Sleep
|
|
12
22
|
"sleep",
|
|
13
23
|
// Process lifecycle
|
|
@@ -22,8 +32,6 @@ export const INTERNAL_ALWAYS_ALLOWED = new Set([
|
|
|
22
32
|
"wiki_search",
|
|
23
33
|
"wiki_stats",
|
|
24
34
|
"wiki_write_file",
|
|
25
|
-
// Web search
|
|
26
|
-
"web_search",
|
|
27
35
|
// Long-term memory
|
|
28
36
|
"archive_memory",
|
|
29
37
|
"search_memory",
|
|
@@ -34,7 +42,103 @@ export const INTERNAL_ALWAYS_ALLOWED = new Set([
|
|
|
34
42
|
"get_file_info",
|
|
35
43
|
"list_directory",
|
|
36
44
|
"search_files",
|
|
45
|
+
// Planning session (mode / plan file)
|
|
46
|
+
ENTER_PLAN_MODE_TOOL,
|
|
47
|
+
EXIT_PLAN_MODE_TOOL,
|
|
48
|
+
]);
|
|
49
|
+
export const PLAN_MODE_ALWAYS_ALLOWED = new Set([
|
|
50
|
+
"read_file",
|
|
51
|
+
"read_multiple_files",
|
|
52
|
+
"fetch",
|
|
53
|
+
"web_search",
|
|
37
54
|
]);
|
|
55
|
+
export const PLAN_MODE_VISIBLE = new Set([
|
|
56
|
+
// Internet
|
|
57
|
+
"fetch",
|
|
58
|
+
"web_search",
|
|
59
|
+
// Strands / runtime
|
|
60
|
+
"strands_structured_output",
|
|
61
|
+
// Todos
|
|
62
|
+
"update_todos",
|
|
63
|
+
// Thinking
|
|
64
|
+
"think",
|
|
65
|
+
// Agent orchestration
|
|
66
|
+
RUN_AGENTS_TOOL_NAME,
|
|
67
|
+
// Sleep
|
|
68
|
+
"sleep",
|
|
69
|
+
// Process lifecycle
|
|
70
|
+
"bye",
|
|
71
|
+
// Time
|
|
72
|
+
"convert_time",
|
|
73
|
+
"get_current_time",
|
|
74
|
+
// Wiki
|
|
75
|
+
"wiki_knowledge_graph",
|
|
76
|
+
"wiki_list_files",
|
|
77
|
+
"wiki_read_file",
|
|
78
|
+
"wiki_search",
|
|
79
|
+
"wiki_stats",
|
|
80
|
+
"wiki_write_file",
|
|
81
|
+
// Long-term memory
|
|
82
|
+
"search_memory",
|
|
83
|
+
// Filesystem (list / search / metadata)
|
|
84
|
+
"directory_tree",
|
|
85
|
+
"get_file_info",
|
|
86
|
+
"list_directory",
|
|
87
|
+
"search_files",
|
|
88
|
+
"read_file",
|
|
89
|
+
"read_multiple_files",
|
|
90
|
+
"write_file",
|
|
91
|
+
"edit_file",
|
|
92
|
+
// Planning session (mode / plan file)
|
|
93
|
+
ENTER_PLAN_MODE_TOOL,
|
|
94
|
+
EXIT_PLAN_MODE_TOOL,
|
|
95
|
+
]);
|
|
96
|
+
/** Same narrowed surface as plan mode but without plan lifecycle tools. */
|
|
97
|
+
export const ASK_MODE_VISIBLE = new Set([...PLAN_MODE_VISIBLE].filter((name) => name !== ENTER_PLAN_MODE_TOOL && name !== EXIT_PLAN_MODE_TOOL));
|
|
98
|
+
function isPlainObjectRecord(value) {
|
|
99
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
100
|
+
}
|
|
101
|
+
/** Skip approval for filesystem tools when targets stay inside trusted app-home dirs. */
|
|
102
|
+
function isImplicitPathAllowed(toolName, toolInput) {
|
|
103
|
+
const attachments = attachmentsPath();
|
|
104
|
+
const plans = plansPath();
|
|
105
|
+
const skills = skillsPath();
|
|
106
|
+
const readRoots = [attachments, plans, skills];
|
|
107
|
+
if (toolName === READ_FILE_TOOL) {
|
|
108
|
+
const raw = toolInput.path;
|
|
109
|
+
if (typeof raw !== "string" || !raw.trim()) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
const resolved = normalizeUserPath(raw);
|
|
113
|
+
return readRoots.some((root) => isResolvedPathInsideDir(resolved, root));
|
|
114
|
+
}
|
|
115
|
+
if (toolName === READ_MULTIPLE_FILES_TOOL) {
|
|
116
|
+
const paths = toolInput.paths;
|
|
117
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
for (const item of paths) {
|
|
121
|
+
if (typeof item !== "string" || !item.trim()) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const resolved = normalizeUserPath(item);
|
|
125
|
+
const ok = readRoots.some((root) => isResolvedPathInsideDir(resolved, root));
|
|
126
|
+
if (!ok) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
if (toolName === WRITE_FILE_TOOL || toolName === EDIT_FILE_TOOL) {
|
|
133
|
+
const raw = toolInput.path;
|
|
134
|
+
if (typeof raw !== "string" || !raw.trim()) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
const resolved = normalizeUserPath(raw);
|
|
138
|
+
return isResolvedPathInsideDir(resolved, plans);
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
38
142
|
function normalizeAllowedTools(value) {
|
|
39
143
|
if (!Array.isArray(value)) {
|
|
40
144
|
return [];
|
|
@@ -60,8 +164,37 @@ export function getSessionAllowedTools(agent) {
|
|
|
60
164
|
}
|
|
61
165
|
return current;
|
|
62
166
|
}
|
|
63
|
-
|
|
64
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Session-wide tool allowlist ("always allow" in UI), plus implicit allow for
|
|
169
|
+
* read/write/edit when paths resolve under attachments, plans, or skills (reads)
|
|
170
|
+
* or plans only (writes/edits).
|
|
171
|
+
*/
|
|
172
|
+
export function isToolSessionAllowed(agent, toolName, toolInput) {
|
|
173
|
+
const mode = getModeState(agent).mode;
|
|
174
|
+
if (getSessionAllowedTools(agent).includes(toolName)) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
if ((mode === "plan" || mode === "ask") &&
|
|
178
|
+
PLAN_MODE_ALWAYS_ALLOWED.has(toolName)) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
if (isPlainObjectRecord(toolInput) &&
|
|
182
|
+
isImplicitPathAllowed(toolName, toolInput)) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
export function isToolVisible(mode, toolName) {
|
|
188
|
+
if (mode === "default") {
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
if (mode === "plan") {
|
|
192
|
+
return PLAN_MODE_VISIBLE.has(toolName);
|
|
193
|
+
}
|
|
194
|
+
if (mode === "ask") {
|
|
195
|
+
return ASK_MODE_VISIBLE.has(toolName);
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
65
198
|
}
|
|
66
199
|
export function allowToolForSession(agent, toolName) {
|
|
67
200
|
const normalized = toolName.trim();
|