diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml
index 1b0275883da..e5aee05785d 100644
--- a/.github/workflows/archie.lock.yml
+++ b/.github/workflows/archie.lock.yml
@@ -68,11 +68,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml
index d67cb472369..f6b76bc5579 100644
--- a/.github/workflows/brave.lock.yml
+++ b/.github/workflows/brave.lock.yml
@@ -55,11 +55,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml
index 2234c6b95a7..cb057eb5164 100644
--- a/.github/workflows/changeset.lock.yml
+++ b/.github/workflows/changeset.lock.yml
@@ -63,10 +63,12 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml
index 1c9a190537d..aa4406bb5f6 100644
--- a/.github/workflows/cloclo.lock.yml
+++ b/.github/workflows/cloclo.lock.yml
@@ -91,11 +91,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml
index 0eec6d4ece1..32366b2b313 100644
--- a/.github/workflows/craft.lock.yml
+++ b/.github/workflows/craft.lock.yml
@@ -55,11 +55,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml
index d9403212aa3..5038a3ba049 100644
--- a/.github/workflows/grumpy-reviewer.lock.yml
+++ b/.github/workflows/grumpy-reviewer.lock.yml
@@ -59,11 +59,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml
index 652a6313974..c986b5411fa 100644
--- a/.github/workflows/issue-classifier.lock.yml
+++ b/.github/workflows/issue-classifier.lock.yml
@@ -52,10 +52,12 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml
index 25e1d201782..5fb31e1bfd7 100644
--- a/.github/workflows/pdf-summary.lock.yml
+++ b/.github/workflows/pdf-summary.lock.yml
@@ -74,11 +74,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml
index 046e5cb311e..6af3fdaced3 100644
--- a/.github/workflows/plan.lock.yml
+++ b/.github/workflows/plan.lock.yml
@@ -59,11 +59,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml
index 09c655b3edb..2701fa418da 100644
--- a/.github/workflows/poem-bot.lock.yml
+++ b/.github/workflows/poem-bot.lock.yml
@@ -63,11 +63,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml
index 2053c63aeb5..59c49a61444 100644
--- a/.github/workflows/q.lock.yml
+++ b/.github/workflows/q.lock.yml
@@ -83,11 +83,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml
index 5e9861148f4..91cd2af08ce 100644
--- a/.github/workflows/scout.lock.yml
+++ b/.github/workflows/scout.lock.yml
@@ -99,11 +99,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml
index a95f838f281..0bfcc17d395 100644
--- a/.github/workflows/security-review.lock.yml
+++ b/.github/workflows/security-review.lock.yml
@@ -59,11 +59,13 @@ jobs:
       issues: write
       pull-requests: write
     outputs:
+      body: ${{ steps.compute-text.outputs.body }}
       comment_id: ${{ steps.add-comment.outputs.comment-id }}
       comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
       comment_url: ${{ steps.add-comment.outputs.comment-url }}
       slash_command: ${{ needs.pre_activation.outputs.matched_command }}
       text: ${{ steps.compute-text.outputs.text }}
+      title: ${{ steps.compute-text.outputs.title }}
     steps:
       - name: Checkout actions folder
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/actions/setup/js/compute_text.cjs b/actions/setup/js/compute_text.cjs
index 19560baaf18..e2edf22c0e0 100644
--- a/actions/setup/js/compute_text.cjs
+++ b/actions/setup/js/compute_text.cjs
@@ -11,6 +11,8 @@ const { getErrorMessage } = require("./error_helpers.cjs");
 
 async function main() {
   let text = "";
+  let title = "";
+  let body = "";
 
   const actor = context.actor;
   const { owner, repo } = context.repo;
@@ -27,6 +29,8 @@ async function main() {
 
   if (permission !== "admin" && permission !== "maintain") {
     core.setOutput("text", "");
+    core.setOutput("title", "");
+    core.setOutput("body", "");
     return;
   }
 
@@ -35,8 +39,8 @@ async function main() {
     case "issues":
       // For issues: title + body
       if (context.payload.issue) {
-        const title = context.payload.issue.title || "";
-        const body = context.payload.issue.body || "";
+        title = context.payload.issue.title || "";
+        body = context.payload.issue.body || "";
         text = `${title}\n\n${body}`;
       }
       break;
@@ -44,8 +48,8 @@ async function main() {
     case "pull_request":
       // For pull requests: title + body
       if (context.payload.pull_request) {
-        const title = context.payload.pull_request.title || "";
-        const body = context.payload.pull_request.body || "";
+        title = context.payload.pull_request.title || "";
+        body = context.payload.pull_request.body || "";
         text = `${title}\n\n${body}`;
       }
       break;
@@ -53,55 +57,59 @@ async function main() {
     case "pull_request_target":
       // For pull request target events: title + body
       if (context.payload.pull_request) {
-        const title = context.payload.pull_request.title || "";
-        const body = context.payload.pull_request.body || "";
+        title = context.payload.pull_request.title || "";
+        body = context.payload.pull_request.body || "";
         text = `${title}\n\n${body}`;
       }
       break;
 
     case "issue_comment":
-      // For issue comments: comment body
+      // For issue comments: comment body (no title)
       if (context.payload.comment) {
-        text = context.payload.comment.body || "";
+        body = context.payload.comment.body || "";
+        text = body;
       }
       break;
 
     case "pull_request_review_comment":
-      // For PR review comments: comment body
+      // For PR review comments: comment body (no title)
       if (context.payload.comment) {
-        text = context.payload.comment.body || "";
+        body = context.payload.comment.body || "";
+        text = body;
       }
       break;
 
     case "pull_request_review":
-      // For PR reviews: review body
+      // For PR reviews: review body (no title)
       if (context.payload.review) {
-        text = context.payload.review.body || "";
+        body = context.payload.review.body || "";
+        text = body;
       }
       break;
 
     case "discussion":
       // For discussions: title + body
       if (context.payload.discussion) {
-        const title = context.payload.discussion.title || "";
-        const body = context.payload.discussion.body || "";
+        title = context.payload.discussion.title || "";
+        body = context.payload.discussion.body || "";
         text = `${title}\n\n${body}`;
       }
       break;
 
     case "discussion_comment":
-      // For discussion comments: comment body
+      // For discussion comments: comment body (no title)
       if (context.payload.comment) {
-        text = context.payload.comment.body || "";
+        body = context.payload.comment.body || "";
+        text = body;
       }
       break;
 
     case "release":
       // For releases: name + body
       if (context.payload.release) {
-        const name = context.payload.release.name || context.payload.release.tag_name || "";
-        const body = context.payload.release.body || "";
-        text = `${name}\n\n${body}`;
+        title = context.payload.release.name || context.payload.release.tag_name || "";
+        body = context.payload.release.body || "";
+        text = `${title}\n\n${body}`;
       }
       break;
 
@@ -122,9 +130,9 @@ async function main() {
                 repo: urlRepo,
                 tag: tag,
               });
-              const name = release.name || release.tag_name || "";
-              const body = release.body || "";
-              text = `${name}\n\n${body}`;
+              title = release.name || release.tag_name || "";
+              body = release.body || "";
+              text = `${title}\n\n${body}`;
             } catch (error) {
               core.warning(`Failed to fetch release from URL: ${getErrorMessage(error)}`);
             }
@@ -137,9 +145,9 @@ async function main() {
               repo: repo,
               release_id: parseInt(releaseId, 10),
             });
-            const name = release.name || release.tag_name || "";
-            const body = release.body || "";
-            text = `${name}\n\n${body}`;
+            title = release.name || release.tag_name || "";
+            body = release.body || "";
+            text = `${title}\n\n${body}`;
           } catch (error) {
             core.warning(`Failed to fetch release by ID: ${getErrorMessage(error)}`);
           }
@@ -153,16 +161,22 @@ async function main() {
       break;
   }
 
-  // Sanitize the text before output
+  // Sanitize the text, title, and body before output
   // All mentions are escaped (wrapped in backticks) to prevent unintended notifications
   // Mention filtering will be applied by the agent output collector
   const sanitizedText = sanitizeIncomingText(text);
+  const sanitizedTitle = sanitizeIncomingText(title);
+  const sanitizedBody = sanitizeIncomingText(body);
 
-  // Display sanitized text in logs
+  // Display sanitized outputs in logs
   core.info(`text: ${sanitizedText}`);
+  core.info(`title: ${sanitizedTitle}`);
+  core.info(`body: ${sanitizedBody}`);
 
-  // Set the sanitized text as output
+  // Set the sanitized outputs
   core.setOutput("text", sanitizedText);
+  core.setOutput("title", sanitizedTitle);
+  core.setOutput("body", sanitizedBody);
 
   // Write redacted URL domains to log file if any were collected
   const logPath = writeRedactedDomainsLog();
diff --git a/actions/setup/js/compute_text.test.cjs b/actions/setup/js/compute_text.test.cjs
index c6fd22590ce..751b2aa03f6 100644
--- a/actions/setup/js/compute_text.test.cjs
+++ b/actions/setup/js/compute_text.test.cjs
@@ -123,47 +123,82 @@ const mockCore = {
             ((mockContext.eventName = "issues"),
               (mockContext.payload = { issue: { title: "Test Issue", body: "Issue description" } }),
               await testMain(),
-              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test Issue\n\nIssue description"));
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test Issue\n\nIssue description"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", "Test Issue"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "Issue description"));
           }),
           it("should extract text from pull request payload", async () => {
             ((mockContext.eventName = "pull_request"),
               (mockContext.payload = { pull_request: { title: "Test PR", body: "PR description" } }),
               await testMain(),
-              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test PR\n\nPR description"));
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test PR\n\nPR description"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", "Test PR"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "PR description"));
           }),
           it("should extract text from issue comment payload", async () => {
-            ((mockContext.eventName = "issue_comment"), (mockContext.payload = { comment: { body: "This is a comment" } }), await testMain(), expect(mockCore.setOutput).toHaveBeenCalledWith("text", "This is a comment"));
+            ((mockContext.eventName = "issue_comment"),
+              (mockContext.payload = { comment: { body: "This is a comment" } }),
+              await testMain(),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "This is a comment"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "This is a comment"));
           }),
           it("should extract text from pull request target payload", async () => {
             ((mockContext.eventName = "pull_request_target"),
               (mockContext.payload = { pull_request: { title: "Test PR Target", body: "PR target description" } }),
               await testMain(),
-              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test PR Target\n\nPR target description"));
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test PR Target\n\nPR target description"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", "Test PR Target"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "PR target description"));
           }),
           it("should extract text from pull request review comment payload", async () => {
-            ((mockContext.eventName = "pull_request_review_comment"), (mockContext.payload = { comment: { body: "Review comment" } }), await testMain(), expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Review comment"));
+            ((mockContext.eventName = "pull_request_review_comment"),
+              (mockContext.payload = { comment: { body: "Review comment" } }),
+              await testMain(),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Review comment"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "Review comment"));
           }),
           it("should extract text from pull request review payload", async () => {
-            ((mockContext.eventName = "pull_request_review"), (mockContext.payload = { review: { body: "Review body" } }), await testMain(), expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Review body"));
+            ((mockContext.eventName = "pull_request_review"),
+              (mockContext.payload = { review: { body: "Review body" } }),
+              await testMain(),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Review body"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "Review body"));
           }),
           it("should extract text from discussion payload", async () => {
             ((mockContext.eventName = "discussion"),
               (mockContext.payload = { discussion: { title: "Test Discussion", body: "Discussion description" } }),
               await testMain(),
-              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test Discussion\n\nDiscussion description"));
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Test Discussion\n\nDiscussion description"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", "Test Discussion"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "Discussion description"));
           }),
           it("should extract text from discussion comment payload", async () => {
-            ((mockContext.eventName = "discussion_comment"), (mockContext.payload = { comment: { body: "Discussion comment text" } }), await testMain(), expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Discussion comment text"));
+            ((mockContext.eventName = "discussion_comment"),
+              (mockContext.payload = { comment: { body: "Discussion comment text" } }),
+              await testMain(),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", "Discussion comment text"),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", "Discussion comment text"));
           }),
           it("should handle unknown event types", async () => {
-            ((mockContext.eventName = "unknown_event"), (mockContext.payload = {}), await testMain(), expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""));
+            ((mockContext.eventName = "unknown_event"),
+              (mockContext.payload = {}),
+              await testMain(),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", ""));
           }),
           it("should deny access for non-admin/maintain users", async () => {
             (mockGithub.rest.repos.getCollaboratorPermissionLevel.mockResolvedValue({ data: { permission: "read" } }),
               (mockContext.eventName = "issues"),
               (mockContext.payload = { issue: { title: "Test Issue", body: "Issue description" } }),
               await testMain(),
-              expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""));
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", ""));
           }),
           it("should sanitize extracted text before output", async () => {
             ((mockContext.eventName = "issues"), (mockContext.payload = { issue: { title: "Test @user fixes #123", body: "Visit https://evil.com" } }), await testMain());
@@ -171,10 +206,20 @@ const mockCore = {
             (expect(outputCall[1]).toContain("`@user`"), expect(outputCall[1]).toContain("`fixes #123`"), expect(outputCall[1]).toContain("/redacted"));
           }),
           it("should handle missing title and body gracefully", async () => {
-            ((mockContext.eventName = "issues"), (mockContext.payload = { issue: {} }), await testMain(), expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""));
+            ((mockContext.eventName = "issues"),
+              (mockContext.payload = { issue: {} }),
+              await testMain(),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", ""));
           }),
           it("should handle null values in payload", async () => {
-            ((mockContext.eventName = "issue_comment"), (mockContext.payload = { comment: { body: null } }), await testMain(), expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""));
+            ((mockContext.eventName = "issue_comment"),
+              (mockContext.payload = { comment: { body: null } }),
+              await testMain(),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("text", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("title", ""),
+              expect(mockCore.setOutput).toHaveBeenCalledWith("body", ""));
           }),
           it("should neutralize all mentions including issue author", async () => {
             ((mockContext.eventName = "issues"), (mockContext.payload = { issue: { title: "Test Issue by @issueAuthor", body: "Body mentioning @issueAuthor and @other", user: { login: "issueAuthor" } } }), await testMain());
diff --git a/pkg/workflow/compiler_activation_jobs.go b/pkg/workflow/compiler_activation_jobs.go
index 813d45238c1..aae723eb629 100644
--- a/pkg/workflow/compiler_activation_jobs.go
+++ b/pkg/workflow/compiler_activation_jobs.go
@@ -425,8 +425,10 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate
 		steps = append(steps, "          script: |\n")
 		steps = append(steps, generateGitHubScriptWithRequire("compute_text.cjs"))
 
-		// Set up outputs
+		// Set up outputs - includes text, title, and body
 		outputs["text"] = "${{ steps.compute-text.outputs.text }}"
+		outputs["title"] = "${{ steps.compute-text.outputs.title }}"
+		outputs["body"] = "${{ steps.compute-text.outputs.body }}"
 	}
 
 	// Add comment with workflow run link if ai-reaction is configured and not "none"
diff --git a/pkg/workflow/compiler_orchestrator_test.go b/pkg/workflow/compiler_orchestrator_test.go
index 69050084d36..5a359cc074e 100644
--- a/pkg/workflow/compiler_orchestrator_test.go
+++ b/pkg/workflow/compiler_orchestrator_test.go
@@ -476,6 +476,21 @@ func TestDetectTextOutputUsageInOrchestrator(t *testing.T) {
 			markdown:       "${{ needs.activation.outputs.text }}\nFirst\n${{ needs.activation.outputs.text }}\nSecond",
 			expectedOutput: true,
 		},
+		{
+			name:           "with title output usage",
+			markdown:       "# Workflow\n\nUse ${{ needs.activation.outputs.title }} here.",
+			expectedOutput: true,
+		},
+		{
+			name:           "with body output usage",
+			markdown:       "# Workflow\n\nUse ${{ needs.activation.outputs.body }} here.",
+			expectedOutput: true,
+		},
+		{
+			name:           "with mixed text, title, body usage",
+			markdown:       "# Workflow\n\nTitle: ${{ needs.activation.outputs.title }}\nBody: ${{ needs.activation.outputs.body }}\nFull: ${{ needs.activation.outputs.text }}",
+			expectedOutput: true,
+		},
 	}
 
 	for _, tt := range tests {
diff --git a/pkg/workflow/compiler_orchestrator_tools.go b/pkg/workflow/compiler_orchestrator_tools.go
index c0dd1f8c6a8..dfd69e884f2 100644
--- a/pkg/workflow/compiler_orchestrator_tools.go
+++ b/pkg/workflow/compiler_orchestrator_tools.go
@@ -322,10 +322,16 @@ func (c *Compiler) processToolsAndMarkdown(result *parser.FrontmatterResult, cle
 	}, nil
 }
 
-// detectTextOutputUsage checks if the markdown content uses ${{ needs.activation.outputs.text }}
+// detectTextOutputUsage checks if the markdown content uses ${{ needs.activation.outputs.text }},
+// ${{ needs.activation.outputs.title }}, or ${{ needs.activation.outputs.body }}
 func (c *Compiler) detectTextOutputUsage(markdownContent string) bool {
-	// Check for the specific GitHub Actions expression
-	hasUsage := strings.Contains(markdownContent, "${{ needs.activation.outputs.text }}")
-	detectionLog.Printf("Detected usage of activation.outputs.text: %v", hasUsage)
+	// Check for any of the text-related output expressions
+	hasTextUsage := strings.Contains(markdownContent, "${{ needs.activation.outputs.text }}")
+	hasTitleUsage := strings.Contains(markdownContent, "${{ needs.activation.outputs.title }}")
+	hasBodyUsage := strings.Contains(markdownContent, "${{ needs.activation.outputs.body }}")
+
+	hasUsage := hasTextUsage || hasTitleUsage || hasBodyUsage
+	detectionLog.Printf("Detected usage of activation outputs - text: %v, title: %v, body: %v, any: %v",
+		hasTextUsage, hasTitleUsage, hasBodyUsage, hasUsage)
 	return hasUsage
 }
