mastracode 0.41.0-alpha.8 → 0.41.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.
@@ -35,6 +35,7 @@ let _mastra_code_sdk_onboarding_index = require("@mastra/code-sdk/onboarding/ind
35
35
  let _mastra_code_sdk_utils_update_check = require("@mastra/code-sdk/utils/update-check");
36
36
  let _earendil_works_pi_tui = require("@earendil-works/pi-tui");
37
37
  let _mastra_core_signals = require("@mastra/core/signals");
38
+ let zod = require("zod");
38
39
  let _mastra_code_sdk_utils_slash_command_processor = require("@mastra/code-sdk/utils/slash-command-processor");
39
40
  let _mastra_code_sdk_goal_signal = require("@mastra/code-sdk/goal-signal");
40
41
  let _mastra_code_sdk_goal_manager = require("@mastra/code-sdk/goal-manager");
@@ -666,6 +667,20 @@ async function detectTerminalTheme() {
666
667
  return { mode: "dark" };
667
668
  }
668
669
  //#endregion
670
+ //#region src/tui/background-tool-result.ts
671
+ const backgroundTaskMetadataSchema = zod.z.object({ mastra: zod.z.object({ backgroundTask: zod.z.object({
672
+ taskId: zod.z.string().min(1),
673
+ status: zod.z.enum([
674
+ "running",
675
+ "completed",
676
+ "failed"
677
+ ])
678
+ }) }) });
679
+ function getBackgroundToolMetadata(providerMetadata) {
680
+ const parsed = backgroundTaskMetadataSchema.safeParse(providerMetadata);
681
+ return parsed.success ? parsed.data.mastra.backgroundTask : void 0;
682
+ }
683
+ //#endregion
669
684
  //#region src/tui/db-message-parts.ts
670
685
  function getParts(message) {
671
686
  const content = message.content;
@@ -762,7 +777,9 @@ function getAssistantRenderParts(message) {
762
777
  case "tool-invocation": {
763
778
  const inv = part.toolInvocation;
764
779
  const hasResult = inv.state === "result" && inv.result !== void 0;
780
+ const backgroundTask = getBackgroundToolMetadata(part.providerMetadata);
765
781
  out.push({
782
+ ...backgroundTask ? { backgroundTask } : {},
766
783
  kind: "tool",
767
784
  toolCallId: String(inv.toolCallId ?? ""),
768
785
  toolName: String(inv.toolName ?? ""),
@@ -786,7 +803,9 @@ function getAssistantRenderParts(message) {
786
803
  const legacyPart = part;
787
804
  const toolCallId = String(legacyPart.toolCallId ?? "");
788
805
  const call = toolCalls.get(toolCallId);
806
+ const backgroundTask = getBackgroundToolMetadata(part.providerMetadata);
789
807
  out.push({
808
+ ...backgroundTask ? { backgroundTask } : {},
790
809
  kind: "tool",
791
810
  toolCallId,
792
811
  toolName: String(legacyPart.toolName ?? call?.toolName ?? ""),
@@ -7547,6 +7566,9 @@ var ToolExecutionComponentEnhanced = class extends WidthAwareContainer {
7547
7566
  this.backgroundTaskId = taskId;
7548
7567
  this.rebuild();
7549
7568
  }
7569
+ getBackgroundTaskId() {
7570
+ return this.backgroundTaskId;
7571
+ }
7550
7572
  cancelBackground() {
7551
7573
  this.backgroundCancelled = true;
7552
7574
  this.isPartial = false;
@@ -8368,18 +8390,18 @@ var ToolExecutionComponentEnhanced = class extends WidthAwareContainer {
8368
8390
  return lines;
8369
8391
  };
8370
8392
  if (this.result.isError) {
8371
- const status = theme.fg("error", " ✗");
8393
+ const status = this.getStatusIndicator(true);
8372
8394
  const output = this.streamingOutput.trim() || this.getFormattedOutput();
8373
8395
  renderBorderedShell(status, this.limitQuietShellLines(prepareOutputLines(output)));
8374
8396
  return;
8375
8397
  }
8376
8398
  if (this.getFormattedOutput().match(/Error:|TypeError:|SyntaxError:|ReferenceError:|command not found|fatal:|error:/i)) {
8377
- const status = theme.fg("error", " ✗");
8399
+ const status = this.getStatusIndicator(true);
8378
8400
  const output = this.streamingOutput.trim() || this.getFormattedOutput();
8379
8401
  renderBorderedShell(status, this.limitQuietShellLines(prepareOutputLines(output)));
8380
8402
  return;
8381
8403
  }
8382
- const status = theme.fg("success", " ✓");
8404
+ const status = this.getStatusIndicator(false);
8383
8405
  const output = this.streamingOutput.trim() || this.getFormattedOutput();
8384
8406
  renderBorderedShell(status, this.limitQuietShellLines(prepareOutputLines(output)));
8385
8407
  }
@@ -8416,7 +8438,7 @@ var ToolExecutionComponentEnhanced = class extends WidthAwareContainer {
8416
8438
  renderBorderedProcess(status, lines);
8417
8439
  return;
8418
8440
  }
8419
- renderBorderedProcess(this.result.isError ? theme.fg("error", " ✗") : theme.fg("success", " ✓"), prepareOutputLines(this.streamingOutput.trim() || this.getFormattedOutput()));
8441
+ renderBorderedProcess(this.getStatusIndicator(this.result.isError), prepareOutputLines(this.streamingOutput.trim() || this.getFormattedOutput()));
8420
8442
  }
8421
8443
  renderEditToolEnhanced() {
8422
8444
  const argsObj = this.args;
@@ -9060,16 +9082,16 @@ var ToolExecutionComponentEnhanced = class extends WidthAwareContainer {
9060
9082
  }
9061
9083
  return " " + theme.fg("toolArgs", parts.join(", "));
9062
9084
  }
9063
- getBackgroundStatusIndicator() {
9085
+ getBackgroundStatusIndicator(isError = this.isErrorResult()) {
9064
9086
  if (!this.backgroundTaskId) return "";
9065
9087
  if (this.backgroundCancelled) return theme.fg("muted", ` ■ background · ${this.backgroundTaskId}`);
9066
9088
  if (this.isPartial) return theme.fg("warning", ` ◌ background · ${this.backgroundTaskId}`);
9067
- return this.isErrorResult() ? theme.fg("error", ` ✗ background · ${this.backgroundTaskId}`) : theme.fg("success", ` ✓ background · ${this.backgroundTaskId}`);
9089
+ return isError ? theme.fg("error", ` ✗ background · ${this.backgroundTaskId}`) : theme.fg("success", ` ✓ background · ${this.backgroundTaskId}`);
9068
9090
  }
9069
- getStatusIndicator() {
9070
- const backgroundStatus = this.getBackgroundStatusIndicator();
9091
+ getStatusIndicator(isError = this.isErrorResult()) {
9092
+ const backgroundStatus = this.getBackgroundStatusIndicator(isError);
9071
9093
  if (backgroundStatus) return backgroundStatus;
9072
- return this.isPartial ? theme.fg("muted", " ⋯") : this.isErrorResult() ? theme.fg("error", " ✗") : theme.fg("success", " ✓");
9094
+ return this.isPartial ? theme.fg("muted", " ⋯") : isError ? theme.fg("error", " ✗") : theme.fg("success", " ✓");
9073
9095
  }
9074
9096
  getDurationSuffix() {
9075
9097
  if (this.isPartial) return "";
@@ -9333,12 +9355,6 @@ var PendingUserMessageComponent = class extends _earendil_works_pi_tui.Container
9333
9355
  }
9334
9356
  };
9335
9357
  //#endregion
9336
- //#region src/tui/background-tool-result.ts
9337
- const BACKGROUND_TOOL_TASK_ID_PATTERN = /^Background task started\. Task ID: ([^.\s]+)/;
9338
- function parseBackgroundToolTaskId(result) {
9339
- return BACKGROUND_TOOL_TASK_ID_PATTERN.exec(result)?.[1];
9340
- }
9341
- //#endregion
9342
9358
  //#region src/tui/components/tool-approval-dialog.ts
9343
9359
  /**
9344
9360
  * Tool approval dialog component.
@@ -9792,12 +9808,6 @@ function ensureSubmitPlanComponent(ctx, toolCallId, args) {
9792
9808
  function isToolResultError(result) {
9793
9809
  return typeof result === "object" && result !== null && result.isError === true;
9794
9810
  }
9795
- function getBackgroundToolTaskId(result) {
9796
- return parseBackgroundToolTaskId(formatToolResult(result));
9797
- }
9798
- function isBackgroundToolPlaceholder(result) {
9799
- return getBackgroundToolTaskId(result) !== void 0;
9800
- }
9801
9811
  function formatToolResult(result) {
9802
9812
  if (result === null || result === void 0) return "";
9803
9813
  if (typeof result === "string") return sanitizeAnsiForRendering(result);
@@ -10097,18 +10107,17 @@ function handleToolInputEnd(ctx, toolCallId) {
10097
10107
  flushLatestParsedToolArgs(ctx, toolCallId);
10098
10108
  closeToolInputParser(toolCallId);
10099
10109
  }
10100
- function handleToolEnd(ctx, toolCallId, result, isError) {
10110
+ function handleToolEnd(ctx, toolCallId, result, isError, providerMetadata) {
10101
10111
  flushPendingShellOutput(ctx, toolCallId);
10102
10112
  const { state } = ctx;
10113
+ const background = state.options?.backgroundToolsEnabled ? getBackgroundToolMetadata(providerMetadata) : void 0;
10103
10114
  const subagentComponent = state.pendingSubagents.get(toolCallId);
10104
10115
  if (subagentComponent) {
10105
10116
  const resultText = formatToolResult(result);
10106
10117
  if (pluginSubagentToolCallIds.has(toolCallId)) {
10107
- const backgroundTaskId = state.options?.backgroundToolsEnabled && !isError ? getBackgroundToolTaskId(result) : void 0;
10108
- if (backgroundTaskId) {
10109
- subagentComponent.setBackgroundTaskId(backgroundTaskId);
10110
- flushRender(state);
10111
- } else {
10118
+ if (background) subagentComponent.setBackgroundTaskId(background.taskId);
10119
+ if (background?.status === "running" && !isError) flushRender(state);
10120
+ else {
10112
10121
  subagentComponent.finish(isError, 0, resultText);
10113
10122
  state.pendingSubagents.delete(toolCallId);
10114
10123
  pluginSubagentToolCallIds.delete(toolCallId);
@@ -10127,9 +10136,8 @@ function handleToolEnd(ctx, toolCallId, result, isError) {
10127
10136
  state.allToolComponents.push(component);
10128
10137
  }
10129
10138
  const resultText = formatToolResult(result);
10130
- const backgroundTaskId = state.options?.backgroundToolsEnabled && !effectiveIsError ? getBackgroundToolTaskId(result) : void 0;
10131
- const isBackgroundPlaceholder = backgroundTaskId !== void 0;
10132
- if (backgroundTaskId) component.setBackgroundTaskId?.(backgroundTaskId);
10139
+ const isBackgroundPlaceholder = background?.status === "running" && !effectiveIsError;
10140
+ if (background) component.setBackgroundTaskId?.(background.taskId);
10133
10141
  const toolResult = {
10134
10142
  content: [{
10135
10143
  type: "text",
@@ -10857,7 +10865,7 @@ async function renderExistingMessages(state) {
10857
10865
  const hasResult = part.hasResult;
10858
10866
  const resultValue = part.result;
10859
10867
  const resultIsError = part.isError;
10860
- const isBackgroundPlaceholder = !!state.options?.backgroundToolsEnabled && hasResult && !resultIsError && isBackgroundToolPlaceholder(resultValue);
10868
+ const isBackgroundPlaceholder = !!state.options?.backgroundToolsEnabled && hasResult && !resultIsError && part.backgroundTask?.status === "running" && !backgroundTasksByToolCallId.has(part.toolCallId);
10861
10869
  if (toolName === "subagent") {
10862
10870
  const subArgs = toolArgs;
10863
10871
  const rawResult = hasResult ? formatToolResult(resultValue) : void 0;
@@ -10905,7 +10913,7 @@ async function renderExistingMessages(state) {
10905
10913
  colors: pluginRenderConfig.colors,
10906
10914
  icons: pluginRenderConfig.icons
10907
10915
  });
10908
- const backgroundTaskId = (isBackgroundPlaceholder ? getBackgroundToolTaskId(resultValue) : void 0) ?? backgroundTasksByToolCallId.get(part.toolCallId);
10916
+ const backgroundTaskId = (isBackgroundPlaceholder || part.backgroundTask?.status !== "running" ? part.backgroundTask?.taskId : void 0) ?? backgroundTasksByToolCallId.get(part.toolCallId);
10909
10917
  if (backgroundTaskId) subComponent.setBackgroundTaskId(backgroundTaskId);
10910
10918
  if (cancelledBackgroundToolCalls.has(part.toolCallId)) subComponent.cancel();
10911
10919
  else if (isBackgroundPlaceholder) state.pendingSubagents.set(part.toolCallId, subComponent);
@@ -10918,7 +10926,7 @@ async function renderExistingMessages(state) {
10918
10926
  showImages: false,
10919
10927
  collapsedByDefault: !state.toolOutputExpanded
10920
10928
  }, state.ui);
10921
- const backgroundTaskId = (isBackgroundPlaceholder ? getBackgroundToolTaskId(resultValue) : void 0) ?? backgroundTasksByToolCallId.get(part.toolCallId);
10929
+ const backgroundTaskId = (isBackgroundPlaceholder || part.backgroundTask?.status !== "running" ? part.backgroundTask?.taskId : void 0) ?? backgroundTasksByToolCallId.get(part.toolCallId);
10922
10930
  if (backgroundTaskId) toolComponent.setBackgroundTaskId(backgroundTaskId);
10923
10931
  if (hasResult) toolComponent.updateResult({
10924
10932
  content: [{
@@ -10927,8 +10935,16 @@ async function renderExistingMessages(state) {
10927
10935
  }],
10928
10936
  isError: resultIsError
10929
10937
  }, isBackgroundPlaceholder);
10930
- if (cancelledBackgroundToolCalls.has(part.toolCallId)) toolComponent.cancelBackground();
10931
- else if (isBackgroundPlaceholder) state.pendingTools.set(part.toolCallId, toolComponent);
10938
+ if (cancelledBackgroundToolCalls.has(part.toolCallId)) {
10939
+ toolComponent.updateResult({
10940
+ content: [{
10941
+ type: "text",
10942
+ text: "Background execution cancelled."
10943
+ }],
10944
+ isError: true
10945
+ }, true);
10946
+ toolComponent.cancelBackground();
10947
+ } else if (isBackgroundPlaceholder) state.pendingTools.set(part.toolCallId, toolComponent);
10932
10948
  let replacedWithInline = false;
10933
10949
  if (isTaskMutationTool(toolName) && hasResult && !resultIsError) {
10934
10950
  hasReplayedTaskState = true;
@@ -11187,6 +11203,11 @@ async function handleNewCommand(ctx) {
11187
11203
  state.globalBackgroundNotice.setActivities([]);
11188
11204
  setCurrentThreadTitle(state, void 0);
11189
11205
  disposeAssistantRenderState(state);
11206
+ state.gradientAnimator?.stop();
11207
+ state.githubPrGradientAnimator?.stop();
11208
+ state.githubPrPollingActive = false;
11209
+ state.agentRunStartedAt = void 0;
11210
+ state.agentRunLastStreamPartAt = void 0;
11190
11211
  state.chatContainer.clear();
11191
11212
  state.pendingTools.clear();
11192
11213
  state.pendingTaskToolIds?.clear();
@@ -18280,8 +18301,8 @@ function showStatus(ctx) {
18280
18301
  lines.push("");
18281
18302
  lines.push(theme.fg("dim", " Run /observability connect to re-enter credentials."));
18282
18303
  } else {
18283
- const envToken = process.env.MASTRA_CLOUD_ACCESS_TOKEN;
18284
- const envProject = process.env.MASTRA_PROJECT_ID;
18304
+ const envToken = process.env.MASTRACODE_CLOUD_ACCESS_TOKEN?.trim();
18305
+ const envProject = process.env.MASTRACODE_PROJECT_ID?.trim();
18285
18306
  if (envToken) {
18286
18307
  lines.push(` ${theme.fg("success", "●")} Connected ${theme.fg("dim", "(via environment variables)")}`);
18287
18308
  if (envProject) lines.push(` Project: ${envProject}`);
@@ -20559,16 +20580,19 @@ function handleMessageEnd(ctx, message) {
20559
20580
  });
20560
20581
  if (stopReason === "aborted" || stopReason === "error") {
20561
20582
  const abortMessage = errorMessage || "Operation aborted";
20562
- for (const [, component] of state.pendingTools) component.updateResult({
20563
- content: [{
20564
- type: "text",
20565
- text: abortMessage
20566
- }],
20567
- isError: true
20568
- }, false);
20583
+ for (const [toolCallId, component] of state.pendingTools) {
20584
+ if (component.getBackgroundTaskId?.()) continue;
20585
+ component.updateResult({
20586
+ content: [{
20587
+ type: "text",
20588
+ text: abortMessage
20589
+ }],
20590
+ isError: true
20591
+ }, false);
20592
+ state.pendingTools.delete(toolCallId);
20593
+ state.pendingTaskToolIds?.delete(toolCallId);
20594
+ }
20569
20595
  reconcileChatBoundarySpacers(state.chatContainer);
20570
- state.pendingTools.clear();
20571
- state.pendingTaskToolIds?.clear();
20572
20596
  }
20573
20597
  state.assistantRenderRegistry.finalize(message.id);
20574
20598
  finalizeStreamingAssistant(state);
@@ -23618,6 +23642,7 @@ function applyMessageUpdate(message, update) {
23618
23642
  };
23619
23643
  }
23620
23644
  async function dispatchEvent(event, ectx, state) {
23645
+ if ("toolCallId" in event && "threadId" in event && event.threadId && (state.pendingNewThread || event.threadId !== state.session.thread.getId())) return;
23621
23646
  switch (event.type) {
23622
23647
  case "agent_start":
23623
23648
  clearToolInputParsers();
@@ -23673,7 +23698,7 @@ async function dispatchEvent(event, ectx, state) {
23673
23698
  case "tool_start":
23674
23699
  state.agentRunLastStreamPartAt = Date.now();
23675
23700
  if (state.options.backgroundToolsEnabled) {
23676
- const threadId = state.session.thread.getId();
23701
+ const threadId = event.threadId ?? state.session.thread.getId();
23677
23702
  if (threadId) state.backgroundToolContexts.set(event.toolCallId, {
23678
23703
  toolName: event.toolName,
23679
23704
  resourceId: state.session.identity.getResourceId(),
@@ -23716,7 +23741,8 @@ async function dispatchEvent(event, ectx, state) {
23716
23741
  case "tool_end":
23717
23742
  state.agentRunLastStreamPartAt = Date.now();
23718
23743
  if (state.options.backgroundToolsEnabled) {
23719
- const taskId = getBackgroundToolTaskId(event.result);
23744
+ const background = getBackgroundToolMetadata(event.providerMetadata);
23745
+ const taskId = !event.isError && background?.status === "running" ? background.taskId : void 0;
23720
23746
  const context = state.backgroundToolContexts.get(event.toolCallId);
23721
23747
  if (taskId && context) {
23722
23748
  acceptBackgroundActivity(state.backgroundActivities, taskId, event.toolCallId, context);
@@ -23726,7 +23752,7 @@ async function dispatchEvent(event, ectx, state) {
23726
23752
  }
23727
23753
  if (!taskId) state.backgroundToolContexts.delete(event.toolCallId);
23728
23754
  }
23729
- handleToolEnd(ectx, event.toolCallId, event.result, event.isError);
23755
+ handleToolEnd(ectx, event.toolCallId, event.result, event.isError, event.providerMetadata);
23730
23756
  break;
23731
23757
  case "info":
23732
23758
  ectx.showInfo(event.message);
@@ -23743,6 +23769,7 @@ async function dispatchEvent(event, ectx, state) {
23743
23769
  case "thread_changed": {
23744
23770
  ectx.showInfo(`Switched to thread: ${event.threadId}`);
23745
23771
  state.latestRequestPromptTokens = void 0;
23772
+ state.backgroundToolContexts?.clear();
23746
23773
  await state.session.state.set({
23747
23774
  tasks: [],
23748
23775
  activePlan: null,
@@ -23777,6 +23804,7 @@ async function dispatchEvent(event, ectx, state) {
23777
23804
  case "thread_created": {
23778
23805
  ectx.showInfo(`Created thread: ${event.thread.id}`);
23779
23806
  state.latestRequestPromptTokens = void 0;
23807
+ state.backgroundToolContexts?.clear();
23780
23808
  setCurrentThreadTitle(state, event.thread.title);
23781
23809
  state.activeGithubPrSubscriptions = getGithubPrSubscriptionsFromMetadata(event.thread.metadata);
23782
23810
  state.githubPrPollingActive = false;
@@ -26978,4 +27006,4 @@ Object.defineProperty(exports, "theme", {
26978
27006
  }
26979
27007
  });
26980
27008
 
26981
- //# sourceMappingURL=tui-V-RCfOzz.cjs.map
27009
+ //# sourceMappingURL=tui-D5UsAQOX.cjs.map