@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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/todoStorage.ts"],
4
- "sourcesContent": ["import { setSessionState, getSessionState } from './sessionState'\nimport { readAgentData, writeAgentData, resolveAgentId } from './agentStorage'\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n unlinkSync,\n} from 'fs'\nimport { join } from 'path'\nimport envPaths from 'env-paths'\nimport { PRODUCT_COMMAND } from '@constants/product'\n\nexport interface TodoItem {\n id: string\n content: string\n activeForm?: string // Optional - will be auto-generated if not provided\n status: 'pending' | 'in_progress' | 'completed'\n priority: 'high' | 'medium' | 'low'\n createdAt?: number\n updatedAt?: number\n tags?: string[]\n estimatedHours?: number\n previousStatus?: 'pending' | 'in_progress' | 'completed'\n}\n\nexport interface TodoQuery {\n status?: TodoItem['status'][]\n priority?: TodoItem['priority'][]\n contentMatch?: string\n tags?: string[]\n dateRange?: { from?: Date; to?: Date }\n}\n\nexport interface TodoStorageConfig {\n maxTodos: number\n autoArchiveCompleted: boolean\n sortBy: 'createdAt' | 'updatedAt' | 'priority' | 'status'\n sortOrder: 'asc' | 'desc'\n}\n\nconst TODO_STORAGE_KEY = 'todos'\nconst TODO_CONFIG_KEY = 'todoConfig'\n\n// Default configuration\nconst DEFAULT_CONFIG: TodoStorageConfig = {\n maxTodos: 100,\n autoArchiveCompleted: false,\n sortBy: 'status', // Using smart sorting now\n sortOrder: 'desc',\n}\n\n// In-memory cache for performance\nlet todoCache: TodoItem[] | null = null\nlet cacheTimestamp = 0\nconst CACHE_TTL = 5000 // 5 seconds cache\n\n// Current session ID - set by initTodoSession()\nlet currentSessionId: string | null = null\n\nconst paths = envPaths(PRODUCT_COMMAND)\n\n/**\n * Get project directory hash for organizing todos by project\n */\nfunction getProjectDir(cwd: string): string {\n return cwd.replace(/[^a-zA-Z0-9]/g, '-')\n}\n\n/**\n * Get session-scoped todo file path\n * Todos are now stored per-session to avoid conflicts between multiple conversations\n */\nfunction getSessionTodoPath(sessionId: string): string {\n const projectDir = getProjectDir(process.cwd())\n const todosDir = join(paths.cache, projectDir, 'todos')\n return join(todosDir, `${sessionId}.json`)\n}\n\n/**\n * Initialize todo session with a specific session ID\n * Must be called when starting a new REPL session\n */\nexport function initTodoSession(sessionId: string): void {\n currentSessionId = sessionId\n // Invalidate cache when session changes\n invalidateCache()\n}\n\n/**\n * Get current session ID\n */\nexport function getCurrentTodoSessionId(): string | null {\n return currentSessionId\n}\n\n/**\n * Read todos from session-scoped file\n */\nfunction readSessionTodos(sessionId: string): TodoItem[] {\n const filePath = getSessionTodoPath(sessionId)\n if (!existsSync(filePath)) {\n return []\n }\n try {\n const content = readFileSync(filePath, 'utf-8')\n return JSON.parse(content) as TodoItem[]\n } catch {\n return []\n }\n}\n\n/**\n * Write todos to session-scoped file\n */\nfunction writeSessionTodos(sessionId: string, todos: TodoItem[]): void {\n const filePath = getSessionTodoPath(sessionId)\n const todosDir = join(paths.cache, getProjectDir(process.cwd()), 'todos')\n\n try {\n // Ensure directory exists\n if (!existsSync(todosDir)) {\n mkdirSync(todosDir, { recursive: true })\n }\n\n if (todos.length === 0) {\n // Remove file if no todos (cleanup)\n if (existsSync(filePath)) {\n unlinkSync(filePath)\n }\n } else {\n writeFileSync(filePath, JSON.stringify(todos, null, 2), 'utf-8')\n }\n } catch (error) {\n // Silently fail if we can't write (e.g., no permissions)\n // console.error('Failed to persist todos:', error)\n }\n}\n\n/**\n * Delete session todo file (used when clearing conversation)\n */\nexport function deleteSessionTodos(sessionId?: string): void {\n const targetSessionId = sessionId || currentSessionId\n if (!targetSessionId) return\n\n const filePath = getSessionTodoPath(targetSessionId)\n try {\n if (existsSync(filePath)) {\n unlinkSync(filePath)\n }\n } catch {\n // Silently fail\n }\n\n // Also clear in-memory state\n if (!sessionId || sessionId === currentSessionId) {\n invalidateCache()\n setSessionState({\n ...getSessionState(),\n [TODO_STORAGE_KEY]: [],\n } as any)\n }\n}\n\n// Performance metrics\nexport interface TodoMetrics {\n totalOperations: number\n cacheHits: number\n cacheMisses: number\n lastOperation: number\n}\n\nfunction invalidateCache(): void {\n todoCache = null\n cacheTimestamp = 0\n}\n\nfunction updateMetrics(operation: string, cacheHit: boolean = false): void {\n const sessionState = getSessionState() as any\n const metrics = sessionState.todoMetrics || {\n totalOperations: 0,\n cacheHits: 0,\n cacheMisses: 0,\n lastOperation: 0,\n }\n\n metrics.totalOperations++\n metrics.lastOperation = Date.now()\n\n if (cacheHit) {\n metrics.cacheHits++\n } else {\n metrics.cacheMisses++\n }\n\n setSessionState({\n ...sessionState,\n todoMetrics: metrics,\n })\n}\n\nexport function getTodoMetrics(): TodoMetrics {\n const sessionState = getSessionState() as any\n return (\n sessionState.todoMetrics || {\n totalOperations: 0,\n cacheHits: 0,\n cacheMisses: 0,\n lastOperation: 0,\n }\n )\n}\n\nexport function getTodos(agentId?: string): TodoItem[] {\n const resolvedAgentId = resolveAgentId(agentId)\n const now = Date.now()\n\n // For agent-scoped storage, use file-based storage instead of session state\n if (agentId) {\n updateMetrics('getTodos', false)\n const agentTodos = readAgentData<TodoItem[]>(resolvedAgentId) || []\n return agentTodos\n }\n\n // Check cache first for performance\n if (todoCache && now - cacheTimestamp < CACHE_TTL) {\n updateMetrics('getTodos', true)\n return todoCache\n }\n\n updateMetrics('getTodos', false)\n\n // Try to read from session-scoped file first (persisted todos)\n if (currentSessionId) {\n const sessionTodos = readSessionTodos(currentSessionId)\n if (sessionTodos.length > 0) {\n // Update cache\n todoCache = [...sessionTodos]\n cacheTimestamp = now\n // Also sync to session state\n setSessionState({\n ...getSessionState(),\n [TODO_STORAGE_KEY]: sessionTodos,\n } as any)\n return sessionTodos\n }\n }\n\n // Fall back to session state (in-memory)\n const sessionState = getSessionState()\n const todos = (sessionState as any)[TODO_STORAGE_KEY] || []\n\n // Update cache\n todoCache = [...todos]\n cacheTimestamp = now\n\n return todos\n}\n\nexport function setTodos(todos: TodoItem[], agentId?: string): void {\n const resolvedAgentId = resolveAgentId(agentId)\n const config = getTodoConfig()\n const existingTodos = getTodos(agentId)\n\n // For agent-scoped storage, use file-based storage\n if (agentId) {\n // Validate todo limit\n if (todos.length > config.maxTodos) {\n throw new Error(\n `Todo limit exceeded. Maximum ${config.maxTodos} todos allowed.`,\n )\n }\n\n // Auto-archive completed todos if enabled\n let processedTodos = todos\n if (config.autoArchiveCompleted) {\n processedTodos = todos.filter(todo => todo.status !== 'completed')\n }\n\n const updatedTodos = processedTodos.map(todo => {\n // Find existing todo to track status changes\n const existingTodo = existingTodos.find(\n existing => existing.id === todo.id,\n )\n\n return {\n ...todo,\n updatedAt: Date.now(),\n createdAt: todo.createdAt || Date.now(),\n previousStatus:\n existingTodo?.status !== todo.status\n ? existingTodo?.status\n : todo.previousStatus,\n }\n })\n\n // Smart sorting for agent todos\n updatedTodos.sort((a, b) => {\n // 1. Status priority: in_progress > pending > completed\n const statusOrder = { in_progress: 3, pending: 2, completed: 1 }\n const statusDiff = statusOrder[b.status] - statusOrder[a.status]\n if (statusDiff !== 0) return statusDiff\n\n // 2. For same status, sort by priority: high > medium > low\n const priorityOrder = { high: 3, medium: 2, low: 1 }\n const priorityDiff = priorityOrder[b.priority] - priorityOrder[a.priority]\n if (priorityDiff !== 0) return priorityDiff\n\n // 3. For same status and priority, sort by updatedAt (newest first)\n const aTime = a.updatedAt || 0\n const bTime = b.updatedAt || 0\n return bTime - aTime\n })\n\n // Write to agent-specific storage\n writeAgentData(resolvedAgentId, updatedTodos)\n updateMetrics('setTodos')\n return\n }\n\n // Original session-based logic for backward compatibility\n // Validate todo limit\n if (todos.length > config.maxTodos) {\n throw new Error(\n `Todo limit exceeded. Maximum ${config.maxTodos} todos allowed.`,\n )\n }\n\n // Auto-archive completed todos if enabled\n let processedTodos = todos\n if (config.autoArchiveCompleted) {\n processedTodos = todos.filter(todo => todo.status !== 'completed')\n }\n\n const updatedTodos = processedTodos.map(todo => {\n // Find existing todo to track status changes\n const existingTodo = existingTodos.find(existing => existing.id === todo.id)\n\n return {\n ...todo,\n updatedAt: Date.now(),\n createdAt: todo.createdAt || Date.now(),\n previousStatus:\n existingTodo?.status !== todo.status\n ? existingTodo?.status\n : todo.previousStatus,\n }\n })\n\n // Smart sorting: status -> priority -> updatedAt\n updatedTodos.sort((a, b) => {\n // 1. Status priority: in_progress > pending > completed\n const statusOrder = { in_progress: 3, pending: 2, completed: 1 }\n const statusDiff = statusOrder[b.status] - statusOrder[a.status]\n if (statusDiff !== 0) return statusDiff\n\n // 2. For same status, sort by priority: high > medium > low\n const priorityOrder = { high: 3, medium: 2, low: 1 }\n const priorityDiff = priorityOrder[b.priority] - priorityOrder[a.priority]\n if (priorityDiff !== 0) return priorityDiff\n\n // 3. For same status and priority, sort by updatedAt (newest first)\n const aTime = a.updatedAt || 0\n const bTime = b.updatedAt || 0\n return bTime - aTime\n })\n\n setSessionState({\n ...getSessionState(),\n [TODO_STORAGE_KEY]: updatedTodos,\n } as any)\n\n // Persist to session-scoped file for persistence within this conversation\n if (currentSessionId) {\n writeSessionTodos(currentSessionId, updatedTodos)\n }\n\n // Invalidate cache\n invalidateCache()\n updateMetrics('setTodos')\n}\n\nexport function getTodoConfig(): TodoStorageConfig {\n const sessionState = getSessionState() as any\n return { ...DEFAULT_CONFIG, ...(sessionState[TODO_CONFIG_KEY] || {}) }\n}\n\nexport function setTodoConfig(config: Partial<TodoStorageConfig>): void {\n const currentConfig = getTodoConfig()\n const newConfig = { ...currentConfig, ...config }\n\n setSessionState({\n ...getSessionState(),\n [TODO_CONFIG_KEY]: newConfig,\n } as any)\n\n // Re-sort existing todos if sort order changed\n if (config.sortBy || config.sortOrder) {\n const todos = getTodos()\n setTodos(todos) // This will re-sort according to new config\n }\n}\n\nexport function addTodo(\n todo: Omit<TodoItem, 'createdAt' | 'updatedAt'>,\n): TodoItem[] {\n const todos = getTodos()\n\n // Check for duplicate IDs\n if (todos.some(existing => existing.id === todo.id)) {\n throw new Error(`Todo with ID '${todo.id}' already exists`)\n }\n\n const newTodo: TodoItem = {\n ...todo,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n }\n\n const updatedTodos = [...todos, newTodo]\n setTodos(updatedTodos)\n updateMetrics('addTodo')\n return updatedTodos\n}\n\nexport function updateTodo(id: string, updates: Partial<TodoItem>): TodoItem[] {\n const todos = getTodos()\n const existingTodo = todos.find(todo => todo.id === id)\n\n if (!existingTodo) {\n throw new Error(`Todo with ID '${id}' not found`)\n }\n\n const updatedTodos = todos.map(todo =>\n todo.id === id ? { ...todo, ...updates, updatedAt: Date.now() } : todo,\n )\n\n setTodos(updatedTodos)\n updateMetrics('updateTodo')\n return updatedTodos\n}\n\nexport function deleteTodo(id: string): TodoItem[] {\n const todos = getTodos()\n const todoExists = todos.some(todo => todo.id === id)\n\n if (!todoExists) {\n throw new Error(`Todo with ID '${id}' not found`)\n }\n\n const updatedTodos = todos.filter(todo => todo.id !== id)\n setTodos(updatedTodos)\n updateMetrics('deleteTodo')\n return updatedTodos\n}\n\nexport function clearTodos(): void {\n setTodos([])\n updateMetrics('clearTodos')\n}\n\nexport function getTodoById(id: string): TodoItem | undefined {\n const todos = getTodos()\n updateMetrics('getTodoById')\n return todos.find(todo => todo.id === id)\n}\n\nexport function getTodosByStatus(status: TodoItem['status']): TodoItem[] {\n const todos = getTodos()\n updateMetrics('getTodosByStatus')\n return todos.filter(todo => todo.status === status)\n}\n\nexport function getTodosByPriority(priority: TodoItem['priority']): TodoItem[] {\n const todos = getTodos()\n updateMetrics('getTodosByPriority')\n return todos.filter(todo => todo.priority === priority)\n}\n\n// Advanced query function\nexport function queryTodos(query: TodoQuery): TodoItem[] {\n const todos = getTodos()\n updateMetrics('queryTodos')\n\n return todos.filter(todo => {\n // Status filter\n if (query.status && !query.status.includes(todo.status)) {\n return false\n }\n\n // Priority filter\n if (query.priority && !query.priority.includes(todo.priority)) {\n return false\n }\n\n // Content search\n if (\n query.contentMatch &&\n !todo.content.toLowerCase().includes(query.contentMatch.toLowerCase())\n ) {\n return false\n }\n\n // Tags filter\n if (query.tags && todo.tags) {\n const hasMatchingTag = query.tags.some(tag => todo.tags!.includes(tag))\n if (!hasMatchingTag) return false\n }\n\n // Date range filter\n if (query.dateRange) {\n const todoDate = new Date(todo.createdAt || 0)\n if (query.dateRange.from && todoDate < query.dateRange.from) return false\n if (query.dateRange.to && todoDate > query.dateRange.to) return false\n }\n\n return true\n })\n}\n\n// Utility functions\nexport function getTodoStatistics() {\n const todos = getTodos()\n const metrics = getTodoMetrics()\n\n return {\n total: todos.length,\n byStatus: {\n pending: todos.filter(t => t.status === 'pending').length,\n in_progress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n },\n byPriority: {\n high: todos.filter(t => t.priority === 'high').length,\n medium: todos.filter(t => t.priority === 'medium').length,\n low: todos.filter(t => t.priority === 'low').length,\n },\n metrics,\n cacheEfficiency:\n metrics.totalOperations > 0\n ? Math.round((metrics.cacheHits / metrics.totalOperations) * 100)\n : 0,\n }\n}\n\nexport function optimizeTodoStorage(): void {\n // Force cache refresh\n invalidateCache()\n\n // Compact storage by removing any invalid entries\n const todos = getTodos()\n const validTodos = todos.filter(\n todo =>\n todo.id &&\n todo.content &&\n ['pending', 'in_progress', 'completed'].includes(todo.status) &&\n ['high', 'medium', 'low'].includes(todo.priority),\n )\n\n if (validTodos.length !== todos.length) {\n setTodos(validTodos)\n }\n\n updateMetrics('optimizeTodoStorage')\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { setSessionState, getSessionState } from './sessionState'\nimport { readAgentData, writeAgentData, resolveAgentId } from './agentStorage'\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n unlinkSync,\n} from 'fs'\nimport { join } from 'path'\nimport { CONFIG_PATHS } from './configPaths'\nimport { getProjectHash } from './sessionIndex'\n\nexport interface TodoItem {\n id: string\n content: string\n activeForm?: string // Optional - will be auto-generated if not provided\n status: 'pending' | 'in_progress' | 'completed'\n priority: 'high' | 'medium' | 'low'\n createdAt?: number\n updatedAt?: number\n tags?: string[]\n estimatedHours?: number\n previousStatus?: 'pending' | 'in_progress' | 'completed'\n}\n\nexport interface TodoQuery {\n status?: TodoItem['status'][]\n priority?: TodoItem['priority'][]\n contentMatch?: string\n tags?: string[]\n dateRange?: { from?: Date; to?: Date }\n}\n\nexport interface TodoStorageConfig {\n maxTodos: number\n autoArchiveCompleted: boolean\n sortBy: 'createdAt' | 'updatedAt' | 'priority' | 'status'\n sortOrder: 'asc' | 'desc'\n}\n\nconst TODO_STORAGE_KEY = 'todos'\nconst TODO_CONFIG_KEY = 'todoConfig'\n\n// Default configuration\nconst DEFAULT_CONFIG: TodoStorageConfig = {\n maxTodos: 100,\n autoArchiveCompleted: false,\n sortBy: 'status', // Using smart sorting now\n sortOrder: 'desc',\n}\n\n// In-memory cache for performance\nlet todoCache: TodoItem[] | null = null\nlet cacheTimestamp = 0\nconst CACHE_TTL = 5000 // 5 seconds cache\n\n// Current session ID - set by initTodoSession()\nlet currentSessionId: string | null = null\n\n// Current project path - set by initTodoSession()\nlet currentProjectPath: string | null = null\n\n/**\n * Legacy todo file pattern for backward compatibility\n * Format: ~/.minto/default-session-agent-{uuid}.json\n */\nfunction getLegacyTodoPath(sessionId: string): string {\n return join(CONFIG_PATHS.base, `default-session-agent-${sessionId}.json`)\n}\n\n/**\n * Get session-scoped todo file path using the new directory structure\n *\n * New format: ~/.minto/sessions/{project-hash}/{session-id}/todos.json\n *\n * @param sessionId - Session identifier\n * @param projectPath - Optional project path, uses process.cwd() if not provided\n * @returns Path to the todos.json file\n */\nfunction getSessionTodoPath(sessionId: string, projectPath?: string): string {\n const effectiveProjectPath =\n projectPath || currentProjectPath || process.cwd()\n const projectHash = getProjectHash(effectiveProjectPath)\n return join(CONFIG_PATHS.sessions, projectHash, sessionId, 'todos.json')\n}\n\n/**\n * Get the todo file path with backward compatibility\n *\n * Priority:\n * 1. Check new path structure first (if it exists)\n * 2. Check legacy path for backward compatibility (read-only)\n * 3. Default to new path for new files\n *\n * @param sessionId - Session identifier\n * @param projectPath - Optional project path\n * @returns Path to read todos from (existing file or new path)\n */\nfunction getTodoFilePath(sessionId: string, projectPath?: string): string {\n // Check new path structure first\n const newPath = getSessionTodoPath(sessionId, projectPath)\n if (existsSync(newPath)) {\n return newPath\n }\n\n // Check legacy path for backward compatibility (read-only)\n const legacyPath = getLegacyTodoPath(sessionId)\n if (existsSync(legacyPath)) {\n return legacyPath\n }\n\n // Default to new path for new files\n return newPath\n}\n\n/**\n * Ensure the directory for a todo file exists\n */\nfunction ensureTodoDirectory(filePath: string): void {\n const dir = join(filePath, '..')\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/**\n * Initialize todo session with a specific session ID and optional project path\n * Must be called when starting a new REPL session\n *\n * @param sessionId - Unique session identifier\n * @param projectPath - Optional project path for organizing todos by project\n */\nexport function initTodoSession(sessionId: string, projectPath?: string): void {\n currentSessionId = sessionId\n currentProjectPath = projectPath || process.cwd()\n // Invalidate cache when session changes\n invalidateCache()\n}\n\n/**\n * Get current session ID\n */\nexport function getCurrentTodoSessionId(): string | null {\n return currentSessionId\n}\n\n/**\n * Get current project path\n */\nexport function getCurrentProjectPath(): string | null {\n return currentProjectPath\n}\n\n/**\n * Read todos from session-scoped file\n * Supports both new path structure and legacy path for backward compatibility\n */\nfunction readSessionTodos(sessionId: string): TodoItem[] {\n const filePath = getTodoFilePath(sessionId, currentProjectPath || undefined)\n if (!existsSync(filePath)) {\n return []\n }\n try {\n const content = readFileSync(filePath, 'utf-8')\n return JSON.parse(content) as TodoItem[]\n } catch {\n return []\n }\n}\n\n/**\n * Write todos to session-scoped file\n * Always writes to the new path structure\n */\nfunction writeSessionTodos(sessionId: string, todos: TodoItem[]): void {\n // Always write to the new path structure\n const filePath = getSessionTodoPath(\n sessionId,\n currentProjectPath || undefined,\n )\n\n try {\n // Ensure directory exists\n ensureTodoDirectory(filePath)\n\n if (todos.length === 0) {\n // Remove file if no todos (cleanup)\n if (existsSync(filePath)) {\n unlinkSync(filePath)\n }\n } else {\n writeFileSync(filePath, JSON.stringify(todos, null, 2), 'utf-8')\n }\n } catch (error) {\n // Silently fail if we can't write (e.g., no permissions)\n // console.error('Failed to persist todos:', error)\n }\n}\n\n/**\n * Delete session todo file (used when clearing conversation)\n * Deletes from both new path and legacy path if they exist\n */\nexport function deleteSessionTodos(sessionId?: string): void {\n const targetSessionId = sessionId || currentSessionId\n if (!targetSessionId) return\n\n // Delete from new path\n const newPath = getSessionTodoPath(\n targetSessionId,\n currentProjectPath || undefined,\n )\n try {\n if (existsSync(newPath)) {\n unlinkSync(newPath)\n }\n } catch {\n // Silently fail\n }\n\n // Also delete from legacy path if it exists\n const legacyPath = getLegacyTodoPath(targetSessionId)\n try {\n if (existsSync(legacyPath)) {\n unlinkSync(legacyPath)\n }\n } catch {\n // Silently fail\n }\n\n // Also clear in-memory state\n if (!sessionId || sessionId === currentSessionId) {\n invalidateCache()\n setSessionState({\n ...getSessionState(),\n [TODO_STORAGE_KEY]: [],\n } as any)\n }\n}\n\n// Performance metrics\nexport interface TodoMetrics {\n totalOperations: number\n cacheHits: number\n cacheMisses: number\n lastOperation: number\n}\n\nfunction invalidateCache(): void {\n todoCache = null\n cacheTimestamp = 0\n}\n\nfunction updateMetrics(operation: string, cacheHit: boolean = false): void {\n const sessionState = getSessionState() as any\n const metrics = sessionState.todoMetrics || {\n totalOperations: 0,\n cacheHits: 0,\n cacheMisses: 0,\n lastOperation: 0,\n }\n\n metrics.totalOperations++\n metrics.lastOperation = Date.now()\n\n if (cacheHit) {\n metrics.cacheHits++\n } else {\n metrics.cacheMisses++\n }\n\n setSessionState({\n ...sessionState,\n todoMetrics: metrics,\n })\n}\n\nexport function getTodoMetrics(): TodoMetrics {\n const sessionState = getSessionState() as any\n return (\n sessionState.todoMetrics || {\n totalOperations: 0,\n cacheHits: 0,\n cacheMisses: 0,\n lastOperation: 0,\n }\n )\n}\n\nexport function getTodos(agentId?: string): TodoItem[] {\n const resolvedAgentId = resolveAgentId(agentId)\n const now = Date.now()\n\n // For agent-scoped storage, use file-based storage instead of session state\n if (agentId) {\n updateMetrics('getTodos', false)\n const agentTodos = readAgentData<TodoItem[]>(resolvedAgentId) || []\n return agentTodos\n }\n\n // Check cache first for performance\n if (todoCache && now - cacheTimestamp < CACHE_TTL) {\n updateMetrics('getTodos', true)\n return todoCache\n }\n\n updateMetrics('getTodos', false)\n\n // Try to read from session-scoped file first (persisted todos)\n if (currentSessionId) {\n const sessionTodos = readSessionTodos(currentSessionId)\n if (sessionTodos.length > 0) {\n // Update cache\n todoCache = [...sessionTodos]\n cacheTimestamp = now\n // Also sync to session state\n setSessionState({\n ...getSessionState(),\n [TODO_STORAGE_KEY]: sessionTodos,\n } as any)\n return sessionTodos\n }\n }\n\n // Fall back to session state (in-memory)\n const sessionState = getSessionState()\n const todos = (sessionState as any)[TODO_STORAGE_KEY] || []\n\n // Update cache\n todoCache = [...todos]\n cacheTimestamp = now\n\n return todos\n}\n\nexport function setTodos(todos: TodoItem[], agentId?: string): void {\n const resolvedAgentId = resolveAgentId(agentId)\n const config = getTodoConfig()\n const existingTodos = getTodos(agentId)\n\n // For agent-scoped storage, use file-based storage\n if (agentId) {\n // Validate todo limit\n if (todos.length > config.maxTodos) {\n throw new Error(\n `Todo limit exceeded. Maximum ${config.maxTodos} todos allowed.`,\n )\n }\n\n // Auto-archive completed todos if enabled\n let processedTodos = todos\n if (config.autoArchiveCompleted) {\n processedTodos = todos.filter(todo => todo.status !== 'completed')\n }\n\n const updatedTodos = processedTodos.map(todo => {\n // Find existing todo to track status changes\n const existingTodo = existingTodos.find(\n existing => existing.id === todo.id,\n )\n\n return {\n ...todo,\n updatedAt: Date.now(),\n createdAt: todo.createdAt || Date.now(),\n previousStatus:\n existingTodo?.status !== todo.status\n ? existingTodo?.status\n : todo.previousStatus,\n }\n })\n\n // Smart sorting for agent todos\n updatedTodos.sort((a, b) => {\n // 1. Status priority: in_progress > pending > completed\n const statusOrder = { in_progress: 3, pending: 2, completed: 1 }\n const statusDiff = statusOrder[b.status] - statusOrder[a.status]\n if (statusDiff !== 0) return statusDiff\n\n // 2. For same status, sort by priority: high > medium > low\n const priorityOrder = { high: 3, medium: 2, low: 1 }\n const priorityDiff = priorityOrder[b.priority] - priorityOrder[a.priority]\n if (priorityDiff !== 0) return priorityDiff\n\n // 3. For same status and priority, sort by updatedAt (newest first)\n const aTime = a.updatedAt || 0\n const bTime = b.updatedAt || 0\n return bTime - aTime\n })\n\n // Write to agent-specific storage\n writeAgentData(resolvedAgentId, updatedTodos)\n updateMetrics('setTodos')\n return\n }\n\n // Original session-based logic for backward compatibility\n // Validate todo limit\n if (todos.length > config.maxTodos) {\n throw new Error(\n `Todo limit exceeded. Maximum ${config.maxTodos} todos allowed.`,\n )\n }\n\n // Auto-archive completed todos if enabled\n let processedTodos = todos\n if (config.autoArchiveCompleted) {\n processedTodos = todos.filter(todo => todo.status !== 'completed')\n }\n\n const updatedTodos = processedTodos.map(todo => {\n // Find existing todo to track status changes\n const existingTodo = existingTodos.find(existing => existing.id === todo.id)\n\n return {\n ...todo,\n updatedAt: Date.now(),\n createdAt: todo.createdAt || Date.now(),\n previousStatus:\n existingTodo?.status !== todo.status\n ? existingTodo?.status\n : todo.previousStatus,\n }\n })\n\n // Smart sorting: status -> priority -> updatedAt\n updatedTodos.sort((a, b) => {\n // 1. Status priority: in_progress > pending > completed\n const statusOrder = { in_progress: 3, pending: 2, completed: 1 }\n const statusDiff = statusOrder[b.status] - statusOrder[a.status]\n if (statusDiff !== 0) return statusDiff\n\n // 2. For same status, sort by priority: high > medium > low\n const priorityOrder = { high: 3, medium: 2, low: 1 }\n const priorityDiff = priorityOrder[b.priority] - priorityOrder[a.priority]\n if (priorityDiff !== 0) return priorityDiff\n\n // 3. For same status and priority, sort by updatedAt (newest first)\n const aTime = a.updatedAt || 0\n const bTime = b.updatedAt || 0\n return bTime - aTime\n })\n\n setSessionState({\n ...getSessionState(),\n [TODO_STORAGE_KEY]: updatedTodos,\n } as any)\n\n // Persist to session-scoped file for persistence within this conversation\n if (currentSessionId) {\n writeSessionTodos(currentSessionId, updatedTodos)\n }\n\n // Invalidate cache\n invalidateCache()\n updateMetrics('setTodos')\n}\n\nexport function getTodoConfig(): TodoStorageConfig {\n const sessionState = getSessionState() as any\n return { ...DEFAULT_CONFIG, ...(sessionState[TODO_CONFIG_KEY] || {}) }\n}\n\nexport function setTodoConfig(config: Partial<TodoStorageConfig>): void {\n const currentConfig = getTodoConfig()\n const newConfig = { ...currentConfig, ...config }\n\n setSessionState({\n ...getSessionState(),\n [TODO_CONFIG_KEY]: newConfig,\n } as any)\n\n // Re-sort existing todos if sort order changed\n if (config.sortBy || config.sortOrder) {\n const todos = getTodos()\n setTodos(todos) // This will re-sort according to new config\n }\n}\n\nexport function addTodo(\n todo: Omit<TodoItem, 'createdAt' | 'updatedAt'>,\n): TodoItem[] {\n const todos = getTodos()\n\n // Check for duplicate IDs\n if (todos.some(existing => existing.id === todo.id)) {\n throw new Error(`Todo with ID '${todo.id}' already exists`)\n }\n\n const newTodo: TodoItem = {\n ...todo,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n }\n\n const updatedTodos = [...todos, newTodo]\n setTodos(updatedTodos)\n updateMetrics('addTodo')\n return updatedTodos\n}\n\nexport function updateTodo(id: string, updates: Partial<TodoItem>): TodoItem[] {\n const todos = getTodos()\n const existingTodo = todos.find(todo => todo.id === id)\n\n if (!existingTodo) {\n throw new Error(`Todo with ID '${id}' not found`)\n }\n\n const updatedTodos = todos.map(todo =>\n todo.id === id ? { ...todo, ...updates, updatedAt: Date.now() } : todo,\n )\n\n setTodos(updatedTodos)\n updateMetrics('updateTodo')\n return updatedTodos\n}\n\nexport function deleteTodo(id: string): TodoItem[] {\n const todos = getTodos()\n const todoExists = todos.some(todo => todo.id === id)\n\n if (!todoExists) {\n throw new Error(`Todo with ID '${id}' not found`)\n }\n\n const updatedTodos = todos.filter(todo => todo.id !== id)\n setTodos(updatedTodos)\n updateMetrics('deleteTodo')\n return updatedTodos\n}\n\nexport function clearTodos(): void {\n setTodos([])\n updateMetrics('clearTodos')\n}\n\nexport function getTodoById(id: string): TodoItem | undefined {\n const todos = getTodos()\n updateMetrics('getTodoById')\n return todos.find(todo => todo.id === id)\n}\n\nexport function getTodosByStatus(status: TodoItem['status']): TodoItem[] {\n const todos = getTodos()\n updateMetrics('getTodosByStatus')\n return todos.filter(todo => todo.status === status)\n}\n\nexport function getTodosByPriority(priority: TodoItem['priority']): TodoItem[] {\n const todos = getTodos()\n updateMetrics('getTodosByPriority')\n return todos.filter(todo => todo.priority === priority)\n}\n\n// Advanced query function\nexport function queryTodos(query: TodoQuery): TodoItem[] {\n const todos = getTodos()\n updateMetrics('queryTodos')\n\n return todos.filter(todo => {\n // Status filter\n if (query.status && !query.status.includes(todo.status)) {\n return false\n }\n\n // Priority filter\n if (query.priority && !query.priority.includes(todo.priority)) {\n return false\n }\n\n // Content search\n if (\n query.contentMatch &&\n !todo.content.toLowerCase().includes(query.contentMatch.toLowerCase())\n ) {\n return false\n }\n\n // Tags filter\n if (query.tags && todo.tags) {\n const hasMatchingTag = query.tags.some(tag => todo.tags!.includes(tag))\n if (!hasMatchingTag) return false\n }\n\n // Date range filter\n if (query.dateRange) {\n const todoDate = new Date(todo.createdAt || 0)\n if (query.dateRange.from && todoDate < query.dateRange.from) return false\n if (query.dateRange.to && todoDate > query.dateRange.to) return false\n }\n\n return true\n })\n}\n\n// Utility functions\nexport function getTodoStatistics() {\n const todos = getTodos()\n const metrics = getTodoMetrics()\n\n return {\n total: todos.length,\n byStatus: {\n pending: todos.filter(t => t.status === 'pending').length,\n in_progress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n },\n byPriority: {\n high: todos.filter(t => t.priority === 'high').length,\n medium: todos.filter(t => t.priority === 'medium').length,\n low: todos.filter(t => t.priority === 'low').length,\n },\n metrics,\n cacheEfficiency:\n metrics.totalOperations > 0\n ? Math.round((metrics.cacheHits / metrics.totalOperations) * 100)\n : 0,\n }\n}\n\nexport function optimizeTodoStorage(): void {\n // Force cache refresh\n invalidateCache()\n\n // Compact storage by removing any invalid entries\n const todos = getTodos()\n const validTodos = todos.filter(\n todo =>\n todo.id &&\n todo.content &&\n ['pending', 'in_progress', 'completed'].includes(todo.status) &&\n ['high', 'medium', 'low'].includes(todo.priority),\n )\n\n if (validTodos.length !== todos.length) {\n setTodos(validTodos)\n }\n\n updateMetrics('optimizeTodoStorage')\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["processedTodos", "updatedTodos"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/utils/tooling/safeRender.tsx"],
4
- "sourcesContent": ["/**\n * Safe Rendering Utilities for Tool Results\n *\n * Provides null-safe wrappers for tool rendering methods to prevent\n * crashes from undefined returns or exceptions.\n *\n * Part of Phase 1.3: Null Guards Completion\n */\n\nimport * as React from 'react'\nimport { Box, Text } from 'ink'\nimport { Tool } from '@tool'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\n/**\n * Default tool result component when tool doesn't provide a renderer.\n *\n * This is used as a fallback when:\n * 1. Tool is not found (e.g., MCP tool no longer available)\n * 2. Tool doesn't have a renderToolResultMessage method\n * 3. Tool's renderToolResultMessage returns null/undefined\n *\n * For better UX, we display a simple success message instead of raw JSON data,\n * which can be confusing for users.\n */\nexport function DefaultToolResult({\n output,\n}: {\n output: unknown\n}): React.ReactElement {\n // For objects (like tool data), show a simple success message\n // instead of raw JSON which can be confusing\n if (output !== null && output !== undefined && typeof output === 'object') {\n // Try to extract meaningful info from the object\n const obj = output as Record<string, unknown>\n\n // Check for common success indicators\n if ('success' in obj || 'result' in obj || 'data' in obj) {\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={SEMANTIC_COLORS.success}>Done</Text>\n </Box>\n )\n }\n\n // For other objects, show a generic completion message\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={SEMANTIC_COLORS.success}>Completed</Text>\n </Box>\n )\n }\n\n // For strings, show the content (truncated if too long)\n if (typeof output === 'string') {\n const displayContent = output.length > 500 ? output.slice(0, 500) + '...' : output\n return (\n <Box flexDirection=\"column\">\n <Text color={SEMANTIC_COLORS.dim}>{displayContent}</Text>\n </Box>\n )\n }\n\n // For null/undefined, show no output message\n if (output === null || output === undefined) {\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={SEMANTIC_COLORS.dim}>(no output)</Text>\n </Box>\n )\n }\n\n // For other primitives, convert to string\n return (\n <Box flexDirection=\"column\">\n <Text color={SEMANTIC_COLORS.dim}>{String(output)}</Text>\n </Box>\n )\n}\n\n/**\n * Error display component for tool rendering failures.\n */\nexport function ErrorToolResult({\n error,\n toolName,\n}: {\n error: unknown\n toolName?: string\n}): React.ReactElement {\n const errorMessage =\n error instanceof Error ? error.message : String(error || 'Unknown error')\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"red\">\n {toolName ? `[${toolName}] ` : ''}Error rendering result:\n </Text>\n <Text color={SEMANTIC_COLORS.dim}>{errorMessage}</Text>\n </Box>\n )\n}\n\n/**\n * Safely render a tool result with comprehensive error handling.\n *\n * @param tool - The tool that produced the result\n * @param output - The tool's output data\n * @param options - Rendering options\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolResult(\n tool: Tool | undefined | null,\n output: unknown,\n options: { verbose: boolean },\n): React.ReactNode {\n // No tool provided\n if (!tool) {\n return <DefaultToolResult output={output} />\n }\n\n // Tool doesn't have a renderer\n if (!tool.renderToolResultMessage) {\n return <DefaultToolResult output={output} />\n }\n\n try {\n const rendered = tool.renderToolResultMessage(output, options)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return <DefaultToolResult output={output} />\n }\n\n return rendered\n } catch (error) {\n // Catch any rendering errors\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Safely render a tool use message with comprehensive error handling.\n *\n * @param tool - The tool being used\n * @param input - The tool's input parameters\n * @param options - Rendering options\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolUseMessage(\n tool: Tool | undefined | null,\n input: unknown,\n options: { verbose: boolean },\n): React.ReactNode {\n // No tool provided\n if (!tool) {\n return (\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>Unknown tool call</Text>\n </Box>\n )\n }\n\n // Tool doesn't have a renderer\n if (!tool.renderToolUseMessage) {\n return (\n <Box>\n <Text>\n <Text color=\"cyan\">{tool.name}</Text>\n {options.verbose && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n {JSON.stringify(input).slice(0, 100)}\n </Text>\n )}\n </Text>\n </Box>\n )\n }\n\n try {\n const rendered = tool.renderToolUseMessage(input, options)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return (\n <Box>\n <Text color=\"cyan\">{tool.name}</Text>\n </Box>\n )\n }\n\n return rendered\n } catch (error) {\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Safely render a tool rejection message with comprehensive error handling.\n *\n * @param tool - The tool that was rejected\n * @param args - Arguments to pass to the rejection renderer\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolRejectedMessage(\n tool: Tool | undefined | null,\n ...args: unknown[]\n): React.ReactNode {\n // No tool or no renderer\n if (!tool || !tool.renderToolUseRejectedMessage) {\n return (\n <Box>\n <Text color=\"yellow\">Tool use rejected</Text>\n </Box>\n )\n }\n\n try {\n const rendered = tool.renderToolUseRejectedMessage(...args)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return (\n <Box>\n <Text color=\"yellow\">{tool.name} rejected</Text>\n </Box>\n )\n }\n\n return rendered\n } catch (error) {\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Type guard to check if a value is a valid React node.\n */\nexport function isValidReactNode(value: unknown): value is React.ReactNode {\n if (value === null || value === undefined) {\n return true // React accepts null/undefined\n }\n\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true\n }\n\n if (Array.isArray(value)) {\n return value.every(isValidReactNode)\n }\n\n // Check for React element\n if (typeof value === 'object' && value !== null) {\n return '$$typeof' in value || React.isValidElement(value)\n }\n\n return false\n}\n\n/**\n * Wrap a potentially unsafe render function with error boundaries.\n *\n * @param renderFn - The render function to wrap\n * @param fallback - Fallback content on error\n * @returns A safe render function\n */\nexport function wrapRenderFunction<TArgs extends unknown[]>(\n renderFn: (...args: TArgs) => React.ReactNode,\n fallback: React.ReactNode,\n): (...args: TArgs) => React.ReactNode {\n return (...args: TArgs) => {\n try {\n const result = renderFn(...args)\n if (result === null || result === undefined) {\n return fallback\n }\n return result\n } catch {\n return fallback\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Safe Rendering Utilities for Tool Results\n *\n * Provides null-safe wrappers for tool rendering methods to prevent\n * crashes from undefined returns or exceptions.\n *\n * Part of Phase 1.3: Null Guards Completion\n */\n\nimport * as React from 'react'\nimport { Box, Text } from 'ink'\nimport { Tool } from '@tool'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\n/**\n * Default tool result component when tool doesn't provide a renderer.\n *\n * This is used as a fallback when:\n * 1. Tool is not found (e.g., MCP tool no longer available)\n * 2. Tool doesn't have a renderToolResultMessage method\n * 3. Tool's renderToolResultMessage returns null/undefined\n *\n * For better UX, we display a simple success message instead of raw JSON data,\n * which can be confusing for users.\n */\nexport function DefaultToolResult({\n output,\n}: {\n output: unknown\n}): React.ReactElement {\n // For objects (like tool data), show a simple success message\n // instead of raw JSON which can be confusing\n if (output !== null && output !== undefined && typeof output === 'object') {\n // Try to extract meaningful info from the object\n const obj = output as Record<string, unknown>\n\n // Check for common success indicators\n if ('success' in obj || 'result' in obj || 'data' in obj) {\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={SEMANTIC_COLORS.success}>Done</Text>\n </Box>\n )\n }\n\n // For other objects, show a generic completion message\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={SEMANTIC_COLORS.success}>Completed</Text>\n </Box>\n )\n }\n\n // For strings, show the content (truncated if too long)\n if (typeof output === 'string') {\n const displayContent =\n output.length > 500 ? output.slice(0, 500) + '...' : output\n return (\n <Box flexDirection=\"column\">\n <Text color={SEMANTIC_COLORS.dim}>{displayContent}</Text>\n </Box>\n )\n }\n\n // For null/undefined, show no output message\n if (output === null || output === undefined) {\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={SEMANTIC_COLORS.dim}>(no output)</Text>\n </Box>\n )\n }\n\n // For other primitives, convert to string\n return (\n <Box flexDirection=\"column\">\n <Text color={SEMANTIC_COLORS.dim}>{String(output)}</Text>\n </Box>\n )\n}\n\n/**\n * Error display component for tool rendering failures.\n */\nexport function ErrorToolResult({\n error,\n toolName,\n}: {\n error: unknown\n toolName?: string\n}): React.ReactElement {\n const errorMessage =\n error instanceof Error ? error.message : String(error || 'Unknown error')\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"red\">\n {toolName ? `[${toolName}] ` : ''}Error rendering result:\n </Text>\n <Text color={SEMANTIC_COLORS.dim}>{errorMessage}</Text>\n </Box>\n )\n}\n\n/**\n * Safely render a tool result with comprehensive error handling.\n *\n * @param tool - The tool that produced the result\n * @param output - The tool's output data\n * @param options - Rendering options\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolResult(\n tool: Tool | undefined | null,\n output: unknown,\n options: { verbose: boolean },\n): React.ReactNode {\n // No tool provided\n if (!tool) {\n return <DefaultToolResult output={output} />\n }\n\n // Tool doesn't have a renderer\n if (!tool.renderToolResultMessage) {\n return <DefaultToolResult output={output} />\n }\n\n try {\n const rendered = tool.renderToolResultMessage(output, options)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return <DefaultToolResult output={output} />\n }\n\n return rendered\n } catch (error) {\n // Catch any rendering errors\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Safely render a tool use message with comprehensive error handling.\n *\n * @param tool - The tool being used\n * @param input - The tool's input parameters\n * @param options - Rendering options\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolUseMessage(\n tool: Tool | undefined | null,\n input: unknown,\n options: { verbose: boolean },\n): React.ReactNode {\n // No tool provided\n if (!tool) {\n return (\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>Unknown tool call</Text>\n </Box>\n )\n }\n\n // Tool doesn't have a renderer\n if (!tool.renderToolUseMessage) {\n return (\n <Box>\n <Text>\n <Text color=\"cyan\">{tool.name}</Text>\n {options.verbose && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n {JSON.stringify(input).slice(0, 100)}\n </Text>\n )}\n </Text>\n </Box>\n )\n }\n\n try {\n const rendered = tool.renderToolUseMessage(input, options)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return (\n <Box>\n <Text color=\"cyan\">{tool.name}</Text>\n </Box>\n )\n }\n\n return rendered\n } catch (error) {\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Safely render a tool rejection message with comprehensive error handling.\n *\n * @param tool - The tool that was rejected\n * @param args - Arguments to pass to the rejection renderer\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolRejectedMessage(\n tool: Tool | undefined | null,\n ...args: unknown[]\n): React.ReactNode {\n // No tool or no renderer\n if (!tool || !tool.renderToolUseRejectedMessage) {\n return (\n <Box>\n <Text color=\"yellow\">Tool use rejected</Text>\n </Box>\n )\n }\n\n try {\n const rendered = tool.renderToolUseRejectedMessage(...args)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return (\n <Box>\n <Text color=\"yellow\">{tool.name} rejected</Text>\n </Box>\n )\n }\n\n return rendered\n } catch (error) {\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Type guard to check if a value is a valid React node.\n */\nexport function isValidReactNode(value: unknown): value is React.ReactNode {\n if (value === null || value === undefined) {\n return true // React accepts null/undefined\n }\n\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true\n }\n\n if (Array.isArray(value)) {\n return value.every(isValidReactNode)\n }\n\n // Check for React element\n if (typeof value === 'object' && value !== null) {\n return '$$typeof' in value || React.isValidElement(value)\n }\n\n return false\n}\n\n/**\n * Wrap a potentially unsafe render function with error boundaries.\n *\n * @param renderFn - The render function to wrap\n * @param fallback - Fallback content on error\n * @returns A safe render function\n */\nexport function wrapRenderFunction<TArgs extends unknown[]>(\n renderFn: (...args: TArgs) => React.ReactNode,\n fallback: React.ReactNode,\n): (...args: TArgs) => React.ReactNode {\n return (...args: TArgs) => {\n try {\n const result = renderFn(...args)\n if (result === null || result === undefined) {\n return fallback\n }\n return result\n } catch {\n return fallback\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
- const VERSION = "0.3.6";
2
- const BUILD_DATE = "2026-02-03T09:29:07.934Z";
1
+ const VERSION = "0.3.10";
2
+ const BUILD_DATE = "2026-02-11T00:33:37.162Z";
3
3
  export {
4
4
  BUILD_DATE,
5
5
  VERSION
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["/**\n * Application version\n * This file is auto-generated during build process\n */\n\nexport const VERSION = '0.3.6'\nexport const BUILD_DATE = '2026-02-03T09:29:07.934Z'\n"],
4
+ "sourcesContent": ["/**\n * Application version\n * This file is auto-generated during build process\n */\n\nexport const VERSION = '0.3.10'\nexport const BUILD_DATE = '2026-02-11T00:33:37.162Z'\n"],
5
5
  "mappings": "AAKO,MAAM,UAAU;AAChB,MAAM,aAAa;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,49 +1,78 @@
1
1
  {
2
2
  "name": "@within-7/minto",
3
- "version": "0.3.6",
3
+ "version": "0.3.10",
4
+ "type": "module",
4
5
  "description": "AI-powered strategic research and planning assistant",
5
6
  "author": "Lib <within-7>",
6
7
  "license": "Apache-2.0",
7
- "homepage": "https://within-7.com/minto",
8
+ "homepage": "https://minto.within-7.com/",
8
9
  "repository": {
9
10
  "type": "git",
10
11
  "url": "git+https://github.com/within-7/minto.git"
11
12
  },
13
+ "bugs": {
14
+ "url": "https://github.com/within-7/minto/issues"
15
+ },
16
+ "keywords": [
17
+ "ai",
18
+ "cli",
19
+ "claude",
20
+ "anthropic",
21
+ "mcp",
22
+ "agent",
23
+ "assistant"
24
+ ],
12
25
  "bin": {
13
- "minto": "cli.js"
26
+ "minto": "cli.cjs"
27
+ },
28
+ "main": "cli.cjs",
29
+ "exports": {
30
+ ".": "./cli.cjs",
31
+ "./package.json": "./package.json"
14
32
  },
15
- "main": "cli.js",
16
33
  "engines": {
17
34
  "node": ">=20.0.0"
18
35
  },
36
+ "os": [
37
+ "darwin",
38
+ "linux",
39
+ "win32"
40
+ ],
41
+ "cpu": [
42
+ "arm64",
43
+ "x64"
44
+ ],
19
45
  "files": [
20
- "cli.js",
46
+ "cli.cjs",
21
47
  "yoga.wasm",
22
48
  "dist/**/*",
23
49
  "!dist/binaries",
24
- "scripts/postinstall.js",
50
+ "scripts/postinstall.cjs",
25
51
  ".npmrc"
26
52
  ],
27
53
  "scripts": {
28
- "dev": "bun run ./src/entrypoints/cli.tsx --verbose",
54
+ "dev": "bun run ./src/entrypoints/bootstrap.ts --verbose",
55
+ "dev:debug": "bun run ./src/entrypoints/bootstrap.ts --debug",
29
56
  "build": "node scripts/build.mjs",
30
57
  "build:packages": "node scripts/build-platform-packages.mjs",
31
- "clean": "rm -rf cli.js dist binaries packages",
58
+ "build:website": "node scripts/build-website.mjs",
59
+ "clean": "rm -rf cli.cjs dist binaries packages",
32
60
  "test": "bun test",
61
+ "test:watch": "bun test --watch",
33
62
  "typecheck": "tsc --noEmit",
63
+ "lint": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json}\"",
34
64
  "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"",
35
- "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json}\"",
36
- "prepublishOnly": "node scripts/build.mjs && node scripts/prepublish-check.js",
37
- "postinstall": "node scripts/postinstall.js || true",
38
- "release": "node scripts/release-full.js",
39
- "release:dry-run": "node scripts/release-full.js --dry-run"
65
+ "prepublishOnly": "node scripts/build.mjs && node scripts/prepublish-check.cjs",
66
+ "postinstall": "node scripts/postinstall.cjs || true",
67
+ "release": "node scripts/release-full.cjs",
68
+ "release:dry-run": "node scripts/release-full.cjs --dry-run"
40
69
  },
41
70
  "optionalDependencies": {
42
- "@within-7/minto-darwin-arm64": "0.3.6",
43
- "@within-7/minto-darwin-x64": "0.3.6",
44
- "@within-7/minto-linux-arm64": "0.3.6",
45
- "@within-7/minto-linux-x64": "0.3.6",
46
- "@within-7/minto-win32-x64": "0.3.6"
71
+ "@within-7/minto-darwin-arm64": "0.3.10",
72
+ "@within-7/minto-darwin-x64": "0.3.10",
73
+ "@within-7/minto-linux-arm64": "0.3.10",
74
+ "@within-7/minto-linux-x64": "0.3.10",
75
+ "@within-7/minto-win32-x64": "0.3.10"
47
76
  },
48
77
  "dependencies": {
49
78
  "@anthropic-ai/bedrock-sdk": "^0.12.6",
@@ -52,8 +81,6 @@
52
81
  "@commander-js/extra-typings": "^13.1.0",
53
82
  "@inkjs/ui": "^2.0.0",
54
83
  "@modelcontextprotocol/sdk": "^1.15.1",
55
- "@types/lodash-es": "^4.17.12",
56
- "@types/react": "^19.1.8",
57
84
  "ansi-escapes": "^7.0.0",
58
85
  "chalk": "^5.4.1",
59
86
  "cli-highlight": "^2.1.11",
@@ -74,19 +101,18 @@
74
101
  "lodash-es": "^4.17.21",
75
102
  "lru-cache": "^11.1.0",
76
103
  "marked": "^15.0.12",
77
- "minimatch": "10.1.1",
104
+ "minimatch": "^10.1.1",
78
105
  "nanoid": "^5.1.5",
79
106
  "node-fetch": "^3.3.2",
80
107
  "node-html-parser": "^7.0.1",
81
108
  "openai": "^4.104.0",
82
- "react": "18.3.1",
109
+ "react": "^18.3.1",
83
110
  "semver": "^7.7.2",
84
111
  "shell-quote": "^1.8.3",
85
112
  "signal-exit": "3.0.7",
86
113
  "spawn-rx": "^5.1.2",
87
114
  "string-width": "4.2.3",
88
115
  "strip-ansi": "6.0.1",
89
- "tsx": "^4.20.3",
90
116
  "turndown": "^7.2.0",
91
117
  "undici": "^6.22.0",
92
118
  "wrap-ansi": "8.1.0",
@@ -95,14 +121,30 @@
95
121
  },
96
122
  "devDependencies": {
97
123
  "@types/bun": "latest",
98
- "@types/minimatch": "6.0.0",
99
- "@types/node": "^24.1.0",
124
+ "@types/debug": "^4.1.12",
125
+ "@types/diff": "^7.0.0",
126
+ "@types/lodash-es": "^4.17.12",
127
+ "@types/minimatch": "^6.0.0",
128
+ "@types/node": "^22.0.0",
129
+ "@types/react": "^18.3.18",
130
+ "@types/semver": "^7.5.8",
131
+ "@types/shell-quote": "^1.7.5",
132
+ "@types/turndown": "^5.0.5",
100
133
  "bun-types": "latest",
101
- "esbuild": "^0.25.9",
134
+ "esbuild": "^0.25.0",
102
135
  "prettier": "^3.6.2",
103
- "sharp": "0.34.5",
136
+ "sharp": "^0.34.5",
137
+ "tsx": "^4.20.3",
104
138
  "typescript": "^5.9.2"
105
139
  },
140
+ "peerDependencies": {
141
+ "react": "^18.0.0"
142
+ },
143
+ "peerDependenciesMeta": {
144
+ "react": {
145
+ "optional": true
146
+ }
147
+ },
106
148
  "resolutions": {
107
149
  "signal-exit": "3.0.7",
108
150
  "string-width": "4.2.3",
@@ -115,5 +157,6 @@
115
157
  "strip-ansi": "6.0.1",
116
158
  "formdata-node": "^6.0.3",
117
159
  "node-domexception": "npm:domexception@^4.0.0"
118
- }
160
+ },
161
+ "packageManager": "bun@1.2.0"
119
162
  }
@@ -114,7 +114,7 @@ function displaySuccessMessage(binaryStatus) {
114
114
  }
115
115
 
116
116
  console.error('');
117
- console.error(' 📚 文档: https://within-7.com/minto');
117
+ console.error(' 📚 文档: https://minto.within-7.com/');
118
118
  console.error(' 🐛 问题反馈: https://github.com/within-7/minto/issues');
119
119
  console.error('');
120
120
  console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');