@code-yeongyu/senpi 2026.5.14 → 2026.5.15-2

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 (161) hide show
  1. package/CHANGELOG.md +1107 -1182
  2. package/README.md +1 -2
  3. package/dist/core/agent-session.d.ts +9 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +109 -7
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/dynamic-prompt/verification.d.ts +31 -0
  8. package/dist/core/dynamic-prompt/verification.d.ts.map +1 -1
  9. package/dist/core/dynamic-prompt/verification.js +41 -0
  10. package/dist/core/dynamic-prompt/verification.js.map +1 -1
  11. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/compaction/index.js +157 -29
  13. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  14. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +197 -0
  15. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -0
  16. package/dist/core/extensions/builtin/compaction/openai-remote.js +690 -0
  17. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -0
  18. package/dist/core/extensions/builtin/compaction/prompts.d.ts +3 -3
  19. package/dist/core/extensions/builtin/compaction/prompts.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/compaction/prompts.js +0 -22
  21. package/dist/core/extensions/builtin/compaction/prompts.js.map +1 -1
  22. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts +4 -0
  23. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts.map +1 -0
  24. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js +48 -0
  25. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js.map +1 -0
  26. package/dist/core/extensions/builtin/compaction/speculative.d.ts +3 -1
  27. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/compaction/speculative.js +82 -33
  29. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  30. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +8 -0
  31. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/todo-bridge.js +12 -6
  33. package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
  34. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/index.js +0 -2
  36. package/dist/core/extensions/builtin/index.js.map +1 -1
  37. package/dist/core/extensions/builtin/permission-system/prompt.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/permission-system/prompt.js +0 -5
  39. package/dist/core/extensions/builtin/permission-system/prompt.js.map +1 -1
  40. package/dist/core/extensions/builtin/system-messages.d.ts +7 -7
  41. package/dist/core/extensions/builtin/system-messages.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/system-messages.js +10 -10
  43. package/dist/core/extensions/builtin/system-messages.js.map +1 -1
  44. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +1 -1
  45. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/todotools/continuation/prompt.js +1 -1
  47. package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +1 -1
  48. package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
  49. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/todotools/state.js +1 -1
  51. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  52. package/dist/core/extensions/builtin/todotools/system-messages.d.ts +3 -3
  53. package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/todotools/system-messages.js +6 -6
  55. package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -1
  56. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts +1 -1
  57. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/tool-pair-guard/index.js +8 -4
  59. package/dist/core/extensions/builtin/tool-pair-guard/index.js.map +1 -1
  60. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts +3 -0
  61. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts.map +1 -0
  62. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js +89 -0
  63. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js.map +1 -0
  64. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts +3 -0
  65. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts.map +1 -0
  66. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js +122 -0
  67. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js.map +1 -0
  68. package/dist/core/extensions/loader.d.ts.map +1 -1
  69. package/dist/core/extensions/loader.js +2 -0
  70. package/dist/core/extensions/loader.js.map +1 -1
  71. package/dist/core/extensions/runner.d.ts +3 -0
  72. package/dist/core/extensions/runner.d.ts.map +1 -1
  73. package/dist/core/extensions/runner.js +18 -0
  74. package/dist/core/extensions/runner.js.map +1 -1
  75. package/dist/core/extensions/types.d.ts +22 -0
  76. package/dist/core/extensions/types.d.ts.map +1 -1
  77. package/dist/core/extensions/types.js.map +1 -1
  78. package/dist/core/messages.d.ts +3 -3
  79. package/dist/core/messages.d.ts.map +1 -1
  80. package/dist/core/messages.js +5 -10
  81. package/dist/core/messages.js.map +1 -1
  82. package/dist/core/sdk.d.ts +1 -1
  83. package/dist/core/sdk.d.ts.map +1 -1
  84. package/dist/core/sdk.js +7 -22
  85. package/dist/core/sdk.js.map +1 -1
  86. package/dist/core/session-manager.d.ts.map +1 -1
  87. package/dist/core/session-manager.js +1 -1
  88. package/dist/core/session-manager.js.map +1 -1
  89. package/dist/core/settings-manager.d.ts +0 -5
  90. package/dist/core/settings-manager.d.ts.map +1 -1
  91. package/dist/core/settings-manager.js.map +1 -1
  92. package/dist/core/thinking-levels.d.ts +6 -0
  93. package/dist/core/thinking-levels.d.ts.map +1 -0
  94. package/dist/core/thinking-levels.js +36 -0
  95. package/dist/core/thinking-levels.js.map +1 -0
  96. package/dist/core/tools/bash.d.ts.map +1 -1
  97. package/dist/core/tools/bash.js +15 -1
  98. package/dist/core/tools/bash.js.map +1 -1
  99. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  100. package/dist/modes/interactive/components/compaction-summary-message.js +20 -2
  101. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  102. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  103. package/dist/modes/interactive/components/keybinding-hints.js +3 -1
  104. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  105. package/dist/modes/interactive/interactive-mode.d.ts +11 -0
  106. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  107. package/dist/modes/interactive/interactive-mode.js +96 -49
  108. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  109. package/docs/extensions.md +0 -1
  110. package/docs/index.md +0 -1
  111. package/docs/sdk.md +0 -1
  112. package/docs/settings.md +1 -29
  113. package/docs/termux.md +2 -2
  114. package/docs/usage.md +1 -1
  115. package/examples/README.md +1 -1
  116. package/examples/extensions/README.md +0 -1
  117. package/examples/extensions/overlay-qa-tests.ts +1 -1
  118. package/package.json +4 -4
  119. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts +0 -10
  120. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts.map +0 -1
  121. package/dist/core/extensions/builtin/background-task/cancel-tool.js +0 -109
  122. package/dist/core/extensions/builtin/background-task/cancel-tool.js.map +0 -1
  123. package/dist/core/extensions/builtin/background-task/index.d.ts +0 -3
  124. package/dist/core/extensions/builtin/background-task/index.d.ts.map +0 -1
  125. package/dist/core/extensions/builtin/background-task/index.js +0 -207
  126. package/dist/core/extensions/builtin/background-task/index.js.map +0 -1
  127. package/dist/core/extensions/builtin/background-task/manager.d.ts +0 -17
  128. package/dist/core/extensions/builtin/background-task/manager.d.ts.map +0 -1
  129. package/dist/core/extensions/builtin/background-task/manager.js +0 -114
  130. package/dist/core/extensions/builtin/background-task/manager.js.map +0 -1
  131. package/dist/core/extensions/builtin/background-task/notification.d.ts +0 -22
  132. package/dist/core/extensions/builtin/background-task/notification.d.ts.map +0 -1
  133. package/dist/core/extensions/builtin/background-task/notification.js +0 -105
  134. package/dist/core/extensions/builtin/background-task/notification.js.map +0 -1
  135. package/dist/core/extensions/builtin/background-task/output-tool.d.ts +0 -11
  136. package/dist/core/extensions/builtin/background-task/output-tool.d.ts.map +0 -1
  137. package/dist/core/extensions/builtin/background-task/output-tool.js +0 -127
  138. package/dist/core/extensions/builtin/background-task/output-tool.js.map +0 -1
  139. package/dist/core/extensions/builtin/background-task/spawner.d.ts +0 -8
  140. package/dist/core/extensions/builtin/background-task/spawner.d.ts.map +0 -1
  141. package/dist/core/extensions/builtin/background-task/spawner.js +0 -207
  142. package/dist/core/extensions/builtin/background-task/spawner.js.map +0 -1
  143. package/dist/core/extensions/builtin/background-task/task-tool.d.ts +0 -20
  144. package/dist/core/extensions/builtin/background-task/task-tool.d.ts.map +0 -1
  145. package/dist/core/extensions/builtin/background-task/task-tool.js +0 -302
  146. package/dist/core/extensions/builtin/background-task/task-tool.js.map +0 -1
  147. package/dist/core/extensions/builtin/background-task/types.d.ts +0 -72
  148. package/dist/core/extensions/builtin/background-task/types.d.ts.map +0 -1
  149. package/dist/core/extensions/builtin/background-task/types.js +0 -32
  150. package/dist/core/extensions/builtin/background-task/types.js.map +0 -1
  151. package/docs/agents.md +0 -348
  152. package/examples/extensions/subagent/README.md +0 -172
  153. package/examples/extensions/subagent/agents/planner.md +0 -37
  154. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  155. package/examples/extensions/subagent/agents/scout.md +0 -50
  156. package/examples/extensions/subagent/agents/worker.md +0 -24
  157. package/examples/extensions/subagent/agents.ts +0 -126
  158. package/examples/extensions/subagent/index.ts +0 -987
  159. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  160. package/examples/extensions/subagent/prompts/implement.md +0 -10
  161. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -1,72 +0,0 @@
1
- import { type Static, Type } from "typebox";
2
- export type SpawnOptions = {
3
- prompt: string;
4
- cwd: string;
5
- model?: string;
6
- agentType?: string;
7
- sessionPath?: string;
8
- permissionFlag?: string;
9
- signal?: AbortSignal;
10
- env?: Record<string, string>;
11
- onEvent?: (event: SpawnEvent) => void;
12
- };
13
- export type SpawnEvent = {
14
- type: "tool_execution_start";
15
- toolCallId: string;
16
- toolName: string;
17
- } | {
18
- type: "tool_execution_end";
19
- toolCallId: string;
20
- toolName: string;
21
- };
22
- export type SpawnedAgent = {
23
- process: import("node:child_process").ChildProcess;
24
- result: Promise<{
25
- text: string;
26
- exitCode: number;
27
- }>;
28
- };
29
- export type BackgroundTask = {
30
- id: string;
31
- description: string;
32
- prompt: string;
33
- model: string | undefined;
34
- agentType: string | undefined;
35
- status: "pending" | "running" | "completed" | "error" | "cancelled";
36
- pid: number | undefined;
37
- sessionPath: string | undefined;
38
- activeToolNames: string[];
39
- startedAt: Date;
40
- completedAt: Date | undefined;
41
- result: string | undefined;
42
- error: string | undefined;
43
- parentSessionId: string;
44
- };
45
- export declare const TaskToolParams: Type.TObject<{
46
- description: Type.TString;
47
- prompt: Type.TString;
48
- run_in_background: Type.TBoolean;
49
- session_id: Type.TOptional<Type.TString>;
50
- model: Type.TOptional<Type.TString>;
51
- agent_type: Type.TOptional<Type.TString>;
52
- }>;
53
- export type TaskToolParamsType = Static<typeof TaskToolParams>;
54
- export declare const BackgroundOutputParams: Type.TObject<{
55
- task_id: Type.TString;
56
- block: Type.TOptional<Type.TBoolean>;
57
- timeout: Type.TOptional<Type.TNumber>;
58
- }>;
59
- export type BackgroundOutputParamsType = Static<typeof BackgroundOutputParams>;
60
- export declare const BackgroundCancelParams: Type.TObject<{
61
- taskId: Type.TOptional<Type.TString>;
62
- all: Type.TOptional<Type.TBoolean>;
63
- }>;
64
- export type BackgroundCancelParamsType = Static<typeof BackgroundCancelParams>;
65
- export declare const MAX_CONCURRENT_TASKS: number;
66
- export declare const MAX_SUBAGENT_DEPTH = 1;
67
- export declare const DEPTH_ENV_VAR = "SANEPI_SUBAGENT_DEPTH";
68
- export declare const AGENT_TYPE_ENV_VAR = "SANEPI_AGENT_TYPE";
69
- export declare const TASK_ENTRY_TYPE = "background-task.state";
70
- export declare const DEFAULT_BLOCK_TIMEOUT = 60000;
71
- export declare const MAX_BLOCK_TIMEOUT = 300000;
72
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,UAAU,GACnB;IACA,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAChB,GACD;IACA,IAAI,EAAE,oBAAoB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAChB,CAAC;AAEL,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,OAAO,oBAAoB,EAAE,YAAY,CAAC;IACnD,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;IACpE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;EAezB,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE/D,eAAO,MAAM,sBAAsB;;;;EAQjC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE/E,eAAO,MAAM,sBAAsB;;;EAGjC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE/E,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAC7C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,aAAa,0BAA0B,CAAC;AACrD,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AACtD,eAAO,MAAM,eAAe,0BAA0B,CAAC;AACvD,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,eAAO,MAAM,iBAAiB,SAAS,CAAC","sourcesContent":["import { type Static, Type } from \"typebox\";\n\nexport type SpawnOptions = {\n\tprompt: string;\n\tcwd: string;\n\tmodel?: string;\n\tagentType?: string;\n\tsessionPath?: string;\n\tpermissionFlag?: string;\n\tsignal?: AbortSignal;\n\tenv?: Record<string, string>;\n\tonEvent?: (event: SpawnEvent) => void;\n};\n\nexport type SpawnEvent =\n\t| {\n\t\t\ttype: \"tool_execution_start\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t }\n\t| {\n\t\t\ttype: \"tool_execution_end\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t };\n\nexport type SpawnedAgent = {\n\tprocess: import(\"node:child_process\").ChildProcess;\n\tresult: Promise<{ text: string; exitCode: number }>;\n};\n\nexport type BackgroundTask = {\n\tid: string;\n\tdescription: string;\n\tprompt: string;\n\tmodel: string | undefined;\n\tagentType: string | undefined;\n\tstatus: \"pending\" | \"running\" | \"completed\" | \"error\" | \"cancelled\";\n\tpid: number | undefined;\n\tsessionPath: string | undefined;\n\tactiveToolNames: string[];\n\tstartedAt: Date;\n\tcompletedAt: Date | undefined;\n\tresult: string | undefined;\n\terror: string | undefined;\n\tparentSessionId: string;\n};\n\nexport const TaskToolParams = Type.Object({\n\tdescription: Type.String({ description: \"A short (3-5 words) description of the task\" }),\n\tprompt: Type.String({ description: \"The task for the agent to perform\" }),\n\trun_in_background: Type.Boolean({\n\t\tdescription:\n\t\t\t\"REQUIRED. true=async (returns task_id, system notifies on completion), false=sync (waits for result).\",\n\t}),\n\tsession_id: Type.Optional(Type.String({ description: \"Existing Task session to continue\" })),\n\tmodel: Type.Optional(Type.String({ description: \"Model to use for this task\" })),\n\tagent_type: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Agent type to use for this task (e.g. 'explore', 'general'). Determines available tools and permissions.\",\n\t\t}),\n\t),\n});\n\nexport type TaskToolParamsType = Static<typeof TaskToolParams>;\n\nexport const BackgroundOutputParams = Type.Object({\n\ttask_id: Type.String({ description: \"Task ID to get output from\" }),\n\tblock: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription: \"Wait for completion (default: false). System notifies when done, so blocking is rarely needed.\",\n\t\t}),\n\t),\n\ttimeout: Type.Optional(Type.Number({ description: \"Max wait time in ms (default: 60000, max: 300000)\" })),\n});\n\nexport type BackgroundOutputParamsType = Static<typeof BackgroundOutputParams>;\n\nexport const BackgroundCancelParams = Type.Object({\n\ttaskId: Type.Optional(Type.String({ description: \"Task ID to cancel (required if all=false)\" })),\n\tall: Type.Optional(Type.Boolean({ description: \"Cancel all running background tasks (default: false)\" })),\n});\n\nexport type BackgroundCancelParamsType = Static<typeof BackgroundCancelParams>;\n\nexport const MAX_CONCURRENT_TASKS = Infinity;\nexport const MAX_SUBAGENT_DEPTH = 1;\nexport const DEPTH_ENV_VAR = \"SANEPI_SUBAGENT_DEPTH\";\nexport const AGENT_TYPE_ENV_VAR = \"SANEPI_AGENT_TYPE\";\nexport const TASK_ENTRY_TYPE = \"background-task.state\";\nexport const DEFAULT_BLOCK_TIMEOUT = 60000;\nexport const MAX_BLOCK_TIMEOUT = 300000;\n"]}
@@ -1,32 +0,0 @@
1
- import { Type } from "typebox";
2
- export const TaskToolParams = Type.Object({
3
- description: Type.String({ description: "A short (3-5 words) description of the task" }),
4
- prompt: Type.String({ description: "The task for the agent to perform" }),
5
- run_in_background: Type.Boolean({
6
- description: "REQUIRED. true=async (returns task_id, system notifies on completion), false=sync (waits for result).",
7
- }),
8
- session_id: Type.Optional(Type.String({ description: "Existing Task session to continue" })),
9
- model: Type.Optional(Type.String({ description: "Model to use for this task" })),
10
- agent_type: Type.Optional(Type.String({
11
- description: "Agent type to use for this task (e.g. 'explore', 'general'). Determines available tools and permissions.",
12
- })),
13
- });
14
- export const BackgroundOutputParams = Type.Object({
15
- task_id: Type.String({ description: "Task ID to get output from" }),
16
- block: Type.Optional(Type.Boolean({
17
- description: "Wait for completion (default: false). System notifies when done, so blocking is rarely needed.",
18
- })),
19
- timeout: Type.Optional(Type.Number({ description: "Max wait time in ms (default: 60000, max: 300000)" })),
20
- });
21
- export const BackgroundCancelParams = Type.Object({
22
- taskId: Type.Optional(Type.String({ description: "Task ID to cancel (required if all=false)" })),
23
- all: Type.Optional(Type.Boolean({ description: "Cancel all running background tasks (default: false)" })),
24
- });
25
- export const MAX_CONCURRENT_TASKS = Infinity;
26
- export const MAX_SUBAGENT_DEPTH = 1;
27
- export const DEPTH_ENV_VAR = "SANEPI_SUBAGENT_DEPTH";
28
- export const AGENT_TYPE_ENV_VAR = "SANEPI_AGENT_TYPE";
29
- export const TASK_ENTRY_TYPE = "background-task.state";
30
- export const DEFAULT_BLOCK_TIMEOUT = 60000;
31
- export const MAX_BLOCK_TIMEOUT = 300000;
32
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAgD5C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;IACzC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;IACxF,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;IACzE,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC;QAC/B,WAAW,EACV,uGAAuG;KACxG,CAAC;IACF,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC,CAAC;IAC5F,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAChF,UAAU,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EACV,0GAA0G;KAC3G,CAAC,CACF;CACD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,OAAO,CAAC;QACZ,WAAW,EAAE,gGAAgG;KAC7G,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC,CAAC;CACzG,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CAAC;IAChG,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC,CAAC;CACzG,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AACrD,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AACtD,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC","sourcesContent":["import { type Static, Type } from \"typebox\";\n\nexport type SpawnOptions = {\n\tprompt: string;\n\tcwd: string;\n\tmodel?: string;\n\tagentType?: string;\n\tsessionPath?: string;\n\tpermissionFlag?: string;\n\tsignal?: AbortSignal;\n\tenv?: Record<string, string>;\n\tonEvent?: (event: SpawnEvent) => void;\n};\n\nexport type SpawnEvent =\n\t| {\n\t\t\ttype: \"tool_execution_start\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t }\n\t| {\n\t\t\ttype: \"tool_execution_end\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t };\n\nexport type SpawnedAgent = {\n\tprocess: import(\"node:child_process\").ChildProcess;\n\tresult: Promise<{ text: string; exitCode: number }>;\n};\n\nexport type BackgroundTask = {\n\tid: string;\n\tdescription: string;\n\tprompt: string;\n\tmodel: string | undefined;\n\tagentType: string | undefined;\n\tstatus: \"pending\" | \"running\" | \"completed\" | \"error\" | \"cancelled\";\n\tpid: number | undefined;\n\tsessionPath: string | undefined;\n\tactiveToolNames: string[];\n\tstartedAt: Date;\n\tcompletedAt: Date | undefined;\n\tresult: string | undefined;\n\terror: string | undefined;\n\tparentSessionId: string;\n};\n\nexport const TaskToolParams = Type.Object({\n\tdescription: Type.String({ description: \"A short (3-5 words) description of the task\" }),\n\tprompt: Type.String({ description: \"The task for the agent to perform\" }),\n\trun_in_background: Type.Boolean({\n\t\tdescription:\n\t\t\t\"REQUIRED. true=async (returns task_id, system notifies on completion), false=sync (waits for result).\",\n\t}),\n\tsession_id: Type.Optional(Type.String({ description: \"Existing Task session to continue\" })),\n\tmodel: Type.Optional(Type.String({ description: \"Model to use for this task\" })),\n\tagent_type: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Agent type to use for this task (e.g. 'explore', 'general'). Determines available tools and permissions.\",\n\t\t}),\n\t),\n});\n\nexport type TaskToolParamsType = Static<typeof TaskToolParams>;\n\nexport const BackgroundOutputParams = Type.Object({\n\ttask_id: Type.String({ description: \"Task ID to get output from\" }),\n\tblock: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription: \"Wait for completion (default: false). System notifies when done, so blocking is rarely needed.\",\n\t\t}),\n\t),\n\ttimeout: Type.Optional(Type.Number({ description: \"Max wait time in ms (default: 60000, max: 300000)\" })),\n});\n\nexport type BackgroundOutputParamsType = Static<typeof BackgroundOutputParams>;\n\nexport const BackgroundCancelParams = Type.Object({\n\ttaskId: Type.Optional(Type.String({ description: \"Task ID to cancel (required if all=false)\" })),\n\tall: Type.Optional(Type.Boolean({ description: \"Cancel all running background tasks (default: false)\" })),\n});\n\nexport type BackgroundCancelParamsType = Static<typeof BackgroundCancelParams>;\n\nexport const MAX_CONCURRENT_TASKS = Infinity;\nexport const MAX_SUBAGENT_DEPTH = 1;\nexport const DEPTH_ENV_VAR = \"SANEPI_SUBAGENT_DEPTH\";\nexport const AGENT_TYPE_ENV_VAR = \"SANEPI_AGENT_TYPE\";\nexport const TASK_ENTRY_TYPE = \"background-task.state\";\nexport const DEFAULT_BLOCK_TIMEOUT = 60000;\nexport const MAX_BLOCK_TIMEOUT = 300000;\n"]}
package/docs/agents.md DELETED
@@ -1,348 +0,0 @@
1
- > pi can create custom agents. Ask it to build one for your use case.
2
-
3
- # Agents
4
-
5
- Agents are typed subagent profiles that control which tools a spawned task can use and what system prompt it receives. Use agents to enforce read-only exploration, restrict dangerous operations, or create specialized task runners.
6
-
7
- ## Table of Contents
8
-
9
- - [Built-in Agents](#built-in-agents)
10
- - [Using Agents](#using-agents)
11
- - [Custom Agents](#custom-agents)
12
- - [Locations](#locations)
13
- - [Frontmatter](#frontmatter)
14
- - [Example](#example)
15
- - [Permissions](#permissions)
16
- - [Permission Actions](#permission-actions)
17
- - [Permission Config](#permission-config)
18
- - [Evaluation Order](#evaluation-order)
19
- - [Ask Mode](#ask-mode)
20
- - [Configuration](#configuration)
21
- - [Directory Setup](#directory-setup)
22
- - [Writing an Agent File](#writing-an-agent-file)
23
- - [Settings](#settings)
24
- - [Priority Order](#priority-order)
25
- - [Quick Start Recipes](#quick-start-recipes)
26
- - [How It Works](#how-it-works)
27
- - [Known Limitations](#known-limitations)
28
-
29
- ## Built-in Agents
30
-
31
- | Agent | Tools | System Prompt | Description |
32
- |-------|-------|---------------|-------------|
33
- | `general` | All except `task`, `todowrite` | Default pi prompt | General-purpose agent for parallel work |
34
- | `explore` | `read`, `grep`, `find`, `ls`, `bash` | File search specialist | Read-only codebase exploration |
35
-
36
- ### general
37
-
38
- The default agent for complex multi-step tasks. It can use all tools except `task` and `todowrite` (to prevent nested subagent spawning and todo list conflicts).
39
-
40
- Permission config:
41
-
42
- ```json
43
- {
44
- "*": "allow",
45
- "task": "deny",
46
- "todowrite": "deny"
47
- }
48
- ```
49
-
50
- ### explore
51
-
52
- A read-only agent optimized for fast codebase exploration. It can search, read, and list files but cannot modify anything.
53
-
54
- Permission config:
55
-
56
- ```json
57
- {
58
- "read": "allow",
59
- "grep": "allow",
60
- "find": "allow",
61
- "ls": "allow",
62
- "bash": "allow"
63
- }
64
- ```
65
-
66
- System prompt appended:
67
-
68
- ```
69
- You are a file search specialist. You excel at thoroughly navigating and exploring codebases.
70
- Guidelines:
71
- - Search file contents by regex or literal pattern when you need to locate usages or definitions
72
- - Read files directly when you already know the path
73
- - List directory contents to build a map of unfamiliar areas
74
- - Return file paths as absolute paths
75
- - Do not create any files or modify the system state
76
- Complete the search request efficiently and report findings clearly.
77
- ```
78
-
79
- ## Using Agents
80
-
81
- Pass `agent_type` when spawning a task:
82
-
83
- ```typescript
84
- task(agent_type="explore", prompt="Find all files importing React", run_in_background=true)
85
- task(agent_type="general", prompt="Refactor the auth module", run_in_background=false)
86
- ```
87
-
88
- Without `agent_type`, the task tool works exactly as before (no restrictions, full backward compat).
89
-
90
- ## Custom Agents
91
-
92
- ### Locations
93
-
94
- Pi loads custom agents from Markdown files in:
95
-
96
- - Global: `~/.senpi/agent/**/*.md` and `~/.senpi/agents/**/*.md`
97
- - Project: `.senpi/agent/**/*.md` and `.senpi/agents/**/*.md` (in current working directory)
98
-
99
- Both `agent/` and `agents/` directories are scanned recursively. The agent name is derived from the filename: `my-agent.md` becomes `my-agent`.
100
-
101
- **Name collision resolution:** Project-local agents override global agents with the same name.
102
-
103
- ### Frontmatter
104
-
105
- Custom agents use YAML frontmatter (same format as skills):
106
-
107
- | Field | Type | Required | Description |
108
- |-------|------|----------|-------------|
109
- | `description` | string | No | What this agent does and when to use it |
110
- | `mode` | string | No | `"subagent"`, `"primary"`, or `"all"` (default: `"all"`) |
111
- | `model` | string | No | Model ID for this agent (e.g., `"anthropic/claude-haiku-4-5"`) |
112
- | `temperature` | number | No | Sampling temperature 0-2 |
113
- | `tools` | object | No | Permission config (see below) |
114
- | `disable` | boolean | No | When `true`, agent is not loaded |
115
-
116
- **Mode values:**
117
- - `"subagent"` - Only runs as a task subagent (spawned via `task()`)
118
- - `"primary"` - Only runs in the main session (not as a subagent)
119
- - `"all"` - Can run in both contexts
120
-
121
- ### Example
122
-
123
- Create `.senpi/agents/readonly.md`:
124
-
125
- ```markdown
126
- ---
127
- description: Read-only agent for safe codebase exploration
128
- mode: subagent
129
- tools:
130
- read: allow
131
- grep: allow
132
- find: allow
133
- ls: allow
134
- bash: deny
135
- write: deny
136
- edit: deny
137
- ---
138
-
139
- You are a read-only exploration agent. You can search and read files but cannot modify anything.
140
-
141
- Guidelines:
142
- - Use grep to search for code patterns
143
- - Use read to examine file contents
144
- - Use find and ls to navigate the filesystem
145
- - Never suggest file modifications
146
- - Report findings clearly and concisely
147
- ```
148
-
149
- Use it:
150
-
151
- ```typescript
152
- task(agent_type="readonly", prompt="Find all TODO comments in the codebase", run_in_background=true)
153
- ```
154
-
155
- ## Permissions
156
-
157
- ### Permission Actions
158
-
159
- Three actions control tool access:
160
-
161
- - `allow` - Tool executes normally
162
- - `deny` - Tool blocked, LLM receives error message explaining the restriction
163
- - `ask` - In interactive mode, user is prompted to allow/deny. In non-interactive mode (json/print), auto-denied.
164
-
165
- ### Permission Config
166
-
167
- The `tools` frontmatter field accepts two formats.
168
-
169
- **Simple format** - single action for all patterns:
170
-
171
- ```yaml
172
- tools:
173
- read: allow
174
- bash: deny
175
- edit: ask
176
- ```
177
-
178
- **Nested format** - pattern-specific rules (for future extensibility):
179
-
180
- ```yaml
181
- tools:
182
- read:
183
- "*": allow
184
- "*.env": ask
185
- bash: deny
186
- ```
187
-
188
- Currently, pattern matching is not implemented for specific paths. The `"*"` pattern applies to all uses of that tool.
189
-
190
- ### Evaluation Order
191
-
192
- Permissions are evaluated using `findLast` semantics: **later rules override earlier ones**.
193
-
194
- Merge order (later wins):
195
-
196
- 1. Global defaults from `settings.json` (`agentDefaults.permission`)
197
- 2. Built-in agent permissions (for built-in agents)
198
- 3. Custom agent permissions (from frontmatter `tools`)
199
-
200
- Example: If global defaults set `"bash": "ask"` but a custom agent sets `"bash": "allow"`, the agent's explicit permission wins.
201
-
202
- ### Ask Mode
203
-
204
- In **interactive mode**, when a tool with `"ask"` permission is called:
205
-
206
- 1. TUI displays a select prompt: "Allow once / Allow always / Deny"
207
- 2. "Allow once" permits this single call
208
- 3. "Allow always" persists a matching approval rule to `.senpi/permissions-approved.jsonl`, so matching calls are auto-allowed after reload too
209
- 4. "Deny" blocks with an error message
210
-
211
- In **non-interactive mode** (json or print output), `ask` permissions are auto-denied with an explanatory message.
212
-
213
- ## Configuration
214
-
215
- ### Directory Setup
216
-
217
- Create your agent directory structure:
218
-
219
- ```
220
- # Project-local agents (recommended)
221
- .senpi/
222
- agents/
223
- my-agent.md
224
- code-reviewer.md
225
-
226
- # Global agents (shared across projects)
227
- ~/.senpi/
228
- agents/
229
- my-global-agent.md
230
- ```
231
-
232
- Both `agent/` and `agents/` subdirectories are scanned recursively.
233
-
234
- ### Writing an Agent File
235
-
236
- Agent files are Markdown with YAML frontmatter. The body (after `---`) becomes the agent's system prompt.
237
-
238
- ```markdown
239
- ---
240
- description: Strict code reviewer that only reads and analyzes
241
- mode: subagent
242
- model: anthropic/claude-sonnet-4-20250514
243
- temperature: 0.3
244
- tools:
245
- read: allow
246
- grep: allow
247
- find: allow
248
- ls: allow
249
- bash: allow
250
- edit: deny
251
- write: deny
252
- task: deny
253
- ---
254
-
255
- You are a code review specialist. Analyze code for bugs, security issues, and style violations.
256
-
257
- Rules:
258
- - Never suggest modifying files directly
259
- - Always reference specific line numbers
260
- - Categorize issues as: critical, warning, or suggestion
261
- ```
262
-
263
- ### Settings
264
-
265
- Configure default permissions and model for all agents in `settings.json`.
266
-
267
- | Location | Scope |
268
- |----------|-------|
269
- | `~/.senpi/agent/settings.json` | Global (all projects) |
270
- | `.senpi/settings.json` | Project (overrides global) |
271
-
272
- Add the `agentDefaults` key:
273
-
274
- ```json
275
- {
276
- "agentDefaults": {
277
- "permission": {
278
- "write": "ask",
279
- "edit": "ask",
280
- "bash": "allow",
281
- "read": "allow"
282
- },
283
- "model": "anthropic/claude-haiku-4-5"
284
- }
285
- }
286
- ```
287
-
288
- | Setting | Type | Default | Description |
289
- |---------|------|---------|-------------|
290
- | `agentDefaults.permission` | object | `{}` | Default tool permissions for all agents (see [Permission Actions](#permission-actions)) |
291
- | `agentDefaults.model` | string | - | Default model ID for spawned agents |
292
-
293
- These defaults are the **lowest priority** layer. Agent-specific permissions (from frontmatter `tools`) override them.
294
-
295
- ### Priority Order
296
-
297
- Permissions are resolved in this order (later wins):
298
-
299
- 1. `settings.json` -> `agentDefaults.permission` (lowest priority)
300
- 2. Built-in agent permissions (`general`, `explore` configs)
301
- 3. Custom agent frontmatter `tools` (highest priority)
302
-
303
- Example: Global settings set `bash: ask`, but your custom agent sets `bash: allow` -> bash is allowed for that agent.
304
-
305
- ### Quick Start Recipes
306
-
307
- **Read-only explorer:**
308
- ```typescript
309
- task(agent_type="explore", prompt="Find all error handling patterns", run_in_background=true)
310
- ```
311
-
312
- **Custom strict reviewer:**
313
- 1. Create `.senpi/agents/reviewer.md` (see [Writing an Agent File](#writing-an-agent-file))
314
- 2. Use: `task(agent_type="reviewer", prompt="Review changes in src/auth/", run_in_background=false)`
315
-
316
- **Restrict all agents by default:**
317
- Add to `~/.senpi/agent/settings.json`:
318
- ```json
319
- {
320
- "agentDefaults": {
321
- "permission": {
322
- "write": "ask",
323
- "edit": "ask"
324
- }
325
- }
326
- }
327
- ```
328
- Now every agent must get user confirmation before writing or editing files.
329
-
330
- ## How It Works
331
-
332
- The agent system is implemented as a builtin extension that intercepts the task tool:
333
-
334
- 1. **Environment variable** - When `task(agent_type="...")` is called, the agent type is passed via `SANEPI_AGENT_TYPE` environment variable to the subprocess
335
- 2. **Registry lookup** - On session start, the extension scans `~/.senpi/` and `.senpi/` for agent definitions, merges with built-in agents, and resolves by name
336
- 3. **Tool filtering** - `setActiveTools()` removes denied tools from the LLM's tool list entirely (they don't appear in the API call)
337
- 4. **Defense in depth** - A `tool_call` event handler acts as backup, catching any tools that slip through (e.g., added dynamically after session start)
338
- 5. **System prompt** - The `before_agent_start` event appends the agent's custom prompt to the existing system prompt (doesn't replace it)
339
- 6. **Permission evaluation** - Each tool call is checked against the merged permission rules (global defaults + agent config)
340
-
341
- ## Known Limitations
342
-
343
- - `disable: true` in custom agents does not currently remove built-in agents (v1 limitation)
344
- - Bash permission bypass: denying `edit` but allowing `bash` still permits `echo > file` via bash redirection
345
- - No sub-pattern matching for bash commands (entire bash tool allow/deny only, no per-command filtering)
346
- - `ask` mode in non-interactive (json/print) mode auto-denies without user input
347
- - No dynamic permission changes at runtime (permissions are immutable after agent start)
348
- - No agent permission inheritance chains (flat configs only, no "extends" mechanism)
@@ -1,172 +0,0 @@
1
- # Subagent Example
2
-
3
- Delegate tasks to specialized subagents with isolated context windows.
4
-
5
- ## Features
6
-
7
- - **Isolated context**: Each subagent runs in a separate `pi` process
8
- - **Streaming output**: See tool calls and progress as they happen
9
- - **Parallel streaming**: All parallel tasks stream updates simultaneously
10
- - **Markdown rendering**: Final output rendered with proper formatting (expanded view)
11
- - **Usage tracking**: Shows turns, tokens, cost, and context usage per agent
12
- - **Abort support**: Ctrl+C propagates to kill subagent processes
13
-
14
- ## Structure
15
-
16
- ```
17
- subagent/
18
- ├── README.md # This file
19
- ├── index.ts # The extension (entry point)
20
- ├── agents.ts # Agent discovery logic
21
- ├── agents/ # Sample agent definitions
22
- │ ├── scout.md # Fast recon, returns compressed context
23
- │ ├── planner.md # Creates implementation plans
24
- │ ├── reviewer.md # Code review
25
- │ └── worker.md # General-purpose (full capabilities)
26
- └── prompts/ # Workflow presets (prompt templates)
27
- ├── implement.md # scout -> planner -> worker
28
- ├── scout-and-plan.md # scout -> planner (no implementation)
29
- └── implement-and-review.md # worker -> reviewer -> worker
30
- ```
31
-
32
- ## Installation
33
-
34
- From the repository root, symlink the files:
35
-
36
- ```bash
37
- # Symlink the extension (must be in a subdirectory with index.ts)
38
- mkdir -p ~/.senpi/agent/extensions/subagent
39
- ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/index.ts" ~/.senpi/agent/extensions/subagent/index.ts
40
- ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/agents.ts" ~/.senpi/agent/extensions/subagent/agents.ts
41
-
42
- # Symlink agents
43
- mkdir -p ~/.senpi/agent/agents
44
- for f in packages/coding-agent/examples/extensions/subagent/agents/*.md; do
45
- ln -sf "$(pwd)/$f" ~/.senpi/agent/agents/$(basename "$f")
46
- done
47
-
48
- # Symlink workflow prompts
49
- mkdir -p ~/.senpi/agent/prompts
50
- for f in packages/coding-agent/examples/extensions/subagent/prompts/*.md; do
51
- ln -sf "$(pwd)/$f" ~/.senpi/agent/prompts/$(basename "$f")
52
- done
53
- ```
54
-
55
- ## Security Model
56
-
57
- This tool executes a separate `pi` subprocess with a delegated system prompt and tool/model configuration.
58
-
59
- **Project-local agents** (`.senpi/agents/*.md`) are repo-controlled prompts that can instruct the model to read files, run bash commands, etc.
60
-
61
- **Default behavior:** Only loads **user-level agents** from `~/.senpi/agent/agents`.
62
-
63
- To enable project-local agents, pass `agentScope: "both"` (or `"project"`). Only do this for repositories you trust.
64
-
65
- When running interactively, the tool prompts for confirmation before running project-local agents. Set `confirmProjectAgents: false` to disable.
66
-
67
- ## Usage
68
-
69
- ### Single agent
70
- ```
71
- Use scout to find all authentication code
72
- ```
73
-
74
- ### Parallel execution
75
- ```
76
- Run 2 scouts in parallel: one to find models, one to find providers
77
- ```
78
-
79
- ### Chained workflow
80
- ```
81
- Use a chain: first have scout find the read tool, then have planner suggest improvements
82
- ```
83
-
84
- ### Workflow prompts
85
- ```
86
- /implement add Redis caching to the session store
87
- /scout-and-plan refactor auth to support OAuth
88
- /implement-and-review add input validation to API endpoints
89
- ```
90
-
91
- ## Tool Modes
92
-
93
- | Mode | Parameter | Description |
94
- |------|-----------|-------------|
95
- | Single | `{ agent, task }` | One agent, one task |
96
- | Parallel | `{ tasks: [...] }` | Multiple agents run concurrently (max 8, 4 concurrent) |
97
- | Chain | `{ chain: [...] }` | Sequential with `{previous}` placeholder |
98
-
99
- ## Output Display
100
-
101
- **Collapsed view** (default):
102
- - Status icon (✓/✗/⏳) and agent name
103
- - Last 5-10 items (tool calls and text)
104
- - Usage stats: `3 turns ↑input ↓output RcacheRead WcacheWrite $cost ctx:contextTokens model`
105
-
106
- **Expanded view** (Ctrl+O):
107
- - Full task text
108
- - All tool calls with formatted arguments
109
- - Final output rendered as Markdown
110
- - Per-task usage (for chain/parallel)
111
-
112
- **Parallel mode streaming**:
113
- - Shows all tasks with live status (⏳ running, ✓ done, ✗ failed)
114
- - Updates as each task makes progress
115
- - Shows "2/3 done, 1 running" status
116
-
117
- **Tool call formatting** (mimics built-in tools):
118
- - `$ command` for bash
119
- - `read ~/path:1-10` for read
120
- - `grep /pattern/ in ~/path` for grep
121
- - etc.
122
-
123
- ## Agent Definitions
124
-
125
- Agents are markdown files with YAML frontmatter:
126
-
127
- ```markdown
128
- ---
129
- name: my-agent
130
- description: What this agent does
131
- tools: read, grep, find, ls
132
- model: claude-haiku-4-5
133
- ---
134
-
135
- System prompt for the agent goes here.
136
- ```
137
-
138
- **Locations:**
139
- - `~/.senpi/agent/agents/*.md` - User-level (always loaded)
140
- - `.senpi/agents/*.md` - Project-level (only with `agentScope: "project"` or `"both"`)
141
-
142
- Project agents override user agents with the same name when `agentScope: "both"`.
143
-
144
- ## Sample Agents
145
-
146
- | Agent | Purpose | Model | Tools |
147
- |-------|---------|-------|-------|
148
- | `scout` | Fast codebase recon | Haiku | read, grep, find, ls, bash |
149
- | `planner` | Implementation plans | Sonnet | read, grep, find, ls |
150
- | `reviewer` | Code review | Sonnet | read, grep, find, ls, bash |
151
- | `worker` | General-purpose | Sonnet | (all default) |
152
-
153
- ## Workflow Prompts
154
-
155
- | Prompt | Flow |
156
- |--------|------|
157
- | `/implement <query>` | scout → planner → worker |
158
- | `/scout-and-plan <query>` | scout → planner |
159
- | `/implement-and-review <query>` | worker → reviewer → worker |
160
-
161
- ## Error Handling
162
-
163
- - **Exit code != 0**: Tool returns error with stderr/output
164
- - **stopReason "error"**: LLM error propagated with error message
165
- - **stopReason "aborted"**: User abort (Ctrl+C) kills subprocess, throws error
166
- - **Chain mode**: Stops at first failing step, reports which step failed
167
-
168
- ## Limitations
169
-
170
- - Output truncated to last 10 items in collapsed view (expand to see all)
171
- - Agents discovered fresh on each invocation (allows editing mid-session)
172
- - Parallel mode limited to 8 tasks, 4 concurrent
@@ -1,37 +0,0 @@
1
- ---
2
- name: planner
3
- description: Creates implementation plans from context and requirements
4
- tools: read, grep, find, ls
5
- model: claude-sonnet-4-5
6
- ---
7
-
8
- You are a planning specialist. You receive context (from a scout) and requirements, then produce a clear implementation plan.
9
-
10
- You must NOT make any changes. Only read, analyze, and plan.
11
-
12
- Input format you'll receive:
13
- - Context/findings from a scout agent
14
- - Original query or requirements
15
-
16
- Output format:
17
-
18
- ## Goal
19
- One sentence summary of what needs to be done.
20
-
21
- ## Plan
22
- Numbered steps, each small and actionable:
23
- 1. Step one - specific file/function to modify
24
- 2. Step two - what to add/change
25
- 3. ...
26
-
27
- ## Files to Modify
28
- - `path/to/file.ts` - what changes
29
- - `path/to/other.ts` - what changes
30
-
31
- ## New Files (if any)
32
- - `path/to/new.ts` - purpose
33
-
34
- ## Risks
35
- Anything to watch out for.
36
-
37
- Keep the plan concrete. The worker agent will execute it verbatim.