mastracode 0.26.0-alpha.5 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/dist/acp/agent.d.ts +4 -4
  3. package/dist/acp/agent.d.ts.map +1 -1
  4. package/dist/acp/event-mapper.d.ts +3 -3
  5. package/dist/acp/event-mapper.d.ts.map +1 -1
  6. package/dist/acp/server.d.ts +2 -2
  7. package/dist/acp/server.d.ts.map +1 -1
  8. package/dist/{acp-7DQDVR3M.js → acp-G5OLW7EV.js} +12 -12
  9. package/dist/acp-G5OLW7EV.js.map +1 -0
  10. package/dist/{acp-NTTZEFVN.cjs → acp-YSYEXVBE.cjs} +15 -15
  11. package/dist/acp-YSYEXVBE.cjs.map +1 -0
  12. package/dist/acp.cjs +2 -2
  13. package/dist/acp.js +1 -1
  14. package/dist/agents/instructions.d.ts.map +1 -1
  15. package/dist/agents/mastracode-gateway.d.ts +8 -1
  16. package/dist/agents/mastracode-gateway.d.ts.map +1 -1
  17. package/dist/agents/memory.d.ts +1 -1
  18. package/dist/agents/model.d.ts +1 -1
  19. package/dist/agents/modes/build.d.ts +2 -2
  20. package/dist/agents/modes/build.d.ts.map +1 -1
  21. package/dist/agents/modes/explore.d.ts +2 -2
  22. package/dist/agents/modes/explore.d.ts.map +1 -1
  23. package/dist/agents/modes/plan.d.ts +2 -2
  24. package/dist/agents/modes/plan.d.ts.map +1 -1
  25. package/dist/agents/prompts/plan.d.ts +5 -4
  26. package/dist/agents/prompts/plan.d.ts.map +1 -1
  27. package/dist/agents/thread-caveman-state.d.ts +2 -2
  28. package/dist/agents/thread-caveman-state.d.ts.map +1 -1
  29. package/dist/agents/tool-availability.d.ts +5 -1
  30. package/dist/agents/tool-availability.d.ts.map +1 -1
  31. package/dist/{chunk-QO4KIOLG.js → chunk-GT3A3LAA.js} +221 -117
  32. package/dist/chunk-GT3A3LAA.js.map +1 -0
  33. package/dist/{chunk-IU477VVQ.js → chunk-IFUIWWGJ.js} +8 -8
  34. package/dist/chunk-IFUIWWGJ.js.map +1 -0
  35. package/dist/{chunk-DVBJN36L.cjs → chunk-KGBCGF6C.cjs} +47 -23
  36. package/dist/chunk-KGBCGF6C.cjs.map +1 -0
  37. package/dist/{chunk-L67CU2OP.js → chunk-LUSQ75XP.js} +233 -136
  38. package/dist/chunk-LUSQ75XP.js.map +1 -0
  39. package/dist/{chunk-F3TKSK3C.js → chunk-NDCWIAKG.js} +43 -21
  40. package/dist/chunk-NDCWIAKG.js.map +1 -0
  41. package/dist/{chunk-UW25EMMX.cjs → chunk-NUKVNLFS.cjs} +1160 -1063
  42. package/dist/chunk-NUKVNLFS.cjs.map +1 -0
  43. package/dist/{chunk-DPRNPXVC.cjs → chunk-VBH3L4LD.cjs} +8 -8
  44. package/dist/chunk-VBH3L4LD.cjs.map +1 -0
  45. package/dist/{chunk-MUZ2ZLWN.cjs → chunk-Z3HFSXTB.cjs} +256 -152
  46. package/dist/chunk-Z3HFSXTB.cjs.map +1 -0
  47. package/dist/cli.cjs +33 -33
  48. package/dist/cli.cjs.map +1 -1
  49. package/dist/cli.js +18 -18
  50. package/dist/cli.js.map +1 -1
  51. package/dist/evals/context-builder.d.ts +5 -5
  52. package/dist/evals/context-builder.d.ts.map +1 -1
  53. package/dist/headless.d.ts +3 -3
  54. package/dist/headless.d.ts.map +1 -1
  55. package/dist/index.cjs +10 -10
  56. package/dist/index.d.ts +36 -34
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1 -1
  59. package/dist/mcp/config.d.ts +6 -2
  60. package/dist/mcp/config.d.ts.map +1 -1
  61. package/dist/processors/plan-rejection-abort.d.ts.map +1 -1
  62. package/dist/tools/request-sandbox-access.d.ts.map +1 -1
  63. package/dist/tools/utils.d.ts +2 -2
  64. package/dist/tui/commands/api-keys.d.ts +15 -0
  65. package/dist/tui/commands/api-keys.d.ts.map +1 -1
  66. package/dist/tui/commands/clone.d.ts +1 -1
  67. package/dist/tui/commands/goal.d.ts +2 -2
  68. package/dist/tui/commands/goal.d.ts.map +1 -1
  69. package/dist/tui/commands/types.d.ts +3 -3
  70. package/dist/tui/commands/types.d.ts.map +1 -1
  71. package/dist/tui/components/assistant-message.d.ts +3 -3
  72. package/dist/tui/components/assistant-message.d.ts.map +1 -1
  73. package/dist/tui/components/help-overlay.d.ts +1 -1
  74. package/dist/tui/components/help-overlay.d.ts.map +1 -1
  75. package/dist/tui/components/login-selector.d.ts +1 -1
  76. package/dist/tui/components/om-progress.d.ts +2 -2
  77. package/dist/tui/components/om-progress.d.ts.map +1 -1
  78. package/dist/tui/components/plan-approval-inline.d.ts.map +1 -1
  79. package/dist/tui/components/task-progress.d.ts +1 -1
  80. package/dist/tui/components/thread-selector.d.ts +4 -4
  81. package/dist/tui/components/thread-selector.d.ts.map +1 -1
  82. package/dist/tui/event-dispatch.d.ts +3 -3
  83. package/dist/tui/event-dispatch.d.ts.map +1 -1
  84. package/dist/tui/handlers/agent-lifecycle.d.ts +1 -1
  85. package/dist/tui/handlers/agent-lifecycle.d.ts.map +1 -1
  86. package/dist/tui/handlers/message.d.ts +4 -4
  87. package/dist/tui/handlers/message.d.ts.map +1 -1
  88. package/dist/tui/handlers/prompts.d.ts +1 -1
  89. package/dist/tui/handlers/prompts.d.ts.map +1 -1
  90. package/dist/tui/handlers/types.d.ts +3 -2
  91. package/dist/tui/handlers/types.d.ts.map +1 -1
  92. package/dist/tui/mastra-tui.d.ts +3 -3
  93. package/dist/tui/mastra-tui.d.ts.map +1 -1
  94. package/dist/tui/render-messages.d.ts +4 -3
  95. package/dist/tui/render-messages.d.ts.map +1 -1
  96. package/dist/tui/setup.d.ts +1 -1
  97. package/dist/tui/setup.d.ts.map +1 -1
  98. package/dist/tui/state.d.ts +24 -10
  99. package/dist/tui/state.d.ts.map +1 -1
  100. package/dist/tui/status-line.d.ts.map +1 -1
  101. package/dist/tui.cjs +19 -19
  102. package/dist/tui.js +2 -2
  103. package/dist/utils/plan-diff.d.ts +25 -0
  104. package/dist/utils/plan-diff.d.ts.map +1 -0
  105. package/dist/utils/plans.d.ts +41 -12
  106. package/dist/utils/plans.d.ts.map +1 -1
  107. package/package.json +16 -16
  108. package/dist/acp-7DQDVR3M.js.map +0 -1
  109. package/dist/acp-NTTZEFVN.cjs.map +0 -1
  110. package/dist/chunk-DPRNPXVC.cjs.map +0 -1
  111. package/dist/chunk-DVBJN36L.cjs.map +0 -1
  112. package/dist/chunk-F3TKSK3C.js.map +0 -1
  113. package/dist/chunk-IU477VVQ.js.map +0 -1
  114. package/dist/chunk-L67CU2OP.js.map +0 -1
  115. package/dist/chunk-MUZ2ZLWN.cjs.map +0 -1
  116. package/dist/chunk-QO4KIOLG.js.map +0 -1
  117. package/dist/chunk-UW25EMMX.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { getPlansDir, setAuthStorage, loadSettings, MEMORY_GATEWAY_PROVIDER, getAvailableModePacks, getAvailableOmPacks, resolveModelDefaults, resolveOmRoleModel, releaseThreadLock, acquireThreadLock, saveSettings, OBSERVABILITY_AUTH_PREFIX, mastra, getCustomProviderId, getEffectiveThinkingLevel, createCodexMiddleware, THINKING_LEVEL_TO_REASONING_EFFORT, buildOpenAICodexOAuthFetch, openaiCodexProvider } from './chunk-F3TKSK3C.js';
1
+ import { getLocalPlansRelativeDir, getPlansDir, setAuthStorage, loadSettings, MEMORY_GATEWAY_PROVIDER, getAvailableModePacks, getAvailableOmPacks, resolveModelDefaults, resolveOmRoleModel, releaseThreadLock, acquireThreadLock, saveSettings, OBSERVABILITY_AUTH_PREFIX, mastra, getCustomProviderId, getEffectiveThinkingLevel, createCodexMiddleware, THINKING_LEVEL_TO_REASONING_EFFORT, buildOpenAICodexOAuthFetch, openaiCodexProvider, isPlanFilePath } from './chunk-NDCWIAKG.js';
2
2
  import { AuthStorage, DEFAULT_OM_MODEL_ID, DEFAULT_CONFIG_DIR, validateConfigDirName, detectProject, getResourceIdOverride, getStorageConfig, getObservabilityDatabasePath, getVectorDatabasePath, getCurrentGitBranchAsync, getOmScope, DEFAULT_REF_THRESHOLD, DEFAULT_OBS_THRESHOLD, getGitHubCopilotBaseUrl, fetchCopilotModels, getDatabasePath, COPILOT_HEADERS, getAppDataDir } from './chunk-Z5EMG7I2.js';
3
3
  import { getToolCategory, MC_TOOLS, TOOL_NAME_OVERRIDES } from './chunk-UOFNLVKF.js';
4
4
  import { createHash } from 'crypto';
@@ -7,7 +7,7 @@ import os__default, { hostname, homedir } from 'os';
7
7
  import * as path from 'path';
8
8
  import path__default, { normalize, join, dirname } from 'path';
9
9
  import { Agent } from '@mastra/core/agent';
10
- import { Harness } from '@mastra/core/harness';
10
+ import { AgentController } from '@mastra/core/agent-controller';
11
11
  import { PROVIDER_REGISTRY, MastraModelGateway, MastraGateway, ModelRouterLanguageModel, GATEWAY_AUTH_HEADER, GatewayRegistry } from '@mastra/core/llm';
12
12
  import { Mastra } from '@mastra/core/mastra';
13
13
  import { StreamErrorRetryProcessor, PrefillErrorHandler, ProviderHistoryCompat, AgentsMDInjector, isBadRequestError } from '@mastra/core/processors';
@@ -21,7 +21,7 @@ import { Observability, SensitiveDataFilter, MastraStorageExporter, MastraPlatfo
21
21
  import { spawn, execFile } from 'child_process';
22
22
  import { createTavilySearchTool, createTavilyExtractTool } from '@mastra/tavily';
23
23
  import { estimateTokenCount, sliceByTokens } from 'tokenx';
24
- import { LocalFilesystem, createWorkspaceTools, Workspace, LocalSandbox } from '@mastra/core/workspace';
24
+ import { LocalFilesystem, createWorkspaceTools, Workspace, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace';
25
25
  import { z } from 'zod';
26
26
  import * as fs from 'fs';
27
27
  import fs__default, { readFileSync, existsSync, mkdirSync, writeFileSync, renameSync } from 'fs';
@@ -316,7 +316,10 @@ When something breaks:
316
316
  `;
317
317
 
318
318
  // src/agents/prompts/plan.ts
319
- var planModePrompt = `
319
+ function planModePrompt(_ctx) {
320
+ const plansDir = getLocalPlansRelativeDir();
321
+ const examplePath = `${plansDir}/add-dark-mode.md`;
322
+ return `
320
323
  # Plan Mode \u2014 READ-ONLY (except plan files)
321
324
 
322
325
  You are in PLAN mode. Your job is to explore the codebase and design an implementation plan \u2014 NOT to make changes to the project.
@@ -329,7 +332,7 @@ This mode is **read-only for project files**. You must NOT modify the project.
329
332
  - Do NOT run commands that change state (no git commit, no npm install, no file creation)
330
333
  - Do NOT run build commands, tests, or scripts that have side effects
331
334
 
332
- The ONE exception is your plan file: you CAN write to \`.mastracode/plans/\` to create and edit your plan.
335
+ The ONE exception is plan files: you CAN create and edit markdown files inside \`${plansDir}/\` (e.g. \`${examplePath}\`). You may NOT write anywhere else.
333
336
 
334
337
  If the user asks you to make changes while in Plan mode, explain that you're in read-only mode and they should switch to Build mode (\`/mode build\`) first.
335
338
 
@@ -375,24 +378,25 @@ For each step:
375
378
 
376
379
  ## Plan File Workflow
377
380
 
378
- Your plan lives as a \`.md\` file in \`.mastracode/plans/\` \u2014 the filename is derived from your plan title (e.g. \`add-dark-mode-toggle.md\`). Use regular workspace tools to manage it:
381
+ Write each plan to its own markdown file under \`${plansDir}/\` (e.g. \`${examplePath}\`). Start the file with a \`# Title\` heading describing the plan.
379
382
 
380
- 1. **First submission**: Write your plan to \`.mastracode/plans/<slug>.md\` using \`write_file\`, then call \`submit_plan\` with the plan content.
381
- 2. **Reading**: Use \`view\` to read the plan file.
383
+ 1. **First submission**: Write your plan to a file under \`${plansDir}/\` using \`write_file\`, then call \`submit_plan\` with the \`path\` to that file.
384
+ 2. **Reading**: Use \`view\` to read a plan file.
382
385
  3. **Editing**: Use \`string_replace_lsp\` for targeted edits to specific sections.
383
386
 
387
+ **Reuse the same file while you keep iterating on the same plan.** Only create a NEW file when you're starting a genuinely different plan \u2014 that keeps each plan available to look back at and keeps revision diffs meaningful.
388
+
384
389
  ## IMMEDIATE ACTION: Write plan file, then call submit_plan
385
390
 
386
391
  As soon as your plan is complete:
387
- 1. Write it to \`.mastracode/plans/<slug>.md\` (slugified from your title) using \`write_file\`
388
- 2. Call \`submit_plan\` with the plan content
392
+ 1. Write it to a file under \`${plansDir}/\` using \`write_file\`
393
+ 2. Call \`submit_plan\` with the \`path\` to that file
389
394
 
390
- **CRITICAL:** Do NOT generate a long text response describing your plan. The plan content belongs in the file and the \`submit_plan\` tool call, not in your text output.
395
+ **CRITICAL:** Do NOT generate a long text response describing your plan. The plan content belongs in the plan file, not in your text output or the \`submit_plan\` arguments.
391
396
 
392
397
  \`\`\`javascript
393
398
  submit_plan({
394
- title: "short descriptive title",
395
- plan: "your full plan in markdown"
399
+ path: "${examplePath}"
396
400
  })
397
401
  \`\`\`
398
402
 
@@ -404,17 +408,16 @@ The user will see the plan rendered inline and can:
404
408
  ## Revision Workflow
405
409
 
406
410
  If the user requests changes, you will be stopped immediately. Wait for their next message \u2014 it will contain their revision feedback. When you receive it:
407
- 1. Use \`view\` to read your plan file in \`.mastracode/plans/\`
411
+ 1. Use \`view\` to read the SAME plan file
408
412
  2. Use \`string_replace_lsp\` to make targeted edits based on feedback
409
413
  3. Use \`view\` to re-read the updated file
410
- 4. Call \`submit_plan\` again with the full updated plan content
414
+ 4. Call \`submit_plan\` again with the same \`path\` \u2014 editing the file alone does NOT resubmit it
411
415
 
412
- The user will see a diff of what changed between the previous and revised plan. Use \`string_replace_lsp\` for targeted edits so the diff is clear and meaningful \u2014 do NOT rewrite the entire plan from scratch for small changes.
413
-
414
- **IMPORTANT**: If a plan file already exists in \`.mastracode/plans/\`, you previously submitted a plan that was rejected. Read it to see your previous attempt before revising.
416
+ The user will see a diff of what changed between the previous and revised plan. Use \`string_replace_lsp\` for targeted edits so the diff is clear and meaningful \u2014 do NOT rewrite the entire plan from scratch for small changes, and do NOT move the plan to a new file for a revision.
415
417
 
416
418
  Do NOT start implementing until the plan is approved.
417
419
  `;
420
+ }
418
421
 
419
422
  // src/agents/prompts/fast.ts
420
423
  var fastModePrompt = `
@@ -505,10 +508,62 @@ Error: ${r.error}`);
505
508
  }
506
509
  });
507
510
  }
508
-
509
- // src/agents/tool-availability.ts
511
+ var PLAN_MODE_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set([
512
+ WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE,
513
+ WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE
514
+ ]);
515
+ function getRequestContextValue(requestContext, key) {
516
+ if (!requestContext) return void 0;
517
+ if (typeof requestContext.get === "function") {
518
+ return requestContext.get(key);
519
+ }
520
+ return requestContext[key];
521
+ }
522
+ function getHarnessContext(context) {
523
+ const requestContext = context?.requestContext;
524
+ const harness = getRequestContextValue(requestContext, "harness");
525
+ return harness && typeof harness === "object" ? harness : void 0;
526
+ }
527
+ function getHarnessState(harness) {
528
+ const state = harness?.session?.state?.get?.();
529
+ return state && typeof state === "object" ? state : void 0;
530
+ }
531
+ function getHarnessModeId(harness) {
532
+ const modeId = harness?.session?.modeId ?? getHarnessState(harness)?.modeId;
533
+ return typeof modeId === "string" ? modeId : void 0;
534
+ }
535
+ function getHarnessProjectPath(harness) {
536
+ const projectPath = getHarnessState(harness)?.projectPath;
537
+ return typeof projectPath === "string" ? projectPath : void 0;
538
+ }
539
+ function getToolInputPath(input) {
540
+ const toolPath = input?.path;
541
+ return typeof toolPath === "string" ? toolPath : void 0;
542
+ }
543
+ var PLAN_DIR_HINT = `${getLocalPlansRelativeDir()}/`;
544
+ function guardPlanModePlanFileWrites({ workspaceToolName, input, context }) {
545
+ if (!PLAN_MODE_WRITE_TOOL_NAMES.has(workspaceToolName)) return;
546
+ const harness = getHarnessContext(context);
547
+ if (getHarnessModeId(harness) !== "plan") return;
548
+ const projectPath = getHarnessProjectPath(harness);
549
+ const inputPath = getToolInputPath(input);
550
+ if (!projectPath || !inputPath) {
551
+ return {
552
+ proceed: false,
553
+ output: `Plan mode can only write plan files inside ${PLAN_DIR_HINT}.`
554
+ };
555
+ }
556
+ if (isPlanFilePath(projectPath, inputPath)) return;
557
+ return {
558
+ proceed: false,
559
+ output: `Plan mode can only write plan files inside ${PLAN_DIR_HINT}. Refusing to edit ${inputPath}.`
560
+ };
561
+ }
510
562
  var MASTRACODE_WORKSPACE_TOOLS = {
511
- ...TOOL_NAME_OVERRIDES
563
+ ...TOOL_NAME_OVERRIDES,
564
+ hooks: {
565
+ beforeToolCall: guardPlanModePlanFileWrites
566
+ }
512
567
  };
513
568
  var PLAN_MODE_AVAILABLE_TOOLS = [
514
569
  // Read-only exploration tools
@@ -517,9 +572,8 @@ var PLAN_MODE_AVAILABLE_TOOLS = [
517
572
  MC_TOOLS.SEARCH_CONTENT,
518
573
  MC_TOOLS.FILE_STAT,
519
574
  MC_TOOLS.LSP_INSPECT,
520
- // Plan file writing (visibility gated by availableTools; the shared workspace
521
- // is mode-agnostic and does not path-restrict these plan-mode instructions
522
- // scope writes to .mastracode/plans/)
575
+ // Plan file writing. Tool hooks enforce that these can only write `.md`
576
+ // files inside `.mastracode/plans/` while the session is in plan mode.
523
577
  MC_TOOLS.WRITE_FILE,
524
578
  MC_TOOLS.STRING_REPLACE_LSP,
525
579
  // Plan delivery tools
@@ -623,7 +677,7 @@ function detectPackageRunner(projectPath) {
623
677
  return "npx --yes";
624
678
  }
625
679
  function getDynamicWorkspace({ requestContext, mastra: mastra2 }) {
626
- const ctx = requestContext.get("harness");
680
+ const ctx = requestContext.get("controller");
627
681
  const state = ctx?.getState();
628
682
  const rawProjectPath = state?.projectPath;
629
683
  if (!rawProjectPath) {
@@ -695,8 +749,8 @@ function isPathAllowed(targetPath, projectRoot, allowedPaths = []) {
695
749
  return roots.some((root) => resolved === root || resolved.startsWith(root + path.sep));
696
750
  }
697
751
  function getAllowedPathsFromContext(toolContext) {
698
- const harnessCtx = toolContext?.requestContext?.get("harness");
699
- const state = harnessCtx?.getState?.() ?? harnessCtx?.session?.state?.get?.();
752
+ const agentControllerCtx = toolContext?.requestContext?.get("controller");
753
+ const state = agentControllerCtx?.getState?.() ?? agentControllerCtx?.session?.state?.get?.();
700
754
  const projectPath = state?.projectPath ? path.resolve(state.projectPath) : process.cwd();
701
755
  const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;
702
756
  const skillPaths = buildSkillPaths(projectPath, configDir);
@@ -726,7 +780,7 @@ var requestSandboxAccessTool = createTool({
726
780
  resumeSchema: z.union([z.string(), z.array(z.string())]),
727
781
  execute: async ({ path: requestedPath, reason }, context) => {
728
782
  try {
729
- const harnessCtx = context?.requestContext?.get("harness");
783
+ const agentControllerCtx = context?.requestContext?.get("controller");
730
784
  const expanded = expandTilde(requestedPath);
731
785
  const absolutePath = path.isAbsolute(expanded) ? expanded : path.resolve(process.cwd(), expanded);
732
786
  const projectRoot = process.cwd();
@@ -752,13 +806,13 @@ var requestSandboxAccessTool = createTool({
752
806
  const answerText = Array.isArray(resumeData) ? resumeData.join(", ") : String(resumeData);
753
807
  const approved = answerText.toLowerCase().startsWith("y") || answerText.toLowerCase() === "approve";
754
808
  if (approved) {
755
- const currentAllowed = harnessCtx?.getState()?.sandboxAllowedPaths ?? [];
809
+ const currentAllowed = agentControllerCtx?.getState()?.sandboxAllowedPaths ?? [];
756
810
  if (!currentAllowed.includes(absolutePath)) {
757
- await harnessCtx?.setState({
811
+ await agentControllerCtx?.setState({
758
812
  sandboxAllowedPaths: [...currentAllowed, absolutePath]
759
813
  });
760
814
  }
761
- const fs4 = harnessCtx?.workspace?.filesystem ?? context?.workspace?.filesystem;
815
+ const fs4 = agentControllerCtx?.workspace?.filesystem ?? context?.workspace?.filesystem;
762
816
  if (fs4 instanceof LocalFilesystem) {
763
817
  fs4.setAllowedPaths((prev) => [...prev, absolutePath]);
764
818
  }
@@ -1033,14 +1087,14 @@ ${patchToolGuidance}
1033
1087
  - Call this tool when your plan is complete. Do NOT just describe your plan in text \u2014 you MUST call this tool.
1034
1088
  - The plan will be rendered as markdown and the user can approve, reject, or request changes.
1035
1089
  - On approval, the system automatically switches to the default mode so you can implement.
1036
- - Takes two arguments: \`title\` (short descriptive title) and \`plan\` (full plan in markdown).`);
1090
+ - Takes one argument: \`path\` (the plan markdown file you wrote under \`.mastracode/plans/\`). Do NOT pass the plan body \u2014 it lives in the file.`);
1037
1091
  }
1038
1092
  if (modeId === "plan") {
1039
1093
  sections.push(`
1040
- **Plan file access** \u2014 Your plan lives in \`.mastracode/plans/\` with a filename derived from the title (e.g. \`add-dark-mode-toggle.md\`)
1094
+ **Plan file access** \u2014 Your plan lives in a markdown file under \`.mastracode/plans/\` (e.g. \`add-dark-mode-toggle.md\`)
1041
1095
  - Use \`write_file\` to create the plan file, \`view\` to read it, and \`string_replace_lsp\` for targeted edits.
1042
- - On first submission: write the plan to the file, then call \`submit_plan\`.
1043
- - On revision: read the existing file, edit specific sections, re-read, then call \`submit_plan\` with updated content.
1096
+ - On first submission: write the plan to the file, then call \`submit_plan\` with its \`path\`.
1097
+ - On revision: read the existing file, edit specific sections, re-read, then call \`submit_plan\` with the same \`path\`.
1044
1098
  - If a plan file already exists, you previously submitted it \u2014 read it before revising.`);
1045
1099
  }
1046
1100
  if (!denied.has("subagent")) {
@@ -1093,9 +1147,9 @@ function buildFullPrompt(ctx) {
1093
1147
 
1094
1148
  // src/agents/instructions.ts
1095
1149
  async function getDynamicInstructions({ requestContext }) {
1096
- const harnessContext = requestContext.get("harness");
1097
- const state = harnessContext?.getState();
1098
- const modeId = harnessContext?.session?.modeId ?? "build";
1150
+ const agentControllerContext = requestContext.get("controller");
1151
+ const state = agentControllerContext?.getState();
1152
+ const modeId = agentControllerContext?.session?.modeId ?? "build";
1099
1153
  const projectPath = state?.projectPath ?? process.cwd();
1100
1154
  const promptCtx = {
1101
1155
  projectPath,
@@ -1105,7 +1159,7 @@ async function getDynamicInstructions({ requestContext }) {
1105
1159
  commonBinaries: await detectCommonBinariesAsync(),
1106
1160
  date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
1107
1161
  mode: modeId,
1108
- modelId: harnessContext?.session?.modelId || void 0,
1162
+ modelId: agentControllerContext?.session?.modelId || void 0,
1109
1163
  activePlan: state?.activePlan ?? null,
1110
1164
  modeId,
1111
1165
  currentDate: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
@@ -1668,6 +1722,29 @@ var MastraCodeGateway = class _MastraCodeGateway extends MastraModelGateway {
1668
1722
  static getMemoryGatewayApiKey() {
1669
1723
  return authStorage.getStoredApiKey(MEMORY_GATEWAY_PROVIDER) ?? process.env["MASTRA_GATEWAY_API_KEY"];
1670
1724
  }
1725
+ /**
1726
+ * Claim an unprefixed model id (e.g. a bare `anthropic/...`) when this gateway
1727
+ * can authenticate it via OAuth or a stored/env credential. This lets the
1728
+ * shared gateway router select MastraCode for auth resolution, so the status
1729
+ * bar and `/api-keys` reflect OAuth logins instead of only checking env vars.
1730
+ */
1731
+ handlesModel(modelId) {
1732
+ const parsed = parseGatewayRouterId(modelId, this);
1733
+ if (!parsed.providerId || !parsed.modelId) return false;
1734
+ if (this.#routeThroughMastraGateway && this.#mastraGatewayApiKey) return true;
1735
+ const customProvider = this.#getCustomProviders().find(
1736
+ (provider) => parsed.providerId === getCustomProviderId(provider.name)
1737
+ );
1738
+ if (customProvider?.apiKey) return true;
1739
+ return hasResolvedAuth(
1740
+ _MastraCodeGateway.resolveProviderAuth({
1741
+ gatewayId: this.id,
1742
+ providerId: parsed.providerId,
1743
+ modelId: parsed.modelId,
1744
+ routerId: modelId
1745
+ })
1746
+ );
1747
+ }
1671
1748
  static resolveProviderAuth(request, memoryGatewayApiKey) {
1672
1749
  if (request.gatewayId === "mastra" && memoryGatewayApiKey) {
1673
1750
  return { apiKey: memoryGatewayApiKey, source: "gateway" };
@@ -1878,11 +1955,11 @@ var MastraCodeGateway = class _MastraCodeGateway extends MastraModelGateway {
1878
1955
  };
1879
1956
 
1880
1957
  // src/agents/model.ts
1881
- function getHarnessHeaders(requestContext) {
1882
- const harnessContext = requestContext?.get("harness");
1958
+ function getAgentControllerHeaders(requestContext) {
1959
+ const agentControllerContext = requestContext?.get("controller");
1883
1960
  const headers = {
1884
- ...harnessContext?.threadId ? { "x-thread-id": harnessContext.threadId } : {},
1885
- ...harnessContext?.resourceId ? { "x-resource-id": harnessContext.resourceId } : {}
1961
+ ...agentControllerContext?.threadId ? { "x-thread-id": agentControllerContext.threadId } : {},
1962
+ ...agentControllerContext?.resourceId ? { "x-resource-id": agentControllerContext.resourceId } : {}
1886
1963
  };
1887
1964
  return Object.keys(headers).length > 0 ? headers : void 0;
1888
1965
  }
@@ -1891,7 +1968,7 @@ function createMastraCodeGateway(options) {
1891
1968
  }
1892
1969
  function resolveModel(modelId, options) {
1893
1970
  reloadAuthStorage();
1894
- const headers = getHarnessHeaders(options?.requestContext);
1971
+ const headers = getAgentControllerHeaders(options?.requestContext);
1895
1972
  const settings = loadSettings();
1896
1973
  const isMastraGatewayModel = modelId.startsWith(MASTRA_GATEWAY_PREFIX);
1897
1974
  const normalizedModelId = stripMastraGatewayPrefix(modelId);
@@ -1924,12 +2001,12 @@ function resolveModel(modelId, options) {
1924
2001
  });
1925
2002
  }
1926
2003
  function getDynamicModel({ requestContext }) {
1927
- const harnessContext = requestContext.get("harness");
1928
- const modelId = harnessContext?.session?.modelId;
2004
+ const agentControllerContext = requestContext.get("controller");
2005
+ const modelId = agentControllerContext?.session?.modelId;
1929
2006
  if (!modelId) {
1930
2007
  throw new Error("No model selected. Use /models to select a model first.");
1931
2008
  }
1932
- const thinkingLevel = harnessContext?.state?.thinkingLevel;
2009
+ const thinkingLevel = agentControllerContext?.state?.thinkingLevel;
1933
2010
  return resolveModel(modelId, { thinkingLevel, requestContext });
1934
2011
  }
1935
2012
  function getGoalJudgeModel({ requestContext }, settingsPath) {
@@ -1941,18 +2018,18 @@ function getGoalJudgeModel({ requestContext }, settingsPath) {
1941
2018
  // src/agents/memory.ts
1942
2019
  var cachedMemory = null;
1943
2020
  var cachedMemoryKey = null;
1944
- function getHarnessState(requestContext) {
1945
- const ctx = requestContext.get("harness");
2021
+ function getAgentControllerState(requestContext) {
2022
+ const ctx = requestContext.get("controller");
1946
2023
  return ctx?.getState();
1947
2024
  }
1948
2025
  function getObserverModel({ requestContext }) {
1949
- const state = getHarnessState(requestContext);
2026
+ const state = getAgentControllerState(requestContext);
1950
2027
  return resolveModel(state?.observerModelId ?? DEFAULT_OM_MODEL_ID, {
1951
2028
  requestContext
1952
2029
  });
1953
2030
  }
1954
2031
  function getReflectorModel({ requestContext }) {
1955
- const state = getHarnessState(requestContext);
2032
+ const state = getAgentControllerState(requestContext);
1956
2033
  return resolveModel(state?.reflectorModelId ?? DEFAULT_OM_MODEL_ID, {
1957
2034
  requestContext
1958
2035
  });
@@ -1982,7 +2059,7 @@ Don't say "Agent did x", say "did x". It will be assumed the agent did what was
1982
2059
  Drop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question, and anything that requires remembering verbatim content. Resume caveman after clear part done`;
1983
2060
  function getDynamicMemory(storage, vector) {
1984
2061
  return ({ requestContext }) => {
1985
- const state = getHarnessState(requestContext);
2062
+ const state = getAgentControllerState(requestContext);
1986
2063
  const omScope = state?.omScope ?? getOmScope(state?.projectPath);
1987
2064
  const obsThreshold = state?.observationThreshold ?? DEFAULT_OBS_THRESHOLD;
1988
2065
  const refThreshold = state?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD;
@@ -2125,7 +2202,7 @@ var planMode = {
2125
2202
 
2126
2203
  ## Rules
2127
2204
  - You have READ-ONLY access to the project. You cannot modify project files or run commands.
2128
- - The one exception is the plan file: you can write and edit files in \`.mastracode/plans/\` using \`write_file\`, \`view\`, and \`string_replace_lsp\`.
2205
+ - The one exception is plan files: you can create and edit markdown files inside \`.mastracode/plans/\` using \`write_file\`, \`view\`, and \`string_replace_lsp\`. You may not write anywhere else.
2129
2206
  - First, explore the codebase to understand existing patterns, architecture, and conventions.
2130
2207
  - Produce a concrete, actionable plan \u2014 not vague suggestions.
2131
2208
 
@@ -2136,11 +2213,13 @@ var planMode = {
2136
2213
  - **Parallelize**: Make multiple independent tool calls when exploring different areas
2137
2214
 
2138
2215
  ## Plan Delivery
2139
- - Write your plan to \`.mastracode/plans/<slug>.md\` (slugified from your title) using \`write_file\`, then call \`submit_plan\`.
2140
- - Do NOT output the plan as text \u2014 it MUST go through the submit_plan tool call.
2216
+ - Write your plan to a markdown file under \`.mastracode/plans/\` (e.g. \`.mastracode/plans/add-dark-mode.md\`) using \`write_file\`, then call \`submit_plan({ path })\` with the path to that file (never the plan body).
2217
+ - Start the file with a \`# Title\` heading describing the plan.
2218
+ - Reuse the same file while iterating on the same plan; only create a new file for a genuinely different plan so each plan stays available to review.
2219
+ - Do NOT output the plan as text \u2014 it MUST live in the plan file.
2141
2220
  - Be concise: reference files by path and line number, don't include raw contents.
2142
2221
  - Focus on actionable details, not general observations.
2143
- - If a plan file already exists in \`.mastracode/plans/\`, you previously submitted a plan \u2014 read it before revising.`,
2222
+ - To revise after "Request changes", edit the same file in place with \`string_replace_lsp\`, and call \`submit_plan\` again with the same path.`,
2144
2223
  metadata: {
2145
2224
  default: false
2146
2225
  },
@@ -2265,7 +2344,7 @@ function createToolHooks(hookManager) {
2265
2344
  }
2266
2345
  function createDynamicTools(mcpManager, extraTools, disabledTools, storage) {
2267
2346
  return function getDynamicTools({ requestContext }) {
2268
- const ctx = requestContext.get("harness");
2347
+ const ctx = requestContext.get("controller");
2269
2348
  const state = ctx?.getState();
2270
2349
  const modelId = ctx?.session?.modelId;
2271
2350
  const isAnthropicModel = modelId?.startsWith("anthropic/");
@@ -3148,12 +3227,16 @@ var HookManager = class {
3148
3227
  function loadMcpConfig(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
3149
3228
  const claudeConfig = loadClaudeSettings(projectDir);
3150
3229
  const globalConfig = loadSingleConfig2(getGlobalMcpPath(configDirName));
3230
+ const rootConfig = loadSingleConfig2(getRootMcpPath(projectDir));
3151
3231
  const projectConfig = loadSingleConfig2(getProjectMcpPath(projectDir, configDirName));
3152
- return mergeConfigs2(claudeConfig, globalConfig, projectConfig);
3232
+ return mergeConfigs2(claudeConfig, globalConfig, rootConfig, projectConfig);
3153
3233
  }
3154
3234
  function getProjectMcpPath(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
3155
3235
  return path.join(projectDir, configDirName, "mcp.json");
3156
3236
  }
3237
+ function getRootMcpPath(projectDir) {
3238
+ return path.join(projectDir, ".mcp.json");
3239
+ }
3157
3240
  function getGlobalMcpPath(configDirName = DEFAULT_CONFIG_DIR) {
3158
3241
  return path.join(os.homedir(), configDirName, "mcp.json");
3159
3242
  }
@@ -3693,6 +3776,21 @@ function createMcpManager(projectDir, configDirName = DEFAULT_CONFIG_DIR, extraS
3693
3776
 
3694
3777
  // src/processors/plan-rejection-abort.ts
3695
3778
  var PLAN_REJECTED_PREFIX = "Plan was not approved";
3779
+ function resultText(result) {
3780
+ if (typeof result === "string") return result;
3781
+ if (result && typeof result === "object") {
3782
+ const content = result.content;
3783
+ if (typeof content === "string") return content;
3784
+ }
3785
+ return "";
3786
+ }
3787
+ function isPlanRejection(inv) {
3788
+ if (!inv || inv.state !== "result" || inv.toolName !== "submit_plan") return false;
3789
+ return resultText(inv.result).startsWith(PLAN_REJECTED_PREFIX);
3790
+ }
3791
+ function isPlanRejectionResultPart(part) {
3792
+ return part.type === "tool_result" && part.name === "submit_plan" && resultText(part.result).startsWith(PLAN_REJECTED_PREFIX);
3793
+ }
3696
3794
  var PlanRejectionAbortProcessor = class {
3697
3795
  id = "plan-rejection-abort";
3698
3796
  async processInputStep({ messages, stepNumber, abort }) {
@@ -3701,18 +3799,24 @@ var PlanRejectionAbortProcessor = class {
3701
3799
  const msg = messages[i];
3702
3800
  if (!msg || msg.role !== "assistant") continue;
3703
3801
  const content = msg.content;
3704
- const parts = content?.parts;
3705
- if (!Array.isArray(parts)) break;
3802
+ const parts = Array.isArray(content) ? content : Array.isArray(content?.parts) ? content.parts : [];
3706
3803
  for (const part of parts) {
3707
3804
  if (!part || typeof part !== "object") continue;
3708
3805
  const p = part;
3709
- if (p.type !== "tool-invocation") continue;
3710
- const inv = p.toolInvocation;
3711
- if (!inv || inv.state !== "result" || inv.toolName !== "submit_plan") continue;
3712
- const result = inv.result;
3713
- const text = typeof result === "string" ? result : typeof result?.content === "string" ? result.content : "";
3714
- if (text.startsWith(PLAN_REJECTED_PREFIX)) {
3806
+ if (p.type === "tool-invocation" && isPlanRejection(p.toolInvocation)) {
3807
+ abort("Plan rejected by user \u2014 no further response needed");
3808
+ return void 0;
3809
+ }
3810
+ if (isPlanRejectionResultPart(p)) {
3811
+ abort("Plan rejected by user \u2014 no further response needed");
3812
+ return void 0;
3813
+ }
3814
+ }
3815
+ const legacy = !Array.isArray(content) && Array.isArray(content?.toolInvocations) ? content.toolInvocations : [];
3816
+ for (const inv of legacy) {
3817
+ if (isPlanRejection(inv)) {
3715
3818
  abort("Plan rejected by user \u2014 no further response needed");
3819
+ return void 0;
3716
3820
  }
3717
3821
  }
3718
3822
  break;
@@ -3721,10 +3825,10 @@ var PlanRejectionAbortProcessor = class {
3721
3825
  }
3722
3826
  };
3723
3827
  var stateSchema = z.object({
3724
- // Session-scoped selection. The legacy Harness stores these in its state and
3828
+ // Session-scoped selection.
3725
3829
  // validates state against this schema, so they MUST be declared here — Zod
3726
3830
  // strips unknown keys on parse, which would otherwise silently discard the
3727
- // seeded model and leave the harness with no model selected.
3831
+ // seeded model and leave the controller with no model selected.
3728
3832
  currentModelId: z.string().optional(),
3729
3833
  modeId: z.string().optional(),
3730
3834
  subagentModelId: z.string().optional(),
@@ -4046,7 +4150,7 @@ function resolveCloudObservabilityConfig(settings, authStorage2, resourceId) {
4046
4150
  projectId: process.env.MASTRA_PROJECT_ID
4047
4151
  };
4048
4152
  }
4049
- async function createMastraCodeHarness(config) {
4153
+ async function createMastraCodeAgentController(config) {
4050
4154
  const cwd = config?.cwd ?? process.cwd();
4051
4155
  const homeDir = config?.homeDir ?? config?.initialState?.homeDir;
4052
4156
  const configDir = config?.configDir ?? DEFAULT_CONFIG_DIR;
@@ -4147,11 +4251,11 @@ async function createMastraCodeHarness(config) {
4147
4251
  default: {
4148
4252
  serviceName: "mastracode",
4149
4253
  // Only these requestContext keys are stored on spans — prevents leaking
4150
- // large objects (harness state, workspace, env vars) into trace data.
4151
- // Use dot-notation because these are nested inside the 'harness' key.
4254
+ // large objects (controller state, workspace, env vars) into trace data.
4255
+ // Use dot-notation because these are nested inside the 'controller' key.
4152
4256
  //
4153
4257
  // Session identifiers:
4154
- // threadId, resourceId, session.modeId, harnessId
4258
+ // threadId, resourceId, session.modeId, agentControllerId
4155
4259
  // Environment & project:
4156
4260
  // state.projectName, state.gitBranch
4157
4261
  // Model configuration:
@@ -4163,26 +4267,26 @@ async function createMastraCodeHarness(config) {
4163
4267
  // state.observationThreshold, state.reflectionThreshold
4164
4268
  requestContextKeys: [
4165
4269
  // Session identifiers
4166
- "harness.threadId",
4167
- "harness.resourceId",
4168
- "harness.session.modeId",
4169
- "harness.harnessId",
4270
+ "controller.threadId",
4271
+ "controller.resourceId",
4272
+ "controller.session.modeId",
4273
+ "controller.controllerId",
4170
4274
  // Environment & project
4171
- "harness.state.projectName",
4172
- "harness.state.gitBranch",
4275
+ "controller.state.projectName",
4276
+ "controller.state.gitBranch",
4173
4277
  // Model configuration
4174
- "harness.session.modelId",
4175
- "harness.state.subagentModelId",
4278
+ "controller.session.modelId",
4279
+ "controller.state.subagentModelId",
4176
4280
  // Agent settings
4177
- "harness.state.yolo",
4178
- "harness.state.thinkingLevel",
4179
- "harness.state.smartEditing",
4281
+ "controller.state.yolo",
4282
+ "controller.state.thinkingLevel",
4283
+ "controller.state.smartEditing",
4180
4284
  // Observational memory settings
4181
- "harness.state.omScope",
4182
- "harness.state.observerModelId",
4183
- "harness.state.reflectorModelId",
4184
- "harness.state.observationThreshold",
4185
- "harness.state.reflectionThreshold"
4285
+ "controller.state.omScope",
4286
+ "controller.state.observerModelId",
4287
+ "controller.state.reflectorModelId",
4288
+ "controller.state.observationThreshold",
4289
+ "controller.state.reflectionThreshold"
4186
4290
  ],
4187
4291
  exporters: [
4188
4292
  // Only persist traces locally when DuckDB observability is available
@@ -4206,13 +4310,13 @@ async function createMastraCodeHarness(config) {
4206
4310
  cwd: project.rootPath,
4207
4311
  gitcrawlCommand: process.env.MASTRACODE_GITCRAWL_BIN ?? process.env.GITCRAWL_BIN ?? process.env.MASTRACODE_GITCRAWL_COMMAND ?? process.env.GITCRAWL_COMMAND,
4208
4312
  getNotificationStreamOptions: async ({ resourceId, threadId }) => {
4209
- const session = await harness.getSessionByResource(resourceId) ?? activeSession;
4313
+ const session = await controller.getSessionByResource(resourceId) ?? activeSession;
4210
4314
  const modeId = session.mode.get();
4211
- const defaultModeModelId = harness.listModes().find((mode) => mode.id === modeId)?.defaultModelId;
4315
+ const defaultModeModelId = controller.listModes().find((mode) => mode.id === modeId)?.defaultModelId;
4212
4316
  const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || "";
4213
4317
  const requestContext = new RequestContext();
4214
- const harnessContext = {
4215
- harnessId: harness.id,
4318
+ const agentControllerContext = {
4319
+ controllerId: controller.id,
4216
4320
  state: session.state.get(),
4217
4321
  getState: () => session.state.get(),
4218
4322
  setState: (updates) => session.state.set(updates),
@@ -4229,10 +4333,10 @@ async function createMastraCodeHarness(config) {
4229
4333
  update: (updater) => session.state.update(updater)
4230
4334
  }
4231
4335
  },
4232
- workspace: harness.getWorkspace(),
4336
+ workspace: controller.getWorkspace(),
4233
4337
  getSubagentModelId: (params) => session.subagents.model.get(params ?? {})
4234
4338
  };
4235
- requestContext.set("harness", harnessContext);
4339
+ requestContext.set("controller", agentControllerContext);
4236
4340
  return {
4237
4341
  memory: { thread: threadId, resource: resourceId },
4238
4342
  requestContext,
@@ -4290,8 +4394,8 @@ async function createMastraCodeHarness(config) {
4290
4394
  new PlanRejectionAbortProcessor(),
4291
4395
  new AgentsMDInjector({
4292
4396
  getIgnoredInstructionPaths: ({ requestContext }) => {
4293
- const harnessContext = requestContext?.get("harness");
4294
- const state = harnessContext?.getState();
4397
+ const agentControllerContext = requestContext?.get("controller");
4398
+ const state = agentControllerContext?.getState();
4295
4399
  return getStaticallyLoadedInstructionPaths(state?.projectPath ?? project.rootPath);
4296
4400
  }
4297
4401
  }),
@@ -4423,7 +4527,7 @@ async function createMastraCodeHarness(config) {
4423
4527
  }
4424
4528
  }
4425
4529
  const typedStateSchema = stateSchema;
4426
- const harness = new Harness({
4530
+ const controller = new AgentController({
4427
4531
  id: "mastra-code",
4428
4532
  resourceId: project.resourceId,
4429
4533
  storage,
@@ -4436,6 +4540,7 @@ async function createMastraCodeHarness(config) {
4436
4540
  gateways: [mastraCodeGateway],
4437
4541
  workspace: config?.workspace ?? ((args) => getDynamicWorkspace(args)),
4438
4542
  browser: config?.browser,
4543
+ idGenerator: config?.idGenerator,
4439
4544
  toolCategoryResolver: getToolCategory,
4440
4545
  initialState: {
4441
4546
  projectPath: project.rootPath,
@@ -4464,10 +4569,9 @@ async function createMastraCodeHarness(config) {
4464
4569
  acquire: acquireThreadLock,
4465
4570
  release: releaseThreadLock
4466
4571
  }
4467
- // , harnessV1
4468
4572
  });
4469
4573
  return {
4470
- harness,
4574
+ controller,
4471
4575
  storage,
4472
4576
  observability,
4473
4577
  memory,
@@ -4534,32 +4638,32 @@ async function wireSessionConcerns(base, session) {
4534
4638
  await restoreOMThreadStateForCurrentThread(omThreadStateSession).catch(() => {
4535
4639
  });
4536
4640
  }
4537
- async function bootLocalHarness(config) {
4538
- const base = await createMastraCodeHarness(config);
4539
- const { harness, sessionId, ownerId } = base;
4540
- await harness.init();
4541
- await harness.getMastra()?.startWorkers();
4542
- const session = await harness.createSession({ id: sessionId, ownerId });
4641
+ async function bootLocalAgentController(config) {
4642
+ const base = await createMastraCodeAgentController(config);
4643
+ const { controller, sessionId, ownerId } = base;
4644
+ await controller.init();
4645
+ await controller.getMastra()?.startWorkers();
4646
+ const session = await controller.createSession({ id: sessionId, ownerId });
4543
4647
  await wireSessionConcerns(base, session);
4544
4648
  return { ...base, session };
4545
4649
  }
4546
- async function mountHarnessOnMastra(config) {
4547
- const base = await createMastraCodeHarness(config);
4548
- const { harness, storage } = base;
4549
- const harnessId = config?.harnessId ?? harness.id;
4650
+ async function mountAgentControllerOnMastra(config) {
4651
+ const base = await createMastraCodeAgentController(config);
4652
+ const { controller, storage } = base;
4653
+ const controllerId = config?.controllerId ?? controller.id;
4550
4654
  let mastra2;
4551
4655
  if (config?.mastra) {
4552
4656
  mastra2 = config.mastra;
4553
- harness.__registerMastra(mastra2);
4657
+ controller.__registerMastra(mastra2);
4554
4658
  } else {
4555
- mastra2 = new Mastra({ harnesses: { [harnessId]: harness }, storage });
4659
+ mastra2 = new Mastra({ agentControllers: { [controllerId]: controller }, storage });
4556
4660
  }
4557
- await harness.init();
4558
- await harness.getMastra()?.startWorkers();
4661
+ await controller.init();
4662
+ await controller.getMastra()?.startWorkers();
4559
4663
  return { ...base, mastra: mastra2 };
4560
4664
  }
4561
- var createMastraCode = bootLocalHarness;
4665
+ var createMastraCode = bootLocalAgentController;
4562
4666
 
4563
- export { bootLocalHarness, createAuthStorage, createMastraCode, createMastraCodeHarness, mountHarnessOnMastra, wireSessionConcerns };
4564
- //# sourceMappingURL=chunk-QO4KIOLG.js.map
4565
- //# sourceMappingURL=chunk-QO4KIOLG.js.map
4667
+ export { bootLocalAgentController, createAuthStorage, createMastraCode, createMastraCodeAgentController, mountAgentControllerOnMastra, wireSessionConcerns };
4668
+ //# sourceMappingURL=chunk-GT3A3LAA.js.map
4669
+ //# sourceMappingURL=chunk-GT3A3LAA.js.map