Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Oct 17, 2025

Implements a cleaner approach for UI messages to prevent bloated ui_messages.json:

  • Add formatContentBlockForUi() to summarize content blocks safely
    • Redacts diffs and large bodies
    • Summarizes XML to file paths/errors/notices only
    • Truncates long text (2000 chars default)
    • Summarizes tool_use parameters (paths/regex/file_pattern), not bodies
  • Replace request preview composition in Task to use the UI-safe formatter for:
    • api_req_started initial preview
    • api_req_started final update before streaming

Functional scope:

  • UI message cleanliness only; apiConversationHistory/export stays full-fidelity for model use.

Follow-ups (optional):

  • Consider making truncation limit configurable
  • Add unit tests around diff redaction, XML summarization (escaped/unescaped), and tool_use summaries.

Important

Introduces formatContentBlockForUi() to safely format content blocks for UI messages, applied in Task.ts for cleaner api_req_started messages.

  • Behavior:
    • Adds formatContentBlockForUi() in formatContentBlockForUi.ts to summarize content blocks for UI messages.
    • Replaces formatContentBlockToMarkdown() with formatContentBlockForUi() in Task.ts for api_req_started messages.
    • Redacts diffs, summarizes XML to paths/errors, truncates long text, and summarizes tool_use parameters.
  • Functional Scope:
    • Affects UI message formatting only; full data retained for apiConversationHistory and exports.
  • Follow-ups:
    • Consider configurable truncation limit.
    • Add unit tests for diff redaction, XML summarization, and tool_use summaries.

This description was created by Ellipsis for 598d7a3. You can customize this summary. It will automatically update as commits are pushed.

…messages; add formatContentBlockForUi() and use for api_req_started
@roomote roomote bot requested review from cte, jr and mrubens as code owners October 17, 2025 06:08
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Oct 17, 2025
@roomote
Copy link
Contributor Author

roomote bot commented Oct 17, 2025

Review Summary

I've identified 3 issues that need to be addressed:

  • Line 91: Fix duplicate condition in sanitizeText - should check for both <files and &lt;files to detect escaped XML
  • Lines 112-114: Fix duplicate diff marker checks in looksLikeDiff - should check for both unescaped and escaped versions
  • Line 126 (and 161): Fix HTML entity decoding order in decode function - &amp; must be decoded last to properly handle double-encoded entities

@dosubot dosubot bot added the UI/UX UI/UX related or focused label Oct 17, 2025
if (!text) return ""

// If this looks like a files XML, summarize paths/errors/notices and drop content bodies
if (text.includes("<files") || text.includes("<files")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Duplicate condition found in sanitizeText: checking text.includes('<files') twice. Remove the redundant check.

Suggested change
if (text.includes("<files") || text.includes("<files")) {
if (text.includes("<files")) {


function looksLikeDiff(s: string): boolean {
return (
s.includes("<<<<<<< SEARCH") ||
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant diff marker checks in looksLikeDiff: the same strings are checked twice. Consider removing the duplicate includes for '<<<<<<< SEARCH' and '>>>>>>> REPLACE'.

*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
Copy link
Contributor

Choose a reason for hiding this comment

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

The decode function does not actually decode HTML entities. It replaces '<' with '<', etc. Consider using proper replacement (e.g. replacing '&lt;' with '<', '&gt;' with '>', '&amp;' with '&').

Suggested change
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) => s.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&')

*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")

Check warning

Code scanning / CodeQL

Replacement of a substring with itself Medium

This replaces '<' with itself.

Copilot Autofix

AI 3 months ago

To resolve this, we should properly decode XML/HTML entities in the string: replace &lt; with <, &gt; with >, and &amp; with & (and possibly more, but these cover the standard cases given the context of parsing XML-like content). This can be done by chaining .replace() calls, or (for broader correctness) by using a well-known library such as he for HTML entity decoding. Since only standard entities are mentioned and only the shown code can be changed, the best fix is to replace the identity replacements with proper entity replacements in the decode helper function, on line 126.

Suggested changeset 1
src/shared/formatContentBlockForUi.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/shared/formatContentBlockForUi.ts b/src/shared/formatContentBlockForUi.ts
--- a/src/shared/formatContentBlockForUi.ts
+++ b/src/shared/formatContentBlockForUi.ts
@@ -123,7 +123,11 @@
  */
 function summarizeFilesXml(xmlLike: string): string {
 	// Support both escaped and unescaped tags
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) =>
+		s
+			.replace(/&lt;/g, "<")
+			.replace(/&gt;/g, ">")
+			.replace(/&amp;/g, "&");
 
 	const raw = decode(xmlLike)
 	const fileRegex = /<file>([\s\S]*?)<\/file>/g
EOF
@@ -123,7 +123,11 @@
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) =>
s
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&amp;/g, "&");

const raw = decode(xmlLike)
const fileRegex = /<file>([\s\S]*?)<\/file>/g
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")

Check warning

Code scanning / CodeQL

Replacement of a substring with itself Medium

This replaces '>' with itself.

Copilot Autofix

AI 3 months ago

To fix this problem, update the decode function (on line 126) to properly decode common XML entities. Specifically, replace all occurrences of &lt; with <, &gt; with >, and &amp; with &. This ensures that both escaped and unescaped XML tags are handled as described in the comment, and the decoder correctly converts XML entity-encoded tags to their character equivalents for further processing. The changes are localized to the decode function, so edit line 126 in the file src/shared/formatContentBlockForUi.ts to swap the current replacement calls for the correct ones.

No additional imports or dependencies are required, and the fix is self-contained.


Suggested changeset 1
src/shared/formatContentBlockForUi.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/shared/formatContentBlockForUi.ts b/src/shared/formatContentBlockForUi.ts
--- a/src/shared/formatContentBlockForUi.ts
+++ b/src/shared/formatContentBlockForUi.ts
@@ -123,7 +123,10 @@
  */
 function summarizeFilesXml(xmlLike: string): string {
 	// Support both escaped and unescaped tags
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) =>
+		s.replace(/&lt;/g, "<")
+		 .replace(/&gt;/g, ">")
+		 .replace(/&amp;/g, "&")
 
 	const raw = decode(xmlLike)
 	const fileRegex = /<file>([\s\S]*?)<\/file>/g
EOF
@@ -123,7 +123,10 @@
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) =>
s.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&amp;/g, "&")

const raw = decode(xmlLike)
const fileRegex = /<file>([\s\S]*?)<\/file>/g
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")

Check warning

Code scanning / CodeQL

Replacement of a substring with itself Medium

This replaces '&' with itself.

Copilot Autofix

AI 3 months ago

The best fix is to replace the decode function with one that properly decodes XML/HTML entities, converting sequences like &lt; to <, &gt; to >, and &amp; to &, as well as any other encountered entities. Since TypeScript/JavaScript does not provide a standard, reliable method for entity decoding, but the well-known library he (html-entities is also popular) can accomplish this robustly. In the context of this file, we only need to decode a string, so importing and using a decoder from a widely used library is the best way to meet the requirement. Therefore, replace the ad-hoc decode function with an implementation using he.decode. This change is limited to src/shared/formatContentBlockForUi.ts. If importing is not possible, you may use a minimum viable manual decoding for the three most common entities (&lt;, &gt;, &amp;).

Suggested changeset 2
src/shared/formatContentBlockForUi.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/shared/formatContentBlockForUi.ts b/src/shared/formatContentBlockForUi.ts
--- a/src/shared/formatContentBlockForUi.ts
+++ b/src/shared/formatContentBlockForUi.ts
@@ -123,7 +123,8 @@
  */
 function summarizeFilesXml(xmlLike: string): string {
 	// Support both escaped and unescaped tags
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	import { decode as heDecode } from "he";
+	const decode = (s: string) => heDecode(s);
 
 	const raw = decode(xmlLike)
 	const fileRegex = /<file>([\s\S]*?)<\/file>/g
EOF
@@ -123,7 +123,8 @@
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
import { decode as heDecode } from "he";
const decode = (s: string) => heDecode(s);

const raw = decode(xmlLike)
const fileRegex = /<file>([\s\S]*?)<\/file>/g
src/package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/package.json b/src/package.json
--- a/src/package.json
+++ b/src/package.json
@@ -521,7 +521,8 @@
 		"web-tree-sitter": "^0.25.6",
 		"workerpool": "^9.2.0",
 		"yaml": "^2.8.0",
-		"zod": "^3.25.61"
+		"zod": "^3.25.61",
+		"he": "^1.2.0"
 	},
 	"devDependencies": {
 		"@roo-code/build": "workspace:^",
EOF
@@ -521,7 +521,8 @@
"web-tree-sitter": "^0.25.6",
"workerpool": "^9.2.0",
"yaml": "^2.8.0",
"zod": "^3.25.61"
"zod": "^3.25.61",
"he": "^1.2.0"
},
"devDependencies": {
"@roo-code/build": "workspace:^",
This fix introduces these dependencies
Package Version Security advisories
he (npm) 1.2.0 None
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
}

function extractPathsFromXml(xml: string): string[] {
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")

Check warning

Code scanning / CodeQL

Replacement of a substring with itself Medium

This replaces '<' with itself.

Copilot Autofix

AI 3 months ago

The main issue is that the decode function is defined as follows:

const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")

This does nothing, because it replaces "<" with "<", and so on. The function should decode XML/HTML entity escapes such as &lt;, &gt;, and &amp; to their respective literal characters, so that subsequent regex matches against tags like <file> work whether the tags are escaped or not.

General repair:
Replace the decode function definition with one that actually decodes &lt;, &gt;, and &amp; to <, >, and &, respectively.

Best way (detailed):

  • Update the decode function in summarizeFilesXml (line 126) and in extractPathsFromXml (line 161) so they replace escaped XML/HTML entities (&lt;, &gt;, &amp;) with the corresponding literal characters (<, >, &).
  • Do not change other code or functionality, only fix the decoding.
  • No new import is needed; simple string replace suffices for these cases.

Suggested changeset 1
src/shared/formatContentBlockForUi.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/shared/formatContentBlockForUi.ts b/src/shared/formatContentBlockForUi.ts
--- a/src/shared/formatContentBlockForUi.ts
+++ b/src/shared/formatContentBlockForUi.ts
@@ -123,7 +123,8 @@
  */
 function summarizeFilesXml(xmlLike: string): string {
 	// Support both escaped and unescaped tags
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) =>
+		s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&")
 
 	const raw = decode(xmlLike)
 	const fileRegex = /<file>([\s\S]*?)<\/file>/g
@@ -158,7 +159,8 @@
 }
 
 function extractPathsFromXml(xml: string): string[] {
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) =>
+		s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&")
 	const raw = decode(xml)
 	const pathRegex = /<path>([\s\S]*?)<\/path>/g
 	const paths: string[] = []
EOF
@@ -123,7 +123,8 @@
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) =>
s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&")

const raw = decode(xmlLike)
const fileRegex = /<file>([\s\S]*?)<\/file>/g
@@ -158,7 +159,8 @@
}

function extractPathsFromXml(xml: string): string[] {
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) =>
s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&")
const raw = decode(xml)
const pathRegex = /<path>([\s\S]*?)<\/path>/g
const paths: string[] = []
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
}

function extractPathsFromXml(xml: string): string[] {
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")

Check warning

Code scanning / CodeQL

Replacement of a substring with itself Medium

This replaces '>' with itself.

Copilot Autofix

AI 3 months ago

The bug exists in the decode functions (lines 126 and 161) where .replace(/</g, "<").replace(/>/g, ">") replaces characters with themselves — a useless operation. The intention appears to be decoding the XML-escaped forms (&lt;, &gt;, and &amp;), converting XML character entities back to their original characters. The correct replacements should therefore be:

  • .replace(/&lt;/g, "<")
  • .replace(/&gt;/g, ">")
  • .replace(/&amp;/g, "&")

To fix this:

  • On lines 126 and 161, update both decode functions to replace &lt;, &gt;, and &amp; with <, >, and & respectively, instead of attempting to replace literal <, >, and & with themselves.
  • No imports are required.
  • Only change the decode lambda body in both places, not other code.

Suggested changeset 1
src/shared/formatContentBlockForUi.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/shared/formatContentBlockForUi.ts b/src/shared/formatContentBlockForUi.ts
--- a/src/shared/formatContentBlockForUi.ts
+++ b/src/shared/formatContentBlockForUi.ts
@@ -123,7 +123,10 @@
  */
 function summarizeFilesXml(xmlLike: string): string {
 	// Support both escaped and unescaped tags
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) => s
+		.replace(/&lt;/g, "<")
+		.replace(/&gt;/g, ">")
+		.replace(/&amp;/g, "&")
 
 	const raw = decode(xmlLike)
 	const fileRegex = /<file>([\s\S]*?)<\/file>/g
@@ -158,7 +161,10 @@
 }
 
 function extractPathsFromXml(xml: string): string[] {
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) => s
+		.replace(/&lt;/g, "<")
+		.replace(/&gt;/g, ">")
+		.replace(/&amp;/g, "&")
 	const raw = decode(xml)
 	const pathRegex = /<path>([\s\S]*?)<\/path>/g
 	const paths: string[] = []
EOF
@@ -123,7 +123,10 @@
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) => s
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&amp;/g, "&")

const raw = decode(xmlLike)
const fileRegex = /<file>([\s\S]*?)<\/file>/g
@@ -158,7 +161,10 @@
}

function extractPathsFromXml(xml: string): string[] {
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) => s
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&amp;/g, "&")
const raw = decode(xml)
const pathRegex = /<path>([\s\S]*?)<\/path>/g
const paths: string[] = []
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
}

function extractPathsFromXml(xml: string): string[] {
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")

Check warning

Code scanning / CodeQL

Replacement of a substring with itself Medium

This replaces '&' with itself.

Copilot Autofix

AI 3 months ago

To fix the problem, the decode function should replace entity-encoded representations (such as &amp;, &lt;, &gt;) with their corresponding normal characters (&, <, >). Therefore, within the decode function, update the replacement logic to convert both < and > entities, as well as &amp; to &. Specifically, change the replacements so that .replace(/&/g, "&") becomes .replace(/&amp;/g, "&"), and (optionally) update < and > handling for XML entities if necessary. Make changes only in the code region defining the decode function within summarizeFilesXml and extractPathsFromXml (lines 126 and 161).

Suggested changeset 1
src/shared/formatContentBlockForUi.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/shared/formatContentBlockForUi.ts b/src/shared/formatContentBlockForUi.ts
--- a/src/shared/formatContentBlockForUi.ts
+++ b/src/shared/formatContentBlockForUi.ts
@@ -123,7 +123,7 @@
  */
 function summarizeFilesXml(xmlLike: string): string {
 	// Support both escaped and unescaped tags
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) => s.replace(/&amp;/g, "&").replace(/</g, "<").replace(/>/g, ">")
 
 	const raw = decode(xmlLike)
 	const fileRegex = /<file>([\s\S]*?)<\/file>/g
@@ -158,7 +158,7 @@
 }
 
 function extractPathsFromXml(xml: string): string[] {
-	const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
+	const decode = (s: string) => s.replace(/&amp;/g, "&").replace(/</g, "<").replace(/>/g, ">")
 	const raw = decode(xml)
 	const pathRegex = /<path>([\s\S]*?)<\/path>/g
 	const paths: string[] = []
EOF
@@ -123,7 +123,7 @@
*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) => s.replace(/&amp;/g, "&").replace(/</g, "<").replace(/>/g, ">")

const raw = decode(xmlLike)
const fileRegex = /<file>([\s\S]*?)<\/file>/g
@@ -158,7 +158,7 @@
}

function extractPathsFromXml(xml: string): string[] {
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
const decode = (s: string) => s.replace(/&amp;/g, "&").replace(/</g, "<").replace(/>/g, ">")
const raw = decode(xml)
const pathRegex = /<path>([\s\S]*?)<\/path>/g
const paths: string[] = []
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
if (!text) return ""

// If this looks like a files XML, summarize paths/errors/notices and drop content bodies
if (text.includes("<files") || text.includes("<files")) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This condition checks for the unescaped <files tag twice. The second check should be for the escaped version &lt;files to properly detect escaped XML in text content. Without this, escaped XML tags won't be summarized and could bloat the UI messages.

Comment on lines +112 to +114
s.includes("<<<<<<< SEARCH") ||
s.includes(">>>>>>> REPLACE") ||
s.includes("<<<<<<< SEARCH") ||
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These lines check for the same unescaped diff markers twice. To properly handle both escaped and unescaped content, the second set should check for escaped versions (e.g., &lt;&lt;&lt;&lt;&lt;&lt;&lt; SEARCH and &gt;&gt;&gt;&gt;&gt;&gt;&gt; REPLACE) to detect diff content that may have been HTML-escaped in the text.

*/
function summarizeFilesXml(xmlLike: string): string {
// Support both escaped and unescaped tags
const decode = (s: string) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The entity decoding order is incorrect. When decoding HTML entities, &amp; must be decoded LAST, otherwise double-encoded entities won't decode properly. For example, with the current order, &amp;lt; becomes &lt; (still escaped) instead of < (correct). The correct order should be: .replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&'). This same issue exists in the decode function at line 161.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Oct 17, 2025
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Oct 17, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Oct 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants