@mastra/code-sdk 1.0.3-alpha.1 → 1.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/acp/agent.js +155 -167
  3. package/dist/acp/agent.js.map +1 -1
  4. package/dist/acp/event-mapper.js +193 -168
  5. package/dist/acp/event-mapper.js.map +1 -1
  6. package/dist/acp/index.js +60 -49
  7. package/dist/acp/index.js.map +1 -1
  8. package/dist/acp/server.js +31 -30
  9. package/dist/acp/server.js.map +1 -1
  10. package/dist/acp.js +1 -4
  11. package/dist/agents/credential-resolver.js +40 -29
  12. package/dist/agents/credential-resolver.js.map +1 -1
  13. package/dist/agents/custom-provider-source.js +16 -9
  14. package/dist/agents/custom-provider-source.js.map +1 -1
  15. package/dist/agents/instructions.js +27 -36
  16. package/dist/agents/instructions.js.map +1 -1
  17. package/dist/agents/mastracode-gateway.js +355 -428
  18. package/dist/agents/mastracode-gateway.js.map +1 -1
  19. package/dist/agents/memory.js +87 -78
  20. package/dist/agents/memory.js.map +1 -1
  21. package/dist/agents/model.js +114 -119
  22. package/dist/agents/model.js.map +1 -1
  23. package/dist/agents/modes/build.js +12 -13
  24. package/dist/agents/modes/build.js.map +1 -1
  25. package/dist/agents/modes/explore.js +14 -13
  26. package/dist/agents/modes/explore.js.map +1 -1
  27. package/dist/agents/modes/plan.js +14 -15
  28. package/dist/agents/modes/plan.js.map +1 -1
  29. package/dist/agents/prompts/agent-instructions.js +78 -69
  30. package/dist/agents/prompts/agent-instructions.js.map +1 -1
  31. package/dist/agents/prompts/build.js +19 -16
  32. package/dist/agents/prompts/build.js.map +1 -1
  33. package/dist/agents/prompts/fast.js +8 -4
  34. package/dist/agents/prompts/fast.js.map +1 -1
  35. package/dist/agents/prompts/index.js +48 -47
  36. package/dist/agents/prompts/index.js.map +1 -1
  37. package/dist/agents/prompts/model.js +6 -5
  38. package/dist/agents/prompts/model.js.map +1 -1
  39. package/dist/agents/prompts/plan.js +20 -16
  40. package/dist/agents/prompts/plan.js.map +1 -1
  41. package/dist/agents/prompts/tool-guidance.js +77 -109
  42. package/dist/agents/prompts/tool-guidance.js.map +1 -1
  43. package/dist/agents/sandbox-filesystem.js +245 -259
  44. package/dist/agents/sandbox-filesystem.js.map +1 -1
  45. package/dist/agents/sandbox-reattach.js +9 -11
  46. package/dist/agents/sandbox-reattach.js.map +1 -1
  47. package/dist/agents/thread-caveman-state.js +92 -81
  48. package/dist/agents/thread-caveman-state.js.map +1 -1
  49. package/dist/agents/tool-availability.js +62 -80
  50. package/dist/agents/tool-availability.js.map +1 -1
  51. package/dist/agents/tools.js +99 -139
  52. package/dist/agents/tools.js.map +1 -1
  53. package/dist/agents/workspace.js +232 -225
  54. package/dist/agents/workspace.js.map +1 -1
  55. package/dist/analytics.js +139 -128
  56. package/dist/analytics.js.map +1 -1
  57. package/dist/auth/authorization-input.js +39 -25
  58. package/dist/auth/authorization-input.js.map +1 -1
  59. package/dist/auth/device-code.js +112 -80
  60. package/dist/auth/device-code.js.map +1 -1
  61. package/dist/auth/index.js +2 -9
  62. package/dist/auth/pkce.js +27 -16
  63. package/dist/auth/pkce.js.map +1 -1
  64. package/dist/auth/providers/anthropic.js +107 -93
  65. package/dist/auth/providers/anthropic.js.map +1 -1
  66. package/dist/auth/providers/github-copilot.js +304 -293
  67. package/dist/auth/providers/github-copilot.js.map +1 -1
  68. package/dist/auth/providers/openai-codex.js +442 -460
  69. package/dist/auth/providers/openai-codex.js.map +1 -1
  70. package/dist/auth/providers/xai.js +179 -145
  71. package/dist/auth/providers/xai.js.map +1 -1
  72. package/dist/auth/storage.js +182 -175
  73. package/dist/auth/storage.js.map +1 -1
  74. package/dist/auth/types.js +1 -1
  75. package/dist/clipboard/index.js +206 -172
  76. package/dist/clipboard/index.js.map +1 -1
  77. package/dist/constants.js +11 -16
  78. package/dist/constants.js.map +1 -1
  79. package/dist/error-classification.js +19 -11
  80. package/dist/error-classification.js.map +1 -1
  81. package/dist/evals/context-builder.js +145 -104
  82. package/dist/evals/context-builder.js.map +1 -1
  83. package/dist/evals/index.js +4 -7
  84. package/dist/evals/scorers/classify-command.js +62 -41
  85. package/dist/evals/scorers/classify-command.js.map +1 -1
  86. package/dist/evals/scorers/efficiency.js +239 -181
  87. package/dist/evals/scorers/efficiency.js.map +1 -1
  88. package/dist/evals/scorers/extract-tools.js +51 -47
  89. package/dist/evals/scorers/extract-tools.js.map +1 -1
  90. package/dist/evals/scorers/index.js +1 -5
  91. package/dist/evals/scorers/outcome.js +321 -212
  92. package/dist/evals/scorers/outcome.js.map +1 -1
  93. package/dist/goal-manager.js +266 -261
  94. package/dist/goal-manager.js.map +1 -1
  95. package/dist/goal-signal.js +14 -13
  96. package/dist/goal-signal.js.map +1 -1
  97. package/dist/headless/cli.js +153 -154
  98. package/dist/headless/cli.js.map +1 -1
  99. package/dist/headless/flags.js +180 -178
  100. package/dist/headless/flags.js.map +1 -1
  101. package/dist/headless/format.js +72 -71
  102. package/dist/headless/format.js.map +1 -1
  103. package/dist/headless/index.js +5 -31
  104. package/dist/headless/policy.js +35 -31
  105. package/dist/headless/policy.js.map +1 -1
  106. package/dist/headless/run-mc.js +332 -334
  107. package/dist/headless/run-mc.js.map +1 -1
  108. package/dist/headless/types.js +16 -7
  109. package/dist/headless/types.js.map +1 -1
  110. package/dist/hooks/config.js +56 -61
  111. package/dist/hooks/config.js.map +1 -1
  112. package/dist/hooks/executor.js +118 -116
  113. package/dist/hooks/executor.js.map +1 -1
  114. package/dist/hooks/index.js +4 -15
  115. package/dist/hooks/manager.js +221 -280
  116. package/dist/hooks/manager.js.map +1 -1
  117. package/dist/hooks/types.js +5 -4
  118. package/dist/hooks/types.js.map +1 -1
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +632 -712
  121. package/dist/index.js.map +1 -1
  122. package/dist/ipc/ipc-reporter.js +19 -22
  123. package/dist/ipc/ipc-reporter.js.map +1 -1
  124. package/dist/lsp/client.js +248 -306
  125. package/dist/lsp/client.js.map +1 -1
  126. package/dist/lsp/index.js +1 -6
  127. package/dist/lsp/language.js +39 -43
  128. package/dist/lsp/language.js.map +1 -1
  129. package/dist/lsp/manager.js +78 -93
  130. package/dist/lsp/manager.js.map +1 -1
  131. package/dist/lsp/server.js +151 -120
  132. package/dist/lsp/server.js.map +1 -1
  133. package/dist/lsp/workspace.js +50 -47
  134. package/dist/lsp/workspace.js.map +1 -1
  135. package/dist/mcp/config.js +210 -199
  136. package/dist/mcp/config.js.map +1 -1
  137. package/dist/mcp/index.js +2 -9
  138. package/dist/mcp/manager.js +482 -475
  139. package/dist/mcp/manager.js.map +1 -1
  140. package/dist/mcp/types.js +1 -1
  141. package/dist/onboarding/custom-packs.js +14 -17
  142. package/dist/onboarding/custom-packs.js.map +1 -1
  143. package/dist/onboarding/custom-providers.js +22 -20
  144. package/dist/onboarding/custom-providers.js.map +1 -1
  145. package/dist/onboarding/index.d.ts +1 -1
  146. package/dist/onboarding/index.d.ts.map +1 -1
  147. package/dist/onboarding/index.js +3 -21
  148. package/dist/onboarding/om-settings.d.ts +5 -0
  149. package/dist/onboarding/om-settings.d.ts.map +1 -1
  150. package/dist/onboarding/om-settings.js +41 -20
  151. package/dist/onboarding/om-settings.js.map +1 -1
  152. package/dist/onboarding/packs.d.ts +4 -6
  153. package/dist/onboarding/packs.d.ts.map +1 -1
  154. package/dist/onboarding/packs.js +154 -105
  155. package/dist/onboarding/packs.js.map +1 -1
  156. package/dist/onboarding/settings.js +575 -517
  157. package/dist/onboarding/settings.js.map +1 -1
  158. package/dist/permissions.js +112 -99
  159. package/dist/permissions.js.map +1 -1
  160. package/dist/plugin.js +21 -23
  161. package/dist/plugin.js.map +1 -1
  162. package/dist/plugins/dependencies.js +64 -87
  163. package/dist/plugins/dependencies.js.map +1 -1
  164. package/dist/plugins/install.js +159 -169
  165. package/dist/plugins/install.js.map +1 -1
  166. package/dist/plugins/loader.js +170 -185
  167. package/dist/plugins/loader.js.map +1 -1
  168. package/dist/plugins/manager.js +374 -380
  169. package/dist/plugins/manager.js.map +1 -1
  170. package/dist/plugins/manifest.js +38 -63
  171. package/dist/plugins/manifest.js.map +1 -1
  172. package/dist/plugins/package-link.js +48 -64
  173. package/dist/plugins/package-link.js.map +1 -1
  174. package/dist/plugins/paths.js +18 -19
  175. package/dist/plugins/paths.js.map +1 -1
  176. package/dist/plugins/registry.js +97 -81
  177. package/dist/plugins/registry.js.map +1 -1
  178. package/dist/plugins/scaffold.js +62 -98
  179. package/dist/plugins/scaffold.js.map +1 -1
  180. package/dist/plugins/types.js +1 -1
  181. package/dist/processors/plan-rejection-abort.js +45 -44
  182. package/dist/processors/plan-rejection-abort.js.map +1 -1
  183. package/dist/providers/amazon-bedrock-gateway.js +134 -125
  184. package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
  185. package/dist/providers/amazon-bedrock.js +68 -47
  186. package/dist/providers/amazon-bedrock.js.map +1 -1
  187. package/dist/providers/claude-max.js +153 -133
  188. package/dist/providers/claude-max.js.map +1 -1
  189. package/dist/providers/github-copilot.js +232 -230
  190. package/dist/providers/github-copilot.js.map +1 -1
  191. package/dist/providers/openai-codex.js +271 -260
  192. package/dist/providers/openai-codex.js.map +1 -1
  193. package/dist/providers/xai.js +57 -50
  194. package/dist/providers/xai.js.map +1 -1
  195. package/dist/schema.js +91 -89
  196. package/dist/schema.js.map +1 -1
  197. package/dist/theme-palette.js +18 -14
  198. package/dist/theme-palette.js.map +1 -1
  199. package/dist/tool-names.js +46 -37
  200. package/dist/tool-names.js.map +1 -1
  201. package/dist/tools/index.js +2 -8
  202. package/dist/tools/request-sandbox-access.js +71 -80
  203. package/dist/tools/request-sandbox-access.js.map +1 -1
  204. package/dist/tools/utils.js +26 -16
  205. package/dist/tools/utils.js.map +1 -1
  206. package/dist/tools/web-search.js +51 -55
  207. package/dist/tools/web-search.js.map +1 -1
  208. package/dist/utils/binaries.js +65 -61
  209. package/dist/utils/binaries.js.map +1 -1
  210. package/dist/utils/debug-log.js +51 -47
  211. package/dist/utils/debug-log.js.map +1 -1
  212. package/dist/utils/errors.js +157 -192
  213. package/dist/utils/errors.js.map +1 -1
  214. package/dist/utils/gateway-sync.js +49 -37
  215. package/dist/utils/gateway-sync.js.map +1 -1
  216. package/dist/utils/path-security.js +7 -6
  217. package/dist/utils/path-security.js.map +1 -1
  218. package/dist/utils/plan-diff.js +58 -39
  219. package/dist/utils/plan-diff.js.map +1 -1
  220. package/dist/utils/plans.js +92 -74
  221. package/dist/utils/plans.js.map +1 -1
  222. package/dist/utils/project.js +318 -256
  223. package/dist/utils/project.js.map +1 -1
  224. package/dist/utils/signals-pubsub.js +117 -99
  225. package/dist/utils/signals-pubsub.js.map +1 -1
  226. package/dist/utils/slash-command-loader.js +118 -154
  227. package/dist/utils/slash-command-loader.js.map +1 -1
  228. package/dist/utils/slash-command-processor.js +92 -83
  229. package/dist/utils/slash-command-processor.js.map +1 -1
  230. package/dist/utils/stdin-pipe.js +87 -63
  231. package/dist/utils/stdin-pipe.js.map +1 -1
  232. package/dist/utils/storage-factory.js +104 -84
  233. package/dist/utils/storage-factory.js.map +1 -1
  234. package/dist/utils/storage-maintenance.js +249 -211
  235. package/dist/utils/storage-maintenance.js.map +1 -1
  236. package/dist/utils/thread-lock.js +96 -92
  237. package/dist/utils/thread-lock.js.map +1 -1
  238. package/dist/utils/token-estimator.js +12 -12
  239. package/dist/utils/token-estimator.js.map +1 -1
  240. package/dist/utils/update-check.d.ts +1 -1
  241. package/dist/utils/update-check.js +341 -259
  242. package/dist/utils/update-check.js.map +1 -1
  243. package/dist/voice/stt-registry.js +131 -113
  244. package/dist/voice/stt-registry.js.map +1 -1
  245. package/package.json +12 -12
  246. package/dist/acp.js.map +0 -1
  247. package/dist/auth/index.js.map +0 -1
  248. package/dist/auth/types.js.map +0 -1
  249. package/dist/evals/index.js.map +0 -1
  250. package/dist/evals/scorers/index.js.map +0 -1
  251. package/dist/headless/index.js.map +0 -1
  252. package/dist/hooks/index.js.map +0 -1
  253. package/dist/lsp/index.js.map +0 -1
  254. package/dist/mcp/index.js.map +0 -1
  255. package/dist/mcp/types.js.map +0 -1
  256. package/dist/onboarding/index.js.map +0 -1
  257. package/dist/plugins/types.js.map +0 -1
  258. package/dist/tools/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/manager.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { execa } from 'execa';\n\nimport type { MastraCodePluginConfigValue } from '../plugin.js';\nimport { getEntryPackageRoot, installPluginDependenciesForEntry } from './dependencies.js';\nimport { discoverLocalPlugins, installGithubPlugin, installLocalPlugin, NON_INTERACTIVE_GIT_ENV } from './install.js';\nimport type { InstallPluginOptions } from './install.js';\nimport { collectActivePluginTools, isInsideDirectory, loadPlugins, resolvePluginEntryPath } from './loader.js';\nimport { ensureMastraCodePackageLink } from './package-link.js';\nimport { getPluginScopePaths } from './paths.js';\nimport type { PluginPathOptions } from './paths.js';\nimport { loadPluginRegistry, removePluginRecord, savePluginRegistry, setPluginRecord } from './registry.js';\nimport type { LoadedPlugin, PluginScope } from './types.js';\n\nconst GITHUB_PLUGIN_POLL_INTERVAL_MS = 60_000;\n\nfunction gitExecOptions(cwd: string) {\n return { cwd, env: NON_INTERACTIVE_GIT_ENV };\n}\n\nfunction getEntryVersion(entryPath: string): string {\n const stat = fs.statSync(entryPath, { bigint: true });\n return `${stat.mtimeNs}:${stat.size}`;\n}\n\ntype PluginManagerOptions = PluginPathOptions & {\n githubCliPath?: string;\n};\n\nexport class PluginManager {\n private loadedPlugins: LoadedPlugin[] = [];\n private readonly pluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly rawPluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly toolRenderConfigs = new Map<string, NonNullable<LoadedPlugin['renderConfigs']>[string]>();\n private readonly watchedLocalEntries = new Set<string>();\n private readonly localEntryVersions = new Map<string, string>();\n private githubPollTimer: ReturnType<typeof setInterval> | undefined;\n private githubPollInFlight: Promise<boolean> | undefined;\n private reloadInFlight: Promise<LoadedPlugin[]> | undefined;\n private readonly reloadListeners = new Set<(plugins: LoadedPlugin[]) => void | Promise<void>>();\n private readonly githubUpdateListeners = new Set<(pluginNames: string[]) => void | Promise<void>>();\n\n constructor(private readonly options: PluginManagerOptions) {}\n\n onReload(listener: (plugins: LoadedPlugin[]) => void | Promise<void>): () => void {\n this.reloadListeners.add(listener);\n return () => this.reloadListeners.delete(listener);\n }\n\n /** Notified with the display names of GitHub plugins that were updated by the background poll. */\n onGithubPluginsUpdated(listener: (pluginNames: string[]) => void | Promise<void>): () => void {\n this.githubUpdateListeners.add(listener);\n return () => this.githubUpdateListeners.delete(listener);\n }\n\n async reload(): Promise<LoadedPlugin[]> {\n if (this.reloadInFlight) return this.reloadInFlight;\n\n this.reloadInFlight = (async () => {\n this.loadedPlugins = await loadPlugins(this.options);\n this.updateLocalEntryWatchers(this.loadedPlugins);\n this.updateGithubPoller(this.loadedPlugins);\n this.updatePluginRenderConfigs(this.loadedPlugins);\n this.updatePluginTools(collectActivePluginTools(this.loadedPlugins));\n await this.notifyReloadListeners(this.loadedPlugins);\n return this.loadedPlugins;\n })().finally(() => {\n this.reloadInFlight = undefined;\n });\n\n return this.reloadInFlight;\n }\n\n async listPlugins(): Promise<LoadedPlugin[]> {\n if (this.loadedPlugins.length === 0) {\n await this.reload();\n }\n return this.loadedPlugins;\n }\n\n getLoadedPlugins(): LoadedPlugin[] {\n return this.loadedPlugins;\n }\n\n getPluginTools() {\n return this.pluginTools;\n }\n\n getToolRenderConfig(toolName: string) {\n return this.toolRenderConfigs.get(toolName);\n }\n\n getPluginSkillPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.skillPaths ?? []) : []));\n }\n\n getPluginCommandPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.commandPaths ?? []) : []));\n }\n\n getPluginInstructions(): string[] {\n return this.loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' && plugin.instructions ? [plugin.instructions] : [],\n );\n }\n\n private async notifyReloadListeners(plugins: LoadedPlugin[]): Promise<void> {\n await Promise.all([...this.reloadListeners].map(listener => Promise.resolve(listener(plugins))));\n }\n\n private updatePluginRenderConfigs(plugins: LoadedPlugin[]): void {\n this.toolRenderConfigs.clear();\n for (const plugin of plugins) {\n if (plugin.status !== 'active') continue;\n for (const [toolName, renderConfig] of Object.entries(plugin.renderConfigs ?? {})) {\n if (!this.toolRenderConfigs.has(toolName)) {\n this.toolRenderConfigs.set(toolName, renderConfig);\n }\n }\n }\n }\n\n private updatePluginTools(nextTools: ReturnType<typeof collectActivePluginTools>): void {\n for (const name of Object.keys(this.rawPluginTools)) {\n if (!(name in nextTools)) {\n delete this.rawPluginTools[name];\n delete this.pluginTools[name];\n }\n }\n\n for (const [name, tool] of Object.entries(nextTools)) {\n this.rawPluginTools[name] = tool;\n if (!this.pluginTools[name]) {\n this.pluginTools[name] = this.createLiveToolProxy(name);\n }\n this.syncLiveToolProxy(name, tool);\n }\n }\n\n private createLiveToolProxy(toolName: string) {\n return {\n execute: async (...args: any[]) => {\n await this.reloadChangedLocalPlugins();\n const latestTool = this.rawPluginTools[toolName];\n if (!latestTool?.execute) {\n throw new Error(`Plugin tool \"${toolName}\" is no longer available`);\n }\n return (latestTool.execute as (...args: any[]) => unknown)(...args);\n },\n } as LoadedPlugin['tools'][string];\n }\n\n private syncLiveToolProxy(toolName: string, tool: LoadedPlugin['tools'][string]): void {\n const proxy = this.pluginTools[toolName];\n if (!proxy) return;\n const mutableProxy = proxy as unknown as Record<string, unknown>;\n for (const key of Object.keys(mutableProxy)) {\n delete mutableProxy[key];\n }\n Object.assign(proxy, tool);\n proxy.execute = this.createLiveToolProxy(toolName).execute;\n }\n\n private async reloadChangedLocalPlugins(): Promise<void> {\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n const entryPath = resolvePluginEntryPath(plugin, this.options);\n const currentVersion = getEntryVersion(entryPath);\n if (this.localEntryVersions.get(entryPath) !== currentVersion) {\n await this.reload();\n return;\n }\n }\n }\n\n private updateLocalEntryWatchers(plugins: LoadedPlugin[]): void {\n const nextEntries = new Set<string>();\n for (const plugin of plugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n let entryPath: string;\n let entryVersion: string;\n try {\n entryPath = resolvePluginEntryPath(plugin, this.options);\n entryVersion = getEntryVersion(entryPath);\n } catch {\n continue;\n }\n nextEntries.add(entryPath);\n this.localEntryVersions.set(entryPath, entryVersion);\n if (this.watchedLocalEntries.has(entryPath)) continue;\n\n const watcher = fs.watchFile(entryPath, { interval: 500 }, (current, previous) => {\n if (current.mtimeMs === previous.mtimeMs) return;\n void this.reload().catch(() => undefined);\n });\n watcher.unref?.();\n this.watchedLocalEntries.add(entryPath);\n }\n\n for (const entryPath of this.watchedLocalEntries) {\n if (nextEntries.has(entryPath)) continue;\n fs.unwatchFile(entryPath);\n this.watchedLocalEntries.delete(entryPath);\n this.localEntryVersions.delete(entryPath);\n }\n }\n\n private updateGithubPoller(plugins: LoadedPlugin[]): void {\n const hasGithubPlugin = plugins.some(\n plugin => plugin.source === 'github' && plugin.status !== 'inactive' && plugin.status !== 'blocked',\n );\n if (hasGithubPlugin && !this.githubPollTimer) {\n this.githubPollTimer = setInterval(() => {\n void this.pollGithubSourcesForUpdates().catch(() => undefined);\n }, GITHUB_PLUGIN_POLL_INTERVAL_MS);\n this.githubPollTimer.unref?.();\n }\n if (!hasGithubPlugin && this.githubPollTimer) {\n clearInterval(this.githubPollTimer);\n this.githubPollTimer = undefined;\n }\n }\n\n async pollGithubSourcesForUpdates(): Promise<boolean> {\n if (this.githubPollInFlight) return this.githubPollInFlight;\n this.githubPollInFlight = this.pollGithubSourcesForUpdatesOnce().finally(() => {\n this.githubPollInFlight = undefined;\n });\n return this.githubPollInFlight;\n }\n\n private async pollGithubSourcesForUpdatesOnce(): Promise<boolean> {\n const changedCheckouts = new Set<string>();\n const seen = new Set<string>();\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'github' || plugin.status === 'inactive' || plugin.status === 'blocked') continue;\n const checkoutPath = this.resolvePluginSourcePath(plugin);\n if (seen.has(checkoutPath) || !fs.existsSync(path.join(checkoutPath, '.git'))) continue;\n seen.add(checkoutPath);\n\n const before = await this.readGitHead(checkoutPath);\n const checkoutChanged = await this.refreshGithubCheckout(plugin, checkoutPath, before);\n const after = await this.readGitHead(checkoutPath);\n if (checkoutChanged || before !== after) changedCheckouts.add(checkoutPath);\n }\n\n if (changedCheckouts.size === 0) return false;\n\n await this.reload();\n // Derive names from the reloaded state so a manifest display-name change reports the new name.\n // Multiple plugins can share one checkout — report every plugin whose source changed.\n const updatedPluginNames = this.loadedPlugins\n .filter(\n plugin =>\n plugin.source === 'github' &&\n plugin.status !== 'inactive' &&\n plugin.status !== 'blocked' &&\n changedCheckouts.has(this.resolvePluginSourcePath(plugin)),\n )\n .map(plugin => plugin.name ?? plugin.id);\n await this.notifyGithubUpdateListeners(updatedPluginNames);\n return true;\n }\n\n private async notifyGithubUpdateListeners(pluginNames: string[]): Promise<void> {\n await Promise.all([...this.githubUpdateListeners].map(listener => Promise.resolve(listener(pluginNames))));\n }\n\n private async refreshGithubCheckout(\n plugin: LoadedPlugin,\n checkoutPath: string,\n currentHead: string,\n ): Promise<boolean> {\n await execa('git', ['fetch', 'origin'], gitExecOptions(checkoutPath));\n const upstream = await this.resolveGitUpstream(checkoutPath, plugin.ref);\n if (!upstream) return false;\n const [localOnly, remoteOnly] = await this.readGitAheadBehind(checkoutPath, upstream);\n const hasLocalChanges = await this.hasGitWorkingTreeChanges(checkoutPath);\n\n if (localOnly > 0 || hasLocalChanges) {\n await this.backupGitCheckout(checkoutPath, currentHead, hasLocalChanges);\n }\n\n if (remoteOnly > 0 || localOnly > 0 || hasLocalChanges) {\n await execa('git', ['reset', '--hard', upstream], gitExecOptions(checkoutPath));\n try {\n await installPluginDependenciesForEntry(checkoutPath, plugin.entry);\n ensureMastraCodePackageLink(getEntryPackageRoot(checkoutPath, plugin.entry));\n } catch (error) {\n await execa('git', ['reset', '--hard', currentHead], gitExecOptions(checkoutPath));\n throw error;\n }\n return true;\n }\n\n return false;\n }\n\n private async backupGitCheckout(\n checkoutPath: string,\n currentHead: string,\n includeWorkingTree: boolean,\n ): Promise<void> {\n const backupBranch = this.createGitBackupBranchName(currentHead);\n\n if (includeWorkingTree) {\n const currentBranch = await this.readGitCurrentBranch(checkoutPath);\n await execa('git', ['switch', '-c', backupBranch], gitExecOptions(checkoutPath));\n await execa('git', ['add', '-A'], gitExecOptions(checkoutPath));\n const hasStagedChanges = await this.hasGitStagedChanges(checkoutPath);\n if (hasStagedChanges) {\n await execa(\n 'git',\n [\n '-c',\n 'user.name=Mastra Code',\n '-c',\n 'user.email=noreply@mastra.ai',\n 'commit',\n '-m',\n 'chore: backup local plugin checkout changes',\n ],\n gitExecOptions(checkoutPath),\n );\n }\n await this.restoreGitCheckout(checkoutPath, currentBranch, currentHead);\n return;\n }\n\n await execa('git', ['branch', backupBranch, 'HEAD'], gitExecOptions(checkoutPath));\n }\n\n private async resolveGitUpstream(cwd: string, installedRef?: string): Promise<string | undefined> {\n try {\n const { stdout } = await execa(\n 'git',\n ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'],\n gitExecOptions(cwd),\n );\n return stdout.trim();\n } catch {\n return installedRef ? undefined : 'origin/main';\n }\n }\n\n private async readGitAheadBehind(cwd: string, upstream: string): Promise<[number, number]> {\n const { stdout } = await execa(\n 'git',\n ['rev-list', '--left-right', '--count', `HEAD...${upstream}`],\n gitExecOptions(cwd),\n );\n const [ahead = '0', behind = '0'] = stdout.trim().split(/\\s+/);\n return [Number(ahead) || 0, Number(behind) || 0];\n }\n\n private async hasGitWorkingTreeChanges(cwd: string): Promise<boolean> {\n const { stdout } = await execa('git', ['status', '--porcelain'], gitExecOptions(cwd));\n return stdout.trim().length > 0;\n }\n\n private async hasGitStagedChanges(cwd: string): Promise<boolean> {\n try {\n await execa('git', ['diff', '--cached', '--quiet'], gitExecOptions(cwd));\n return false;\n } catch {\n return true;\n }\n }\n\n private async restoreGitCheckout(cwd: string, branch: string | undefined, fallbackHead: string): Promise<void> {\n if (branch) {\n await execa('git', ['switch', branch], gitExecOptions(cwd));\n return;\n }\n await execa('git', ['checkout', fallbackHead], gitExecOptions(cwd));\n }\n\n private async readGitCurrentBranch(cwd: string): Promise<string | undefined> {\n const { stdout } = await execa('git', ['branch', '--show-current'], gitExecOptions(cwd));\n const branch = stdout.trim();\n return branch.length > 0 ? branch : undefined;\n }\n\n private createGitBackupBranchName(currentHead: string): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n return `mastracode/plugin-backup/${timestamp}-${currentHead.slice(0, 8)}`;\n }\n\n private resolvePluginSourcePath(plugin: LoadedPlugin): string {\n const paths = getPluginScopePaths(plugin.scope, this.options);\n return path.isAbsolute(plugin.path) ? plugin.path : path.join(paths.root, plugin.path);\n }\n\n private async readGitHead(cwd: string): Promise<string> {\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], gitExecOptions(cwd));\n return stdout.trim();\n }\n\n discoverLocal(searchRoot = '.'): ReturnType<typeof discoverLocalPlugins> {\n return discoverLocalPlugins(searchRoot, this.options);\n }\n\n async installLocal(\n localPath: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry'> = {},\n ): Promise<string> {\n const id = await installLocalPlugin(localPath, scope, { ...this.options, ...options });\n await this.reload();\n return id;\n }\n\n async installGithub(\n url: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry' | 'ref' | 'onOutput' | 'signal'> = {},\n ): Promise<string> {\n const id = await installGithubPlugin(url, scope, { ...this.options, ...options });\n await this.reload();\n return id;\n }\n\n async setEnabled(pluginId: string, scope: PluginScope, enabled: boolean): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, { ...record, enabled }));\n await this.reload();\n }\n\n async setConfigValue(\n pluginId: string,\n scope: PluginScope,\n key: string,\n value: MastraCodePluginConfigValue,\n ): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n const config = { ...(record.config ?? {}) };\n if (value === undefined || value === '') {\n delete config[key];\n } else {\n config[key] = value;\n }\n const nextRecord = { ...record, config: Object.keys(config).length > 0 ? config : undefined };\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, nextRecord));\n await this.reload();\n }\n\n async uninstall(pluginId: string, scope: PluginScope): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n\n savePluginRegistry(paths.registryPath, removePluginRecord(registry, pluginId));\n if (record.source === 'github') {\n const checkoutPath = path.resolve(\n path.isAbsolute(record.path) ? record.path : path.join(paths.root, record.path),\n );\n const githubSourcesPath = path.resolve(paths.sourcesPath, 'github');\n if (isInsideDirectory(checkoutPath, githubSourcesPath)) {\n fs.rmSync(checkoutPath, { recursive: true, force: true });\n }\n }\n await this.reload();\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"manager.js","names":[],"sources":["../../src/plugins/manager.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { execa } from 'execa';\n\nimport type { MastraCodePluginConfigValue } from '../plugin.js';\nimport { getEntryPackageRoot, installPluginDependenciesForEntry } from './dependencies.js';\nimport { discoverLocalPlugins, installGithubPlugin, installLocalPlugin, NON_INTERACTIVE_GIT_ENV } from './install.js';\nimport type { InstallPluginOptions } from './install.js';\nimport { collectActivePluginTools, isInsideDirectory, loadPlugins, resolvePluginEntryPath } from './loader.js';\nimport { ensureMastraCodePackageLink } from './package-link.js';\nimport { getPluginScopePaths } from './paths.js';\nimport type { PluginPathOptions } from './paths.js';\nimport { loadPluginRegistry, removePluginRecord, savePluginRegistry, setPluginRecord } from './registry.js';\nimport type { LoadedPlugin, PluginScope } from './types.js';\n\nconst GITHUB_PLUGIN_POLL_INTERVAL_MS = 60_000;\n\nfunction gitExecOptions(cwd: string) {\n return { cwd, env: NON_INTERACTIVE_GIT_ENV };\n}\n\nfunction getEntryVersion(entryPath: string): string {\n const stat = fs.statSync(entryPath, { bigint: true });\n return `${stat.mtimeNs}:${stat.size}`;\n}\n\ntype PluginManagerOptions = PluginPathOptions & {\n githubCliPath?: string;\n};\n\nexport class PluginManager {\n private loadedPlugins: LoadedPlugin[] = [];\n private readonly pluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly rawPluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly toolRenderConfigs = new Map<string, NonNullable<LoadedPlugin['renderConfigs']>[string]>();\n private readonly watchedLocalEntries = new Set<string>();\n private readonly localEntryVersions = new Map<string, string>();\n private githubPollTimer: ReturnType<typeof setInterval> | undefined;\n private githubPollInFlight: Promise<boolean> | undefined;\n private reloadInFlight: Promise<LoadedPlugin[]> | undefined;\n private readonly reloadListeners = new Set<(plugins: LoadedPlugin[]) => void | Promise<void>>();\n private readonly githubUpdateListeners = new Set<(pluginNames: string[]) => void | Promise<void>>();\n\n constructor(private readonly options: PluginManagerOptions) {}\n\n onReload(listener: (plugins: LoadedPlugin[]) => void | Promise<void>): () => void {\n this.reloadListeners.add(listener);\n return () => this.reloadListeners.delete(listener);\n }\n\n /** Notified with the display names of GitHub plugins that were updated by the background poll. */\n onGithubPluginsUpdated(listener: (pluginNames: string[]) => void | Promise<void>): () => void {\n this.githubUpdateListeners.add(listener);\n return () => this.githubUpdateListeners.delete(listener);\n }\n\n async reload(): Promise<LoadedPlugin[]> {\n if (this.reloadInFlight) return this.reloadInFlight;\n\n this.reloadInFlight = (async () => {\n this.loadedPlugins = await loadPlugins(this.options);\n this.updateLocalEntryWatchers(this.loadedPlugins);\n this.updateGithubPoller(this.loadedPlugins);\n this.updatePluginRenderConfigs(this.loadedPlugins);\n this.updatePluginTools(collectActivePluginTools(this.loadedPlugins));\n await this.notifyReloadListeners(this.loadedPlugins);\n return this.loadedPlugins;\n })().finally(() => {\n this.reloadInFlight = undefined;\n });\n\n return this.reloadInFlight;\n }\n\n async listPlugins(): Promise<LoadedPlugin[]> {\n if (this.loadedPlugins.length === 0) {\n await this.reload();\n }\n return this.loadedPlugins;\n }\n\n getLoadedPlugins(): LoadedPlugin[] {\n return this.loadedPlugins;\n }\n\n getPluginTools() {\n return this.pluginTools;\n }\n\n getToolRenderConfig(toolName: string) {\n return this.toolRenderConfigs.get(toolName);\n }\n\n getPluginSkillPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.skillPaths ?? []) : []));\n }\n\n getPluginCommandPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.commandPaths ?? []) : []));\n }\n\n getPluginInstructions(): string[] {\n return this.loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' && plugin.instructions ? [plugin.instructions] : [],\n );\n }\n\n private async notifyReloadListeners(plugins: LoadedPlugin[]): Promise<void> {\n await Promise.all([...this.reloadListeners].map(listener => Promise.resolve(listener(plugins))));\n }\n\n private updatePluginRenderConfigs(plugins: LoadedPlugin[]): void {\n this.toolRenderConfigs.clear();\n for (const plugin of plugins) {\n if (plugin.status !== 'active') continue;\n for (const [toolName, renderConfig] of Object.entries(plugin.renderConfigs ?? {})) {\n if (!this.toolRenderConfigs.has(toolName)) {\n this.toolRenderConfigs.set(toolName, renderConfig);\n }\n }\n }\n }\n\n private updatePluginTools(nextTools: ReturnType<typeof collectActivePluginTools>): void {\n for (const name of Object.keys(this.rawPluginTools)) {\n if (!(name in nextTools)) {\n delete this.rawPluginTools[name];\n delete this.pluginTools[name];\n }\n }\n\n for (const [name, tool] of Object.entries(nextTools)) {\n this.rawPluginTools[name] = tool;\n if (!this.pluginTools[name]) {\n this.pluginTools[name] = this.createLiveToolProxy(name);\n }\n this.syncLiveToolProxy(name, tool);\n }\n }\n\n private createLiveToolProxy(toolName: string) {\n return {\n execute: async (...args: any[]) => {\n await this.reloadChangedLocalPlugins();\n const latestTool = this.rawPluginTools[toolName];\n if (!latestTool?.execute) {\n throw new Error(`Plugin tool \"${toolName}\" is no longer available`);\n }\n return (latestTool.execute as (...args: any[]) => unknown)(...args);\n },\n } as LoadedPlugin['tools'][string];\n }\n\n private syncLiveToolProxy(toolName: string, tool: LoadedPlugin['tools'][string]): void {\n const proxy = this.pluginTools[toolName];\n if (!proxy) return;\n const mutableProxy = proxy as unknown as Record<string, unknown>;\n for (const key of Object.keys(mutableProxy)) {\n delete mutableProxy[key];\n }\n Object.assign(proxy, tool);\n proxy.execute = this.createLiveToolProxy(toolName).execute;\n }\n\n private async reloadChangedLocalPlugins(): Promise<void> {\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n const entryPath = resolvePluginEntryPath(plugin, this.options);\n const currentVersion = getEntryVersion(entryPath);\n if (this.localEntryVersions.get(entryPath) !== currentVersion) {\n await this.reload();\n return;\n }\n }\n }\n\n private updateLocalEntryWatchers(plugins: LoadedPlugin[]): void {\n const nextEntries = new Set<string>();\n for (const plugin of plugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n let entryPath: string;\n let entryVersion: string;\n try {\n entryPath = resolvePluginEntryPath(plugin, this.options);\n entryVersion = getEntryVersion(entryPath);\n } catch {\n continue;\n }\n nextEntries.add(entryPath);\n this.localEntryVersions.set(entryPath, entryVersion);\n if (this.watchedLocalEntries.has(entryPath)) continue;\n\n const watcher = fs.watchFile(entryPath, { interval: 500 }, (current, previous) => {\n if (current.mtimeMs === previous.mtimeMs) return;\n void this.reload().catch(() => undefined);\n });\n watcher.unref?.();\n this.watchedLocalEntries.add(entryPath);\n }\n\n for (const entryPath of this.watchedLocalEntries) {\n if (nextEntries.has(entryPath)) continue;\n fs.unwatchFile(entryPath);\n this.watchedLocalEntries.delete(entryPath);\n this.localEntryVersions.delete(entryPath);\n }\n }\n\n private updateGithubPoller(plugins: LoadedPlugin[]): void {\n const hasGithubPlugin = plugins.some(\n plugin => plugin.source === 'github' && plugin.status !== 'inactive' && plugin.status !== 'blocked',\n );\n if (hasGithubPlugin && !this.githubPollTimer) {\n this.githubPollTimer = setInterval(() => {\n void this.pollGithubSourcesForUpdates().catch(() => undefined);\n }, GITHUB_PLUGIN_POLL_INTERVAL_MS);\n this.githubPollTimer.unref?.();\n }\n if (!hasGithubPlugin && this.githubPollTimer) {\n clearInterval(this.githubPollTimer);\n this.githubPollTimer = undefined;\n }\n }\n\n async pollGithubSourcesForUpdates(): Promise<boolean> {\n if (this.githubPollInFlight) return this.githubPollInFlight;\n this.githubPollInFlight = this.pollGithubSourcesForUpdatesOnce().finally(() => {\n this.githubPollInFlight = undefined;\n });\n return this.githubPollInFlight;\n }\n\n private async pollGithubSourcesForUpdatesOnce(): Promise<boolean> {\n const changedCheckouts = new Set<string>();\n const seen = new Set<string>();\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'github' || plugin.status === 'inactive' || plugin.status === 'blocked') continue;\n const checkoutPath = this.resolvePluginSourcePath(plugin);\n if (seen.has(checkoutPath) || !fs.existsSync(path.join(checkoutPath, '.git'))) continue;\n seen.add(checkoutPath);\n\n const before = await this.readGitHead(checkoutPath);\n const checkoutChanged = await this.refreshGithubCheckout(plugin, checkoutPath, before);\n const after = await this.readGitHead(checkoutPath);\n if (checkoutChanged || before !== after) changedCheckouts.add(checkoutPath);\n }\n\n if (changedCheckouts.size === 0) return false;\n\n await this.reload();\n // Derive names from the reloaded state so a manifest display-name change reports the new name.\n // Multiple plugins can share one checkout — report every plugin whose source changed.\n const updatedPluginNames = this.loadedPlugins\n .filter(\n plugin =>\n plugin.source === 'github' &&\n plugin.status !== 'inactive' &&\n plugin.status !== 'blocked' &&\n changedCheckouts.has(this.resolvePluginSourcePath(plugin)),\n )\n .map(plugin => plugin.name ?? plugin.id);\n await this.notifyGithubUpdateListeners(updatedPluginNames);\n return true;\n }\n\n private async notifyGithubUpdateListeners(pluginNames: string[]): Promise<void> {\n await Promise.all([...this.githubUpdateListeners].map(listener => Promise.resolve(listener(pluginNames))));\n }\n\n private async refreshGithubCheckout(\n plugin: LoadedPlugin,\n checkoutPath: string,\n currentHead: string,\n ): Promise<boolean> {\n await execa('git', ['fetch', 'origin'], gitExecOptions(checkoutPath));\n const upstream = await this.resolveGitUpstream(checkoutPath, plugin.ref);\n if (!upstream) return false;\n const [localOnly, remoteOnly] = await this.readGitAheadBehind(checkoutPath, upstream);\n const hasLocalChanges = await this.hasGitWorkingTreeChanges(checkoutPath);\n\n if (localOnly > 0 || hasLocalChanges) {\n await this.backupGitCheckout(checkoutPath, currentHead, hasLocalChanges);\n }\n\n if (remoteOnly > 0 || localOnly > 0 || hasLocalChanges) {\n await execa('git', ['reset', '--hard', upstream], gitExecOptions(checkoutPath));\n try {\n await installPluginDependenciesForEntry(checkoutPath, plugin.entry);\n ensureMastraCodePackageLink(getEntryPackageRoot(checkoutPath, plugin.entry));\n } catch (error) {\n await execa('git', ['reset', '--hard', currentHead], gitExecOptions(checkoutPath));\n throw error;\n }\n return true;\n }\n\n return false;\n }\n\n private async backupGitCheckout(\n checkoutPath: string,\n currentHead: string,\n includeWorkingTree: boolean,\n ): Promise<void> {\n const backupBranch = this.createGitBackupBranchName(currentHead);\n\n if (includeWorkingTree) {\n const currentBranch = await this.readGitCurrentBranch(checkoutPath);\n await execa('git', ['switch', '-c', backupBranch], gitExecOptions(checkoutPath));\n await execa('git', ['add', '-A'], gitExecOptions(checkoutPath));\n const hasStagedChanges = await this.hasGitStagedChanges(checkoutPath);\n if (hasStagedChanges) {\n await execa(\n 'git',\n [\n '-c',\n 'user.name=Mastra Code',\n '-c',\n 'user.email=noreply@mastra.ai',\n 'commit',\n '-m',\n 'chore: backup local plugin checkout changes',\n ],\n gitExecOptions(checkoutPath),\n );\n }\n await this.restoreGitCheckout(checkoutPath, currentBranch, currentHead);\n return;\n }\n\n await execa('git', ['branch', backupBranch, 'HEAD'], gitExecOptions(checkoutPath));\n }\n\n private async resolveGitUpstream(cwd: string, installedRef?: string): Promise<string | undefined> {\n try {\n const { stdout } = await execa(\n 'git',\n ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'],\n gitExecOptions(cwd),\n );\n return stdout.trim();\n } catch {\n return installedRef ? undefined : 'origin/main';\n }\n }\n\n private async readGitAheadBehind(cwd: string, upstream: string): Promise<[number, number]> {\n const { stdout } = await execa(\n 'git',\n ['rev-list', '--left-right', '--count', `HEAD...${upstream}`],\n gitExecOptions(cwd),\n );\n const [ahead = '0', behind = '0'] = stdout.trim().split(/\\s+/);\n return [Number(ahead) || 0, Number(behind) || 0];\n }\n\n private async hasGitWorkingTreeChanges(cwd: string): Promise<boolean> {\n const { stdout } = await execa('git', ['status', '--porcelain'], gitExecOptions(cwd));\n return stdout.trim().length > 0;\n }\n\n private async hasGitStagedChanges(cwd: string): Promise<boolean> {\n try {\n await execa('git', ['diff', '--cached', '--quiet'], gitExecOptions(cwd));\n return false;\n } catch {\n return true;\n }\n }\n\n private async restoreGitCheckout(cwd: string, branch: string | undefined, fallbackHead: string): Promise<void> {\n if (branch) {\n await execa('git', ['switch', branch], gitExecOptions(cwd));\n return;\n }\n await execa('git', ['checkout', fallbackHead], gitExecOptions(cwd));\n }\n\n private async readGitCurrentBranch(cwd: string): Promise<string | undefined> {\n const { stdout } = await execa('git', ['branch', '--show-current'], gitExecOptions(cwd));\n const branch = stdout.trim();\n return branch.length > 0 ? branch : undefined;\n }\n\n private createGitBackupBranchName(currentHead: string): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n return `mastracode/plugin-backup/${timestamp}-${currentHead.slice(0, 8)}`;\n }\n\n private resolvePluginSourcePath(plugin: LoadedPlugin): string {\n const paths = getPluginScopePaths(plugin.scope, this.options);\n return path.isAbsolute(plugin.path) ? plugin.path : path.join(paths.root, plugin.path);\n }\n\n private async readGitHead(cwd: string): Promise<string> {\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], gitExecOptions(cwd));\n return stdout.trim();\n }\n\n discoverLocal(searchRoot = '.'): ReturnType<typeof discoverLocalPlugins> {\n return discoverLocalPlugins(searchRoot, this.options);\n }\n\n async installLocal(\n localPath: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry'> = {},\n ): Promise<string> {\n const id = await installLocalPlugin(localPath, scope, { ...this.options, ...options });\n await this.reload();\n return id;\n }\n\n async installGithub(\n url: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry' | 'ref' | 'onOutput' | 'signal'> = {},\n ): Promise<string> {\n const id = await installGithubPlugin(url, scope, { ...this.options, ...options });\n await this.reload();\n return id;\n }\n\n async setEnabled(pluginId: string, scope: PluginScope, enabled: boolean): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, { ...record, enabled }));\n await this.reload();\n }\n\n async setConfigValue(\n pluginId: string,\n scope: PluginScope,\n key: string,\n value: MastraCodePluginConfigValue,\n ): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n const config = { ...(record.config ?? {}) };\n if (value === undefined || value === '') {\n delete config[key];\n } else {\n config[key] = value;\n }\n const nextRecord = { ...record, config: Object.keys(config).length > 0 ? config : undefined };\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, nextRecord));\n await this.reload();\n }\n\n async uninstall(pluginId: string, scope: PluginScope): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n\n savePluginRegistry(paths.registryPath, removePluginRecord(registry, pluginId));\n if (record.source === 'github') {\n const checkoutPath = path.resolve(\n path.isAbsolute(record.path) ? record.path : path.join(paths.root, record.path),\n );\n const githubSourcesPath = path.resolve(paths.sourcesPath, 'github');\n if (isInsideDirectory(checkoutPath, githubSourcesPath)) {\n fs.rmSync(checkoutPath, { recursive: true, force: true });\n }\n }\n await this.reload();\n }\n}\n"],"mappings":"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"}
@@ -1,75 +1,50 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
1
+ import fs from "fs";
2
+ import path from "path";
3
+ //#region src/plugins/manifest.ts
3
4
  const PLUGIN_MANIFEST_FILE = ".mastracode-plugin.json";
4
5
  function loadPluginManifest(rootDir) {
5
- const manifestPath = path.join(rootDir, PLUGIN_MANIFEST_FILE);
6
- if (!fs.existsSync(manifestPath)) return void 0;
7
- let parsed;
8
- try {
9
- parsed = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
10
- } catch (error) {
11
- throw new Error(
12
- `Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof Error ? error.message : String(error)}`
13
- );
14
- }
15
- if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.plugins)) {
16
- throw new Error(`${PLUGIN_MANIFEST_FILE} must contain a plugins array`);
17
- }
18
- return {
19
- plugins: parsed.plugins.map((entry, index) => validateManifestEntry(entry, index))
20
- };
6
+ const manifestPath = path.join(rootDir, PLUGIN_MANIFEST_FILE);
7
+ if (!fs.existsSync(manifestPath)) return void 0;
8
+ let parsed;
9
+ try {
10
+ parsed = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
11
+ } catch (error) {
12
+ throw new Error(`Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof Error ? error.message : String(error)}`);
13
+ }
14
+ if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.plugins)) throw new Error(`${PLUGIN_MANIFEST_FILE} must contain a plugins array`);
15
+ return { plugins: parsed.plugins.map((entry, index) => validateManifestEntry(entry, index)) };
21
16
  }
22
17
  function savePluginManifest(rootDir, manifest) {
23
- fs.writeFileSync(path.join(rootDir, PLUGIN_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
24
- `);
18
+ fs.writeFileSync(path.join(rootDir, PLUGIN_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}\n`);
25
19
  }
26
20
  function upsertPluginManifestEntry(rootDir, entry) {
27
- const manifest = loadPluginManifest(rootDir) ?? { plugins: [] };
28
- const validatedEntry = validateManifestEntry(entry, manifest.plugins.length);
29
- const existingIndex = manifest.plugins.findIndex((plugin) => plugin.id === validatedEntry.id);
30
- if (existingIndex >= 0) {
31
- manifest.plugins[existingIndex] = validateManifestEntry(validatedEntry, existingIndex);
32
- } else {
33
- manifest.plugins.push(validatedEntry);
34
- }
35
- savePluginManifest(rootDir, manifest);
21
+ const manifest = loadPluginManifest(rootDir) ?? { plugins: [] };
22
+ const validatedEntry = validateManifestEntry(entry, manifest.plugins.length);
23
+ const existingIndex = manifest.plugins.findIndex((plugin) => plugin.id === validatedEntry.id);
24
+ if (existingIndex >= 0) manifest.plugins[existingIndex] = validateManifestEntry(validatedEntry, existingIndex);
25
+ else manifest.plugins.push(validatedEntry);
26
+ savePluginManifest(rootDir, manifest);
36
27
  }
37
28
  function getSingleManifestPlugin(rootDir) {
38
- const manifest = loadPluginManifest(rootDir);
39
- if (!manifest) return void 0;
40
- if (manifest.plugins.length === 0) return void 0;
41
- if (manifest.plugins.length > 1) {
42
- throw new Error(
43
- `${PLUGIN_MANIFEST_FILE} contains multiple plugins. Provide an entry path for one of: ${manifest.plugins.map((plugin) => `${plugin.id} (${plugin.entry})`).join(", ")}`
44
- );
45
- }
46
- return manifest.plugins[0];
29
+ const manifest = loadPluginManifest(rootDir);
30
+ if (!manifest) return void 0;
31
+ if (manifest.plugins.length === 0) return void 0;
32
+ if (manifest.plugins.length > 1) throw new Error(`${PLUGIN_MANIFEST_FILE} contains multiple plugins. Provide an entry path for one of: ${manifest.plugins.map((plugin) => `${plugin.id} (${plugin.entry})`).join(", ")}`);
33
+ return manifest.plugins[0];
47
34
  }
48
35
  function validateManifestEntry(entry, index) {
49
- if (!entry || typeof entry !== "object") {
50
- throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an object`);
51
- }
52
- const candidate = entry;
53
- if (typeof candidate.id !== "string" || candidate.id.length === 0) {
54
- throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must include an id`);
55
- }
56
- if (typeof candidate.entry !== "string" || candidate.entry.length === 0) {
57
- throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include an entry`);
58
- }
59
- if (candidate.name !== void 0 && typeof candidate.name !== "string") {
60
- throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string`);
61
- }
62
- return {
63
- id: candidate.id,
64
- entry: candidate.entry,
65
- ...candidate.name ? { name: candidate.name } : {}
66
- };
36
+ if (!entry || typeof entry !== "object") throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an object`);
37
+ const candidate = entry;
38
+ if (typeof candidate.id !== "string" || candidate.id.length === 0) throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must include an id`);
39
+ if (typeof candidate.entry !== "string" || candidate.entry.length === 0) throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include an entry`);
40
+ if (candidate.name !== void 0 && typeof candidate.name !== "string") throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string`);
41
+ return {
42
+ id: candidate.id,
43
+ entry: candidate.entry,
44
+ ...candidate.name ? { name: candidate.name } : {}
45
+ };
67
46
  }
68
- export {
69
- PLUGIN_MANIFEST_FILE,
70
- getSingleManifestPlugin,
71
- loadPluginManifest,
72
- savePluginManifest,
73
- upsertPluginManifestEntry
74
- };
47
+ //#endregion
48
+ export { PLUGIN_MANIFEST_FILE, getSingleManifestPlugin, loadPluginManifest, savePluginManifest, upsertPluginManifestEntry };
49
+
75
50
  //# sourceMappingURL=manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/manifest.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nexport const PLUGIN_MANIFEST_FILE = '.mastracode-plugin.json';\n\nexport type PluginManifestEntry = {\n id: string;\n name?: string;\n entry: string;\n};\n\nexport type PluginManifest = {\n plugins: PluginManifestEntry[];\n};\n\nexport function loadPluginManifest(rootDir: string): PluginManifest | undefined {\n const manifestPath = path.join(rootDir, PLUGIN_MANIFEST_FILE);\n if (!fs.existsSync(manifestPath)) return undefined;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\n } catch (error) {\n throw new Error(\n `Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (!parsed || typeof parsed !== 'object' || !Array.isArray((parsed as { plugins?: unknown }).plugins)) {\n throw new Error(`${PLUGIN_MANIFEST_FILE} must contain a plugins array`);\n }\n\n return {\n plugins: (parsed as { plugins: unknown[] }).plugins.map((entry, index) => validateManifestEntry(entry, index)),\n };\n}\n\nexport function savePluginManifest(rootDir: string, manifest: PluginManifest): void {\n fs.writeFileSync(path.join(rootDir, PLUGIN_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}\\n`);\n}\n\nexport function upsertPluginManifestEntry(rootDir: string, entry: PluginManifestEntry): void {\n const manifest = loadPluginManifest(rootDir) ?? { plugins: [] };\n const validatedEntry = validateManifestEntry(entry, manifest.plugins.length);\n const existingIndex = manifest.plugins.findIndex(plugin => plugin.id === validatedEntry.id);\n if (existingIndex >= 0) {\n manifest.plugins[existingIndex] = validateManifestEntry(validatedEntry, existingIndex);\n } else {\n manifest.plugins.push(validatedEntry);\n }\n savePluginManifest(rootDir, manifest);\n}\n\nexport function getSingleManifestPlugin(rootDir: string): PluginManifestEntry | undefined {\n const manifest = loadPluginManifest(rootDir);\n if (!manifest) return undefined;\n if (manifest.plugins.length === 0) return undefined;\n if (manifest.plugins.length > 1) {\n throw new Error(\n `${PLUGIN_MANIFEST_FILE} contains multiple plugins. Provide an entry path for one of: ${manifest.plugins\n .map(plugin => `${plugin.id} (${plugin.entry})`)\n .join(', ')}`,\n );\n }\n return manifest.plugins[0];\n}\n\nfunction validateManifestEntry(entry: unknown, index: number): PluginManifestEntry {\n if (!entry || typeof entry !== 'object') {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an object`);\n }\n const candidate = entry as { id?: unknown; name?: unknown; entry?: unknown };\n if (typeof candidate.id !== 'string' || candidate.id.length === 0) {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must include an id`);\n }\n if (typeof candidate.entry !== 'string' || candidate.entry.length === 0) {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include an entry`);\n }\n if (candidate.name !== undefined && typeof candidate.name !== 'string') {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string`);\n }\n return {\n id: candidate.id,\n entry: candidate.entry,\n ...(candidate.name ? { name: candidate.name } : {}),\n };\n}\n"],"mappings":"AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEV,MAAM,uBAAuB;AAY7B,SAAS,mBAAmB,SAA6C;AAC9E,QAAM,eAAe,KAAK,KAAK,SAAS,oBAAoB;AAC5D,MAAI,CAAC,GAAG,WAAW,YAAY,EAAG,QAAO;AAEzC,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG,aAAa,cAAc,MAAM,CAAC;AAAA,EAC3D,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,mBAAmB,oBAAoB,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IACpG;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAS,OAAiC,OAAO,GAAG;AACtG,UAAM,IAAI,MAAM,GAAG,oBAAoB,+BAA+B;AAAA,EACxE;AAEA,SAAO;AAAA,IACL,SAAU,OAAkC,QAAQ,IAAI,CAAC,OAAO,UAAU,sBAAsB,OAAO,KAAK,CAAC;AAAA,EAC/G;AACF;AAEO,SAAS,mBAAmB,SAAiB,UAAgC;AAClF,KAAG,cAAc,KAAK,KAAK,SAAS,oBAAoB,GAAG,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,CAAI;AACrG;AAEO,SAAS,0BAA0B,SAAiB,OAAkC;AAC3F,QAAM,WAAW,mBAAmB,OAAO,KAAK,EAAE,SAAS,CAAC,EAAE;AAC9D,QAAM,iBAAiB,sBAAsB,OAAO,SAAS,QAAQ,MAAM;AAC3E,QAAM,gBAAgB,SAAS,QAAQ,UAAU,YAAU,OAAO,OAAO,eAAe,EAAE;AAC1F,MAAI,iBAAiB,GAAG;AACtB,aAAS,QAAQ,aAAa,IAAI,sBAAsB,gBAAgB,aAAa;AAAA,EACvF,OAAO;AACL,aAAS,QAAQ,KAAK,cAAc;AAAA,EACtC;AACA,qBAAmB,SAAS,QAAQ;AACtC;AAEO,SAAS,wBAAwB,SAAkD;AACxF,QAAM,WAAW,mBAAmB,OAAO;AAC3C,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,SAAS,QAAQ,WAAW,EAAG,QAAO;AAC1C,MAAI,SAAS,QAAQ,SAAS,GAAG;AAC/B,UAAM,IAAI;AAAA,MACR,GAAG,oBAAoB,iEAAiE,SAAS,QAC9F,IAAI,YAAU,GAAG,OAAO,EAAE,KAAK,OAAO,KAAK,GAAG,EAC9C,KAAK,IAAI,CAAC;AAAA,IACf;AAAA,EACF;AACA,SAAO,SAAS,QAAQ,CAAC;AAC3B;AAEA,SAAS,sBAAsB,OAAgB,OAAoC;AACjF,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,UAAM,IAAI,MAAM,GAAG,oBAAoB,oBAAoB,KAAK,oBAAoB;AAAA,EACtF;AACA,QAAM,YAAY;AAClB,MAAI,OAAO,UAAU,OAAO,YAAY,UAAU,GAAG,WAAW,GAAG;AACjE,UAAM,IAAI,MAAM,GAAG,oBAAoB,oBAAoB,KAAK,qBAAqB;AAAA,EACvF;AACA,MAAI,OAAO,UAAU,UAAU,YAAY,UAAU,MAAM,WAAW,GAAG;AACvE,UAAM,IAAI,MAAM,GAAG,oBAAoB,WAAW,UAAU,EAAE,wBAAwB;AAAA,EACxF;AACA,MAAI,UAAU,SAAS,UAAa,OAAO,UAAU,SAAS,UAAU;AACtE,UAAM,IAAI,MAAM,GAAG,oBAAoB,WAAW,UAAU,EAAE,wBAAwB;AAAA,EACxF;AACA,SAAO;AAAA,IACL,IAAI,UAAU;AAAA,IACd,OAAO,UAAU;AAAA,IACjB,GAAI,UAAU,OAAO,EAAE,MAAM,UAAU,KAAK,IAAI,CAAC;AAAA,EACnD;AACF;","names":[]}
1
+ {"version":3,"file":"manifest.js","names":[],"sources":["../../src/plugins/manifest.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nexport const PLUGIN_MANIFEST_FILE = '.mastracode-plugin.json';\n\nexport type PluginManifestEntry = {\n id: string;\n name?: string;\n entry: string;\n};\n\nexport type PluginManifest = {\n plugins: PluginManifestEntry[];\n};\n\nexport function loadPluginManifest(rootDir: string): PluginManifest | undefined {\n const manifestPath = path.join(rootDir, PLUGIN_MANIFEST_FILE);\n if (!fs.existsSync(manifestPath)) return undefined;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\n } catch (error) {\n throw new Error(\n `Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (!parsed || typeof parsed !== 'object' || !Array.isArray((parsed as { plugins?: unknown }).plugins)) {\n throw new Error(`${PLUGIN_MANIFEST_FILE} must contain a plugins array`);\n }\n\n return {\n plugins: (parsed as { plugins: unknown[] }).plugins.map((entry, index) => validateManifestEntry(entry, index)),\n };\n}\n\nexport function savePluginManifest(rootDir: string, manifest: PluginManifest): void {\n fs.writeFileSync(path.join(rootDir, PLUGIN_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}\\n`);\n}\n\nexport function upsertPluginManifestEntry(rootDir: string, entry: PluginManifestEntry): void {\n const manifest = loadPluginManifest(rootDir) ?? { plugins: [] };\n const validatedEntry = validateManifestEntry(entry, manifest.plugins.length);\n const existingIndex = manifest.plugins.findIndex(plugin => plugin.id === validatedEntry.id);\n if (existingIndex >= 0) {\n manifest.plugins[existingIndex] = validateManifestEntry(validatedEntry, existingIndex);\n } else {\n manifest.plugins.push(validatedEntry);\n }\n savePluginManifest(rootDir, manifest);\n}\n\nexport function getSingleManifestPlugin(rootDir: string): PluginManifestEntry | undefined {\n const manifest = loadPluginManifest(rootDir);\n if (!manifest) return undefined;\n if (manifest.plugins.length === 0) return undefined;\n if (manifest.plugins.length > 1) {\n throw new Error(\n `${PLUGIN_MANIFEST_FILE} contains multiple plugins. Provide an entry path for one of: ${manifest.plugins\n .map(plugin => `${plugin.id} (${plugin.entry})`)\n .join(', ')}`,\n );\n }\n return manifest.plugins[0];\n}\n\nfunction validateManifestEntry(entry: unknown, index: number): PluginManifestEntry {\n if (!entry || typeof entry !== 'object') {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an object`);\n }\n const candidate = entry as { id?: unknown; name?: unknown; entry?: unknown };\n if (typeof candidate.id !== 'string' || candidate.id.length === 0) {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must include an id`);\n }\n if (typeof candidate.entry !== 'string' || candidate.entry.length === 0) {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include an entry`);\n }\n if (candidate.name !== undefined && typeof candidate.name !== 'string') {\n throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string`);\n }\n return {\n id: candidate.id,\n entry: candidate.entry,\n ...(candidate.name ? { name: candidate.name } : {}),\n };\n}\n"],"mappings":";;;AAGA,MAAa,uBAAuB;AAYpC,SAAgB,mBAAmB,SAA6C;CAC9E,MAAM,eAAe,KAAK,KAAK,SAAS,oBAAoB;CAC5D,IAAI,CAAC,GAAG,WAAW,YAAY,GAAG,OAAO,KAAA;CAEzC,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,GAAG,aAAa,cAAc,MAAM,CAAC;CAC3D,SAAS,OAAO;EACd,MAAM,IAAI,MACR,mBAAmB,qBAAqB,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GACnG;CACF;CAEA,IAAI,CAAC,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAS,OAAiC,OAAO,GACnG,MAAM,IAAI,MAAM,GAAG,qBAAqB,8BAA8B;CAGxE,OAAO,EACL,SAAU,OAAkC,QAAQ,KAAK,OAAO,UAAU,sBAAsB,OAAO,KAAK,CAAC,EAC/G;AACF;AAEA,SAAgB,mBAAmB,SAAiB,UAAgC;CAClF,GAAG,cAAc,KAAK,KAAK,SAAS,oBAAoB,GAAG,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,GAAG;AACrG;AAEA,SAAgB,0BAA0B,SAAiB,OAAkC;CAC3F,MAAM,WAAW,mBAAmB,OAAO,KAAK,EAAE,SAAS,CAAC,EAAE;CAC9D,MAAM,iBAAiB,sBAAsB,OAAO,SAAS,QAAQ,MAAM;CAC3E,MAAM,gBAAgB,SAAS,QAAQ,WAAU,WAAU,OAAO,OAAO,eAAe,EAAE;CAC1F,IAAI,iBAAiB,GACnB,SAAS,QAAQ,iBAAiB,sBAAsB,gBAAgB,aAAa;MAErF,SAAS,QAAQ,KAAK,cAAc;CAEtC,mBAAmB,SAAS,QAAQ;AACtC;AAEA,SAAgB,wBAAwB,SAAkD;CACxF,MAAM,WAAW,mBAAmB,OAAO;CAC3C,IAAI,CAAC,UAAU,OAAO,KAAA;CACtB,IAAI,SAAS,QAAQ,WAAW,GAAG,OAAO,KAAA;CAC1C,IAAI,SAAS,QAAQ,SAAS,GAC5B,MAAM,IAAI,MACR,GAAG,qBAAqB,gEAAgE,SAAS,QAC9F,KAAI,WAAU,GAAG,OAAO,GAAG,IAAI,OAAO,MAAM,EAAE,CAAC,CAC/C,KAAK,IAAI,GACd;CAEF,OAAO,SAAS,QAAQ;AAC1B;AAEA,SAAS,sBAAsB,OAAgB,OAAoC;CACjF,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B,MAAM,IAAI,MAAM,GAAG,qBAAqB,mBAAmB,MAAM,mBAAmB;CAEtF,MAAM,YAAY;CAClB,IAAI,OAAO,UAAU,OAAO,YAAY,UAAU,GAAG,WAAW,GAC9D,MAAM,IAAI,MAAM,GAAG,qBAAqB,mBAAmB,MAAM,oBAAoB;CAEvF,IAAI,OAAO,UAAU,UAAU,YAAY,UAAU,MAAM,WAAW,GACpE,MAAM,IAAI,MAAM,GAAG,qBAAqB,UAAU,UAAU,GAAG,uBAAuB;CAExF,IAAI,UAAU,SAAS,KAAA,KAAa,OAAO,UAAU,SAAS,UAC5D,MAAM,IAAI,MAAM,GAAG,qBAAqB,UAAU,UAAU,GAAG,uBAAuB;CAExF,OAAO;EACL,IAAI,UAAU;EACd,OAAO,UAAU;EACjB,GAAI,UAAU,OAAO,EAAE,MAAM,UAAU,KAAK,IAAI,CAAC;CACnD;AACF"}
@@ -1,77 +1,61 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ //#region src/plugins/package-link.ts
4
5
  const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
5
6
  let cachedPackageRoot;
6
7
  function mastraCodePackageRoot() {
7
- if (cachedPackageRoot === void 0) {
8
- try {
9
- cachedPackageRoot = findMastraCodePackageRoot(MODULE_DIR);
10
- } catch (error) {
11
- const entryScript = process.argv[1];
12
- if (!entryScript) throw error;
13
- cachedPackageRoot = findMastraCodePackageRoot(path.dirname(fs.realpathSync(entryScript)));
14
- }
15
- }
16
- return cachedPackageRoot;
8
+ if (cachedPackageRoot === void 0) try {
9
+ cachedPackageRoot = findMastraCodePackageRoot(MODULE_DIR);
10
+ } catch (error) {
11
+ const entryScript = process.argv[1];
12
+ if (!entryScript) throw error;
13
+ cachedPackageRoot = findMastraCodePackageRoot(path.dirname(fs.realpathSync(entryScript)));
14
+ }
15
+ return cachedPackageRoot;
17
16
  }
18
17
  function readPackageName(dir) {
19
- const packageJsonPath = path.join(dir, "package.json");
20
- if (!fs.existsSync(packageJsonPath)) return void 0;
21
- return JSON.parse(fs.readFileSync(packageJsonPath, "utf8")).name;
18
+ const packageJsonPath = path.join(dir, "package.json");
19
+ if (!fs.existsSync(packageJsonPath)) return void 0;
20
+ return JSON.parse(fs.readFileSync(packageJsonPath, "utf8")).name;
22
21
  }
23
22
  function findMastraCodePackageRoot(startDir) {
24
- let currentDir = path.resolve(startDir);
25
- while (true) {
26
- const packageName = readPackageName(currentDir);
27
- if (packageName === "mastracode") {
28
- return currentDir;
29
- }
30
- if (packageName === "@mastra/code-sdk") {
31
- for (const candidate of [
32
- path.resolve(currentDir, "..", "tui"),
33
- path.resolve(currentDir, "..", "..", "mastracode")
34
- ]) {
35
- if (readPackageName(candidate) === "mastracode") {
36
- return candidate;
37
- }
38
- }
39
- }
40
- const parentDir = path.dirname(currentDir);
41
- if (parentDir === currentDir) {
42
- throw new Error(`Could not find mastracode package root from ${startDir}`);
43
- }
44
- currentDir = parentDir;
45
- }
23
+ let currentDir = path.resolve(startDir);
24
+ while (true) {
25
+ const packageName = readPackageName(currentDir);
26
+ if (packageName === "mastracode") return currentDir;
27
+ if (packageName === "@mastra/code-sdk") {
28
+ for (const candidate of [path.resolve(currentDir, "..", "tui"), path.resolve(currentDir, "..", "..", "mastracode")]) if (readPackageName(candidate) === "mastracode") return candidate;
29
+ }
30
+ const parentDir = path.dirname(currentDir);
31
+ if (parentDir === currentDir) throw new Error(`Could not find mastracode package root from ${startDir}`);
32
+ currentDir = parentDir;
33
+ }
46
34
  }
47
35
  function ensureMastraCodePackageLink(pluginDir) {
48
- if (declaresInstallableMastraCodeDependency(pluginDir)) {
49
- return;
50
- }
51
- const packageRoot = mastraCodePackageRoot();
52
- const nodeModulesDir = path.join(pluginDir, "node_modules");
53
- const linkPath = path.join(nodeModulesDir, "mastracode");
54
- try {
55
- if (fs.realpathSync(linkPath) === fs.realpathSync(packageRoot)) {
56
- return;
57
- }
58
- fs.rmSync(linkPath, { recursive: true, force: true });
59
- } catch (error) {
60
- if (error.code !== "ENOENT") throw error;
61
- }
62
- fs.mkdirSync(nodeModulesDir, { recursive: true });
63
- fs.symlinkSync(packageRoot, linkPath, "dir");
36
+ if (declaresInstallableMastraCodeDependency(pluginDir)) return;
37
+ const packageRoot = mastraCodePackageRoot();
38
+ const nodeModulesDir = path.join(pluginDir, "node_modules");
39
+ const linkPath = path.join(nodeModulesDir, "mastracode");
40
+ try {
41
+ if (fs.realpathSync(linkPath) === fs.realpathSync(packageRoot)) return;
42
+ fs.rmSync(linkPath, {
43
+ recursive: true,
44
+ force: true
45
+ });
46
+ } catch (error) {
47
+ if (error.code !== "ENOENT") throw error;
48
+ }
49
+ fs.mkdirSync(nodeModulesDir, { recursive: true });
50
+ fs.symlinkSync(packageRoot, linkPath, "dir");
64
51
  }
65
52
  function declaresInstallableMastraCodeDependency(pluginDir) {
66
- const packageJsonPath = path.join(pluginDir, "package.json");
67
- if (!fs.existsSync(packageJsonPath)) return false;
68
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
69
- return Boolean(
70
- packageJson.dependencies?.mastracode ?? packageJson.devDependencies?.mastracode ?? packageJson.optionalDependencies?.mastracode
71
- );
53
+ const packageJsonPath = path.join(pluginDir, "package.json");
54
+ if (!fs.existsSync(packageJsonPath)) return false;
55
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
56
+ return Boolean(packageJson.dependencies?.mastracode ?? packageJson.devDependencies?.mastracode ?? packageJson.optionalDependencies?.mastracode);
72
57
  }
73
- export {
74
- ensureMastraCodePackageLink,
75
- findMastraCodePackageRoot
76
- };
58
+ //#endregion
59
+ export { ensureMastraCodePackageLink, findMastraCodePackageRoot };
60
+
77
61
  //# sourceMappingURL=package-link.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/package-link.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));\n\nlet cachedPackageRoot: string | undefined;\n\n// This module ships in @mastra/code-sdk, so the `mastracode` package root is\n// resolved lazily: from the module location (source tree / bundled dist), or —\n// for the published CLI where the sdk is an external dependency — from the\n// entry script, which lives inside the `mastracode` package.\nfunction mastraCodePackageRoot(): string {\n if (cachedPackageRoot === undefined) {\n try {\n cachedPackageRoot = findMastraCodePackageRoot(MODULE_DIR);\n } catch (error) {\n const entryScript = process.argv[1];\n if (!entryScript) throw error;\n cachedPackageRoot = findMastraCodePackageRoot(path.dirname(fs.realpathSync(entryScript)));\n }\n }\n return cachedPackageRoot;\n}\n\nfunction readPackageName(dir: string): string | undefined {\n const packageJsonPath = path.join(dir, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return undefined;\n return (JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string }).name;\n}\n\nexport function findMastraCodePackageRoot(startDir: string): string {\n let currentDir = path.resolve(startDir);\n\n while (true) {\n const packageName = readPackageName(currentDir);\n if (packageName === 'mastracode') {\n return currentDir;\n }\n if (packageName === '@mastra/code-sdk') {\n // The `mastracode` package sits next to the sdk: mastracode/sdk ↔\n // mastracode/tui in the source tree, node_modules/@mastra/code-sdk ↔\n // node_modules/mastracode when installed.\n for (const candidate of [\n path.resolve(currentDir, '..', 'tui'),\n path.resolve(currentDir, '..', '..', 'mastracode'),\n ]) {\n if (readPackageName(candidate) === 'mastracode') {\n return candidate;\n }\n }\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n throw new Error(`Could not find mastracode package root from ${startDir}`);\n }\n currentDir = parentDir;\n }\n}\n\nexport function ensureMastraCodePackageLink(pluginDir: string): void {\n if (declaresInstallableMastraCodeDependency(pluginDir)) {\n return;\n }\n\n const packageRoot = mastraCodePackageRoot();\n const nodeModulesDir = path.join(pluginDir, 'node_modules');\n const linkPath = path.join(nodeModulesDir, 'mastracode');\n try {\n if (fs.realpathSync(linkPath) === fs.realpathSync(packageRoot)) {\n return;\n }\n fs.rmSync(linkPath, { recursive: true, force: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n\n fs.mkdirSync(nodeModulesDir, { recursive: true });\n fs.symlinkSync(packageRoot, linkPath, 'dir');\n}\n\nfunction declaresInstallableMastraCodeDependency(pluginDir: string): boolean {\n const packageJsonPath = path.join(pluginDir, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, unknown>;\n devDependencies?: Record<string, unknown>;\n optionalDependencies?: Record<string, unknown>;\n };\n\n return Boolean(\n packageJson.dependencies?.mastracode ??\n packageJson.devDependencies?.mastracode ??\n packageJson.optionalDependencies?.mastracode,\n );\n}\n"],"mappings":"AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,MAAM,aAAa,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAE9D,IAAI;AAMJ,SAAS,wBAAgC;AACvC,MAAI,sBAAsB,QAAW;AACnC,QAAI;AACF,0BAAoB,0BAA0B,UAAU;AAAA,IAC1D,SAAS,OAAO;AACd,YAAM,cAAc,QAAQ,KAAK,CAAC;AAClC,UAAI,CAAC,YAAa,OAAM;AACxB,0BAAoB,0BAA0B,KAAK,QAAQ,GAAG,aAAa,WAAW,CAAC,CAAC;AAAA,IAC1F;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAiC;AACxD,QAAM,kBAAkB,KAAK,KAAK,KAAK,cAAc;AACrD,MAAI,CAAC,GAAG,WAAW,eAAe,EAAG,QAAO;AAC5C,SAAQ,KAAK,MAAM,GAAG,aAAa,iBAAiB,MAAM,CAAC,EAAwB;AACrF;AAEO,SAAS,0BAA0B,UAA0B;AAClE,MAAI,aAAa,KAAK,QAAQ,QAAQ;AAEtC,SAAO,MAAM;AACX,UAAM,cAAc,gBAAgB,UAAU;AAC9C,QAAI,gBAAgB,cAAc;AAChC,aAAO;AAAA,IACT;AACA,QAAI,gBAAgB,oBAAoB;AAItC,iBAAW,aAAa;AAAA,QACtB,KAAK,QAAQ,YAAY,MAAM,KAAK;AAAA,QACpC,KAAK,QAAQ,YAAY,MAAM,MAAM,YAAY;AAAA,MACnD,GAAG;AACD,YAAI,gBAAgB,SAAS,MAAM,cAAc;AAC/C,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,QAAQ,UAAU;AACzC,QAAI,cAAc,YAAY;AAC5B,YAAM,IAAI,MAAM,+CAA+C,QAAQ,EAAE;AAAA,IAC3E;AACA,iBAAa;AAAA,EACf;AACF;AAEO,SAAS,4BAA4B,WAAyB;AACnE,MAAI,wCAAwC,SAAS,GAAG;AACtD;AAAA,EACF;AAEA,QAAM,cAAc,sBAAsB;AAC1C,QAAM,iBAAiB,KAAK,KAAK,WAAW,cAAc;AAC1D,QAAM,WAAW,KAAK,KAAK,gBAAgB,YAAY;AACvD,MAAI;AACF,QAAI,GAAG,aAAa,QAAQ,MAAM,GAAG,aAAa,WAAW,GAAG;AAC9D;AAAA,IACF;AACA,OAAG,OAAO,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACtD,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,OAAM;AAAA,EAChE;AAEA,KAAG,UAAU,gBAAgB,EAAE,WAAW,KAAK,CAAC;AAChD,KAAG,YAAY,aAAa,UAAU,KAAK;AAC7C;AAEA,SAAS,wCAAwC,WAA4B;AAC3E,QAAM,kBAAkB,KAAK,KAAK,WAAW,cAAc;AAC3D,MAAI,CAAC,GAAG,WAAW,eAAe,EAAG,QAAO;AAE5C,QAAM,cAAc,KAAK,MAAM,GAAG,aAAa,iBAAiB,MAAM,CAAC;AAMvE,SAAO;AAAA,IACL,YAAY,cAAc,cAC1B,YAAY,iBAAiB,cAC7B,YAAY,sBAAsB;AAAA,EACpC;AACF;","names":[]}
1
+ {"version":3,"file":"package-link.js","names":[],"sources":["../../src/plugins/package-link.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));\n\nlet cachedPackageRoot: string | undefined;\n\n// This module ships in @mastra/code-sdk, so the `mastracode` package root is\n// resolved lazily: from the module location (source tree / bundled dist), or —\n// for the published CLI where the sdk is an external dependency — from the\n// entry script, which lives inside the `mastracode` package.\nfunction mastraCodePackageRoot(): string {\n if (cachedPackageRoot === undefined) {\n try {\n cachedPackageRoot = findMastraCodePackageRoot(MODULE_DIR);\n } catch (error) {\n const entryScript = process.argv[1];\n if (!entryScript) throw error;\n cachedPackageRoot = findMastraCodePackageRoot(path.dirname(fs.realpathSync(entryScript)));\n }\n }\n return cachedPackageRoot;\n}\n\nfunction readPackageName(dir: string): string | undefined {\n const packageJsonPath = path.join(dir, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return undefined;\n return (JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string }).name;\n}\n\nexport function findMastraCodePackageRoot(startDir: string): string {\n let currentDir = path.resolve(startDir);\n\n while (true) {\n const packageName = readPackageName(currentDir);\n if (packageName === 'mastracode') {\n return currentDir;\n }\n if (packageName === '@mastra/code-sdk') {\n // The `mastracode` package sits next to the sdk: mastracode/sdk ↔\n // mastracode/tui in the source tree, node_modules/@mastra/code-sdk ↔\n // node_modules/mastracode when installed.\n for (const candidate of [\n path.resolve(currentDir, '..', 'tui'),\n path.resolve(currentDir, '..', '..', 'mastracode'),\n ]) {\n if (readPackageName(candidate) === 'mastracode') {\n return candidate;\n }\n }\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n throw new Error(`Could not find mastracode package root from ${startDir}`);\n }\n currentDir = parentDir;\n }\n}\n\nexport function ensureMastraCodePackageLink(pluginDir: string): void {\n if (declaresInstallableMastraCodeDependency(pluginDir)) {\n return;\n }\n\n const packageRoot = mastraCodePackageRoot();\n const nodeModulesDir = path.join(pluginDir, 'node_modules');\n const linkPath = path.join(nodeModulesDir, 'mastracode');\n try {\n if (fs.realpathSync(linkPath) === fs.realpathSync(packageRoot)) {\n return;\n }\n fs.rmSync(linkPath, { recursive: true, force: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n\n fs.mkdirSync(nodeModulesDir, { recursive: true });\n fs.symlinkSync(packageRoot, linkPath, 'dir');\n}\n\nfunction declaresInstallableMastraCodeDependency(pluginDir: string): boolean {\n const packageJsonPath = path.join(pluginDir, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, unknown>;\n devDependencies?: Record<string, unknown>;\n optionalDependencies?: Record<string, unknown>;\n };\n\n return Boolean(\n packageJson.dependencies?.mastracode ??\n packageJson.devDependencies?.mastracode ??\n packageJson.optionalDependencies?.mastracode,\n );\n}\n"],"mappings":";;;;AAIA,MAAM,aAAa,KAAK,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;AAE9D,IAAI;AAMJ,SAAS,wBAAgC;CACvC,IAAI,sBAAsB,KAAA,GACxB,IAAI;EACF,oBAAoB,0BAA0B,UAAU;CAC1D,SAAS,OAAO;EACd,MAAM,cAAc,QAAQ,KAAK;EACjC,IAAI,CAAC,aAAa,MAAM;EACxB,oBAAoB,0BAA0B,KAAK,QAAQ,GAAG,aAAa,WAAW,CAAC,CAAC;CAC1F;CAEF,OAAO;AACT;AAEA,SAAS,gBAAgB,KAAiC;CACxD,MAAM,kBAAkB,KAAK,KAAK,KAAK,cAAc;CACrD,IAAI,CAAC,GAAG,WAAW,eAAe,GAAG,OAAO,KAAA;CAC5C,OAAQ,KAAK,MAAM,GAAG,aAAa,iBAAiB,MAAM,CAAC,CAAC,CAAuB;AACrF;AAEA,SAAgB,0BAA0B,UAA0B;CAClE,IAAI,aAAa,KAAK,QAAQ,QAAQ;CAEtC,OAAO,MAAM;EACX,MAAM,cAAc,gBAAgB,UAAU;EAC9C,IAAI,gBAAgB,cAClB,OAAO;EAET,IAAI,gBAAgB,oBAIb;QAAA,MAAM,aAAa,CACtB,KAAK,QAAQ,YAAY,MAAM,KAAK,GACpC,KAAK,QAAQ,YAAY,MAAM,MAAM,YAAY,CACnD,GACE,IAAI,gBAAgB,SAAS,MAAM,cACjC,OAAO;EAAA;EAKb,MAAM,YAAY,KAAK,QAAQ,UAAU;EACzC,IAAI,cAAc,YAChB,MAAM,IAAI,MAAM,+CAA+C,UAAU;EAE3E,aAAa;CACf;AACF;AAEA,SAAgB,4BAA4B,WAAyB;CACnE,IAAI,wCAAwC,SAAS,GACnD;CAGF,MAAM,cAAc,sBAAsB;CAC1C,MAAM,iBAAiB,KAAK,KAAK,WAAW,cAAc;CAC1D,MAAM,WAAW,KAAK,KAAK,gBAAgB,YAAY;CACvD,IAAI;EACF,IAAI,GAAG,aAAa,QAAQ,MAAM,GAAG,aAAa,WAAW,GAC3D;EAEF,GAAG,OAAO,UAAU;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;CACtD,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU,MAAM;CAChE;CAEA,GAAG,UAAU,gBAAgB,EAAE,WAAW,KAAK,CAAC;CAChD,GAAG,YAAY,aAAa,UAAU,KAAK;AAC7C;AAEA,SAAS,wCAAwC,WAA4B;CAC3E,MAAM,kBAAkB,KAAK,KAAK,WAAW,cAAc;CAC3D,IAAI,CAAC,GAAG,WAAW,eAAe,GAAG,OAAO;CAE5C,MAAM,cAAc,KAAK,MAAM,GAAG,aAAa,iBAAiB,MAAM,CAAC;CAMvE,OAAO,QACL,YAAY,cAAc,cAC1B,YAAY,iBAAiB,cAC7B,YAAY,sBAAsB,UACpC;AACF"}
@@ -1,26 +1,25 @@
1
- import os from "node:os";
2
- import path from "node:path";
3
- import { DEFAULT_CONFIG_DIR } from "../constants.js";
1
+ import "../constants.js";
2
+ import os from "os";
3
+ import path from "path";
4
+ //#region src/plugins/paths.ts
4
5
  function getPluginRoot(scope, options) {
5
- const configDir = options.configDir ?? DEFAULT_CONFIG_DIR;
6
- const baseDir = scope === "project" ? options.projectRoot : options.homeDir ?? os.homedir();
7
- return path.join(baseDir, configDir, "plugins");
6
+ const configDir = options.configDir ?? ".mastracode";
7
+ const baseDir = scope === "project" ? options.projectRoot : options.homeDir ?? os.homedir();
8
+ return path.join(baseDir, configDir, "plugins");
8
9
  }
9
10
  function getPluginRegistryPath(scope, options) {
10
- return path.join(getPluginRoot(scope, options), "plugins.json");
11
+ return path.join(getPluginRoot(scope, options), "plugins.json");
11
12
  }
12
13
  function getPluginScopePaths(scope, options) {
13
- const root = getPluginRoot(scope, options);
14
- return {
15
- scope,
16
- root,
17
- registryPath: path.join(root, "plugins.json"),
18
- sourcesPath: path.join(root, "sources")
19
- };
14
+ const root = getPluginRoot(scope, options);
15
+ return {
16
+ scope,
17
+ root,
18
+ registryPath: path.join(root, "plugins.json"),
19
+ sourcesPath: path.join(root, "sources")
20
+ };
20
21
  }
21
- export {
22
- getPluginRegistryPath,
23
- getPluginRoot,
24
- getPluginScopePaths
25
- };
22
+ //#endregion
23
+ export { getPluginRegistryPath, getPluginRoot, getPluginScopePaths };
24
+
26
25
  //# sourceMappingURL=paths.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/paths.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport type { PluginScope, PluginScopePaths } from './types.js';\n\nexport type PluginPathOptions = {\n projectRoot: string;\n configDir?: string;\n homeDir?: string;\n};\n\nexport function getPluginRoot(scope: PluginScope, options: PluginPathOptions): string {\n const configDir = options.configDir ?? DEFAULT_CONFIG_DIR;\n const baseDir = scope === 'project' ? options.projectRoot : (options.homeDir ?? os.homedir());\n return path.join(baseDir, configDir, 'plugins');\n}\n\nexport function getPluginRegistryPath(scope: PluginScope, options: PluginPathOptions): string {\n return path.join(getPluginRoot(scope, options), 'plugins.json');\n}\n\nexport function getPluginScopePaths(scope: PluginScope, options: PluginPathOptions): PluginScopePaths {\n const root = getPluginRoot(scope, options);\n return {\n scope,\n root,\n registryPath: path.join(root, 'plugins.json'),\n sourcesPath: path.join(root, 'sources'),\n };\n}\n"],"mappings":"AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,SAAS,0BAA0B;AAS5B,SAAS,cAAc,OAAoB,SAAoC;AACpF,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,UAAU,UAAU,YAAY,QAAQ,cAAe,QAAQ,WAAW,GAAG,QAAQ;AAC3F,SAAO,KAAK,KAAK,SAAS,WAAW,SAAS;AAChD;AAEO,SAAS,sBAAsB,OAAoB,SAAoC;AAC5F,SAAO,KAAK,KAAK,cAAc,OAAO,OAAO,GAAG,cAAc;AAChE;AAEO,SAAS,oBAAoB,OAAoB,SAA8C;AACpG,QAAM,OAAO,cAAc,OAAO,OAAO;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,cAAc,KAAK,KAAK,MAAM,cAAc;AAAA,IAC5C,aAAa,KAAK,KAAK,MAAM,SAAS;AAAA,EACxC;AACF;","names":[]}
1
+ {"version":3,"file":"paths.js","names":[],"sources":["../../src/plugins/paths.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport type { PluginScope, PluginScopePaths } from './types.js';\n\nexport type PluginPathOptions = {\n projectRoot: string;\n configDir?: string;\n homeDir?: string;\n};\n\nexport function getPluginRoot(scope: PluginScope, options: PluginPathOptions): string {\n const configDir = options.configDir ?? DEFAULT_CONFIG_DIR;\n const baseDir = scope === 'project' ? options.projectRoot : (options.homeDir ?? os.homedir());\n return path.join(baseDir, configDir, 'plugins');\n}\n\nexport function getPluginRegistryPath(scope: PluginScope, options: PluginPathOptions): string {\n return path.join(getPluginRoot(scope, options), 'plugins.json');\n}\n\nexport function getPluginScopePaths(scope: PluginScope, options: PluginPathOptions): PluginScopePaths {\n const root = getPluginRoot(scope, options);\n return {\n scope,\n root,\n registryPath: path.join(root, 'plugins.json'),\n sourcesPath: path.join(root, 'sources'),\n };\n}\n"],"mappings":";;;;AAYA,SAAgB,cAAc,OAAoB,SAAoC;CACpF,MAAM,YAAY,QAAQ,aAAA;CAC1B,MAAM,UAAU,UAAU,YAAY,QAAQ,cAAe,QAAQ,WAAW,GAAG,QAAQ;CAC3F,OAAO,KAAK,KAAK,SAAS,WAAW,SAAS;AAChD;AAEA,SAAgB,sBAAsB,OAAoB,SAAoC;CAC5F,OAAO,KAAK,KAAK,cAAc,OAAO,OAAO,GAAG,cAAc;AAChE;AAEA,SAAgB,oBAAoB,OAAoB,SAA8C;CACpG,MAAM,OAAO,cAAc,OAAO,OAAO;CACzC,OAAO;EACL;EACA;EACA,cAAc,KAAK,KAAK,MAAM,cAAc;EAC5C,aAAa,KAAK,KAAK,MAAM,SAAS;CACxC;AACF"}