@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,234 @@
1
+ import {
2
+ existsSync,
3
+ appendFileSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ mkdirSync
7
+ } from "fs";
8
+ import { dirname, resolve } from "path";
9
+ import { CONFIG_PATHS } from "./configPaths.js";
10
+ import { sanitizeInput, containsDangerousSequences } from "./sanitizeInput.js";
11
+ import { debug as debugLogger } from "./debugLogger.js";
12
+ import { getCwd } from "./state.js";
13
+ const DEFAULT_LIMIT = 100;
14
+ const MAX_HISTORY_ENTRIES = 1e4;
15
+ let historyCache = null;
16
+ let cacheTimestamp = 0;
17
+ const CACHE_TTL = 5e3;
18
+ function invalidateCache() {
19
+ historyCache = null;
20
+ cacheTimestamp = 0;
21
+ }
22
+ function getHistoryFilePath() {
23
+ return CONFIG_PATHS.globalHistoryFile;
24
+ }
25
+ function ensureHistoryDir() {
26
+ const historyDir = dirname(getHistoryFilePath());
27
+ if (!existsSync(historyDir)) {
28
+ mkdirSync(historyDir, { recursive: true });
29
+ }
30
+ }
31
+ function appendHistoryEntry(entry) {
32
+ try {
33
+ ensureHistoryDir();
34
+ const line = JSON.stringify(entry) + "\n";
35
+ appendFileSync(getHistoryFilePath(), line, "utf-8");
36
+ historyCache = null;
37
+ debugLogger.trace("HISTORY_ENTRY_APPENDED", {
38
+ command: entry.command.slice(0, 50),
39
+ projectPath: entry.projectPath
40
+ });
41
+ } catch (error) {
42
+ debugLogger.error("HISTORY_APPEND_FAILED", {
43
+ error: error instanceof Error ? error.message : String(error)
44
+ });
45
+ }
46
+ }
47
+ function addToHistoryNew(command, mode = "prompt") {
48
+ const sanitizedCommand = sanitizeInput(command);
49
+ if (!sanitizedCommand.trim()) {
50
+ return;
51
+ }
52
+ if (containsDangerousSequences(command)) {
53
+ debugLogger.warn("HISTORY_DANGEROUS_SEQUENCE", {
54
+ command: command.slice(0, 50)
55
+ });
56
+ }
57
+ let projectPath;
58
+ try {
59
+ projectPath = getCwd();
60
+ } catch {
61
+ }
62
+ const entry = {
63
+ command: sanitizedCommand,
64
+ timestamp: Date.now(),
65
+ projectPath,
66
+ mode
67
+ };
68
+ const recent = readHistoryEntries({ limit: 1 });
69
+ if (recent.length > 0 && recent[0].command === sanitizedCommand) {
70
+ return;
71
+ }
72
+ appendHistoryEntry(entry);
73
+ }
74
+ function readAllHistoryEntries() {
75
+ if (historyCache && Date.now() - cacheTimestamp < CACHE_TTL) {
76
+ return historyCache;
77
+ }
78
+ const filePath = getHistoryFilePath();
79
+ if (!existsSync(filePath)) {
80
+ return [];
81
+ }
82
+ try {
83
+ const content = readFileSync(filePath, "utf-8");
84
+ const lines = content.split("\n").filter((line) => line.trim());
85
+ const entries = [];
86
+ for (const line of lines) {
87
+ try {
88
+ const entry = JSON.parse(line);
89
+ entries.push(entry);
90
+ } catch {
91
+ debugLogger.trace("HISTORY_INVALID_LINE", { line: line.slice(0, 50) });
92
+ }
93
+ }
94
+ historyCache = entries;
95
+ cacheTimestamp = Date.now();
96
+ return entries;
97
+ } catch (error) {
98
+ debugLogger.error("HISTORY_READ_FAILED", {
99
+ error: error instanceof Error ? error.message : String(error)
100
+ });
101
+ return [];
102
+ }
103
+ }
104
+ function readHistoryEntries(options = {}) {
105
+ const { limit = DEFAULT_LIMIT, projectPath, mode, since } = options;
106
+ let entries = readAllHistoryEntries();
107
+ if (projectPath) {
108
+ const normalizedPath = resolve(projectPath).toLowerCase();
109
+ entries = entries.filter(
110
+ (e) => e.projectPath && resolve(e.projectPath).toLowerCase() === normalizedPath
111
+ );
112
+ }
113
+ if (mode) {
114
+ entries = entries.filter((e) => e.mode === mode);
115
+ }
116
+ if (since) {
117
+ entries = entries.filter((e) => e.timestamp > since);
118
+ }
119
+ return entries.sort((a, b) => b.timestamp - a.timestamp).slice(0, limit);
120
+ }
121
+ function getHistoryStrings(options = {}) {
122
+ return readHistoryEntries(options).map((e) => e.command);
123
+ }
124
+ function getCurrentProjectHistory(limit = DEFAULT_LIMIT) {
125
+ let projectPath;
126
+ try {
127
+ projectPath = getCwd();
128
+ } catch {
129
+ return getHistoryStrings({ limit });
130
+ }
131
+ return getHistoryStrings({ limit, projectPath });
132
+ }
133
+ function searchHistory(searchTerm, options = {}) {
134
+ const term = searchTerm.toLowerCase();
135
+ const entries = readHistoryEntries({ ...options, limit: MAX_HISTORY_ENTRIES });
136
+ return entries.filter((e) => e.command.toLowerCase().includes(term)).slice(0, options.limit || DEFAULT_LIMIT);
137
+ }
138
+ function rotateHistoryIfNeeded() {
139
+ const entries = readAllHistoryEntries();
140
+ if (entries.length <= MAX_HISTORY_ENTRIES) {
141
+ return;
142
+ }
143
+ debugLogger.info("HISTORY_ROTATION_STARTED", {
144
+ currentEntries: entries.length,
145
+ maxEntries: MAX_HISTORY_ENTRIES
146
+ });
147
+ const keepEntries = entries.sort((a, b) => b.timestamp - a.timestamp).slice(0, MAX_HISTORY_ENTRIES);
148
+ keepEntries.sort((a, b) => a.timestamp - b.timestamp);
149
+ try {
150
+ const filePath = getHistoryFilePath();
151
+ const content = keepEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
152
+ writeFileSync(filePath, content, "utf-8");
153
+ historyCache = null;
154
+ debugLogger.info("HISTORY_ROTATION_COMPLETE", {
155
+ removedEntries: entries.length - keepEntries.length,
156
+ keptEntries: keepEntries.length
157
+ });
158
+ } catch (error) {
159
+ debugLogger.error("HISTORY_ROTATION_FAILED", {
160
+ error: error instanceof Error ? error.message : String(error)
161
+ });
162
+ }
163
+ }
164
+ function clearHistory() {
165
+ const filePath = getHistoryFilePath();
166
+ if (existsSync(filePath)) {
167
+ try {
168
+ writeFileSync(filePath, "", "utf-8");
169
+ historyCache = null;
170
+ debugLogger.info("HISTORY_CLEARED", {});
171
+ } catch (error) {
172
+ debugLogger.error("HISTORY_CLEAR_FAILED", {
173
+ error: error instanceof Error ? error.message : String(error)
174
+ });
175
+ }
176
+ }
177
+ }
178
+ function getHistoryStats() {
179
+ const entries = readAllHistoryEntries();
180
+ if (entries.length === 0) {
181
+ return {
182
+ totalEntries: 0,
183
+ oldestEntry: null,
184
+ newestEntry: null,
185
+ uniqueProjects: 0
186
+ };
187
+ }
188
+ const timestamps = entries.map((e) => e.timestamp).filter((t) => t > 0);
189
+ const projects = new Set(entries.map((e) => e.projectPath).filter(Boolean));
190
+ return {
191
+ totalEntries: entries.length,
192
+ oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : null,
193
+ newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : null,
194
+ uniqueProjects: projects.size
195
+ };
196
+ }
197
+ function exportHistory() {
198
+ return readAllHistoryEntries();
199
+ }
200
+ function importHistory(entries) {
201
+ const existing = readAllHistoryEntries();
202
+ const existingSet = new Set(existing.map((e) => `${e.command}:${e.timestamp}`));
203
+ let imported = 0;
204
+ for (const entry of entries) {
205
+ const key = `${entry.command}:${entry.timestamp}`;
206
+ if (!existingSet.has(key)) {
207
+ appendHistoryEntry(entry);
208
+ imported++;
209
+ }
210
+ }
211
+ debugLogger.info("HISTORY_IMPORTED", {
212
+ total: entries.length,
213
+ imported,
214
+ skipped: entries.length - imported
215
+ });
216
+ return imported;
217
+ }
218
+ export {
219
+ addToHistoryNew,
220
+ appendHistoryEntry,
221
+ clearHistory,
222
+ exportHistory,
223
+ getCurrentProjectHistory,
224
+ getHistoryFilePath,
225
+ getHistoryStats,
226
+ getHistoryStrings,
227
+ importHistory,
228
+ invalidateCache,
229
+ readAllHistoryEntries,
230
+ readHistoryEntries,
231
+ rotateHistoryIfNeeded,
232
+ searchHistory
233
+ };
234
+ //# sourceMappingURL=historyManager.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/historyManager.ts"],
4
+ "sourcesContent": ["/**\n * History Manager Module\n *\n * Provides high-performance JSONL-based command history management.\n * Uses append-only writes for efficiency and supports project-level filtering.\n *\n * Storage: ~/.minto/history/global.jsonl\n *\n * Entry format (one JSON object per line):\n * {\n * \"command\": \"git status\",\n * \"timestamp\": 1706976000000,\n * \"projectPath\": \"/path/to/project\",\n * \"mode\": \"prompt\" | \"bash\" | \"koding\"\n * }\n */\n\nimport {\n existsSync,\n appendFileSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n} from 'fs'\nimport { dirname, resolve } from 'path'\nimport { CONFIG_PATHS, ensureConfigDirs } from './configPaths'\nimport { sanitizeInput, containsDangerousSequences } from './sanitizeInput'\nimport { debug as debugLogger } from './debugLogger'\nimport { getCwd } from './state'\n\n/**\n * History entry stored in JSONL format\n */\nexport interface HistoryEntry {\n /** The command/input that was entered */\n command: string\n /** Unix timestamp when the command was entered */\n timestamp: number\n /** Project path where the command was executed */\n projectPath?: string\n /** Input mode: prompt, bash, or koding */\n mode?: 'prompt' | 'bash' | 'koding'\n}\n\n/**\n * Options for reading history\n */\nexport interface HistoryReadOptions {\n /** Maximum number of entries to return (default: 100) */\n limit?: number\n /** Filter by project path */\n projectPath?: string\n /** Filter by mode */\n mode?: 'prompt' | 'bash' | 'koding'\n /** Return entries newer than this timestamp */\n since?: number\n}\n\n// Default limits\nconst DEFAULT_LIMIT = 100\nconst MAX_HISTORY_ENTRIES = 10000 // Maximum entries before rotation\n\n// In-memory cache for performance\nlet historyCache: HistoryEntry[] | null = null\nlet cacheTimestamp: number = 0\nconst CACHE_TTL = 5000 // 5 seconds cache TTL\n\n/**\n * Invalidate the in-memory cache\n * Useful for testing and after external file modifications\n */\nexport function invalidateCache(): void {\n historyCache = null\n cacheTimestamp = 0\n}\n\n/**\n * Get the path to the global history file\n */\nexport function getHistoryFilePath(): string {\n return CONFIG_PATHS.globalHistoryFile\n}\n\n/**\n * Ensure the history directory exists\n */\nfunction ensureHistoryDir(): void {\n const historyDir = dirname(getHistoryFilePath())\n if (!existsSync(historyDir)) {\n mkdirSync(historyDir, { recursive: true })\n }\n}\n\n/**\n * Append a history entry to the JSONL file\n * Uses append mode for high performance\n */\nexport function appendHistoryEntry(entry: HistoryEntry): void {\n try {\n ensureHistoryDir()\n\n const line = JSON.stringify(entry) + '\\n'\n appendFileSync(getHistoryFilePath(), line, 'utf-8')\n\n // Invalidate cache\n historyCache = null\n\n debugLogger.trace('HISTORY_ENTRY_APPENDED', {\n command: entry.command.slice(0, 50),\n projectPath: entry.projectPath,\n })\n } catch (error) {\n debugLogger.error('HISTORY_APPEND_FAILED', {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/**\n * Add a command to history with automatic metadata\n *\n * @param command The command to add\n * @param mode The input mode (prompt, bash, koding)\n */\nexport function addToHistoryNew(\n command: string,\n mode: 'prompt' | 'bash' | 'koding' = 'prompt',\n): void {\n // Sanitize the command before saving\n const sanitizedCommand = sanitizeInput(command)\n\n // Skip empty commands after sanitization\n if (!sanitizedCommand.trim()) {\n return\n }\n\n // Warn if command contains dangerous sequences\n if (containsDangerousSequences(command)) {\n debugLogger.warn('HISTORY_DANGEROUS_SEQUENCE', {\n command: command.slice(0, 50),\n })\n }\n\n // Get current project path\n let projectPath: string | undefined\n try {\n projectPath = getCwd()\n } catch {\n // Ignore if we can't get cwd\n }\n\n // Create entry\n const entry: HistoryEntry = {\n command: sanitizedCommand,\n timestamp: Date.now(),\n projectPath,\n mode,\n }\n\n // Check for duplicate (same as last entry)\n const recent = readHistoryEntries({ limit: 1 })\n if (recent.length > 0 && recent[0].command === sanitizedCommand) {\n return // Skip duplicate\n }\n\n appendHistoryEntry(entry)\n}\n\n/**\n * Read all history entries from the JSONL file\n * Uses caching for performance\n */\nexport function readAllHistoryEntries(): HistoryEntry[] {\n // Check cache\n if (historyCache && Date.now() - cacheTimestamp < CACHE_TTL) {\n return historyCache\n }\n\n const filePath = getHistoryFilePath()\n\n if (!existsSync(filePath)) {\n return []\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n const lines = content.split('\\n').filter(line => line.trim())\n\n const entries: HistoryEntry[] = []\n\n for (const line of lines) {\n try {\n const entry = JSON.parse(line) as HistoryEntry\n entries.push(entry)\n } catch {\n // Skip invalid lines\n debugLogger.trace('HISTORY_INVALID_LINE', { line: line.slice(0, 50) })\n }\n }\n\n // Update cache\n historyCache = entries\n cacheTimestamp = Date.now()\n\n return entries\n } catch (error) {\n debugLogger.error('HISTORY_READ_FAILED', {\n error: error instanceof Error ? error.message : String(error),\n })\n return []\n }\n}\n\n/**\n * Read history entries with filtering and limiting\n *\n * @param options Read options for filtering\n * @returns Filtered history entries (newest first)\n */\nexport function readHistoryEntries(\n options: HistoryReadOptions = {},\n): HistoryEntry[] {\n const { limit = DEFAULT_LIMIT, projectPath, mode, since } = options\n\n let entries = readAllHistoryEntries()\n\n // Apply filters\n if (projectPath) {\n const normalizedPath = resolve(projectPath).toLowerCase()\n entries = entries.filter(\n e =>\n e.projectPath &&\n resolve(e.projectPath).toLowerCase() === normalizedPath,\n )\n }\n\n if (mode) {\n entries = entries.filter(e => e.mode === mode)\n }\n\n if (since) {\n entries = entries.filter(e => e.timestamp > since)\n }\n\n // Sort by timestamp (newest first) and limit\n return entries.sort((a, b) => b.timestamp - a.timestamp).slice(0, limit)\n}\n\n/**\n * Get history as simple string array (for backward compatibility)\n *\n * @param options Read options\n * @returns Array of command strings (newest first)\n */\nexport function getHistoryStrings(options: HistoryReadOptions = {}): string[] {\n return readHistoryEntries(options).map(e => e.command)\n}\n\n/**\n * Get history for the current project\n *\n * @param limit Maximum number of entries\n * @returns Array of command strings (newest first)\n */\nexport function getCurrentProjectHistory(\n limit: number = DEFAULT_LIMIT,\n): string[] {\n let projectPath: string | undefined\n try {\n projectPath = getCwd()\n } catch {\n // Fallback to global history if we can't get cwd\n return getHistoryStrings({ limit })\n }\n\n return getHistoryStrings({ limit, projectPath })\n}\n\n/**\n * Search history for matching commands\n *\n * @param searchTerm Term to search for\n * @param options Additional read options\n * @returns Matching history entries (newest first)\n */\nexport function searchHistory(\n searchTerm: string,\n options: HistoryReadOptions = {},\n): HistoryEntry[] {\n const term = searchTerm.toLowerCase()\n const entries = readHistoryEntries({ ...options, limit: MAX_HISTORY_ENTRIES })\n\n return entries\n .filter(e => e.command.toLowerCase().includes(term))\n .slice(0, options.limit || DEFAULT_LIMIT)\n}\n\n/**\n * Rotate history file if it exceeds maximum entries\n * Keeps the most recent entries and removes older ones\n */\nexport function rotateHistoryIfNeeded(): void {\n const entries = readAllHistoryEntries()\n\n if (entries.length <= MAX_HISTORY_ENTRIES) {\n return\n }\n\n debugLogger.info('HISTORY_ROTATION_STARTED', {\n currentEntries: entries.length,\n maxEntries: MAX_HISTORY_ENTRIES,\n })\n\n // Keep the most recent entries\n const keepEntries = entries\n .sort((a, b) => b.timestamp - a.timestamp)\n .slice(0, MAX_HISTORY_ENTRIES)\n\n // Re-sort by timestamp ascending for writing\n keepEntries.sort((a, b) => a.timestamp - b.timestamp)\n\n // Rewrite the file\n try {\n const filePath = getHistoryFilePath()\n const content = keepEntries.map(e => JSON.stringify(e)).join('\\n') + '\\n'\n writeFileSync(filePath, content, 'utf-8')\n\n // Invalidate cache\n historyCache = null\n\n debugLogger.info('HISTORY_ROTATION_COMPLETE', {\n removedEntries: entries.length - keepEntries.length,\n keptEntries: keepEntries.length,\n })\n } catch (error) {\n debugLogger.error('HISTORY_ROTATION_FAILED', {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/**\n * Clear all history entries\n * Use with caution - this is destructive\n */\nexport function clearHistory(): void {\n const filePath = getHistoryFilePath()\n\n if (existsSync(filePath)) {\n try {\n writeFileSync(filePath, '', 'utf-8')\n historyCache = null\n debugLogger.info('HISTORY_CLEARED', {})\n } catch (error) {\n debugLogger.error('HISTORY_CLEAR_FAILED', {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n\n/**\n * Get history statistics\n */\nexport function getHistoryStats(): {\n totalEntries: number\n oldestEntry: number | null\n newestEntry: number | null\n uniqueProjects: number\n} {\n const entries = readAllHistoryEntries()\n\n if (entries.length === 0) {\n return {\n totalEntries: 0,\n oldestEntry: null,\n newestEntry: null,\n uniqueProjects: 0,\n }\n }\n\n const timestamps = entries.map(e => e.timestamp).filter(t => t > 0)\n const projects = new Set(entries.map(e => e.projectPath).filter(Boolean))\n\n return {\n totalEntries: entries.length,\n oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : null,\n newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : null,\n uniqueProjects: projects.size,\n }\n}\n\n/**\n * Export history to a JSON array (for backup/migration)\n */\nexport function exportHistory(): HistoryEntry[] {\n return readAllHistoryEntries()\n}\n\n/**\n * Import history from a JSON array (for migration)\n * Merges with existing history, avoiding duplicates\n */\nexport function importHistory(entries: HistoryEntry[]): number {\n const existing = readAllHistoryEntries()\n const existingSet = new Set(existing.map(e => `${e.command}:${e.timestamp}`))\n\n let imported = 0\n\n for (const entry of entries) {\n const key = `${entry.command}:${entry.timestamp}`\n if (!existingSet.has(key)) {\n appendHistoryEntry(entry)\n imported++\n }\n }\n\n debugLogger.info('HISTORY_IMPORTED', {\n total: entries.length,\n imported,\n skipped: entries.length - imported,\n })\n\n return imported\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -10,7 +10,7 @@ import {
10
10
  } from "fs";
11
11
  import { join, resolve, isAbsolute } from "path";
12
12
  import { homedir } from "os";
13
- import { execFileNoThrow } from "./execFileNoThrow.js";
13
+ import { fetchRepo } from "./repoFetcher.js";
14
14
  import {
15
15
  MarketplaceManifestSchema,
16
16
  MarketplaceError,
@@ -45,38 +45,13 @@ function saveRegistry(marketplaces) {
45
45
  const registryPath = getRegistryPath();
46
46
  writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), "utf-8");
47
47
  }
48
- async function cloneGitRepo(url, ref) {
49
- const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
50
- mkdirSync(tempDir, { recursive: true });
51
- try {
52
- const args = ["clone", "--depth", "1"];
53
- if (ref) {
54
- args.push("--branch", ref);
55
- }
56
- args.push(url, tempDir);
57
- const result = await execFileNoThrow("git", args);
58
- if (result.code !== 0) {
59
- throw new Error(`Git clone failed: ${result.stderr || result.stdout}`);
60
- }
61
- return tempDir;
62
- } catch (error) {
63
- try {
64
- rmSync(tempDir, { recursive: true, force: true });
65
- } catch (cleanupError) {
66
- }
67
- throw new MarketplaceError(
68
- `Failed to clone repository: ${error instanceof Error ? error.message : String(error)}`,
69
- MarketplaceErrorCode.GIT_ERROR,
70
- void 0,
71
- error
72
- );
73
- }
74
- }
75
48
  function loadManifestFromDirectory(dir) {
76
- const manifestPath = join(dir, ".minto-plugin", "marketplace.json");
77
- if (!existsSync(manifestPath)) {
49
+ const mintoPath = join(dir, ".minto-plugin", "marketplace.json");
50
+ const claudePath = join(dir, ".claude-plugin", "marketplace.json");
51
+ const manifestPath = existsSync(mintoPath) ? mintoPath : existsSync(claudePath) ? claudePath : null;
52
+ if (!manifestPath) {
78
53
  throw new MarketplaceError(
79
- `Marketplace manifest not found at ${manifestPath}`,
54
+ `Marketplace manifest not found (checked .minto-plugin/ and .claude-plugin/ in ${dir})`,
80
55
  MarketplaceErrorCode.MANIFEST_NOT_FOUND
81
56
  );
82
57
  }
@@ -94,10 +69,18 @@ function loadManifestFromDirectory(dir) {
94
69
  }
95
70
  }
96
71
  async function fetchGitHubMarketplace(repo, ref) {
97
- const url = `https://github.com/${repo}.git`;
98
- const tempDir = await cloneGitRepo(url, ref);
72
+ const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
73
+ mkdirSync(tempDir, { recursive: true });
99
74
  try {
75
+ await fetchRepo({ type: "github", repo, ref }, tempDir);
100
76
  return loadManifestFromDirectory(tempDir);
77
+ } catch (error) {
78
+ throw new MarketplaceError(
79
+ `Failed to fetch repository: ${error instanceof Error ? error.message : String(error)}`,
80
+ MarketplaceErrorCode.GIT_ERROR,
81
+ void 0,
82
+ error
83
+ );
101
84
  } finally {
102
85
  try {
103
86
  rmSync(tempDir, { recursive: true, force: true });
@@ -106,9 +89,18 @@ async function fetchGitHubMarketplace(repo, ref) {
106
89
  }
107
90
  }
108
91
  async function fetchUrlMarketplace(url, ref) {
109
- const tempDir = await cloneGitRepo(url, ref);
92
+ const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
93
+ mkdirSync(tempDir, { recursive: true });
110
94
  try {
95
+ await fetchRepo({ type: "url", url, ref }, tempDir);
111
96
  return loadManifestFromDirectory(tempDir);
97
+ } catch (error) {
98
+ throw new MarketplaceError(
99
+ `Failed to fetch repository: ${error instanceof Error ? error.message : String(error)}`,
100
+ MarketplaceErrorCode.GIT_ERROR,
101
+ void 0,
102
+ error
103
+ );
112
104
  } finally {
113
105
  try {
114
106
  rmSync(tempDir, { recursive: true, force: true });
@@ -120,6 +112,24 @@ function loadLocalMarketplace(path) {
120
112
  const resolvedPath = path.startsWith("/") ? path : join(getCwd(), path);
121
113
  return loadManifestFromDirectory(resolvedPath);
122
114
  }
115
+ function isMarketplaceRegistered(name) {
116
+ return loadRegistry().some((m) => m.name === name);
117
+ }
118
+ function registerMarketplaceFromDirectory(name, source, localDir) {
119
+ const registry = loadRegistry();
120
+ if (registry.some((m) => m.name === name)) return null;
121
+ const manifest = loadManifestFromDirectory(localDir);
122
+ const registered = {
123
+ name: manifest.name,
124
+ source,
125
+ manifest,
126
+ lastUpdated: /* @__PURE__ */ new Date(),
127
+ enabled: true
128
+ };
129
+ registry.push(registered);
130
+ saveRegistry(registry);
131
+ return registered;
132
+ }
123
133
  function parseMarketplaceSource(input) {
124
134
  if (/^[\w-]+\/[\w-]+$/.test(input)) {
125
135
  return { type: "github", repo: input };
@@ -243,7 +253,9 @@ function loadMarketplaceSettings() {
243
253
  const home = homedir();
244
254
  const settingsPaths = [
245
255
  { path: join(cwd, ".minto", "settings.json"), label: "project" },
246
- { path: join(home, ".minto", "settings.json"), label: "user" }
256
+ { path: join(cwd, ".claude", "settings.json"), label: "project/.claude" },
257
+ { path: join(home, ".minto", "settings.json"), label: "user" },
258
+ { path: join(home, ".claude", "settings.json"), label: "user/.claude" }
247
259
  ];
248
260
  for (const { path, label } of settingsPaths) {
249
261
  if (existsSync(path)) {
@@ -312,14 +324,28 @@ async function autoRegisterMarketplaces() {
312
324
  async function getMarketplaceRepoPath(marketplace) {
313
325
  switch (marketplace.source.type) {
314
326
  case "github": {
315
- const url = `https://github.com/${marketplace.source.repo}.git`;
316
- const tempDir = await cloneGitRepo(url, marketplace.source.ref);
327
+ const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
328
+ mkdirSync(tempDir, { recursive: true });
329
+ await fetchRepo(
330
+ {
331
+ type: "github",
332
+ repo: marketplace.source.repo,
333
+ ref: marketplace.source.ref
334
+ },
335
+ tempDir
336
+ );
317
337
  return { path: tempDir, cleanup: true };
318
338
  }
319
339
  case "url": {
320
- const tempDir = await cloneGitRepo(
321
- marketplace.source.url,
322
- marketplace.source.ref
340
+ const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
341
+ mkdirSync(tempDir, { recursive: true });
342
+ await fetchRepo(
343
+ {
344
+ type: "url",
345
+ url: marketplace.source.url,
346
+ ref: marketplace.source.ref
347
+ },
348
+ tempDir
323
349
  );
324
350
  return { path: tempDir, cleanup: true };
325
351
  }
@@ -426,16 +452,25 @@ async function installPluginFromMarketplace(pluginName, marketplaceName, targetD
426
452
  }
427
453
  copyDirectory(pluginSourcePath, installDir);
428
454
  } else if (plugin.source.source === "github") {
429
- const url = `https://github.com/${plugin.source.repo}.git`;
430
- const tempDir = await cloneGitRepo(url, plugin.source.ref);
455
+ const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
456
+ mkdirSync(tempDir, { recursive: true });
431
457
  try {
458
+ await fetchRepo(
459
+ { type: "github", repo: plugin.source.repo, ref: plugin.source.ref },
460
+ tempDir
461
+ );
432
462
  copyDirectory(tempDir, installDir);
433
463
  } finally {
434
464
  rmSync(tempDir, { recursive: true, force: true });
435
465
  }
436
466
  } else if (plugin.source.source === "url") {
437
- const tempDir = await cloneGitRepo(plugin.source.url, plugin.source.ref);
467
+ const tempDir = join(getMarketplaceDir(), "temp", Date.now().toString());
468
+ mkdirSync(tempDir, { recursive: true });
438
469
  try {
470
+ await fetchRepo(
471
+ { type: "url", url: plugin.source.url, ref: plugin.source.ref },
472
+ tempDir
473
+ );
439
474
  copyDirectory(tempDir, installDir);
440
475
  } finally {
441
476
  rmSync(tempDir, { recursive: true, force: true });
@@ -499,9 +534,11 @@ export {
499
534
  findPlugin,
500
535
  getMarketplace,
501
536
  installPluginFromMarketplace,
537
+ isMarketplaceRegistered,
502
538
  listMarketplaces,
503
539
  loadMarketplaceSettings,
504
540
  parseMarketplaceSource,
541
+ registerMarketplaceFromDirectory,
505
542
  removeMarketplace,
506
543
  updateMarketplace
507
544
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/marketplaceManager.ts"],
4
- "sourcesContent": ["/**\n * Marketplace Manager\n *\n * Manages plugin marketplaces including registration, updates, and plugin installation\n * from git-based marketplace sources.\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n rmSync,\n cpSync,\n symlinkSync,\n lstatSync,\n} from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { homedir } from 'os'\nimport { execFileNoThrow } from './execFileNoThrow'\nimport {\n MarketplaceManifest,\n MarketplaceManifestSchema,\n MarketplaceSource,\n RegisteredMarketplace,\n MarketplaceSettings,\n MarketplaceError,\n MarketplaceErrorCode,\n MarketplacePlugin,\n} from '../types/marketplace'\nimport { getCwd } from './state'\n\n/**\n * Get marketplace storage directory\n */\nfunction getMarketplaceDir(): string {\n const home = homedir()\n const dir = join(home, '.minto', 'marketplaces')\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n return dir\n}\n\n/**\n * Get marketplace registry file path\n */\nfunction getRegistryPath(): string {\n return join(getMarketplaceDir(), 'registry.json')\n}\n\n/**\n * Load marketplace registry\n */\nfunction loadRegistry(): RegisteredMarketplace[] {\n const registryPath = getRegistryPath()\n\n if (!existsSync(registryPath)) {\n return []\n }\n\n try {\n const content = readFileSync(registryPath, 'utf-8')\n return JSON.parse(content)\n } catch (error) {\n console.error('Error loading marketplace registry:', error)\n return []\n }\n}\n\n/**\n * Save marketplace registry\n */\nfunction saveRegistry(marketplaces: RegisteredMarketplace[]): void {\n const registryPath = getRegistryPath()\n writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), 'utf-8')\n}\n\n/**\n * Clone git repository to temporary location using safe execFile\n */\nasync function cloneGitRepo(url: string, ref?: string): Promise<string> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n // Build git clone arguments safely\n const args = ['clone', '--depth', '1']\n\n if (ref) {\n args.push('--branch', ref)\n }\n\n args.push(url, tempDir)\n\n // Clone repository using safe execFile\n const result = await execFileNoThrow('git', args)\n\n if (result.code !== 0) {\n throw new Error(`Git clone failed: ${result.stderr || result.stdout}`)\n }\n\n return tempDir\n } catch (error) {\n // Clean up on error\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Ignore cleanup errors\n }\n\n throw new MarketplaceError(\n `Failed to clone repository: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Load marketplace manifest from directory\n */\nfunction loadManifestFromDirectory(dir: string): MarketplaceManifest {\n const manifestPath = join(dir, '.minto-plugin', 'marketplace.json')\n\n if (!existsSync(manifestPath)) {\n throw new MarketplaceError(\n `Marketplace manifest not found at ${manifestPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n\n // Validate with Zod schema\n return MarketplaceManifestSchema.parse(data)\n } catch (error) {\n throw new MarketplaceError(\n `Invalid marketplace manifest: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest from GitHub\n */\nasync function fetchGitHubMarketplace(\n repo: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const url = `https://github.com/${repo}.git`\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n return loadManifestFromDirectory(tempDir)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from git URL\n */\nasync function fetchUrlMarketplace(\n url: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = await cloneGitRepo(url, ref)\n\n try {\n return loadManifestFromDirectory(tempDir)\n } finally {\n // Clean up temp directory\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Load marketplace manifest from local path\n */\nfunction loadLocalMarketplace(path: string): MarketplaceManifest {\n const resolvedPath = path.startsWith('/') ? path : join(getCwd(), path)\n return loadManifestFromDirectory(resolvedPath)\n}\n\n/**\n * Parse marketplace source from string input\n */\nexport function parseMarketplaceSource(input: string): MarketplaceSource {\n // GitHub shorthand: owner/repo\n if (/^[\\w-]+\\/[\\w-]+$/.test(input)) {\n return { type: 'github', repo: input }\n }\n\n // GitHub URL\n if (input.includes('github.com')) {\n const match = input.match(/github\\.com[/:]([\\w-]+\\/[\\w-]+)/)\n if (match) {\n return { type: 'github', repo: match[1] }\n }\n }\n\n // Git URL\n if (\n input.startsWith('http://') ||\n input.startsWith('https://') ||\n input.endsWith('.git')\n ) {\n return { type: 'url', url: input }\n }\n\n // Local path\n return { type: 'local', path: input }\n}\n\n/**\n * Add/register a marketplace\n */\nexport async function addMarketplace(\n input: string,\n): Promise<RegisteredMarketplace> {\n const source = parseMarketplaceSource(input)\n\n // Fetch manifest based on source type\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n // Check if already registered\n const registry = loadRegistry()\n if (registry.some(m => m.name === manifest.name)) {\n throw new MarketplaceError(\n `Marketplace \"${manifest.name}\" is already registered`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n manifest.name,\n )\n }\n\n // Create registered marketplace\n const registered: RegisteredMarketplace = {\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n }\n\n // Save to registry\n registry.push(registered)\n saveRegistry(registry)\n\n return registered\n}\n\n/**\n * Remove a marketplace\n */\nexport function removeMarketplace(name: string): void {\n const registry = loadRegistry()\n const filtered = registry.filter(m => m.name !== name)\n\n if (filtered.length === registry.length) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n saveRegistry(filtered)\n}\n\n/**\n * Update a marketplace (re-fetch manifest)\n */\nexport async function updateMarketplace(\n name: string,\n): Promise<RegisteredMarketplace> {\n const registry = loadRegistry()\n const marketplace = registry.find(m => m.name === name)\n\n if (!marketplace) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n // Re-fetch manifest\n let manifest: MarketplaceManifest\n\n switch (marketplace.source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(\n marketplace.source.repo,\n marketplace.source.ref,\n )\n break\n case 'url':\n manifest = await fetchUrlMarketplace(\n marketplace.source.url,\n marketplace.source.ref,\n )\n break\n case 'local':\n manifest = loadLocalMarketplace(marketplace.source.path)\n break\n }\n\n // Update in registry\n marketplace.manifest = manifest\n marketplace.lastUpdated = new Date()\n\n saveRegistry(registry)\n\n return marketplace\n}\n\n/**\n * List all registered marketplaces\n */\nexport function listMarketplaces(): RegisteredMarketplace[] {\n return loadRegistry()\n}\n\n/**\n * Get a specific marketplace\n */\nexport function getMarketplace(\n name: string,\n): RegisteredMarketplace | undefined {\n const registry = loadRegistry()\n return registry.find(m => m.name === name)\n}\n\n/**\n * Find plugin in marketplaces\n */\nexport function findPlugin(\n pluginName: string,\n marketplaceName?: string,\n):\n | {\n marketplace: RegisteredMarketplace\n plugin: MarketplacePlugin\n }\n | undefined {\n const registry = loadRegistry()\n\n // Search in specific marketplace\n if (marketplaceName) {\n const marketplace = registry.find(m => m.name === marketplaceName)\n if (!marketplace) return undefined\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (!plugin) return undefined\n\n return { marketplace, plugin }\n }\n\n // Search in all marketplaces\n for (const marketplace of registry) {\n if (!marketplace.enabled) continue\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (plugin) {\n return { marketplace, plugin }\n }\n }\n\n return undefined\n}\n\n/**\n * Load marketplace settings with hierarchical priority\n * Priority (highest to lowest):\n * 1. Project .minto/settings.json\n * 2. User ~/.minto/settings.json\n */\nexport function loadMarketplaceSettings(): MarketplaceSettings {\n const cwd = getCwd()\n const home = homedir()\n\n // Define search paths in priority order\n const settingsPaths = [\n { path: join(cwd, '.minto', 'settings.json'), label: 'project' },\n { path: join(home, '.minto', 'settings.json'), label: 'user' },\n ]\n\n // Try loading from each path in priority order\n for (const { path, label } of settingsPaths) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8')\n const settings = JSON.parse(content)\n // Optional: log which settings file was used for debugging\n // console.log(`Loaded marketplace settings from ${label}: ${path}`)\n return settings\n } catch (error) {\n console.error(\n `Error loading marketplace settings from ${label} (${path}):`,\n error,\n )\n // Continue to next path on error\n }\n }\n }\n\n // No settings found\n return {}\n}\n\n/**\n * Auto-register marketplaces from settings\n */\nexport async function autoRegisterMarketplaces(): Promise<void> {\n const settings = loadMarketplaceSettings()\n\n if (!settings.extraKnownMarketplaces) return\n\n const registry = loadRegistry()\n\n for (const [name, config] of Object.entries(\n settings.extraKnownMarketplaces,\n )) {\n // Skip if already registered\n if (registry.some(m => m.name === name)) continue\n\n try {\n let source: MarketplaceSource\n\n if (config.source.source === 'github' && config.source.repo) {\n source = {\n type: 'github',\n repo: config.source.repo,\n ref: config.source.ref,\n }\n } else if (config.source.source === 'url' && config.source.url) {\n source = { type: 'url', url: config.source.url, ref: config.source.ref }\n } else if (config.source.source === 'local' && config.source.path) {\n source = { type: 'local', path: config.source.path }\n } else {\n continue\n }\n\n // Fetch and register\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n registry.push({\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n })\n } catch (error) {\n console.error(`Error auto-registering marketplace ${name}:`, error)\n }\n }\n\n saveRegistry(registry)\n}\n\n/**\n * Get marketplace repository directory path\n * For cloned marketplaces, returns the temp directory path\n * For local marketplaces, returns the local path\n */\nasync function getMarketplaceRepoPath(\n marketplace: RegisteredMarketplace,\n): Promise<{ path: string; cleanup: boolean }> {\n switch (marketplace.source.type) {\n case 'github': {\n const url = `https://github.com/${marketplace.source.repo}.git`\n const tempDir = await cloneGitRepo(url, marketplace.source.ref)\n return { path: tempDir, cleanup: true }\n }\n case 'url': {\n const tempDir = await cloneGitRepo(\n marketplace.source.url,\n marketplace.source.ref,\n )\n return { path: tempDir, cleanup: true }\n }\n case 'local': {\n const resolvedPath = isAbsolute(marketplace.source.path)\n ? marketplace.source.path\n : resolve(getCwd(), marketplace.source.path)\n\n if (!existsSync(resolvedPath)) {\n throw new MarketplaceError(\n `Local marketplace path does not exist: ${resolvedPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n return { path: resolvedPath, cleanup: false }\n }\n }\n}\n\n/**\n * Copy directory contents recursively\n */\nfunction copyDirectory(sourcePath: string, destPath: string): void {\n try {\n // Create destination directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true })\n }\n\n // Copy recursively, excluding .git directories\n cpSync(sourcePath, destPath, {\n recursive: true,\n filter: src => {\n // Skip .git directories to avoid copying version control history\n return !src.includes('/.git/') && !src.endsWith('/.git')\n },\n })\n } catch (error) {\n throw new MarketplaceError(\n `Failed to copy directory from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Create symlink to directory\n */\nfunction symlinkDirectory(sourcePath: string, destPath: string): void {\n try {\n // Remove destination if it exists\n if (existsSync(destPath)) {\n // Check if it's already a symlink pointing to the right place\n try {\n const stats = lstatSync(destPath)\n if (stats.isSymbolicLink()) {\n // Already a symlink, remove it\n rmSync(destPath, { force: true })\n } else {\n throw new MarketplaceError(\n `Destination path already exists and is not a symlink: ${destPath}`,\n MarketplaceErrorCode.GIT_ERROR,\n )\n }\n } catch (error) {\n throw new MarketplaceError(\n `Failed to check existing path: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n } else {\n // Create parent directory\n const parentDir = join(destPath, '..')\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true })\n }\n }\n\n // Create symlink\n symlinkSync(sourcePath, destPath, 'dir')\n } catch (error) {\n throw new MarketplaceError(\n `Failed to create symlink from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Install plugin from marketplace\n */\nexport async function installPluginFromMarketplace(\n pluginName: string,\n marketplaceName?: string,\n targetDir?: string,\n options?: { dev?: boolean },\n): Promise<string> {\n const found = findPlugin(pluginName, marketplaceName)\n\n if (!found) {\n throw new MarketplaceError(\n marketplaceName\n ? `Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`\n : `Plugin \"${pluginName}\" not found in any marketplace`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n const { marketplace, plugin } = found\n\n // Determine installation directory\n const installDir =\n targetDir || join(getCwd(), '.minto', 'plugins', plugin.name)\n\n // Create installation directory\n if (!existsSync(installDir)) {\n mkdirSync(installDir, { recursive: true })\n }\n\n let cleanupMarketplaceRepo = false\n let marketplaceRepoPath: string | undefined\n\n try {\n // Install plugin based on source type\n if (typeof plugin.source === 'string') {\n // Relative path - resolve from marketplace source\n const repoInfo = await getMarketplaceRepoPath(marketplace)\n marketplaceRepoPath = repoInfo.path\n cleanupMarketplaceRepo = repoInfo.cleanup\n\n // Determine base path for relative plugin sources\n const pluginRoot = marketplace.manifest.metadata?.pluginRoot || ''\n const pluginSourcePath = join(\n marketplaceRepoPath,\n pluginRoot,\n plugin.source,\n )\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Plugin source path does not exist: ${pluginSourcePath} (relative path: ${plugin.source})`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // Copy plugin files to installation directory\n copyDirectory(pluginSourcePath, installDir)\n } else if (plugin.source.source === 'github') {\n // GitHub repository - clone directly\n const url = `https://github.com/${plugin.source.repo}.git`\n const tempDir = await cloneGitRepo(url, plugin.source.ref)\n\n try {\n copyDirectory(tempDir, installDir)\n } finally {\n // Clean up temp directory\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'url') {\n // Git URL - clone directly\n const tempDir = await cloneGitRepo(plugin.source.url, plugin.source.ref)\n\n try {\n copyDirectory(tempDir, installDir)\n } finally {\n // Clean up temp directory\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'local') {\n // Local path - resolve and copy or symlink\n const pluginSourcePath = isAbsolute(plugin.source.path)\n ? plugin.source.path\n : resolve(getCwd(), plugin.source.path)\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Local plugin path does not exist: ${pluginSourcePath}`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // In dev mode, create symlink for easier development\n // In production mode, copy files for isolation\n if (options?.dev) {\n symlinkDirectory(pluginSourcePath, installDir)\n } else {\n copyDirectory(pluginSourcePath, installDir)\n }\n }\n\n // Create marketplace metadata file to track source\n const metadataPath = join(installDir, '.marketplace-meta.json')\n const metadata = {\n marketplace: marketplace.name,\n plugin: plugin.name,\n installedAt: new Date().toISOString(),\n source: plugin.source,\n }\n writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), 'utf-8')\n\n // Create plugin.json if it doesn't exist (required for plugin discovery)\n const pluginManifestPath = join(installDir, 'plugin.json')\n if (!existsSync(pluginManifestPath)) {\n const pluginManifest = {\n name: plugin.name,\n displayName: plugin.name, // Use name as displayName for marketplace plugins\n version: plugin.version || '1.0.0',\n description: plugin.description || '',\n author: plugin.author,\n license: plugin.license,\n homepage: plugin.homepage,\n repository: plugin.repository,\n keywords: plugin.keywords || [],\n category: plugin.category,\n }\n writeFileSync(\n pluginManifestPath,\n JSON.stringify(pluginManifest, null, 2),\n 'utf-8',\n )\n }\n\n return installDir\n } finally {\n // Clean up marketplace repo if it was cloned\n if (cleanupMarketplaceRepo && marketplaceRepoPath) {\n try {\n rmSync(marketplaceRepoPath, { recursive: true, force: true })\n } catch (error) {\n // Ignore cleanup errors\n }\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Marketplace Manager\n *\n * Manages plugin marketplaces including registration, updates, and plugin installation\n * from git-based marketplace sources.\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n rmSync,\n cpSync,\n symlinkSync,\n lstatSync,\n} from 'fs'\nimport { join, resolve, isAbsolute } from 'path'\nimport { homedir } from 'os'\nimport { fetchRepo } from './repoFetcher'\nimport {\n MarketplaceManifest,\n MarketplaceManifestSchema,\n MarketplaceSource,\n RegisteredMarketplace,\n MarketplaceSettings,\n MarketplaceError,\n MarketplaceErrorCode,\n MarketplacePlugin,\n} from '../types/marketplace'\nimport { getCwd } from './state'\n\n/**\n * Get marketplace storage directory\n */\nfunction getMarketplaceDir(): string {\n const home = homedir()\n const dir = join(home, '.minto', 'marketplaces')\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n return dir\n}\n\n/**\n * Get marketplace registry file path\n */\nfunction getRegistryPath(): string {\n return join(getMarketplaceDir(), 'registry.json')\n}\n\n/**\n * Load marketplace registry\n */\nfunction loadRegistry(): RegisteredMarketplace[] {\n const registryPath = getRegistryPath()\n\n if (!existsSync(registryPath)) {\n return []\n }\n\n try {\n const content = readFileSync(registryPath, 'utf-8')\n return JSON.parse(content)\n } catch (error) {\n console.error('Error loading marketplace registry:', error)\n return []\n }\n}\n\n/**\n * Save marketplace registry\n */\nfunction saveRegistry(marketplaces: RegisteredMarketplace[]): void {\n const registryPath = getRegistryPath()\n writeFileSync(registryPath, JSON.stringify(marketplaces, null, 2), 'utf-8')\n}\n\n/**\n * Load marketplace manifest from directory\n */\nfunction loadManifestFromDirectory(dir: string): MarketplaceManifest {\n // Support both .minto-plugin (current) and .claude-plugin (legacy) directory names\n const mintoPath = join(dir, '.minto-plugin', 'marketplace.json')\n const claudePath = join(dir, '.claude-plugin', 'marketplace.json')\n const manifestPath = existsSync(mintoPath)\n ? mintoPath\n : existsSync(claudePath)\n ? claudePath\n : null\n\n if (!manifestPath) {\n throw new MarketplaceError(\n `Marketplace manifest not found (checked .minto-plugin/ and .claude-plugin/ in ${dir})`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n try {\n const content = readFileSync(manifestPath, 'utf-8')\n const data = JSON.parse(content)\n\n // Validate with Zod schema\n return MarketplaceManifestSchema.parse(data)\n } catch (error) {\n throw new MarketplaceError(\n `Invalid marketplace manifest: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.MANIFEST_INVALID,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Fetch marketplace manifest from GitHub\n */\nasync function fetchGitHubMarketplace(\n repo: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n await fetchRepo({ type: 'github', repo, ref }, tempDir)\n return loadManifestFromDirectory(tempDir)\n } catch (error) {\n throw new MarketplaceError(\n `Failed to fetch repository: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n } finally {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Fetch marketplace manifest from git URL\n */\nasync function fetchUrlMarketplace(\n url: string,\n ref?: string,\n): Promise<MarketplaceManifest> {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n await fetchRepo({ type: 'url', url, ref }, tempDir)\n return loadManifestFromDirectory(tempDir)\n } catch (error) {\n throw new MarketplaceError(\n `Failed to fetch repository: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n } finally {\n try {\n rmSync(tempDir, { recursive: true, force: true })\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Load marketplace manifest from local path\n */\nfunction loadLocalMarketplace(path: string): MarketplaceManifest {\n const resolvedPath = path.startsWith('/') ? path : join(getCwd(), path)\n return loadManifestFromDirectory(resolvedPath)\n}\n\n/**\n * Check if a marketplace is already registered by name\n */\nexport function isMarketplaceRegistered(name: string): boolean {\n return loadRegistry().some(m => m.name === name)\n}\n\n/**\n * Register a marketplace from a local directory containing a marketplace manifest.\n * Returns the registered marketplace, or null if already registered.\n */\nexport function registerMarketplaceFromDirectory(\n name: string,\n source: MarketplaceSource,\n localDir: string,\n): RegisteredMarketplace | null {\n const registry = loadRegistry()\n if (registry.some(m => m.name === name)) return null // already registered\n\n const manifest = loadManifestFromDirectory(localDir)\n const registered: RegisteredMarketplace = {\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n }\n\n registry.push(registered)\n saveRegistry(registry)\n return registered\n}\n\n/**\n * Parse marketplace source from string input\n */\nexport function parseMarketplaceSource(input: string): MarketplaceSource {\n // GitHub shorthand: owner/repo\n if (/^[\\w-]+\\/[\\w-]+$/.test(input)) {\n return { type: 'github', repo: input }\n }\n\n // GitHub URL\n if (input.includes('github.com')) {\n const match = input.match(/github\\.com[/:]([\\w-]+\\/[\\w-]+)/)\n if (match) {\n return { type: 'github', repo: match[1] }\n }\n }\n\n // Git URL\n if (\n input.startsWith('http://') ||\n input.startsWith('https://') ||\n input.endsWith('.git')\n ) {\n return { type: 'url', url: input }\n }\n\n // Local path\n return { type: 'local', path: input }\n}\n\n/**\n * Add/register a marketplace\n */\nexport async function addMarketplace(\n input: string,\n): Promise<RegisteredMarketplace> {\n const source = parseMarketplaceSource(input)\n\n // Fetch manifest based on source type\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n // Check if already registered\n const registry = loadRegistry()\n if (registry.some(m => m.name === manifest.name)) {\n throw new MarketplaceError(\n `Marketplace \"${manifest.name}\" is already registered`,\n MarketplaceErrorCode.ALREADY_REGISTERED,\n manifest.name,\n )\n }\n\n // Create registered marketplace\n const registered: RegisteredMarketplace = {\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n }\n\n // Save to registry\n registry.push(registered)\n saveRegistry(registry)\n\n return registered\n}\n\n/**\n * Remove a marketplace\n */\nexport function removeMarketplace(name: string): void {\n const registry = loadRegistry()\n const filtered = registry.filter(m => m.name !== name)\n\n if (filtered.length === registry.length) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n saveRegistry(filtered)\n}\n\n/**\n * Update a marketplace (re-fetch manifest)\n */\nexport async function updateMarketplace(\n name: string,\n): Promise<RegisteredMarketplace> {\n const registry = loadRegistry()\n const marketplace = registry.find(m => m.name === name)\n\n if (!marketplace) {\n throw new MarketplaceError(\n `Marketplace \"${name}\" is not registered`,\n MarketplaceErrorCode.NOT_REGISTERED,\n name,\n )\n }\n\n // Re-fetch manifest\n let manifest: MarketplaceManifest\n\n switch (marketplace.source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(\n marketplace.source.repo,\n marketplace.source.ref,\n )\n break\n case 'url':\n manifest = await fetchUrlMarketplace(\n marketplace.source.url,\n marketplace.source.ref,\n )\n break\n case 'local':\n manifest = loadLocalMarketplace(marketplace.source.path)\n break\n }\n\n // Update in registry\n marketplace.manifest = manifest\n marketplace.lastUpdated = new Date()\n\n saveRegistry(registry)\n\n return marketplace\n}\n\n/**\n * List all registered marketplaces\n */\nexport function listMarketplaces(): RegisteredMarketplace[] {\n return loadRegistry()\n}\n\n/**\n * Get a specific marketplace\n */\nexport function getMarketplace(\n name: string,\n): RegisteredMarketplace | undefined {\n const registry = loadRegistry()\n return registry.find(m => m.name === name)\n}\n\n/**\n * Find plugin in marketplaces\n */\nexport function findPlugin(\n pluginName: string,\n marketplaceName?: string,\n):\n | {\n marketplace: RegisteredMarketplace\n plugin: MarketplacePlugin\n }\n | undefined {\n const registry = loadRegistry()\n\n // Search in specific marketplace\n if (marketplaceName) {\n const marketplace = registry.find(m => m.name === marketplaceName)\n if (!marketplace) return undefined\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (!plugin) return undefined\n\n return { marketplace, plugin }\n }\n\n // Search in all marketplaces\n for (const marketplace of registry) {\n if (!marketplace.enabled) continue\n\n const plugin = marketplace.manifest.plugins.find(p => p.name === pluginName)\n if (plugin) {\n return { marketplace, plugin }\n }\n }\n\n return undefined\n}\n\n/**\n * Load marketplace settings with hierarchical priority\n * Priority (highest to lowest):\n * 1. Project .minto/settings.json\n * 2. Project .claude/settings.json (legacy)\n * 3. User ~/.minto/settings.json\n * 4. User ~/.claude/settings.json (legacy)\n */\nexport function loadMarketplaceSettings(): MarketplaceSettings {\n const cwd = getCwd()\n const home = homedir()\n\n // Define search paths in priority order (.minto > .claude at each level)\n const settingsPaths = [\n { path: join(cwd, '.minto', 'settings.json'), label: 'project' },\n { path: join(cwd, '.claude', 'settings.json'), label: 'project/.claude' },\n { path: join(home, '.minto', 'settings.json'), label: 'user' },\n { path: join(home, '.claude', 'settings.json'), label: 'user/.claude' },\n ]\n\n // Try loading from each path in priority order\n for (const { path, label } of settingsPaths) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8')\n const settings = JSON.parse(content)\n // Optional: log which settings file was used for debugging\n // console.log(`Loaded marketplace settings from ${label}: ${path}`)\n return settings\n } catch (error) {\n console.error(\n `Error loading marketplace settings from ${label} (${path}):`,\n error,\n )\n // Continue to next path on error\n }\n }\n }\n\n // No settings found\n return {}\n}\n\n/**\n * Auto-register marketplaces from settings\n */\nexport async function autoRegisterMarketplaces(): Promise<void> {\n const settings = loadMarketplaceSettings()\n\n if (!settings.extraKnownMarketplaces) return\n\n const registry = loadRegistry()\n\n for (const [name, config] of Object.entries(\n settings.extraKnownMarketplaces,\n )) {\n // Skip if already registered\n if (registry.some(m => m.name === name)) continue\n\n try {\n let source: MarketplaceSource\n\n if (config.source.source === 'github' && config.source.repo) {\n source = {\n type: 'github',\n repo: config.source.repo,\n ref: config.source.ref,\n }\n } else if (config.source.source === 'url' && config.source.url) {\n source = { type: 'url', url: config.source.url, ref: config.source.ref }\n } else if (config.source.source === 'local' && config.source.path) {\n source = { type: 'local', path: config.source.path }\n } else {\n continue\n }\n\n // Fetch and register\n let manifest: MarketplaceManifest\n\n switch (source.type) {\n case 'github':\n manifest = await fetchGitHubMarketplace(source.repo, source.ref)\n break\n case 'url':\n manifest = await fetchUrlMarketplace(source.url, source.ref)\n break\n case 'local':\n manifest = loadLocalMarketplace(source.path)\n break\n }\n\n registry.push({\n name: manifest.name,\n source,\n manifest,\n lastUpdated: new Date(),\n enabled: true,\n })\n } catch (error) {\n console.error(`Error auto-registering marketplace ${name}:`, error)\n }\n }\n\n saveRegistry(registry)\n}\n\n/**\n * Get marketplace repository directory path\n * For cloned marketplaces, returns the temp directory path\n * For local marketplaces, returns the local path\n */\nasync function getMarketplaceRepoPath(\n marketplace: RegisteredMarketplace,\n): Promise<{ path: string; cleanup: boolean }> {\n switch (marketplace.source.type) {\n case 'github': {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n await fetchRepo(\n {\n type: 'github',\n repo: marketplace.source.repo,\n ref: marketplace.source.ref,\n },\n tempDir,\n )\n return { path: tempDir, cleanup: true }\n }\n case 'url': {\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n await fetchRepo(\n {\n type: 'url',\n url: marketplace.source.url,\n ref: marketplace.source.ref,\n },\n tempDir,\n )\n return { path: tempDir, cleanup: true }\n }\n case 'local': {\n const resolvedPath = isAbsolute(marketplace.source.path)\n ? marketplace.source.path\n : resolve(getCwd(), marketplace.source.path)\n\n if (!existsSync(resolvedPath)) {\n throw new MarketplaceError(\n `Local marketplace path does not exist: ${resolvedPath}`,\n MarketplaceErrorCode.MANIFEST_NOT_FOUND,\n )\n }\n\n return { path: resolvedPath, cleanup: false }\n }\n }\n}\n\n/**\n * Copy directory contents recursively\n */\nfunction copyDirectory(sourcePath: string, destPath: string): void {\n try {\n // Create destination directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true })\n }\n\n // Copy recursively, excluding .git directories\n cpSync(sourcePath, destPath, {\n recursive: true,\n filter: src => {\n // Skip .git directories to avoid copying version control history\n return !src.includes('/.git/') && !src.endsWith('/.git')\n },\n })\n } catch (error) {\n throw new MarketplaceError(\n `Failed to copy directory from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Create symlink to directory\n */\nfunction symlinkDirectory(sourcePath: string, destPath: string): void {\n try {\n // Remove destination if it exists\n if (existsSync(destPath)) {\n // Check if it's already a symlink pointing to the right place\n try {\n const stats = lstatSync(destPath)\n if (stats.isSymbolicLink()) {\n // Already a symlink, remove it\n rmSync(destPath, { force: true })\n } else {\n throw new MarketplaceError(\n `Destination path already exists and is not a symlink: ${destPath}`,\n MarketplaceErrorCode.GIT_ERROR,\n )\n }\n } catch (error) {\n throw new MarketplaceError(\n `Failed to check existing path: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n } else {\n // Create parent directory\n const parentDir = join(destPath, '..')\n if (!existsSync(parentDir)) {\n mkdirSync(parentDir, { recursive: true })\n }\n }\n\n // Create symlink\n symlinkSync(sourcePath, destPath, 'dir')\n } catch (error) {\n throw new MarketplaceError(\n `Failed to create symlink from ${sourcePath} to ${destPath}: ${error instanceof Error ? error.message : String(error)}`,\n MarketplaceErrorCode.GIT_ERROR,\n undefined,\n error,\n )\n }\n}\n\n/**\n * Install plugin from marketplace\n */\nexport async function installPluginFromMarketplace(\n pluginName: string,\n marketplaceName?: string,\n targetDir?: string,\n options?: { dev?: boolean },\n): Promise<string> {\n const found = findPlugin(pluginName, marketplaceName)\n\n if (!found) {\n throw new MarketplaceError(\n marketplaceName\n ? `Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`\n : `Plugin \"${pluginName}\" not found in any marketplace`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n const { marketplace, plugin } = found\n\n // Determine installation directory\n const installDir =\n targetDir || join(getCwd(), '.minto', 'plugins', plugin.name)\n\n // Create installation directory\n if (!existsSync(installDir)) {\n mkdirSync(installDir, { recursive: true })\n }\n\n let cleanupMarketplaceRepo = false\n let marketplaceRepoPath: string | undefined\n\n try {\n // Install plugin based on source type\n if (typeof plugin.source === 'string') {\n // Relative path - resolve from marketplace source\n const repoInfo = await getMarketplaceRepoPath(marketplace)\n marketplaceRepoPath = repoInfo.path\n cleanupMarketplaceRepo = repoInfo.cleanup\n\n // Determine base path for relative plugin sources\n const pluginRoot = marketplace.manifest.metadata?.pluginRoot || ''\n const pluginSourcePath = join(\n marketplaceRepoPath,\n pluginRoot,\n plugin.source,\n )\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Plugin source path does not exist: ${pluginSourcePath} (relative path: ${plugin.source})`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // Copy plugin files to installation directory\n copyDirectory(pluginSourcePath, installDir)\n } else if (plugin.source.source === 'github') {\n // GitHub repository - fetch via tarball/clone\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n await fetchRepo(\n { type: 'github', repo: plugin.source.repo, ref: plugin.source.ref },\n tempDir,\n )\n copyDirectory(tempDir, installDir)\n } finally {\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'url') {\n // URL - fetch via tarball/clone\n const tempDir = join(getMarketplaceDir(), 'temp', Date.now().toString())\n mkdirSync(tempDir, { recursive: true })\n\n try {\n await fetchRepo(\n { type: 'url', url: plugin.source.url, ref: plugin.source.ref },\n tempDir,\n )\n copyDirectory(tempDir, installDir)\n } finally {\n rmSync(tempDir, { recursive: true, force: true })\n }\n } else if (plugin.source.source === 'local') {\n // Local path - resolve and copy or symlink\n const pluginSourcePath = isAbsolute(plugin.source.path)\n ? plugin.source.path\n : resolve(getCwd(), plugin.source.path)\n\n if (!existsSync(pluginSourcePath)) {\n throw new MarketplaceError(\n `Local plugin path does not exist: ${pluginSourcePath}`,\n MarketplaceErrorCode.PLUGIN_NOT_FOUND,\n )\n }\n\n // In dev mode, create symlink for easier development\n // In production mode, copy files for isolation\n if (options?.dev) {\n symlinkDirectory(pluginSourcePath, installDir)\n } else {\n copyDirectory(pluginSourcePath, installDir)\n }\n }\n\n // Create marketplace metadata file to track source\n const metadataPath = join(installDir, '.marketplace-meta.json')\n const metadata = {\n marketplace: marketplace.name,\n plugin: plugin.name,\n installedAt: new Date().toISOString(),\n source: plugin.source,\n }\n writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), 'utf-8')\n\n // Create plugin.json if it doesn't exist (required for plugin discovery)\n const pluginManifestPath = join(installDir, 'plugin.json')\n if (!existsSync(pluginManifestPath)) {\n const pluginManifest = {\n name: plugin.name,\n displayName: plugin.name, // Use name as displayName for marketplace plugins\n version: plugin.version || '1.0.0',\n description: plugin.description || '',\n author: plugin.author,\n license: plugin.license,\n homepage: plugin.homepage,\n repository: plugin.repository,\n keywords: plugin.keywords || [],\n category: plugin.category,\n }\n writeFileSync(\n pluginManifestPath,\n JSON.stringify(pluginManifest, null, 2),\n 'utf-8',\n )\n }\n\n return installDir\n } finally {\n // Clean up marketplace repo if it was cloned\n if (cleanupMarketplaceRepo && marketplaceRepoPath) {\n try {\n rmSync(marketplaceRepoPath, { recursive: true, force: true })\n } catch (error) {\n // Ignore cleanup errors\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }