@within-7/minto 0.3.6 → 0.3.10

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 (238) hide show
  1. package/{cli.js → cli.cjs} +25 -23
  2. package/dist/commands/agents/AgentsCommand.js +459 -655
  3. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  4. package/dist/commands/agents/types.js +1 -0
  5. package/dist/commands/agents/types.js.map +2 -2
  6. package/dist/commands/agents/utils/fileOperations.js +96 -36
  7. package/dist/commands/agents/utils/fileOperations.js.map +3 -3
  8. package/dist/commands/agents/utils/index.js +3 -1
  9. package/dist/commands/agents/utils/index.js.map +2 -2
  10. package/dist/commands/context.js +54 -23
  11. package/dist/commands/context.js.map +2 -2
  12. package/dist/commands/export.js +673 -93
  13. package/dist/commands/export.js.map +2 -2
  14. package/dist/commands/language.js +110 -0
  15. package/dist/commands/language.js.map +7 -0
  16. package/dist/commands/mcp-interactive.js +419 -217
  17. package/dist/commands/mcp-interactive.js.map +2 -2
  18. package/dist/commands/model.js +415 -66
  19. package/dist/commands/model.js.map +2 -2
  20. package/dist/commands/new.js +56 -0
  21. package/dist/commands/new.js.map +7 -0
  22. package/dist/commands/permissions.js +75 -49
  23. package/dist/commands/permissions.js.map +2 -2
  24. package/dist/commands/plugin.js +882 -185
  25. package/dist/commands/plugin.js.map +3 -3
  26. package/dist/commands/resume.js +251 -16
  27. package/dist/commands/resume.js.map +2 -2
  28. package/dist/commands/sandbox.js +168 -70
  29. package/dist/commands/sandbox.js.map +2 -2
  30. package/dist/commands/sessions.js +224 -0
  31. package/dist/commands/sessions.js.map +7 -0
  32. package/dist/commands/setup.js +596 -109
  33. package/dist/commands/setup.js.map +2 -2
  34. package/dist/commands/stats.js +292 -0
  35. package/dist/commands/stats.js.map +7 -0
  36. package/dist/commands/status.js +75 -7
  37. package/dist/commands/status.js.map +2 -2
  38. package/dist/commands/undo.js +154 -180
  39. package/dist/commands/undo.js.map +2 -2
  40. package/dist/commands.js +6 -0
  41. package/dist/commands.js.map +2 -2
  42. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
  43. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  44. package/dist/components/Config.js +9 -8
  45. package/dist/components/Config.js.map +2 -2
  46. package/dist/components/HeaderBar.js +2 -1
  47. package/dist/components/HeaderBar.js.map +2 -2
  48. package/dist/components/Help.js +166 -32
  49. package/dist/components/Help.js.map +2 -2
  50. package/dist/components/HotkeyHelpPanel.js +46 -44
  51. package/dist/components/HotkeyHelpPanel.js.map +2 -2
  52. package/dist/components/InfoPanel/InfoPanel.js +123 -0
  53. package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
  54. package/dist/components/InfoPanel/index.js +5 -0
  55. package/dist/components/InfoPanel/index.js.map +7 -0
  56. package/dist/components/InfoPanel/types.js +1 -0
  57. package/dist/components/InfoPanel/types.js.map +7 -0
  58. package/dist/components/Logo.js +5 -2
  59. package/dist/components/Logo.js.map +2 -2
  60. package/dist/components/MCPServerApprovalDialog.js +6 -5
  61. package/dist/components/MCPServerApprovalDialog.js.map +2 -2
  62. package/dist/components/MCPServerMultiselectDialog.js +5 -4
  63. package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
  64. package/dist/components/MessageSelector.js +4 -3
  65. package/dist/components/MessageSelector.js.map +2 -2
  66. package/dist/components/ModelConfig.js +13 -12
  67. package/dist/components/ModelConfig.js.map +2 -2
  68. package/dist/components/ModelListManager.js +4 -3
  69. package/dist/components/ModelListManager.js.map +2 -2
  70. package/dist/components/ModelSelector/BrandTextInput.js +43 -0
  71. package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
  72. package/dist/components/ModelSelector/ModelSelector.js +419 -501
  73. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  74. package/dist/components/ModelSelector/WizardContainer.js +45 -0
  75. package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
  76. package/dist/components/ModelSelector/index.js +1 -3
  77. package/dist/components/ModelSelector/index.js.map +2 -2
  78. package/dist/components/PromptInput.js +77 -44
  79. package/dist/components/PromptInput.js.map +2 -2
  80. package/dist/components/SensitiveFileWarning.js +12 -8
  81. package/dist/components/SensitiveFileWarning.js.map +2 -2
  82. package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
  83. package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
  84. package/dist/components/SimpleSelector/index.js +5 -0
  85. package/dist/components/SimpleSelector/index.js.map +7 -0
  86. package/dist/components/SimpleSelector/types.js +1 -0
  87. package/dist/components/SimpleSelector/types.js.map +7 -0
  88. package/dist/components/StatusOverlayContent.js +21 -0
  89. package/dist/components/StatusOverlayContent.js.map +7 -0
  90. package/dist/components/TabbedListView/ScrollableList.js +117 -0
  91. package/dist/components/TabbedListView/ScrollableList.js.map +7 -0
  92. package/dist/components/TabbedListView/SearchInput.js +23 -0
  93. package/dist/components/TabbedListView/SearchInput.js.map +7 -0
  94. package/dist/components/TabbedListView/TabBar.js +20 -0
  95. package/dist/components/TabbedListView/TabBar.js.map +7 -0
  96. package/dist/components/TabbedListView/TabbedListView.js +246 -0
  97. package/dist/components/TabbedListView/TabbedListView.js.map +7 -0
  98. package/dist/components/TabbedListView/index.js +11 -0
  99. package/dist/components/TabbedListView/index.js.map +7 -0
  100. package/dist/components/TabbedListView/types.js +1 -0
  101. package/dist/components/TabbedListView/types.js.map +7 -0
  102. package/dist/components/TodoChangeBlock.js +6 -5
  103. package/dist/components/TodoChangeBlock.js.map +3 -3
  104. package/dist/components/TodoPanel.js +6 -3
  105. package/dist/components/TodoPanel.js.map +3 -3
  106. package/dist/components/TrustDialog.js +6 -5
  107. package/dist/components/TrustDialog.js.map +2 -2
  108. package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +2 -1
  109. package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +2 -2
  110. package/dist/constants/macros.js +1 -1
  111. package/dist/constants/macros.js.map +1 -1
  112. package/dist/constants/product.js +2 -2
  113. package/dist/constants/product.js.map +1 -1
  114. package/dist/constants/prompts.js +17 -0
  115. package/dist/constants/prompts.js.map +2 -2
  116. package/dist/constants/toolInputExamples.js +5 -1
  117. package/dist/constants/toolInputExamples.js.map +2 -2
  118. package/dist/core/backupHook.js +29 -0
  119. package/dist/core/backupHook.js.map +7 -0
  120. package/dist/core/config/defaults.js +8 -2
  121. package/dist/core/config/defaults.js.map +2 -2
  122. package/dist/core/config/schema.js +14 -2
  123. package/dist/core/config/schema.js.map +2 -2
  124. package/dist/core/costTracker.js +0 -16
  125. package/dist/core/costTracker.js.map +2 -2
  126. package/dist/core/tokenStatsManager.js +5 -0
  127. package/dist/core/tokenStatsManager.js.map +2 -2
  128. package/dist/cost-tracker.js +0 -16
  129. package/dist/cost-tracker.js.map +2 -2
  130. package/dist/entrypoints/bootstrap.js +56 -0
  131. package/dist/entrypoints/bootstrap.js.map +7 -0
  132. package/dist/entrypoints/cli.js +164 -23
  133. package/dist/entrypoints/cli.js.map +3 -3
  134. package/dist/history.js +75 -15
  135. package/dist/history.js.map +2 -2
  136. package/dist/i18n/index.js +2 -2
  137. package/dist/i18n/index.js.map +2 -2
  138. package/dist/i18n/locales/en.js +582 -1
  139. package/dist/i18n/locales/en.js.map +2 -2
  140. package/dist/i18n/locales/zh-CN.js +582 -1
  141. package/dist/i18n/locales/zh-CN.js.map +2 -2
  142. package/dist/i18n/types.js.map +1 -1
  143. package/dist/index.js +1 -1
  144. package/dist/index.js.map +2 -2
  145. package/dist/messages.js +11 -0
  146. package/dist/messages.js.map +2 -2
  147. package/dist/permissions.js.map +2 -2
  148. package/dist/query.js +9 -0
  149. package/dist/query.js.map +2 -2
  150. package/dist/screens/REPL.js +45 -7
  151. package/dist/screens/REPL.js.map +2 -2
  152. package/dist/services/customCommands.js +44 -16
  153. package/dist/services/customCommands.js.map +2 -2
  154. package/dist/services/plugins/lspServers.js +1 -1
  155. package/dist/services/plugins/lspServers.js.map +2 -2
  156. package/dist/services/plugins/pluginRuntime.js +2 -1
  157. package/dist/services/plugins/pluginRuntime.js.map +2 -2
  158. package/dist/services/plugins/pluginValidation.js +10 -3
  159. package/dist/services/plugins/pluginValidation.js.map +2 -2
  160. package/dist/services/plugins/skillMarketplace.js +16 -8
  161. package/dist/services/plugins/skillMarketplace.js.map +2 -2
  162. package/dist/services/systemReminder.js +17 -6
  163. package/dist/services/systemReminder.js.map +2 -2
  164. package/dist/tools/FileEditTool/FileEditTool.js +7 -0
  165. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  166. package/dist/tools/FileWriteTool/FileWriteTool.js +7 -0
  167. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  168. package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
  169. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  170. package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
  171. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  172. package/dist/tools/TaskTool/TaskTool.js +179 -1
  173. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  174. package/dist/tools/TodoWriteTool/prompt.js +21 -0
  175. package/dist/tools/TodoWriteTool/prompt.js.map +2 -2
  176. package/dist/tools/URLFetcherTool/prompt.js +14 -9
  177. package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
  178. package/dist/tools/WebSearchTool/prompt.js +12 -6
  179. package/dist/tools/WebSearchTool/prompt.js.map +2 -2
  180. package/dist/types/PermissionMode.js +30 -1
  181. package/dist/types/PermissionMode.js.map +2 -2
  182. package/dist/types/plugin.js +2 -4
  183. package/dist/types/plugin.js.map +2 -2
  184. package/dist/utils/agentHookExecutor.js +103 -0
  185. package/dist/utils/agentHookExecutor.js.map +7 -0
  186. package/dist/utils/agentLoader.js +272 -32
  187. package/dist/utils/agentLoader.js.map +2 -2
  188. package/dist/utils/agentMemory.js +134 -0
  189. package/dist/utils/agentMemory.js.map +7 -0
  190. package/dist/utils/claudeCodeSync.js +439 -0
  191. package/dist/utils/claudeCodeSync.js.map +7 -0
  192. package/dist/utils/config.js +52 -24
  193. package/dist/utils/config.js.map +2 -2
  194. package/dist/utils/configPaths.js +199 -0
  195. package/dist/utils/configPaths.js.map +7 -0
  196. package/dist/utils/execFileNoThrow.js +2 -1
  197. package/dist/utils/execFileNoThrow.js.map +2 -2
  198. package/dist/utils/historyManager.js +234 -0
  199. package/dist/utils/historyManager.js.map +7 -0
  200. package/dist/utils/marketplaceManager.js +80 -43
  201. package/dist/utils/marketplaceManager.js.map +2 -2
  202. package/dist/utils/messages.js +13 -8
  203. package/dist/utils/messages.js.map +2 -2
  204. package/dist/utils/migration/index.js +37 -0
  205. package/dist/utils/migration/index.js.map +7 -0
  206. package/dist/utils/migration/migrateHistory.js +273 -0
  207. package/dist/utils/migration/migrateHistory.js.map +7 -0
  208. package/dist/utils/migration/migrateTodos.js +323 -0
  209. package/dist/utils/migration/migrateTodos.js.map +7 -0
  210. package/dist/utils/pasteCache.js +309 -0
  211. package/dist/utils/pasteCache.js.map +7 -0
  212. package/dist/utils/pluginInstaller.js +34 -24
  213. package/dist/utils/pluginInstaller.js.map +2 -2
  214. package/dist/utils/pluginLoader.js +54 -28
  215. package/dist/utils/pluginLoader.js.map +2 -2
  216. package/dist/utils/repoFetcher.js +110 -0
  217. package/dist/utils/repoFetcher.js.map +7 -0
  218. package/dist/utils/sessionIndex.js +192 -0
  219. package/dist/utils/sessionIndex.js.map +7 -0
  220. package/dist/utils/sessionTracker.js +170 -0
  221. package/dist/utils/sessionTracker.js.map +7 -0
  222. package/dist/utils/skillLoader.js +103 -5
  223. package/dist/utils/skillLoader.js.map +2 -2
  224. package/dist/utils/stats.js +417 -0
  225. package/dist/utils/stats.js.map +7 -0
  226. package/dist/utils/stringSubstitution.js +106 -0
  227. package/dist/utils/stringSubstitution.js.map +7 -0
  228. package/dist/utils/teamConfig.js +156 -14
  229. package/dist/utils/teamConfig.js.map +2 -2
  230. package/dist/utils/terminal.js +1 -1
  231. package/dist/utils/terminal.js.map +2 -2
  232. package/dist/utils/todoStorage.js +51 -19
  233. package/dist/utils/todoStorage.js.map +2 -2
  234. package/dist/utils/tooling/safeRender.js.map +2 -2
  235. package/dist/version.js +2 -2
  236. package/dist/version.js.map +1 -1
  237. package/package.json +71 -28
  238. package/scripts/{postinstall.js → postinstall.cjs} +1 -1
@@ -0,0 +1,103 @@
1
+ import { exec } from "child_process";
2
+ import { promisify } from "util";
3
+ import { getCwd } from "./state.js";
4
+ const execAsync = promisify(exec);
5
+ const DEFAULT_HOOK_TIMEOUT = 6e4;
6
+ async function executeHook(hook, context) {
7
+ const startTime = Date.now();
8
+ const timeout = (hook.timeout ?? 60) * 1e3;
9
+ try {
10
+ if (hook.type === "command" && hook.command) {
11
+ const { stdout, stderr } = await execAsync(hook.command, {
12
+ timeout: Math.min(timeout, DEFAULT_HOOK_TIMEOUT),
13
+ cwd: context.cwd,
14
+ env: {
15
+ ...process.env,
16
+ ...context.env,
17
+ AGENT_ID: context.agentId,
18
+ AGENT_TYPE: context.agentType,
19
+ SESSION_ID: context.sessionId,
20
+ HOOK_CWD: context.cwd
21
+ }
22
+ });
23
+ let parsedOutput = null;
24
+ try {
25
+ if (stdout.trim().startsWith("{")) {
26
+ parsedOutput = JSON.parse(stdout.trim());
27
+ }
28
+ } catch {
29
+ }
30
+ return {
31
+ success: true,
32
+ continue: parsedOutput?.continue !== false,
33
+ reason: parsedOutput?.stopReason,
34
+ output: stdout,
35
+ executionTime: Date.now() - startTime
36
+ };
37
+ } else if (hook.type === "prompt" && hook.prompt) {
38
+ return {
39
+ success: true,
40
+ continue: true,
41
+ output: hook.prompt,
42
+ executionTime: Date.now() - startTime
43
+ };
44
+ }
45
+ return {
46
+ success: false,
47
+ continue: true,
48
+ reason: "Invalid hook configuration: missing command or prompt",
49
+ executionTime: Date.now() - startTime
50
+ };
51
+ } catch (error) {
52
+ return {
53
+ success: false,
54
+ continue: true,
55
+ // Default to continue on error
56
+ error: error instanceof Error ? error : new Error(String(error)),
57
+ executionTime: Date.now() - startTime
58
+ };
59
+ }
60
+ }
61
+ async function executeAgentHooks(event, agentConfig, context) {
62
+ const hooks = agentConfig.hooks?.[event];
63
+ if (!hooks || hooks.length === 0) {
64
+ return { continue: true, outputs: [] };
65
+ }
66
+ const outputs = [];
67
+ let shouldContinue = true;
68
+ let stopReason;
69
+ for (const hook of hooks) {
70
+ const result = await executeHook(hook, context);
71
+ if (result.output) {
72
+ outputs.push(result.output);
73
+ }
74
+ if (!result.continue) {
75
+ shouldContinue = false;
76
+ stopReason = result.reason || "Hook requested stop";
77
+ break;
78
+ }
79
+ if (!result.success && result.error) {
80
+ console.warn(`Hook ${event} execution failed:`, result.error.message);
81
+ }
82
+ }
83
+ return {
84
+ continue: shouldContinue,
85
+ reason: stopReason,
86
+ outputs
87
+ };
88
+ }
89
+ function createHookContext(params) {
90
+ return {
91
+ sessionId: params.sessionId,
92
+ agentId: params.agentId,
93
+ agentType: params.agentType,
94
+ cwd: getCwd(),
95
+ error: params.error,
96
+ result: params.result
97
+ };
98
+ }
99
+ export {
100
+ createHookContext,
101
+ executeAgentHooks
102
+ };
103
+ //# sourceMappingURL=agentHookExecutor.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/agentHookExecutor.ts"],
4
+ "sourcesContent": ["/**\n * Agent Hook Executor\n *\n * Executes lifecycle hooks for agents as defined in Claude Code specification.\n * Supports onStart, onComplete, and onError hooks with security controls.\n */\n\nimport { exec } from 'child_process'\nimport { promisify } from 'util'\nimport type { HookDefinition } from '@minto-types/hooks'\nimport type { AgentConfig, AgentHooks } from './agentLoader'\nimport { getCwd } from './state'\n\nconst execAsync = promisify(exec)\n\n/**\n * Hook execution context\n */\nexport interface HookExecutionContext {\n sessionId: string\n agentId: string\n agentType: string\n cwd: string\n env?: Record<string, string>\n error?: Error // For onError hooks\n result?: string // For onComplete hooks\n}\n\n/**\n * Hook execution result\n */\nexport interface HookExecutionResult {\n success: boolean\n continue: boolean\n reason?: string\n output?: string\n error?: Error\n executionTime: number\n}\n\n/**\n * Default hook timeout in milliseconds\n */\nconst DEFAULT_HOOK_TIMEOUT = 60000 // 60 seconds\n\n/**\n * Execute a single hook\n */\nasync function executeHook(\n hook: HookDefinition,\n context: HookExecutionContext,\n): Promise<HookExecutionResult> {\n const startTime = Date.now()\n const timeout = (hook.timeout ?? 60) * 1000 // Convert seconds to milliseconds\n\n try {\n if (hook.type === 'command' && hook.command) {\n // Execute shell command\n const { stdout, stderr } = await execAsync(hook.command, {\n timeout: Math.min(timeout, DEFAULT_HOOK_TIMEOUT),\n cwd: context.cwd,\n env: {\n ...process.env,\n ...context.env,\n AGENT_ID: context.agentId,\n AGENT_TYPE: context.agentType,\n SESSION_ID: context.sessionId,\n HOOK_CWD: context.cwd,\n },\n })\n\n // Try to parse JSON output for hook control\n let parsedOutput: any = null\n try {\n if (stdout.trim().startsWith('{')) {\n parsedOutput = JSON.parse(stdout.trim())\n }\n } catch {\n // Not JSON, that's fine\n }\n\n return {\n success: true,\n continue: parsedOutput?.continue !== false,\n reason: parsedOutput?.stopReason,\n output: stdout,\n executionTime: Date.now() - startTime,\n }\n } else if (hook.type === 'prompt' && hook.prompt) {\n // Prompt hooks are handled by the agent system\n // For now, we just return success and let the caller handle the prompt\n return {\n success: true,\n continue: true,\n output: hook.prompt,\n executionTime: Date.now() - startTime,\n }\n }\n\n // Invalid hook configuration\n return {\n success: false,\n continue: true,\n reason: 'Invalid hook configuration: missing command or prompt',\n executionTime: Date.now() - startTime,\n }\n } catch (error) {\n return {\n success: false,\n continue: true, // Default to continue on error\n error: error instanceof Error ? error : new Error(String(error)),\n executionTime: Date.now() - startTime,\n }\n }\n}\n\n/**\n * Execute agent lifecycle hooks\n *\n * @param event - The lifecycle event (onStart, onComplete, onError)\n * @param agentConfig - The agent configuration containing hooks\n * @param context - The execution context\n * @returns Combined result of all hook executions\n */\nexport async function executeAgentHooks(\n event: keyof AgentHooks,\n agentConfig: AgentConfig,\n context: HookExecutionContext,\n): Promise<{ continue: boolean; reason?: string; outputs: string[] }> {\n const hooks = agentConfig.hooks?.[event]\n\n if (!hooks || hooks.length === 0) {\n return { continue: true, outputs: [] }\n }\n\n const outputs: string[] = []\n let shouldContinue = true\n let stopReason: string | undefined\n\n for (const hook of hooks) {\n const result = await executeHook(hook, context)\n\n if (result.output) {\n outputs.push(result.output)\n }\n\n if (!result.continue) {\n shouldContinue = false\n stopReason = result.reason || 'Hook requested stop'\n break // Stop executing further hooks\n }\n\n if (!result.success && result.error) {\n console.warn(`Hook ${event} execution failed:`, result.error.message)\n // Continue to next hook on error by default\n }\n }\n\n return {\n continue: shouldContinue,\n reason: stopReason,\n outputs,\n }\n}\n\n/**\n * Create hook execution context from agent execution state\n */\nexport function createHookContext(params: {\n sessionId: string\n agentId: string\n agentType: string\n error?: Error\n result?: string\n}): HookExecutionContext {\n return {\n sessionId: params.sessionId,\n agentId: params.agentId,\n agentType: params.agentType,\n cwd: getCwd(),\n error: params.error,\n result: params.result,\n }\n}\n"],
5
+ "mappings": "AAOA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAG1B,SAAS,cAAc;AAEvB,MAAM,YAAY,UAAU,IAAI;AA8BhC,MAAM,uBAAuB;AAK7B,eAAe,YACb,MACA,SAC8B;AAC9B,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,WAAW,KAAK,WAAW,MAAM;AAEvC,MAAI;AACF,QAAI,KAAK,SAAS,aAAa,KAAK,SAAS;AAE3C,YAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,UAAU,KAAK,SAAS;AAAA,QACvD,SAAS,KAAK,IAAI,SAAS,oBAAoB;AAAA,QAC/C,KAAK,QAAQ;AAAA,QACb,KAAK;AAAA,UACH,GAAG,QAAQ;AAAA,UACX,GAAG,QAAQ;AAAA,UACX,UAAU,QAAQ;AAAA,UAClB,YAAY,QAAQ;AAAA,UACpB,YAAY,QAAQ;AAAA,UACpB,UAAU,QAAQ;AAAA,QACpB;AAAA,MACF,CAAC;AAGD,UAAI,eAAoB;AACxB,UAAI;AACF,YAAI,OAAO,KAAK,EAAE,WAAW,GAAG,GAAG;AACjC,yBAAe,KAAK,MAAM,OAAO,KAAK,CAAC;AAAA,QACzC;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU,cAAc,aAAa;AAAA,QACrC,QAAQ,cAAc;AAAA,QACtB,QAAQ;AAAA,QACR,eAAe,KAAK,IAAI,IAAI;AAAA,MAC9B;AAAA,IACF,WAAW,KAAK,SAAS,YAAY,KAAK,QAAQ;AAGhD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,KAAK;AAAA,QACb,eAAe,KAAK,IAAI,IAAI;AAAA,MAC9B;AAAA,IACF;AAGA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,eAAe,KAAK,IAAI,IAAI;AAAA,IAC9B;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA;AAAA,MACV,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MAC/D,eAAe,KAAK,IAAI,IAAI;AAAA,IAC9B;AAAA,EACF;AACF;AAUA,eAAsB,kBACpB,OACA,aACA,SACoE;AACpE,QAAM,QAAQ,YAAY,QAAQ,KAAK;AAEvC,MAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,WAAO,EAAE,UAAU,MAAM,SAAS,CAAC,EAAE;AAAA,EACvC;AAEA,QAAM,UAAoB,CAAC;AAC3B,MAAI,iBAAiB;AACrB,MAAI;AAEJ,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,MAAM,YAAY,MAAM,OAAO;AAE9C,QAAI,OAAO,QAAQ;AACjB,cAAQ,KAAK,OAAO,MAAM;AAAA,IAC5B;AAEA,QAAI,CAAC,OAAO,UAAU;AACpB,uBAAiB;AACjB,mBAAa,OAAO,UAAU;AAC9B;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,WAAW,OAAO,OAAO;AACnC,cAAQ,KAAK,QAAQ,KAAK,sBAAsB,OAAO,MAAM,OAAO;AAAA,IAEtE;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV,QAAQ;AAAA,IACR;AAAA,EACF;AACF;AAKO,SAAS,kBAAkB,QAMT;AACvB,SAAO;AAAA,IACL,WAAW,OAAO;AAAA,IAClB,SAAS,OAAO;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB,KAAK,OAAO;AAAA,IACZ,OAAO,OAAO;AAAA,IACd,QAAQ,OAAO;AAAA,EACjB;AACF;",
6
+ "names": []
7
+ }
@@ -12,25 +12,117 @@ import { getCwd } from "./state.js";
12
12
  import { memoize } from "lodash-es";
13
13
  import { loadAllPlugins } from "./pluginLoader.js";
14
14
  const warnedAgents = /* @__PURE__ */ new Set();
15
- const BUILTIN_GENERAL_PURPOSE = {
16
- agentType: "general-purpose",
17
- whenToUse: "General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks",
18
- tools: "*",
19
- systemPrompt: `You are a general-purpose agent. Given the user's task, use the tools available to complete it efficiently and thoroughly.
15
+ const BUILTIN_AGENTS = [
16
+ // general-purpose: Default agent for multi-step tasks
17
+ {
18
+ agentType: "general-purpose",
19
+ whenToUse: "General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent.",
20
+ tools: "*",
21
+ systemPrompt: `You are a general-purpose agent. Given the user's task, use the tools available to complete it efficiently and thoroughly.
20
22
 
21
23
  When to use your capabilities:
22
24
  - Searching for code, configurations, and patterns across large codebases
23
- - Analyzing multiple files to understand system architecture
25
+ - Analyzing multiple files to understand system architecture
24
26
  - Investigating complex questions that require exploring many files
25
27
  - Performing multi-step research tasks
26
28
 
27
29
  Guidelines:
28
- - For file searches: Use Grep or Glob when you need to search broadly. Use FileRead when you know the specific file path.
30
+ - For file searches: Use Grep or Glob when you need to search broadly. Use Read when you know the specific file path.
29
31
  - For analysis: Start broad and narrow down. Use multiple search strategies if the first doesn't yield results.
30
32
  - Be thorough: Check multiple locations, consider different naming conventions, look for related files.
31
33
  - Complete tasks directly using your capabilities.`,
32
- location: "built-in"
33
- };
34
+ location: "built-in"
35
+ },
36
+ // Explore: Fast read-only codebase exploration (Claude Code spec)
37
+ {
38
+ agentType: "Explore",
39
+ whenToUse: 'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns, search code for keywords, or answer questions about the codebase. Specify thoroughness: "quick" for basic searches, "medium" for moderate exploration, "very thorough" for comprehensive analysis.',
40
+ tools: ["Read", "Glob", "Grep", "LS", "WebSearch", "WebFetch"],
41
+ disallowedTools: ["Edit", "Write", "Bash", "NotebookEdit"],
42
+ model_name: "quick",
43
+ // Maps to haiku equivalent
44
+ permissionMode: "plan",
45
+ // Read-only mode
46
+ systemPrompt: `You are an exploration agent optimized for fast codebase searches and understanding.
47
+
48
+ Your role:
49
+ - Quickly find files, functions, classes, and patterns
50
+ - Understand code structure and architecture
51
+ - Answer questions about how code works
52
+ - Identify relevant files for a given task
53
+
54
+ Guidelines:
55
+ - Use Glob for finding files by pattern (e.g., "**/*.tsx", "src/**/*.ts")
56
+ - Use Grep for searching code content (e.g., function names, imports, patterns)
57
+ - Use Read to examine specific files you've identified
58
+ - Start broad, then narrow down based on results
59
+ - Report findings with specific file paths and line numbers
60
+ - Be thorough but efficient - check multiple locations and naming conventions
61
+
62
+ You are READ-ONLY. You cannot modify any files.`,
63
+ location: "built-in"
64
+ },
65
+ // Plan: Research and planning agent (Claude Code spec)
66
+ {
67
+ agentType: "Plan",
68
+ whenToUse: "Software architect agent for designing implementation plans. Use this when you need to plan the implementation strategy for a task. Returns step-by-step plans, identifies critical files, and considers architectural trade-offs.",
69
+ tools: ["Read", "Glob", "Grep", "LS", "WebSearch", "WebFetch", "Think"],
70
+ disallowedTools: ["Edit", "Write", "Bash", "NotebookEdit"],
71
+ model_name: "inherit",
72
+ // Inherit caller's model
73
+ permissionMode: "plan",
74
+ // Read-only mode
75
+ systemPrompt: `You are a planning agent specialized in analyzing codebases and creating implementation plans.
76
+
77
+ Your role:
78
+ - Understand requirements and constraints
79
+ - Analyze existing code patterns and architecture
80
+ - Create detailed, step-by-step implementation plans
81
+ - Identify potential issues and trade-offs
82
+ - Recommend best approaches based on codebase conventions
83
+
84
+ Guidelines:
85
+ - Read relevant files to understand current patterns
86
+ - Identify all files that will need modification
87
+ - Consider edge cases and error handling
88
+ - Note any dependencies or prerequisites
89
+ - Provide specific, actionable steps
90
+
91
+ Output format:
92
+ 1. Summary of the task
93
+ 2. Files to modify/create (with paths)
94
+ 3. Step-by-step implementation plan
95
+ 4. Potential challenges or considerations
96
+ 5. Testing approach
97
+
98
+ You are READ-ONLY. You cannot modify any files. Focus on planning, not execution.`,
99
+ location: "built-in"
100
+ },
101
+ // Bash: Shell command execution agent (Claude Code spec)
102
+ {
103
+ agentType: "Bash",
104
+ whenToUse: "Command execution specialist for running bash commands. Use this for git operations, command execution, and other terminal tasks.",
105
+ tools: ["Bash", "Read", "LS"],
106
+ systemPrompt: `You are a bash execution agent specialized in running shell commands.
107
+
108
+ Your role:
109
+ - Execute shell commands safely and effectively
110
+ - Handle build, test, and deployment tasks
111
+ - Manage git operations
112
+ - Run scripts and automation
113
+
114
+ Guidelines:
115
+ - Check command syntax before execution
116
+ - Handle errors gracefully with clear messages
117
+ - Report command output and exit codes
118
+ - Be cautious with destructive commands (rm, git reset, etc.)
119
+ - Use appropriate flags for verbose output when debugging
120
+ - Chain commands with && for dependent operations
121
+
122
+ Always explain what a command will do before running it if it modifies the system.`,
123
+ location: "built-in"
124
+ }
125
+ ];
34
126
  function parseTools(tools) {
35
127
  if (!tools) return "*";
36
128
  if (tools === "*") return "*";
@@ -41,10 +133,76 @@ function parseTools(tools) {
41
133
  return filteredTools.length > 0 ? filteredTools : "*";
42
134
  }
43
135
  if (typeof tools === "string") {
136
+ if (tools.includes(",")) {
137
+ return tools.split(",").map((t) => t.trim()).filter(Boolean);
138
+ }
44
139
  return [tools];
45
140
  }
46
141
  return "*";
47
142
  }
143
+ function parseDisallowedTools(disallowedTools) {
144
+ if (!disallowedTools) return void 0;
145
+ if (Array.isArray(disallowedTools)) {
146
+ const filtered = disallowedTools.filter(
147
+ (t) => typeof t === "string"
148
+ );
149
+ return filtered.length > 0 ? filtered : void 0;
150
+ }
151
+ if (typeof disallowedTools === "string") {
152
+ if (disallowedTools.includes(",")) {
153
+ return disallowedTools.split(",").map((t) => t.trim()).filter(Boolean);
154
+ }
155
+ return [disallowedTools];
156
+ }
157
+ return void 0;
158
+ }
159
+ function parseSkills(skills) {
160
+ if (!skills) return void 0;
161
+ if (Array.isArray(skills)) {
162
+ const filtered = skills.filter((s) => typeof s === "string");
163
+ return filtered.length > 0 ? filtered : void 0;
164
+ }
165
+ if (typeof skills === "string") {
166
+ if (skills.includes(",")) {
167
+ return skills.split(",").map((s) => s.trim()).filter(Boolean);
168
+ }
169
+ return [skills];
170
+ }
171
+ return void 0;
172
+ }
173
+ function parseMemory(memory) {
174
+ if (!memory) return void 0;
175
+ if (typeof memory === "string") {
176
+ if (["user", "project", "local"].includes(memory)) {
177
+ return { scope: memory };
178
+ }
179
+ return void 0;
180
+ }
181
+ if (typeof memory === "object") {
182
+ const scope = memory.scope;
183
+ if (["user", "project", "local"].includes(scope)) {
184
+ return {
185
+ scope,
186
+ ...memory.key && { key: String(memory.key) }
187
+ };
188
+ }
189
+ }
190
+ return void 0;
191
+ }
192
+ function parsePermissionMode(mode) {
193
+ if (!mode) return void 0;
194
+ const validModes = [
195
+ "default",
196
+ "acceptEdits",
197
+ "dontAsk",
198
+ "plan",
199
+ "bypassPermissions"
200
+ ];
201
+ if (typeof mode === "string" && validModes.includes(mode)) {
202
+ return mode;
203
+ }
204
+ return void 0;
205
+ }
48
206
  async function scanAgentDirectory(dirPath, location) {
49
207
  if (!existsSync(dirPath)) {
50
208
  return [];
@@ -59,12 +217,24 @@ async function scanAgentDirectory(dirPath, location) {
59
217
  if (!stat.isFile()) continue;
60
218
  try {
61
219
  const content = readFileSync(filePath, "utf-8");
220
+ if (!content.trim()) continue;
62
221
  const { data: frontmatter, content: body } = matter(content);
63
222
  if (!frontmatter.name || !frontmatter.description) {
64
- console.warn(
65
- `Skipping ${filePath}: missing required fields (name, description)`
66
- );
67
- continue;
223
+ const headingMatch = body.match(/^#\s+(.+)/m);
224
+ const firstParagraph = body.split(/\n\n/).find((p) => p.trim() && !p.trim().startsWith("#"));
225
+ if (headingMatch) {
226
+ if (!frontmatter.name) {
227
+ frontmatter.name = headingMatch[1].trim();
228
+ }
229
+ if (!frontmatter.description) {
230
+ frontmatter.description = firstParagraph?.trim() || frontmatter.name;
231
+ }
232
+ } else {
233
+ console.warn(
234
+ `Skipping ${filePath}: missing required fields (name, description)`
235
+ );
236
+ continue;
237
+ }
68
238
  }
69
239
  if (frontmatter.model && !frontmatter.model_name && !warnedAgents.has(frontmatter.name) && process.env.MINTO_DEBUG_AGENTS) {
70
240
  console.warn(
@@ -72,15 +242,30 @@ async function scanAgentDirectory(dirPath, location) {
72
242
  );
73
243
  warnedAgents.add(frontmatter.name);
74
244
  }
245
+ const disallowedTools = parseDisallowedTools(
246
+ frontmatter.disallowedTools
247
+ );
248
+ const skills = parseSkills(frontmatter.skills);
249
+ const memory = parseMemory(frontmatter.memory);
250
+ const permissionMode = parsePermissionMode(frontmatter.permissionMode);
75
251
  const agent = {
76
252
  agentType: frontmatter.name,
77
253
  whenToUse: frontmatter.description.replace(/\\n/g, "\n"),
78
254
  tools: parseTools(frontmatter.tools),
79
255
  systemPrompt: body.trim(),
80
256
  location,
257
+ sourcePath: filePath,
258
+ // Optional fields - only include if defined
81
259
  ...frontmatter.color && { color: frontmatter.color },
82
- // Only use model_name field, ignore deprecated 'model' field
83
- ...frontmatter.model_name && { model_name: frontmatter.model_name }
260
+ ...frontmatter.model_name && { model_name: frontmatter.model_name },
261
+ ...disallowedTools && { disallowedTools },
262
+ ...permissionMode && { permissionMode },
263
+ ...skills && { skills },
264
+ ...memory && { memory },
265
+ ...frontmatter.maxThinkingTokens && {
266
+ maxThinkingTokens: Number(frontmatter.maxThinkingTokens)
267
+ },
268
+ ...frontmatter.hooks && { hooks: frontmatter.hooks }
84
269
  };
85
270
  agents.push(agent);
86
271
  } catch (error) {
@@ -101,12 +286,24 @@ async function loadPluginAgents() {
101
286
  for (const pluginAgent of plugin.agents) {
102
287
  try {
103
288
  const content = readFileSync(pluginAgent.filePath, "utf-8");
289
+ if (!content.trim()) continue;
104
290
  const { data: frontmatter, content: body } = matter(content);
105
291
  if (!frontmatter.name || !frontmatter.description) {
106
- console.warn(
107
- `Skipping plugin agent ${pluginAgent.filePath}: missing required fields (name, description)`
108
- );
109
- continue;
292
+ const headingMatch = body.match(/^#\s+(.+)/m);
293
+ const firstParagraph = body.split(/\n\n/).find((p) => p.trim() && !p.trim().startsWith("#"));
294
+ if (headingMatch) {
295
+ if (!frontmatter.name) {
296
+ frontmatter.name = headingMatch[1].trim();
297
+ }
298
+ if (!frontmatter.description) {
299
+ frontmatter.description = firstParagraph?.trim() || frontmatter.name;
300
+ }
301
+ } else {
302
+ console.warn(
303
+ `Skipping plugin agent ${pluginAgent.filePath}: missing required fields (name, description)`
304
+ );
305
+ continue;
306
+ }
110
307
  }
111
308
  if (frontmatter.model && !frontmatter.model_name && !warnedAgents.has(frontmatter.name) && process.env.MINTO_DEBUG_AGENTS) {
112
309
  console.warn(
@@ -114,6 +311,12 @@ async function loadPluginAgents() {
114
311
  );
115
312
  warnedAgents.add(frontmatter.name);
116
313
  }
314
+ const disallowedTools = parseDisallowedTools(
315
+ frontmatter.disallowedTools
316
+ );
317
+ const skills = parseSkills(frontmatter.skills);
318
+ const memory = parseMemory(frontmatter.memory);
319
+ const permissionMode = parsePermissionMode(frontmatter.permissionMode);
117
320
  const agent = {
118
321
  agentType: frontmatter.name,
119
322
  whenToUse: frontmatter.description.replace(/\\n/g, "\n"),
@@ -121,10 +324,21 @@ async function loadPluginAgents() {
121
324
  systemPrompt: body.trim(),
122
325
  location: "plugin",
123
326
  pluginName: plugin.manifest.name,
327
+ sourcePath: pluginAgent.filePath,
328
+ // Optional fields
124
329
  ...frontmatter.color && { color: frontmatter.color },
125
- // Only use model_name field, ignore deprecated 'model' field
126
330
  ...frontmatter.model_name && {
127
331
  model_name: frontmatter.model_name
332
+ },
333
+ ...disallowedTools && { disallowedTools },
334
+ ...permissionMode && { permissionMode },
335
+ ...skills && { skills },
336
+ ...memory && { memory },
337
+ ...frontmatter.maxThinkingTokens && {
338
+ maxThinkingTokens: Number(frontmatter.maxThinkingTokens)
339
+ },
340
+ ...frontmatter.hooks && {
341
+ hooks: frontmatter.hooks
128
342
  }
129
343
  };
130
344
  agents.push(agent);
@@ -143,40 +357,59 @@ async function loadPluginAgents() {
143
357
  }
144
358
  async function loadAllAgents() {
145
359
  try {
146
- const userMintoDir = join(homedir(), ".minto", "agents");
147
- const projectMintoDir = join(getCwd(), ".minto", "agents");
148
- const [pluginAgents, userMintoAgents, projectMintoAgents] = await Promise.all([
360
+ const home = homedir();
361
+ const cwd = getCwd();
362
+ const userClaudeDir = join(home, ".claude", "agents");
363
+ const userMintoDir = join(home, ".minto", "agents");
364
+ const projectClaudeDir = join(cwd, ".claude", "agents");
365
+ const projectMintoDir = join(cwd, ".minto", "agents");
366
+ const [
367
+ pluginAgents,
368
+ userClaudeAgents,
369
+ userMintoAgents,
370
+ projectClaudeAgents,
371
+ projectMintoAgents
372
+ ] = await Promise.all([
149
373
  loadPluginAgents(),
374
+ scanAgentDirectory(userClaudeDir, "user"),
150
375
  scanAgentDirectory(userMintoDir, "user"),
376
+ scanAgentDirectory(projectClaudeDir, "project"),
151
377
  scanAgentDirectory(projectMintoDir, "project")
152
378
  ]);
153
- const builtinAgents = [BUILTIN_GENERAL_PURPOSE];
154
379
  const agentMap = /* @__PURE__ */ new Map();
155
- for (const agent of builtinAgents) {
380
+ for (const agent of BUILTIN_AGENTS) {
156
381
  agentMap.set(agent.agentType, agent);
157
382
  }
158
383
  for (const agent of pluginAgents) {
159
384
  agentMap.set(agent.agentType, agent);
160
385
  }
386
+ for (const agent of userClaudeAgents) {
387
+ agentMap.set(agent.agentType, agent);
388
+ }
161
389
  for (const agent of userMintoAgents) {
162
390
  agentMap.set(agent.agentType, agent);
163
391
  }
392
+ for (const agent of projectClaudeAgents) {
393
+ agentMap.set(agent.agentType, agent);
394
+ }
164
395
  for (const agent of projectMintoAgents) {
165
396
  agentMap.set(agent.agentType, agent);
166
397
  }
167
398
  const activeAgents = Array.from(agentMap.values());
168
399
  const allAgents = [
169
- ...builtinAgents,
400
+ ...BUILTIN_AGENTS,
170
401
  ...pluginAgents,
402
+ ...userClaudeAgents,
171
403
  ...userMintoAgents,
404
+ ...projectClaudeAgents,
172
405
  ...projectMintoAgents
173
406
  ];
174
407
  return { activeAgents, allAgents };
175
408
  } catch (error) {
176
409
  console.error("Failed to load agents, falling back to built-in:", error);
177
410
  return {
178
- activeAgents: [BUILTIN_GENERAL_PURPOSE],
179
- allAgents: [BUILTIN_GENERAL_PURPOSE]
411
+ activeAgents: [...BUILTIN_AGENTS],
412
+ allAgents: [...BUILTIN_AGENTS]
180
413
  };
181
414
  }
182
415
  }
@@ -207,8 +440,14 @@ const getAvailableAgentTypes = memoize(async () => {
207
440
  let watchers = [];
208
441
  async function startAgentWatcher(onChange) {
209
442
  await stopAgentWatcher();
210
- const userMintoDir = join(homedir(), ".minto", "agents");
211
- const projectMintoDir = join(getCwd(), ".minto", "agents");
443
+ const home = homedir();
444
+ const cwd = getCwd();
445
+ const directories = [
446
+ { path: join(home, ".claude", "agents"), label: "user/.claude" },
447
+ { path: join(home, ".minto", "agents"), label: "user/.minto" },
448
+ { path: join(cwd, ".claude", "agents"), label: "project/.claude" },
449
+ { path: join(cwd, ".minto", "agents"), label: "project/.minto" }
450
+ ];
212
451
  const watchDirectory = (dirPath, label) => {
213
452
  if (existsSync(dirPath)) {
214
453
  const watcher = watch(
@@ -228,8 +467,9 @@ async function startAgentWatcher(onChange) {
228
467
  watchers.push(watcher);
229
468
  }
230
469
  };
231
- watchDirectory(userMintoDir, "user/.minto");
232
- watchDirectory(projectMintoDir, "project/.minto");
470
+ for (const { path, label } of directories) {
471
+ watchDirectory(path, label);
472
+ }
233
473
  }
234
474
  async function stopAgentWatcher() {
235
475
  try {