@mastra/code-sdk 1.2.0-alpha.10 → 1.2.0-alpha.14

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 (51) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/agents/model.d.ts.map +1 -1
  3. package/dist/agents/model.js +4 -1
  4. package/dist/agents/model.js.map +1 -1
  5. package/dist/agents/modes/plan.js +2 -2
  6. package/dist/agents/modes/plan.js.map +1 -1
  7. package/dist/agents/prompts/index.d.ts.map +1 -1
  8. package/dist/agents/prompts/index.js +4 -1
  9. package/dist/agents/prompts/index.js.map +1 -1
  10. package/dist/agents/prompts/plan.d.ts +1 -1
  11. package/dist/agents/prompts/plan.d.ts.map +1 -1
  12. package/dist/agents/prompts/plan.js +2 -2
  13. package/dist/agents/prompts/plan.js.map +1 -1
  14. package/dist/agents/prompts/tool-guidance.d.ts +2 -0
  15. package/dist/agents/prompts/tool-guidance.d.ts.map +1 -1
  16. package/dist/agents/prompts/tool-guidance.js +3 -2
  17. package/dist/agents/prompts/tool-guidance.js.map +1 -1
  18. package/dist/agents/tool-availability.d.ts.map +1 -1
  19. package/dist/agents/tool-availability.js +9 -4
  20. package/dist/agents/tool-availability.js.map +1 -1
  21. package/dist/agents/tools.js +1 -1
  22. package/dist/headless/cli.d.ts.map +1 -1
  23. package/dist/headless/cli.js +3 -0
  24. package/dist/headless/cli.js.map +1 -1
  25. package/dist/index.d.ts +68 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +173 -61
  28. package/dist/index.js.map +1 -1
  29. package/dist/plugin.d.ts +64 -1
  30. package/dist/plugin.d.ts.map +1 -1
  31. package/dist/plugin.js +3 -1
  32. package/dist/plugin.js.map +1 -1
  33. package/dist/plugins/loader.d.ts +7 -3
  34. package/dist/plugins/loader.d.ts.map +1 -1
  35. package/dist/plugins/loader.js +53 -1
  36. package/dist/plugins/loader.js.map +1 -1
  37. package/dist/plugins/manager.d.ts +36 -2
  38. package/dist/plugins/manager.d.ts.map +1 -1
  39. package/dist/plugins/manager.js +74 -2
  40. package/dist/plugins/manager.js.map +1 -1
  41. package/dist/plugins/signal-lane.d.ts +58 -0
  42. package/dist/plugins/signal-lane.d.ts.map +1 -0
  43. package/dist/plugins/signal-lane.js +166 -0
  44. package/dist/plugins/signal-lane.js.map +1 -0
  45. package/dist/plugins/types.d.ts +36 -0
  46. package/dist/plugins/types.d.ts.map +1 -1
  47. package/dist/utils/plans.d.ts +9 -6
  48. package/dist/utils/plans.d.ts.map +1 -1
  49. package/dist/utils/plans.js +11 -11
  50. package/dist/utils/plans.js.map +1 -1
  51. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":[],"sources":["../../src/headless/cli.ts"],"sourcesContent":["/**\n * CLI adapter for headless MastraCode runs.\n *\n * This is the only headless layer that touches the process: it parses argv,\n * reads stdin, bootstraps MastraCode via `createMastraCode`, drives `runMC`,\n * renders events/results to stdout/stderr through the pure formatters, maps the\n * result to an exit code, and owns teardown + `process.exit`.\n */\nimport { existsSync } from 'node:fs';\nimport { parseArgs } from 'node:util';\n\nimport { createMastraCode } from '../index.js';\nimport { setupDebugLogging } from '../utils/debug-log.js';\nimport { releaseAllThreadLocks } from '../utils/thread-lock.js';\n\nimport { buildParseArgsOptions, FLAGS, renderFlagUsage } from './flags.js';\nimport { createHumanFormatState, formatHuman, formatJsonl, renderJsonResult } from './format.js';\nimport { permissionModeToPolicy } from './policy.js';\nimport { runMC } from './run-mc.js';\nimport type { PermissionMode, RunMode, ThinkingLevel } from './types.js';\n\n/** Consolidated output mode (replaces the old `--format` + `--output-format`). */\nexport type OutputMode = 'human' | 'json' | 'jsonl';\n\nexport interface HeadlessArgs {\n prompt?: string;\n /** Timeout in seconds (CLI surface); converted to ms before `runMC`. */\n timeout?: number;\n output: OutputMode;\n continue_: boolean;\n model?: string;\n mode?: RunMode;\n thinkingLevel?: ThinkingLevel;\n settings?: string;\n thread?: string;\n title?: string;\n cloneThread: boolean;\n resourceId?: string;\n /** Max agentic turns before the run aborts with exit code 1. */\n maxTurns?: number;\n /** Named permission mode resolving to a built-in policy. Defaults to `auto`. */\n permissionMode?: PermissionMode;\n}\n\nconst parseArgsOptions = buildParseArgsOptions();\n\n/**\n * Returns true if `argv` selects headless mode. This must agree with what\n * {@link parseHeadlessArgs} (and `runMCCli`) accept as a prompt: `--prompt`/`-p`\n * or a bare positional prompt (e.g. `mastracode \"Fix the bug\"`). Note that a\n * prompt piped via stdin without a flag is handled separately by the caller.\n */\nexport function hasHeadlessFlag(argv: string[]): boolean {\n if (argv.some(a => a === '--prompt' || a === '-p')) return true;\n try {\n const { values, positionals } = parseArgs({\n args: argv.slice(2),\n options: parseArgsOptions,\n strict: false,\n allowPositionals: true,\n });\n // A positional prompt only counts when not asking for help.\n return positionals.length > 0 && !values.help;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse CLI arguments for headless mode. The flag table in `flags.ts` is the\n * single source of truth: each flag carries its own coercion/validation, so this\n * function just walks {@link FLAGS} and assembles the typed {@link HeadlessArgs}.\n */\nexport function parseHeadlessArgs(argv: string[]): HeadlessArgs {\n const { values, positionals } = parseArgs({\n args: argv.slice(2),\n options: parseArgsOptions,\n strict: false,\n allowPositionals: true,\n });\n\n // Seed defaults; per-flag values below override these.\n const args: HeadlessArgs = {\n output: 'human',\n continue_: false,\n cloneThread: false,\n };\n const sink = args as unknown as Record<string, unknown>;\n\n for (const flag of FLAGS) {\n if (!flag.field) continue; // e.g. --help, handled by the caller\n const raw = values[flag.key];\n if (raw === undefined) continue;\n\n if (flag.type === 'boolean') {\n sink[flag.field] = Boolean(raw);\n } else if (typeof raw === 'string') {\n sink[flag.field] = flag.coerce ? flag.coerce(raw) : raw;\n }\n }\n\n // A bare positional acts as the prompt when --prompt/-p is absent.\n if (args.prompt === undefined && positionals[0] !== undefined) {\n args.prompt = positionals[0];\n }\n\n if (args.continue_ && args.thread) {\n throw new Error('--continue and --thread cannot be used together');\n }\n\n return args;\n}\n\nexport function printHeadlessUsage(): void {\n process.stdout.write(`\nUsage: mastracode --prompt <text> [options]\n\nHeadless (non-interactive) mode options:\n${renderFlagUsage()}\n\nThread behavior:\n By default, a new thread is created for each run.\n Use --continue to resume the most recent thread, or --thread to target a specific one.\n Use --clone-thread to branch off a copy before running.\n\nSettings file:\n Uses the same settings.json as the interactive TUI. Pass --settings to use\n a custom settings file (e.g., settings-ci.json for CI). All model, pack,\n subagent, and OM configuration is resolved from settings at startup.\n\nExit codes:\n 0 Agent completed successfully\n 1 Error, aborted, or max turns reached\n 2 Timeout\n\nExamples:\n mastracode --prompt \"Fix the bug in auth.ts\"\n mastracode --prompt \"Add tests\" --timeout 300 --output json\n mastracode --prompt \"Refactor\" --output jsonl\n mastracode --prompt \"Review this PR\" --permission-mode deny --max-turns 10\n mastracode --settings ./settings-ci.json --prompt \"Run tests\"\n mastracode -c --prompt \"Continue where you left off\"\n echo \"Summarize the repo\" | mastracode --prompt -\n`);\n}\n\n/**\n * Headless CLI entry point: parse arguments, read stdin, initialize MastraCode,\n * run via `runMC`, render output, and exit with the mapped code.\n */\nexport async function runMCCli(predrainedInput?: string | null): Promise<never> {\n if (process.argv.includes('--help') || process.argv.includes('-h')) {\n printHeadlessUsage();\n process.exit(0);\n }\n\n let args: HeadlessArgs;\n try {\n args = parseHeadlessArgs(process.argv);\n } catch (e) {\n process.stderr.write(`Error: ${(e as Error).message}\\n`);\n process.exit(1);\n }\n\n let prompt = args.prompt;\n if (predrainedInput !== undefined) {\n prompt = predrainedInput ?? '';\n } else if (prompt === '-' || (!prompt && !process.stdin.isTTY)) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n prompt = Buffer.concat(chunks).toString('utf-8').trim();\n }\n\n if (!prompt) {\n printHeadlessUsage();\n process.stderr.write('Error: --prompt is required (or pipe via stdin)\\n');\n process.exit(1);\n }\n\n if (args.settings && !existsSync(args.settings)) {\n process.stderr.write(`Error: Settings file not found: ${args.settings}\\n`);\n process.exit(1);\n }\n\n const boot = await createMastraCode({ settingsPath: args.settings });\n const { controller, session, mcpManager, effectiveDefaults } = boot;\n\n if (mcpManager?.hasServers()) {\n try {\n await mcpManager.initInBackground();\n } catch (err) {\n process.stderr.write(`Warning: MCP server initialization failed: ${(err as Error).message ?? err}\\n`);\n }\n }\n\n setupDebugLogging();\n\n // Default to a non-zero exit so an unexpected throw before the run resolves\n // still surfaces as a failure to the caller / CI.\n let exitCode = 1;\n try {\n const humanState = createHumanFormatState();\n const run = runMC({\n controller,\n session,\n prompt,\n model: args.model,\n mode: args.mode,\n modeDefaults: effectiveDefaults,\n thinkingLevel: args.thinkingLevel,\n thread: { id: args.thread, continueLatest: args.continue_, clone: args.cloneThread },\n resourceId: args.resourceId,\n title: args.title,\n timeoutMs: args.timeout ? args.timeout * 1000 : undefined,\n maxTurns: args.maxTurns,\n policy: args.permissionMode ? permissionModeToPolicy(args.permissionMode) : undefined,\n });\n\n // Stream live events for human + jsonl modes. (json mode prints only the final object.)\n for await (const event of run) {\n if (args.output === 'human') {\n const out = formatHuman(event, humanState);\n if (out.stdout) process.stdout.write(out.stdout);\n if (out.stderr) process.stderr.write(out.stderr);\n } else if (args.output === 'jsonl') {\n process.stdout.write(JSON.stringify(formatJsonl(event)) + '\\n');\n }\n }\n\n const result = await run.result;\n exitCode = result.exitCode;\n\n if (args.output === 'json') {\n process.stdout.write(renderJsonResult(result));\n } else if (args.output === 'jsonl') {\n process.stdout.write(JSON.stringify({ type: 'result', ...result }) + '\\n');\n }\n\n if (result.status === 'timeout') {\n process.stderr.write(`\\nTimeout elapsed. Aborted.\\n`);\n } else if (result.error && args.output === 'human') {\n process.stderr.write(`Error: ${result.error.message}\\n`);\n }\n } catch (err) {\n process.stderr.write(`Error: ${(err as Error).message ?? err}\\n`);\n exitCode = 1;\n } finally {\n // --- Teardown (always runs, even on a thrown error) ---\n releaseAllThreadLocks();\n const closeSignalsPubSub = (boot.signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([\n mcpManager?.disconnect(),\n controller.getMastra()?.stopWorkers(),\n controller?.stopIntervals(),\n closeSignalsPubSub?.(),\n ]);\n }\n\n process.exit(exitCode);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../../src/headless/cli.ts"],"sourcesContent":["/**\n * CLI adapter for headless MastraCode runs.\n *\n * This is the only headless layer that touches the process: it parses argv,\n * reads stdin, bootstraps MastraCode via `createMastraCode`, drives `runMC`,\n * renders events/results to stdout/stderr through the pure formatters, maps the\n * result to an exit code, and owns teardown + `process.exit`.\n */\nimport { existsSync } from 'node:fs';\nimport { parseArgs } from 'node:util';\n\nimport { createMastraCode } from '../index.js';\nimport { setupDebugLogging } from '../utils/debug-log.js';\nimport { releaseAllThreadLocks } from '../utils/thread-lock.js';\n\nimport { buildParseArgsOptions, FLAGS, renderFlagUsage } from './flags.js';\nimport { createHumanFormatState, formatHuman, formatJsonl, renderJsonResult } from './format.js';\nimport { permissionModeToPolicy } from './policy.js';\nimport { runMC } from './run-mc.js';\nimport type { PermissionMode, RunMode, ThinkingLevel } from './types.js';\n\n/** Consolidated output mode (replaces the old `--format` + `--output-format`). */\nexport type OutputMode = 'human' | 'json' | 'jsonl';\n\nexport interface HeadlessArgs {\n prompt?: string;\n /** Timeout in seconds (CLI surface); converted to ms before `runMC`. */\n timeout?: number;\n output: OutputMode;\n continue_: boolean;\n model?: string;\n mode?: RunMode;\n thinkingLevel?: ThinkingLevel;\n settings?: string;\n thread?: string;\n title?: string;\n cloneThread: boolean;\n resourceId?: string;\n /** Max agentic turns before the run aborts with exit code 1. */\n maxTurns?: number;\n /** Named permission mode resolving to a built-in policy. Defaults to `auto`. */\n permissionMode?: PermissionMode;\n}\n\nconst parseArgsOptions = buildParseArgsOptions();\n\n/**\n * Returns true if `argv` selects headless mode. This must agree with what\n * {@link parseHeadlessArgs} (and `runMCCli`) accept as a prompt: `--prompt`/`-p`\n * or a bare positional prompt (e.g. `mastracode \"Fix the bug\"`). Note that a\n * prompt piped via stdin without a flag is handled separately by the caller.\n */\nexport function hasHeadlessFlag(argv: string[]): boolean {\n if (argv.some(a => a === '--prompt' || a === '-p')) return true;\n try {\n const { values, positionals } = parseArgs({\n args: argv.slice(2),\n options: parseArgsOptions,\n strict: false,\n allowPositionals: true,\n });\n // A positional prompt only counts when not asking for help.\n return positionals.length > 0 && !values.help;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse CLI arguments for headless mode. The flag table in `flags.ts` is the\n * single source of truth: each flag carries its own coercion/validation, so this\n * function just walks {@link FLAGS} and assembles the typed {@link HeadlessArgs}.\n */\nexport function parseHeadlessArgs(argv: string[]): HeadlessArgs {\n const { values, positionals } = parseArgs({\n args: argv.slice(2),\n options: parseArgsOptions,\n strict: false,\n allowPositionals: true,\n });\n\n // Seed defaults; per-flag values below override these.\n const args: HeadlessArgs = {\n output: 'human',\n continue_: false,\n cloneThread: false,\n };\n const sink = args as unknown as Record<string, unknown>;\n\n for (const flag of FLAGS) {\n if (!flag.field) continue; // e.g. --help, handled by the caller\n const raw = values[flag.key];\n if (raw === undefined) continue;\n\n if (flag.type === 'boolean') {\n sink[flag.field] = Boolean(raw);\n } else if (typeof raw === 'string') {\n sink[flag.field] = flag.coerce ? flag.coerce(raw) : raw;\n }\n }\n\n // A bare positional acts as the prompt when --prompt/-p is absent.\n if (args.prompt === undefined && positionals[0] !== undefined) {\n args.prompt = positionals[0];\n }\n\n if (args.continue_ && args.thread) {\n throw new Error('--continue and --thread cannot be used together');\n }\n\n return args;\n}\n\nexport function printHeadlessUsage(): void {\n process.stdout.write(`\nUsage: mastracode --prompt <text> [options]\n\nHeadless (non-interactive) mode options:\n${renderFlagUsage()}\n\nThread behavior:\n By default, a new thread is created for each run.\n Use --continue to resume the most recent thread, or --thread to target a specific one.\n Use --clone-thread to branch off a copy before running.\n\nSettings file:\n Uses the same settings.json as the interactive TUI. Pass --settings to use\n a custom settings file (e.g., settings-ci.json for CI). All model, pack,\n subagent, and OM configuration is resolved from settings at startup.\n\nExit codes:\n 0 Agent completed successfully\n 1 Error, aborted, or max turns reached\n 2 Timeout\n\nExamples:\n mastracode --prompt \"Fix the bug in auth.ts\"\n mastracode --prompt \"Add tests\" --timeout 300 --output json\n mastracode --prompt \"Refactor\" --output jsonl\n mastracode --prompt \"Review this PR\" --permission-mode deny --max-turns 10\n mastracode --settings ./settings-ci.json --prompt \"Run tests\"\n mastracode -c --prompt \"Continue where you left off\"\n echo \"Summarize the repo\" | mastracode --prompt -\n`);\n}\n\n/**\n * Headless CLI entry point: parse arguments, read stdin, initialize MastraCode,\n * run via `runMC`, render output, and exit with the mapped code.\n */\nexport async function runMCCli(predrainedInput?: string | null): Promise<never> {\n if (process.argv.includes('--help') || process.argv.includes('-h')) {\n printHeadlessUsage();\n process.exit(0);\n }\n\n let args: HeadlessArgs;\n try {\n args = parseHeadlessArgs(process.argv);\n } catch (e) {\n process.stderr.write(`Error: ${(e as Error).message}\\n`);\n process.exit(1);\n }\n\n let prompt = args.prompt;\n if (predrainedInput !== undefined) {\n prompt = predrainedInput ?? '';\n } else if (prompt === '-' || (!prompt && !process.stdin.isTTY)) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n prompt = Buffer.concat(chunks).toString('utf-8').trim();\n }\n\n if (!prompt) {\n printHeadlessUsage();\n process.stderr.write('Error: --prompt is required (or pipe via stdin)\\n');\n process.exit(1);\n }\n\n if (args.settings && !existsSync(args.settings)) {\n process.stderr.write(`Error: Settings file not found: ${args.settings}\\n`);\n process.exit(1);\n }\n\n const boot = await createMastraCode({ settingsPath: args.settings });\n const { controller, session, mcpManager, effectiveDefaults } = boot;\n\n if (mcpManager?.hasServers()) {\n try {\n await mcpManager.initInBackground();\n } catch (err) {\n process.stderr.write(`Warning: MCP server initialization failed: ${(err as Error).message ?? err}\\n`);\n }\n }\n\n setupDebugLogging();\n\n // Default to a non-zero exit so an unexpected throw before the run resolves\n // still surfaces as a failure to the caller / CI.\n let exitCode = 1;\n try {\n const humanState = createHumanFormatState();\n const run = runMC({\n controller,\n session,\n prompt,\n model: args.model,\n mode: args.mode,\n modeDefaults: effectiveDefaults,\n thinkingLevel: args.thinkingLevel,\n thread: { id: args.thread, continueLatest: args.continue_, clone: args.cloneThread },\n resourceId: args.resourceId,\n title: args.title,\n timeoutMs: args.timeout ? args.timeout * 1000 : undefined,\n maxTurns: args.maxTurns,\n policy: args.permissionMode ? permissionModeToPolicy(args.permissionMode) : undefined,\n });\n\n // Stream live events for human + jsonl modes. (json mode prints only the final object.)\n for await (const event of run) {\n if (args.output === 'human') {\n const out = formatHuman(event, humanState);\n if (out.stdout) process.stdout.write(out.stdout);\n if (out.stderr) process.stderr.write(out.stderr);\n } else if (args.output === 'jsonl') {\n process.stdout.write(JSON.stringify(formatJsonl(event)) + '\\n');\n }\n }\n\n const result = await run.result;\n exitCode = result.exitCode;\n\n if (args.output === 'json') {\n process.stdout.write(renderJsonResult(result));\n } else if (args.output === 'jsonl') {\n process.stdout.write(JSON.stringify({ type: 'result', ...result }) + '\\n');\n }\n\n if (result.status === 'timeout') {\n process.stderr.write(`\\nTimeout elapsed. Aborted.\\n`);\n } else if (result.error && args.output === 'human') {\n process.stderr.write(`Error: ${result.error.message}\\n`);\n }\n } catch (err) {\n process.stderr.write(`Error: ${(err as Error).message ?? err}\\n`);\n exitCode = 1;\n } finally {\n // --- Teardown (always runs, even on a thrown error) ---\n releaseAllThreadLocks();\n // Stop plugin-contributed signal providers (and the plugin reload listener)\n // before quiescing workers: a provider that keeps polling past this point\n // could dispatch into a controller that is shutting down.\n try {\n boot.stopPluginSignalProviders();\n } catch {\n // Best-effort — the process is exiting.\n }\n const closeSignalsPubSub = (boot.signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([\n mcpManager?.disconnect(),\n controller.getMastra()?.stopWorkers(),\n controller?.stopIntervals(),\n closeSignalsPubSub?.(),\n ]);\n }\n\n process.exit(exitCode);\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -128,6 +128,40 @@ export declare function createMastraCodeAgentController(config?: MastraCodeConfi
128
128
  sessionId: string;
129
129
  ownerId: string;
130
130
  setActiveSession: (session: Session<MastraCodeState>) => void;
131
+ /**
132
+ * Starts the signal providers contributed by plugins. Called by the
133
+ * composition layer once the controller is inited, because that is when a
134
+ * Mastra instance exists — a provider without one has no storage, and
135
+ * nothing else will hand it one: the Agent propagates Mastra only to the
136
+ * providers in its own `signals` array, which these deliberately are not in.
137
+ */
138
+ startPluginSignalProviders: () => void;
139
+ /**
140
+ * Stops every plugin-contributed signal provider and stops listening for
141
+ * plugin reloads. The inverse of `startPluginSignalProviders`, for an
142
+ * embedder that is done with this controller: a `pluginManager` shared
143
+ * across controllers (`MastraCodeConfig.pluginManager`) outlives any one of
144
+ * them, so without this its providers keep polling and its reload listener
145
+ * keeps firing for a controller that is gone.
146
+ */
147
+ stopPluginSignalProviders: () => void;
148
+ /**
149
+ * Hands Mastra to the statically configured input processors.
150
+ *
151
+ * The Agent does this itself, but only for processors configured as a
152
+ * plain array (`Array.isArray` in `__registerMastra`). This lane is a
153
+ * function so plugins can contribute to it, which takes those processors
154
+ * out of that branch — including any an embedder passed as
155
+ * `config.inputProcessors`, some of which need Mastra to work at all
156
+ * (`CostGuardProcessor` reads observability storage there). Doing it here
157
+ * keeps that unchanged.
158
+ *
159
+ * Plugin processors are deliberately not included: they come and go with
160
+ * their plugin, and the registry keeps the first instance registered under
161
+ * an id forever, which would leave a retired instance behind. Plugins
162
+ * reach Mastra through `getController()` on the plugin context instead.
163
+ */
164
+ registerConfiguredProcessorsWithMastra: () => void;
131
165
  }>;
132
166
  /**
133
167
  * Result of {@link createMastraCodeAgentController}: every shared resource plus the
@@ -175,6 +209,40 @@ export declare function bootLocalAgentController(config?: MastraCodeConfig): Pro
175
209
  sessionId: string;
176
210
  ownerId: string;
177
211
  setActiveSession: (session: Session<MastraCodeState>) => void;
212
+ /**
213
+ * Starts the signal providers contributed by plugins. Called by the
214
+ * composition layer once the controller is inited, because that is when a
215
+ * Mastra instance exists — a provider without one has no storage, and
216
+ * nothing else will hand it one: the Agent propagates Mastra only to the
217
+ * providers in its own `signals` array, which these deliberately are not in.
218
+ */
219
+ startPluginSignalProviders: () => void;
220
+ /**
221
+ * Stops every plugin-contributed signal provider and stops listening for
222
+ * plugin reloads. The inverse of `startPluginSignalProviders`, for an
223
+ * embedder that is done with this controller: a `pluginManager` shared
224
+ * across controllers (`MastraCodeConfig.pluginManager`) outlives any one of
225
+ * them, so without this its providers keep polling and its reload listener
226
+ * keeps firing for a controller that is gone.
227
+ */
228
+ stopPluginSignalProviders: () => void;
229
+ /**
230
+ * Hands Mastra to the statically configured input processors.
231
+ *
232
+ * The Agent does this itself, but only for processors configured as a
233
+ * plain array (`Array.isArray` in `__registerMastra`). This lane is a
234
+ * function so plugins can contribute to it, which takes those processors
235
+ * out of that branch — including any an embedder passed as
236
+ * `config.inputProcessors`, some of which need Mastra to work at all
237
+ * (`CostGuardProcessor` reads observability storage there). Doing it here
238
+ * keeps that unchanged.
239
+ *
240
+ * Plugin processors are deliberately not included: they come and go with
241
+ * their plugin, and the registry keeps the first instance registered under
242
+ * an id forever, which would leave a retired instance behind. Plugins
243
+ * reach Mastra through `getController()` on the plugin context instead.
244
+ */
245
+ registerConfiguredProcessorsWithMastra: () => void;
178
246
  }>;
179
247
  /** Result of {@link mountAgentControllerOnMastra}: shared handles plus the owning Mastra. */
180
248
  export type MountedMastraCode = MastraCodeAgentController & {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ import { hasExplicitOMConfiguration } from "./onboarding/om-settings.js";
29
29
  import { getAvailableModePacks, getAvailableOmPacks, selectPreferredOMPack } from "./onboarding/packs.js";
30
30
  import { getToolCategory } from "./permissions.js";
31
31
  import { PluginManager } from "./plugins/manager.js";
32
+ import { PluginSignalLane } from "./plugins/signal-lane.js";
32
33
  import { PlanRejectionAbortProcessor } from "./processors/plan-rejection-abort.js";
33
34
  import { stateSchema } from "./schema.js";
34
35
  import { mastraBrand } from "./theme-palette.js";
@@ -50,6 +51,7 @@ import { AgentController } from "@mastra/core/agent-controller";
50
51
  import { createCodingAgent } from "@mastra/core/coding-agent";
51
52
  import { PROVIDER_REGISTRY } from "@mastra/core/llm";
52
53
  import { Mastra } from "@mastra/core/mastra";
54
+ import { defaultNotificationDeliveryDecision } from "@mastra/core/notifications";
53
55
  import { AgentsMDInjector, PrefillErrorHandler, ProviderHistoryCompat, StreamErrorRetryProcessor, isBadRequestError } from "@mastra/core/processors";
54
56
  import { RequestContext } from "@mastra/core/request-context";
55
57
  import { InMemoryHarness, MastraCompositeStore } from "@mastra/core/storage";
@@ -201,6 +203,7 @@ async function createMastraCodeAgentController(config) {
201
203
  const homeDir = config?.homeDir ?? config?.initialState?.homeDir;
202
204
  const configDir = config?.configDir ?? ".mastracode";
203
205
  let activeSession;
206
+ let pluginRuntimeController;
204
207
  if (configDir !== ".mastracode") validateConfigDirName(configDir);
205
208
  try {
206
209
  process.loadEnvFile(path.join(cwd, ".env"));
@@ -324,60 +327,126 @@ async function createMastraCodeAgentController(config) {
324
327
  configDir,
325
328
  homeDir
326
329
  });
330
+ pluginManager?.setRuntime({
331
+ getController: () => pluginRuntimeController,
332
+ getActiveSession: () => activeSession
333
+ });
327
334
  const loadedPlugins = pluginManager ? await pluginManager.reload() : [];
328
335
  const pluginTools = pluginManager?.getPluginTools() ?? {};
329
336
  const outcomeScorer = createOutcomeScorer();
330
337
  const efficiencyScorer = createEfficiencyScorer();
338
+ const getNotificationStreamOptions = async ({ resourceId, threadId }) => {
339
+ const session = await controller.getSessionByResource(resourceId) ?? activeSession;
340
+ if (!session) return void 0;
341
+ const modeId = session.mode.get();
342
+ const defaultModeModelId = controller.listModes().find((mode) => mode.id === modeId)?.defaultModelId;
343
+ const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || "";
344
+ const requestContext = new RequestContext();
345
+ const agentControllerContext = {
346
+ controllerId: controller.id,
347
+ state: session.state.get(),
348
+ getState: () => session.state.get(),
349
+ setState: (updates) => session.state.set(updates),
350
+ threadId,
351
+ resourceId,
352
+ session: {
353
+ id: session.identity.getId(),
354
+ ownerId: session.identity.getOwnerId(),
355
+ modeId,
356
+ modelId,
357
+ state: {
358
+ get: () => session.state.get(),
359
+ set: (updates) => session.state.set(updates),
360
+ update: (updater) => session.state.update(updater)
361
+ }
362
+ },
363
+ workspace: session.getWorkspace(),
364
+ getSubagentModelId: (params) => session.subagents.model.get(params ?? {})
365
+ };
366
+ requestContext.set("controller", agentControllerContext);
367
+ return {
368
+ memory: {
369
+ thread: threadId,
370
+ resource: resourceId
371
+ },
372
+ requestContext,
373
+ maxSteps: 1e3,
374
+ savePerStep: false,
375
+ requireToolApproval: session.state.get().yolo !== true,
376
+ modelSettings: { temperature: 1 }
377
+ };
378
+ };
331
379
  const githubSignals = globalSettings.signals?.experimentalGithubSignals && !config?.disableGithubSignals ? new GithubSignals({
332
380
  cwd: project.rootPath,
333
381
  gitcrawlCommand: process.env.MASTRACODE_GITCRAWL_BIN ?? process.env.GITCRAWL_BIN ?? process.env.MASTRACODE_GITCRAWL_COMMAND ?? process.env.GITCRAWL_COMMAND,
334
- getNotificationStreamOptions: async ({ resourceId, threadId }) => {
335
- const session = await controller.getSessionByResource(resourceId) ?? activeSession;
336
- const modeId = session.mode.get();
337
- const defaultModeModelId = controller.listModes().find((mode) => mode.id === modeId)?.defaultModelId;
338
- const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || "";
339
- const requestContext = new RequestContext();
340
- const agentControllerContext = {
341
- controllerId: controller.id,
342
- state: session.state.get(),
343
- getState: () => session.state.get(),
344
- setState: (updates) => session.state.set(updates),
345
- threadId,
346
- resourceId,
347
- session: {
348
- id: session.identity.getId(),
349
- ownerId: session.identity.getOwnerId(),
350
- modeId,
351
- modelId,
352
- state: {
353
- get: () => session.state.get(),
354
- set: (updates) => session.state.set(updates),
355
- update: (updater) => session.state.update(updater)
356
- }
357
- },
358
- workspace: controller.getWorkspace(),
359
- getSubagentModelId: (params) => session.subagents.model.get(params ?? {})
360
- };
361
- requestContext.set("controller", agentControllerContext);
362
- return {
363
- memory: {
364
- thread: threadId,
365
- resource: resourceId
366
- },
367
- requestContext,
368
- maxSteps: 1e3,
369
- savePerStep: false,
370
- requireToolApproval: session.state.get().yolo !== true,
371
- modelSettings: { temperature: 1 }
372
- };
373
- }
382
+ getNotificationStreamOptions
374
383
  }) : void 0;
384
+ const mastraCodeInputProcessors = [
385
+ ...config?.inputProcessors ?? [],
386
+ new PlanRejectionAbortProcessor(),
387
+ new AgentsMDInjector({
388
+ isEnabled: ({ requestContext }) => {
389
+ const state = getInjectorSessionState(requestContext);
390
+ return state?.untrustedCheckout !== true || typeof state?.baseRef === "string";
391
+ },
392
+ getReader: ({ requestContext }) => {
393
+ const state = getInjectorSessionState(requestContext);
394
+ if (state?.untrustedCheckout !== true || typeof state?.baseRef !== "string") return void 0;
395
+ return createGitRefReminderReader(state?.projectPath ?? project.rootPath, state.baseRef);
396
+ },
397
+ getIgnoredInstructionPaths: ({ requestContext }) => {
398
+ const state = getInjectorSessionState(requestContext);
399
+ const projectPath = state?.projectPath ?? project.rootPath;
400
+ return getStaticallyLoadedInstructionPaths(projectPath, void 0, state?.untrustedCheckout === true && typeof state?.baseRef === "string" ? createGitRefInstructionReader(projectPath, state.baseRef) : void 0);
401
+ }
402
+ }),
403
+ new ProviderHistoryCompat()
404
+ ];
405
+ const taskSignalProvider = new TaskSignalProvider();
406
+ const NO_PLUGIN_PROCESSORS = {
407
+ input: [],
408
+ output: []
409
+ };
410
+ let pluginProcessorReadWarned = false;
411
+ const pluginSignalLane = pluginManager ? new PluginSignalLane({ reservedProviderIds: [taskSignalProvider.id, ...githubSignals ? [githubSignals.id] : []] }) : void 0;
412
+ let unsubscribePluginReload;
413
+ /**
414
+ * Plugin processors are read through a function so that enabling, disabling or
415
+ * updating a plugin takes effect on the next request rather than requiring a
416
+ * new agent. This runs before every LLM call, and also outside the request
417
+ * path when the Agent catalogues its configured processors — where a throw is
418
+ * swallowed into a debug log. So it only reads already-resolved state: no
419
+ * filesystem, no network, no construction, and it never throws.
420
+ */
421
+ const readPluginProcessors = () => {
422
+ try {
423
+ return pluginManager?.getPluginProcessors() ?? NO_PLUGIN_PROCESSORS;
424
+ } catch (error) {
425
+ if (!pluginProcessorReadWarned) {
426
+ pluginProcessorReadWarned = true;
427
+ console.warn("Failed to read plugin processors:", error);
428
+ }
429
+ return NO_PLUGIN_PROCESSORS;
430
+ }
431
+ };
375
432
  const codeAgent = createCodingAgent({
376
433
  id: CODE_AGENT_ID,
377
434
  name: "Code Agent",
378
435
  workspace: void 0,
379
436
  instructions: getDynamicInstructions,
380
437
  model: (ctx) => getDynamicModel(ctx, config?.settingsPath),
438
+ notifications: { deliveryPolicy: { decide: async (input) => {
439
+ const decision = defaultNotificationDeliveryDecision(input);
440
+ if (!input.record.resourceId) return decision;
441
+ const streamOptions = await getNotificationStreamOptions({
442
+ resourceId: input.record.resourceId,
443
+ threadId: input.record.threadId
444
+ });
445
+ return streamOptions ? {
446
+ ...decision,
447
+ streamOptions
448
+ } : decision;
449
+ } } },
381
450
  tools: createDynamicTools(mcpManager, config?.extraTools, config?.disabledTools, storage, pluginTools),
382
451
  hooks: createToolHooks(hookManager, config?.postToolObserver),
383
452
  scorers: {
@@ -393,7 +462,7 @@ async function createMastraCodeAgentController(config) {
393
462
  }
394
463
  }
395
464
  },
396
- signals: [new TaskSignalProvider(), ...githubSignals ? [githubSignals] : []],
465
+ signals: [taskSignalProvider, ...githubSignals ? [githubSignals] : []],
397
466
  goal: {
398
467
  judge: (ctx) => getGoalJudgeModel(ctx, config?.settingsPath),
399
468
  maxRuns: globalSettings.models.goalMaxTurns ?? 50,
@@ -401,27 +470,12 @@ async function createMastraCodeAgentController(config) {
401
470
  prompt: DEFAULT_GOAL_JUDGE_PROMPT,
402
471
  tools: getGoalJudgeTools
403
472
  },
404
- inputProcessors: [
405
- ...config?.inputProcessors ?? [],
406
- new PlanRejectionAbortProcessor(),
407
- new AgentsMDInjector({
408
- isEnabled: ({ requestContext }) => {
409
- const state = getInjectorSessionState(requestContext);
410
- return state?.untrustedCheckout !== true || typeof state?.baseRef === "string";
411
- },
412
- getReader: ({ requestContext }) => {
413
- const state = getInjectorSessionState(requestContext);
414
- if (state?.untrustedCheckout !== true || typeof state?.baseRef !== "string") return void 0;
415
- return createGitRefReminderReader(state?.projectPath ?? project.rootPath, state.baseRef);
416
- },
417
- getIgnoredInstructionPaths: ({ requestContext }) => {
418
- const state = getInjectorSessionState(requestContext);
419
- const projectPath = state?.projectPath ?? project.rootPath;
420
- return getStaticallyLoadedInstructionPaths(projectPath, void 0, state?.untrustedCheckout === true && typeof state?.baseRef === "string" ? createGitRefInstructionReader(projectPath, state.baseRef) : void 0);
421
- }
422
- }),
423
- new ProviderHistoryCompat()
473
+ inputProcessors: () => [
474
+ ...mastraCodeInputProcessors,
475
+ ...readPluginProcessors().input.map((entry) => entry.value),
476
+ ...pluginSignalLane?.getInputProcessors() ?? []
424
477
  ],
478
+ outputProcessors: () => [...readPluginProcessors().output.map((entry) => entry.value), ...pluginSignalLane?.getOutputProcessors() ?? []],
425
479
  errorProcessors: [
426
480
  new ProviderHistoryCompat(),
427
481
  new StreamErrorRetryProcessor({ matchers: [
@@ -570,6 +624,11 @@ async function createMastraCodeAgentController(config) {
570
624
  release: releaseThreadLock
571
625
  }
572
626
  });
627
+ pluginRuntimeController = controller;
628
+ if (pluginSignalLane && pluginManager) {
629
+ pluginSignalLane.sync(pluginManager.getPluginSignalProviders());
630
+ unsubscribePluginReload = pluginManager.onReload(() => pluginSignalLane.sync(pluginManager.getPluginSignalProviders()));
631
+ }
573
632
  return {
574
633
  controller,
575
634
  storage,
@@ -594,6 +653,55 @@ async function createMastraCodeAgentController(config) {
594
653
  ownerId,
595
654
  setActiveSession: (session) => {
596
655
  activeSession = session;
656
+ },
657
+ /**
658
+ * Starts the signal providers contributed by plugins. Called by the
659
+ * composition layer once the controller is inited, because that is when a
660
+ * Mastra instance exists — a provider without one has no storage, and
661
+ * nothing else will hand it one: the Agent propagates Mastra only to the
662
+ * providers in its own `signals` array, which these deliberately are not in.
663
+ */
664
+ startPluginSignalProviders: () => {
665
+ const mastra = controller.getMastra();
666
+ if (!pluginSignalLane || !mastra) return;
667
+ pluginSignalLane.setMastra(mastra, codeAgent);
668
+ },
669
+ /**
670
+ * Stops every plugin-contributed signal provider and stops listening for
671
+ * plugin reloads. The inverse of `startPluginSignalProviders`, for an
672
+ * embedder that is done with this controller: a `pluginManager` shared
673
+ * across controllers (`MastraCodeConfig.pluginManager`) outlives any one of
674
+ * them, so without this its providers keep polling and its reload listener
675
+ * keeps firing for a controller that is gone.
676
+ */
677
+ stopPluginSignalProviders: () => {
678
+ unsubscribePluginReload?.();
679
+ unsubscribePluginReload = void 0;
680
+ pluginSignalLane?.stopAll();
681
+ },
682
+ /**
683
+ * Hands Mastra to the statically configured input processors.
684
+ *
685
+ * The Agent does this itself, but only for processors configured as a
686
+ * plain array (`Array.isArray` in `__registerMastra`). This lane is a
687
+ * function so plugins can contribute to it, which takes those processors
688
+ * out of that branch — including any an embedder passed as
689
+ * `config.inputProcessors`, some of which need Mastra to work at all
690
+ * (`CostGuardProcessor` reads observability storage there). Doing it here
691
+ * keeps that unchanged.
692
+ *
693
+ * Plugin processors are deliberately not included: they come and go with
694
+ * their plugin, and the registry keeps the first instance registered under
695
+ * an id forever, which would leave a retired instance behind. Plugins
696
+ * reach Mastra through `getController()` on the plugin context instead.
697
+ */
698
+ registerConfiguredProcessorsWithMastra: () => {
699
+ const mastra = controller.getMastra();
700
+ if (!mastra) return;
701
+ for (const processor of mastraCodeInputProcessors) {
702
+ mastra.addProcessor(processor);
703
+ mastra.addProcessorConfiguration(processor, CODE_AGENT_ID, "input");
704
+ }
597
705
  }
598
706
  };
599
707
  }
@@ -646,6 +754,8 @@ async function bootLocalAgentController(config) {
646
754
  const { controller, sessionId, ownerId } = base;
647
755
  await controller.init();
648
756
  await controller.getMastra()?.startWorkers();
757
+ base.registerConfiguredProcessorsWithMastra();
758
+ base.startPluginSignalProviders();
649
759
  const session = await controller.createSession({
650
760
  id: sessionId,
651
761
  ownerId
@@ -723,6 +833,8 @@ async function prepareAgentControllerMount(config) {
723
833
  const finalize = async () => {
724
834
  await controller.init();
725
835
  await controller.getMastra()?.startWorkers();
836
+ base.registerConfiguredProcessorsWithMastra();
837
+ base.startPluginSignalProviders();
726
838
  };
727
839
  return {
728
840
  base,