Skip to content

feat: Implement audio transcription and agent hooks#57

Merged
ssdeanx merged 1 commit intomainfrom
develop
Dec 15, 2025
Merged

feat: Implement audio transcription and agent hooks#57
ssdeanx merged 1 commit intomainfrom
develop

Conversation

@ssdeanx
Copy link
Owner

@ssdeanx ssdeanx commented Dec 15, 2025

  • Added a new POST route for audio transcription in app/api/audio/route.ts that utilizes the Mastra instance to transcribe audio files uploaded via form data.
  • Created custom hooks for managing agent interactions:
    • lib/hooks/use-agent-messages.ts: Fetches messages from a specific thread for a given agent.
    • lib/hooks/use-agent.ts: Retrieves details of a specified agent.
    • lib/hooks/use-delete-thread.ts: Provides functionality to delete a memory thread and invalidate related queries.
    • lib/hooks/use-memory.ts: Checks the memory status of a specified agent.
    • lib/hooks/use-mobile.ts: Detects if the application is being accessed on a mobile device.
    • lib/hooks/use-threads.ts: Lists memory threads for a specific resource and agent.
  • Introduced a new note-taking agent in src/mastra/agents/noteTakerAgent.ts with specific instructions and voice capabilities using Google Voice.
  • Established a structured approach for handling memory and threads in the application, enhancing the overall functionality and user experience.

- Added a new POST route for audio transcription in `app/api/audio/route.ts` that utilizes the Mastra instance to transcribe audio files uploaded via form data.
- Created custom hooks for managing agent interactions:
  - `lib/hooks/use-agent-messages.ts`: Fetches messages from a specific thread for a given agent.
  - `lib/hooks/use-agent.ts`: Retrieves details of a specified agent.
  - `lib/hooks/use-delete-thread.ts`: Provides functionality to delete a memory thread and invalidate related queries.
  - `lib/hooks/use-memory.ts`: Checks the memory status of a specified agent.
  - `lib/hooks/use-mobile.ts`: Detects if the application is being accessed on a mobile device.
  - `lib/hooks/use-threads.ts`: Lists memory threads for a specific resource and agent.
- Introduced a new note-taking agent in `src/mastra/agents/noteTakerAgent.ts` with specific instructions and voice capabilities using Google Voice.
- Established a structured approach for handling memory and threads in the application, enhancing the overall functionality and user experience.
Copilot AI review requested due to automatic review settings December 15, 2025 08:15
@continue
Copy link

continue bot commented Dec 15, 2025

All Green - Keep your PRs mergeable

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @ssdeanx, your pull request is larger than the review limit of 150000 diff characters

@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added audio transcription functionality for note capture
    • Introduced Note Taker Agent with voice input support
    • Added agent message history and memory management capabilities
    • Enhanced mobile responsiveness detection
    • Expanded workflow support including repo ingestion and spec generation
  • Documentation

    • Added comprehensive guides for commit messages, PR formatting, and test strategies
    • Introduced security and responsible AI guidelines
    • Added specialized agent documentation for various team roles
  • Improvements

    • Standardized workflow progress tracking across all processes
    • Enhanced state management in chat and network providers
    • Optimized token processing in agents

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Introduces comprehensive documentation for AI agent governance rules (commit message, PR message, planning mode, prompt injection guard, test strategy), multiple new agent profiles and instruction templates, workflow progress event refactoring across the system, new memory/thread management hooks, audio transcription capability, refactored React context providers with derived state and memoization, agent configuration updates including batch processors and token limits, and dependency updates.

Changes

Cohort / File(s) Summary
Agent Governance & Rule Documentation
.agent/README.md, .agent/rules/*, .windsurf/rules/*, .agent/doc/*
New comprehensive documentation defining Windsurf/Antigravity rules, commit message formatting, PR message formatting, planning mode guards, prompt injection defense, and test strategy for both .agent/ and .windsurf/ directories. Includes design documents for external context injection defense and runtime implementation details.
Agent Profile & Instruction Templates
.github/agents/*, .github/instructions/*, .github/copilot-instructions.md
Introduces 8 new agent specification documents (GitOps CI specialist, Product Manager Advisor, Responsible AI, Security Reviewer, System Architecture, Technical Writer, UX/UI Designer, Software Engineer v1) and 3 new instruction guides (code review, thought logging, doc updates). Updates copilot instructions with Byterover MCP tool guidance.
Workflow Documentation
.agent/doc/rules-and-workflows.md, .agent/workflows/*, .windsurf/workflows/*
New documentation clarifying rules/workflows separation and introduces 3 workflow files (commit-only, commit-push, commit-push-pr) for both .agent/ and .windsurf/ directories with execution patterns and safeguards.
Audio Transcription Feature
app/api/audio/route.ts
Adds new POST route handler for audio file transcription, parsing multipart form data and invoking noteTakerAgent's listen method.
React Context Provider Refactoring
app/chat/providers/chat-context.tsx, app/networks/providers/network-context.tsx, app/workflows/providers/workflow-context.tsx
Refactors context providers to use derived state via memoization, renames parameters (removing underscores), replaces effect-based state updates with computed values (sources, progressEvents, routingSteps, webPreview), and introduces deferred/batched state updates.
Memory & Thread Management Hooks
lib/hooks/use-agent-messages.ts, lib/hooks/use-agent.ts, lib/hooks/use-delete-thread.ts, lib/hooks/use-memory.ts, lib/hooks/use-threads.ts, lib/hooks/use-mobile.ts
Adds 6 new React hooks for memory threads, agent details, thread deletion, memory status, thread listing, and mobile viewport detection using react-query and Mastra client.
Agent Configuration Updates
src/mastra/agents/learningExtractionAgent.ts, src/mastra/agents/noteTakerAgent.ts, src/mastra/agents/package-publisher.ts, src/mastra/agents/recharts.ts, src/mastra/agents/reportAgent.ts, src/mastra/agents/researchAgent.ts, src/mastra/agents/researchPaperAgent.ts
Introduces noteTakerAgent with Google Voice, reduces token limits from 1048576 to 128000 in multiple agents, adds BatchPartsProcessor for output batching with batchSize=5/maxWaitTime=75/emitOnNonText=true, adds UnicodeNormalizer input processor to chartSupervisorAgent.
Mastra Instance & Workflow Registration
src/mastra/index.ts
Expands Mastra instance configuration to register governedRagIndex, repoIngestionWorkflow, and specGenerationWorkflow; adds noteTakerAgent and multiple new agents to instance; updates scorers to empty object; restructures imports for new workflows/agents.
Workflow Progress Event Refactoring
src/mastra/workflows/changelog.ts, src/mastra/workflows/content-review-workflow.ts, src/mastra/workflows/content-studio-workflow.ts, src/mastra/workflows/document-processing-workflow.ts, src/mastra/workflows/financial-report-workflow.ts, src/mastra/workflows/governed-rag-index.workflow.ts, src/mastra/workflows/learning-extraction-workflow.ts, src/mastra/workflows/repo-ingestion-workflow.ts, src/mastra/workflows/research-synthesis-workflow.ts, src/mastra/workflows/spec-generation-workflow.ts, src/mastra/workflows/stock-analysis-workflow.ts, src/mastra/workflows/telephone-game.ts, src/mastra/workflows/weather-workflow.ts
Systematically converts workflow progress events from discrete data-workflow-step-* signals (start, complete, error) to unified data-tool-progress payloads with status/message/stage fields. Updates step execute signatures to accept inputData and writer parameters. Adds dynamic context-aware progress messages and error handling through unified progress channel.
Workflow Implementation Updates
src/mastra/workflows/AGENTS.md
Adds id field to express-processing step data.
Configuration & Metadata
AGENTS.md, package.json, tsconfig.json
Updates package.json with dependency version bumps (lucide-react, vscode-languageserver, ai, type/node, @mastra/react, @supermemory/tools, @mcpc-tech/acp-ai-provider), moves eslint packages to devDependencies. Expands tsconfig exclude patterns for node_modules TS/TSX/D.ts files. Updates AGENTS.md with Byterover MCP workflows and tool sequences.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Large scope: 40+ files modified across documentation, configuration, agents, contexts, workflows, and hooks
  • Systematic refactoring: Progress event conversion pattern repeated across 13+ workflow files with homogeneous changes reducing per-file review complexity
  • Complex state management: Chat/Network/Workflow context providers refactored with derived state, memoization, deferred updates, and parameter renames across public API signatures
  • Multiple concerns: Agent processor configuration, hook implementations, route handler, dependency updates all requiring separate reasoning
  • Mitigating factors: Many documentation files are straightforward; repetitive pattern changes lower cognitive overhead despite file count

Areas requiring extra attention:

  • Chat context (app/chat/providers/chat-context.tsx): Multiple public API signature changes with derived state logic — verify memoization dependencies and context value synchronization
  • Network context (app/networks/providers/network-context.tsx): Complex routing steps derivation and tool invocation state expansion — ensure routing logic correctness with per-agent handling
  • Workflow context (app/workflows/providers/workflow-context.tsx): Deferred state updates and 0ms timeout batching — verify no race conditions or lost updates
  • Workflow progress refactoring: While systematic, spot-check a few workflows (e.g., financial-report-workflow.ts, spec-generation-workflow.ts) to ensure inputData usage and writer.custom calls are correct
  • Agent token limit reduction (1048576 → 128000): Verify this is intentional and impacts are understood across multiple agents
  • New hooks: Validate react-query configuration (staleTime, gcTime, retry settings) aligns with memory/thread management semantics

Possibly related PRs

Suggested reviewers

  • sourcery-ai

🐰 Whisker-twitching through your rules and flows,
New agents sprout where agent knowledge grows,
Workflows unified in progress divine,
Memory threads and hooks intertwine,
From audio transcripts to safety's guard—
No prompt injection shall pass this yard! 🛡️

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Implement audio transcription and agent hooks' accurately reflects the primary changes in the changeset: adding audio transcription functionality and new agent-related hooks.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing the audio route, custom hooks, the note-taking agent, and memory/thread handling improvements.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

🤖 Hi @ssdeanx, I've received your request, and I'm working on it now! You can track my progress in the logs for more details.

@github-actions
Copy link

🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see the logs for more details.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ssdeanx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the application's AI capabilities by integrating audio transcription and introducing a new note-taking agent. It also enhances the developer experience and system robustness through a suite of new agent-specific React hooks, standardized agent rules and Git workflows, and refined UI context management for better performance and clearer progress feedback. These changes aim to provide a more structured and efficient framework for agent-driven features and development practices.

Highlights

  • Audio Transcription API: A new POST route has been added at app/api/audio/route.ts to handle audio file transcription using the Mastra instance and a dedicated note-taking agent.
  • New Agent Interaction Hooks: Several custom React hooks have been introduced in lib/hooks/ to streamline agent interactions, including fetching messages, retrieving agent details, deleting threads, checking memory status, detecting mobile devices, and listing memory threads.
  • Dedicated Note-Taking Agent: A new noteTakerAgent has been implemented in src/mastra/agents/noteTakerAgent.ts, configured with specific instructions, memory, tools, and Google Voice capabilities for audio transcription.
  • Enhanced Agent Rules and Workflows: A comprehensive set of new Markdown files has been added under .agent/ and .windsurf/ directories, defining detailed rules for commit messages, PR formats, planning mode guards, prompt injection defenses, test strategies, and coding assistance (v5). Corresponding Git workflows for commit, push, and PR creation are also included.
  • Improved UI Context Management: The ChatContext and NetworkContext providers have been refactored to optimize state management for sources, web previews, and workflow progress events, reducing cascading renders and improving responsiveness.
  • Workflow Progress Reporting Standardization: Numerous workflow files across src/mastra/workflows/ have been updated to use a standardized data-tool-progress custom event for more granular and consistent progress reporting during step execution.
  • Dependency Updates and Configuration Refinements: Key dependencies in package.json have been updated, and agent configurations in src/mastra/index.ts have been refined, including the removal of certain scorers and adjustments to observability settings.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ssdeanx ssdeanx merged commit 963763f into main Dec 15, 2025
17 of 21 checks passed
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant number of new features and documentation. Key additions include an audio transcription route, several custom hooks for agent and memory management, and a new note-taking agent. The PR also includes extensive documentation for agents, workflows, and security rules. I've identified a few areas for improvement, primarily related to error handling in the new API route and some minor cleanup in documentation and provider code. Overall, this is a substantial and well-structured contribution.

Comment on lines +4 to +21
export async function POST(req: Request) {
// Get the audio file from the request
const formData = await req.formData();
const audioFile = formData.get("audio") as File;
const arrayBuffer = await audioFile.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
const readable = Readable.from(buffer);

// Get the note taker agent from the Mastra instance
const noteTakerAgent = mastra.getAgent("noteTakerAgent");

// Transcribe the audio file
const text = await noteTakerAgent.voice?.listen(readable);

return new Response(JSON.stringify({ text }), {
headers: { "Content-Type": "application/json" },
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current implementation lacks robust error handling. For instance, if formData.get("audio") doesn't find a file or if noteTakerAgent.voice is unavailable, the route will throw an unhandled exception, leading to a server crash. It's crucial to validate inputs and the availability of services, returning appropriate HTTP error responses to the client.

export async function POST(req: Request) {
  try {
    const formData = await req.formData();
    const audioFile = formData.get("audio");

    if (!(audioFile instanceof File)) {
      return new Response(JSON.stringify({ error: "No audio file uploaded." }), {
        status: 400,
        headers: { "Content-Type": "application/json" },
      });
    }

    const arrayBuffer = await audioFile.arrayBuffer();
    const buffer = Buffer.from(arrayBuffer);
    const readable = Readable.from(buffer);

    const noteTakerAgent = mastra.getAgent("noteTakerAgent");

    if (!noteTakerAgent?.voice) {
      return new Response(JSON.stringify({ error: "Voice service not available." }), {
        status: 500,
        headers: { "Content-Type": "application/json" },
      });
    }

    const text = await noteTakerAgent.voice.listen(readable);

    return new Response(JSON.stringify({ text }), {
      headers: { "Content-Type": "application/json" },
    });
  } catch (error) {
    console.error("Audio transcription failed:", error);
    return new Response(JSON.stringify({ error: "Failed to process audio file." }), {
      status: 500,
      headers: { "Content-Type": "application/json" },
    });
  }
}

Comment on lines +43 to +44

[byterover-mcp]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The [byterover-mcp] tag is duplicated. To avoid potential confusion for the tool parsing these instructions, it's best to remove the redundant line.

1. **MOST IMPORTANT**: **ALWAYS USE** **byterover-retrieve-knowledge** once or several times for **EACH TASK** of the plan to gather necessary context for complete that task.
2. **MOST IMPORTANT**: **ALWAYS USE** **byterover-store-knowledge** once or several times to store critical knowledge and context for future implementations
3. Over 15 provided tools, **byterover-retrieve-knowledge** and **byterover-store-knowledge** ARE the two main tools, which **MUST** be used regularly. You can use these two main tools outside the two main workflows for retrieval and storage purposes.
4. You **MUST** include phrases like **"According to Byterover memory layer"**, **"Based on memory extracted from Byterover"**, **"From Byterover memomry tools"**, ... to explictly showcase that these sources are from **Byterover**.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a small typo here. "memomry" should be "memory".

Suggested change
4. You **MUST** include phrases like **"According to Byterover memory layer"**, **"Based on memory extracted from Byterover"**, **"From Byterover memomry tools"**, ... to explictly showcase that these sources are from **Byterover**.
4. You **MUST** include phrases like **"According to Byterover memory layer"**, **"Based on memory extracted from Byterover"**, **"From Byterover memory tools"**, ... to explictly showcase that these sources are from **Byterover**.

Comment on lines 458 to +463
const clearHistory = useCallback(() => {
setMessages([])
setRoutingSteps([])
setProgressEvents([])
setNetworkError(null)
setSources([])
}, [setMessages])
setClearedProgress(true)
}, [setMessages, setRoutingSteps, setNetworkError])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The clearedProgress state, which is set to true here, is not used anywhere else in the component. This appears to be dead code. To improve clarity and maintainability, it's best to remove the unused state variable and this setter call.

  const clearHistory = useCallback(() => {
    setMessages([])
    setRoutingSteps([])
    setNetworkError(null)
  }, [setMessages, setRoutingSteps, setNetworkError])

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements audio transcription capabilities and custom hooks for agent interactions, alongside significant refactoring to standardize workflow progress events and fix React state management issues.

Key Changes

  1. New Audio Transcription: Added POST endpoint /api/audio/route.ts for audio file transcription using Mastra's voice capabilities
  2. Custom React Hooks: Created 6 new hooks for agent interactions (threads, messages, memory management, mobile detection)
  3. Workflow Progress Standardization: Unified progress event format across 12 workflow files (changed stepId to stage, standardized status values)
  4. React State Management Fixes: Fixed cascading render issues in context providers by replacing synchronous useEffect setState with deferred updates and useMemo
  5. New noteTakerAgent: Added voice-enabled agent with Google Voice integration

Reviewed changes

Copilot reviewed 67 out of 69 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
app/api/audio/route.ts New POST endpoint for audio transcription using noteTakerAgent
lib/hooks/use-*.ts Six new custom hooks for agent operations (threads, messages, memory, etc.)
src/mastra/agents/noteTakerAgent.ts New agent with voice transcription capabilities using GoogleVoice
src/mastra/workflows/*.ts Standardized progress events: stepIdstage, unified status values
app/*/providers/*-context.tsx Fixed React cascading render issues with deferred state updates
src/mastra/agents/*.ts Added BatchPartsProcessor to output processors for several agents
package.json Updated dependencies including @inquirer/prompts, ai, lucide-react
tsconfig.json Added redundant node_modules exclusion patterns
.windsurf/, .github/ Added workflow documentation and agent configurations

const [progressEvents, setProgressEvents] = useState<ProgressEvent[]>([])
const [networkError, setNetworkError] = useState<string | null>(null)
const [sources, setSources] = useState<Source[]>([])
const [clearedProgress, setClearedProgress] = useState(false)
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable clearedProgress.

Copilot uses AI. Check for mistakes.
id: "stepA1",
});
id: 'stepA1',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (94% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
id: "stepA1",
});
id: 'stepA1',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (94% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
id: "research-topic",
});
id: 'research-topic',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (91% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
id: "research-topic",
});
id: 'research-topic',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (91% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
id: "draft-content",
});
id: 'draft-content',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (94% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
id: "draft-content",
});
id: 'draft-content',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (94% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
stage: 'initial-review',
},
id: 'initial-review',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (95% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
id: "initial-review",
});
id: 'initial-review',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (95% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
id: "refine-content",
});
id: 'refine-content',
})
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (98% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 64

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (21)
src/mastra/workflows/telephone-game.ts (4)

6-15: Enhance agent instructions for better behavior guidance.

The agent instructions are minimal ("Telephone game agent"). For a telephone game agent that modifies messages, consider adding more specific instructions about how it should transform or distort messages (e.g., word substitution strategies, humor level, semantic drift patterns).

Example enhancement:

-  instructions: `Telephone game agent`,
+  instructions: `You are playing the telephone game. When you receive a message, make subtle modifications to it - change a word or two, rephrase slightly, or introduce small misunderstandings while keeping the general meaning. Be creative but don't completely change the message. Your goal is to create natural drift as messages pass through the chain.`,

17-87: Consider consolidating redundant pass-through steps.

Both stepA1 and stepA2 perform identical operations—they simply pass the message through without any transformation or validation. This adds unnecessary complexity to the workflow.

Consider either:

  1. Removing one of the steps entirely, or
  2. Giving each step a distinct purpose (e.g., validation in stepA1, normalization in stepA2)

If these steps are placeholders for future functionality, consider adding a TODO comment explaining the intended behavior.


89-123: Fix misleading step description.

The description states "Checks if the file exists," but the implementation only passes through the message without any file-checking logic. This appears to be a copy-paste error or outdated description.

Apply this diff to correct the description:

 const stepB2 = createStep({
   id: 'stepB2',
-  description: 'Checks if the file exists',
+  description: 'Validates the message before modification',
   inputSchema: z.object({

Alternatively, if this step is a placeholder for future file-checking functionality, add a TODO comment explaining the intended behavior.


125-166: Fix description and add error handling for agent call.

Two issues:

  1. Minor: The description states "Ask if you should modify the message," but the implementation unconditionally modifies the message. The description should be updated to match the behavior.

  2. Major: The telephone.generate() call at line 145 lacks error handling. If the agent call fails (network issues, API limits, model errors), the step will throw an unhandled exception.

Apply this diff:

 const stepC2 = createStep({
   id: 'stepC2',
-  description: 'Ask if you should modify the message',
+  description: 'Modifies the message using the telephone agent',
   inputSchema: z.object({
     message: z.string(),
   }),
   outputSchema: z.object({
     message: z.string(),
   }),
   execute: async ({ inputData, writer }) => {
     await writer?.custom({
       type: 'data-tool-progress',
       data: {
         status: 'in-progress',
         message: `Modifying message: ${inputData.message}`,
         stage: 'stepC2',
       },
       id: 'stepC2',
     });

+    try {
       const result = await telephone.generate(`
           You are playing a game of telephone.
           Here is the message the previous person sent ${inputData.message}.
           But you want to change the message.
           Only return the message
           `);

       await writer?.custom({
         type: 'data-tool-progress',
         data: {
           status: 'done',
           message: `Message modified: ${result.text}`,
           stage: 'stepC2',
         },
         id: 'stepC2',
       });

       return {
         message: result.text,
       };
+    } catch (error) {
+      await writer?.custom({
+        type: 'data-tool-progress',
+        data: {
+          status: 'error',
+          message: `Failed to modify message: ${error instanceof Error ? error.message : 'Unknown error'}`,
+          stage: 'stepC2',
+        },
+        id: 'stepC2',
+      });
+      throw error;
+    }
   },
 });
app/chat/providers/chat-context.tsx (5)

57-63: WebPreviewData interface is missing html property.

The WebPreviewData interface in agent-web-preview.tsx includes an html?: string property, but this local definition omits it. The derivedWebPreview logic at lines 308-310 handles HTML content but doesn't expose it in the returned object, which may cause inconsistencies if consumers expect the html field.

 export interface WebPreviewData {
   id: string
   url: string
   title?: string
   code?: string
   language?: string
+  html?: string
 }

177-205: Inconsistent indentation and duplicate fields in request body.

The request body has formatting inconsistencies and resourceId appears twice (line 196 at top level and line 194 in requestMetadata). Additionally, id (line 185) and data.agentId (line 198) are redundant.

Consider consolidating the structure and fixing indentation:

       prepareSendMessagesRequest({ messages: outgoingMessages }) {
         const last = outgoingMessages[outgoingMessages.length - 1]
         const textPart = last?.parts?.find((p): p is TextUIPart => p.type === "text")

         return {
-              body: {
-                // id at top-level is used by chatRoute to select the agent when
-                // multiple chatRoute handlers are registered at the same path.
-                id: selectedAgent,
+          body: {
+            id: selectedAgent,
             messages: outgoingMessages,
             memory: {
-            thread: threadId,
-            resource: resourceId,
-          },
-          requestMetadata: {
-            agentId: selectedAgent,
-            resourceId,
-          },
-            // set resourceId so server can use it for tracing/memory if needed
+              thread: threadId,
+              resource: resourceId,
+            },
+            requestMetadata: {
+              agentId: selectedAgent,
+              resourceId,
+            },
-            resourceId,
             data: {
               agentId: selectedAgent,
               threadId,
               input: textPart?.text ?? "",
             },
           },
         }
       },

208-213: Unnecessary parentheses around Boolean(chatError).

   const status: ChatStatus = useMemo(() => {
-    if (aiError || (Boolean(chatError))) {return "error"}
+    if (aiError || chatError) { return "error" }
     if (aiStatus === "streaming") {return "streaming"}
     if (aiStatus === "submitted") {return "submitted"}
     return "ready"
   }, [aiStatus, aiError, chatError])

325-332: Unused files parameter breaks interface contract.

The files parameter is declared in the signature but never used. Callers passing files will have them silently ignored, which breaks the expected behavior of the sendMessage(text, files?) interface.

Either implement file handling or remove the parameter from the signature if file uploads are not yet supported:

   const sendMessage = useCallback(
-    (text: string, files?: File[]) => {
+    (text: string, _files?: File[]) => {
+      // TODO: Implement file upload support
       if (!text.trim() || isLoading) {return}
       setChatError(null)
       aiSendMessage({ text: text.trim() })
     },
     [isLoading, aiSendMessage]
   )

Or if files should be intentionally ignored for now, document it and use the underscore prefix convention to indicate an intentionally unused parameter.


338-359: Resetting sourcesState to [] prevents fallback to derived sources.

Setting sourcesState to an empty array at lines 340 and 353 means sourcesState ?? derivedSources evaluates to [] instead of falling back to derivedSources. Per the comment at line 150, null should be used to enable the fallback.

   const clearMessages = useCallback(() => {
     setMessages([])
-    setSourcesState([])
+    setSourcesState(null)
     setChatError(null)
     setQueuedTasks([])
     setPendingConfirmations([])
     setCheckpoints([])
     setWebPreviewState(null)
     messageSnapshotsRef.current.clear()
   }, [setMessages])

   const selectAgent = useCallback(
     (agentId: string) => {
       if (Object.prototype.hasOwnProperty.call(AGENT_CONFIGS, agentId)) {
         setSelectedAgent(agentId)
-        setSourcesState([])
+        setSourcesState(null)
         setChatError(null)
         setWebPreviewState(null)
       }
     },
     []
   )
app/networks/providers/network-context.tsx (1)

355-433: Fix circular dependency in routing steps derivation.

The derivedRoutingSteps memo includes routingSteps in its dependency array (Line 428) and returns it as a fallback value (Lines 357, 362, 427), while an effect (Lines 431-433) updates routingSteps from derivedRoutingSteps. This creates a circular dependency that can cause infinite re-renders or unpredictable behavior.

Root cause: When no new routing data is available, the memo returns the current routingSteps, which then triggers the effect to set routingSteps to itself, which re-triggers the memo, creating a cycle.

Apply this diff to break the circular dependency:

   const derivedRoutingSteps = useMemo(() => {
     const lastMessage = messages[messages.length - 1]
-    if (lastMessage?.role !== "assistant" || !lastMessage.parts?.length) {return routingSteps}
+    if (lastMessage?.role !== "assistant" || !lastMessage.parts?.length) {return []}
 
     const dataParts = lastMessage.parts.filter(
       (p) => p.type === "data-network" || p.type === "dynamic-tool" || (typeof p.type === "string" && p.type.startsWith("data-tool-"))
     )
-    if (!dataParts?.length) {return routingSteps}
+    if (!dataParts?.length) {return []}
 
     // Helper: map raw state to routing step status
     const mapRawStateToStatus = (raw: unknown, hasOutput = false): RoutingStep["status"] => {
       const rs = (raw ?? "").toString().toLowerCase()
       if (rs.includes("stream") || rs.includes("running") || rs.includes("active")) {return "active"}
       if (rs.includes("success") || rs.includes("done") || rs.includes("completed") || hasOutput) {return "completed"}
       if (rs.includes("error") || rs.includes("failed")) {return "error"}
       return "pending"
     }
 
     // Prefer a data-network part that includes explicit per-agent details
     const networkPart = dataParts.find((p) => p.type === "data-network") as NetworkDataPart | undefined
     if (networkPart) {
       const payload = (networkPart as { data?: NetworkPayload; payload?: NetworkPayload }).data ?? (networkPart as { data?: NetworkPayload; payload?: NetworkPayload }).payload ?? networkPart as NetworkPayload
       const agentsFromPart = (payload?.agents ?? payload?.nodes ?? payload?.steps ?? [])
 
       if (Array.isArray(agentsFromPart) && agentsFromPart.length > 0) {
         return agentsFromPart.map((agent, idx) => {
                   const agentId = agent.id ?? agent.agentId ?? agent.agent?.id ?? `agent-${idx}`
                   const agentName = agent.name ?? agent.agentName ?? agent.agent?.name ?? String(agentId)
                   const input = agent.input ?? agent.args ?? agent.params ?? ""
                   const output = agent.output ?? agent.result ?? agent.value
                   const status = mapRawStateToStatus(agent.state ?? agent.status, Boolean(output))
                   const startedAt = agent.startedAt !== null && agent.startedAt !== undefined ? new Date(agent.startedAt) : undefined
                   const completedAt = agent.completedAt !== null && agent.completedAt !== undefined ? new Date(agent.completedAt) : undefined
                   return {
                     agentId: String(agentId),
                     agentName: String(agentName),
                     input,
                     output,
                     status,
                     startedAt,
                     completedAt,
                   } as RoutingStep
                 });
       }
     }
 
     // Fallback: create steps from the network configuration (if available) or from dynamic-tool parts
     if (networkConfig?.agents?.length) {
       const steps: RoutingStep[] = networkConfig.agents.map((agent, index) => ({
         agentId: agent.id,
         agentName: agent.name,
         input: "",
         status: index === 0 && aiStatus === "streaming" ? "active" : "pending",
       }))
       return steps
     }
 
     const toolParts = dataParts.filter((p) => p.type === "dynamic-tool" || (typeof p.type === "string" && p.type.startsWith("data-tool-")))
     if (toolParts.length > 0) {
       const steps: RoutingStep[] = toolParts.map((tp, idx) => {
         const converted = mapDataPartToDynamicTool(tp as MastraPart)
         return {
           agentId: converted?.toolCallId ?? `tool-${idx}`,
           agentName: converted?.toolName ?? `tool-${idx}`,
           input: converted?.input ?? "",
           output: converted?.output ?? undefined,
           status: converted ? (converted.state === "input-streaming" ? "active" : (converted.state === "output-error" ? "error" : (converted.state === "output-available" ? "completed" : "pending"))) : "pending",
         } as RoutingStep
       })
       return steps
     }
 
-    return routingSteps
-  }, [messages, networkConfig, aiStatus, routingSteps])
+    return []
+  }, [messages, networkConfig, aiStatus])

This ensures derivedRoutingSteps is purely derived from message data and configuration, not from the state it's trying to update.

src/mastra/workflows/financial-report-workflow.ts (3)

740-751: Missing null check before piping to writer.

writer could be undefined (accessed via optional chaining elsewhere), but here it's passed directly to pipeTo() without a check. If writer is undefined, this will throw a runtime error.

-        // Pipe streaming partial output to the workflow writer so clients see progress
-        await stream.textStream.pipeTo(writer);
+        // Pipe streaming partial output to the workflow writer so clients see progress
+        if (writer) {
+          await stream.textStream.pipeTo(writer);
+        }

881-893: Same missing null check for writer before piping.

Consistent with the issue in analyzeDataStep, writer needs a null check before being passed to pipeTo().

-        // Pipe text deltas into the workflow writer to surface partial report progress to callers
-        await stream.textStream.pipeTo(writer);
+        // Pipe text deltas into the workflow writer to surface partial report progress to callers
+        if (writer) {
+          await stream.textStream.pipeTo(writer);
+        }

730-738: Remove the unsupported output parameter from agent.stream() call.

The output option is not supported by Mastra's agent.stream() method; this is documented in other workflows as an unsupported parameter. Use agent.generate() instead if structured output validation is needed, or parse the JSON response manually from stream.text without the cast.

src/mastra/workflows/content-studio-workflow.ts (1)

153-153: Remove extraneous double semicolons.

There are double semicolons (;;) at the end of several step definitions (lines 153, 209, 263, 332, 493, 563). While not causing runtime errors, they are unnecessary noise.

-});;
+});
src/mastra/workflows/document-processing-workflow.ts (1)

385-413: Avoid logging full document content in progress messages.

Lines 389 and 409 include inputData.content in progress messages. For large documents, this creates oversized payloads and may expose sensitive content:

      await writer?.custom({
        type: 'data-tool-progress',
        data: {
          status: 'in-progress',
-          message: `Processing text content ${startTime}, ${inputData.content}...`,
+          message: `Processing text content (${inputData.content.length} chars)...`,
          stage: 'pass-text-through',
        },
        id: 'pass-text-through',
      });
      await writer?.custom({
        type: 'data-tool-progress',
        data: {
          status: "done",
-          message: `Text passed through successfully ${inputData.content}`,
+          message: `Text passed through successfully (${inputData.content.length} chars)`,
          stage: 'pass-text-through',
        },
        id: 'pass-text-through',
      });
src/mastra/workflows/changelog.ts (2)

350-354: Bug: Incorrect error type casting.

The caught error e is an Error object (or unknown), but it's cast as string and returned directly. This will produce incorrect output like "[object Object]":

      return {
-        message: e as string,
+        message: e instanceof Error ? e.message : String(e),
      };

272-272: Address TODO: Hardcoded channelId.

Line 272 has a TODO for passing channelId through the workflow properly. Since stepA2 receives input from stepA1 which only outputs { message: string }, the channelId is lost. Consider:

  1. Extending stepA1's output schema to include channelId
  2. Or passing channelId through workflow context

Would you like me to generate a solution that threads channelId through the workflow?

src/mastra/workflows/content-review-workflow.ts (3)

132-139: Type safety bypassed with as any cast on stream output options.

The as any cast on line 139 bypasses TypeScript's type checking. This pattern appears multiple times in the file (lines 139, 273, 390, 413). If the Mastra agent stream method doesn't accept the output schema directly, consider creating a typed wrapper or documenting why this cast is necessary.


519-523: Inconsistent error handling: MAX_ITERATIONS exceeded does not emit progress event.

When the maximum iterations limit is exceeded, the error is thrown immediately without emitting a data-tool-progress event with status: 'done'. This is inconsistent with other error paths in the workflow that emit progress before re-throwing.

Apply this diff to maintain consistency:

     if (nextIteration > MAX_ITERATIONS) {
       const error = new Error(`Maximum iterations (${MAX_ITERATIONS}) exceeded. Final score: ${inputData.score}`);
       logError('refine-content', error, { iteration: nextIteration, score: inputData.score });
+      await writer?.custom({
+        type: 'data-tool-progress',
+        data: {
+          status: 'done',
+          message: `Error: Maximum iterations (${MAX_ITERATIONS}) exceeded. Final score: ${inputData.score}`,
+          stage: 'refine-content',
+        },
+        id: 'refine-content',
+      });
       throw error;
     }

699-757: Missing error handling in finalizeContentStep.

Unlike all other steps in this workflow, finalizeContentStep lacks a try-catch block. If any operation fails (e.g., writer?.custom throws), no error progress event will be emitted, breaking the consistent error handling pattern established across the workflow.

Consider wrapping the step logic in a try-catch block for consistency:

 execute: async ({ inputData, writer }) => {
   const startTime = Date.now();
   logStepStart('finalize-content', { topic: inputData.topic, finalScore: inputData.score });

+  try {
     await writer?.custom({
       // ... existing code
     });
     // ... rest of implementation
     return result;
+  } catch (error) {
+    logError('finalize-content', error, { topic: inputData.topic });
+    await writer?.custom({
+      type: 'data-tool-progress',
+      data: {
+        status: 'done',
+        message: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
+        stage: 'finalize-content',
+      },
+      id: 'finalize-content',
+    });
+    throw error;
+  }
 },
src/mastra/workflows/learning-extraction-workflow.ts (1)

696-708: Type safety concern with any typed agent response.

The response from agent.generate() is typed as any, and the subsequent type guards (lines 701-708) handle the runtime shape checking. Consider defining an expected response type or using Zod to parse the response for better type safety and documentation.

-        const response: any = await agent.generate(prompt);
+        const response = await agent.generate(prompt);
+        const parsed = z.object({
+          report: z.string().optional(),
+          summary: z.string().optional(),
+        }).safeParse(response);

-        // Guard against undefined or unexpected shapes.
-        if (response && typeof response === 'object') {
-          report = response.report ?? '';
-          summary = response.summary ?? '';
-        } else {
-          // Fallback: treat the raw response as the report.
-          report = String(response);
-          summary = '';
-        }
+        if (parsed.success) {
+          report = parsed.data.report ?? '';
+          summary = parsed.data.summary ?? '';
+        } else {
+          report = String(response);
+          summary = '';
+        }

Comment on lines +36 to +39
BRANCH=$(git branch --show-current) && \
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then \
echo "⚠️ Direct push to main/master is prohibited"; exit 1; \
fi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider handling edge cases in branch check.

The branch check doesn't handle detached HEAD state or empty branch names. While this is workflow documentation, adding error handling guidance would make it more robust.

BRANCH=$(git branch --show-current)
if [ -z "$BRANCH" ]; then
  echo "⚠️ Not on a branch (detached HEAD?)"; exit 1;
fi
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
  echo "⚠️ Direct push to main/master is prohibited"; exit 1;
fi
🤖 Prompt for AI Agents
.agent/workflows/commit-push-pr.md around lines 36 to 39: the current branch
check doesn't handle detached HEAD or empty branch names; add an explicit check
immediately after reading BRANCH to test for empty string (indicating detached
HEAD or not on a branch) and exit with a clear warning, then proceed to the
existing main/master comparison; ensure the script returns non‑zero status on
both error cases and uses clear messages like "Not on a branch (detached HEAD?)"
and "Direct push to main/master is prohibited."

Comment on lines +1 to +6
---
name: 'SE: Product Manager'
description: 'Product management guidance for creating GitHub issues, aligning business value with user needs, and making data-driven product decisions'
infer: true
tools: ['vscode', 'execute', 'read', 'edit', 'search', 'web', 'lotus/*', 'mastrabeta/mastraBlog', 'mastrabeta/mastraChanges', 'mastrabeta/mastraDocs', 'mastrabeta/mastraExamples', 'mastrabeta/mastraMigration', 'multi_orchestrator/*', 'next-devtools/*', 's-ai/*', 'thoughtbox/*', 'docfork/*', 'agent', 'vscode.mermaid-chat-features/renderMermaidDiagram', 'updateUserPreferences', 'memory', 'malaksedarous.copilot-context-optimizer/askAboutFile', 'malaksedarous.copilot-context-optimizer/runAndExtract', 'malaksedarous.copilot-context-optimizer/askFollowUp', 'malaksedarous.copilot-context-optimizer/researchTopic', 'malaksedarous.copilot-context-optimizer/deepResearch', 'ms-python.python/getPythonEnvironmentInfo', 'ms-python.python/getPythonExecutableCommand', 'ms-python.python/installPythonPackage', 'ms-python.python/configurePythonEnvironment', 'ms-vscode.vscode-websearchforcopilot/websearch', 'todo']
---
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Tools list is comprehensive but verify necessity.

The tools list at line 5 includes ~30 integrations. While comprehensive, consider whether all tools are necessary for the product manager agent's core responsibilities, or if the list could be streamlined to reduce attack surface and configuration complexity.

🤖 Prompt for AI Agents
.github/agents/se-product-manager-advisor.agent.md lines 1-6: the agent's tools
list is overly broad (≈30 entries) which increases attack surface and config
complexity; review each tool and remove non-essential integrations for core
product-manager responsibilities (e.g., low-value or unrelated repos, heavy
external exec tools), group or document remaining tools by purpose, and keep
only minimal required permissions; update the file to a trimmed list and add a
short comment explaining why each retained tool is needed.

Comment on lines +8 to +187
# Product Manager Advisor

Build the Right Thing. No feature without clear user need. No GitHub issue without business context.

## Your Mission

Ensure every feature addresses a real user need with measurable success criteria. Create comprehensive GitHub issues that capture both technical implementation and business value.

## Step 1: Question-First (Never Assume Requirements)

**When someone asks for a feature, ALWAYS ask:**

1. **Who's the user?** (Be specific)
"Tell me about the person who will use this:
- What's their role? (developer, manager, end customer?)
- What's their skill level? (beginner, expert?)
- How often will they use it? (daily, monthly?)"

2. **What problem are they solving?**
"Can you give me an example:
- What do they currently do? (their exact workflow)
- Where does it break down? (specific pain point)
- How much time/money does this cost them?"

3. **How do we measure success?**
"What does success look like:
- How will we know it's working? (specific metric)
- What's the target? (50% faster, 90% of users, $X savings?)
- When do we need to see results? (timeline)"

## Step 2: Create Actionable GitHub Issues

**CRITICAL**: Every code change MUST have a GitHub issue. No exceptions.

### Issue Size Guidelines (MANDATORY)
- **Small** (1-3 days): Label `size: small` - Single component, clear scope
- **Medium** (4-7 days): Label `size: medium` - Multiple changes, some complexity
- **Large** (8+ days): Label `epic` + `size: large` - Create Epic with sub-issues

**Rule**: If >1 week of work, create Epic and break into sub-issues.

### Required Labels (MANDATORY - Every Issue Needs 3 Minimum)
1. **Component**: `frontend`, `backend`, `ai-services`, `infrastructure`, `documentation`
2. **Size**: `size: small`, `size: medium`, `size: large`, or `epic`
3. **Phase**: `phase-1-mvp`, `phase-2-enhanced`, etc.

**Optional but Recommended:**
- Priority: `priority: high/medium/low`
- Type: `bug`, `enhancement`, `good first issue`
- Team: `team: frontend`, `team: backend`

### Complete Issue Template
```markdown
## Overview
[1-2 sentence description - what is being built]

## User Story
As a [specific user from step 1]
I want [specific capability]
So that [measurable outcome from step 3]

## Context
- Why is this needed? [business driver]
- Current workflow: [how they do it now]
- Pain point: [specific problem - with data if available]
- Success metric: [how we measure - specific number/percentage]
- Reference: [link to product docs/ADRs if applicable]

## Acceptance Criteria
- [ ] User can [specific testable action]
- [ ] System responds [specific behavior with expected outcome]
- [ ] Success = [specific measurement with target]
- [ ] Error case: [how system handles failure]

## Technical Requirements
- Technology/framework: [specific tech stack]
- Performance: [response time, load requirements]
- Security: [authentication, data protection needs]
- Accessibility: [WCAG 2.1 AA compliance, screen reader support]

## Definition of Done
- [ ] Code implemented and follows project conventions
- [ ] Unit tests written with ≥85% coverage
- [ ] Integration tests pass
- [ ] Documentation updated (README, API docs, inline comments)
- [ ] Code reviewed and approved by 1+ reviewer
- [ ] All acceptance criteria met and verified
- [ ] PR merged to main branch

## Dependencies
- Blocked by: #XX [issue that must be completed first]
- Blocks: #YY [issues waiting on this one]
- Related to: #ZZ [connected issues]

## Estimated Effort
[X days] - Based on complexity analysis

## Related Documentation
- Product spec: [link to docs/product/]
- ADR: [link to docs/decisions/ if architectural decision]
- Design: [link to Figma/design docs]
- Backend API: [link to API endpoint documentation]
```

### Epic Structure (For Large Features >1 Week)
```markdown
Issue Title: [EPIC] Feature Name

Labels: epic, size: large, [component], [phase]

## Overview
[High-level feature description - 2-3 sentences]

## Business Value
- User impact: [how many users, what improvement]
- Revenue impact: [conversion, retention, cost savings]
- Strategic alignment: [company goals this supports]

## Sub-Issues
- [ ] #XX - [Sub-task 1 name] (Est: 3 days) (Owner: @username)
- [ ] #YY - [Sub-task 2 name] (Est: 2 days) (Owner: @username)
- [ ] #ZZ - [Sub-task 3 name] (Est: 4 days) (Owner: @username)

## Progress Tracking
- **Total sub-issues**: 3
- **Completed**: 0 (0%)
- **In Progress**: 0
- **Not Started**: 3

## Dependencies
[List any external dependencies or blockers]

## Definition of Done
- [ ] All sub-issues completed and merged
- [ ] Integration testing passed across all sub-features
- [ ] End-to-end user flow tested
- [ ] Performance benchmarks met
- [ ] Documentation complete (user guide + technical docs)
- [ ] Stakeholder demo completed and approved

## Success Metrics
- [Specific KPI 1]: Target X%, measured via [tool/method]
- [Specific KPI 2]: Target Y units, measured via [tool/method]
```

## Step 3: Prioritization (When Multiple Requests)

Ask these questions to help prioritize:

**Impact vs Effort:**
- "How many users does this affect?" (impact)
- "How complex is this to build?" (effort)

**Business Alignment:**
- "Does this help us [achieve business goal]?"
- "What happens if we don't build this?" (urgency)

## Document Creation & Management

### For Every Feature Request, CREATE:

1. **Product Requirements Document** - Save to `docs/product/[feature-name]-requirements.md`
2. **GitHub Issues** - Using template above
3. **User Journey Map** - Save to `docs/product/[feature-name]-journey.md`

## Product Discovery & Validation

### Hypothesis-Driven Development
1. **Hypothesis Formation**: What we believe and why
2. **Experiment Design**: Minimal approach to test assumptions
3. **Success Criteria**: Specific metrics that prove or disprove hypotheses
4. **Learning Integration**: How insights will influence product decisions
5. **Iteration Planning**: How to build on learnings and pivot if necessary

## Escalate to Human When
- Business strategy unclear
- Budget decisions needed
- Conflicting requirements

Remember: Better to build one thing users love than five things they tolerate.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Document provides comprehensive product management guidance—well-structured and actionable.

This agent profile effectively documents a product manager workflow with clear steps (Question-First, Issue Creation, Prioritization) and detailed templates. The guidance balances user-centric thinking with business value and includes practical checklists for issue creation and epic management.

Optional enhancements for future iterations:

  1. Expand Prioritization Framework (lines 153-163): Consider adding RICE scoring, MoSCoW prioritization, or Kano modeling guidance alongside impact/effort.

  2. Add Escalation Guidance: The escalation criteria (lines 182-186) are brief. Consider expanding with examples:

    • Unclear technical feasibility
    • Conflicting user needs
    • Performance/security implications requiring specialist review
  3. Document Technical Constraints: Add a template section for documenting technical constraints, backward compatibility, and migration paths for breaking changes.

  4. Experimentation & Validation: Expand the Product Discovery section (lines 173-181) with A/B testing, analytics integration, and success measurement tooling.

These are nice-to-have enhancements; the current structure is solid and immediately usable.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

60-60: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


113-113: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

Comment on lines +59 to +61
### Complete Issue Template
```markdown
## Overview
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add blank line before first fenced code block.

Markdown linting rule MD031 requires blank lines surrounding fenced code blocks. Add a blank line before the code block.

 **Rule**: If >1 week of work, create Epic and break into sub-issues.
 
+
 ### Complete Issue Template
 ```markdown

As per markdownlint-cli2 rules...

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

60-60: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
In .github/agents/se-product-manager-advisor.agent.md around lines 59-61, the
first fenced code block lacks a blank line before the opening ``` which violates
MD031; insert a single blank line immediately before the ``` that begins the
code block (so there is an empty line between the heading/preceding text and the
fenced code block) and ensure no extra blank lines are added.

Comment on lines +112 to +114
### Epic Structure (For Large Features >1 Week)
```markdown
Issue Title: [EPIC] Feature Name
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add blank line before second fenced code block.

Markdown linting rule MD031 requires blank lines surrounding fenced code blocks. Add a blank line before this code block.

 Ask these questions to help prioritize:
 
+
 **Impact vs Effort:**
 - "How many users does this affect?" (impact)
 - "How complex is this to build?" (effort)
 
 **Business Alignment:**
 - "Does this help us [achieve business goal]?"
 - "What happens if we don't build this?" (urgency)
 
 ## Document Creation & Management
 
 ### For Every Feature Request, CREATE:
 
 1. **Product Requirements Document** - Save to `docs/product/[feature-name]-requirements.md`
 2. **GitHub Issues** - Using template above
 3. **User Journey Map** - Save to `docs/product/[feature-name]-journey.md`
 
 ## Product Discovery & Validation
 
 ### Hypothesis-Driven Development
 1. **Hypothesis Formation**: What we believe and why
 2. **Experiment Design**: Minimal approach to test assumptions
 3. **Success Criteria**: Specific metrics that prove or disprove hypotheses
 4. **Learning Integration**: How insights will influence product decisions
 5. **Iteration Planning**: How to build on learnings and pivot if necessary
 
 ## Escalate to Human When
 - Business strategy unclear
 - Budget decisions needed
 - Conflicting requirements
 
 Remember: Better to build one thing users love than five things they tolerate.

Looking at the correct location for the second violation at lines 112-114:

 [List any external dependencies or blockers]
 
 ## Definition of Done
-```markdown
+
+```markdown

As per markdownlint-cli2 rules...

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

113-113: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
.github/agents/se-product-manager-advisor.agent.md around lines 112-114: the
fenced code block starting at line 114 lacks a blank line before it which
violates markdownlint MD031; insert a single blank line immediately before the
opening ```markdown fence (i.e., add an empty line at line 113) so the code
block is surrounded by blank lines and the lint rule is satisfied.

Comment on lines +5 to +8
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add TSDoc documentation for this public hook.

As per coding guidelines, public APIs should include TSDoc comments with parameter descriptions, return types, and usage context.

+/**
+ * Detects whether the current viewport is mobile-sized.
+ * 
+ * @returns `true` if viewport width is below 768px, `false` otherwise.
+ *          Returns `false` during SSR and initial render before hydration.
+ */
 export function useIsMobile() {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
/**
* Detects whether the current viewport is mobile-sized.
*
* @returns `true` if viewport width is below 768px, `false` otherwise.
* Returns `false` during SSR and initial render before hydration.
*/
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
🤖 Prompt for AI Agents
In lib/hooks/use-mobile.ts around lines 5 to 8, the public hook useIsMobile
lacks TSDoc comments; add a TSDoc block above the function describing the hook's
purpose, any parameters (none), the return type (React state boolean |
undefined), behavior (when undefined vs true/false), and a short usage example
or notes about SSR/client-only usage to satisfy public API docs requirements.

Comment on lines +10 to +18
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener("change", onChange);
}, []);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider using mql.matches for consistency.

The media query already defines the breakpoint logic. Using mql.matches directly would be more consistent and avoid duplicating the comparison logic.

 React.useEffect(() => {
   const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
   const onChange = () => {
-    setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
+    setIsMobile(mql.matches);
   };
   mql.addEventListener("change", onChange);
-  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
+  setIsMobile(mql.matches);
   return () => mql.removeEventListener("change", onChange);
 }, []);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener("change", onChange);
}, []);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(mql.matches);
};
mql.addEventListener("change", onChange);
setIsMobile(mql.matches);
return () => mql.removeEventListener("change", onChange);
}, []);
🤖 Prompt for AI Agents
In lib/hooks/use-mobile.ts around lines 10 to 18, the code duplicates breakpoint
logic by comparing window.innerWidth to MOBILE_BREAKPOINT; replace those
comparisons by using the MediaQueryList result instead: create the mql, set
initial state with setIsMobile(mql.matches), and change the listener to use the
event's matches (e.g., onChange = (e) => setIsMobile(e.matches)) or read
mql.matches inside the handler; keep the same
addEventListener/removeEventListener setup and cleanup.

message: `Processing express order ${inputData.orderId}...`,
stage: "express-processing",
},
id: "express-processing",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Inconsistent id property usage in progress events.

The id property is added here for the express-processing stage, but most other writer.custom() calls throughout the file (lines 164-180, 224-253, 297-338) omit this property. Only line 198 in the validation error handler includes an id. This inconsistency makes it unclear when the id field is required or beneficial.

Consider either:

  1. Adding id properties consistently to all progress events for better traceability
  2. Documenting when id should be included vs. omitted
  3. Removing the id property if it's optional and not serving a clear purpose

If you intended to add id for tracking purposes, apply this pattern consistently:

     await writer?.custom({
       type: "data-tool-progress",
       data: {
         status: "in-progress",
         message: `Processing standard order ${inputData.orderId}...`,
         stage: "standard-processing",
       },
+      id: "standard-processing",
     });

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/mastra/workflows/AGENTS.md around line 304, the express-processing
progress event includes an id property while most other writer.custom() progress
events in this file omit it, creating inconsistency; decide on a single approach
and apply it consistently: either add an id property to all progress events
(e.g., same naming pattern and unique values per stage) to improve traceability,
or remove the id from express-processing and any lone occurrences (like line
198) if it's optional; update the file so every writer.custom() progress event
follows the chosen convention and, if choosing to keep ids, ensure they are
unique and documented in a short comment near the top of the section.

data: {
status: 'in-progress',
message: 'Generating research report...',
message: `Generating research report for ${inputData.synthesis.overallSummary.length} topics...`,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Incorrect topic count in progress message.

Line 427 uses inputData.synthesis.overallSummary.length, which returns the character length of the summary string, not the number of topics. This will display misleading information like "Generating research report for 500 topics..." when the summary is 500 characters long.

Apply this diff to use the correct property:

-          message: `Generating research report for ${inputData.synthesis.overallSummary.length} topics...`,
+          message: `Generating research report for ${inputData.metadata.topicsCount} topics...`,

Note: Line 510 correctly uses inputData.metadata.topicsCount, so this change aligns with the existing pattern.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
message: `Generating research report for ${inputData.synthesis.overallSummary.length} topics...`,
message: `Generating research report for ${inputData.metadata.topicsCount} topics...`,
🤖 Prompt for AI Agents
In src/mastra/workflows/research-synthesis-workflow.ts around line 427, the
progress message uses inputData.synthesis.overallSummary.length (string length)
which is incorrect; change the message to use inputData.metadata.topicsCount to
show the actual number of topics, and guard/format it as a number (e.g., default
to 0 or validate presence) so the log reads "Generating research report for X
topics..." with the correct count.

Comment on lines +75 to +78
"node_modules/**/*.ts",
"node_modules/**/*.tsx",
"node_modules/**/*.d.ts",
"/node_modules/**/*.tsx",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Redundant exclude patterns for node_modules.

Lines 75-78 add granular exclusions for TypeScript files within node_modules, but line 74 already excludes "node_modules" entirely. TypeScript's exclude patterns are recursive by default, so the general node_modules exclusion already covers all .ts, .tsx, and .d.ts files within it.

Additionally, line 78 ("/node_modules/**/*.tsx") duplicates coverage from line 76 ("node_modules/**/*.tsx").

Consider removing the redundant patterns:

   "exclude": [
     "node_modules",
-    "node_modules/**/*.ts",
-    "node_modules/**/*.tsx",
-    "node_modules/**/*.d.ts",
-    "/node_modules/**/*.tsx",
     "/node_modules",

If you have a specific reason for these granular exclusions (e.g., working around a TypeScript bug or tooling issue), please document it in a comment.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"node_modules/**/*.ts",
"node_modules/**/*.tsx",
"node_modules/**/*.d.ts",
"/node_modules/**/*.tsx",
"exclude": [
"node_modules",
"/node_modules"
]
🤖 Prompt for AI Agents
In tsconfig.json around lines 75 to 78, the granular exclude patterns for files
inside node_modules are redundant because line 74 already excludes
"node_modules" recursively; remove the four specific patterns
("node_modules/**/*.ts", "node_modules/**/*.tsx", "node_modules/**/*.d.ts",
"/node_modules/**/*.tsx") and keep the single "node_modules" exclusion, or if
there is a specific tooling/TS bug reason to keep them, add a short inline
comment explaining the rationale.

@greptile-apps
Copy link

greptile-apps bot commented Dec 15, 2025

Greptile Overview

Greptile Summary

This PR introduces comprehensive audio transcription functionality and agent memory management hooks to the Mastra framework. The primary change is a new audio transcription endpoint (app/api/audio/route.ts) that processes uploaded audio files using a dedicated note-taking agent with Google Voice capabilities. The PR adds 6 React hooks for managing agent interactions, threads, and memory states, following TanStack Query patterns for consistent data fetching and caching. Additionally, the PR includes extensive governance documentation updates, workflow progress message standardization across 15+ workflow files, and agent configuration improvements with batch processing optimizations.

The changes integrate seamlessly with the existing Mastra architecture by leveraging the established agent pattern, maintaining consistent API conventions, and following the framework's multi-agent coordination approach. The governance updates in .agent/ and .windsurf/ directories establish standardized development workflows, security protocols, and documentation standards.

Important Files Changed

Filename Score Overview
app/api/audio/route.ts 3/5 New audio transcription endpoint using Mastra note-taking agent - needs better error handling
src/mastra/agents/noteTakerAgent.ts 2/5 New note-taking agent with Google Voice - critical issue with truncated instructions
lib/hooks/use-agent-messages.ts 4/5 React hook for fetching agent messages with aggressive cache policies
lib/hooks/use-agent.ts 5/5 React hook for retrieving agent details with proper query management
lib/hooks/use-delete-thread.ts 4/5 React hook for deleting memory threads - minor cache invalidation issue
lib/hooks/use-memory.ts 5/5 React hook for checking agent memory status with clean implementation
lib/hooks/use-mobile.ts 3/5 Mobile detection hook with potential SSR hydration issues
lib/hooks/use-threads.ts 4/5 React hook for listing memory threads with conditional fetching
src/mastra/index.ts 5/5 Added noteTakerAgent to main configuration and cleaned up imports
src/mastra/workflows/telephone-game.ts 5/5 Refactored from CLI interactive to web-compatible streaming workflow
src/mastra/workflows/spec-generation-workflow.ts 2/5 Added progress reporting but has stream handling issues
app/workflows/providers/workflow-context.tsx 4/5 Fixed React cascading render warnings with deferred state updates
app/chat/providers/chat-context.tsx 4/5 Performance optimizations using useMemo instead of useEffect patterns
app/networks/providers/network-context.tsx 4/5 Refactored state management from useState to computed/memoized values
package.json 4/5 Added @mastra/react dependency and moved ESLint plugins to devDependencies

Confidence score: 3/5

  • This PR requires careful review due to several implementation issues in core functionality files
  • Score lowered due to truncated agent instructions, potential stream handling bugs, SSR hydration risks, and missing error handling in the audio API
  • Pay close attention to the noteTakerAgent implementation, audio route error handling, and mobile hook SSR compatibility

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

68 files reviewed, 25 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +20 to +21
staleTime: 0,
gcTime: 0,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Setting staleTime: 0 and gcTime: 0 means data is always considered stale and never cached, which may cause excessive API calls. Are frequent API calls expected here, or should there be some caching strategy for better performance?

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/hooks/use-agent-messages.ts
Line: 20:21

Comment:
**style:** Setting `staleTime: 0` and `gcTime: 0` means data is always considered stale and never cached, which may cause excessive API calls. Are frequent API calls expected here, or should there be some caching strategy for better performance?

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +17 to +18
queryFn: () =>
threadId ? client.listThreadMessages(threadId, { agentId }) : null,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The queryFn returns null when threadId is falsy, but this might cause React Query to treat this as a successful response with null data

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/hooks/use-agent-messages.ts
Line: 17:18

Comment:
**logic:** The `queryFn` returns `null` when `threadId` is falsy, but this might cause React Query to treat this as a successful response with null data

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +23 to +24
staleTime: 0,
gcTime: 0,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Setting both staleTime: 0 and gcTime: 0 makes data immediately stale and removes it from cache right after use. This might cause excessive API calls. Are you intentionally preventing any caching for memory threads, or should these values be higher to improve performance?

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/hooks/use-threads.ts
Line: 23:24

Comment:
**style:** Setting both `staleTime: 0` and `gcTime: 0` makes data immediately stale and removes it from cache right after use. This might cause excessive API calls. Are you intentionally preventing any caching for memory threads, or should these values be higher to improve performance?

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +75 to +78
"node_modules/**/*.ts",
"node_modules/**/*.tsx",
"node_modules/**/*.d.ts",
"/node_modules/**/*.tsx",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Redundant exclusion patterns since node_modules on line 74 already excludes all files in node_modules directory

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: tsconfig.json
Line: 75:78

Comment:
**style:** Redundant exclusion patterns since `node_modules` on line 74 already excludes all files in node_modules directory

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +42 to +44
[byterover-mcp]

[byterover-mcp]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Duplicate section header - remove one of these identical [byterover-mcp] lines

Suggested change
[byterover-mcp]
[byterover-mcp]
[byterover-mcp]
You are given two tools from Byterover MCP server, including

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/copilot-instructions.md
Line: 42:44

Comment:
**style:** Duplicate section header - remove one of these identical `[byterover-mcp]` lines

```suggestion
[byterover-mcp]

You are given two tools from Byterover MCP server, including
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +15 to +16
mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Redundant window.innerWidth check when MediaQueryList.matches property could be used instead

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/hooks/use-mobile.ts
Line: 15:16

Comment:
**style:** Redundant window.innerWidth check when MediaQueryList.matches property could be used instead

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +1 to +103
# Windsurf / Antigravity Rules "v5"

🇬🇧 English Documentation

[🌏 Back to Top](../README.md) | [🇯🇵 日本語](../ja/README.md)

This repository manages custom instructions for Windsurf and Antigravity.

> **Note**: For the Cursor version, see the separate repository [kinopeee/cursorrules](https://github.com/kinopeee/cursorrules).

## Premise

- This `v5` is a set of custom instructions optimized for Windsurf and Antigravity.
- For the agent to operate autonomously (without human intervention), each editor's settings must be configured appropriately.
- See the [changelog](CHANGELOG.md) for the latest updates.

## Overview

- After the release of AI agent features, I noticed a recurring issue: insufficient analytical rigor. I began crafting custom instructions to better draw out the model's inherent analytical ability (originally Claude 3.5 Sonnet at the time).
- The early themes were improving analytical capability and autonomous execution. Later iterations also targeted preventing duplicate module/resource generation, unintended design changes by the AI, and infinite loops in error handling. These efforts, combined with model refreshes and performance gains, have produced reasonable results.
- The focus of this version upgrade is GPT-5.1 optimization:
1. We create a checklist-style execution plan first, then verify completion item-by-item for a more disciplined process.
1. Tasks are classified into Lightweight, Standard, and Critical levels, with simplified reporting for lightweight tasks and more thorough processes for heavier ones.
1. Independent tasks are executed in parallel to improve throughput.
- In addition, this version codifies detailed tooling policies (e.g., always read files before editing, use appropriate edit tools for modifications, and run terminal commands only when necessary with safe flags) so the agent executes tasks with consistent safeguards.
- `v5` was initially created with Anthropic Prompt Generator and has since gone through cycles of evaluation by contemporary models and practical improvements. When customizing, we recommend having your chosen AI evaluate it as well.
- For detailed updates, including task classification, error handling tiers, and tooling policies, see [CHANGELOG.md](CHANGELOG.md).

- This repository itself also serves as a best-practice example, providing rule files for commit/PR messages and workflow command templates for commit, push, and PR creation.

## Usage

### Windsurf

1. If `.windsurf/rules` does not exist yet, create the folder.
2. Copy the required rule files from `ja/.windsurf/rules/` or `en/.windsurf/rules/`.
3. To use workflows, copy them to `.windsurf/workflows/`.

### Antigravity

1. If `.agent/rules` does not exist yet, create the folder.
2. Copy the required rule files from `ja/.agent/rules/` or `en/.agent/rules/`.
3. To use workflows, copy them to `.agent/workflows/`.

### Common Notes

- Because their application condition is `trigger: always_on`, they will be referenced in subsequent chats as long as they exist at the designated path.
- You may want to adjust this setting based on your preferred language and whether you want the test rules enabled by default.

For the division of responsibilities and usage patterns between rule files and workflows, see [doc/rules-and-workflows.md](doc/rules-and-workflows.md).

### Guardrail-related files

The following files are available for both Windsurf (`.windsurf/rules/`) and Antigravity (`.agent/rules/`).

- `commit-message-format.md`
- **Role**: Defines the commit message format (prefix, summary, bullet-list body) and prohibited patterns.
- **Characteristics**: Based on Conventional Commits, with additional guidelines such as `language`-based language selection and diff-based message generation.

- `pr-message-format.md`
- **Role**: Defines the format for PR titles and bodies (prefix-style titles and structured sections such as Overview, Changes, Tests) and prohibited patterns.
- **Characteristics**: Aligns PR messages with the commit message conventions and encourages structured descriptions that facilitate review and understanding of change intent.

- `test-strategy.md`
- **Role**: Defines test strategy rules for test implementation and maintenance, including equivalence partitioning, boundary value analysis, and coverage requirements.
- **Purpose**: Serves as a quality guardrail by requiring corresponding automated tests whenever meaningful changes are made to production code, where reasonably feasible.

- `prompt-injection-guard.md`
- **Role**: Defines defense rules against **context injection attacks from external sources (RAG, web, files, API responses, etc.)**.
- **Contents**: Describes guardrails such as restrictions on executing commands originating from external data, the Instruction Quarantine mechanism, the `SECURITY_ALERT` format, and detection of user impersonation attempts.
- **Characteristics**: Does not restrict the user's own direct instructions; only malicious commands injected via external sources are neutralized.
- **Note**: This file has `trigger: always_on` set in its metadata, but users can still control when these rules are applied via the editor's UI settings. See the [operational guide](doc/prompt-injection-guard.md) for details on handling false positives.

- `planning-mode-guard.md` **(Antigravity only)**
- **Role**: A guardrail to prevent problematic behaviors in Antigravity's Planning Mode.
- **Issues addressed**:
- Transitioning to the implementation phase without user instruction
- Responding in English even when instructed in another language (e.g., Japanese)
- **Contents**: In Planning Mode, only analysis and planning are performed; file modifications and command execution are prevented without explicit user approval. Also encourages responses in the user's preferred language.
- **Characteristics**: Placed only in `.agent/rules/`; not used in Windsurf.

- `doc/custom_instruction_plan_prompt_injection.md`
- **Role**: Design and threat analysis document for external context injection defense.
- **Contents**: Organizes attack categories (A-01–A-09) via external sources, corresponding defense requirements (R-01–R-08), design principles for the external data control layer, and validation/operations planning.
- **Update**: Fully revised in November 2024 to focus on external-source attacks.


## Translation Guide

For the recommended prompt to translate custom instructions into other languages, see [TRANSLATION_GUIDE.md](../TRANSLATION_GUIDE.md).

## Notes

- If there are instructions in User Rules or Memories that conflict with v5, the model may become confused and effectiveness may decrease. Please check the contents carefully.

## License

Released under the MIT License. See [LICENSE](../LICENSE) for details.

## Support

- There is no official support for this repository, but feedback is welcome. I also share Cursor-related information on X (Twitter).
[Follow on X (Twitter)](https://x.com/kinopee_ai)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: This file appears to be copied from an external project and may conflict with existing .agent governance. The RAG sources indicate .agent should contain 'governance, conventions, and reference material' for Mastra/AgentStack, but this introduces Windsurf/Antigravity editor rules.

Context Used: Context from dashboard - AGENTS.md (source). Is this intended to replace or supplement the existing .agent/rules/ structure described in the project documentation?

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: .agent/README.md
Line: 1:103

Comment:
**style:** This file appears to be copied from an external project and may conflict with existing `.agent` governance. The RAG sources indicate `.agent` should contain 'governance, conventions, and reference material' for Mastra/AgentStack, but this introduces Windsurf/Antigravity editor rules.

**Context Used:** Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=5cd64f16-a8ef-4638-a5c4-e8cee91a4609)). Is this intended to replace or supplement the existing `.agent/rules/` structure described in the project documentation?

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.


## Translation Guide

For the recommended prompt to translate custom instructions into other languages, see [TRANSLATION_GUIDE.md](../TRANSLATION_GUIDE.md).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: References ../TRANSLATION_GUIDE.md which doesn't exist in the AgentStack project structure.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .agent/README.md
Line: 90:90

Comment:
**logic:** References `../TRANSLATION_GUIDE.md` which doesn't exist in the AgentStack project structure.

How can I resolve this? If you propose a fix, please make it concise.


## License

Released under the MIT License. See [LICENSE](../LICENSE) for details.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: References ../LICENSE which may not correspond to AgentStack's license structure.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .agent/README.md
Line: 98:98

Comment:
**logic:** References `../LICENSE` which may not correspond to AgentStack's license structure.

How can I resolve this? If you propose a fix, please make it concise.

1. **MOST IMPORTANT**: **ALWAYS USE** **byterover-retrieve-knowledge** once or several times for **EACH TASK** of the plan to gather necessary context for complete that task.
2. **MOST IMPORTANT**: **ALWAYS USE** **byterover-store-knowledge** once or several times to store critical knowledge and context for future implementations
3. Over 15 provided tools, **byterover-retrieve-knowledge** and **byterover-store-knowledge** ARE the two main tools, which **MUST** be used regularly. You can use these two main tools outside the two main workflows for retrieval and storage purposes.
4. You **MUST** include phrases like **"According to Byterover memory layer"**, **"Based on memory extracted from Byterover"**, **"From Byterover memomry tools"**, ... to explictly showcase that these sources are from **Byterover**.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: Typo in 'memomry' should be 'memory'

Suggested change
4. You **MUST** include phrases like **"According to Byterover memory layer"**, **"Based on memory extracted from Byterover"**, **"From Byterover memomry tools"**, ... to explictly showcase that these sources are from **Byterover**.
4. You **MUST** include phrases like **"According to Byterover memory layer"**, **"Based on memory extracted from Byterover"**, **"From Byterover memory tools"**, ... to explictly showcase that these sources are from **Byterover**.
Prompt To Fix With AI
This is a comment left during a code review.
Path: AGENTS.md
Line: 40:40

Comment:
**syntax:** Typo in 'memomry' should be 'memory'

```suggestion
4. You **MUST** include phrases like **"According to Byterover memory layer"**, **"Based on memory extracted from Byterover"**, **"From Byterover memory tools"**, ... to explictly showcase that these sources are from **Byterover**.
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment on lines +90 to +175
## Relationship between Rules and Workflows

### Commit and PR Workflows

```mermaid
flowchart TB
WLabel[Workflows<br/>workflows/*.md]

subgraph Workflow[" "]
direction LR
W1[commit-only]
W2[commit-push]
W3[commit-push-pr]
end

subgraph Rules[" "]
direction TB
R1[commit-message-format]
R2[pr-message-format]
space[ ]
V5[v5: Coding Foundation Rules]
end

RLabel[Rules<br/>rules/*.md]

WLabel ~~~ Workflow
Workflow ~~~ Rules
Rules ~~~ RLabel

W1 -->|refs| R1
W2 -->|refs| R1
W3 -->|refs| R1
W3 -->|refs| R2

R1 -.->|complies| V5
R2 -.->|complies| V5

style Workflow fill:#e8e8f4,stroke:#44a
style Rules fill:#e8f4e8,stroke:#4a4
style WLabel fill:none,stroke:none
style RLabel fill:none,stroke:none
style space fill:none,stroke:none

linkStyle 0 stroke:none
linkStyle 1 stroke:none
linkStyle 2 stroke:none
```

### Test Strategy

```mermaid
flowchart TB
subgraph TestWork[" "]
direction LR
T1[Test Design]
T2[Test Implementation]
T3[Coverage Verification]
end

subgraph TestRules[" "]
direction TB
TR1[test-strategy]
space2[ ]
V5T[v5: Coding Foundation Rules]
end

RLabelT[Rules<br/>rules/*.md]

TestWork ~~~ TestRules
TestRules ~~~ RLabelT

T1 -->|refs| TR1
T2 -->|refs| TR1
T3 -->|refs| TR1

TR1 -.->|complies| V5T

style TestWork fill:#e8e8f4,stroke:#44a
style TestRules fill:#e8f4e8,stroke:#4a4
style RLabelT fill:none,stroke:none
style space2 fill:none,stroke:none

linkStyle 0 stroke:none
linkStyle 1 stroke:none
```

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Ensure all fenced code blocks declare a language

The documentation and diagrams are clear, and the mermaid examples are helpful. markdownlint has flagged missing fenced-code languages (MD040), so it’s worth double‑checking that every ``` block in this file specifies a language (e.g., mermaid, `bash`, `text`) to keep lint clean and improve editor tooling.

🤖 Prompt for AI Agents
.agent/doc/rules-and-workflows.md around lines 90 to 175: the fenced code blocks
for the two mermaid diagrams are missing language identifiers which triggers
MD040; update each triple-backtick fence to specify the language (e.g.,
```mermaid) so both diagram blocks declare their language and the markdown
linter/editor tooling recognize them.

Comment on lines +25 to +39
### 🛡️ Planning Mode (PLANNING)
**Purpose**: Formulating implementation plans, defining requirements, building consensus with users
- **✅ What to do**:
- Create and present implementation plans (`implementation_plan.md`) aligned with user requests
- Investigate and understand existing code
- **🚫 Strictly Prohibited**:
- **Implementing or editing production code** (use of `replace_file_content`, etc. is prohibited)
- Starting implementation before obtaining explicit user approval (instructions like "implement it")
- *Updating plan files themselves is permitted

### 🚀 Execution Mode (Fast / Agent / EXECUTION)
**Purpose**: Task execution, coding
- **✅ What to do**:
- Execute tasks instructed by the user promptly based on approved plans

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider explicitly listing allowed edit operations in Execution mode

Planning mode correctly prohibits using replace_file_content and similar tools for production edits. For symmetry and clarity, you might explicitly state in the Execution Mode section that such editing tools are permitted there (subject to approved plans), so agents have an unambiguous signal about when code changes are allowed.

🤖 Prompt for AI Agents
.agent/rules/planning-mode-guard.md lines 25-39: the Execution Mode section
lacks an explicit list of allowed edit operations, causing ambiguity about when
file-editing tools are permitted; update the Execution Mode text to explicitly
permit specific editing operations (e.g., replace_file_content, create_file,
update_file, delete_file, apply_patch) when acting under approved plans, and add
a short guard that these operations require prior explicit user or plan approval
and must be limited to the scope of the approved plan.

Comment on lines +83 to +85
- **Parallel Execution**:
- Actively execute **read-type** operations like `view_file` / `grep_search` / `codebase_search` / `search_web` in parallel when there are no dependencies.
- Do not execute `replace_file_content` or state-changing commands in parallel.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Optional: Replace slashes with “and” for readability

The list “view_file / grep_search / codebase_search / search_web” is clear but slightly less readable than a conjunction-based list. Consider “view_file, grep_search, codebase_search, and search_web” for smoother reading.

🧰 Tools
🪛 LanguageTool

[style] ~84-~84: For improved clarity, try using the conjunction “and” instead of a slash.
Context: ...le/grep_search/codebase_search/search_web` in parallel when there are...

(QB_NEW_EN_SLASH_TO_AND)

🤖 Prompt for AI Agents
In .agent/rules/v5.md around lines 83 to 85, replace the slash-separated list
"view_file / grep_search / codebase_search / search_web" with a
conjunction-based list for readability; change it to "view_file, grep_search,
codebase_search, and search_web" while keeping the surrounding sentence and
emphasis intact.

## Step 2: Common Failure Patterns & Solutions

### **Build Failures**
```json
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add blank lines around fenced code blocks for proper Markdown formatting.

Multiple fenced code blocks throughout the document are not surrounded by blank lines, violating Markdown best practices (MD031). This affects readability and may cause rendering issues in some Markdown processors.

Add a blank line before and after each fenced code block. For example:

 ### **Build Failures**
+
 ```json
 // Problem: Dependency version conflicts
 ...

This issue occurs at lines 41, 54, 68, 84, 96, 109, 123, 134, 141, 150, 174, 200, and 237.


Also applies to: 54-54, 68-68, 84-84, 96-96, 109-109, 123-123, 134-134, 141-141, 150-150, 174-174, 200-200, 237-237

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

41-41: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

.github/agents/se-gitops-ci-specialist.agent.md around lines
41,54,68,84,96,109,123,134,141,150,174,200,237: several fenced code blocks lack
an empty line before and/or after the triple-backtick delimiters; add a single
blank line immediately above the opening ``` and immediately below the closing

line on both sides to comply with MD031 and improve rendering/readability.

Comment on lines +60 to +245
### Technical Blog Posts
```markdown
# [Compelling Title That Promises Value]

[Hook - Problem or interesting observation]
[Stakes - Why this matters now]
[Promise - What reader will learn]

## The Challenge
[Specific problem with context]
[Why existing solutions fall short]

## The Approach
[High-level solution overview]
[Key insights that made it possible]

## Implementation Deep Dive
[Technical details with code examples]
[Decision points and tradeoffs]

## Results and Metrics
[Quantified improvements]
[Unexpected discoveries]

## Lessons Learned
[What worked well]
[What we'd do differently]

## Next Steps
[How readers can apply this]
[Resources for going deeper]
```

### Documentation
```markdown
# [Feature/Component Name]

## Overview
[What it does in one sentence]
[When to use it]
[When NOT to use it]

## Quick Start
[Minimal working example]
[Most common use case]

## Core Concepts
[Essential understanding needed]
[Mental model for how it works]

## API Reference
[Complete interface documentation]
[Parameter descriptions]
[Return values]

## Examples
[Common patterns]
[Advanced usage]
[Integration scenarios]

## Troubleshooting
[Common errors and solutions]
[Debug strategies]
[Performance tips]
```

### Tutorials
```markdown
# Learn [Skill] by Building [Project]

## What We're Building
[Visual/description of end result]
[Skills you'll learn]
[Prerequisites]

## Step 1: [First Tangible Progress]
[Why this step matters]
[Code/commands]
[Verify it works]

## Step 2: [Build on Previous]
[Connect to previous step]
[New concept introduction]
[Hands-on exercise]

[Continue steps...]

## Going Further
[Variations to try]
[Additional challenges]
[Related topics to explore]
```

### Architecture Decision Records (ADRs)
Follow the [Michael Nygard ADR format](https://github.com/joelparkerhenderson/architecture-decision-record):

```markdown
# ADR-[Number]: [Short Title of Decision]

**Status**: [Proposed | Accepted | Deprecated | Superseded by ADR-XXX]
**Date**: YYYY-MM-DD
**Deciders**: [List key people involved]

## Context
[What forces are at play? Technical, organizational, political? What needs must be met?]

## Decision
[What's the change we're proposing/have agreed to?]

## Consequences
**Positive:**
- [What becomes easier or better?]

**Negative:**
- [What becomes harder or worse?]
- [What tradeoffs are we accepting?]

**Neutral:**
- [What changes but is neither better nor worse?]

## Alternatives Considered
**Option 1**: [Brief description]
- Pros: [Why this could work]
- Cons: [Why we didn't choose it]

## References
- [Links to related docs, RFCs, benchmarks]
```

**ADR Best Practices:**
- One decision per ADR - keep focused
- Immutable once accepted - new context = new ADR
- Include metrics/data that informed the decision
- Reference: [ADR GitHub organization](https://adr.github.io/)

### User Guides
```markdown
# [Product/Feature] User Guide

## Overview
**What is [Product]?**: [One sentence explanation]
**Who is this for?**: [Target user personas]
**Time to complete**: [Estimated time for key workflows]

## Getting Started
### Prerequisites
- [System requirements]
- [Required accounts/access]
- [Knowledge assumed]

### First Steps
1. [Most critical setup step with why it matters]
2. [Second critical step]
3. [Verification: "You should see..."]

## Common Workflows

### [Primary Use Case 1]
**Goal**: [What user wants to accomplish]
**Steps**:
1. [Action with expected result]
2. [Next action]
3. [Verification checkpoint]

**Tips**:
- [Shortcut or best practice]
- [Common mistake to avoid]

### [Primary Use Case 2]
[Same structure as above]

## Troubleshooting
| Problem | Solution |
|---------|----------|
| [Common error message] | [How to fix with explanation] |
| [Feature not working] | [Check these 3 things...] |

## FAQs
**Q: [Most common question]?**
A: [Clear answer with link to deeper docs if needed]

## Additional Resources
- [Link to API docs/reference]
- [Link to video tutorials]
- [Community forum/support]
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix markdownlint issues around fenced code blocks

markdownlint (MD031) is flagging some fenced code blocks as not being surrounded by blank lines. To keep this file lint‑clean, ensure every trio of backticks has a blank line immediately before and after the fenced block, especially around the templates (Technical Blog Posts, Documentation, Tutorials, User Guides, etc.).

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

63-63: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


135-135: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


169-169: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
.github/agents/se-technical-writer.agent.md around lines 60 to 245: markdownlint
MD031 reports fenced code blocks missing surrounding blank lines; fix by
ensuring every ``` fenced block has an empty line immediately before the opening
``` and an empty line immediately after the closing ```, including around each
template section (Technical Blog Posts, Documentation, Tutorials, ADRs, User
Guides); scan the file for each trio of backticks and insert or remove
surrounding blank lines so there is exactly one blank line above and below each
fenced block to keep formatting consistent and lint‑clean.

Comment on lines 193 to +194
observability: new Observability({
// default: { enabled: false },
// default: { enabled: false },
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Remove commented-out code.

Per coding guidelines: "Avoid commenting out dead code. Use version control instead of maintaining commented code blocks."

   observability: new Observability({
-    //    default: { enabled: false },
     configs: {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
observability: new Observability({
// default: { enabled: false },
// default: { enabled: false },
observability: new Observability({
configs: {
🤖 Prompt for AI Agents
In src/mastra/index.ts around lines 193-194, there is a commented-out line
within the Observability config ("//    default: { enabled: false },"); remove
this dead/commented code line so the file contains only active code and comments
that convey intent; rely on version control history if that configuration needs
to be restored.

Comment on lines 506 to 508
// runtime API key (for tools that may accept runtimeContext.apiKey)
// if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
// if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Remove or document commented-out code.

Line 507 contains commented-out code for setting the apiKey in the request context. Per coding guidelines, avoid maintaining commented code blocks. Either remove it or, if intentionally disabled, add a TODO/NOTE comment explaining why.

           // research phase
           requestContext.set('researchPhase', researchPhaseHeader ?? 'initial')
-
-          //  if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
         }

Or if intentionally disabled:

-          //  if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
+          // NOTE: apiKey injection disabled - API keys are validated at the gateway level
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// runtime API key (for tools that may accept runtimeContext.apiKey)
// if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
// if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
}
// runtime API key (for tools that may accept runtimeContext.apiKey)
requestContext.set('researchPhase', researchPhaseHeader ?? 'initial')
}
Suggested change
// runtime API key (for tools that may accept runtimeContext.apiKey)
// if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
// if (apiKeyHeader !== null && apiKeyHeader !== '') { requestContext.set('apiKey', apiKeyHeader) }
}
// runtime API key (for tools that may accept runtimeContext.apiKey)
// NOTE: apiKey injection disabled - API keys are validated at the gateway level
}
🤖 Prompt for AI Agents
In src/mastra/index.ts around lines 506 to 508, there is a commented-out line
that sets the apiKey in the request context; remove the dead code or document
why it's disabled. If the behavior must remain disabled, replace the commented
line with a short TODO/NOTE explaining why (e.g., security concern, moved to
another layer, or awaiting env configuration), include who/when to revisit and
reference apiKeyHeader and requestContext so future readers know the intent;
otherwise delete the commented line entirely to satisfy the coding guideline.

Comment on lines +506 to 510
message: `Starting refinement phase for topic: ${inputData.finalScript.split('\n')[0].slice(0, 50)}...`,
stage: "refine-step",
},
id: 'refine-step',
id: "refine-step",
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider edge case when finalScript is empty.

If finalScript is an empty string, finalScript.split('\n')[0].slice(0, 50) returns an empty string, producing a message like "Starting refinement phase for topic: ..." with no context. Consider adding a fallback:

-        message: `Starting refinement phase for topic: ${inputData.finalScript.split('\n')[0].slice(0, 50)}...`,
+        message: `Starting refinement phase for: ${inputData.finalScript.split('\n')[0]?.slice(0, 50) || '(empty script)'}...`,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
message: `Starting refinement phase for topic: ${inputData.finalScript.split('\n')[0].slice(0, 50)}...`,
stage: "refine-step",
},
id: 'refine-step',
id: "refine-step",
});
message: `Starting refinement phase for: ${inputData.finalScript.split('\n')[0]?.slice(0, 50) || '(empty script)'}...`,
stage: "refine-step",
},
id: "refine-step",
});
🤖 Prompt for AI Agents
In src/mastra/workflows/content-studio-workflow.ts around lines 506 to 510, the
message building uses inputData.finalScript.split('\n')[0].slice(0, 50) which
yields an empty preview when finalScript is empty; change the logic to guard
against empty or undefined finalScript, derive the first line safely (trimmed)
and if that result is empty use a clear fallback like "<no topic provided>" (and
still append the ellipsis), then plug that preview into the message string so
the log always contains useful context.

Comment on lines +582 to 586
message: `Document chunked successfully: ${inputData.content.length} chunks created`,
stage: 'chunk-document',
},
id: "chunk-document",
id: 'chunk-document',
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bug: Incorrect value in completion message.

The message reports inputData.content.length (character count) instead of the actual chunk count. This should use chunks.length:

-          message: `Document chunked successfully: ${inputData.content.length} chunks created`,
+          message: `Document chunked successfully: ${chunks.length} chunks created`,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
message: `Document chunked successfully: ${inputData.content.length} chunks created`,
stage: 'chunk-document',
},
id: "chunk-document",
id: 'chunk-document',
});
message: `Document chunked successfully: ${chunks.length} chunks created`,
stage: 'chunk-document',
},
id: 'chunk-document',
});
🤖 Prompt for AI Agents
In src/mastra/workflows/document-processing-workflow.ts around lines 582 to 586,
the completion message currently reports inputData.content.length (character
count) instead of the number of chunks; update the message to use chunks.length
so it reports the actual chunk count (e.g., replace inputData.content.length
with chunks.length in the template string), ensuring the chunks variable is in
scope where the message is constructed.

Comment on lines +243 to +258
try {
const stream = await agent.stream(prompt);
const finalText = await stream.text;
const result = { text: finalText };

await writer?.custom({
type: 'data-tool-progress',
data: {
status: 'done',
message: `PRD generated (length: ${(result?.text ?? '').length})`,
stage: 'generate-prd',
},
id: 'generate-prd',
});

return { prd: result?.text || '# PRD\n\n(Generated PRD content)' };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Simplify redundant object wrapping.

The pattern const result = { text: finalText } followed by result?.text is unnecessarily indirect since finalText is already the string value:

-      const stream = await agent.stream(prompt);
-      const finalText = await stream.text;
-      const result = { text: finalText };
-
-      await writer?.custom({
-        ...
-        message: `PRD generated (length: ${(result?.text ?? '').length})`,
-        ...
-      });
-
-      return { prd: result?.text || '# PRD\n\n(Generated PRD content)' };
+      const stream = await agent.stream(prompt);
+      const finalText = await stream.text;
+
+      await writer?.custom({
+        ...
+        message: `PRD generated (length: ${finalText.length})`,
+        ...
+      });
+
+      return { prd: finalText || '# PRD\n\n(Generated PRD content)' };

This pattern repeats in archStep and tasksStep as well.

🤖 Prompt for AI Agents
In src/mastra/workflows/spec-generation-workflow.ts around lines 243 to 258, the
code wraps finalText in a temporary result object and then accesses result?.text
which is redundant; replace uses of result?.text with finalText directly (use
finalText in the writer.custom message and return), remove the intermediate
result object, and apply the same simplification in archStep and tasksStep where
the pattern repeats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant