mastracode 0.25.1-alpha.1 → 0.25.1-alpha.3

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 (58) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/acp/server.d.ts.map +1 -1
  3. package/dist/{acp-2SQWNEWR.cjs → acp-2PKADLXH.cjs} +11 -7
  4. package/dist/acp-2PKADLXH.cjs.map +1 -0
  5. package/dist/{acp-UJJECLRJ.js → acp-XPUZA6K3.js} +9 -5
  6. package/dist/acp-XPUZA6K3.js.map +1 -0
  7. package/dist/agents/modes/explore.d.ts.map +1 -1
  8. package/dist/agents/modes/plan.d.ts.map +1 -1
  9. package/dist/agents/prompts/plan.d.ts +1 -1
  10. package/dist/agents/prompts/plan.d.ts.map +1 -1
  11. package/dist/agents/prompts/tool-guidance.d.ts.map +1 -1
  12. package/dist/agents/tool-availability.d.ts +6 -0
  13. package/dist/agents/tool-availability.d.ts.map +1 -0
  14. package/dist/agents/workspace.d.ts.map +1 -1
  15. package/dist/{chunk-7EJGM23M.js → chunk-CE46OHG7.js} +134 -45
  16. package/dist/chunk-CE46OHG7.js.map +1 -0
  17. package/dist/{chunk-FJDEUQWY.cjs → chunk-DVBJN36L.cjs} +72 -13
  18. package/dist/chunk-DVBJN36L.cjs.map +1 -0
  19. package/dist/{chunk-JKKDPFQD.js → chunk-F3TKSK3C.js} +63 -9
  20. package/dist/chunk-F3TKSK3C.js.map +1 -0
  21. package/dist/{chunk-GQBMYJWP.cjs → chunk-KLJO3DTE.cjs} +167 -78
  22. package/dist/chunk-KLJO3DTE.cjs.map +1 -0
  23. package/dist/{chunk-G4EH5HMP.js → chunk-NLEMHCXO.js} +363 -216
  24. package/dist/chunk-NLEMHCXO.js.map +1 -0
  25. package/dist/{chunk-A7TXUJUD.cjs → chunk-UWC5XVCQ.cjs} +1264 -1118
  26. package/dist/chunk-UWC5XVCQ.cjs.map +1 -0
  27. package/dist/cli.cjs +19 -19
  28. package/dist/cli.js +4 -4
  29. package/dist/index.cjs +3 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -1
  32. package/dist/processors/plan-rejection-abort.d.ts +12 -0
  33. package/dist/processors/plan-rejection-abort.d.ts.map +1 -0
  34. package/dist/tui/commands/clone.d.ts.map +1 -1
  35. package/dist/tui/commands/new.d.ts.map +1 -1
  36. package/dist/tui/commands/threads.d.ts.map +1 -1
  37. package/dist/tui/components/plan-approval-inline.d.ts +14 -6
  38. package/dist/tui/components/plan-approval-inline.d.ts.map +1 -1
  39. package/dist/tui/event-dispatch.d.ts.map +1 -1
  40. package/dist/tui/handlers/prompts.d.ts.map +1 -1
  41. package/dist/tui/mastra-tui.d.ts.map +1 -1
  42. package/dist/tui/render-messages.d.ts.map +1 -1
  43. package/dist/tui/setup.d.ts.map +1 -1
  44. package/dist/tui/state.d.ts +5 -0
  45. package/dist/tui/state.d.ts.map +1 -1
  46. package/dist/tui.cjs +19 -19
  47. package/dist/tui.js +2 -2
  48. package/dist/utils/plans.d.ts +20 -0
  49. package/dist/utils/plans.d.ts.map +1 -1
  50. package/package.json +11 -11
  51. package/dist/acp-2SQWNEWR.cjs.map +0 -1
  52. package/dist/acp-UJJECLRJ.js.map +0 -1
  53. package/dist/chunk-7EJGM23M.js.map +0 -1
  54. package/dist/chunk-A7TXUJUD.cjs.map +0 -1
  55. package/dist/chunk-FJDEUQWY.cjs.map +0 -1
  56. package/dist/chunk-G4EH5HMP.js.map +0 -1
  57. package/dist/chunk-GQBMYJWP.cjs.map +0 -1
  58. package/dist/chunk-JKKDPFQD.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # mastracode
2
2
 
3
+ ## 0.25.1-alpha.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated plan and explore modes to declare `availableTools` allowlists so tool visibility is gated at LLM-call time instead of workspace construction. Plan mode includes read-only tools plus plan-file editing and delivery tools; explore mode includes only read-only tools. Build mode remains unrestricted. Workspace creation no longer branches on mode for tool visibility — all modes now share the same workspace instance. ([#18463](https://github.com/mastra-ai/mastra/pull/18463))
8
+
9
+ - Updated dependencies [[`bf3fe49`](https://github.com/mastra-ai/mastra/commit/bf3fe49f9467dbbdb8f9eaf74e0f7971ffb19559), [`24ceaea`](https://github.com/mastra-ai/mastra/commit/24ceaea0bdd8609cabbab764380608ca6621a194), [`24ceaea`](https://github.com/mastra-ai/mastra/commit/24ceaea0bdd8609cabbab764380608ca6621a194), [`24ceaea`](https://github.com/mastra-ai/mastra/commit/24ceaea0bdd8609cabbab764380608ca6621a194), [`e1f272d`](https://github.com/mastra-ai/mastra/commit/e1f272d2bf1963c0ccb060f34b103b0b780bbff0), [`6ccf67b`](https://github.com/mastra-ai/mastra/commit/6ccf67bf075753754927a57bc2e1734ba2c820c5), [`825d8de`](https://github.com/mastra-ai/mastra/commit/825d8def9fa64c2bcc3d8dd6b49e09342c3ac5c7), [`74f447a`](https://github.com/mastra-ai/mastra/commit/74f447a6fae171ac3a6ec2d9e61be171ca46d23c), [`ffa09e7`](https://github.com/mastra-ai/mastra/commit/ffa09e772a5c92270eabe2090fc42d45bd8ec4b7), [`461a7c5`](https://github.com/mastra-ai/mastra/commit/461a7c501449295287f4f0ee4b0b42344f39fcf8), [`4211472`](https://github.com/mastra-ai/mastra/commit/4211472a5a2bd319c60cd2e42d9109c3eef7ac1c), [`9e45902`](https://github.com/mastra-ai/mastra/commit/9e4590208e745055cecca202e2db0e5c65e17d3c), [`5c0df77`](https://github.com/mastra-ai/mastra/commit/5c0df776c40efa420f8c07a2f3ee66010296618e)]:
10
+ - @mastra/core@1.47.0-alpha.3
11
+ - @mastra/pg@1.14.2-alpha.1
12
+ - @mastra/libsql@1.14.2-alpha.0
13
+ - @mastra/observability@1.15.2-alpha.0
14
+
15
+ ## 0.25.1-alpha.2
16
+
17
+ ### Patch Changes
18
+
19
+ - Fixed thread auto-resume selecting the wrong thread in git worktrees by scoping startup selection to threads tagged with the current project path. When Mastra Code detects a matching project thread on a different resource after resourceId drift, it now prompts before cloning and resuming that thread under the current resource; accepting the prompt leaves the old thread untouched and loads the clone, while declining starts fresh and leaves the old resource untouched. ([#18333](https://github.com/mastra-ai/mastra/pull/18333))
20
+
21
+ - Resolve all Harness models through gateways. The Harness now builds its available-models catalog, model auth status, mode agents, Observational Memory models, and subagents from the gateways you register, instead of the separate `resolveModel`, `customModelCatalogProvider`, and `modelAuthChecker` config hooks. Removed those three options from `HarnessConfig` (and the `ModelAuthChecker` type) — register a gateway via `gateways` instead. ([#18382](https://github.com/mastra-ai/mastra/pull/18382))
22
+
23
+ `listAvailableModels()` and `getCurrentModelAuthStatus()` are now sourced entirely from gateways: model discovery comes from each gateway's `fetchProviders()` (a network call for gateways like models.dev and Netlify), and auth status is resolved through the same gateway chain the model router uses at run time (`resolveAuth()`, falling back to `getApiKey()`). There is no static provider-registry fallback — everything the model picker shows comes from a gateway.
24
+
25
+ The gateway-chain operations shared by `ModelRouterLanguageModel` and the Harness (gateway merging, model→gateway selection, auth resolution, provider/model listing) are now centralized in a new `GatewayManager` class exported from `@mastra/core`. Both consumers delegate to it, eliminating duplicated logic. `defaultGateways` is still re-exported from the same paths for backward compatibility.
26
+
27
+ - Improved plan mode UX: "Request changes" stops the agent via processor-based abort and lets you provide revision feedback via chat. Plan resubmissions show a diff of what changed. Plans save to title-derived filenames (e.g. `add-dark-mode.md`) for multi-plan support. Plan filename displayed in TUI header. ([#18323](https://github.com/mastra-ai/mastra/pull/18323))
28
+
29
+ - Updated dependencies [[`86623c1`](https://github.com/mastra-ai/mastra/commit/86623c1adf7d22de32cc916dda17f4155184db36), [`7c9dd77`](https://github.com/mastra-ai/mastra/commit/7c9dd77bd18cb8dc72797e25f1a0fbdc71a11347), [`9990965`](https://github.com/mastra-ai/mastra/commit/999096571635a83b42ef40841fd7028cfa630779), [`c0ffa3c`](https://github.com/mastra-ai/mastra/commit/c0ffa3c897ccd326de880df734740a7f0681a18f), [`0504bf5`](https://github.com/mastra-ai/mastra/commit/0504bf5e8cffc571a4b343326178de371e6f859b), [`26f54af`](https://github.com/mastra-ai/mastra/commit/26f54afb5dbfbbb02d4d09bec4bd7c5029751767), [`5afe423`](https://github.com/mastra-ai/mastra/commit/5afe423e4badf040f1b0d4525183a856fcb8146e), [`86623c1`](https://github.com/mastra-ai/mastra/commit/86623c1adf7d22de32cc916dda17f4155184db36), [`8c9f1c0`](https://github.com/mastra-ai/mastra/commit/8c9f1c0361d89066f9bcd14a2f69e761b01766c8)]:
30
+ - @mastra/core@1.47.0-alpha.2
31
+ - @mastra/pg@1.14.2-alpha.0
32
+
3
33
  ## 0.25.1-alpha.1
4
34
 
5
35
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/acp/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAW,MAAM,sBAAsB,CAAC;AAG1E;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/acp/server.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAW,MAAM,sBAAsB,CAAC;AAG1E;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
@@ -1,8 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkGQBMYJWP_cjs = require('./chunk-GQBMYJWP.cjs');
4
- var chunkFJDEUQWY_cjs = require('./chunk-FJDEUQWY.cjs');
3
+ var chunkKLJO3DTE_cjs = require('./chunk-KLJO3DTE.cjs');
4
+ var chunkDVBJN36L_cjs = require('./chunk-DVBJN36L.cjs');
5
5
  var chunkDPRNPXVC_cjs = require('./chunk-DPRNPXVC.cjs');
6
+ var crypto = require('crypto');
6
7
  var stream = require('stream');
7
8
  var sdk = require('@agentclientprotocol/sdk');
8
9
 
@@ -13,7 +14,10 @@ async function runAcpServer(harness, modes, cleanup) {
13
14
  let session;
14
15
  let agent;
15
16
  try {
16
- session = await harness.createSession();
17
+ session = await harness.createSession({
18
+ id: `acp-${crypto.randomUUID()}`,
19
+ ownerId: `acp-owner-${crypto.randomUUID()}`
20
+ });
17
21
  const activeSession = session;
18
22
  const connection = new sdk.AgentSideConnection((conn) => {
19
23
  agent = new chunkDPRNPXVC_cjs.MastraCodeAcpAgent(conn, harness, activeSession, modes);
@@ -41,7 +45,7 @@ async function acpMain(options) {
41
45
  };
42
46
  let result;
43
47
  try {
44
- result = await chunkGQBMYJWP_cjs.createMastraCode({
48
+ result = await chunkKLJO3DTE_cjs.createMastraCode({
45
49
  unixSocketPubSub: false,
46
50
  disableMcp: false,
47
51
  disableHooks: false
@@ -53,7 +57,7 @@ async function acpMain(options) {
53
57
  { id: "fast", name: "Fast" }
54
58
  ];
55
59
  const cleanup = async () => {
56
- chunkFJDEUQWY_cjs.releaseAllThreadLocks();
60
+ chunkDVBJN36L_cjs.releaseAllThreadLocks();
57
61
  const closeSignalsPubSub = signalsPubSub?.close;
58
62
  await Promise.allSettled([
59
63
  mcpManager?.disconnect(),
@@ -79,5 +83,5 @@ async function acpMain(options) {
79
83
  }
80
84
 
81
85
  exports.acpMain = acpMain;
82
- //# sourceMappingURL=acp-2SQWNEWR.cjs.map
83
- //# sourceMappingURL=acp-2SQWNEWR.cjs.map
86
+ //# sourceMappingURL=acp-2PKADLXH.cjs.map
87
+ //# sourceMappingURL=acp-2PKADLXH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/acp/server.ts","../src/acp/index.ts"],"names":["Readable","Writable","stream","ndJsonStream","randomUUID","AgentSideConnection","MastraCodeAcpAgent","setAutoApprove","createMastraCode","releaseAllThreadLocks"],"mappings":"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","file":"acp-2PKADLXH.cjs","sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { Readable, Writable } from 'node:stream';\nimport { AgentSideConnection, ndJsonStream } from '@agentclientprotocol/sdk';\nimport type { Harness, HarnessMode, Session } from '@mastra/core/harness';\nimport { MastraCodeAcpAgent } from './agent.js';\n\n/**\n * Run the ACP server over stdio.\n * This sets up the JSON-RPC stream and keeps the process alive until the client disconnects.\n */\nexport async function runAcpServer(\n harness: Harness,\n modes: HarnessMode[],\n cleanup?: () => Promise<void>,\n): Promise<void> {\n // Create the ndJSON stream from stdin/stdout\n const input = Readable.toWeb(process.stdin) as ReadableStream<Uint8Array>;\n const output = Writable.toWeb(process.stdout) as WritableStream<Uint8Array>;\n const stream = ndJsonStream(output, input);\n let session: Session | undefined;\n let agent: MastraCodeAcpAgent | undefined;\n\n // Handle cleanup on disconnect (success or error)\n try {\n session = await harness.createSession({\n id: `acp-${randomUUID()}`,\n ownerId: `acp-owner-${randomUUID()}`,\n });\n const activeSession = session;\n\n // Create the agent-side connection\n const connection = new AgentSideConnection(conn => {\n agent = new MastraCodeAcpAgent(conn, harness, activeSession, modes);\n return agent;\n }, stream);\n\n await connection.closed;\n } finally {\n agent?.dispose();\n session?.thread.detachFromCurrent();\n await session?.thread.clearAndReleaseLock();\n if (cleanup) {\n await cleanup();\n }\n }\n}\n","import type { HarnessMode } from '@mastra/core/harness';\n\nimport { createMastraCode } from '../index.js';\nimport { releaseAllThreadLocks } from '../utils/thread-lock.js';\nimport { setAutoApprove } from './event-mapper.js';\nimport { runAcpServer } from './server.js';\n\n/**\n * Entry point for ACP server mode.\n * Initializes mastracode and runs the ACP protocol over stdio.\n */\nexport async function acpMain(options?: { dangerousAutoApprove?: boolean }): Promise<void> {\n if (options?.dangerousAutoApprove) {\n setAutoApprove(true);\n }\n // Redirect console.log to stderr to avoid polluting the JSON-RPC stream on stdout.\n // eslint-disable-next-line no-console\n const originalConsoleLog = console.log;\n // eslint-disable-next-line no-console\n console.log = (...args: unknown[]) => {\n process.stderr.write(args.map(String).join(' ') + '\\n');\n };\n\n let result: Awaited<ReturnType<typeof createMastraCode>> | undefined;\n\n try {\n result = await createMastraCode({\n unixSocketPubSub: false,\n disableMcp: false,\n disableHooks: false,\n });\n\n const { harness, mcpManager, signalsPubSub } = result;\n\n // Default modes (same as createMastraCode defaults)\n const modes: HarnessMode[] = [\n { id: 'build', name: 'Build' },\n { id: 'plan', name: 'Plan' },\n { id: 'fast', name: 'Fast' },\n ];\n\n // Cleanup function (mirrors main.ts asyncCleanup)\n const cleanup = async () => {\n releaseAllThreadLocks();\n const closeSignalsPubSub = (signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([\n mcpManager?.disconnect(),\n harness?.getMastra()?.stopWorkers(),\n harness?.stopHeartbeats(),\n closeSignalsPubSub?.(),\n ]);\n\n // Restore console.log\n // eslint-disable-next-line no-console\n console.log = originalConsoleLog;\n };\n\n // Handle signals\n const handleSignal = async () => {\n await cleanup();\n process.exit(0);\n };\n\n process.on('SIGINT', handleSignal);\n process.on('SIGTERM', handleSignal);\n\n await runAcpServer(harness, modes, cleanup);\n } catch (error) {\n process.stderr.write(`[acp] Fatal error: ${error}\\n`);\n // eslint-disable-next-line no-console\n console.log = originalConsoleLog;\n process.exit(1);\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
- import { createMastraCode } from './chunk-7EJGM23M.js';
2
- import { releaseAllThreadLocks } from './chunk-JKKDPFQD.js';
1
+ import { createMastraCode } from './chunk-CE46OHG7.js';
2
+ import { releaseAllThreadLocks } from './chunk-F3TKSK3C.js';
3
3
  import { setAutoApprove, MastraCodeAcpAgent } from './chunk-IU477VVQ.js';
4
+ import { randomUUID } from 'crypto';
4
5
  import { Readable, Writable } from 'stream';
5
6
  import { ndJsonStream, AgentSideConnection } from '@agentclientprotocol/sdk';
6
7
 
@@ -11,7 +12,10 @@ async function runAcpServer(harness, modes, cleanup) {
11
12
  let session;
12
13
  let agent;
13
14
  try {
14
- session = await harness.createSession();
15
+ session = await harness.createSession({
16
+ id: `acp-${randomUUID()}`,
17
+ ownerId: `acp-owner-${randomUUID()}`
18
+ });
15
19
  const activeSession = session;
16
20
  const connection = new AgentSideConnection((conn) => {
17
21
  agent = new MastraCodeAcpAgent(conn, harness, activeSession, modes);
@@ -77,5 +81,5 @@ async function acpMain(options) {
77
81
  }
78
82
 
79
83
  export { acpMain };
80
- //# sourceMappingURL=acp-UJJECLRJ.js.map
81
- //# sourceMappingURL=acp-UJJECLRJ.js.map
84
+ //# sourceMappingURL=acp-XPUZA6K3.js.map
85
+ //# sourceMappingURL=acp-XPUZA6K3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/acp/server.ts","../src/acp/index.ts"],"names":[],"mappings":"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","file":"acp-XPUZA6K3.js","sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { Readable, Writable } from 'node:stream';\nimport { AgentSideConnection, ndJsonStream } from '@agentclientprotocol/sdk';\nimport type { Harness, HarnessMode, Session } from '@mastra/core/harness';\nimport { MastraCodeAcpAgent } from './agent.js';\n\n/**\n * Run the ACP server over stdio.\n * This sets up the JSON-RPC stream and keeps the process alive until the client disconnects.\n */\nexport async function runAcpServer(\n harness: Harness,\n modes: HarnessMode[],\n cleanup?: () => Promise<void>,\n): Promise<void> {\n // Create the ndJSON stream from stdin/stdout\n const input = Readable.toWeb(process.stdin) as ReadableStream<Uint8Array>;\n const output = Writable.toWeb(process.stdout) as WritableStream<Uint8Array>;\n const stream = ndJsonStream(output, input);\n let session: Session | undefined;\n let agent: MastraCodeAcpAgent | undefined;\n\n // Handle cleanup on disconnect (success or error)\n try {\n session = await harness.createSession({\n id: `acp-${randomUUID()}`,\n ownerId: `acp-owner-${randomUUID()}`,\n });\n const activeSession = session;\n\n // Create the agent-side connection\n const connection = new AgentSideConnection(conn => {\n agent = new MastraCodeAcpAgent(conn, harness, activeSession, modes);\n return agent;\n }, stream);\n\n await connection.closed;\n } finally {\n agent?.dispose();\n session?.thread.detachFromCurrent();\n await session?.thread.clearAndReleaseLock();\n if (cleanup) {\n await cleanup();\n }\n }\n}\n","import type { HarnessMode } from '@mastra/core/harness';\n\nimport { createMastraCode } from '../index.js';\nimport { releaseAllThreadLocks } from '../utils/thread-lock.js';\nimport { setAutoApprove } from './event-mapper.js';\nimport { runAcpServer } from './server.js';\n\n/**\n * Entry point for ACP server mode.\n * Initializes mastracode and runs the ACP protocol over stdio.\n */\nexport async function acpMain(options?: { dangerousAutoApprove?: boolean }): Promise<void> {\n if (options?.dangerousAutoApprove) {\n setAutoApprove(true);\n }\n // Redirect console.log to stderr to avoid polluting the JSON-RPC stream on stdout.\n // eslint-disable-next-line no-console\n const originalConsoleLog = console.log;\n // eslint-disable-next-line no-console\n console.log = (...args: unknown[]) => {\n process.stderr.write(args.map(String).join(' ') + '\\n');\n };\n\n let result: Awaited<ReturnType<typeof createMastraCode>> | undefined;\n\n try {\n result = await createMastraCode({\n unixSocketPubSub: false,\n disableMcp: false,\n disableHooks: false,\n });\n\n const { harness, mcpManager, signalsPubSub } = result;\n\n // Default modes (same as createMastraCode defaults)\n const modes: HarnessMode[] = [\n { id: 'build', name: 'Build' },\n { id: 'plan', name: 'Plan' },\n { id: 'fast', name: 'Fast' },\n ];\n\n // Cleanup function (mirrors main.ts asyncCleanup)\n const cleanup = async () => {\n releaseAllThreadLocks();\n const closeSignalsPubSub = (signalsPubSub as { close?: () => Promise<void> | void } | undefined)?.close;\n await Promise.allSettled([\n mcpManager?.disconnect(),\n harness?.getMastra()?.stopWorkers(),\n harness?.stopHeartbeats(),\n closeSignalsPubSub?.(),\n ]);\n\n // Restore console.log\n // eslint-disable-next-line no-console\n console.log = originalConsoleLog;\n };\n\n // Handle signals\n const handleSignal = async () => {\n await cleanup();\n process.exit(0);\n };\n\n process.on('SIGINT', handleSignal);\n process.on('SIGTERM', handleSignal);\n\n await runAcpServer(harness, modes, cleanup);\n } catch (error) {\n process.stderr.write(`[acp] Fatal error: ${error}\\n`);\n // eslint-disable-next-line no-console\n console.log = originalConsoleLog;\n process.exit(1);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../../src/agents/modes/explore.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,eAAO,MAAM,QAAQ,EAAE,WAgCtB,CAAC"}
1
+ {"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../../src/agents/modes/explore.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,eAAO,MAAM,QAAQ,EAAE,WAkCtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/agents/modes/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,eAAO,MAAM,QAAQ,EAAE,WA6BtB,CAAC"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/agents/modes/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,eAAO,MAAM,QAAQ,EAAE,WAiCtB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Plan mode prompt — read-only exploration and planning.
3
3
  */
4
- export declare const planModePrompt = "\n# Plan Mode \u2014 READ-ONLY\n\nYou are in PLAN mode. Your job is to explore the codebase and design an implementation plan \u2014 NOT to make changes.\n\n## CRITICAL: Read-Only Mode\n\nThis mode is **strictly read-only**. You must NOT modify anything.\n\n- Do NOT modify, create, or delete any files\n- Do NOT run commands that change state (no git commit, no npm install, no file creation)\n- Do NOT run build commands, tests, or scripts that have side effects\n\nIf 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.\n\n## Exploration Strategy\n\nBefore writing any plan, build a mental model of the codebase:\n1. Start with the directory structure (`view` on the project root or relevant subdirectory).\n2. Find the relevant entry points and core files using `search_content` and `find_files`.\n3. Read the actual code \u2014 don't assume based on file names alone.\n4. Trace data flow: where does input come from, how is it transformed, where does it go?\n5. Identify existing patterns the codebase uses (naming, structure, error handling, testing).\n\n## Goal-Ready Plans\n\nThe submit_plan approval UI can let the user approve the plan normally or start it as a persistent goal. Write plans so they can be carried out as a goal if the user chooses that option:\n- Make the desired outcome explicit and verifiable.\n- Break work into ordered, actionable steps that can be executed autonomously.\n- Include constraints, risks, blockers, and decision points that may require user input.\n- Include concrete verification criteria so the goal judge can tell when the work is done.\n\n## Your Plan Output\n\nProduce a clear, step-by-step plan with this structure:\n\n### Overview\nOne paragraph: what the change does and why.\n\n### Complexity Estimate\n- **Size**: Small (1-2 files) / Medium (3-5 files) / Large (6+ files)\n- **Risk**: Low (additive, no breaking changes) / Medium (modifies existing behavior) / High (architectural, affects many consumers)\n- **Dependencies**: List any new packages, external services, or migration steps needed.\n\n### Steps\nFor each step:\n1. **File**: path to create or modify\n2. **Change**: what to add/modify/remove, with enough specificity to implement directly\n3. **Why**: brief rationale connecting this step to the overall goal\n\n### Verification\n- What tests to run\n- What to check manually\n- What could go wrong\n\n## IMMEDIATE ACTION: Call submit_plan Tool\n\nAs soon as your plan is complete, **STOP** and call the `submit_plan` tool immediately.\n\n**CRITICAL:** Do NOT generate a long text response describing your plan. The plan content belongs in the `submit_plan` tool call, not in your text output.\n\nWhen done, call:\n```javascript\nsubmit_plan({\n title: \"short descriptive title\",\n plan: \"your full plan in markdown\"\n})\n```\n\nThe user will see the plan rendered inline and can:\n- **Approve** \u2014 automatically switches to Build mode for implementation\n- **Start as goal** \u2014 approves the plan and enters goal mode so the agent keeps working toward the plan until judged complete, paused, or waiting for user input\n- **Reject** \u2014 stays in Plan mode\n- **Request changes** \u2014 provides feedback for you to revise and resubmit\n\nDo NOT start implementing until the plan is approved. If rejected with feedback, revise the plan and call `submit_plan` again.\n";
4
+ export declare const planModePrompt = "\n# Plan Mode \u2014 READ-ONLY (except plan files)\n\nYou are in PLAN mode. Your job is to explore the codebase and design an implementation plan \u2014 NOT to make changes to the project.\n\n## CRITICAL: Read-Only Mode (project files)\n\nThis mode is **read-only for project files**. You must NOT modify the project.\n\n- Do NOT modify, create, or delete project files\n- Do NOT run commands that change state (no git commit, no npm install, no file creation)\n- Do NOT run build commands, tests, or scripts that have side effects\n\nThe ONE exception is your plan file: you CAN write to `.mastracode/plans/` to create and edit your plan.\n\nIf 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.\n\n## Exploration Strategy\n\nBefore writing any plan, build a mental model of the codebase:\n1. Start with the directory structure (`view` on the project root or relevant subdirectory).\n2. Find the relevant entry points and core files using `search_content` and `find_files`.\n3. Read the actual code \u2014 don't assume based on file names alone.\n4. Trace data flow: where does input come from, how is it transformed, where does it go?\n5. Identify existing patterns the codebase uses (naming, structure, error handling, testing).\n\n## Goal-Ready Plans\n\nThe submit_plan approval UI can let the user approve the plan normally or start it as a persistent goal. Write plans so they can be carried out as a goal if the user chooses that option:\n- Make the desired outcome explicit and verifiable.\n- Break work into ordered, actionable steps that can be executed autonomously.\n- Include constraints, risks, blockers, and decision points that may require user input.\n- Include concrete verification criteria so the goal judge can tell when the work is done.\n\n## Your Plan Output\n\nProduce a clear, step-by-step plan with this structure:\n\n### Overview\nOne paragraph: what the change does and why.\n\n### Complexity Estimate\n- **Size**: Small (1-2 files) / Medium (3-5 files) / Large (6+ files)\n- **Risk**: Low (additive, no breaking changes) / Medium (modifies existing behavior) / High (architectural, affects many consumers)\n- **Dependencies**: List any new packages, external services, or migration steps needed.\n\n### Steps\nFor each step:\n1. **File**: path to create or modify\n2. **Change**: what to add/modify/remove, with enough specificity to implement directly\n3. **Why**: brief rationale connecting this step to the overall goal\n\n### Verification\n- What tests to run\n- What to check manually\n- What could go wrong\n\n## Plan File Workflow\n\nYour 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:\n\n1. **First submission**: Write your plan to `.mastracode/plans/<slug>.md` using `write_file`, then call `submit_plan` with the plan content.\n2. **Reading**: Use `view` to read the plan file.\n3. **Editing**: Use `string_replace_lsp` for targeted edits to specific sections.\n\n## IMMEDIATE ACTION: Write plan file, then call submit_plan\n\nAs soon as your plan is complete:\n1. Write it to `.mastracode/plans/<slug>.md` (slugified from your title) using `write_file`\n2. Call `submit_plan` with the plan content\n\n**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.\n\n```javascript\nsubmit_plan({\n title: \"short descriptive title\",\n plan: \"your full plan in markdown\"\n})\n```\n\nThe user will see the plan rendered inline and can:\n- **Approve** \u2014 automatically switches to Build mode for implementation\n- **Start as goal** \u2014 approves the plan and enters goal mode so the agent keeps working toward the plan until judged complete, paused, or waiting for user input\n- **Request changes** \u2014 rejects the plan; the agent stops immediately and the user provides revision feedback in their next chat message\n\n## Revision Workflow\n\nIf 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:\n1. Use `view` to read your plan file in `.mastracode/plans/`\n2. Use `string_replace_lsp` to make targeted edits based on feedback\n3. Use `view` to re-read the updated file\n4. Call `submit_plan` again with the full updated plan content\n\nThe 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.\n\n**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.\n\nDo NOT start implementing until the plan is approved.\n";
5
5
  //# sourceMappingURL=plan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc,i4GA4E1B,CAAC"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc,84JAkG1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-guidance.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/tool-guidance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAsN3F"}
1
+ {"version":3,"file":"tool-guidance.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/tool-guidance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CA+N3F"}
@@ -0,0 +1,6 @@
1
+ import type { WorkspaceToolsConfig } from '@mastra/core/workspace';
2
+ export declare const MASTRACODE_WORKSPACE_TOOLS: WorkspaceToolsConfig;
3
+ export declare const PLAN_MODE_AVAILABLE_TOOLS: readonly string[];
4
+ export declare const EXPLORE_MODE_AVAILABLE_TOOLS: readonly string[];
5
+ export declare const GOAL_JUDGE_READONLY_TOOLS: readonly string[];
6
+ //# sourceMappingURL=tool-availability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-availability.d.ts","sourceRoot":"","sources":["../../src/agents/tool-availability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,eAAO,MAAM,0BAA0B,EAAE,oBAExC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAsBtD,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,SAAS,MAAM,EAOzD,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAMtD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/agents/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAwB,MAAM,wBAAwB,CAAC;AA8ExG,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,SAAe,GAAG,MAAM,EAAE,CAgBxG;AA2BD,wBAAgB,mBAAmB,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE;IAAE,cAAc,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,uDAkElH;AAiBD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,cAAc,EACd,MAAM,GACP,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAclC"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/agents/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAwB,MAAM,wBAAwB,CAAC;AA+ExG,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,SAAe,GAAG,MAAM,EAAE,CAgBxG;AA2BD,wBAAgB,mBAAmB,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE;IAAE,cAAc,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,uDA2DlH;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,cAAc,EACd,MAAM,GACP,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAclC"}
@@ -1,4 +1,4 @@
1
- import { 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-JKKDPFQD.js';
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';
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';
@@ -316,18 +316,20 @@ When something breaks:
316
316
 
317
317
  // src/agents/prompts/plan.ts
318
318
  var planModePrompt = `
319
- # Plan Mode \u2014 READ-ONLY
319
+ # Plan Mode \u2014 READ-ONLY (except plan files)
320
320
 
321
- You are in PLAN mode. Your job is to explore the codebase and design an implementation plan \u2014 NOT to make changes.
321
+ 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.
322
322
 
323
- ## CRITICAL: Read-Only Mode
323
+ ## CRITICAL: Read-Only Mode (project files)
324
324
 
325
- This mode is **strictly read-only**. You must NOT modify anything.
325
+ This mode is **read-only for project files**. You must NOT modify the project.
326
326
 
327
- - Do NOT modify, create, or delete any files
327
+ - Do NOT modify, create, or delete project files
328
328
  - Do NOT run commands that change state (no git commit, no npm install, no file creation)
329
329
  - Do NOT run build commands, tests, or scripts that have side effects
330
330
 
331
+ The ONE exception is your plan file: you CAN write to \`.mastracode/plans/\` to create and edit your plan.
332
+
331
333
  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.
332
334
 
333
335
  ## Exploration Strategy
@@ -370,13 +372,22 @@ For each step:
370
372
  - What to check manually
371
373
  - What could go wrong
372
374
 
373
- ## IMMEDIATE ACTION: Call submit_plan Tool
375
+ ## Plan File Workflow
376
+
377
+ 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:
378
+
379
+ 1. **First submission**: Write your plan to \`.mastracode/plans/<slug>.md\` using \`write_file\`, then call \`submit_plan\` with the plan content.
380
+ 2. **Reading**: Use \`view\` to read the plan file.
381
+ 3. **Editing**: Use \`string_replace_lsp\` for targeted edits to specific sections.
382
+
383
+ ## IMMEDIATE ACTION: Write plan file, then call submit_plan
374
384
 
375
- As soon as your plan is complete, **STOP** and call the \`submit_plan\` tool immediately.
385
+ As soon as your plan is complete:
386
+ 1. Write it to \`.mastracode/plans/<slug>.md\` (slugified from your title) using \`write_file\`
387
+ 2. Call \`submit_plan\` with the plan content
376
388
 
377
- **CRITICAL:** Do NOT generate a long text response describing your plan. The plan content belongs in the \`submit_plan\` tool call, not in your text output.
389
+ **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.
378
390
 
379
- When done, call:
380
391
  \`\`\`javascript
381
392
  submit_plan({
382
393
  title: "short descriptive title",
@@ -387,10 +398,21 @@ submit_plan({
387
398
  The user will see the plan rendered inline and can:
388
399
  - **Approve** \u2014 automatically switches to Build mode for implementation
389
400
  - **Start as goal** \u2014 approves the plan and enters goal mode so the agent keeps working toward the plan until judged complete, paused, or waiting for user input
390
- - **Reject** \u2014 stays in Plan mode
391
- - **Request changes** \u2014 provides feedback for you to revise and resubmit
401
+ - **Request changes** \u2014 rejects the plan; the agent stops immediately and the user provides revision feedback in their next chat message
402
+
403
+ ## Revision Workflow
404
+
405
+ 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:
406
+ 1. Use \`view\` to read your plan file in \`.mastracode/plans/\`
407
+ 2. Use \`string_replace_lsp\` to make targeted edits based on feedback
408
+ 3. Use \`view\` to re-read the updated file
409
+ 4. Call \`submit_plan\` again with the full updated plan content
410
+
411
+ 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.
392
412
 
393
- Do NOT start implementing until the plan is approved. If rejected with feedback, revise the plan and call \`submit_plan\` again.
413
+ **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.
414
+
415
+ Do NOT start implementing until the plan is approved.
394
416
  `;
395
417
 
396
418
  // src/agents/prompts/fast.ts
@@ -482,6 +504,51 @@ Error: ${r.error}`);
482
504
  }
483
505
  });
484
506
  }
507
+
508
+ // src/agents/tool-availability.ts
509
+ var MASTRACODE_WORKSPACE_TOOLS = {
510
+ ...TOOL_NAME_OVERRIDES
511
+ };
512
+ var PLAN_MODE_AVAILABLE_TOOLS = [
513
+ // Read-only exploration tools
514
+ MC_TOOLS.VIEW,
515
+ MC_TOOLS.FIND_FILES,
516
+ MC_TOOLS.SEARCH_CONTENT,
517
+ MC_TOOLS.FILE_STAT,
518
+ MC_TOOLS.LSP_INSPECT,
519
+ // Plan file writing (visibility gated by availableTools; the shared workspace
520
+ // is mode-agnostic and does not path-restrict these — plan-mode instructions
521
+ // scope writes to .mastracode/plans/)
522
+ MC_TOOLS.WRITE_FILE,
523
+ MC_TOOLS.STRING_REPLACE_LSP,
524
+ // Plan delivery tools
525
+ "ask_user",
526
+ "submit_plan",
527
+ // Task tools for plan-stage tracking
528
+ "task_write",
529
+ "task_update",
530
+ "task_complete",
531
+ "task_check",
532
+ // Notification access
533
+ MC_TOOLS.NOTIFICATION_INBOX
534
+ ];
535
+ var EXPLORE_MODE_AVAILABLE_TOOLS = [
536
+ MC_TOOLS.VIEW,
537
+ MC_TOOLS.FIND_FILES,
538
+ MC_TOOLS.SEARCH_CONTENT,
539
+ MC_TOOLS.FILE_STAT,
540
+ MC_TOOLS.LSP_INSPECT,
541
+ "ask_user"
542
+ ];
543
+ var GOAL_JUDGE_READONLY_TOOLS = [
544
+ MC_TOOLS.VIEW,
545
+ MC_TOOLS.SEARCH_CONTENT,
546
+ MC_TOOLS.FIND_FILES,
547
+ MC_TOOLS.FILE_STAT,
548
+ MC_TOOLS.LSP_INSPECT
549
+ ];
550
+
551
+ // src/agents/workspace.ts
485
552
  function buildSandboxEnv() {
486
553
  return {
487
554
  ...process.env,
@@ -541,7 +608,7 @@ function buildSkillPaths(projectPath, configDir, homeDir = os__default.homedir()
541
608
  agentSkillsGlobalPath
542
609
  ]);
543
610
  }
544
- var DEFAULT_ALLOWED_PATHS = [os__default.tmpdir(), "/tmp"].reduce((acc, p) => {
611
+ var DEFAULT_ALLOWED_PATHS = [os__default.tmpdir(), "/tmp", getPlansDir()].reduce((acc, p) => {
545
612
  const resolved = path__default.resolve(p);
546
613
  if (!acc.includes(resolved)) acc.push(resolved);
547
614
  return acc;
@@ -557,7 +624,6 @@ function detectPackageRunner(projectPath) {
557
624
  function getDynamicWorkspace({ requestContext, mastra: mastra2 }) {
558
625
  const ctx = requestContext.get("harness");
559
626
  const state = ctx?.session.state.get();
560
- const modeId = ctx?.session?.modeId ?? "build";
561
627
  const rawProjectPath = state?.projectPath;
562
628
  if (!rawProjectPath) {
563
629
  throw new Error("Project path is required");
@@ -568,15 +634,7 @@ function getDynamicWorkspace({ requestContext, mastra: mastra2 }) {
568
634
  const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}`;
569
635
  const sandboxPaths = state?.sandboxAllowedPaths ?? [];
570
636
  const allowedPaths = [...skillPaths, ...DEFAULT_ALLOWED_PATHS, ...sandboxPaths.map((p) => path__default.resolve(p))];
571
- const isPlanMode = modeId === "plan";
572
- const planModeTools = {
573
- mastra_workspace_write_file: { ...TOOL_NAME_OVERRIDES.mastra_workspace_write_file, enabled: false },
574
- mastra_workspace_edit_file: { ...TOOL_NAME_OVERRIDES.mastra_workspace_edit_file, enabled: false },
575
- mastra_workspace_ast_edit: { ...TOOL_NAME_OVERRIDES.mastra_workspace_ast_edit, enabled: false }
576
- };
577
- const workspaceTools = {
578
- ...isPlanMode ? { ...TOOL_NAME_OVERRIDES, ...planModeTools } : TOOL_NAME_OVERRIDES
579
- };
637
+ const workspaceTools = MASTRACODE_WORKSPACE_TOOLS;
580
638
  let existing;
581
639
  try {
582
640
  existing = mastra2?.getWorkspaceById(workspaceId);
@@ -611,13 +669,6 @@ function getDynamicWorkspace({ requestContext, mastra: mastra2 }) {
611
669
  lsp: lspConfig
612
670
  });
613
671
  }
614
- var GOAL_JUDGE_READONLY_TOOLS = [
615
- MC_TOOLS.VIEW,
616
- MC_TOOLS.SEARCH_CONTENT,
617
- MC_TOOLS.FIND_FILES,
618
- MC_TOOLS.FILE_STAT,
619
- MC_TOOLS.LSP_INSPECT
620
- ];
621
672
  async function getGoalJudgeTools({
622
673
  requestContext,
623
674
  mastra: mastra2
@@ -982,6 +1033,14 @@ ${patchToolGuidance}
982
1033
  - The plan will be rendered as markdown and the user can approve, reject, or request changes.
983
1034
  - On approval, the system automatically switches to the default mode so you can implement.
984
1035
  - Takes two arguments: \`title\` (short descriptive title) and \`plan\` (full plan in markdown).`);
1036
+ }
1037
+ if (modeId === "plan") {
1038
+ sections.push(`
1039
+ **Plan file access** \u2014 Your plan lives in \`.mastracode/plans/\` with a filename derived from the title (e.g. \`add-dark-mode-toggle.md\`)
1040
+ - Use \`write_file\` to create the plan file, \`view\` to read it, and \`string_replace_lsp\` for targeted edits.
1041
+ - On first submission: write the plan to the file, then call \`submit_plan\`.
1042
+ - On revision: read the existing file, edit specific sections, re-read, then call \`submit_plan\` with updated content.
1043
+ - If a plan file already exists, you previously submitted it \u2014 read it before revising.`);
985
1044
  }
986
1045
  if (!denied.has("subagent")) {
987
1046
  sections.push(`
@@ -1829,9 +1888,6 @@ function getHarnessHeaders(requestContext) {
1829
1888
  function createMastraCodeGateway(options) {
1830
1889
  return new MastraCodeGateway(options);
1831
1890
  }
1832
- function createMastraCodeModelCatalogProvider(gateway) {
1833
- return gateway instanceof MastraCodeGateway ? gateway.createModelCatalogProvider() : MastraCodeGateway.createModelCatalogProvider(gateway);
1834
- }
1835
1891
  function resolveModel(modelId, options) {
1836
1892
  reloadAuthStorage();
1837
1893
  const headers = getHarnessHeaders(options?.requestContext);
@@ -2053,7 +2109,8 @@ End with a structured summary:
2053
2109
  . **Key Files**: Most relevant files with line numbers
2054
2110
  . **Details**: Additional context if needed
2055
2111
 
2056
- Keep your summary under 300 words.`
2112
+ Keep your summary under 300 words.`,
2113
+ availableTools: [...EXPLORE_MODE_AVAILABLE_TOOLS]
2057
2114
  };
2058
2115
 
2059
2116
  // src/agents/modes/plan.ts
@@ -2066,7 +2123,8 @@ var planMode = {
2066
2123
  instructions: `You are an expert software architect and planner. Your job is to analyze a codebase and produce a detailed implementation plan for a given task.
2067
2124
 
2068
2125
  ## Rules
2069
- - You have READ-ONLY access. You cannot modify files or run commands.
2126
+ - You have READ-ONLY access to the project. You cannot modify project files or run commands.
2127
+ - The one exception is the plan file: you can write and edit files in \`.mastracode/plans/\` using \`write_file\`, \`view\`, and \`string_replace_lsp\`.
2070
2128
  - First, explore the codebase to understand existing patterns, architecture, and conventions.
2071
2129
  - Produce a concrete, actionable plan \u2014 not vague suggestions.
2072
2130
 
@@ -2077,13 +2135,15 @@ var planMode = {
2077
2135
  - **Parallelize**: Make multiple independent tool calls when exploring different areas
2078
2136
 
2079
2137
  ## Plan Delivery
2080
- - When your exploration is complete, call the \`submit_plan\` tool with your plan.
2138
+ - Write your plan to \`.mastracode/plans/<slug>.md\` (slugified from your title) using \`write_file\`, then call \`submit_plan\`.
2081
2139
  - Do NOT output the plan as text \u2014 it MUST go through the submit_plan tool call.
2082
2140
  - Be concise: reference files by path and line number, don't include raw contents.
2083
- - Focus on actionable details, not general observations.`,
2141
+ - Focus on actionable details, not general observations.
2142
+ - If a plan file already exists in \`.mastracode/plans/\`, you previously submitted a plan \u2014 read it before revising.`,
2084
2143
  metadata: {
2085
2144
  default: false
2086
- }
2145
+ },
2146
+ availableTools: [...PLAN_MODE_AVAILABLE_TOOLS]
2087
2147
  };
2088
2148
 
2089
2149
  // src/agents/thread-caveman-state.ts
@@ -3629,6 +3689,36 @@ function createMcpManager(projectDir, configDirName = DEFAULT_CONFIG_DIR, extraS
3629
3689
  }
3630
3690
  };
3631
3691
  }
3692
+
3693
+ // src/processors/plan-rejection-abort.ts
3694
+ var PLAN_REJECTED_PREFIX = "Plan was not approved";
3695
+ var PlanRejectionAbortProcessor = class {
3696
+ id = "plan-rejection-abort";
3697
+ async processInputStep({ messages, stepNumber, abort }) {
3698
+ if (stepNumber === 0) return void 0;
3699
+ for (let i = messages.length - 1; i >= 0; i--) {
3700
+ const msg = messages[i];
3701
+ if (!msg || msg.role !== "assistant") continue;
3702
+ const content = msg.content;
3703
+ const parts = content?.parts;
3704
+ if (!Array.isArray(parts)) break;
3705
+ for (const part of parts) {
3706
+ if (!part || typeof part !== "object") continue;
3707
+ const p = part;
3708
+ if (p.type !== "tool-invocation") continue;
3709
+ const inv = p.toolInvocation;
3710
+ if (!inv || inv.state !== "result" || inv.toolName !== "submit_plan") continue;
3711
+ const result = inv.result;
3712
+ const text = typeof result === "string" ? result : typeof result?.content === "string" ? result.content : "";
3713
+ if (text.startsWith(PLAN_REJECTED_PREFIX)) {
3714
+ abort("Plan rejected by user \u2014 no further response needed");
3715
+ }
3716
+ }
3717
+ break;
3718
+ }
3719
+ return void 0;
3720
+ }
3721
+ };
3632
3722
  var stateSchema = z.object({
3633
3723
  // Session-scoped selection. The legacy Harness stores these in its state and
3634
3724
  // validates state against this schema, so they MUST be declared here — Zod
@@ -4196,6 +4286,7 @@ async function createMastraCode(config) {
4196
4286
  tools: getGoalJudgeTools
4197
4287
  },
4198
4288
  inputProcessors: [
4289
+ new PlanRejectionAbortProcessor(),
4199
4290
  new AgentsMDInjector({
4200
4291
  getIgnoredInstructionPaths: ({ requestContext }) => {
4201
4292
  const harnessContext = requestContext?.get("harness");
@@ -4342,6 +4433,8 @@ async function createMastraCode(config) {
4342
4433
  agent: codeAgent,
4343
4434
  subagents: config?.subagents ?? [],
4344
4435
  gateways: [mastraCodeGateway],
4436
+ workspace: config?.workspace ?? ((args) => getDynamicWorkspace(args)),
4437
+ browser: config?.browser,
4345
4438
  toolCategoryResolver: getToolCategory,
4346
4439
  initialState: {
4347
4440
  projectPath: project.rootPath,
@@ -4354,12 +4447,8 @@ async function createMastraCode(config) {
4354
4447
  // with MCP/hooks/storage which were already initialized with this value.
4355
4448
  configDir
4356
4449
  },
4357
- workspace: config?.workspace ?? ((args) => getDynamicWorkspace(args)),
4358
- browser: config?.browser,
4359
4450
  modes,
4360
4451
  heartbeatHandlers,
4361
- resolveModel,
4362
- customModelCatalogProvider: createMastraCodeModelCatalogProvider(mastraCodeGateway),
4363
4452
  modelUseCountProvider: () => loadSettings().modelUseCounts,
4364
4453
  modelUseCountTracker: (modelId) => {
4365
4454
  try {
@@ -4435,5 +4524,5 @@ async function createMastraCode(config) {
4435
4524
  }
4436
4525
 
4437
4526
  export { createAuthStorage, createMastraCode };
4438
- //# sourceMappingURL=chunk-7EJGM23M.js.map
4439
- //# sourceMappingURL=chunk-7EJGM23M.js.map
4527
+ //# sourceMappingURL=chunk-CE46OHG7.js.map
4528
+ //# sourceMappingURL=chunk-CE46OHG7.js.map