claudeup 1.8.0 → 3.3.0

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 (301) hide show
  1. package/bin/claudeup.js +20 -2
  2. package/package.json +10 -19
  3. package/src/data/cli-tools.js +123 -0
  4. package/src/data/cli-tools.ts +140 -0
  5. package/{dist → src}/data/marketplaces.js +23 -24
  6. package/src/data/marketplaces.ts +95 -0
  7. package/src/data/mcp-servers.js +509 -0
  8. package/src/data/mcp-servers.ts +526 -0
  9. package/src/data/statuslines.js +159 -0
  10. package/src/data/statuslines.ts +188 -0
  11. package/src/index.js +4 -0
  12. package/src/index.ts +5 -0
  13. package/{dist → src}/main.js +46 -47
  14. package/src/main.tsx +145 -0
  15. package/src/opentui.d.ts +191 -0
  16. package/{dist → src}/prerunner/index.js +31 -41
  17. package/src/prerunner/index.ts +124 -0
  18. package/{dist → src}/services/claude-runner.js +9 -10
  19. package/src/services/claude-runner.ts +31 -0
  20. package/{dist → src}/services/claude-settings.js +72 -33
  21. package/src/services/claude-settings.ts +934 -0
  22. package/src/services/local-marketplace.js +339 -0
  23. package/src/services/local-marketplace.ts +489 -0
  24. package/{dist → src}/services/mcp-registry.js +13 -14
  25. package/src/services/mcp-registry.ts +105 -0
  26. package/{dist → src}/services/plugin-manager.js +61 -13
  27. package/src/services/plugin-manager.ts +693 -0
  28. package/{dist → src}/services/plugin-mcp-config.js +19 -18
  29. package/src/services/plugin-mcp-config.ts +242 -0
  30. package/{dist → src}/services/update-cache.js +0 -1
  31. package/src/services/update-cache.ts +78 -0
  32. package/{dist → src}/services/version-check.js +15 -14
  33. package/src/services/version-check.ts +122 -0
  34. package/src/types/index.js +1 -0
  35. package/src/types/index.ts +141 -0
  36. package/src/ui/App.js +213 -0
  37. package/src/ui/App.tsx +359 -0
  38. package/src/ui/components/CategoryHeader.js +9 -0
  39. package/src/ui/components/CategoryHeader.tsx +41 -0
  40. package/{dist → src}/ui/components/ScrollableList.js +19 -6
  41. package/src/ui/components/ScrollableList.tsx +98 -0
  42. package/src/ui/components/SearchInput.js +19 -0
  43. package/src/ui/components/SearchInput.tsx +56 -0
  44. package/src/ui/components/StyledText.js +39 -0
  45. package/src/ui/components/StyledText.tsx +70 -0
  46. package/src/ui/components/TabBar.js +38 -0
  47. package/src/ui/components/TabBar.tsx +88 -0
  48. package/src/ui/components/layout/Panel.js +6 -0
  49. package/src/ui/components/layout/Panel.tsx +62 -0
  50. package/src/ui/components/layout/ProgressBar.js +14 -0
  51. package/src/ui/components/layout/ProgressBar.tsx +47 -0
  52. package/src/ui/components/layout/ScopeTabs.js +6 -0
  53. package/src/ui/components/layout/ScopeTabs.tsx +53 -0
  54. package/src/ui/components/layout/ScreenLayout.js +21 -0
  55. package/src/ui/components/layout/ScreenLayout.tsx +147 -0
  56. package/src/ui/components/layout/index.js +4 -0
  57. package/src/ui/components/layout/index.ts +4 -0
  58. package/src/ui/components/modals/ConfirmModal.js +14 -0
  59. package/src/ui/components/modals/ConfirmModal.tsx +59 -0
  60. package/src/ui/components/modals/InputModal.js +16 -0
  61. package/src/ui/components/modals/InputModal.tsx +68 -0
  62. package/src/ui/components/modals/LoadingModal.js +14 -0
  63. package/src/ui/components/modals/LoadingModal.tsx +40 -0
  64. package/src/ui/components/modals/MessageModal.js +16 -0
  65. package/src/ui/components/modals/MessageModal.tsx +64 -0
  66. package/src/ui/components/modals/ModalContainer.js +56 -0
  67. package/src/ui/components/modals/ModalContainer.tsx +104 -0
  68. package/src/ui/components/modals/SelectModal.js +26 -0
  69. package/src/ui/components/modals/SelectModal.tsx +82 -0
  70. package/src/ui/components/modals/index.js +6 -0
  71. package/src/ui/components/modals/index.ts +6 -0
  72. package/src/ui/hooks/index.js +3 -0
  73. package/src/ui/hooks/index.ts +3 -0
  74. package/{dist → src}/ui/hooks/useAsyncData.js +21 -22
  75. package/src/ui/hooks/useAsyncData.ts +127 -0
  76. package/src/ui/hooks/useKeyboard.js +13 -0
  77. package/src/ui/hooks/useKeyboard.ts +26 -0
  78. package/src/ui/hooks/useKeyboardHandler.js +39 -0
  79. package/src/ui/hooks/useKeyboardHandler.ts +63 -0
  80. package/{dist → src}/ui/screens/CliToolsScreen.js +60 -54
  81. package/src/ui/screens/CliToolsScreen.tsx +468 -0
  82. package/src/ui/screens/EnvVarsScreen.js +154 -0
  83. package/src/ui/screens/EnvVarsScreen.tsx +269 -0
  84. package/{dist → src}/ui/screens/McpRegistryScreen.js +56 -55
  85. package/src/ui/screens/McpRegistryScreen.tsx +331 -0
  86. package/{dist → src}/ui/screens/McpScreen.js +46 -47
  87. package/src/ui/screens/McpScreen.tsx +392 -0
  88. package/src/ui/screens/ModelSelectorScreen.js +292 -0
  89. package/src/ui/screens/ModelSelectorScreen.tsx +441 -0
  90. package/{dist → src}/ui/screens/PluginsScreen.js +305 -293
  91. package/src/ui/screens/PluginsScreen.tsx +1231 -0
  92. package/src/ui/screens/StatusLineScreen.js +200 -0
  93. package/src/ui/screens/StatusLineScreen.tsx +411 -0
  94. package/src/ui/screens/index.js +7 -0
  95. package/src/ui/screens/index.ts +7 -0
  96. package/src/ui/state/AnimationContext.js +34 -0
  97. package/src/ui/state/AnimationContext.tsx +76 -0
  98. package/{dist → src}/ui/state/AppContext.js +31 -32
  99. package/src/ui/state/AppContext.tsx +235 -0
  100. package/{dist → src}/ui/state/DimensionsContext.js +16 -17
  101. package/src/ui/state/DimensionsContext.tsx +144 -0
  102. package/{dist → src}/ui/state/reducer.js +89 -90
  103. package/src/ui/state/reducer.ts +467 -0
  104. package/src/ui/state/types.js +1 -0
  105. package/src/ui/state/types.ts +273 -0
  106. package/{dist → src}/utils/command-utils.js +3 -4
  107. package/src/utils/command-utils.ts +20 -0
  108. package/{dist → src}/utils/fuzzy-search.js +2 -3
  109. package/src/utils/fuzzy-search.ts +138 -0
  110. package/{dist → src}/utils/string-utils.js +6 -6
  111. package/src/utils/string-utils.ts +88 -0
  112. package/dist/data/cli-tools.d.ts +0 -13
  113. package/dist/data/cli-tools.d.ts.map +0 -1
  114. package/dist/data/cli-tools.js +0 -124
  115. package/dist/data/cli-tools.js.map +0 -1
  116. package/dist/data/marketplaces.d.ts +0 -6
  117. package/dist/data/marketplaces.d.ts.map +0 -1
  118. package/dist/data/marketplaces.js.map +0 -1
  119. package/dist/data/mcp-servers.d.ts +0 -8
  120. package/dist/data/mcp-servers.d.ts.map +0 -1
  121. package/dist/data/mcp-servers.js +0 -503
  122. package/dist/data/mcp-servers.js.map +0 -1
  123. package/dist/data/statuslines.d.ts +0 -10
  124. package/dist/data/statuslines.d.ts.map +0 -1
  125. package/dist/data/statuslines.js +0 -160
  126. package/dist/data/statuslines.js.map +0 -1
  127. package/dist/index.d.ts +0 -3
  128. package/dist/index.d.ts.map +0 -1
  129. package/dist/index.js +0 -90
  130. package/dist/index.js.map +0 -1
  131. package/dist/main.d.ts +0 -3
  132. package/dist/main.d.ts.map +0 -1
  133. package/dist/main.js.map +0 -1
  134. package/dist/prerunner/index.d.ts +0 -7
  135. package/dist/prerunner/index.d.ts.map +0 -1
  136. package/dist/prerunner/index.js.map +0 -1
  137. package/dist/services/claude-runner.d.ts +0 -7
  138. package/dist/services/claude-runner.d.ts.map +0 -1
  139. package/dist/services/claude-runner.js.map +0 -1
  140. package/dist/services/claude-settings.d.ts +0 -73
  141. package/dist/services/claude-settings.d.ts.map +0 -1
  142. package/dist/services/claude-settings.js.map +0 -1
  143. package/dist/services/local-marketplace.d.ts +0 -111
  144. package/dist/services/local-marketplace.d.ts.map +0 -1
  145. package/dist/services/local-marketplace.js +0 -599
  146. package/dist/services/local-marketplace.js.map +0 -1
  147. package/dist/services/mcp-registry.d.ts +0 -10
  148. package/dist/services/mcp-registry.d.ts.map +0 -1
  149. package/dist/services/mcp-registry.js.map +0 -1
  150. package/dist/services/plugin-manager.d.ts +0 -65
  151. package/dist/services/plugin-manager.d.ts.map +0 -1
  152. package/dist/services/plugin-manager.js.map +0 -1
  153. package/dist/services/plugin-mcp-config.d.ts +0 -52
  154. package/dist/services/plugin-mcp-config.d.ts.map +0 -1
  155. package/dist/services/plugin-mcp-config.js.map +0 -1
  156. package/dist/services/update-cache.d.ts +0 -21
  157. package/dist/services/update-cache.d.ts.map +0 -1
  158. package/dist/services/update-cache.js.map +0 -1
  159. package/dist/services/version-check.d.ts +0 -20
  160. package/dist/services/version-check.d.ts.map +0 -1
  161. package/dist/services/version-check.js.map +0 -1
  162. package/dist/types/index.d.ts +0 -105
  163. package/dist/types/index.d.ts.map +0 -1
  164. package/dist/types/index.js +0 -2
  165. package/dist/types/index.js.map +0 -1
  166. package/dist/ui/InkApp.d.ts +0 -5
  167. package/dist/ui/InkApp.d.ts.map +0 -1
  168. package/dist/ui/InkApp.js +0 -188
  169. package/dist/ui/InkApp.js.map +0 -1
  170. package/dist/ui/components/CategoryHeader.d.ts +0 -16
  171. package/dist/ui/components/CategoryHeader.d.ts.map +0 -1
  172. package/dist/ui/components/CategoryHeader.js +0 -11
  173. package/dist/ui/components/CategoryHeader.js.map +0 -1
  174. package/dist/ui/components/ScrollableList.d.ts +0 -16
  175. package/dist/ui/components/ScrollableList.d.ts.map +0 -1
  176. package/dist/ui/components/ScrollableList.js.map +0 -1
  177. package/dist/ui/components/SearchInput.d.ts +0 -18
  178. package/dist/ui/components/SearchInput.d.ts.map +0 -1
  179. package/dist/ui/components/SearchInput.js +0 -30
  180. package/dist/ui/components/SearchInput.js.map +0 -1
  181. package/dist/ui/components/TabBar.d.ts +0 -8
  182. package/dist/ui/components/TabBar.d.ts.map +0 -1
  183. package/dist/ui/components/TabBar.js +0 -18
  184. package/dist/ui/components/TabBar.js.map +0 -1
  185. package/dist/ui/components/layout/Footer.d.ts +0 -14
  186. package/dist/ui/components/layout/Footer.d.ts.map +0 -1
  187. package/dist/ui/components/layout/Footer.js +0 -23
  188. package/dist/ui/components/layout/Footer.js.map +0 -1
  189. package/dist/ui/components/layout/Header.d.ts +0 -4
  190. package/dist/ui/components/layout/Header.d.ts.map +0 -1
  191. package/dist/ui/components/layout/Header.js +0 -25
  192. package/dist/ui/components/layout/Header.js.map +0 -1
  193. package/dist/ui/components/layout/Panel.d.ts +0 -22
  194. package/dist/ui/components/layout/Panel.d.ts.map +0 -1
  195. package/dist/ui/components/layout/Panel.js +0 -8
  196. package/dist/ui/components/layout/Panel.js.map +0 -1
  197. package/dist/ui/components/layout/ProgressBar.d.ts +0 -12
  198. package/dist/ui/components/layout/ProgressBar.d.ts.map +0 -1
  199. package/dist/ui/components/layout/ProgressBar.js +0 -16
  200. package/dist/ui/components/layout/ProgressBar.js.map +0 -1
  201. package/dist/ui/components/layout/ScopeTabs.d.ts +0 -12
  202. package/dist/ui/components/layout/ScopeTabs.d.ts.map +0 -1
  203. package/dist/ui/components/layout/ScopeTabs.js +0 -8
  204. package/dist/ui/components/layout/ScopeTabs.js.map +0 -1
  205. package/dist/ui/components/layout/ScreenLayout.d.ts +0 -30
  206. package/dist/ui/components/layout/ScreenLayout.d.ts.map +0 -1
  207. package/dist/ui/components/layout/ScreenLayout.js +0 -23
  208. package/dist/ui/components/layout/ScreenLayout.js.map +0 -1
  209. package/dist/ui/components/layout/index.d.ts +0 -7
  210. package/dist/ui/components/layout/index.d.ts.map +0 -1
  211. package/dist/ui/components/layout/index.js +0 -7
  212. package/dist/ui/components/layout/index.js.map +0 -1
  213. package/dist/ui/components/modals/ConfirmModal.d.ts +0 -14
  214. package/dist/ui/components/modals/ConfirmModal.d.ts.map +0 -1
  215. package/dist/ui/components/modals/ConfirmModal.js +0 -15
  216. package/dist/ui/components/modals/ConfirmModal.js.map +0 -1
  217. package/dist/ui/components/modals/InputModal.d.ts +0 -16
  218. package/dist/ui/components/modals/InputModal.d.ts.map +0 -1
  219. package/dist/ui/components/modals/InputModal.js +0 -23
  220. package/dist/ui/components/modals/InputModal.js.map +0 -1
  221. package/dist/ui/components/modals/LoadingModal.d.ts +0 -8
  222. package/dist/ui/components/modals/LoadingModal.d.ts.map +0 -1
  223. package/dist/ui/components/modals/LoadingModal.js +0 -8
  224. package/dist/ui/components/modals/LoadingModal.js.map +0 -1
  225. package/dist/ui/components/modals/MessageModal.d.ts +0 -14
  226. package/dist/ui/components/modals/MessageModal.d.ts.map +0 -1
  227. package/dist/ui/components/modals/MessageModal.js +0 -17
  228. package/dist/ui/components/modals/MessageModal.js.map +0 -1
  229. package/dist/ui/components/modals/ModalContainer.d.ts +0 -7
  230. package/dist/ui/components/modals/ModalContainer.d.ts.map +0 -1
  231. package/dist/ui/components/modals/ModalContainer.js +0 -38
  232. package/dist/ui/components/modals/ModalContainer.js.map +0 -1
  233. package/dist/ui/components/modals/SelectModal.d.ts +0 -17
  234. package/dist/ui/components/modals/SelectModal.d.ts.map +0 -1
  235. package/dist/ui/components/modals/SelectModal.js +0 -33
  236. package/dist/ui/components/modals/SelectModal.js.map +0 -1
  237. package/dist/ui/components/modals/index.d.ts +0 -7
  238. package/dist/ui/components/modals/index.d.ts.map +0 -1
  239. package/dist/ui/components/modals/index.js +0 -7
  240. package/dist/ui/components/modals/index.js.map +0 -1
  241. package/dist/ui/hooks/index.d.ts +0 -3
  242. package/dist/ui/hooks/index.d.ts.map +0 -1
  243. package/dist/ui/hooks/index.js +0 -3
  244. package/dist/ui/hooks/index.js.map +0 -1
  245. package/dist/ui/hooks/useAsyncData.d.ts +0 -40
  246. package/dist/ui/hooks/useAsyncData.d.ts.map +0 -1
  247. package/dist/ui/hooks/useAsyncData.js.map +0 -1
  248. package/dist/ui/hooks/useKeyboardNavigation.d.ts +0 -27
  249. package/dist/ui/hooks/useKeyboardNavigation.d.ts.map +0 -1
  250. package/dist/ui/hooks/useKeyboardNavigation.js +0 -82
  251. package/dist/ui/hooks/useKeyboardNavigation.js.map +0 -1
  252. package/dist/ui/screens/CliToolsScreen.d.ts +0 -4
  253. package/dist/ui/screens/CliToolsScreen.d.ts.map +0 -1
  254. package/dist/ui/screens/CliToolsScreen.js.map +0 -1
  255. package/dist/ui/screens/EnvVarsScreen.d.ts +0 -4
  256. package/dist/ui/screens/EnvVarsScreen.d.ts.map +0 -1
  257. package/dist/ui/screens/EnvVarsScreen.js +0 -145
  258. package/dist/ui/screens/EnvVarsScreen.js.map +0 -1
  259. package/dist/ui/screens/McpRegistryScreen.d.ts +0 -4
  260. package/dist/ui/screens/McpRegistryScreen.d.ts.map +0 -1
  261. package/dist/ui/screens/McpRegistryScreen.js.map +0 -1
  262. package/dist/ui/screens/McpScreen.d.ts +0 -4
  263. package/dist/ui/screens/McpScreen.d.ts.map +0 -1
  264. package/dist/ui/screens/McpScreen.js.map +0 -1
  265. package/dist/ui/screens/ModelSelectorScreen.d.ts +0 -4
  266. package/dist/ui/screens/ModelSelectorScreen.d.ts.map +0 -1
  267. package/dist/ui/screens/ModelSelectorScreen.js +0 -143
  268. package/dist/ui/screens/ModelSelectorScreen.js.map +0 -1
  269. package/dist/ui/screens/PluginsScreen.d.ts +0 -4
  270. package/dist/ui/screens/PluginsScreen.d.ts.map +0 -1
  271. package/dist/ui/screens/PluginsScreen.js.map +0 -1
  272. package/dist/ui/screens/StatusLineScreen.d.ts +0 -4
  273. package/dist/ui/screens/StatusLineScreen.d.ts.map +0 -1
  274. package/dist/ui/screens/StatusLineScreen.js +0 -197
  275. package/dist/ui/screens/StatusLineScreen.js.map +0 -1
  276. package/dist/ui/screens/index.d.ts +0 -8
  277. package/dist/ui/screens/index.d.ts.map +0 -1
  278. package/dist/ui/screens/index.js +0 -8
  279. package/dist/ui/screens/index.js.map +0 -1
  280. package/dist/ui/state/AppContext.d.ts +0 -40
  281. package/dist/ui/state/AppContext.d.ts.map +0 -1
  282. package/dist/ui/state/AppContext.js.map +0 -1
  283. package/dist/ui/state/DimensionsContext.d.ts +0 -27
  284. package/dist/ui/state/DimensionsContext.d.ts.map +0 -1
  285. package/dist/ui/state/DimensionsContext.js.map +0 -1
  286. package/dist/ui/state/reducer.d.ts +0 -4
  287. package/dist/ui/state/reducer.d.ts.map +0 -1
  288. package/dist/ui/state/reducer.js.map +0 -1
  289. package/dist/ui/state/types.d.ts +0 -266
  290. package/dist/ui/state/types.d.ts.map +0 -1
  291. package/dist/ui/state/types.js +0 -2
  292. package/dist/ui/state/types.js.map +0 -1
  293. package/dist/utils/command-utils.d.ts +0 -8
  294. package/dist/utils/command-utils.d.ts.map +0 -1
  295. package/dist/utils/command-utils.js.map +0 -1
  296. package/dist/utils/fuzzy-search.d.ts +0 -33
  297. package/dist/utils/fuzzy-search.d.ts.map +0 -1
  298. package/dist/utils/fuzzy-search.js.map +0 -1
  299. package/dist/utils/string-utils.d.ts +0 -24
  300. package/dist/utils/string-utils.d.ts.map +0 -1
  301. package/dist/utils/string-utils.js.map +0 -1
@@ -1,32 +1,46 @@
1
1
  import { UpdateCache } from "../services/update-cache.js";
2
- import { refreshLocalMarketplaces } from "../services/local-marketplace.js";
3
2
  import { getAvailablePlugins, clearMarketplaceCache, saveInstalledPluginVersion, } from "../services/plugin-manager.js";
4
3
  import { runClaude } from "../services/claude-runner.js";
4
+ import { recoverMarketplaceSettings } from "../services/claude-settings.js";
5
5
  /**
6
6
  * Prerun orchestration: Check for updates, apply them, then run claude
7
7
  * @param claudeArgs - Arguments to pass to claude CLI
8
+ * @param options - Prerun options (force, etc.)
8
9
  * @returns Exit code from claude process
9
10
  */
10
- export async function prerunClaude(claudeArgs) {
11
+ export async function prerunClaude(claudeArgs, options = {}) {
11
12
  const cache = new UpdateCache();
12
13
  try {
13
- // STEP 1: Check if we should update (time-based cache)
14
- const shouldUpdate = await cache.shouldCheckForUpdates();
14
+ // STEP 1: Check if we should update (time-based cache, or forced)
15
+ const shouldUpdate = options.force || (await cache.shouldCheckForUpdates());
16
+ if (options.force) {
17
+ console.log("⟳ Forcing plugin update check...");
18
+ }
15
19
  if (shouldUpdate) {
16
- // STEP 2: Refresh all marketplaces (git pull)
17
- const refreshResults = await refreshLocalMarketplaces();
18
- // STEP 3: Clear cache to force fresh plugin info
20
+ // STEP 1.5: Recover marketplace settings (enable autoUpdate, remove stale entries)
21
+ const recovery = await recoverMarketplaceSettings();
22
+ if (recovery.enabledAutoUpdate.length > 0) {
23
+ console.log(`✓ Enabled auto-update for: ${recovery.enabledAutoUpdate.join(", ")}`);
24
+ }
25
+ if (recovery.removed.length > 0) {
26
+ console.log(`✓ Removed stale marketplaces: ${recovery.removed.join(", ")}`);
27
+ }
28
+ // STEP 2: Clear cache to force fresh plugin info
29
+ // Note: Marketplace updates should be done via Claude Code's /plugin marketplace update
19
30
  clearMarketplaceCache();
20
- // STEP 4: Get updated plugin info (to detect versions)
31
+ // STEP 3: Get updated plugin info (to detect versions)
21
32
  const plugins = await getAvailablePlugins();
22
- // STEP 4.5: Auto-update enabled plugins with available updates
33
+ // STEP 4: Auto-update enabled plugins with available updates
23
34
  const autoUpdatedPlugins = [];
24
35
  for (const plugin of plugins) {
25
36
  // Only update if:
26
37
  // 1. Plugin is enabled
27
38
  // 2. Plugin has an update available
28
39
  // 3. Plugin has both installedVersion and version (newVersion)
29
- if (plugin.enabled && plugin.hasUpdate && plugin.installedVersion && plugin.version) {
40
+ if (plugin.enabled &&
41
+ plugin.hasUpdate &&
42
+ plugin.installedVersion &&
43
+ plugin.version) {
30
44
  try {
31
45
  // Save new version - this will:
32
46
  // 1. Update settings.json
@@ -45,39 +59,16 @@ export async function prerunClaude(claudeArgs) {
45
59
  }
46
60
  }
47
61
  }
48
- // STEP 5: Build summary - show all updated plugins (not just enabled)
49
- const updatedMarketplaces = [];
50
- const updatedPlugins = [];
51
- const failed = [];
52
- for (const result of refreshResults) {
53
- if (result.success && result.updated) {
54
- updatedMarketplaces.push(result.name);
55
- // Find ALL plugins from this marketplace (regardless of enabled state)
56
- const mpPlugins = plugins.filter((p) => p.marketplace === result.name);
57
- if (mpPlugins.length > 0) {
58
- updatedPlugins.push(...mpPlugins.map((p) => `${p.name} v${p.version}`));
59
- }
60
- }
61
- else if (!result.success) {
62
- failed.push(`${result.name}${result.error ? ` (${result.error})` : ""}`);
63
- }
64
- }
65
- // STEP 6: Save cache
62
+ // STEP 5: Save cache
66
63
  await cache.saveCheck({
67
64
  lastUpdateCheck: new Date().toISOString(),
68
- lastUpdateResult: { updated: updatedPlugins, failed, autoUpdated: autoUpdatedPlugins },
65
+ lastUpdateResult: {
66
+ updated: [],
67
+ failed: [],
68
+ autoUpdated: autoUpdatedPlugins,
69
+ },
69
70
  });
70
- // STEP 7: Display summary (marketplace-level and plugin-level)
71
- if (updatedMarketplaces.length > 0) {
72
- console.log(`✓ Updated marketplace(s): ${updatedMarketplaces.join(", ")}`);
73
- if (updatedPlugins.length > 0) {
74
- console.log(` Plugins: ${updatedPlugins.join(", ")}`);
75
- }
76
- }
77
- if (failed.length > 0) {
78
- console.warn(`⚠ Failed to update: ${failed.join(", ")}`);
79
- }
80
- // Display auto-update summary
71
+ // STEP 6: Display auto-update summary
81
72
  if (autoUpdatedPlugins.length > 0) {
82
73
  console.log(`✓ Auto-updated ${autoUpdatedPlugins.length} plugin(s):`);
83
74
  for (const { pluginId, oldVersion, newVersion } of autoUpdatedPlugins) {
@@ -94,4 +85,3 @@ export async function prerunClaude(claudeArgs) {
94
85
  // STEP 8: Always run claude (even if update failed)
95
86
  return runClaude(claudeArgs);
96
87
  }
97
- //# sourceMappingURL=index.js.map
@@ -0,0 +1,124 @@
1
+ import { UpdateCache } from "../services/update-cache.js";
2
+ import {
3
+ getAvailablePlugins,
4
+ clearMarketplaceCache,
5
+ saveInstalledPluginVersion,
6
+ } from "../services/plugin-manager.js";
7
+ import { runClaude } from "../services/claude-runner.js";
8
+ import { recoverMarketplaceSettings } from "../services/claude-settings.js";
9
+
10
+ export interface PrerunOptions {
11
+ force?: boolean; // Bypass cache and force update check
12
+ }
13
+
14
+ /**
15
+ * Prerun orchestration: Check for updates, apply them, then run claude
16
+ * @param claudeArgs - Arguments to pass to claude CLI
17
+ * @param options - Prerun options (force, etc.)
18
+ * @returns Exit code from claude process
19
+ */
20
+ export async function prerunClaude(
21
+ claudeArgs: string[],
22
+ options: PrerunOptions = {},
23
+ ): Promise<number> {
24
+ const cache = new UpdateCache();
25
+
26
+ try {
27
+ // STEP 1: Check if we should update (time-based cache, or forced)
28
+ const shouldUpdate = options.force || (await cache.shouldCheckForUpdates());
29
+
30
+ if (options.force) {
31
+ console.log("⟳ Forcing plugin update check...");
32
+ }
33
+
34
+ if (shouldUpdate) {
35
+ // STEP 1.5: Recover marketplace settings (enable autoUpdate, remove stale entries)
36
+ const recovery = await recoverMarketplaceSettings();
37
+ if (recovery.enabledAutoUpdate.length > 0) {
38
+ console.log(
39
+ `✓ Enabled auto-update for: ${recovery.enabledAutoUpdate.join(", ")}`,
40
+ );
41
+ }
42
+ if (recovery.removed.length > 0) {
43
+ console.log(
44
+ `✓ Removed stale marketplaces: ${recovery.removed.join(", ")}`,
45
+ );
46
+ }
47
+
48
+ // STEP 2: Clear cache to force fresh plugin info
49
+ // Note: Marketplace updates should be done via Claude Code's /plugin marketplace update
50
+ clearMarketplaceCache();
51
+
52
+ // STEP 3: Get updated plugin info (to detect versions)
53
+ const plugins = await getAvailablePlugins();
54
+
55
+ // STEP 4: Auto-update enabled plugins with available updates
56
+ const autoUpdatedPlugins: Array<{
57
+ pluginId: string;
58
+ oldVersion: string;
59
+ newVersion: string;
60
+ }> = [];
61
+
62
+ for (const plugin of plugins) {
63
+ // Only update if:
64
+ // 1. Plugin is enabled
65
+ // 2. Plugin has an update available
66
+ // 3. Plugin has both installedVersion and version (newVersion)
67
+ if (
68
+ plugin.enabled &&
69
+ plugin.hasUpdate &&
70
+ plugin.installedVersion &&
71
+ plugin.version
72
+ ) {
73
+ try {
74
+ // Save new version - this will:
75
+ // 1. Update settings.json
76
+ // 2. Call updateInstalledPluginsRegistry()
77
+ // 3. Copy plugin files to cache (via copyPluginToCache())
78
+ await saveInstalledPluginVersion(plugin.id, plugin.version);
79
+
80
+ autoUpdatedPlugins.push({
81
+ pluginId: plugin.id,
82
+ oldVersion: plugin.installedVersion,
83
+ newVersion: plugin.version,
84
+ });
85
+ } catch (error) {
86
+ // Non-fatal: Log warning and continue
87
+ console.warn(
88
+ `⚠ Failed to auto-update ${plugin.id}:`,
89
+ error instanceof Error ? error.message : "Unknown error",
90
+ );
91
+ }
92
+ }
93
+ }
94
+
95
+ // STEP 5: Save cache
96
+ await cache.saveCheck({
97
+ lastUpdateCheck: new Date().toISOString(),
98
+ lastUpdateResult: {
99
+ updated: [],
100
+ failed: [],
101
+ autoUpdated: autoUpdatedPlugins,
102
+ },
103
+ });
104
+
105
+ // STEP 6: Display auto-update summary
106
+ if (autoUpdatedPlugins.length > 0) {
107
+ console.log(`✓ Auto-updated ${autoUpdatedPlugins.length} plugin(s):`);
108
+ for (const { pluginId, oldVersion, newVersion } of autoUpdatedPlugins) {
109
+ console.log(` - ${pluginId}: ${oldVersion} → ${newVersion}`);
110
+ }
111
+ }
112
+ }
113
+ // If !shouldUpdate → silent (no output)
114
+ } catch (error) {
115
+ // Non-fatal errors - warn and continue
116
+ console.warn(
117
+ "Warning: Plugin update check failed:",
118
+ error instanceof Error ? error.message : "Unknown error",
119
+ );
120
+ }
121
+
122
+ // STEP 8: Always run claude (even if update failed)
123
+ return runClaude(claudeArgs);
124
+ }
@@ -1,5 +1,5 @@
1
- import { spawn } from 'node:child_process';
2
- import { which } from '../utils/command-utils.js';
1
+ import { spawn } from "node:child_process";
2
+ import { which } from "../utils/command-utils.js";
3
3
  /**
4
4
  * Execute claude CLI with provided arguments
5
5
  * @param args - Arguments to pass to claude
@@ -7,23 +7,22 @@ import { which } from '../utils/command-utils.js';
7
7
  */
8
8
  export async function runClaude(args) {
9
9
  // Check if claude exists
10
- const claudePath = await which('claude');
10
+ const claudePath = await which("claude");
11
11
  if (!claudePath) {
12
- console.error('Error: claude CLI not found in PATH');
13
- console.error('Install with: npm install -g @anthropic-ai/claude-code');
12
+ console.error("Error: claude CLI not found in PATH");
13
+ console.error("Install with: npm install -g @anthropic-ai/claude-code");
14
14
  return 1;
15
15
  }
16
16
  // Spawn claude with full TTY inheritance using the resolved path
17
17
  return new Promise((resolve) => {
18
18
  const proc = spawn(claudePath, args, {
19
- stdio: 'inherit', // Pass through stdin, stdout, stderr
19
+ stdio: "inherit", // Pass through stdin, stdout, stderr
20
20
  shell: false, // Use full path, no shell needed (fixes DEP0190)
21
21
  });
22
- proc.on('exit', (code) => resolve(code || 0));
23
- proc.on('error', (err) => {
24
- console.error('Failed to run claude:', err.message);
22
+ proc.on("exit", (code) => resolve(code || 0));
23
+ proc.on("error", (err) => {
24
+ console.error("Failed to run claude:", err.message);
25
25
  resolve(1);
26
26
  });
27
27
  });
28
28
  }
29
- //# sourceMappingURL=claude-runner.js.map
@@ -0,0 +1,31 @@
1
+ import { spawn } from "node:child_process";
2
+ import { which } from "../utils/command-utils.js";
3
+
4
+ /**
5
+ * Execute claude CLI with provided arguments
6
+ * @param args - Arguments to pass to claude
7
+ * @returns Exit code from claude process
8
+ */
9
+ export async function runClaude(args: string[]): Promise<number> {
10
+ // Check if claude exists
11
+ const claudePath = await which("claude");
12
+ if (!claudePath) {
13
+ console.error("Error: claude CLI not found in PATH");
14
+ console.error("Install with: npm install -g @anthropic-ai/claude-code");
15
+ return 1;
16
+ }
17
+
18
+ // Spawn claude with full TTY inheritance using the resolved path
19
+ return new Promise((resolve) => {
20
+ const proc = spawn(claudePath, args, {
21
+ stdio: "inherit", // Pass through stdin, stdout, stderr
22
+ shell: false, // Use full path, no shell needed (fixes DEP0190)
23
+ });
24
+
25
+ proc.on("exit", (code) => resolve(code || 0));
26
+ proc.on("error", (err) => {
27
+ console.error("Failed to run claude:", err.message);
28
+ resolve(1);
29
+ });
30
+ });
31
+ }
@@ -148,22 +148,10 @@ export async function setAllowMcp(_allow, _projectPath) {
148
148
  // .mcp.json doesn't have an allowMcp setting - servers are either in the file or not
149
149
  // This function is kept for API compatibility but is now a no-op
150
150
  }
151
- // Marketplace management
152
- export async function addMarketplace(marketplace, projectPath) {
153
- const settings = await readSettings(projectPath);
154
- settings.extraKnownMarketplaces = settings.extraKnownMarketplaces || {};
155
- settings.extraKnownMarketplaces[marketplace.name] = {
156
- source: marketplace.source,
157
- };
158
- await writeSettings(settings, projectPath);
159
- }
160
- export async function removeMarketplace(name, projectPath) {
161
- const settings = await readSettings(projectPath);
162
- if (settings.extraKnownMarketplaces) {
163
- delete settings.extraKnownMarketplaces[name];
164
- }
165
- await writeSettings(settings, projectPath);
166
- }
151
+ // Marketplace management - READ ONLY
152
+ // Use Claude Code CLI commands to add/remove marketplaces:
153
+ // claude marketplace add owner/repo
154
+ // claude marketplace remove name
167
155
  // Plugin management
168
156
  export async function enablePlugin(pluginId, enabled, projectPath) {
169
157
  const settings = await readSettings(projectPath);
@@ -286,22 +274,8 @@ export async function getConfiguredMarketplaces(projectPath) {
286
274
  const settings = await readSettings(projectPath);
287
275
  return settings.extraKnownMarketplaces || {};
288
276
  }
289
- // Global marketplace management
290
- export async function addGlobalMarketplace(marketplace) {
291
- const settings = await readGlobalSettings();
292
- settings.extraKnownMarketplaces = settings.extraKnownMarketplaces || {};
293
- settings.extraKnownMarketplaces[marketplace.name] = {
294
- source: marketplace.source,
295
- };
296
- await writeGlobalSettings(settings);
297
- }
298
- export async function removeGlobalMarketplace(name) {
299
- const settings = await readGlobalSettings();
300
- if (settings.extraKnownMarketplaces) {
301
- delete settings.extraKnownMarketplaces[name];
302
- }
303
- await writeGlobalSettings(settings);
304
- }
277
+ // Global marketplace management - READ ONLY
278
+ // Marketplaces are managed via Claude Code's native system
305
279
  export async function getGlobalConfiguredMarketplaces() {
306
280
  const settings = await readGlobalSettings();
307
281
  return settings.extraKnownMarketplaces || {};
@@ -397,6 +371,72 @@ export async function discoverAllGlobalMarketplaces() {
397
371
  // installed_plugins.json registry management
398
372
  const INSTALLED_PLUGINS_FILE = path.join(os.homedir(), ".claude", "plugins", "installed_plugins.json");
399
373
  const KNOWN_MARKETPLACES_FILE = path.join(os.homedir(), ".claude", "plugins", "known_marketplaces.json");
374
+ /**
375
+ * Write known_marketplaces.json
376
+ */
377
+ async function writeKnownMarketplaces(marketplaces) {
378
+ await fs.ensureDir(path.dirname(KNOWN_MARKETPLACES_FILE));
379
+ await fs.writeJson(KNOWN_MARKETPLACES_FILE, marketplaces, { spaces: 2 });
380
+ }
381
+ /**
382
+ * Set autoUpdate flag for a marketplace in known_marketplaces.json
383
+ * This is where Claude Code actually reads the autoUpdate setting
384
+ */
385
+ export async function setMarketplaceAutoUpdate(marketplaceName, autoUpdate) {
386
+ const known = await readKnownMarketplaces();
387
+ if (known[marketplaceName]) {
388
+ known[marketplaceName].autoUpdate = autoUpdate;
389
+ await writeKnownMarketplaces(known);
390
+ return true;
391
+ }
392
+ return false; // Marketplace not yet installed by Claude Code
393
+ }
394
+ /**
395
+ * Get autoUpdate status for a marketplace
396
+ */
397
+ export async function getMarketplaceAutoUpdate(marketplaceName) {
398
+ const known = await readKnownMarketplaces();
399
+ return known[marketplaceName]?.autoUpdate;
400
+ }
401
+ /**
402
+ * Check if a marketplace is from MadAppGang
403
+ */
404
+ function isMadAppGangMarketplace(entry) {
405
+ const repo = entry.source?.repo?.toLowerCase() || "";
406
+ return repo.includes("madappgang");
407
+ }
408
+ /**
409
+ * Recover/sync marketplace settings:
410
+ * - Enable autoUpdate for MadAppGang marketplaces that don't have it set
411
+ * - Remove entries for marketplaces whose installLocation no longer exists
412
+ */
413
+ export async function recoverMarketplaceSettings() {
414
+ const known = await readKnownMarketplaces();
415
+ const result = {
416
+ enabledAutoUpdate: [],
417
+ removed: [],
418
+ };
419
+ const updatedKnown = {};
420
+ for (const [name, entry] of Object.entries(known)) {
421
+ // Check if install location still exists
422
+ if (entry.installLocation &&
423
+ !(await fs.pathExists(entry.installLocation))) {
424
+ result.removed.push(name);
425
+ continue;
426
+ }
427
+ // Enable autoUpdate if not set - only for MadAppGang marketplaces
428
+ if (entry.autoUpdate === undefined && isMadAppGangMarketplace(entry)) {
429
+ entry.autoUpdate = true;
430
+ result.enabledAutoUpdate.push(name);
431
+ }
432
+ updatedKnown[name] = entry;
433
+ }
434
+ // Write back if any changes were made
435
+ if (result.enabledAutoUpdate.length > 0 || result.removed.length > 0) {
436
+ await writeKnownMarketplaces(updatedKnown);
437
+ }
438
+ return result;
439
+ }
400
440
  /**
401
441
  * Read known_marketplaces.json to get marketplace source info
402
442
  */
@@ -604,4 +644,3 @@ export async function removeFromInstalledPluginsRegistry(pluginId, scope, projec
604
644
  console.warn(`Failed to remove from registry for ${pluginId}:`, error instanceof Error ? error.message : "Unknown error");
605
645
  }
606
646
  }
607
- //# sourceMappingURL=claude-settings.js.map